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
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