Beispiel #1
0
    def test_modifyincar(self):
        # create an INCAR
        incar = self.ref_incar
        incar.write_file(os.path.join(module_dir, "INCAR"))

        # modify and test
        ft = ModifyIncar({
            "incar_update": {
                "ISMEAR": 1000
            },
            "incar_multiply": {
                "ENCUT": 1.5
            },
            "incar_dictmod": {
                "_inc": {
                    "ISPIN": -1
                }
            }
        })
        ft = load_object(ft.to_dict())  # simulate database insertion
        ft.run_task({})

        incar_mod = Incar.from_file("INCAR")
        self.assertEqual(incar_mod['ISMEAR'], 1000)
        self.assertEqual(incar_mod['ENCUT'], 780)
        self.assertEqual(incar_mod['ISPIN'], 1)
Beispiel #2
0
    def __init__(self, structure, isif=2, scale_lattice=None, name="static", vasp_input_set=None, 
                 vasp_cmd="vasp", metadata=None, prev_calc_loc=True, Prestatic=False, modify_incar=None, 
                 db_file=None, parents=None, tag=None, override_default_vasp_params=None,
                 store_volumetric_data=False, **kwargs):

        # TODO: @computron - I really don't like how you need to set the structure even for
        # prev_calc_loc jobs. Sometimes it makes appending new FWs to an existing workflow
        # difficult. Maybe think about how to remove this need? -computron
        metadata = metadata or {}
        tag = tag or metadata.get('tag')
        # generate a tag with a warning
        if tag is None:
            tag = str(uuid4())
            metadata['tag'] = tag

        if isinstance(store_volumetric_data, (list, tuple)):
            store_volumetric_data = store_volumetric_data
        elif isinstance(store_volumetric_data, bool):
            if store_volumetric_data:
                store_volumetric_data = STORE_VOLUMETRIC_DATA
            else:
                store_volumetric_data = ()
        else:
            raise ValueError('The store_volumetric_data should be list or bool')

        override_default_vasp_params = override_default_vasp_params or {}
        self.override_default_vasp_params = override_default_vasp_params
        vasp_input_set = vasp_input_set or StaticSet(structure, isif=isif, **override_default_vasp_params)
        site_properties = deepcopy(structure).site_properties
        # Avoids delivery (prev_calc_loc == '' (instead by True))
        t = []
        if type(prev_calc_loc) == str:
            t.append(CopyVaspOutputs(calc_dir=prev_calc_loc, contcar_to_poscar=True))
            t.append(WriteVaspFromIOSetPrevStructure(vasp_input_set=vasp_input_set, site_properties=site_properties))
        elif parents:
            if prev_calc_loc:
                t.append(CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True))
            t.append(WriteVaspFromIOSetPrevStructure(vasp_input_set=vasp_input_set, site_properties=site_properties))
        else:
            t.append(WriteVaspFromIOSetPrevStructure(structure=structure, vasp_input_set=vasp_input_set, site_properties=site_properties))
        if (scale_lattice is not None) and not Prestatic:
            t.append(ScaleVolumeTransformation(scale_factor=scale_lattice, structure=structure))
        t.append(ModifyIncar(incar_update=">>incar_update<<"))
        if modify_incar != None:
             t.append(ModifyIncar(incar_update=modify_incar))
        t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, auto_npar=">>auto_npar<<", gzip_output=False))
        t.append(PassCalcLocs(name=name))
        if Prestatic:
            t.append(Record_PreStatic_result(db_file = ">>db_file<<", metadata = metadata, structure = structure, scale_lattice = scale_lattice))
        else:
            t.append(VaspToDb(db_file=">>db_file<<", parse_dos=True, additional_fields={"task_label": name, "metadata": metadata,
                                "version_atomate": atomate_ver, "version_dfttk": dfttk_ver, "adopted": True, "tag": tag},
                                store_volumetric_data=store_volumetric_data))
            run_task_ext(t,vasp_cmd,">>db_file<<",structure,tag,self.override_default_vasp_params)

        t.append(CheckSymmetryToDb(db_file=">>db_file<<", tag=tag, site_properties=site_properties))
        super(StaticFW, self).__init__(t, parents=parents, name="{}-{}".format(
            structure.composition.reduced_formula, name), **kwargs)
