Ejemplo n.º 1
0
def test_check_symbol():
    struc = Structure.from_str(POSCAR_STR_check_symbol, fmt="POSCAR")
    magmoms = [4.0, 4.0, -4.0, -4.0]
    struc.add_site_property("magmom", magmoms)
    InputSet = RelaxSet(struc)
    symbols, natom = dfttkutils.check_symbol(InputSet)
    assert (symbols == ["Fe", "Fe"])
    assert (natom == ["2", "2"])
Ejemplo n.º 2
0
def test_update_pot_by_symbols():
    struc = Structure.from_str(POSCAR_STR_check_symbol, fmt="POSCAR")
    magmoms = [4.0, 4.0, -4.0, -4.0]
    struc.add_site_property("magmom", magmoms)
    InputSet = RelaxSet(struc)
    potcar = dfttkutils.update_pot_by_symbols(InputSet, write_file=False)
    syms = potcar.symbols
    assert (syms == ["Fe", "Fe"])
Ejemplo n.º 3
0
    def run_task(self, fw_spec):
        # unrelaxed cell
        cell = Structure.from_file('POSCAR')
        cell.to(filename='str.out', fmt='mcsqs')

        # relaxed cell
        cell = Structure.from_file('CONTCAR')
        cell.to(filename='str_relax.out', fmt='mcsqs')

        # check the symmetry
        out = subprocess.run(['checkrelax', '-1'], stdout=subprocess.PIPE)
        relaxation = float(out.stdout)

        # we relax too much, add a volume relax and inflection detection WF as a detour
        if relaxation > self['tolerance']:
            from dfttk.fworks import OptimizeFW, InflectionDetectionFW
            from fireworks import Workflow
            from dfttk.input_sets import RelaxSet
            from dfttk.utils import add_modify_incar_by_FWname, add_modify_kpoints_by_FWname

            fws = []
            vis = RelaxSet(self.get('structure'), volume_relax=True)
            vol_relax_fw = OptimizeFW(
                self.get('structure'),
                symmetry_tolerance=None,
                job_type='normal',
                name='Volume relax',  #record_path = True, 
                vasp_input_set=vis,
                modify_incar={'ISIF': 7},
                vasp_cmd=self.get('vasp_cmd'),
                db_file=self.get('db_file'),
                metadata=self.get('metadata'),
            )
            fws.append(vol_relax_fw)

            modify_incar_params = self.get('modify_incar_params')
            modify_kpoints_params = self.get('modify_kpoints_params')

            # we have to add the calc locs for this calculation by hand
            # because the detour action seems to disable spec mods
            fws.append(
                InflectionDetectionFW(
                    self.get('structure'),
                    parents=[vol_relax_fw],
                    Pos_Shape_relax=self.get('Pos_Shape_relax') or False,
                    metadata=self.get('metadata'),
                    db_file=self.get('db_file'),
                    spec={
                        'calc_locs':
                        extend_calc_locs(self.get('name', 'Full relax'),
                                         fw_spec)
                    }))
            infdet_wf = Workflow(fws)
            add_modify_incar_by_FWname(infdet_wf,
                                       modify_incar_params=modify_incar_params)
            add_modify_kpoints_by_FWname(
                infdet_wf, modify_kpoints_params=modify_kpoints_params)
            return FWAction(detours=[infdet_wf])
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
def test_update_pos_by_symbols():
    struc = Structure.from_str(POSCAR_STR_check_symbol, fmt="POSCAR")
    magmoms = [4.0, 4.0, -4.0, -4.0]
    struc.add_site_property("magmom", magmoms)
    InputSet = RelaxSet(struc)
    poscar_str = dfttkutils.update_pos_by_symbols(InputSet, write_file=False)
    syms = poscar_str.split("\n")[5]
    natom = poscar_str.split("\n")[6]
    assert (syms == "Fe Fe")
    assert (natom == "2 2")
