def check_POSCAR(self, config): ''' First line must like [1,0]32 to match the elements in POSCAR, 0 could not ignored. ''' # To check the sum of occupancies for m in range(len(self.site_ratios)): sum_occupancy = 0 for n in range(len(self.occupancies[m])): sum_occupancy += self.occupancies[m][n] if abs(sum_occupancy - 1) > 1e-10: print( 'The sum of occupancies in %s is NOT equal to 1, please check!' % self.occupancies[m]) return (False) # To check config and occupancy temp_struct = Structure.from_file(self.poscarfile) namelist_elements = [] numlist_elements = [] for e, a in temp_struct.composition.items(): namelist_elements.append(e) numlist_elements.append(a) # [8.0, 24.0] num_element_firstline = 0 for ocs in self.occupancies: num_element_firstline += len(ocs) if len(numlist_elements) != num_element_firstline: print( 'The number of element kind(%s) in first line of POASCAR is NOT same one in the structure(%s), maybe "0" occupancy should be added.' % (num_element_firstline, len(numlist_elements))) return (False) index = 0 for m in range(len(self.site_ratios)): if len(config[m]) < len(self.occupancies[m]): num_occupancy = 0 for n in range(len(self.occupancies[m])): num_occupancy += self.occupancies[m][n] * self.site_ratios[ m] if abs(num_occupancy - numlist_elements[index]) > 1e-10: print( 'The sum of sites in %s%s is NOT equal to %s(Element: %s), please check!' % (self.occupancies[m], self.site_ratios[m], numlist_elements[index], namelist_elements[index])) return (False) index += len(self.occupancies[m]) else: for n in range(len(self.occupancies[m])): if abs(numlist_elements[index] - self.occupancies[m][n] * self.site_ratios[m]) > 1e-10: print( 'The sites in %s * %s is NOT equal to %s(Element: %s), please check!' % (self.occupancies[m][n], self.site_ratios[m], numlist_elements[index], namelist_elements[index])) return (False) index += 1 return (True)
def debye_find(self): hit = [] phases = [] count = [] for i in self.items: mm = i['metadata'] if mm in hit: count[hit.index(mm)] += 1 else: hit.append(mm) count.append(1) structure = Structure.from_dict(i['structure']) formula_pretty = structure.composition.reduced_formula try: formula2composition(formula_pretty) except: formula_pretty = reduced_formula( structure.composition.alphabetical_formula) sa = SpacegroupAnalyzer(structure) phasename = formula_pretty+'_'\ + sa.get_space_group_symbol().replace('/','.')+'_'+str(sa.get_space_group_number()) if phasename in phases: for jj in range(10000): nphasename = phasename + "#" + str(jj) if nphasename in phases: continue phasename = nphasename break phases.append(phasename) print("\nfound complete calculations in the collection:", self.qhamode, "\n") all_static_calculations = list((self.vasp_db).db['tasks'].\ find({'$and':[{'metadata': { "$exists": True }}, {'adopted': True} ]},\ {'metadata':1, 'output':1, 'input':1, 'orig_inputs':1})) for i, m in enumerate(hit): if self.skipby(phases[i], m['tag']): continue static_calculations = [ f for f in all_static_calculations if f['metadata']['tag'] == m['tag'] ] for ii, calc in enumerate(static_calculations): potsoc = get_used_pot(calc) if self.qhamode == 'qha': potsoc += "_debye" pname = phases[i].split('#') if len(pname) > 1: phases[i] = pname[0] + potsoc + '#' + pname[1] else: phases[i] = pname[0] + potsoc break print(m, ":", phases[i]) self.tags.append({'tag': m['tag'], 'phasename': phases[i]})
def debye_find(self): hit = [] phases = [] count = [] for i in self.items: """ try: ii = len(i['debye']) mm = i['metadata'] except: continue if ii < 6: continue """ mm = i['metadata'] if mm in hit: count[hit.index(mm)] += 1 else: hit.append(mm) count.append(1) structure = Structure.from_dict(i['structure']) formula_pretty = structure.composition.reduced_formula try: formula2composition(formula_pretty) except: formula_pretty = reduced_formula( structure.composition.alphabetical_formula) sa = SpacegroupAnalyzer(structure) phasename = formula_pretty+'_'\ + sa.get_space_group_symbol().replace('/','.')+'_'+str(sa.get_space_group_number()) if phasename in phases: for jj in range(10000): nphasename = phasename + "#" + str(jj) if nphasename in phases: continue phasename = nphasename break phases.append(phasename) print("\nfound complete calculations in the collection:", self.qhamode, "\n") for i, m in enumerate(hit): if self.skipby(phases[i], m['tag']): continue print(m, ":", phases[i]) self.tags.append({'tag': m['tag'], 'phasename': phases[i]})
def get_dielecfij(self, phdir, tag): volumes_b = (self.vasp_db).db['borncharge'].find({'metadata.tag': tag}, { '_id': 0, 'volume': 1 }) volumes_b = [i['volume'] for i in volumes_b] num_Born = len(volumes_b) if num_Born > 0: for i in (self.vasp_db).db['borncharge'].find( {'metadata.tag': tag}): vol = 'V{:010.6f}'.format(float(i['volume'])) voldir = phdir + '/' + vol if not os.path.exists(voldir): os.mkdir(voldir) structure = Structure.from_dict(i['structure']) poscar = structure.to(fmt="poscar") poscar = str(poscar).split('\n') natom = len(structure.sites) with open(voldir + '/dielecfij.out', 'w') as out: for line in range(2, 5): out.write('{}\n'.format(poscar[line])) for line in range(8, natom + 8): out.write('{}\n'.format(poscar[line])) dielectric_tensor = np.array(i['dielectric_tensor']) for x in range(3): for y in range(3): out.write('{} '.format(dielectric_tensor[x, y])) out.write('\n') born_charge = np.array(i['born_charge']) for ii in range(natom): out.write(' ion {}\n'.format(ii + 1)) for x in range(3): out.write(' {} '.format(x + 1)) for y in range(3): out.write('{} '.format(born_charge[ii, x, y])) out.write('\n') return num_Born
def get_rec_from_metatag(vasp_db, m, test=False): if vasp_db.collection.count_documents({'$and':[ {'metadata.tag': m}, {'adopted': True}, \ {'output.structure.lattice.volume': {'$exists': True}}]}) <= 5: static_calculations = vasp_db.collection.find({'$and':[ {'metadata.tag': m}, \ {'output.structure.lattice.volume': {'$exists': True} }]}) else: static_calculations = vasp_db.collection.\ find({'$and':[ {'metadata': {'tag':m}}, {'adopted': True} ]}) gapfound = False energies = [] volumes = [] stresses = [] lattices = [] bandgaps = [] pressures = [] magmoms = [] emin = 1.e36 kpoints = None for calc in static_calculations: vol = calc['output']['structure']['lattice']['volume'] if kpoints is None: kpoints = calc['orig_inputs']['kpoints']['kpoints'] if vol_within(vol, volumes): continue natoms = len(calc['output']['structure']['sites']) try: sites = calc['output']['structure']['sites'] magmoms.append([{ s['label']: s['properties']['magmom'] } for s in sites]) except: pass lat = calc['output']['structure']['lattice']['matrix'] sts = calc['output']['stress'] ene = calc['output']['energy'] if ene < emin: emin = ene structure = Structure.from_dict(calc['input']['structure']) MagState = get_Magnetic_State(calc) POSCAR = structure.to(fmt="poscar") INCAR = calc['input']['incar'] gap = calc['output']['bandgap'] volumes.append(vol) energies.append(ene) stresses.append(sts) lattices.append(lat) bandgaps.append(gap) if sts != None: pressures.append((sts[0][0] + sts[1][1] + sts[2][2]) / 3.) else: pressures.append(None) if not gapfound: gapfound = float(gap) > 0.0 tvolumes = np.array(sorted(volumes)) if len(tvolumes) >= 3: dvolumes = tvolumes[1:] - tvolumes[0:-1] dvolumes = sorted(dvolumes) if abs(dvolumes[-1] - dvolumes[-2]) > 0.01 * dvolumes[-1]: all_static_calculations = vasp_db.collection.\ find({'$and':[ {'metadata.tag': m}, {'adopted': True} ]}) for calc in all_static_calculations: if len(calc['metadata']) <= 1: continue # only check constrained calculation vol = calc['output']['structure']['lattice']['volume'] if vol_within(vol, volumes): continue natoms = len(calc['output']['structure']['sites']) try: sites = calc['output']['structure']['sites'] magmoms.append([{ s['label']: s['properties']['magmom'] } for s in sites]) except: pass lat = calc['output']['structure']['lattice']['matrix'] sts = calc['output']['stress'] ene = calc['output']['energy'] if test: structure = Structure.from_dict(calc['input']['structure']) POSCAR = structure.to(fmt="poscar") INCAR = calc['input']['incar'] break if ene < emin: emin = ene structure = Structure.from_dict(calc['input']['structure']) MagState = get_Magnetic_State(calc) POSCAR = structure.to(fmt="poscar") INCAR = calc['input']['incar'] gap = calc['output']['bandgap'] volumes.append(vol) energies.append(ene) stresses.append(sts) lattices.append(lat) bandgaps.append(gap) if sts != None: pressures.append((sts[0][0] + sts[1][1] + sts[2][2]) / 3.) else: pressures.append(None) if not gapfound: gapfound = float(gap) > 0.0 energies = sort_x_by_y(energies, volumes) pressures = sort_x_by_y(pressures, volumes) stresses = sort_x_by_y(stresses, volumes) lattices = sort_x_by_y(lattices, volumes) bandgaps = sort_x_by_y(bandgaps, volumes) try: magmoms = sort_x_by_y(magmoms, volumes) except: pass volumes = sort_x_by_y(volumes, volumes) EV = {} EV['metatag'] = m EV['natoms'] = natoms EV['volumes'] = volumes EV['stresses'] = stresses EV['energies'] = energies EV['pressures'] = pressures EV['bandgaps'] = bandgaps EV['lattices'] = lattices EV['magmoms'] = magmoms EV['kpoints'] = kpoints EV['MagState'] = MagState return EV, POSCAR, INCAR
def get_rec_from_metatag(vasp_db, m): static_calculations = vasp_db.collection.\ find({'$and':[ {'metadata.tag': m}, {'adopted': True} ]}) gapfound = False energies = [] volumes = [] stresses = [] lattices = [] bandgaps = [] pressures = [] magmoms = [] emin = 1.e36 for calc in static_calculations: vol = calc['output']['structure']['lattice']['volume'] if vol_within(vol, volumes): continue natoms = len(calc['output']['structure']['sites']) try: sites = calc['output']['structure']['sites'] magmoms.append([{ s['label']: s['properties']['magmom'] } for s in sites]) except: pass lat = calc['output']['structure']['lattice']['matrix'] sts = calc['output']['stress'] ene = calc['output']['energy'] if ene < emin: structure = Structure.from_dict(calc['input']['structure']) POSCAR = structure.to(fmt="poscar") INCAR = calc['input']['incar'] gap = calc['output']['bandgap'] volumes.append(vol) energies.append(ene) stresses.append(sts) lattices.append(lat) bandgaps.append(gap) if sts != None: pressures.append((sts[0][0] + sts[1][1] + sts[2][2]) / 3.) else: pressures.append(None) if not gapfound: gapfound = float(gap) > 0.0 energies = sort_x_by_y(energies, volumes) pressures = sort_x_by_y(pressures, volumes) stresses = sort_x_by_y(stresses, volumes) lattices = sort_x_by_y(lattices, volumes) bandgaps = sort_x_by_y(bandgaps, volumes) try: magmoms = sort_x_by_y(magmoms, volumes) except: pass volumes = sort_x_by_y(volumes, volumes) EV = {} EV['metatag'] = m EV['natoms'] = natoms EV['volumes'] = volumes EV['stresses'] = stresses EV['energies'] = energies EV['pressures'] = pressures EV['bandgaps'] = bandgaps EV['lattices'] = lattices try: for volume in magmoms: for magmom in volume.values(): if magmom != 0.: EV['magmoms'] = magmoms break except: pass return EV, POSCAR, INCAR
def run(args): """ Run dfttk Currently, only support get_wf_gibbs Parameters STR_FOLDER = args.STRUCTURE_FOLDER folder/file containing structures MATCH_PATTERN = args.MATCH_PATTERN Match patterns for structure file, e.g. *POSCAR RECURSIVE = args.RECURSIVE recursive or not WORKFLOW = args.WORKFLOW workflow, current only get_wf_gibbs LAUNCH = args.LAUNCH Launch to lpad or not MAX_JOB = args.MAX_JOB Max job to submit SETTINGS = args.SETTINGS Settings file WRITE_OUT_WF = args.WRITE_OUT_WF Write out wf file or not """ STR_FOLDER = args.STRUCTURE_FOLDER # folder/file containing structures MATCH_PATTERN = args.MATCH_PATTERN # Match patterns for structure file, e.g. *POSCAR RECURSIVE = args.RECURSIVE # recursive or not WORKFLOW = args.WORKFLOW # workflow, current only get_wf_gibbs PHONON = args.PHONON # run phonon LAUNCH = args.LAUNCH # Launch to lpad or not MAX_JOB = args.MAX_JOB # Max job to submit SETTINGS = args.SETTINGS # Settings file WRITE_OUT_WF = args.WRITE_OUT_WF # Write out wf file or not TAG = args.TAG # Metadata from the command line APPEND = args.APPEND # Append calculations, e.g. appending volumes or phonon or born db_file = args.db_file # user supplier db_file such as db.json if not db_file: if os.path.exists('db.json'): db_file = 'db.json' elif not os.path.exists(db_file): db_file = None ## Initial wfs and metadatas wfs = [] metadatas = {} if APPEND: if TAG: metadatas = { os.path.join(os.path.abspath('./'), 'POSCAR'): { 'tag': TAG } } elif os.path.exists('METADATAS.yaml'): metadatas = loadfn('METADATAS.yaml') else: raise ValueError( 'For APPEND model, please provide TAG with -tag or provide METADATAS.yaml file' ) for keyi in metadatas: (STR_PATH, STR_FILENAME_WITH_EXT) = os.path.split(keyi) (STR_FILENAME, STR_EXT) = os.path.splitext(STR_FILENAME_WITH_EXT) user_settings = get_user_settings(STR_FILENAME_WITH_EXT, STR_PATH=STR_PATH, NEW_SETTING=SETTINGS) metadata = user_settings.get('metadata', {}) metadata.update(metadatas[keyi]) user_settings.update({'metadata': metadata}) structure = get_eq_structure_by_metadata(metadata=metadata, db_file=db_file) if structure is None: raise FileNotFoundError( 'There is no static results under current metadata tag({})' .format(metadata['tag'])) if PHONON: user_settings.update({'phonon': True}) phonon_supercell_matrix = user_settings.get( 'phonon_supercell_matrix', None) if phonon_supercell_matrix is None: user_settings.update({"phonon_supercell_matrix": "atoms"}) wf = get_wf_single(structure, WORKFLOW=WORKFLOW, settings=user_settings, db_file=db_file) wf = Customizing_Workflows(wf, powerups_options=user_settings.get( 'powerups', None)) if isinstance(wf, list): wfs = wfs + wf else: wfs.append(wf) if WRITE_OUT_WF: dfttk_wf_filename = os.path.join( STR_PATH, "dfttk_wf-" + STR_FILENAME_WITH_EXT + ".yaml") dumpfn(wf, dfttk_wf_filename) else: if os.path.exists('METADATAS.yaml'): metadatas = loadfn('METADATAS.yaml') ## Get the file names of files STR_FILES = get_structure_file(STR_FOLDER=STR_FOLDER, RECURSIVE=RECURSIVE, MATCH_PATTERN=MATCH_PATTERN) ## generat the wf for STR_FILE in STR_FILES: (STR_PATH, STR_FILENAME_WITH_EXT) = os.path.split(STR_FILE) (STR_FILENAME, STR_EXT) = os.path.splitext(STR_FILENAME_WITH_EXT) str_filename = STR_FILENAME.lower() if (str_filename.endswith("-" + SETTINGS.lower()) or str_filename.startswith(SETTINGS.lower() + "-") or (str_filename == SETTINGS.lower())): print( STR_FILE + " is a setting file, not structure file, and skipped when reading the structure." ) elif STR_FILE == os.path.abspath(__file__): #This is current file pass else: flag_run = False try: structure = Structure.from_file(STR_FILE) flag_run = True except Exception as e: warnings.warn("The name or the contant of " + STR_FILE + " is not supported by dfttk, and skipped. " + \ "Ref. https://pymatgen.org/pymatgen.core.structure.html#pymatgen.core.structure.IStructure.from_file") if flag_run: user_settings = get_user_settings(STR_FILENAME_WITH_EXT, STR_PATH=STR_PATH, NEW_SETTING=SETTINGS) metadatai = metadatas.get(STR_FILE, None) if metadatai: user_settings.update({'metadata': metadatai}) if PHONON: user_settings.update({'phonon': True}) phonon_supercell_matrix = user_settings.get( 'phonon_supercell_matrix', None) if phonon_supercell_matrix is None: user_settings.update( {"phonon_supercell_matrix": "atoms"}) wf = get_wf_single(structure, WORKFLOW=WORKFLOW, settings=user_settings) wf = Customizing_Workflows( wf, powerups_options=user_settings.get('powerups', None)) metadatas[STR_FILE] = wf.as_dict()["metadata"] wfs.append(wf) if WRITE_OUT_WF: dfttk_wf_filename = os.path.join( STR_PATH, "dfttk_wf-" + STR_FILENAME_WITH_EXT + ".yaml") dumpfn(wf.to_dict(), dfttk_wf_filename) #Write Out the metadata for POST and continue purpose dumpfn(metadatas, "METADATAS.yaml") """ _fws = [] for wflow in wfs: revised_wflow = Customizing_Workflows(wflow,user_settings={}) _fws.append(revised_wflow) fws = _fws """ if LAUNCH: from fireworks import LaunchPad lpad = LaunchPad.auto_load() for wflow in wfs: lpad.add_wf(wflow) if MAX_JOB: # Not False or Empty if MAX_JOB == 1: os.system("qlaunch singleshot") else: os.system("qlaunch rapidfire -m " + str(MAX_JOB))
def EV_find(self): hit = [] count = [] phases = [] volumes = [] ITEMS = [] for i in self.items: try: mm = i['metadata']['tag'] except: continue if mm in hit: volume = i['output']['structure']['lattice']['volume'] if volume not in volumes[hit.index(mm)]: volumes[hit.index(mm)].append(volume) count[hit.index(mm)] += 1 else: ITEMS.append(i) hit.append(mm) count.append(1) volumes.append([i['output']['structure']['lattice']['volume']]) pot = i['input']['pseudo_potential']['functional'].upper() if pot == "": pot = i['orig_inputs']['potcar']['functional'].upper() if pot == 'Perdew-Zunger81'.upper(): pot = "LDA" try: pot += "+" + i['input']['GGA'] except: pass if i['input']['is_hubbard']: pot += '+U' try: if i['input']['incar']['LSORBIT']: potsoc = pot + "SOC" except: potsoc = pot structure = Structure.from_dict(i['output']['structure']) natoms = len(structure.sites) formula_pretty = structure.composition.reduced_formula try: formula2composition(formula_pretty) except: formula_pretty = reduced_formula( structure.composition.alphabetical_formula) sa = SpacegroupAnalyzer(structure) phasename = formula_pretty+'_'\ + sa.get_space_group_symbol().replace('/','.')+'_'+str(sa.get_space_group_number())+potsoc if phasename in phases: for jj in range(10000): nphasename = phasename + "#" + str(jj) if nphasename in phases: continue phasename = nphasename break phases.append(phasename) for i, m in enumerate(hit): if count[i] < self.nV: continue if self.skipby(phases[i]): continue metadata = {'tag': m} sys.stdout.write('{}, static: {:>2}, {}\n'.format( metadata, count[i], phases[i])) EV, POSCAR, INCAR = get_rec_from_metatag(self.vasp_db, m) evdir = 'E-V' if not os.path.exists(evdir): os.mkdir(evdir) folder = os.path.join(evdir, phases[i]) if not os.path.exists(folder): os.mkdir(folder) with open(os.path.join(folder, 'POSCAR'), 'w') as fp: fp.write(POSCAR) readme = {} readme['E-V'] = EV readme['INCAR'] = INCAR readme['POSCAR'] = POSCAR with open(os.path.join(folder, 'readme'), 'w') as fp: myjsonout(readme, fp, indent="", comma="") thermoplot(folder, "0 K total energies (eV/atom)", EV['volumes'], EV['energies'])
def get_superfij(self, i, phdir, volumes, energies): try: structure = Structure.from_dict(i['unitcell']) except: print("\nit seems phonon for", i['volume'], "is not finished yet and so it is discared\n") return None vol = 'V{:010.6f}'.format(float(i['volume'])) voldir = os.path.join(phdir, vol) if not os.path.exists(voldir): os.mkdir(voldir) elif os.path.exists(os.path.join(voldir, 'superfij.out')): return voldir poscar = structure.to(fmt="poscar") unitcell_l = str(poscar).split('\n') natom = len(structure.sites) supercell_matrix = i['supercell_matrix'] supercell_structure = copy.deepcopy(structure) supercell_structure.make_supercell(supercell_matrix) sa = SpacegroupAnalyzer(supercell_structure) #reduced_structure = supercell_structure.get_reduced_structure(reduction_algo='niggli') #print ('niggli reduced structure', reduced_structure) #poscar = reduced_structure.to(fmt="poscar") primitive_unitcell_structure = sa.find_primitive() poscar = primitive_unitcell_structure.to(fmt="poscar") punitcell_l = str(poscar).split('\n') natoms = len(supercell_structure.sites) ##print(supercell_structure.sites) poscar = supercell_structure.to(fmt="poscar") supercell_l = str(poscar).split('\n') structure.to(filename=os.path.join(voldir, 'POSCAR')) with open(os.path.join(voldir, 'OSZICAR'), 'w') as out: out.write(' 1 F= xx E0= {}\n'.format( energies[(list(volumes)).index(i['volume'])])) with open(os.path.join(voldir, 'superfij.out'), 'w') as out: for line in range(2, 5): out.write('{}\n'.format(unitcell_l[line])) for line in range(2, 5): out.write('{}\n'.format(supercell_l[line])) out.write('{} {}\n'.format(natoms, natoms // natom)) for line in range(7, natoms + 8): out.write('{}\n'.format(supercell_l[line])) force_constant_matrix = np.array(i['force_constants']) hessian_matrix = np.empty((natoms * 3, natoms * 3), dtype=float) for ii in range(natoms): for jj in range(natoms): for x in range(3): for y in range(3): hessian_matrix[ii * 3 + x, jj * 3 + y] = -force_constant_matrix[ii, jj, x, y] hessian_matrix *= self.force_constant_factor if self.force_constant_factor != 1.0: print("\n force constant matrix has been rescaled by :", self.force_constant_factor) for xx in range(natoms * 3): for yy in range(natoms * 3 - 1): out.write('{} '.format(hessian_matrix[xx, yy])) out.write('{}\n'.format(hessian_matrix[xx, natoms * 3 - 1])) return voldir
def qha_renew(self): hit = [] phases = [] static_collection = (self.vasp_db).collection.find({'$and':[{'metadata': { "$exists": True }}, \ {'adopted': True} ]}) for i in static_collection: mm = i['metadata'] if mm in hit: continue if len(mm) > 1: continue else: hit.append(mm) structure = Structure.from_dict(i['output']['structure']) formula_pretty = structure.composition.reduced_formula try: formula2composition(formula_pretty) except: formula_pretty = reduced_formula( structure.composition.alphabetical_formula) sa = SpacegroupAnalyzer(structure) phasename = formula_pretty+'_'\ + sa.get_space_group_symbol().replace('/','.')+'_'+str(sa.get_space_group_number()) if phasename in phases: for jj in range(10000): nphasename = phasename + "#" + str(jj) if nphasename in phases: continue phasename = nphasename break phases.append(phasename) print("\nfound complete calculations in the task collection:\n") total = 0 total_qha = 0 total_qha_phonon = 0 all_static_calculations = list((self.vasp_db).db['tasks'].\ find({'$and':[{'metadata': { "$exists": True }}, {'adopted': True} ]},\ {'metadata':1, 'output':1, 'input':1, 'orig_inputs':1})) all_qha_calculations = list((self.vasp_db).db['qha'].\ find({'$and':[{'metadata': { "$exists": True }},{'has_phonon':True}]}, {'metadata':1, 'temperatures':1})) all_qha_phonon_calculations = list((self.vasp_db).db['qha_phonon'].\ find({'$and':[{'metadata': { "$exists": True }},{'has_phonon':True}]}, {'metadata':1, 'temperatures':1})) for i, m in enumerate(hit): if self.skipby(phases[i], m['tag']): continue total += 1 static_calculations = [ f for f in all_static_calculations if f['metadata']['tag'] == m['tag'] ] qha_calculations = [ f for f in all_qha_calculations if f['metadata']['tag'] == m['tag'] ] qha_phonon_calculations = [ f for f in all_qha_phonon_calculations if f['metadata']['tag'] == m['tag'] ] qha_phonon_success = len(qha_phonon_calculations) > 0 if qha_phonon_success: total_qha_phonon += 1 if len(qha_calculations) > 0 or qha_phonon_success: total_qha += 1 potsoc = None volumes = [] energies = [] for ii, calc in enumerate(static_calculations): vol = calc['output']['structure']['lattice']['volume'] if vol in volumes: if len(calc['metadata']) > 1: continue else: ix = volumes.index(vol) volumes.pop(ix) energies.pop(ix) volumes.append( calc['output']['structure']['lattice']['volume']) energies.append(calc['output']['energy']) if potsoc is None: potsoc = get_used_pot(calc) pname = phases[i].split('#') if len(pname) > 1: phases[i] = pname[0] + potsoc + '#' + pname[1] else: phases[i] = pname[0] + potsoc nS = len(volumes) if nS < 6: continue if qha_phonon_success and not self.db_renew: continue energies = sort_x_by_y(energies, volumes) volumes = sorted(volumes) volumes = np.array(volumes) energies = np.array(energies) val, idx = min((val, idx) for (idx, val) in enumerate(energies)) if idx < 2 or idx > nS - 2: continue jobpath = findjobdir(self.jobpath, m['tag']) if jobpath == None: sys.stdout.write('{}, static: {:>2}, qha_phonon: {:<1.1s}, {}\n'\ .format(m, nS, str(qha_phonon_success), phases[i])) else: sys.stdout.write('{}, static: {:>2}, qha_phonon: {:<1.1s}, {},{}\n'\ .format(m, nS, str(qha_phonon_success), phases[i],jobpath)) self.tags.append({'tag': m['tag'], 'phasename': phases[i]}) sys.stdout.write ('\n({},{})/{} (qha, qha_phonon) entries returned under the given searching conditions.\n'\ .format(total_qha, total_qha_phonon, total))
def check_find(self): """ hit = [] relaxations_collection = (self.vasp_db).db['relaxations'].find({}) for i in relaxations_collection: try: mm = i['metadata']['tag'] hit.append(mm) except: continue lastupdated = [None] * len(hit) for i,mm in enumerate(hit): static_calc = (self.vasp_db).collection.\ find({'$and':[ {'metadata.tag': mm} ]}) for calc in static_calc: lnew = calc['last_updated'] if lastupdated[i]!=None: lold = lastupdated[i] if lnew > lold: lastupdated[i] = lnew else: lastupdated[i] = lnew """ print( "\nfinding tags for complete calculations in the static collection\n" ) hit = [] lastupdated = [] static_collection = (self.vasp_db).collection.find({}) for i in static_collection: try: mm = i['metadata']['tag'] except: continue if mm in hit: idx = hit.index(mm) lold = lastupdated[idx] lnew = i['last_updated'] if lnew > lold: lastupdated[idx] = lnew else: lastupdated.append(i['last_updated']) hit.append(mm) print("\nfinding complete calculations in the phonon collection\n") phases = [""] * len(hit) supercellsize = [0] * len(hit) phonon_count = [0] * len(hit) phonon_calc = list((self.vasp_db).db['phonon'].find({"S_vib": { "$exists": True } },\ {'metadata':1, 'unitcell':1, 'supercell_matrix':1})) for i, mm in enumerate(hit): for calc in phonon_calc: if calc['metadata']['tag'] != mm: continue phonon_count[i] += 1 if phonon_count[i] == 1: structure = Structure.from_dict(calc['unitcell']) natoms = len(structure.sites) supercell_matrix = calc['supercell_matrix'] supercellsize[i] = ( natoms * int(np.linalg.det(np.array(supercell_matrix)) + .5)) formula_pretty = structure.composition.reduced_formula try: formula2composition(formula_pretty) except: formula_pretty = reduced_formula( structure.composition.alphabetical_formula) sa = SpacegroupAnalyzer(structure) phasename = formula_pretty+'_'\ + sa.get_space_group_symbol().replace('/','.')+'_'+str(sa.get_space_group_number()) if phasename in phases: for jj in range(10000): nphasename = phasename + "#" + str(jj) if nphasename in phases: continue phasename = nphasename break phases[i] = phasename print("\nfinding complete calculations in the static collection\n") static_count = [0] * len(hit) for i, mm in enumerate(hit): if self.skipby(phases[i], mm): continue static_calc = (self.vasp_db).collection.\ find({'$and':[ {'metadata.tag': mm} ]}) for calc in static_calc: static_count[i] += 1 print("\nfinding complete calculations in the qha collection\n") qha_count = [0] * len(hit) for i, mm in enumerate(hit): qha_calc = (self.vasp_db).db['qha'].\ find({'$and':[ {'metadata.tag': mm} ]}) for calc in qha_calc: qha_count[i] += 1 print("\nfinding complete calculations in the qha_phonon collection\n") qha_phonon_count = [0] * len(hit) for i, mm in enumerate(hit): try: qha_phonon_calculations = self.vasp_db.db['qha_phonon'].find( {'metadata.tag': mm}) T = qha_phonon_calculations[0]['phonon']['temperatures'] qha_phonon_count[i] += 1 except: try: qha_phonon_calculations = self.vasp_db.db['qha'].find( {'metadata.tag': mm}) T = qha_phonon_calculations[0]['phonon']['temperatures'] qha_phonon_count[i] += 1 except: pass print( "\nfinding complete calculations in the relaxations collection\n") relaxations_count = [0] * len(hit) for i, mm in enumerate(hit): relaxations_calc = (self.vasp_db).db['relaxations'].\ find({'$and':[ {'metadata.tag': mm} ]}) for calc in relaxations_calc: relaxations_count[i] += 1 nTBD = 0 for i, mm in enumerate(hit): #dd = datetime.datetime.strptime(lastupdated[i], '%Y-%m-%d %H:%M:%S.%f').date() dd = lastupdated[i].date() now = datetime.datetime.now().date() #if supercellsize[i]>=16 and phonon_count[i]>=5: continue if supercellsize[i] >= self.supercellN and phonon_count[ i] >= self.nV: continue if dd > now - datetime.timedelta(days=7): continue nTBD += 1 sys.stdout.write( '[{:>04}] relax: {:>2}, static: {:>2}, qha: {:>2}, qha_phonon: {:>2}, phonon: {:>2}, SN: {:>3}, phases: {}, {}\n' .format(i, relaxations_count[i], static_count[i], qha_count[i], qha_phonon_count[i], phonon_count[i], supercellsize[i], phases[i], dd)) #sys.stdout.write('{}, static: {:>2}, qha: {:>2}, qha_phonon: {:>2}, phonon: {:>2}, SN: {:>3}, phases: {}, date: {}\n'.format(mm['tag'], static_count[i], qha_count[i], qha_phonon_count[i], phonon_count[i], supercellsize[i], phases[i], lastupdated[i])) self.tags.append({'tag': mm, 'phasename': phases[i]}) print("\n", nTBD, "/", len(hit), "recs to be removed\n") for t in self.tags: print(t)
def phonon_find(self): hit = [] count = [] phases = [] volumes = [] ITEMS = [] self.supercellsize = [] for i in self.items: """ try: ii = len(i['S_vib']) mm = i['metadata'] except: continue if ii <= 0: continue """ mm = i['metadata'] if mm in hit: if i['volume'] not in volumes[hit.index(mm)]: volumes[hit.index(mm)].append(i['volume']) count[hit.index(mm)] += 1 else: ITEMS.append(i) hit.append(mm) count.append(1) volumes.append([i['volume']]) structure = Structure.from_dict(i['unitcell']) natoms = len(structure.sites) supercell_matrix = i['supercell_matrix'] self.supercellsize.append( natoms * int(np.linalg.det(np.array(supercell_matrix)) + .5)) formula_pretty = structure.composition.reduced_formula try: formula2composition(formula_pretty) except: formula_pretty = reduced_formula( structure.composition.alphabetical_formula) sa = SpacegroupAnalyzer(structure) phasename = formula_pretty+'_'\ + sa.get_space_group_symbol().replace('/','.')+'_'+str(sa.get_space_group_number()) if phasename in phases: for jj in range(10000): nphasename = phasename + "#" + str(jj) if nphasename in phases: continue phasename = nphasename break phases.append(phasename) print("\nfound complete calculations in the collection:", self.qhamode, "\n") total = 0 total_qha_phonon = 0 all_static_calculations = list((self.vasp_db).db['tasks'].\ find({'$and':[{'metadata': { "$exists": True }}, {'adopted': True} ]},\ {'metadata':1, 'output':1, 'input':1, 'orig_inputs':1})) all_qha_calculations = list((self.vasp_db).db['qha'].\ find({'$and':[{'metadata': { "$exists": True }},{'has_phonon':True}]}, {'metadata':1, 'temperatures':1})) all_qha_phonon_calculations = list((self.vasp_db).db['qha_phonon'].\ find({'$and':[{'metadata': { "$exists": True }},{'has_phonon':True}]}, {'metadata':1, 'temperatures':1})) for i, m in enumerate(hit): if self.skipby(phases[i], m['tag']): continue total += 1 static_calculations = [ f for f in all_static_calculations if f['metadata']['tag'] == m['tag'] ] qha_calculations = [ f for f in all_qha_calculations if f['metadata']['tag'] == m['tag'] ] qha_phonon_calculations = [ f for f in all_qha_phonon_calculations if f['metadata']['tag'] == m['tag'] ] """ static_calculations = [f for f in all_static_calculations if f['metadata']==m] qha_calculations = [f for f in all_qha_calculations if f['metadata']==m] qha_phonon_calculations = [f for f in all_qha_phonon_calculations if f['metadata']==m] """ qha_phonon_success = True if len(qha_calculations) > 0: total_qha_phonon += 1 elif len(qha_phonon_calculations) > 0: total_qha_phonon += 1 else: qha_phonon_success = False nS = 0 gapfound = False potsoc = None for ii, calc in enumerate(static_calculations): vol = calc['output']['structure']['lattice']['volume'] if potsoc is None: pot = calc['input']['pseudo_potential'][ 'functional'].upper() if pot == "": pot = calc['orig_inputs']['potcar'][ 'functional'].upper() if pot == 'Perdew-Zunger81'.upper(): pot = "LDA" try: pot += "+" + calc['input']['incar']['GGA'] except: pass if calc['input']['is_hubbard']: pot += '+U' try: if calc['input']['incar']['LSORBIT']: potsoc = pot + "+SOC" except: potsoc = pot pname = phases[i].split('#') if len(pname) > 1: phases[i] = pname[0] + potsoc + '#' + pname[1] else: phases[i] = pname[0] + potsoc nS += 1 bandgap = calc['output']['bandgap'] if not gapfound: gapfound = float(bandgap) > 0.0 if self.findbandgap: if gapfound: sys.stdout.write( '{}, phonon: {:>2}, static: {:>2}, supercellsize: {:>3}, {}\n' .format(m, count[i], nS, self.supercellsize[i], phases[i])) else: if count[i] < self.nV: continue if self.supercellsize[i] < self.supercellN: continue jobpath = findjobdir(self.jobpath, m['tag']) if self.remove: sys.stdout.write('dfttk db_remove --force -m all -tag {} phonon: {:>2}, static: {:>2}, SN: {:>3}, qha_phonon: {:<1.1s}, {}\n'\ .format(m['tag'], count[i], nS, self.supercellsize[i], str(qha_phonon_success), phases[i])) elif jobpath == None: sys.stdout.write('{}, phonon: {:>2}, static: {:>2}, SN: {:>3}, qha_phonon: {:<1.1s}, {}\n'\ .format(m, count[i], nS, self.supercellsize[i], str(qha_phonon_success), phases[i])) else: sys.stdout.write('{}, phonon: {:>2}, static: {:>2}, SN: {:>3}, qha_phonon: {:<1.1s}, {},{}\n'\ .format(m, count[i], nS, self.supercellsize[i], str(qha_phonon_success), phases[i],jobpath)) #if count[i]>=5: self.tags.append({'tag':m['tag'],'phasename':phases[i]}) if count[i] >= self.nV: self.tags.append({'tag': m['tag'], 'phasename': phases[i]}) sys.stdout.write ('\n{}/{} qha_phonon successful under the given searching conditions.\n'\ .format(total_qha_phonon, total))
def check_symmetry(tol_energy=0.025, tol_strain=0.05, tol_bond=0.10, site_properties=None): ''' Check symmetry for vasp run. This should be run for each vasp run Parameter --------- tol_energy: float The tolerance of energy tol_strain: float The tolerance of strain tol_bond: float The tolerance of bond Return symm_data: dict It will store the initial structure/final_structure, isif, initial_energy_per_atom, final_energy_per_atom, symmetry_checks_passed, tolerances, failures, number_of_failures ------ ''' # Get relevant files as pmg objects incar = Incar.from_file("INCAR") outcar = Outcar('OUTCAR') vasprun = Vasprun("vasprun.xml") inp_struct = Structure.from_file("POSCAR") out_struct = Structure.from_file("CONTCAR") if site_properties: if 'magmom' in site_properties: in_mag = incar.as_dict()['MAGMOM'] inp_struct.add_site_property('magmom', in_mag) out_mag = [m['tot'] for m in outcar.magnetization] if len(out_mag) == 0: out_mag = copy.deepcopy(in_mag) out_struct.add_site_property('magmom', out_mag) site_properties.pop('magmom') for site_property in site_properties: inp_struct.add_site_property(site_property, site_properties[site_property]) out_struct.add_site_property(site_property, site_properties[site_property]) current_isif = incar['ISIF'] initial_energy = float( vasprun.ionic_steps[0]['e_wo_entrp']) / len(inp_struct) final_energy = float(vasprun.final_energy) / len(out_struct) # perform all symmetry breaking checks failures = [] energy_difference = np.abs(final_energy - initial_energy) if energy_difference > tol_energy: fail_dict = { 'reason': 'energy', 'tolerance': tol_energy, 'value': energy_difference, } failures.append(fail_dict) strain_norm = get_non_isotropic_strain(inp_struct.lattice.matrix, out_struct.lattice.matrix) if strain_norm > tol_strain: fail_dict = { 'reason': 'strain', 'tolerance': tol_strain, 'value': strain_norm, } failures.append(fail_dict) bond_distance_change = get_bond_distance_change(inp_struct, out_struct) if bond_distance_change > tol_bond: fail_dict = { 'reason': 'bond distance', 'tolerance': tol_bond, 'value': bond_distance_change, } failures.append(fail_dict) symm_data = { "initial_structure": inp_struct.as_dict(), "final_structure": out_struct.as_dict(), "isif": current_isif, "initial_energy_per_atom": initial_energy, "final_energy_per_atom": final_energy, "real_value": { "energy": energy_difference, "strain": strain_norm, "bond": bond_distance_change }, "tolerances": { "energy": tol_energy, "strain": tol_strain, "bond": tol_bond, }, "failures": failures, "number_of_failures": len(failures), "symmetry_checks_passed": len(failures) == 0, } return symm_data
def ext_thelec(args, plotfiles=None, vasp_db=None): global no_MongoDB print ("Postprocess for thermodynamic properties, Seebeck, Lorenz number etc. Yi Wang\n") """ Postprocess for thermodynamic properties, Seebeck, Lorenz number etc Parameters STR_FOLDER = args.STRUCTURE_FOLDER folder/file containing structures MATCH_PATTERN = args.MATCH_PATTERN Match patterns for structure file, e.g. *POSCAR RECURSIVE = args.RECURSIVE recursive or not WORKFLOW = args.WORKFLOW workflow, current only get_wf_gibbs LAUNCH = args.LAUNCH Launch to lpad or not MAX_JOB = args.MAX_JOB Max job to submit SETTINGS = args.SETTINGS Settings file WRITE_OUT_WF = args.WRITE_OUT_WF Write out wf file or not """ t0 = args.t0 t1 = args.t1 td = args.td xdn = args.xdn xup = args.xup ndosmx = args.ndosmx natom = args.natom gaussian = args.gaussian dope = args.dope doscar = args.doscar outf = args.outf qhamode = args.qhamode eqmode = args.eqmode elmode = args.elmode metatag = args.metatag everyT = args.everyT noel = args.noel smooth = args.smooth expt = args.expt xlim = args.xlim if abs(dope)<5.e-9: ndosmx = max(100001, int(ndosmx)) gaussian = max(10000., float(gaussian)) formula = None if args.local != "": print("\nRun using local data\n") readme = {} record_cmd(readme) proc = thelecMDB(t0, t1, td, xdn, xup, dope, ndosmx, gaussian, natom, outf, noel=noel, qhamode=qhamode, eqmode=eqmode, elmode=elmode, smooth=smooth, debug=args.debug, phasename=args.local, pyphon=True, renew=args.renew, fitF=args.fitF, args=args) volumes, energies, thermofile, comments = proc.run_console() if comments!=None: readme.update(comments) else: return if "ERROR" in readme.keys(): record_cmd_print(thermofile, readme, dir=args.phasename) return print("\nFull thermodynamic properties have outputed into:", thermofile) #print(args.plot, "eeeeeeeee", volumes, energies, thermofile, comments) if args.plot==None: print("\nSupply '-plot phasename' for plot\n") else: from dfttk.analysis.ywplot import plotAPI #print("xxxxxxx",proc.get_formula()) if plotAPI(readme, thermofile, volumes, energies, expt=expt, xlim=xlim, _fitCp=args.SGTEfitCp, formula = proc.get_formula(), debug=args.debug, plotlabel=args.plot, local=args.local): #print ("xxxxxxx",proc.get_formula()) vtof = proc.get_free_energy_for_plot(readme) if vtof is not None: plotAPI(readme, thermofile, volumes, energies, expt=expt, xlim=xlim, _fitCp=args.SGTEfitCp, formula = proc.get_formula(), vtof=vtof, plotlabel=args.plot) """ """ #print("xxxxxxxxxxxx",readme) record_cmd_print(thermofile, readme) elif no_MongoDB: print("\n*********WARNING: CANNOT get MongoDB service, so I will proceed using local data") print("*********WARNING: CANNOT get MongoDB service, so I will proceed using local data") print("*********WARNING: CANNOT get MongoDB service, so I will proceed using local data\n") elif not args.plotonly: #if True: try: if vasp_db is None: db_file = loadfn(config_to_dict()["FWORKER_LOC"])["env"]["db_file"] vasp_db = VaspCalcDb.from_db_file(db_file, admin=False) static_calculations = vasp_db.collection.\ find({'$and':[ {'metadata.tag': metatag}, {'adopted': True} ]}) structure = Structure.from_dict(static_calculations[0]['output']['structure']) formula = reduced_formula(structure.composition.alphabetical_formula) except: no_MongoDB = True print("\n*********WARNING: CANNOT get MongoDB service, so I will proceed using local data") print("*********WARNING: CANNOT get MongoDB service, so I will proceed using local data") print("*********WARNING: CANNOT get MongoDB service, so I will proceed using local data\n") """ """ #call API if args.plotonly and plotfiles!=None: metatag, thermofile, volumes, energies, dir, formula = plotfiles sys.stdout.write('Processing {}, dir: {}, formula: {}\n'.format(metatag, dir, formula)) #print(thermofile, volumes, energies, formula) #print(thermofile, dir, formula) readme={} from dfttk.analysis.ywplot import plotAPI plotAPI(readme, thermofile, None, energies, expt=expt, xlim=xlim, _fitCp=args.SGTEfitCp, formula = formula, vtof=None, plotlabel=args.plot) elif vasp_db==None and plotfiles!=None: metatag, thermofile, volumes, energies, dir, formula = plotfiles sys.stdout.write('Processing {}, dir: {}, formula: {}\n'.format(metatag, dir, formula)) #print("xxxxxxxxxx", plotfiles) if expt!=None: _t1 = get_melting_temperature(expt, formula) if _t1!=None: t1 = _t1 readme = {} record_cmd(readme) proc = thelecMDB(t0, t1, td, xdn, xup, dope, ndosmx, gaussian, natom, outf, vasp_db=vasp_db, noel=noel, metatag=metatag, qhamode=qhamode, eqmode=eqmode, elmode=elmode, everyT=everyT, smooth=smooth, debug=args.debug, phasename=dir, pyphon=args.pyphon, renew=args.renew, fitF=args.fitF, args=args) volumes, energies, thermofile, comments = proc.run_console() #print ("xxxxxxx", comments) if comments!=None: readme.update(comments) else: return if "ERROR" in readme.keys(): #record_cmd_print(thermofile, readme, dir=args.phasename) return print("\nFull thermodynamic properties have outputed into:", thermofile) #print(args.plot, "eeeeeeeee", volumes, energies, thermofile, comments) if args.plot==None: print("\nSupply '-plot phasename' for plot\n") else: from dfttk.analysis.ywplot import plotAPI if plotAPI(readme, thermofile, volumes, energies, expt=expt, xlim=xlim, _fitCp=args.SGTEfitCp, formula = proc.get_formula(), debug=args.debug, plotlabel=args.plot): vtof = proc.get_free_energy_for_plot(readme) if vtof is not None: plotAPI(readme, thermofile, volumes, energies, expt=expt, xlim=xlim, _fitCp=args.SGTEfitCp, formula = proc.get_formula(), vtof=vtof, plotlabel=args.plot) """ """ record_cmd_print(thermofile, readme) elif metatag != None: if expt!=None: _t1 = get_melting_temperature(expt, formula) if _t1!=None: t1 = _t1 readme = {} record_cmd(readme) proc = thelecMDB(t0, t1, td, xdn, xup, dope, ndosmx, gaussian, natom, outf, vasp_db=vasp_db, noel=noel, metatag=metatag, qhamode=qhamode, eqmode=eqmode, elmode=elmode, everyT=everyT, smooth=smooth, debug=args.debug, phasename=args.phasename, pyphon=args.pyphon, renew=args.renew, fitF=args.fitF, args=args) volumes, energies, thermofile, comments = proc.run_console() if comments!=None: readme.update(comments) else: return if "ERROR" in readme.keys(): record_cmd_print(thermofile, readme, dir=args.phasename) return print("\nFull thermodynamic properties have outputed into:", thermofile) #print(args.plot, "eeeeeeeee", volumes, energies, thermofile, comments) if args.plot==None: print("\nSupply '-plot phasename' for plot\n") else: from dfttk.analysis.ywplot import plotAPI if plotAPI(readme, thermofile, volumes, energies, expt=expt, xlim=xlim, _fitCp=args.SGTEfitCp, formula = proc.get_formula(), debug=args.debug, plotlabel=args.plot): vtof = proc.get_free_energy_for_plot(readme) if vtof is not None: plotAPI(readme, thermofile, volumes, energies, expt=expt, xlim=xlim, _fitCp=args.SGTEfitCp, formula = proc.get_formula(), vtof=vtof, plotlabel=args.plot) """ """ record_cmd_print(thermofile, readme) elif args.vdos is not None: readme = {} record_cmd(readme) proc = thelecMDB(t0, t1, td, xdn, xup, dope, ndosmx, gaussian, natom, outf, renew=True, args=args) thermofile, comments, natoms = proc.run_single() if thermofile is None: return readme.update(comments) #record_cmd(thermofile, readme) print("\nFull thermodynamic properties have outputed into:", thermofile) if args.plot!=None: from dfttk.analysis.ywplot import plotAPI if plotAPI(readme, thermofile, None, None, expt=expt, xlim=xlim, _fitCp=args.SGTEfitCp, formula = proc.get_formula(), debug=args.debug, poscar=args.poscar,vdos=args.vdos, doscar=args.doscar, natoms=natoms, plotlabel=args.plot): record_cmd_print(thermofile, readme) elif args.local == "": pythelec.thelecAPI(t0, t1, td, xdn, xup, dope, ndosmx, gaussian, natom, outf, doscar)
modify_incar_params = { 'Full relax': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}}, 'PreStatic': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}}, 'PS2': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}}, 'static': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}}, """ modify_incar_params={} #dict, dict of class ModifyKpoints with keywords in Workflow name, similar with modify_incar_params modify_kpoints_params={} #bool, print(True) or not(False) some informations, used for debug verbose=False ###################### DO NOT CHANGE THE FOLLOWING LINES ############################## from pymatgen.ext.matproj import MPRester, Structure from dfttk.wflows import get_wf_gibbs structure = Structure.from_file(TEMPLATE_STRUCTURE_FILENAME) if magmom: structure.add_site_property('magmom', magmom) if not 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"] wf = get_wf_gibbs(structure, num_deformations=num_deformations, deformation_fraction=deformation_fraction, phonon=phonon, phonon_supercell_matrix=phonon_supercell_matrix, t_min=t_min, t_max=t_max, t_step=t_step, tolerance=tolerance, volume_spacing_min=volume_spacing_min,vasp_cmd=vasp_cmd, db_file=db_file, metadata=metadata, name='EV_QHA', symmetry_tolerance=symmetry_tolerance, run_isif2=run_isif2, pass_isif4=pass_isif4, passinitrun=passinitrun, relax_path=relax_path, modify_incar_params=modify_incar_params, modify_kpoints_params=modify_kpoints_params,
def EV_find(self): evdirhome = 'E-V' if not os.path.exists(evdirhome): os.mkdir(evdirhome) hit = [] count = [] phases = [] volumes = [] ITEMS = [] potname = [] fp_ev = open(os.path.join(evdirhome, "E-V.dat"), "w") for i in self.items: mm = i['metadata']['tag'] els = i['elements'] if self.skipby("", mm, els=els): continue if self.hit_condition is not None: if mm not in self.hit_condition: continue if mm in hit: volume = i['output']['structure']['lattice']['volume'] if volume not in volumes[hit.index(mm)]: volumes[hit.index(mm)].append(volume) count[hit.index(mm)] += 1 else: ITEMS.append(i) hit.append(mm) count.append(1) volumes.append([i['output']['structure']['lattice']['volume']]) potsoc = get_used_pot(i) structure = Structure.from_dict(i['output']['structure']) formula_pretty = structure.composition.reduced_formula try: formula2composition(formula_pretty) except: formula_pretty = reduced_formula( structure.composition.alphabetical_formula) sa = SpacegroupAnalyzer(structure) phasename = formula_pretty+'_'\ + sa.get_space_group_symbol().replace('/','.')+'_'+str(sa.get_space_group_number()) potname.append(potsoc) if phasename in phases: for jj in range(10000): nphasename = phasename + "#" + str(jj) if nphasename in phases: continue phasename = nphasename break phases.append(phasename) blank_lines = False for i, mm in enumerate(hit): if self.hit_condition is not None: if mm not in self.hit_condition: continue if self.qhamode == 'phonon': if self.hit_count[mm] < self.nV: continue if count[i] < self.nV: continue if self.skipby(phases[i], mm): continue EV, POSCAR, INCAR = get_rec_from_metatag(self.vasp_db, mm) metadata = {'tag': mm} pname = phases[i].split('#') if len(pname) > 1: phases[i] = pname[0] + potname[i] + EV[ 'MagState'] + '#' + pname[1] else: phases[i] = pname[0] + potname[i] + EV['MagState'] if EV['natoms'] < self.natoms: continue sys.stdout.write('{}, static: {:>2}, natoms: {:>3}, {}\n'.format( metadata, count[i], EV['natoms'], phases[i])) folder = os.path.join(evdirhome, phases[i]) if not os.path.exists(folder): os.mkdir(folder) with open(os.path.join(folder, 'POSCAR'), 'w') as fp: fp.write(POSCAR) readme = {} readme['E-V'] = EV readme['INCAR'] = INCAR readme['POSCAR'] = POSCAR natoms = readme['E-V']['natoms'] with open(os.path.join(folder, 'readme'), 'w') as fp: myjsonout(readme, fp, indent="", comma="") i_energies = np.array(EV['energies']) / natoms i_volumes = np.array(EV['volumes']) / natoms val, idx = min((val, idx) for (idx, val) in enumerate(i_energies)) if blank_lines: print("\n", file=fp_ev) blank_lines = True print("#phase:", phases[i], file=fp_ev) print("#metadata:", mm, file=fp_ev) print("#natoms:", natoms, file=fp_ev) elist = ['Fe', 'Cu', 'Se', 'Al', 'Ni', 'Co', 'Pt', 'Ta', 'O'] el = [] nel = [] if len(EV['magmoms']) > 0: fp_ev.write("#magmoms:") magmoms = EV['magmoms'][idx] m0 = magmoms[0] n0 = 1 for j in range(1, len(magmoms)): if magmoms[j] == m0: n0 += 1 else: if n0 == 1: fp_ev.write('{},'.format(m0)) else: fp_ev.write('{}*{},'.format(n0, m0)) idx = len(el) % len(elist) el.append(elist[idx]) nel.append(n0) n0 = 1 m0 = magmoms[j] if n0 == 1: fp_ev.write('{}\n'.format(m0)) else: fp_ev.write('{}*{}\n'.format(n0, m0)) idx = len(el) % len(elist) el.append(elist[idx]) nel.append(n0) lines = [l for l in POSCAR.split('\n') if l != ""] with open(os.path.join(folder, phases[i] + '.VASP'), 'w') as fp: for j in range(0, 5): print(lines[j], file=fp) for j in range(len(el)): fp.write(' {}'.format(el[j])) fp.write('\n') for j in range(len(nel)): fp.write(' {}'.format(nel[j])) fp.write('\n') print(lines[7], file=fp) for j in range(8, len(lines)): print(lines[j], float(list(magmoms[j - 8].values())[0]), file=fp) for j in range(len(i_volumes)): print(i_volumes[j], i_energies[j], file=fp_ev) thermoplot(folder, "0 K total energies (eV/atom)", i_volumes, i_energies)
def phonon_find(self): hit = [] count = [] phases = [] volumes = [] ITEMS = [] self.supercellsize = [] for i in self.items: mm = i['metadata'] if mm in hit: if i['volume'] not in volumes[hit.index(mm)]: volumes[hit.index(mm)].append(i['volume']) count[hit.index(mm)] += 1 else: ITEMS.append(i) hit.append(mm) count.append(1) volumes.append([i['volume']]) structure = Structure.from_dict(i['unitcell']) natoms = len(structure.sites) supercell_matrix = i['supercell_matrix'] self.supercellsize.append( natoms * int(np.linalg.det(np.array(supercell_matrix)) + .5)) formula_pretty = structure.composition.reduced_formula try: formula2composition(formula_pretty) except: formula_pretty = reduced_formula( structure.composition.alphabetical_formula) sa = SpacegroupAnalyzer(structure) phasename = formula_pretty+'_'\ + sa.get_space_group_symbol().replace('/','.')+'_'+str(sa.get_space_group_number()) if phasename in phases: for jj in range(10000): nphasename = phasename + "#" + str(jj) if nphasename in phases: continue phasename = nphasename break phases.append(phasename) print("\nfound complete calculations in the collection:", self.qhamode, "\n") total = 0 total_qha_phonon = 0 all_static_calculations = list((self.vasp_db).db['tasks'].\ find({'$and':[{'metadata': { "$exists": True }}, {'adopted': True} ]},\ {'metadata':1, 'output':1, 'input':1, 'orig_inputs':1})) all_qha_calculations = list((self.vasp_db).db['qha'].\ find({'$and':[{'metadata': { "$exists": True }},{'has_phonon':True}]}, {'metadata':1, 'temperatures':1})) all_qha_phonon_calculations = list((self.vasp_db).db['qha_phonon'].\ find({'$and':[{'metadata': { "$exists": True }},{'has_phonon':True}]}, {'metadata':1, 'temperatures':1})) for i, m in enumerate(hit): if self.skipby(phases[i], m['tag']): continue total += 1 static_calculations = [ f for f in all_static_calculations if f['metadata']['tag'] == m['tag'] ] qha_calculations = [ f for f in all_qha_calculations if f['metadata']['tag'] == m['tag'] ] qha_phonon_calculations = [ f for f in all_qha_phonon_calculations if f['metadata']['tag'] == m['tag'] ] """ static_calculations = [f for f in all_static_calculations if f['metadata']==m] qha_calculations = [f for f in all_qha_calculations if f['metadata']==m] qha_phonon_calculations = [f for f in all_qha_phonon_calculations if f['metadata']==m] """ qha_phonon_success = True if len(qha_calculations) > 0: total_qha_phonon += 1 elif len(qha_phonon_calculations) > 0: total_qha_phonon += 1 else: qha_phonon_success = False gapfound = False potsoc = None _volumes = [] emin = 1.e36 for ii, calc in enumerate(static_calculations): vol = calc['output']['structure']['lattice']['volume'] ene = calc['output']['energy'] if ene < emin: _calc = calc if vol not in _volumes: _volumes.append(vol) bandgap = calc['output']['bandgap'] if not gapfound: gapfound = float(bandgap) > 0.0 potsoc = get_used_pot(_calc) Mag_State = get_Magnetic_State(_calc) pname = phases[i].split('#') if len(pname) > 1: phases[i] = pname[0] + potsoc + Mag_State + '#' + pname[1] else: phases[i] = pname[0] + potsoc + Mag_State nS = len(_volumes) if self.findbandgap: if gapfound: sys.stdout.write( '{}, phonon: {:>2}, static: {:>2}, supercellsize: {:>3}, {}\n' .format(m, count[i], nS, self.supercellsize[i], phases[i])) else: if count[i] < self.nV: continue if self.db_repair: if qha_phonon_success and not self.db_renew: continue if self.supercellsize[i] < self.supercellN: continue jobpath = findjobdir(self.jobpath, m['tag']) if self.remove: sys.stdout.write('dfttk db_remove --force -m all -tag {} phonon: {:>2}, static: {:>2}, SN: {:>3}, qha_phonon: {:<1.1s}, {}\n'\ .format(m['tag'], count[i], nS, self.supercellsize[i], str(qha_phonon_success), phases[i])) elif jobpath == None: sys.stdout.write('{}, phonon: {:>2}, static: {:>2}, SN: {:>3}, qha_phonon: {:<1.1s}, {}\n'\ .format(m, count[i], nS, self.supercellsize[i], str(qha_phonon_success), phases[i])) else: sys.stdout.write('{}, phonon: {:>2}, static: {:>2}, SN: {:>3}, qha_phonon: {:<1.1s}, {},{}\n'\ .format(m, count[i], nS, self.supercellsize[i], str(qha_phonon_success), phases[i],jobpath)) #if count[i]>=5: self.tags.append({'tag':m['tag'],'phasename':phases[i]}) self.tags.append({'tag': m['tag'], 'phasename': phases[i]}) #print(sorted(volumes[i])) sys.stdout.write ('\n{}/{} qha_phonon successful under the given searching conditions.\n'\ .format(total_qha_phonon, total))