Beispiel #3
0
    def __init__(self, structure, scale_lattice=None, isif=4, override_symmetry_tolerances=None, 
                 name="structure optimization", vasp_input_set=None, job_type="normal", vasp_cmd="vasp", 
                 metadata=None, override_default_vasp_params=None, db_file=None, record_path=False, 
                 prev_calc_loc=True, parents=None, db_insert=False, tag=None,
                 run_isif2=False, pass_isif4=False, force_gamma=True, store_volumetric_data=False,
                 modify_incar=None, modify_incar_params={}, modify_kpoints_params={}, **kwargs):

        metadata = metadata or {}
        tag = tag or metadata.get('tag')
        # generate a tag with a warning
        if tag is None:
            tag = str(uuid4())
            metadata['tag'] = tag
        metadata.update({'tag': tag})

        if isinstance(store_volumetric_data, (list, tuple)):
            store_volumetric_data = store_volumetric_data
        elif isinstance(store_volumetric_data, bool):
            if store_volumetric_data:
                store_volumetric_data = STORE_VOLUMETRIC_DATA
            else:
                store_volumetric_data = ()
        else:
            raise ValueError('The store_volumetric_data should be list or bool')

        override_default_vasp_params = override_default_vasp_params or {}
        override_symmetry_tolerances = override_symmetry_tolerances or {}
        vasp_input_set = vasp_input_set or RelaxSet(structure, isif=isif, force_gamma=force_gamma,
                                                       **override_default_vasp_params)
        site_properties = deepcopy(structure).site_properties

        t = []
        # Avoids delivery (prev_calc_loc == '' (instead by True))
        if type(prev_calc_loc) == str:
            t.append(CopyVaspOutputs(calc_dir=prev_calc_loc, contcar_to_poscar=True))
            t.append(WriteVaspFromIOSetPrevStructure(vasp_input_set=vasp_input_set, site_properties=site_properties))
        elif parents:
            if prev_calc_loc:
                t.append(CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True))
            t.append(WriteVaspFromIOSetPrevStructure(vasp_input_set=vasp_input_set, site_properties=site_properties))
        else:
        #vasp_input_set = vasp_input_set or RelaxSet(structure)  # ??
            t.append(WriteVaspFromIOSetPrevStructure(structure=structure, vasp_input_set=vasp_input_set, site_properties=site_properties))
        if scale_lattice is not None:
            t.append(ScaleVolumeTransformation(scale_factor=scale_lattice, structure=structure))
        t.append(ModifyIncar(incar_update=">>incar_update<<"))
        if modify_incar != None:
             t.append(ModifyIncar(incar_update=modify_incar))
        t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, job_type=job_type, gzip_output=False))
        t.append(PassCalcLocs(name=name))
        if record_path:
            t.append(Record_relax_running_path(db_file = db_file, metadata = metadata, run_isif2=run_isif2, pass_isif4=pass_isif4))
        if db_insert:
            t.append(VaspToDb(db_file=db_file, additional_fields={"task_label": name, "metadata": metadata}, store_volumetric_data=store_volumetric_data))
        t.append(CheckSymmetryToDb(db_file=db_file, tag=tag, override_symmetry_tolerances=override_symmetry_tolerances, site_properties=site_properties))
        super(OptimizeFW, self).__init__(t, parents=parents, name="{}-{}".format(structure.composition.reduced_formula, name), **kwargs)
Beispiel #4
0
def add_modify_incar(original_wf,
                     modify_incar_params=None,
                     fw_name_constraint=None):
    """
    Every FireWork that runs VASP has a ModifyIncar task just beforehand. For example, allows
    you to modify the INCAR based on the Worker using env_chk or using hard-coded changes.

    Args:
        original_wf (Workflow)
        modify_incar_params (dict) - dict of parameters for ModifyIncar.
        fw_name_constraint (str) - Only apply changes to FWs where fw_name contains this substring.

    Returns:
       Workflow
    """
    modify_incar_params = modify_incar_params or {
        "incar_update": ">>incar_update<<"
    }
    for idx_fw, idx_t in get_fws_and_tasks(
            original_wf,
            fw_name_constraint=fw_name_constraint,
            task_name_constraint="RunVasp"):
        original_wf.fws[idx_fw].tasks.insert(
            idx_t, ModifyIncar(**modify_incar_params))
    return original_wf