Ejemplo n.º 6
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)
Ejemplo n.º 7
0
def get_wf_gibbs(structure,
                 num_deformations=7,
                 deformation_fraction=(-0.1, 0.1),
                 run_isif2=False,
                 phonon=False,
                 phonon_supercell_matrix=None,
                 pass_isif4=False,
                 t_min=5,
                 t_max=2000,
                 t_step=5,
                 tolerance=0.01,
                 volume_spacing_min=0.03,
                 vasp_cmd=None,
                 db_file=None,
                 metadata=None,
                 name='EV_QHA',
                 symmetry_tolerance=0.05,
                 passinitrun=False,
                 relax_path='',
                 modify_incar_params={},
                 modify_kpoints_params={},
                 verbose=False,
                 store_volumetric_data=False):
    """
    E - V
    curve

    workflow
    Parameters
    ------
    structure: pymatgen.Structure
    num_deformations: int
    deformation_fraction: float
        Can be a float (a single value) or a 2-type of a min,max deformation fraction.
        Default is (-0.05, 0.1) leading to volumes of 0.95-1.10. A single value gives plus/minus
        by default.
    phonon : bool
        Whether to do a phonon calculation. Defaults to False, meaning the Debye model.
    phonon_supercell_matrix : list
        3x3 array of the supercell matrix, e.g. [[2,0,0],[0,2,0],[0,0,2]]. Must be specified if phonon is specified.
    t_min : float
        Minimum temperature
    t_step : float
        Temperature step size
    t_max : float
        Maximum temperature (inclusive)
    tolerance: float
        Acceptable value for average RMS, recommend >= 0.005.
    volume_spacing_min: float
        Minimum ratio of Volumes spacing
    vasp_cmd : str
        Command to run VASP. If None (the default) is passed, the command will be looked up in the FWorker.
    db_file : str
        Points to the database JSON file. If None (the default) is passed, the path will be looked up in the FWorker.
    name : str
        Name of the workflow
    metadata : dict
        Metadata to include
    passinitrun : bool
        Set True to pass initial VASP running if the results exist in DB, use carefully to keep data consistent.
    relax_path : str
        Set the path already exists for new static calculations; if set as '', will try to get the path from db_file.
    modify_incar_params : dict
        User can use these params to modify the INCAR set. It is a dict of class ModifyIncar with keywords in Workflow name.
    modify_kpoints_params : dict
        User can use these params to modify the KPOINTS set. It is a dict of class ModifyKpoints with keywords in Workflow name.
        Only 'kpts' supported now.
    run_isif2: bool
        Whether run isif=2 calculation before isif=4 running.
    pass_isif4: bool
        Whether pass isif=4 calculation.
   """
    vasp_cmd = vasp_cmd or VASP_CMD
    db_file = db_file or DB_FILE

    if db_file == ">>db_file<<":
        #In PengGao's version, some function used the absolute db_file
        from fireworks.fw_config import config_to_dict
        from monty.serialization import loadfn
        db_file = loadfn(config_to_dict()["FWORKER_LOC"])["env"]["db_file"]

    site_properties = deepcopy(structure).site_properties

    metadata = metadata or {}
    tag = metadata.get('tag', '{}'.format(str(uuid4())))

    if isinstance(deformation_fraction, (list, tuple)):
        deformations = np.linspace(1 + deformation_fraction[0],
                                   1 + deformation_fraction[1],
                                   num_deformations)
        vol_spacing = max((deformation_fraction[1] - deformation_fraction[0]) /
                          (num_deformations - 0.999999) + 0.001,
                          volume_spacing_min)
    else:
        deformations = np.linspace(1 - deformation_fraction,
                                   1 + deformation_fraction, num_deformations)
        vol_spacing = max(
            deformation_fraction / (num_deformations - 0.999999) * 2 + 0.001,
            volume_spacing_min)

    fws = []
    if 'tag' not in metadata.keys():
        metadata['tag'] = tag
    relax_path, run_isif2, pass_isif4 = check_relax_path(
        relax_path, db_file, tag, run_isif2, pass_isif4)

    if (relax_path == ''):
        # follow a scheme of
        # 1. Full relax + symmetry check
        # 2. If symmetry check fails, detour to 1. Volume relax, 2. inflection detection
        # 3. Inflection detection
        # 4. Static EV
        # 5. Phonon EV
        # for each FW, we set the structure to the original structure to verify to ourselves that the
        # volume deformed structure is set by input set.

        vis_relax = RelaxSet(structure)
        print('Full relax will be running ...')
        full_relax_fw = OptimizeFW(structure,
                                   symmetry_tolerance=symmetry_tolerance,
                                   job_type='normal',
                                   name='Full relax',
                                   prev_calc_loc=False,
                                   vasp_input_set=vis_relax,
                                   vasp_cmd=vasp_cmd,
                                   db_file=db_file,
                                   metadata=metadata,
                                   record_path=True,
                                   run_isif2=run_isif2,
                                   pass_isif4=pass_isif4,
                                   modify_incar_params=modify_incar_params,
                                   modify_kpoints_params=modify_kpoints_params,
                                   store_volumetric_data=store_volumetric_data,
                                   spec={'_preserve_fworker': True})
        fws.append(full_relax_fw)
    else:
        full_relax_fw = None

    check_result = Firework(
        EVcheck_QHA(db_file=db_file,
                    tag=tag,
                    relax_path=relax_path,
                    deformations=deformations,
                    site_properties=site_properties,
                    tolerance=tolerance,
                    threshold=14,
                    vol_spacing=vol_spacing,
                    vasp_cmd=vasp_cmd,
                    metadata=metadata,
                    t_min=t_min,
                    t_max=t_max,
                    t_step=t_step,
                    phonon=phonon,
                    symmetry_tolerance=symmetry_tolerance,
                    phonon_supercell_matrix=phonon_supercell_matrix,
                    verbose=verbose,
                    run_isif2=run_isif2,
                    pass_isif4=pass_isif4,
                    modify_incar_params=modify_incar_params,
                    modify_kpoints_params=modify_kpoints_params,
                    store_volumetric_data=store_volumetric_data),
        parents=full_relax_fw,
        name='%s-EVcheck_QHA' % structure.composition.reduced_formula)
    fws.append(check_result)

    wfname = "{}:{}".format(structure.composition.reduced_formula, name)
    wf = Workflow(fws, name=wfname, metadata=metadata)
    add_modify_incar_by_FWname(wf, modify_incar_params=modify_incar_params)
    add_modify_kpoints_by_FWname(wf,
                                 modify_kpoints_params=modify_kpoints_params)

    return wf
