예제 #1
0
def get_wf_elastic(structure=None,
                   metadata=None,
                   tag=None,
                   vasp_cmd=None,
                   db_file=None,
                   name="elastic",
                   vasp_input_set=None,
                   override_default_vasp_params=None,
                   strain_states=None,
                   stencils=None,
                   analysis=True,
                   sym_reduce=False,
                   order=2,
                   conventional=False,
                   **kwargs):
    '''
    Parameter
    ---------
        structure (Structure): the structure to be calculated.
            if the metedata is exist in db, then get the structure from the databae,
                else using current provided structure.
        db_file (str): path to file containing the database settings.
        vasp_input_set (VaspInputSet): vasp input set to be used.  Defaults to ElasticSet in input_sets
        override_default_vasp_params (dict): change the vasp settings.
            e.g. {'user_incar_settings': {}, 'user_kpoints_settings': {}, 'user_potcar_functional': str}
        tag (str):
        #########The following parameters is taken from atomate directly#########
        strain_states (list of Voigt-notation strains): list of ratios of nonzero elements
            of Voigt-notation strain, e. g. [(1, 0, 0, 0, 0, 0), (0, 1, 0, 0, 0, 0), etc.].
        stencils (list of floats, or list of list of floats): values of strain to multiply
            by for each strain state, i. e. stencil for the perturbation along the strain
            state direction, e. g. [-0.01, -0.005, 0.005, 0.01].  If a list of lists,
            stencils must correspond to each strain state provided.
        conventional (bool): flag to convert input structure to conventional structure,
            defaults to False.
        order (int): order of the tensor expansion to be determined.  Defaults to 2 and
            currently supports up to 3.
        analysis (bool): flag to indicate whether analysis task should be added
            and stresses and strains passed to that task
        sym_reduce (bool): Whether or not to apply symmetry reductions

    '''
    vasp_cmd = vasp_cmd or VASP_CMD
    db_file = db_file or DB_FILE

    override_default_vasp_params = override_default_vasp_params or {}

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

    struct_energy_elasticity = is_property_exist_in_db(metadata=metadata,
                                                       db_file=db_file)
    if struct_energy_elasticity:
        bandgap = struct_energy_elasticity[2]
        static_setting = struct_energy_elasticity[3]

        volumes_existed_calc = is_property_exist_in_db(metadata=metadata,
                                                       db_file=db_file,
                                                       collection='elasticity')
        if not volumes_existed_calc:
            structures = struct_energy_elasticity[0]
            bandgap = struct_energy_elasticity[2]
            volumes = struct_energy_elasticity[4]
        else:
            structures = []
            bandgap = []
            volumes = []
            for i, vol in enumerate(struct_energy_elasticity[4]):
                #if vol in volumes_existed_calc:
                if vol_in_volumes(vol, volumes_existed_calc):
                    print("Elasticity already calculated for volume=", vol)
                    continue
                structures.append(struct_energy_elasticity[0][i])
                bandgap.append(struct_energy_elasticity[2][i])
                volumes.append(struct_energy_elasticity[4][i])

        if len(structures) == 0:
            print("Elasticity already calculated for all volumes for", \
            struct_energy_elasticity[0][0].composition.reduced_formula, " with tag:", tag, "\n")
            sys.exit()
        else:
            print("Elasticity will be calculated for volumes=", volumes," for", \
            struct_energy_elasticity[0][0].composition.reduced_formula, " with tag:", tag, "\n")
    else:
        bandgap = False

    wfs = []
    if bandgap:
        if override_default_vasp_params is None:
            override_default_vasp_params = {}
        using_incar_new_settings = override_default_vasp_params.get(
            'user_incar_settings', None)
        override_default_vasp_params.update(static_setting)
        if using_incar_new_settings is not None:
            override_default_vasp_params['user_incar_settings'].update(
                using_incar_new_settings)

        for i, struct in enumerate(structures):
            if conventional:
                _struct = SpacegroupAnalyzer(
                    struct).get_conventional_standard_structure()
            else:
                _struct = struct
            """
            if bandgap[i]==0.0:
                override_default_vasp_params['user_incar_settings'].update({'ISMEAR': 0})
                override_default_vasp_params['user_incar_settings'].update({'SIGMA': 0.05})
            print(vasp_input_set.CONFIG['INCAR'])
            """
            vasp_input_set = vasp_input_set or ElasticSet(
                structure=_struct, **override_default_vasp_params)

            wf_elastic = get_wf_elastic_constant(struct,
                                                 metadata,
                                                 strain_states=strain_states,
                                                 stencils=stencils,
                                                 db_file=db_file,
                                                 conventional=conventional,
                                                 order=order,
                                                 vasp_input_set=vasp_input_set,
                                                 analysis=analysis,
                                                 sym_reduce=sym_reduce,
                                                 tag='{}-{}'.format(name, tag),
                                                 vasp_cmd=vasp_cmd,
                                                 **kwargs)
            wfs.append(wf_elastic)
    else:
        if structure is None:
            raise ValueError(
                'There is no optimized structure with tag={}, Please provide structure.'
                .format(tag))
        else:
            wfs = get_wf_elastic_constant(structure,
                                          metadata,
                                          strain_states=strain_states,
                                          stencils=stencils,
                                          db_file=db_file,
                                          conventional=conventional,
                                          order=order,
                                          vasp_input_set=vasp_input_set,
                                          analysis=analysis,
                                          sym_reduce=sym_reduce,
                                          tag='{}-{}'.format(name, tag),
                                          vasp_cmd=vasp_cmd,
                                          **kwargs)
    return wfs