Beispiel #5
0
    def test_modify_incar(self):
        # create an INCAR
        incar = self.ref_incar
        incar.write_file("INCAR")

        # modify and test
        ft = ModifyIncar(
            {"incar_update": {"ISMEAR": 1000}, "incar_multiply": {"ENCUT": 1.5},
             "incar_dictmod": {"_inc": {"ISPIN": -1}}})
        ft = load_object(ft.to_dict())  # simulate database insertion
        ft.run_task({})

        incar_mod = Incar.from_file("INCAR")
        self.assertEqual(incar_mod['ISMEAR'], 1000)
        self.assertEqual(incar_mod['ENCUT'], 780)
        self.assertEqual(incar_mod['ISPIN'], 1)
Beispiel #6
0
    def __init__(self,
                 structure,
                 scale_lattice=None,
                 name="static",
                 vasp_input_set=None,
                 vasp_cmd="vasp",
                 metadata=None,
                 prev_calc_loc=True,
                 db_file=None,
                 parents=None,
                 **kwargs):

        # TODO: @computron - I really don't like how you need to set the structure even for
        # prev_calc_loc jobs. Sometimes it makes appending new FWs to an existing workflow
        # difficult. Maybe think about how to remove this need? -computron
        metadata = metadata or {}
        vasp_input_set = vasp_input_set or StaticSet(structure)
        site_properties = deepcopy(structure).site_properties

        t = []

        if parents:
            if prev_calc_loc:
                t.append(
                    CopyVaspOutputs(calc_loc=prev_calc_loc,
                                    contcar_to_poscar=True))
            t.append(
                WriteVaspFromIOSetPrevStructure(
                    vasp_input_set=vasp_input_set,
                    site_properties=site_properties))
        else:
            t.append(
                WriteVaspFromIOSet(structure=structure,
                                   vasp_input_set=vasp_input_set))
        if scale_lattice is not None:
            t.append(ScaleVolumeTransformation(scale_factor=scale_lattice))
        t.append(ModifyIncar(incar_update=">>incar_update<<"))
        t.append(
            RunVaspCustodian(vasp_cmd=vasp_cmd,
                             auto_npar=">>auto_npar<<",
                             gzip_output=False))
        t.append(PassCalcLocs(name=name))
        t.append(
            VaspToDb(
                db_file=db_file,
                parse_dos=True,
                additional_fields={
                    "task_label": name,
                    "metadata": metadata
                },
            ))
        super(StaticFW,
              self).__init__(t,
                             parents=parents,
                             name="{}-{}".format(
                                 structure.composition.reduced_formula, name),
                             **kwargs)
Beispiel #7
0
    def run_task(self, fw_spec):

        prev_checkpoint_dirs = fw_spec.get(
            "checkpoint_dirs",
            [])  # If this is the first spawn, have no prev dirs
        prev_checkpoint_dirs.append(os.getcwd(
        ))  # add the current directory to the list of checkpoints

        vasp_cmd = self["vasp_cmd"]
        wall_time = self["wall_time"]
        db_file = self.get("db_file", None)
        spawn_count = self["spawn_count"]
        production = self['production']
        num_checkpoints = production.get('num_checkpoints', 1)
        incar_update = production.get('incar_update', None)

        if spawn_count > num_checkpoints:
            logger.info(
                "LOGGER: Production run completed. Took {} spawns total".
                format(spawn_count))
            return FWAction(stored_data={'production_run_completed': True})

        else:
            name = ("ProductionRun" + str(abs(spawn_count)))

            logger.info("LOGGER: Starting spawn {} of production run".format(
                spawn_count))

            t = []

            t.append(
                CopyVaspOutputs(calc_dir=os.getcwd(), contcar_to_poscar=True))

            if incar_update:
                t.append(ModifyIncar(incar_update=incar_update))

            t.append(
                RunVaspCustodian(vasp_cmd=vasp_cmd,
                                 gamma_vasp_cmd=">>vasp_gam<<",
                                 handler_group="md",
                                 wall_time=wall_time))
            t.append(
                ProductionSpawnTask(wall_time=wall_time,
                                    vasp_cmd=vasp_cmd,
                                    db_file=db_file,
                                    spawn_count=spawn_count + 1,
                                    production=production))
            new_fw = Firework(t,
                              name=name,
                              spec={'checkpoint_dirs': prev_checkpoint_dirs})

            return FWAction(
                stored_data={'production_run_completed': False},
                update_spec={'checkpoint_dirs': prev_checkpoint_dirs},
                detours=[new_fw])