Ejemplo n.º 8
0
    def run_task(self, fw_spec):
        '''
        run_num: maximum number of appending VASP running; this limitation is to avoid always running due to bad settings;
            only for internal usage;

        Important args:
        tolerance: acceptable value for average RMS, recommend >= 0.005;
        threshold: total point number above the value should be reduced, recommend < 16 or much time to run;
        del_limited: maximum deletion ration for large results;
        vol_spacing: the maximum ratio step between two volumes, larger step will be inserted points to calculate;
        '''
        max_run = 10
        deformations = self.get('deformations') or []
        db_file = self['db_file']
        tag = self['tag']
        vasp_cmd = self['vasp_cmd']
        metadata = self['metadata']
        relax_path = self['relax_path'] or ''
        structure = self.get('structure') or None
        run_num = self.get('run_num') or 0
        tolerance = self.get('tolerance') or 0.005
        threshold = self.get('threshold') or 14
        del_limited = self.get('del_limited') or 0.3
        vol_spacing = self.get('vol_spacing') or 0.05
        t_min = self.get('t_min') or 5
        t_max = self.get('t_max') or 2000
        t_step = self.get('t_step') or 5
        phonon = self.get('phonon') or False
        phonon_supercell_matrix = self.get('phonon_supercell_matrix') or None
        verbose = self.get('verbose') or False
        modify_incar_params = self.get('modify_incar_params') or {}
        modify_kpoints_params = self.get('modify_kpoints_params') or {}
        powerups_options = modify_incar_params.get('powerups', None)
        symmetry_tolerance = self.get('symmetry_tolerance') or None
        run_isif2 = self.get('run_isif2') or None
        pass_isif4 = self.get('pass_isif4') or False
        site_properties = self.get('site_properties') or None
        store_volumetric_data = self.get('store_volumetric_data', False)
        run_num += 1

        volumes, energies = self.get_orig_EV_structure(db_file, tag)
        self.check_points(db_file, metadata, tolerance, 0.1, del_limited,
                          volumes, energies, verbose)

        EVcheck_result = init_evcheck_result(run_num, self.correct, volumes,
                                             energies, tolerance, threshold,
                                             vol_spacing, self.error, metadata)

        structure.scale_lattice(self.minE_value)
        if site_properties:
            for pkey in site_properties:
                structure.add_site_property(pkey, site_properties[pkey])
        vol_orig = structure.volume
        volume, energy = gen_volenergdos(self.points, volumes, energies)
        vol_adds = self.check_vol_coverage(volume, vol_spacing, vol_orig,
                                           run_num, energy, structure, phonon,
                                           db_file, tag, t_min, t_max, t_step,
                                           EVcheck_result)  # Normalized to 1
        if self.correct or len(vol_adds) > 0:
            EVcheck_result['sellected'] = volume
            EVcheck_result['minE_value'] = self.minE_value
            EVcheck_result['append'] = (vol_adds).tolist()
            # Marked as adopted in db
            lpad = LaunchPad.auto_load()
            fws = []
            if len(vol_adds) > 0:  # VASP calculations need to append
                if run_num < max_run:
                    # Do VASP and check again
                    print('Appending PreStatic of : %s to calculate in VASP!' %
                          (vol_adds * vol_orig).tolist())

                    fws = []
                    prestatic_calcs = []
                    vis_prestatic = PreStaticSet(structure)
                    for vol_add in vol_adds:
                        prestatic = StaticFW(
                            structure=structure,
                            job_type='normal',
                            name='VR_%.3f-PreStatic' % vol_add,
                            prev_calc_loc=False,
                            vasp_input_set=vis_prestatic,
                            vasp_cmd=">>vasp_cmd<<",
                            db_file=self.get('db_file', DB_FILE),
                            metadata=metadata,
                            Prestatic=True)
                        fws.append(prestatic)
                        prestatic_calcs.append(prestatic)

                    check_result = Firework(
                        PreEV_check(
                            db_file=self.get('db_file', DB_FILE),
                            tag=tag,
                            relax_path=relax_path,
                            deformations=deformations,
                            run_isif2=run_isif2,
                            tolerance=tolerance,
                            threshold=14,
                            vol_spacing=vol_spacing,
                            vasp_cmd=">>vasp_cmd<<",
                            pass_isif4=pass_isif4,
                            metadata=metadata,
                            t_min=t_min,
                            t_max=t_max,
                            t_step=t_step,
                            phonon=phonon,
                            symmetry_tolerance=symmetry_tolerance,
                            phonon_supercell_matrix=phonon_supercell_matrix,
                            verbose=verbose,
                            site_properties=site_properties,
                            modify_incar_params=modify_incar_params,
                            modify_kpoints_params=modify_kpoints_params),
                        parents=prestatic_calcs,
                        name='%s-PreEV_check%s' %
                        (structure.composition.reduced_formula, run_num))
                    fws.append(check_result)
                    strname = "{}:{}".format(
                        structure.composition.reduced_formula, 'PreEV_check')
                    wfs = Workflow(fws, name=strname, metadata=metadata)
                    if modify_incar_params != {}:
                        from dfttk.utils import add_modify_incar_by_FWname
                        add_modify_incar_by_FWname(
                            wfs, modify_incar_params=modify_incar_params)
                    if modify_kpoints_params != {}:
                        from dfttk.utils import add_modify_kpoints_by_FWname
                        add_modify_kpoints_by_FWname(
                            wfs, modify_kpoints_params=modify_kpoints_params)
                    wfs = Customizing_Workflows(
                        wfs, powerups_options=powerups_options)
                    lpad.add_wf(wfs)
                else:
                    too_many_run_error()
            else:  # No need to do more VASP calculation, QHA could be running
                relax_path, run_isif2, pass_isif4 = check_relax_path(
                    relax_path, db_file, tag, run_isif2, pass_isif4)
                if relax_path == '':
                    print(
                        'Success in PreStatic calculations, entering Position relax ...'
                    )
                    vis_relax = RelaxSet(structure)
                    ps2_relax_fw = OptimizeFW(
                        structure,
                        symmetry_tolerance=symmetry_tolerance,
                        job_type='normal',
                        name='MinE V=%.3f relax' % vol_orig,
                        prev_calc_loc=False,
                        vasp_input_set=vis_relax,
                        vasp_cmd=">>vasp_cmd<<",
                        db_file=self.get('db_file', DB_FILE),
                        metadata=metadata,
                        record_path=True,
                        modify_incar={'ISIF': 2},
                        run_isif2=run_isif2,
                        pass_isif4=pass_isif4,
                        modify_incar_params=modify_incar_params,
                        modify_kpoints_params=modify_kpoints_params,
                        spec={'_preserve_fworker': True},
                        store_volumetric_data=store_volumetric_data)
                    fws.append(ps2_relax_fw)
                else:
                    print(
                        'Initial setting found, enter static claculations ...')
                    ps2_relax_fw = None
                check_result = Firework(
                    EVcheck_QHA(
                        db_file=self.get('db_file', DB_FILE),
                        tag=tag,
                        relax_path=relax_path,
                        tolerance=tolerance,
                        run_isif2=run_isif2,
                        threshold=threshold,
                        vol_spacing=vol_spacing,
                        vasp_cmd=">>vasp_cmd<<",
                        run_num=run_num,
                        metadata=metadata,
                        t_min=t_min,
                        t_max=t_max,
                        t_step=t_step,
                        phonon=phonon,
                        deformations=deformations,
                        phonon_supercell_matrix=phonon_supercell_matrix,
                        symmetry_tolerance=symmetry_tolerance,
                        modify_incar_params=modify_incar_params,
                        verbose=verbose,
                        pass_isif4=pass_isif4,
                        modify_kpoints_params=modify_kpoints_params,
                        site_properties=site_properties),
                    parents=ps2_relax_fw,
                    name='%s-EVcheck_QHA' %
                    structure.composition.reduced_formula,
                    store_volumetric_data=store_volumetric_data)
                fws.append(check_result)
                strname = "{}:{}".format(structure.composition.reduced_formula,
                                         'prePS2_Relax')
                wfs = Workflow(fws, name=strname, metadata=metadata)
                if modify_incar_params != {}:
                    from dfttk.utils import add_modify_incar_by_FWname
                    add_modify_incar_by_FWname(
                        wfs, modify_incar_params=modify_incar_params)
                if modify_kpoints_params != {}:
                    from dfttk.utils import add_modify_kpoints_by_FWname
                    add_modify_kpoints_by_FWname(
                        wfs, modify_kpoints_params=modify_kpoints_params)
                wfs = Customizing_Workflows(wfs,
                                            powerups_options=powerups_options)
                lpad.add_wf(wfs)
        else:  # failure to meet the tolerance
            if len(volumes
                   ) == 0:  #self.error == 1e10:   # Bad initial running set
                pass_result_error()
            else:  # fitting fails
                tol_error()

        import json
        with open('PreStatic_check_summary.json', 'w') as fp:
            json.dump(EVcheck_result, fp)