예제 #2
0
def get_wf_borncharge(structure=None,
                      metadata=None,
                      db_file=None,
                      isif=2,
                      name="born charge",
                      vasp_input_set=None,
                      vasp_cmd=None,
                      override_default_vasp_params=None,
                      tag=None,
                      modify_incar=None,
                      **kwargs):
    '''
    The born charge work flow

    structure or metadata must be given.
        If structure is given, then run borncharge for the structure
        If metadata is given, then it will try to find the static calculations form mongodb,
            then it will run born charge calculaions for all structures, if not exist, raise error
        If both are given, then it will try to find structure from mongodb, if not exist, using the given structure
        If both are not given, raise error

    Parameters
    ----------
        structure: pymatgen.Structure
        metadata: dict
            metadata = {'tag': xxxxxxx}
    Return
    ------
        wf: workflow
            The borncharge workflow
    '''
    vasp_cmd = vasp_cmd or VASP_CMD
    metadata = metadata or {}
    tag = metadata.get('tag', '{}'.format(str(uuid4())))
    metadata.update({'tag': tag})
    struct_energy_bandgap = is_property_exist_in_db(metadata=metadata,
                                                    db_file=db_file)
    if struct_energy_bandgap:
        bandgap = struct_energy_bandgap[2]
        static_setting = struct_energy_bandgap[3]
        if all(np.array(bandgap) == 0):
            print("\nWARNING! No bandgap found for ", \
            struct_energy_bandgap[0][0].composition.reduced_formula, " with tag:", tag, "\n")

        volumes_existed_calc = is_property_exist_in_db(metadata=metadata,
                                                       db_file=db_file,
                                                       collection='borncharge')
        if not volumes_existed_calc:
            structures = struct_energy_bandgap[0]
            bandgap = struct_energy_bandgap[2]
            volumes = struct_energy_bandgap[4]
        else:
            structures = []
            bandgap = []
            volumes = []
            for i, vol in enumerate(struct_energy_bandgap[4]):
                if vol in volumes_existed_calc:
                    print(
                        "Born effective charges already calculated for volume=",
                        vol)
                    continue
                structures.append(struct_energy_bandgap[0][i])
                bandgap.append(struct_energy_bandgap[2][i])
                volumes.append(struct_energy_bandgap[4][i])

            #Born charge has been calculated
            #raise ValueError('The borncharge with tag={} has been calculated.'.format(tag))
        if len(structures) == 0:
            print("Born effective charges already calculated for all volumes for", \
            struct_energy_bandgap[0][0].composition.reduced_formula, " with tag:", tag, "\n")
            sys.exit()
        else:
            print("Born effective charges will be calculated for volumes=", volumes," for", \
            struct_energy_bandgap[0][0].composition.reduced_formula, " with tag:", tag, "\n")
    else:
        bandgap = False

    fws = []
    if bandgap:
        if override_default_vasp_params is None:
            override_default_vasp_params = {}
        using_incar_new_settings = None
        if 'user_incar_settings' in override_default_vasp_params.keys():
            using_incar_new_settings = override_default_vasp_params[
                'user_incar_settings']
        override_default_vasp_params.update(static_setting)
        if using_incar_new_settings is not None:
            override_default_vasp_params['user_incar_settings'].update(
                using_incar_new_settings)

        #any bandgap > 0
        #if any(np.array(bandgap) > 0):
        if True:
            for i in range(0, len(bandgap)):
                structure = structures[i]
                fw = BornChargeFW(
                    structure,
                    isif=isif,
                    name="{}-{:.3f}".format(name, structure.volume),
                    vasp_cmd=vasp_cmd,
                    metadata=metadata,
                    modify_incar=modify_incar,
                    override_default_vasp_params=override_default_vasp_params,
                    tag=tag,
                    prev_calc_loc=False,
                    db_file=db_file,
                    **kwargs)
                fws.append(fw)
    else:
        if structure is None:
            raise ValueError(
                'You must provide metadata existed in mongodb or structure')
        else:
            fw = BornChargeFW(
                structure,
                isif=isif,
                name="{}-{:.3f}".format(name, structure.volume),
                vasp_cmd=vasp_cmd,
                metadata=metadata,
                modify_incar=modify_incar,
                override_default_vasp_params=override_default_vasp_params,
                tag=tag,
                prev_calc_loc=False,
                db_file=db_file,
                **kwargs)
            fws.append(fw)
    if not fws:
        raise ValueError(
            'The system is metal or no static result under given metadata in the mongodb'
        )

    wfname = "{}:{}".format(structure.composition.reduced_formula, name)
    wf = Workflow(fws, name=wfname, metadata=metadata)
    return wf