Beispiel #8
0
 def __init__(self,
              structure,
              name="structure optimization",
              vasp_input_set=None,
              job_type="normal",
              vasp_cmd="vasp",
              isif=None,
              metadata=None,
              override_default_vasp_params=None,
              db_file=None,
              force_gamma=True,
              parents=None,
              **kwargs):
     """
     Optimize the given structure.
     Args:
         structure (Structure): Input structure.
         name (str): Name for the Firework.
         vasp_input_set (VaspInputSet): input set to use. Defaults to MPRelaxSet() if None.
         override_default_vasp_params (dict): If this is not None, these params are passed to
             the default vasp_input_set, i.e., MPRelaxSet. This allows one to easily override
             some settings, e.g., user_incar_settings, etc.
         isif : int
             Shortcut to override the ISIF parameter. Defaults to None.
             Will take precedent over override_default_vasp_params
         vasp_cmd (str): Command to run vasp.
         db_file (str): Path to file specifying db credentials to place output parsing.
         force_gamma (bool): Force gamma centered kpoint generation
         parents ([Firework]): Parents of this particular Firework.
         \*\*kwargs: Other kwargs that are passed to Firework.__init__.
     """
     metadata = metadata or {}
     override_default_vasp_params = override_default_vasp_params or {}
     vasp_input_set = vasp_input_set or PRLRelaxSet(
         structure, force_gamma=force_gamma, **override_default_vasp_params)
     t = []
     t.append(
         WriteVaspFromIOSet(structure=structure,
                            vasp_input_set=vasp_input_set))
     if isif:
         t.append(ModifyIncar(incar_update={'ISIF': isif}))
     t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, job_type=job_type))
     t.append(PassCalcLocs(name=name))
     t.append(
         VaspToDb(db_file=db_file,
                  additional_fields={
                      "task_label": name,
                      "metadata": metadata
                  }))
     super(OptimizeFW,
           self).__init__(t,
                          parents=parents,
                          name="{}-{}".format(
                              structure.composition.reduced_formula, name),
                          **kwargs)
Beispiel #9
0
    def test_modify_incar(self):
        # create an INCAR
        incar = self.ref_incar
        incar.write_file("INCAR")

        # modify and test
        ft = ModifyIncar(
            incar_update={"ISMEAR": 1000},
            incar_multiply={"ENCUT": 1.5},
            incar_dictmod={"_inc": {
                "ISPIN": -1
            }},
        )
        ft = load_object(ft.to_dict())  # simulate database insertion
        ft.run_task({})

        incar_mod = Incar.from_file("INCAR")
        self.assertEqual(incar_mod["ISMEAR"], 1000)
        self.assertEqual(incar_mod["ENCUT"], 780)
        self.assertEqual(incar_mod["ISPIN"], 1)
Beispiel #10
0
    def __init__(self, structure, isif=7, name="structure optimization", isif4=False, level=1,
                 override_symmetry_tolerances=None, job_type="normal", vasp_input_set=None,
                 vasp_cmd="vasp", metadata=None, override_default_vasp_params=None, db_file=None,
                 prev_calc_loc=True, parents=None, db_insert=False, tag=None, modify_incar_params={},
                 modify_kpoints_params={}, energy_with_isif={}, store_volumetric_data=False, 
                 **kwargs):
        metadata = metadata or {}
        tag = tag or metadata.get('tag')
        # generate a tag with a warning
        if tag is None:
            tag = str(uuid4())
            metadata['tag'] = tag

        if isinstance(store_volumetric_data, (list, tuple)):
            store_volumetric_data = store_volumetric_data
        elif isinstance(store_volumetric_data, bool):
            if store_volumetric_data:
                store_volumetric_data = STORE_VOLUMETRIC_DATA
            else:
                store_volumetric_data = ()
        else:
            raise ValueError('The store_volumetric_data should be list or bool')

        override_default_vasp_params = override_default_vasp_params or {}
        override_symmetry_tolerances = override_symmetry_tolerances or {}
        vasp_input_set = vasp_input_set or RelaxSet(structure, isif=isif, **override_default_vasp_params)
        site_properties = deepcopy(structure).site_properties

        t = []
        if parents:
            if prev_calc_loc:
                t.append(CopyVaspOutputs(calc_loc=prev_calc_loc, contcar_to_poscar=True))
            t.append(WriteVaspFromIOSetPrevStructure(vasp_input_set=vasp_input_set, site_properties=site_properties))
        else:
            t.append(WriteVaspFromIOSetPrevStructure(structure=structure, vasp_input_set=vasp_input_set, site_properties=site_properties))
        t.append(ModifyIncar(incar_update=">>incar_update<<"))
        t.append(RunVaspCustodian(vasp_cmd=vasp_cmd, job_type=job_type, gzip_output=False))
        t.append(PassCalcLocs(name=name))
        if db_insert:
            t.append(VaspToDb(db_file=">>db_file<<", additional_fields={"task_label": name, "metadata": metadata}, store_volumetric_data=store_volumetric_data))
        t.append(CheckSymmetryToDb(db_file=">>db_file<<", tag=tag, site_properties=site_properties))

        common_kwargs = {'vasp_cmd': vasp_cmd, 'db_file': ">>db_file<<", "metadata": metadata, "tag": tag,
                         'override_default_vasp_params': override_default_vasp_params}
        static_kwargs = {}
        relax_kwargs = {}
        t.append(CheckRelaxation(db_file=">>db_file<<", metadata=metadata, tag=tag, isif4=isif4, level=level, energy_with_isif=energy_with_isif,
                                 common_kwargs=common_kwargs, relax_kwargs=relax_kwargs, static_kwargs=static_kwargs, site_properties=site_properties,
                                 store_volumetric_data=store_volumetric_data, 
                                 **override_symmetry_tolerances))
        super().__init__(t, parents=parents, name="{}-{}".format(structure.composition.reduced_formula, name), **kwargs)