Ejemplo n.º 9
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)
Ejemplo n.º 10
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)
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
    def run_task(self, fw_spec):
        ''' 
        run_num: maximum number of appending VASP running; this limitation is to avoid always running due to bad settings;
            only for internal usage;

        Important args:
        tolerance: acceptable value for average RMS, recommend >= 0.005;
        threshold: total point number above the value should be reduced, recommend < 16 or much time to run;
        del_limited: maximum deletion ration for large results;
        vol_spacing: the maximum ratio step between two volumes, larger step will be inserted points to calculate;
        '''
        max_run = 10
        deformations = self.get('deformations') or []
        db_file = self['db_file']
        tag = self['tag']
        vasp_cmd = self['vasp_cmd']
        metadata = self['metadata']
        relax_path = self['relax_path'] or ''
        run_num = self.get('run_num') or 0
        tolerance = self.get('tolerance') or 0.005
        threshold = self.get('threshold') or 14
        del_limited = self.get('del_limited') or 0.3
        vol_spacing = self.get('vol_spacing') or 0.03
        t_min = self.get('t_min') or 5 
        t_max = self.get('t_max') or 2000
        t_step = self.get('t_step') or 5
        phonon = self.get('phonon') or False
        phonon_supercell_matrix = self.get('phonon_supercell_matrix') or None
        verbose = self.get('verbose') or False
        modify_incar_params = self.get('modify_incar_params') or {}
        modify_kpoints_params = self.get('modify_kpoints_params') or {}
        Pos_Shape_relax = self.get('Pos_Shape_relax') or False
        symmetry_tolerance = self.get('symmetry_tolerance') or None
        run_num += 1
        
        relax_path, Pos_Shape_relax = check_relax_path(relax_path, db_file, tag, Pos_Shape_relax)
        if relax_path == '':
            print('''
#######################################################################
#                                                                     #
#       Cannot find relax path for static calculations, exit!         #
#               You can modify the tag and run again!                 #
#                                                                     #
#######################################################################
                ''')
            return
        
        from pymatgen.io.vasp.inputs import Poscar
        poscar = Poscar.from_file(relax_path + '/CONTCAR')
        structure = poscar.structure
        
        if phonon:
            if not consistent_check_db(db_file, tag):
                print('Please check DB, DFTTK running ended!')
                return

        volumes, energies, dos_objs = self.get_orig_EV(db_file, tag)
        vol_adds = self.check_deformations_in_volumes(deformations, volumes, structure.volume)
        if (len(vol_adds)) == 0:
            self.check_points(db_file, metadata, tolerance, threshold, del_limited, volumes, energies, verbose)
        else:
            self.correct = True
            self.error = 1e10
        
        EVcheck_result = {}
        EVcheck_result['append_run_num'] = run_num
        EVcheck_result['correct'] = self.correct
        EVcheck_result['volumes'] = volumes
        EVcheck_result['energies'] = energies
        EVcheck_result['tolerance'] = tolerance
        EVcheck_result['threshold'] = threshold
        EVcheck_result['vol_spacing'] = vol_spacing
        EVcheck_result['error'] = self.error
        EVcheck_result['metadata'] = metadata

        if self.correct:
            vol_orig = structure.volume
            if (len(vol_adds)) == 0:
                volume, energy, dos_obj = self.gen_volenergdos(self.points, volumes, energies, dos_objs)
                vol_adds = self.check_vol_coverage(volume, vol_spacing, vol_orig, run_num, 
                                                   energy, structure, dos_obj, phonon, 
                                                   db_file, tag, t_min, t_max, t_step,
                                                   EVcheck_result)   # Normalized to 1
                EVcheck_result['sellected'] = volume
                EVcheck_result['append'] = (vol_adds * vol_orig).tolist()
                # Marked as adopted in db
                mark_adopted(tag, db_file, volume)
            lpad = LaunchPad.auto_load()
            fws = []
            if len(vol_adds) > 0:      # VASP calculations need to append
                if run_num < max_run:
                    # Do VASP and check again
                    print('Appending the volumes of : %s to calculate in VASP!' %(vol_adds * vol_orig).tolist())
                    calcs = []
                    vis_relax = RelaxSet(structure)
                    vis_static = StaticSet(structure)
                    isif = 5 if 'infdet' in relax_path else 4
                    for vol_add in vol_adds:
                        if Pos_Shape_relax:
                            ps_relax_fw = OptimizeFW(structure, scale_lattice=vol_add, symmetry_tolerance=None, modify_incar = {'ISIF': isif},
                                                     job_type='normal', name='Pos_Shape_%.3f-relax' %(vol_add * vol_orig), prev_calc_loc=relax_path, 
                                                     vasp_input_set=vis_relax, vasp_cmd=vasp_cmd, db_file=db_file, metadata=metadata, Pos_Shape_relax = True,
                                                     modify_incar_params=modify_incar_params, modify_kpoints_params = modify_kpoints_params,
                                                     parents=None)
                            calcs.append(ps_relax_fw)
                            fws.append(ps_relax_fw)
                            static = StaticFW(structure, name = 'structure_%.3f-static' %(vol_add * vol_orig), vasp_input_set=vis_static, vasp_cmd=vasp_cmd, 
                                              db_file=db_file, metadata=metadata, prev_calc_loc=True, parents=ps_relax_fw)
                        else:
                            static = StaticFW(structure, scale_lattice=vol_add, name = 'structure_%.3f-static' %(vol_add * vol_orig), vasp_input_set=vis_static, vasp_cmd=vasp_cmd, 
                                              db_file=db_file, metadata=metadata, prev_calc_loc=relax_path, parents=None)
                        fws.append(static)
                        calcs.append(static)
                        if phonon:
                            visphonon = ForceConstantsSet(structure)
                            phonon_fw = PhononFW(structure, phonon_supercell_matrix, t_min=t_min, t_max=t_max, t_step=t_step,
                                     name='structure_%.3f-phonon' %(vol_add * vol_orig), vasp_input_set=visphonon,
                                     vasp_cmd=vasp_cmd, db_file=db_file, metadata=metadata,
                                     prev_calc_loc=True, parents=static)
                            fws.append(phonon_fw)
                            calcs.append(phonon_fw)
                    check_result = Firework(EVcheck_QHA(db_file = db_file, tag = tag, relax_path = relax_path, tolerance = tolerance, 
                                                        threshold = threshold, vol_spacing = vol_spacing, vasp_cmd = vasp_cmd, run_num = run_num,
                                                        metadata = metadata, t_min = t_min, t_max = t_max, t_step = t_step, phonon = phonon,
                                                        phonon_supercell_matrix = phonon_supercell_matrix, symmetry_tolerance = symmetry_tolerance,
                                                        modify_incar_params = modify_incar_params, verbose = verbose, Pos_Shape_relax = Pos_Shape_relax,
                                                        modify_kpoints_params = modify_kpoints_params), 
                                            parents = calcs, name='%s-EVcheck_QHA' %structure.composition.reduced_formula)
                    fws.append(check_result)
                    strname = "{}:{}".format(structure.composition.reduced_formula, 'EV_QHA_Append')
                    wfs = Workflow(fws, name = strname, metadata=metadata)
                    if modify_incar_params != {}:
                        from dfttk.utils import add_modify_incar_by_FWname
                        add_modify_incar_by_FWname(wfs, modify_incar_params = modify_incar_params)
                    if modify_kpoints_params != {}:
                        from dfttk.utils import add_modify_kpoints_by_FWname
                        add_modify_kpoints_by_FWname(wfs, modify_kpoints_params = modify_kpoints_params)
                    lpad.add_wf(wfs)
                else:
                    print('''

#######################################################################
#                                                                     #
#            Too many appended VASP running times, abort!             #
#                      Please check VASP setting!                     #
#                                                                     #
#######################################################################

                         ''')
            else:  # No need to do more VASP calculation, QHA could be running 
                print('Success in Volumes-Energies checking, enter QHA ...')
                # Debye
                debye_fw = Firework(QHAAnalysis(phonon=False, t_min=t_min, t_max=t_max, t_step=t_step, db_file=db_file, tag=tag, metadata=metadata), 
                                    name="{}-qha_analysis-Debye".format(structure.composition.reduced_formula))
                fws.append(debye_fw)
                if phonon:
                    phonon_supercell_matrix = self.get('phonon_supercell_matrix')
                    # do a Debye run before the phonon, so they can be done in stages.
                    phonon_fw = Firework(QHAAnalysis(phonon=True, t_min=t_min, t_max=t_max, t_step=t_step, db_file=db_file, tag=tag, 
                                                     metadata=metadata), parents=debye_fw, name="{}-qha_analysis-phonon".format(structure.composition.reduced_formula))
                    fws.append(phonon_fw)
                strname = "{}:{}".format(structure.composition.reduced_formula, 'QHA')
                wfs = Workflow(fws, name = strname, metadata=metadata)
                lpad.add_wf(wfs)
        else:   # failure to meet the tolerance
            if len(volumes) == 0: #self.error == 1e10:   # Bad initial running set
                print('''

#######################################################################
#                                                                     #
#  "passinitrun = True" could not set while initial results absent.   #
#                                                                     #
#######################################################################

                      
                      ''')
            else:                      # fitting fails
                print('''

#######################################################################
#                                                                     #
#           Can not achieve the tolerance requirement, abort!         #
#                                                                     #
#######################################################################

                      ''')
        import json
        with open('E-V check_summary.json', 'w') as fp:
            json.dump(EVcheck_result, fp)
