Make calculation Fireworks able to be chained
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.

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
-
WriteVaspStaticFromPrev -
WriteVaspHSEBSFromPrev -
WriteVaspNSCFFromPrev
Can we discuss what the behavior of Fireworks should be?
My suggestion is that
- Without parents, we keep the current implementation
- With parents
A. If Input set has a
from_prevmethod, 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
This is just thinking out loud, but how about for the general "write inputs from a vaspinputset class" to has the following args:
-
structure. This is either a pymatgen Structure, which is probably want to use if your FW is the first one in your workflow, or it could be the string "CONTCAR" or "POSCAR" (or any other name you are using for your structure file like "CONTCAR.thebestone". The structure is loaded based on your setting. -
vaspinputsetandvasp_input_params- same as what you have above -
from_prev(bool) - if true, will use thefrom_prevmethod of the vaspinputset.
So the differences from your initial sketch:
- Instead of assuming the structure is from the POSCAR, the user can either provide a structure or give the location (POSCAR or CONTCAR) where they want to grab the structure from. This allows this Firework to essentially also replace
WriteVaspFromIOSet, in fact I would expectWriteVaspFromIOSetwould just include these new features. - Making
from_prevexplicit; I always like it when actions like this are set by the user rather than decided by the code
What do you think?
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.
Ok here's a revised plan:
- Tasks like
WriteVaspFromIOSetwhich currently require aStructureinput will be more flexible to allow for either aStructureorstrrepresenting 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). - 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
OptimizeFWwould work at any place in the workflow. - For the
from_prevtype FWs likeWriteVaspNSCFFromPrev, 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.
Also:
- The
from_prevFiretasks should be modified to allow writing only the VASP input files they need to in order to operate. For example, theWriteVaspNSCFFromPrevwould 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 askip_potcaroption for some of these. I know I've sometimes changed a POTCAR upstream intentionally only to have it get re-changed back.
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