Beispiel #11
0
def modify_to_soc(original_wf, nbands, structure=None, modify_incar_params=None, fw_name_constraint=None):
    """
    Takes a regular workflow and transforms its VASP fireworkers that are specified with
    fw_name_constraints to non-collinear calculations taking spin orbit coupling into account.

    Args:
        original_wf (Workflow)
        nbands (int): number of bands selected by the user (for now)
        structure (Structure)
        modify_incar_params ({}): a dictionary containing the setting for modyfining the INCAR (e.g. {"ICHARG": 11})
        fw_name_constraint (string): name of the fireworks to be modified (all if None is passed)

    Returns:
        Workflow: modified with SOC
    """

    if structure is None:
        try:
            sid = get_fws_and_tasks(original_wf, fw_name_constraint="structure optimization",
                                    task_name_constraint="WriteVasp")
            fw_id = sid[0][0]
            task_id = sid[0][1]
            structure = original_wf.fws[fw_id].tasks[task_id]["vasp_input_set"].structure
        except:
            raise ValueError("modify_to_soc powerup requires the structure in vasp_input_set")

    magmom = ""
    for _ in structure:
        magmom += "0 0 0.6 "
    # TODO: add saxis as an input parameter with default being (0 0 1)
    modify_incar_params = modify_incar_params or {"incar_update": {"LSORBIT": "T", "NBANDS":
                                                                   nbands, "MAGMOM": magmom, "ISPIN": 1, "LMAXMIX": 4, "ISYM": 0}}

    for idx_fw, idx_t in get_fws_and_tasks(original_wf, fw_name_constraint=fw_name_constraint,
                                           task_name_constraint="RunVasp"):
        original_wf.fws[idx_fw].tasks[idx_t]["vasp_cmd"] = ">>vasp_ncl<<"
        original_wf.fws[idx_fw].tasks.insert(idx_t, ModifyIncar(**modify_incar_params))

        original_wf.fws[idx_fw].name += " soc"

    for idx_fw, idx_t in get_fws_and_tasks(original_wf, fw_name_constraint=fw_name_constraint,
                                           task_name_constraint="RunBoltztrap"):
        original_wf.fws[idx_fw].name += " soc"

    return original_wf
