hackingmaterials / atomate

atomate is a powerful software for computational materials science and contains pre-built workflows.
https://hackingmaterials.github.io/atomate
Other
241 stars 173 forks source link

Make calculation Fireworks able to be chained #238

Open bocklund opened 6 years ago

bocklund commented 6 years ago

General calculation Fireworks such OptimizeFW cannot be chained. OptimizeFW doesn't use WriteVaspStaticFromPrev (or any kind of WriteVasp*FromPrev). This makes executing graphs such as the one below hard to do because each OptimizeFW will use the same initial Structure over and over.

phonon-start

The current versions of these Firetasks are not that flexible. For example WriteVaspStaticFromPrev forces you to start with a MPStaticSet and customize it.

My suggestion is to have a Firetask somewhat like the following:

@explicit_serialize
class WriteVaspFromIOSetPrevStructure(FiretaskBase):
    """
    Create VASP input files using implementations of pymatgen's VaspInputSet, overriding the
    Structure using a POSCAR in the current directory. An input set
    can be provided as an object or as a String/parameter combo.
    Required params:
        vasp_input_set (AbstractVaspInputSet or str): Either a VaspInputSet object or a string
            name for the VASP input set (e.g., "PRLStaticSet").
    Optional params:
        vasp_input_params (dict): When using a string name for VASP input set, use this as a dict
            to specify kwargs for instantiating the input set parameters. For example, if you want
            to change the user_incar_settings, you should provide: {"user_incar_settings": ...}.
            This setting is ignored if you provide the full object representation of a VaspInputSet
            rather than a String.
    """

    required_params = ["vasp_input_set"]
    optional_params = ["vasp_input_params"]

    def run_task(self, fw_spec):
        struct = Structure.from_file('POSCAR')
        # if a full VaspInputSet object was provided
        if hasattr(self['vasp_input_set'], 'write_input'):
            vis = self['vasp_input_set']
            vis.structure = struct
        # if VaspInputSet String + parameters was provided
        else:
            vis_cls = load_class("pymatgen.io.vasp.sets", self["vasp_input_set"])
            vis = vis_cls(struct, **self.get("vasp_input_params", {}))
        vis.write_input(".")

The way this is implemented assumes that you have the input set the way you want it and that a POSCAR is in the current directory. At the Firework level, use the same logic as in the StaticFW: copy files over any way you like (CONTCAR -> POSCAR) then use this task. You can then use any input set (defaulting to MPStatic or whatever) and then modify it like before. An alternative would be to use prev_calc_dir.

This may be able take the place of the following Firetasks, depending on how prev_calc_dir is used

bocklund commented 6 years ago

Can we discuss what the behavior of Fireworks should be?

My suggestion is that

  1. Without parents, we keep the current implementation
  2. With parents A. If Input set has a from_prev method, use it with the structure from the previous calculation B. else (other input set is specified) instantiate if necessary and override the structure with the structure copied from the parent calculation
computron commented 6 years ago

This is just thinking out loud, but how about for the general "write inputs from a vaspinputset class" to has the following args:

So the differences from your initial sketch:

What do you think?

computron commented 6 years ago

Btw I'm still thinking about this, I think what I wrote above moves things forward a little bit but still has problems. e.g., if we remove things like WriteVaspNSCFFromPrev then all the default values associated with that task no longer exist anywhere which will make using a more generic task more awkward / painful.

computron commented 6 years ago

Ok here's a revised plan:

  1. Tasks like WriteVaspFromIOSet which currently require a Structure input will be more flexible to allow for either a Structure or str representing the file from which to get the Structure ("CONTCAR", "POSCAR", etc). This will allow these tasks to be used both as the initial step (give it a Structure) as well as an intermediate step (give it a string filename to read from).
  2. This should also make it easy to make the associated Fireworks that use these tasks to act both at the beginning of or in between a workflow. e.g., something like OptimizeFW would work at any place in the workflow.
  3. For the from_prev type FWs like WriteVaspNSCFFromPrev, I mostly see them remaining largely as-is for now. They contain a bunch of useful defaults, etc. and these are really intended to be run in the middle of a workflow.
computron commented 6 years ago

Also:

  1. The from_prev Firetasks should be modified to allow writing only the VASP input files they need to in order to operate. For example, the WriteVaspNSCFFromPrev would have an option to avoid rewriting the POTCAR. This is so if an upstream Firework made some change to the POTCAR settings, it would still be respected by the current FW rather than overwritten by the input set (when you really just wanted the input set to change a few INCAR settings). This might be a little problematic since sometimes these are coupled, e..g. removing or reordering sites from a POSCAR or switching functioanls in INCAR does necessitate rewriting the POTCAR. But it might be nice to have a skip_potcar option for some of these. I know I've sometimes changed a POTCAR upstream intentionally only to have it get re-changed back.
computron commented 6 years ago

We could also explore getting the Structure from the fw_spec which would make things really flexible, not sure if that's just adding complication for no good reason