Ejemplo n.º 13
0
def get_wf_gibbs(structure, num_deformations=7, deformation_fraction=(-0.05, 0.1),
                 phonon=False, phonon_supercell_matrix=None,
                 t_min=5, t_max=2000, t_step=5,
                 vasp_cmd=None, db_file=None, metadata=None, name='EV_QHA'):
    """
    E - V
    curve

    workflow
    Parameters
    ------
    structure: pymatgen.Structure
    num_deformations: int
    deformation_fraction: float
        Can be a float (a single value) or a 2-type of a min,max deformation fraction.
        Default is (-0.05, 0.1) leading to volumes of 0.95-1.10. A single value gives plus/minus
        by default.
    phonon : bool
        Whether to do a phonon calculation. Defaults to False, meaning the Debye model.
    phonon_supercell_matrix : list
        3x3 array of the supercell matrix, e.g. [[2,0,0],[0,2,0],[0,0,2]]. Must be specified if phonon is specified.
    t_min : float
        Minimum temperature
    t_step : float
        Temperature step size
    t_max : float
        Maximum temperature (inclusive)
    vasp_cmd : str
        Command to run VASP. If None (the default) is passed, the command will be looked up in the FWorker.
    db_file : str
        Points to the database JSON file. If None (the default) is passed, the path will be looked up in the FWorker.
    name : str
        Name of the workflow
    metadata : dict
        Metadata to include
    """
    vasp_cmd = vasp_cmd or VASP_CMD
    db_file = db_file or DB_FILE

    metadata = metadata or {}
    tag = metadata.get('tag', '{}'.format(str(uuid4())))
    if 'tag' not in metadata.keys():
        metadata['tag'] = tag

    if isinstance(deformation_fraction, (list, tuple)):
        deformations = np.linspace(1+deformation_fraction[0], 1+deformation_fraction[1], num_deformations)
    else:
        deformations = np.linspace(1-deformation_fraction, 1+deformation_fraction, num_deformations)

    # follow a scheme of
    # 1. Full relax + symmetry check
    # 2. If symmetry check fails, detour to 1. Volume relax, 2. inflection detection
    # 3. Inflection detection
    # 4. Static EV
    # 5. Phonon EV
    fws = []
    static_calcs = []
    phonon_calcs = []
    # for each FW, we set the structure to the original structure to verify to ourselves that the
    # volume deformed structure is set by input set.

    # Full relax
    vis = RelaxSet(structure)
    full_relax_fw = OptimizeFW(structure, symmetry_tolerance=0.05, job_type='normal', name='Full relax', prev_calc_loc=False, vasp_input_set=vis, vasp_cmd=vasp_cmd, db_file=db_file, metadata=metadata, spec={'_preserve_fworker': True})
    fws.append(full_relax_fw)

    for i, deformation in enumerate(deformations):
        vis = StaticSet(structure)
        static = StaticFW(structure, scale_lattice=deformation, name='structure_{}-static'.format(i), vasp_input_set=vis, vasp_cmd=vasp_cmd, db_file=db_file, metadata=metadata, parents=full_relax_fw)
        fws.append(static)
        static_calcs.append(static)

        if phonon:
            vis = ForceConstantsSet(structure)
            phonon_fw = PhononFW(structure, phonon_supercell_matrix, t_min=t_min, t_max=t_max, t_step=t_step,
                     name='structure_{}-phonon'.format(i), vasp_input_set=vis,
                     vasp_cmd=vasp_cmd, db_file=db_file, metadata=metadata,
                     prev_calc_loc=True, parents=static)
            fws.append(phonon_fw)
            phonon_calcs.append(static)
            phonon_calcs.append(phonon_fw)

    # always do a Debye after the static calculations. That way we can set up a phonon calculation, do a Debye fitting, then do the phonon if we want.
    debye_fw = Firework(QHAAnalysis(phonon=False, t_min=t_min, t_max=t_max, t_step=t_step, db_file=db_file, tag=tag, metadata=metadata), parents=static_calcs, name="{}-qha_analysis-Debye".format(structure.composition.reduced_formula))
    fws.append(debye_fw)
    if phonon:
        # do a Debye run before the phonon, so they can be done in stages.
        phonon_fw = Firework(QHAAnalysis(phonon=True, t_min=t_min, t_max=t_max, t_step=t_step, db_file=db_file, tag=tag, metadata=metadata), parents=phonon_calcs, name="{}-qha_analysis-phonon".format(structure.composition.reduced_formula))
        fws.append(phonon_fw)

    wfname = "{}:{}".format(structure.composition.reduced_formula, name)

    return Workflow(fws, name=wfname, metadata=metadata)