Beispiel #12
0
    def __init__(self,
                 structure,
                 symmetry_tolerance=None,
                 name="structure optimization",
                 vasp_input_set=None,
                 job_type="normal",
                 vasp_cmd="vasp",
                 metadata=None,
                 override_default_vasp_params=None,
                 db_file=None,
                 force_gamma=True,
                 prev_calc_loc=True,
                 parents=None,
                 db_insert=False,
                 **kwargs):

        metadata = metadata or {}
        override_default_vasp_params = override_default_vasp_params or {}
        vasp_input_set = vasp_input_set or RelaxSet(
            structure, force_gamma=force_gamma, **override_default_vasp_params)
        site_properties = deepcopy(structure).site_properties

        t = []
        if parents:
            if prev_calc_loc:
                t.append(
                    CopyVaspOutputs(calc_loc=prev_calc_loc,
                                    contcar_to_poscar=True))
            t.append(
                WriteVaspFromIOSetPrevStructure(
                    vasp_input_set=vasp_input_set,
                    site_properties=site_properties))
        else:
            vasp_input_set = vasp_input_set or RelaxSet(structure)
            t.append(
                WriteVaspFromIOSet(structure=structure,
                                   vasp_input_set=vasp_input_set))
        t.append(ModifyIncar(incar_update=">>incar_update<<"))
        t.append(
            RunVaspCustodian(vasp_cmd=vasp_cmd,
                             job_type=job_type,
                             gzip_output=False))
        t.append(PassCalcLocs(name=name))
        if db_insert:
            t.append(
                VaspToDb(db_file=db_file,
                         additional_fields={
                             "task_label": name,
                             "metadata": metadata
                         }))
        # This has to happen at the end because dynamically adding Fireworks if the symmetry breaks skips the rest of the tasks in the Firework.
        if symmetry_tolerance is not None:
            t.append(
                CheckSymmetry(tolerance=symmetry_tolerance,
                              vasp_cmd=vasp_cmd,
                              db_file=db_file,
                              structure=structure,
                              metadata=metadata,
                              name=name))
        super(OptimizeFW,
              self).__init__(t,
                             parents=parents,
                             name="{}-{}".format(
                                 structure.composition.reduced_formula, name),
                             **kwargs)
Beispiel #13
0
    def __init__(self,
                 structure,
                 scale_lattice=None,
                 symmetry_tolerance=None,
                 name="structure optimization",
                 vasp_input_set=None,
                 job_type="normal",
                 vasp_cmd="vasp",
                 metadata=None,
                 override_default_vasp_params=None,
                 db_file=None,
                 record_path=False,
                 modify_incar=None,
                 force_gamma=True,
                 prev_calc_loc=True,
                 parents=None,
                 db_insert=False,
                 Pos_Shape_relax=False,
                 modify_incar_params={},
                 modify_kpoints_params={},
                 **kwargs):

        metadata = metadata or {}
        override_default_vasp_params = override_default_vasp_params or {}
        vasp_input_set = vasp_input_set or RelaxSet(
            structure, force_gamma=force_gamma, **override_default_vasp_params)
        site_properties = deepcopy(structure).site_properties

        t = []
        # Avoids delivery (prev_calc_loc == '' (instead by True))
        if type(prev_calc_loc) == str:
            t.append(
                CopyVaspOutputs(calc_dir=prev_calc_loc,
                                contcar_to_poscar=True))
            t.append(
                WriteVaspFromIOSetPrevStructure(
                    vasp_input_set=vasp_input_set,
                    site_properties=site_properties))
        elif parents:
            if prev_calc_loc:
                t.append(
                    CopyVaspOutputs(calc_loc=prev_calc_loc,
                                    contcar_to_poscar=True))
            t.append(
                WriteVaspFromIOSetPrevStructure(
                    vasp_input_set=vasp_input_set,
                    site_properties=site_properties))
        else:
            #            vasp_input_set = vasp_input_set or RelaxSet(structure)  # ??
            t.append(
                WriteVaspFromIOSet(structure=structure,
                                   vasp_input_set=vasp_input_set))
        if scale_lattice is not None:
            t.append(ScaleVolumeTransformation(scale_factor=scale_lattice))
        t.append(ModifyIncar(incar_update=">>incar_update<<"))
        if modify_incar != None:
            t.append(ModifyIncar(incar_update=modify_incar))
        t.append(
            RunVaspCustodian(vasp_cmd=vasp_cmd,
                             job_type=job_type,
                             gzip_output=False))
        t.append(PassCalcLocs(name=name))
        if record_path:
            t.append(
                Record_relax_running_path(db_file=db_file,
                                          metadata=metadata,
                                          Pos_Shape_relax=Pos_Shape_relax))
        if db_insert:
            t.append(
                VaspToDb(db_file=db_file,
                         additional_fields={
                             "task_label": name,
                             "metadata": metadata
                         }))
        # This has to happen at the end because dynamically adding Fireworks if the symmetry breaks skips the rest of the tasks in the Firework.
        if symmetry_tolerance is not None:
            t.append(
                CheckSymmetry(tolerance=symmetry_tolerance,
                              vasp_cmd=vasp_cmd,
                              db_file=db_file,
                              structure=structure,
                              metadata=metadata,
                              name=name,
                              modify_incar_params=modify_incar_params,
                              modify_kpoints_params=modify_kpoints_params,
                              Pos_Shape_relax=Pos_Shape_relax))
        super(OptimizeFW,
              self).__init__(t,
                             parents=parents,
                             name="{}-{}".format(
                                 structure.composition.reduced_formula, name),
                             **kwargs)
Beispiel #14
0
    def __init__(
        self,
        structure=None,
        name="SCAN structure optimization",
        vasp_input_set=None,
        vasp_input_set_params=None,
        vasp_cmd=VASP_CMD,
        vdw_kernel_dir=VDW_KERNEL_DIR,
        prev_calc_loc=None,
        prev_calc_dir=None,
        db_file=DB_FILE,
        vasptodb_kwargs=None,
        parents=None,
        **kwargs,
    ):
        """
        Structure optimization using the SCAN metaGGA functional. If this Firework is
        initialized with no parents, it will perform a GGA optimization of the provided
        structure using the PBESol functional. This GGA-relaxed structure is intended
        to be passed to a second instance of this Firework for optimization with SCAN.
        (see workflow definition in SCAN_optimization.yaml)

        Args:
            structure (Structure): Input structure. Note that for prev_calc_loc jobs, the structure
                is only used to set the name of the FW and any structure with the same composition
                can be used.
            name (str): Name for the Firework.
            vasp_input_set (VaspInputSet): input set to use (for jobs w/no parents)
                Defaults to MpScanRelaxSet() if None.
            vasp_input_set_params (dict): Dict of vasp_input_set kwargs.
            vasp_cmd (str): Command to run vasp.
            vdw_kernel_dir (str): Directory containing the pre-compiled VdW
                kernel. Supports env_chk.
            prev_calc_loc (bool or str): If true (default), copies outputs from previous calc. If
                a str value, retrieves a previous calculation output by name. If False/None, will create
                new SCAN calculation using the provided structure.
            prev_calc_dir (str): Path to a previous calculation to copy from
            db_file (str): Path to file specifying db credentials.
            parents (Firework): Parents of this particular Firework. FW or list of FWs.
            vasptodb_kwargs (dict): kwargs to pass to VaspToDb
            **kwargs: Other kwargs that are passed to Firework.__init__.
        """
        t = []

        vasp_input_set_params = vasp_input_set_params or {}
        vasptodb_kwargs = vasptodb_kwargs or {}
        if "additional_fields" not in vasptodb_kwargs:
            vasptodb_kwargs["additional_fields"] = {}
        vasptodb_kwargs["additional_fields"]["task_label"] = name

        fw_name = "{}-{}".format(
            structure.composition.reduced_formula if structure else "unknown",
            name)

        has_previous_calc = False

        # Raise a warning if the InputSet is not MPScanRelaxSet, because the
        # kspacing calculation from bandgap is only supported in MPScanRelaxSet.
        if vasp_input_set and not isinstance(vasp_input_set, MPScanRelaxSet):
            raise UserWarning("You have specified a vasp_input_set other than \
                 MPScanRelaxSet. Automatic adjustment of kspacing\
                 is not supported by this InputSet.")

        if prev_calc_dir:
            has_previous_calc = True
            # Copy the CHGCAR from previous calc directory (usually PBE)
            t.append(
                CopyVaspOutputs(
                    calc_dir=prev_calc_dir,
                    contcar_to_poscar=True,
                    additional_files=["CHGCAR"],
                ))
        elif parents:
            if prev_calc_loc:
                has_previous_calc = True
                # Copy the CHGCAR from previous calc location (usually PBE)
                t.append(
                    CopyVaspOutputs(
                        calc_loc=prev_calc_loc,
                        contcar_to_poscar=True,
                        additional_files=["CHGCAR"],
                    ))
            else:
                raise UserWarning(
                    "You specified parent Firework but did not provide its location. Set "
                    "prev_calc_dir or prev_calc_loc and try again.")
        elif prev_calc_loc:
            raise UserWarning(
                "You specified prev_calc_loc but did not provide a parent Firework. Set "
                "parents and try again.")

        if has_previous_calc:
            # Update the InputSet with the bandgap from the previous calc
            t.append(
                WriteScanRelaxFromPrev(
                    vasp_input_set_params=vasp_input_set_params))

            # Set ICHARG to 1 to utilize the pre-existing CHGCAR
            settings = {"_set": {"ICHARG": 1}}

            if vasp_input_set_params.get("vdw"):
                # Copy the pre-compiled VdW kernel for VASP
                t.append(
                    CopyFiles(files_to_copy=["vdw_kernel.bindat"],
                              from_dir=vdw_kernel_dir))

                # Enable vdW for the SCAN step
                settings["_set"]["LUSE_VDW"] = True
                settings["_set"]["BPARAM"] = 15.7

            t.append(ModifyIncar(incar_dictmod=settings))

            # use the 'scan' custodian handler group
            handler_group = "scan"

        elif structure:
            vasp_input_set = vasp_input_set or MPScanRelaxSet(
                structure, **vasp_input_set_params)
            t.append(
                WriteVaspFromIOSet(structure=structure,
                                   vasp_input_set=vasp_input_set))
            # Update the INCAR for the PBESol GGA preconditioning step
            pre_opt_settings = {
                "_set": {
                    "GGA": "Ps",
                    "METAGGA": None,
                    "EDIFFG": -0.05
                }
            }

            # Disable vdW for the precondition step
            if vasp_input_set_params.get("vdw"):
                pre_opt_settings.update(
                    {"_unset": {
                        "LUSE_VDW": True,
                        "BPARAM": 15.7
                    }})

            t.append(ModifyIncar(incar_dictmod=pre_opt_settings))

            # use the 'default' custodian handler group
            handler_group = "default"
        else:
            raise ValueError("Must specify structure or previous calculation")

        # Run VASP
        t.append(
            RunVaspCustodian(
                vasp_cmd=vasp_cmd,
                auto_npar=">>auto_npar<<",
                handler_group=handler_group,
                gzip_output=False,
            ))
        t.append(PassCalcLocs(name=name))
        # Parse
        t.append(VaspToDb(db_file=db_file, **vasptodb_kwargs))
        # Delete the VdW kernel
        t.append(DeleteFiles(files=["vdw_kernel.bindat"]))
        # zip the output (don't rely on custodian to do it)
        t.append(GzipDir())

        super().__init__(t, parents=parents, name=fw_name, **kwargs)
Beispiel #15
0
    def __init__(self,
                 structure,
                 isif=4,
                 name="structure optimization",
                 override_symmetry_tolerances=None,
                 job_type="normal",
                 vasp_cmd="vasp_std",
                 metadata=None,
                 override_default_vasp_params=None,
                 db_file=None,
                 prev_calc_loc=True,
                 parents=None,
                 db_insert=False,
                 tag=None,
                 **kwargs):

        metadata = metadata or {}
        metadata = metadata or {}
        tag = tag or metadata.get('tag')
        # generate a tag with a warning
        if tag is None:
            tag = str(uuid4())
            metadata['tag'] = tag

        override_default_vasp_params = override_default_vasp_params or {}
        override_symmetry_tolerances = override_symmetry_tolerances or {}
        vasp_input_set = RelaxSet(structure,
                                  isif=isif,
                                  **override_default_vasp_params)
        site_properties = deepcopy(structure).site_properties

        t = []
        if parents:
            if prev_calc_loc:
                t.append(
                    CopyVaspOutputs(calc_loc=prev_calc_loc,
                                    contcar_to_poscar=True))
            t.append(
                WriteVaspFromIOSetPrevStructure(
                    vasp_input_set=vasp_input_set,
                    site_properties=site_properties))
        else:
            t.append(
                WriteVaspFromIOSet(structure=structure,
                                   vasp_input_set=vasp_input_set))
        t.append(ModifyIncar(incar_update=">>incar_update<<"))
        t.append(
            RunVaspCustodian(vasp_cmd=vasp_cmd,
                             job_type=job_type,
                             gzip_output=False))
        t.append(PassCalcLocs(name=name))
        if db_insert:
            t.append(
                VaspToDb(db_file=db_file,
                         additional_fields={
                             "task_label": name,
                             "metadata": metadata
                         }))
        common_kwargs = {
            'vasp_cmd': vasp_cmd,
            'db_file': db_file,
            "metadata": metadata,
            "tag": tag
        }
        relax_kwargs = {}
        static_kwargs = {}
        t.append(
            CheckRelaxation(db_file=db_file,
                            metadata=metadata,
                            tag=tag,
                            common_kwargs=common_kwargs,
                            relax_kwargs=relax_kwargs,
                            static_kwargs=static_kwargs,
                            **override_symmetry_tolerances))
        super().__init__(t,
                         parents=parents,
                         name="{}-{}".format(
                             structure.composition.reduced_formula, name),
                         **kwargs)