def get_extreme(self, kpt,iband,only_energy=False,cbm=True): engre,latt_points,nwave, nsym, nsymop, symop, br_dir = self.get_engre(iband) if only_energy == False: energy, denergy, ddenergy = get_energy(kpt,engre,nwave, nsym, nstv, vec, vec2, br_dir,cbm=cbm) return Energy(energy,"Ry").to("eV"), denergy, ddenergy else: energy = get_energy(kpt,engre,nwave, nsym, nstv, vec, cbm=cbm) return Energy(energy,"Ry").to("eV") # This is in eV automatically
def __new__(cls, l, u, j, unit): """ Args: l: Angular momentum (int or string). u: U value j: J Value unit: Energy unit for u and j. """ l = l u, j = Energy(u, unit), Energy(j, unit) return super(cls, LujForSpecie).__new__(cls, l, u, j, unit)
def test_energy(self): a = Energy(1.1, "eV") b = a.to("Ha") self.assertAlmostEqual(b, 0.0404242579378) c = Energy(3.14, "J") self.assertAlmostEqual(c.to("eV"), 1.9598339337836966e+19) self.assertRaises(UnitError, Energy, 1, "m") d = Energy(1, "Ha") self.assertAlmostEqual(a + d, 28.31138386) self.assertAlmostEqual(a - d, -26.11138386) self.assertEqual(a + 1, 2.1) self.assertEqual(str(a / d), "1.1 eV Ha^-1")
def _make_intrans_file(self, file_name, doping=[1e15, 1e16, 1e17, 1e18, 1e19, 1e20]): with open(file_name, 'w') as fout: fout.write("GENE # use generic interface\n") fout.write( "1 0 0 0.0 # iskip (not presently used) idebug setgap shiftgap \n" ) fout.write( "0.0 %f 0.1 %6.1f # Fermilevel (Ry),energygrid,energy span around Fermilevel, number of electrons\n" % (Energy(self.energy_grid, "eV").to("Ry"), self._nelec)) fout.write( "CALC # CALC (calculate expansion coeff), NOCALC read from file\n" ) fout.write( "%d # lpfac, number of latt-points per k-point\n" % self.lpfac) fout.write( "BOLTZ # run mode (only BOLTZ is supported)\n" ) fout.write( ".15 # (efcut) energy range of chemical potential\n" ) fout.write("800. 100. # Tmax, temperature grid\n") fout.write( "-1. # energyrange of bands given DOS output sig_xxx and dos_xxx (xxx is band number)\n" ) fout.write(self.dos_type + "\n") fout.write("1 0 0 -1\n") fout.write(str(2 * len(doping)) + "\n") for d in doping: fout.write(str(d) + "\n") for d in doping: fout.write(str(-d) + "\n")
def run_mopac(self, mol): cur_dir = os.getcwd() all_errors = set() energy = 0.0 with tempfile.TemporaryDirectory() as scratch_dir: order_text = ["st", "nd", "th"] title = "Salt Alignment {}{} Calculation".format( self.run_number, order_text[self.run_number - 1 if self.run_number < 3 else 2]) self.run_number += 1 mop = MopTask(mol, self.total_charge, "opt", title, "PM7", {"CYCLES": 2000}) mop.write_file("mol.mop") job = MopacJob(backup=False) handler = MopacErrorHandler() c = Custodian(handlers=[handler], jobs=[job], max_errors=50) custodian_out = c.run() mopout = MopOutput("mol.out") final_pmg_mol = mopout.data["molecules"][-1] final_ob_mol = BabelMolAdaptor(final_pmg_mol)._obmol energy = Energy(mopout.data["energies"][-1][-1], "eV").to("Ha") if energy < self.global_best_energy: self.global_best_energy = energy shutil.copy("mol.out", os.path.join(cur_dir, "best_mol.out")) for run in custodian_out: for correction in run['corrections']: all_errors.update(correction['errors']) if len(all_errors) > 0: out_error_logs_file = os.path.join(cur_dir, "out_error_logs.txt") bak_cmd = "cat {} >> {}".format("mol.out", out_error_logs_file) os.system(bak_cmd) return energy, final_ob_mol
def collect_qe(current_id, work_path): # ---------- check optimization in previous stage try: with open(work_path + rin.qe_outfile, 'r') as fpout: lines = fpout.readlines() check_opt = 'not_yet' for line in lines: if 'End final coordinates' in line: check_opt = 'done' except: check_opt = 'no_file' # ---------- obtain energy and magmom try: with open(work_path + rin.qe_outfile, 'r') as fpout: lines = fpout.readlines() energy = np.nan for line in reversed(lines): if line.startswith('!'): energy = float(line.split()[-2]) # in Ry energy = float(Energy(energy, 'Ry').to('eV')) # Ry --> eV energy = energy / float(rin.natot) # eV/cell --> eV/atom break magmom = np.nan # not implemented yet... except: energy = np.nan # error magmom = np.nan # error print(' Structure ID {0}, could not obtain energy from {1}'.format( current_id, rin.qe_outfile)) # ---------- collect the last structure try: lines_cell = qe_structure.extract_cell_parameters(work_path + rin.qe_outfile) if lines_cell is None: lines_cell = qe_structure.extract_cell_parameters(work_path + rin.qe_infile) lines_atom = qe_structure.extract_atomic_positions(work_path + rin.qe_outfile) if lines_atom is None: lines_atom = qe_structure.extract_atomic_positions(work_path + rin.qe_infile) opt_struc = qe_structure.from_lines(lines_cell, lines_atom) # ------ opt_qe-structure with open('./data/opt_qe-structure', 'a') as fstruc: fstruc.write('# ID {0:d}\n'.format(current_id)) qe_structure.write(opt_struc, './data/opt_qe-structure', mode='a') except: opt_struc = None # ---------- check if np.isnan(energy): opt_struc = None if opt_struc is None: energy = np.nan magmom = np.nan # ---------- return return opt_struc, energy, magmom, check_opt
def collect_OMX(current_id, work_path): # ---------- check optimization in previous stage (done) # If *.out file exists, the calculation is done. try: with open(work_path+rin.OMX_outfile, 'r') as fpout: lines = fpout.readlines() check_opt = 'done' except: check_opt = 'no_file' # ---------- obtain energy and magmom (done) try: with open(work_path+rin.OMX_outfile, 'r') as fpout: lines = fpout.readlines() energy = np.nan for line in reversed(lines): if re.search('Utot\.', line): energy = float(re.search(r"-\d.+", line).group()) energy = float(Energy(energy, 'Ha').to('eV')) energy = energy / float(rin.natot) break magmom = np.nan # not implement (2020/03/05) except: energy = np.nan # error magmom = np.nan # error print(' Structure ID {0}, could not obtain energy from {1}'.format( current_id, rin.OMX_outfile)) # ---------- collect the last structure (yet) try: lines_cell = OMX_structure.extract_cell_parameters_from_outfile( work_path+rin.OMX_outfile) if lines_cell is None: lines_cell = OMX_structure.extract_cell_parameters_from_infile( work_path+rin.OMX_infile) lines_atom = OMX_structure.extract_atomic_positions_from_outfile( work_path+rin.OMX_outfile) if lines_atom is None: lines_atom = OMX_structure.extract_atomic_positions_from_infile( work_path+rin.OMX_infile) opt_struc = OMX_structure.from_lines(lines_cell, lines_atom) # ------ opt_OMX-structure with open('./data/opt_OMX-structure', 'a') as fstruc: fstruc.write('# ID {0:d}\n'.format(current_id)) OMX_structure.write(opt_struc, './data/opt_OMX-structure', mode='a') except: opt_struc = None # ---------- check if np.isnan(energy): opt_struc = None if opt_struc is None: energy = np.nan magmom = np.nan # ---------- return return opt_struc, energy, magmom, check_opt
def test_energy(self): a = Energy(1.1, "eV") b = a.to("Ha") self.assertAlmostEqual(b, 0.0404242579378) c = Energy(3.14, "J") self.assertAlmostEqual(c.to("eV"), 1.9598338493806797e19) self.assertRaises(UnitError, Energy, 1, "m") d = Energy(1, "Ha") self.assertAlmostEqual(a + d, 28.311386245987997) self.assertAlmostEqual(a - d, -26.111386245987994) self.assertEqual(a + 1, 2.1) self.assertEqual(str(a / d), "1.1 eV Ha^-1") e = Energy(1, "kJ") f = e.to("kCal") self.assertAlmostEqual(f, 0.2390057361376673) self.assertEqual(str(e + f), "2.0 kJ") self.assertEqual(str(f + e), "0.4780114722753346 kCal")
def collect_soiap(current_id, work_path): # ---------- check optimization in current stage try: with open(work_path + rin.soiap_outfile, 'r') as fout: lines = fout.readlines() check_opt = 'not_yet' for i, line in enumerate(lines): if '*** QMD%loopc' in line: if 'QMD%frc converged.' in lines[ i - 2] and 'QMD%strs converged.' in lines[i - 1]: check_opt = 'done' break except: check_opt = 'no_file' # ---------- obtain energy and magmom magmom = np.nan # magnetic moment is not calculated try: with open(work_path + 'log.tote') as f: lines = f.readlines() energy = float(lines[-1].split()[2]) # in Hartree energy = float(Energy(energy, 'Ha').to('eV')) # Hartree --> eV except: energy = np.nan # error print(' Structure ID {0}, could not obtain energy from {1}'.format( current_id, rin.soiap_outfile)) # ---------- collect the last structure try: opt_struc = soiap_structure.from_file(work_path + 'log.struc') except: opt_struc = None # ---------- check if np.isnan(energy): opt_struc = None if opt_struc is None: energy = np.nan magmom = np.nan # ---------- mv xxxxx fin_xxxxx soiap_files = [ rin.soiap_infile, rin.soiap_outfile, rin.soiap_cif, 'log.struc', 'log.tote', 'log.frc', 'log.strs' ] for f in soiap_files: if os.path.isfile(work_path + f): os.rename(work_path + f, work_path + 'fin_' + f) # ---------- clean stat file os.remove(work_path + 'stat_job') # ---------- return return opt_struc, energy, magmom, check_opt
def test_energy(self): a = Energy(1.1, "eV") b = a.to("Ha") self.assertAlmostEqual(b, 0.0404242579378) c = Energy(3.14, "J") self.assertAlmostEqual(c.to("eV"), 1.9598339337836966e+19) self.assertRaises(UnitError, Energy, 1, "m") d = Energy(1, "Ha") self.assertAlmostEqual(a + d, 28.31138386) self.assertAlmostEqual(a - d, -26.11138386) self.assertEqual(a + 1, 2.1) self.assertEqual(str(a / d), "1.1 eV Ha^-1")
def _make_energy_file(self, file_name): with open(file_name, 'w') as f: f.write("test\n") f.write(str(len(self._bs.kpoints))+"\n") for i in range(len(self._bs.kpoints)): tmp_eigs = [] for spin in self._bs._bands: for j in range(int(math.floor(self._bs._nb_bands * 0.9))): tmp_eigs.append(Energy(self._bs._bands[spin][j][i] - self._bs.efermi, "eV").to("Ry")) tmp_eigs.sort() f.write("%12.8f %12.8f %12.8f %d\n" % (self._bs.kpoints[i].frac_coords[0], self._bs.kpoints[i].frac_coords[1], self._bs.kpoints[i].frac_coords[2], len(tmp_eigs))) for j in range(len(tmp_eigs)): f.write("%18.8f\n" % float(tmp_eigs[j]))
def collect_soiap(current_id, work_path): # ---------- check optimization in current stage try: with open(work_path+rin.soiap_outfile, 'r') as fout: lines = fout.readlines() check_opt = 'not_yet' for i, line in enumerate(lines): if '*** QMD%loopc' in line: if ('QMD%frc converged.' in lines[i-2] and 'QMD%strs converged.' in lines[i-1]): check_opt = 'done' break except: check_opt = 'no_file' # ---------- obtain energy and magmom magmom = np.nan # magnetic moment is not calculated try: with open(work_path+'log.tote') as f: lines = f.readlines() energy = float(lines[-1].split()[2]) # in Hartree energy = float(Energy(energy, 'Ha').to('eV')) # Hartree --> eV energy = energy/float(rin.natot) # eV/cell --> eV/atom except: energy = np.nan # error print(' Structure ID {0}, could not obtain energy from {1}'.format( current_id, rin.soiap_outfile)) # ---------- collect the last structure try: opt_struc = soiap_structure.from_file(work_path+'log.struc') except: opt_struc = None # ---------- check if np.isnan(energy): opt_struc = None if opt_struc is None: energy = np.nan magmom = np.nan # ---------- return return opt_struc, energy, magmom, check_opt
def _parse_job(self, output): energy_patt = re.compile(r'Total \w+ energy\s+=\s+([.\-\d]+)') energy_gas_patt = re.compile(r'gas phase energy\s+=\s+([.\-\d]+)') energy_sol_patt = re.compile(r'sol phase energy\s+=\s+([.\-\d]+)') coord_patt = re.compile(r'\d+\s+(\w+)\s+[.\-\d]+\s+([.\-\d]+)\s+' r'([.\-\d]+)\s+([.\-\d]+)') lat_vector_patt = re.compile(r'a[123]=<\s+([.\-\d]+)\s+' r'([.\-\d]+)\s+([.\-\d]+)\s+>') corrections_patt = re.compile(r'([\w\-]+ correction to \w+)\s+=' r'\s+([.\-\d]+)') preamble_patt = re.compile(r'(No. of atoms|No. of electrons' r'|SCF calculation type|Charge|Spin ' r'multiplicity)\s*:\s*(\S+)') force_patt = re.compile(r'\s+(\d+)\s+(\w+)' + 6 * r'\s+([0-9\.\-]+)') time_patt = re.compile( r'\s+ Task \s+ times \s+ cpu: \s+ ([.\d]+)s .+ ', re.VERBOSE) error_defs = { "calculations not reaching convergence": "Bad convergence", "Calculation failed to converge": "Bad convergence", "geom_binvr: #indep variables incorrect": "autoz error", "dft optimize failed": "Geometry optimization failed"} fort2py = lambda x: x.replace("D", "e") isfloatstring = lambda s: s.find(".") == -1 parse_hess = False parse_proj_hess = False hessian = None projected_hessian = None parse_force = False all_forces = [] forces = [] data = {} energies = [] frequencies = None normal_frequencies = None corrections = {} molecules = [] structures = [] species = [] coords = [] lattice = [] errors = [] basis_set = {} bset_header = [] parse_geom = False parse_freq = False parse_bset = False parse_projected_freq = False job_type = "" parse_time = False time = 0 for l in output.split("\n"): for e, v in error_defs.items(): if l.find(e) != -1: errors.append(v) if parse_time: m = time_patt.search(l) if m: time = m.group(1) parse_time = False if parse_geom: if l.strip() == "Atomic Mass": if lattice: structures.append(Structure(lattice, species, coords, coords_are_cartesian=True)) else: molecules.append(Molecule(species, coords)) species = [] coords = [] lattice = [] parse_geom = False else: m = coord_patt.search(l) if m: species.append(m.group(1).capitalize()) coords.append([float(m.group(2)), float(m.group(3)), float(m.group(4))]) m = lat_vector_patt.search(l) if m: lattice.append([float(m.group(1)), float(m.group(2)), float(m.group(3))]) if parse_force: m = force_patt.search(l) if m: forces.extend(map(float, m.groups()[5:])) elif len(forces) > 0: all_forces.append(forces) forces = [] parse_force = False elif parse_freq: if len(l.strip()) == 0: if len(normal_frequencies[-1][1]) == 0: continue else: parse_freq = False else: vibs = [float(vib) for vib in l.strip().split()[1:]] num_vibs = len(vibs) for mode, dis in zip(normal_frequencies[-num_vibs:], vibs): mode[1].append(dis) elif parse_projected_freq: if len(l.strip()) == 0: if len(frequencies[-1][1]) == 0: continue else: parse_projected_freq = False else: vibs = [float(vib) for vib in l.strip().split()[1:]] num_vibs = len(vibs) for mode, dis in zip( frequencies[-num_vibs:], vibs): mode[1].append(dis) elif parse_bset: if l.strip() == "": parse_bset = False else: toks = l.split() if toks[0] != "Tag" and not re.match(r"-+", toks[0]): basis_set[toks[0]] = dict(zip(bset_header[1:], toks[1:])) elif toks[0] == "Tag": bset_header = toks bset_header.pop(4) bset_header = [h.lower() for h in bset_header] elif parse_hess: if l.strip() == "": continue if len(hessian) > 0 and l.find("----------") != -1: parse_hess = False continue toks = l.strip().split() if len(toks) > 1: try: row = int(toks[0]) except Exception: continue if isfloatstring(toks[1]): continue vals = [float(fort2py(x)) for x in toks[1:]] if len(hessian) < row: hessian.append(vals) else: hessian[row - 1].extend(vals) elif parse_proj_hess: if l.strip() == "": continue nat3 = len(hessian) toks = l.strip().split() if len(toks) > 1: try: row = int(toks[0]) except Exception: continue if isfloatstring(toks[1]): continue vals = [float(fort2py(x)) for x in toks[1:]] if len(projected_hessian) < row: projected_hessian.append(vals) else: projected_hessian[row - 1].extend(vals) if len(projected_hessian[-1]) == nat3: parse_proj_hess = False else: m = energy_patt.search(l) if m: energies.append(Energy(m.group(1), "Ha").to("eV")) parse_time = True continue m = energy_gas_patt.search(l) if m: cosmo_scf_energy = energies[-1] energies[-1] = dict() energies[-1].update({"cosmo scf": cosmo_scf_energy}) energies[-1].update({"gas phase": Energy(m.group(1), "Ha").to("eV")}) m = energy_sol_patt.search(l) if m: energies[-1].update( {"sol phase": Energy(m.group(1), "Ha").to("eV")}) m = preamble_patt.search(l) if m: try: val = int(m.group(2)) except ValueError: val = m.group(2) k = m.group(1).replace("No. of ", "n").replace(" ", "_") data[k.lower()] = val elif l.find("Geometry \"geometry\"") != -1: parse_geom = True elif l.find("Summary of \"ao basis\"") != -1: parse_bset = True elif l.find("P.Frequency") != -1: parse_projected_freq = True if frequencies is None: frequencies = [] toks = l.strip().split()[1:] frequencies.extend([(float(freq), []) for freq in toks]) elif l.find("Frequency") != -1: toks = l.strip().split() if len(toks) > 1 and toks[0] == "Frequency": parse_freq = True if normal_frequencies is None: normal_frequencies = [] normal_frequencies.extend([(float(freq), []) for freq in l.strip().split()[1:]]) elif l.find("MASS-WEIGHTED NUCLEAR HESSIAN") != -1: parse_hess = True if not hessian: hessian = [] elif l.find("MASS-WEIGHTED PROJECTED HESSIAN") != -1: parse_proj_hess = True if not projected_hessian: projected_hessian = [] elif l.find("atom coordinates gradient") != -1: parse_force = True elif job_type == "" and l.strip().startswith("NWChem"): job_type = l.strip() if job_type == "NWChem DFT Module" and \ "COSMO solvation results" in output: job_type += " COSMO" else: m = corrections_patt.search(l) if m: corrections[m.group(1)] = FloatWithUnit( m.group(2), "kJ mol^-1").to("eV atom^-1") if frequencies: for freq, mode in frequencies: mode[:] = zip(*[iter(mode)]*3) if normal_frequencies: for freq, mode in normal_frequencies: mode[:] = zip(*[iter(mode)]*3) if hessian: n = len(hessian) for i in range(n): for j in range(i + 1, n): hessian[i].append(hessian[j][i]) if projected_hessian: n = len(projected_hessian) for i in range(n): for j in range(i + 1, n): projected_hessian[i].append(projected_hessian[j][i]) data.update({"job_type": job_type, "energies": energies, "corrections": corrections, "molecules": molecules, "structures": structures, "basis_set": basis_set, "errors": errors, "has_error": len(errors) > 0, "frequencies": frequencies, "normal_frequencies": normal_frequencies, "hessian": hessian, "projected_hessian": projected_hessian, "forces": all_forces, "task_time": time}) return data
def bxsf_write(file, structure, nsppol, nband, ndivs, emesh_sbk, fermie, unit="eV"): """ Write band structure data in the Xcrysden format (XSF) Args: file: file-like object. structure: :class:`Structure` object. nsppol: Number of spins. nband: Number of bands. ndivs: Number of divisions of the full k-mesh. emesh_sbk: Array [nsppol, nband, ndivs[0], ndivs[1], mpdvis[2]] with the emesh_sbk in energy unit `unit`. fermie: Fermi energy. .. note:: #. The k-points must span the reciprocal unit cell, not the Brillouin zone. #. The mesh must be closed and centered on Gamma. #. Energies are written in row-major (i.e. C) order. # Energies are in Hartree. See also http://www.xcrysden.org/doc/XSF.html """ emesh_sbk = EnergyArray(emesh_sbk, unit).to("Ha") fermie = Energy(fermie, unit).to("Ha") emesh_sbk = np.reshape(emesh_sbk, (nsppol, nband, np.product(ndivs))) close_it = False if not hasattr(file, "write"): file = open(file, mode="w") close_it = True fw = file.write # Write the header. fw('BEGIN_INFO\n') fw('# Band-XCRYSDEN-Structure-File for Visualization of Fermi Surface generated by the ABINIT package\n' ) fw('# NOTE: the first band is relative to spin-up electrons,\n') fw('# the second band to spin-down electrons (if any) and so on ...\n#\n' ) fw('# Launch as: xcrysden --bxsf\n#\n') fw(' Fermi Energy: %f\n' % fermie) fw('END_INFO\n\n') fw('BEGIN_BLOCK_BANDGRID_3D\n') fw(' band_energies\n') fw(' BEGIN_BANDGRID_3D\n') fw(str(nsppol * nband) + "\n") # Number of bands written. fw("%d %d %d\n" % tuple(ndivs)) # Number of division in the full BZ mesh. fw("0 0 0\n") # Unshifted meshes are not supported. # Reciprocal lattice vectors in Ang^{-1} gcell = structure.lattice_vectors("g") for i in range(3): fw('%f %f %f\n' % tuple(gcell[i])) # Write energies on the full mesh for all spins and bands. idx = 0 for band in range(nband): for spin in range(nsppol): idx += 1 enebz = emesh_sbk[spin, band, :] fw(" BAND: %d\n" % idx) fw("\n".join("%.18e" % v for v in enebz)) fw("\n") fw(' END_BANDGRID_3D\n') fw('END_BLOCK_BANDGRID_3D\n') file.flush() if close_it: file.close()
def get_2nd_round_calcualtion_result(mission_tag, bench_key_name, bench_dict, no_expt_bench_dict, db_collection): result_cursor = db_collection.find( filter={"user_tags.mission": mission_tag}, projection=['user_tags', 'IE', 'EA', 'calculations', 'inchi']) calc_result = list(result_cursor) for m in calc_result: ref_name = m['user_tags']['fw_name'] if ref_name in bench_dict: d = bench_dict[ref_name] else: if not ref_name in no_expt_bench_dict: no_expt_bench_dict[ref_name] = {} d = no_expt_bench_dict[ref_name] if 'IE' in m: if 'IP' in d: d['IP'][bench_key_name] = m['IE'] else: d['IP'] = {bench_key_name: m['IE']} if 'EA' in m: if 'EA' in d: d['EA'][bench_key_name] = m['EA'] else: d['EA'] = {bench_key_name: m['EA']} if 'scf' in m['calculations']: if 'neutral_energy' in d: d['neutral_energy'][bench_key_name] = float( Energy(m['calculations']['scf']['energies'][-1], 'eV').to('Ha')) else: d['neutral_energy'] = { bench_key_name: float( Energy(m['calculations']['scf']['energies'][-1], 'eV').to('Ha')) } if 'scf_IE' in m['calculations']: if 'cation_energy' in d: d['cation_energy'][bench_key_name] = float( Energy(m['calculations']['scf_IE']['energies'][-1], 'eV').to('Ha')) else: d['cation_energy'] = { bench_key_name: float( Energy(m['calculations']['scf_IE']['energies'][-1], 'eV').to('Ha')) } if 'scf_EA' in m['calculations']: if 'anion_energy' in d: d['anion_energy'][bench_key_name] = float( Energy(m['calculations']['scf_EA']['energies'][-1], 'eV').to('Ha')) else: d['anion_energy'] = { bench_key_name: float( Energy(m['calculations']['scf_EA']['energies'][-1], 'eV').to('Ha')) }
def from_files(path_dir): """ get a BoltztrapAnalyzer object from a set of files Args: path_dir: directory where the boltztrap files are Returns: a BoltztrapAnalyzer object """ t_steps = set() m_steps = set() gap = None doping = [] data_doping_full = [] data_doping_hall = [] with open(os.path.join(path_dir, "boltztrap.condtens"), 'r') as f: data_full = [] for line in f: if not line.startswith("#"): t_steps.add(int(float(line.split()[1]))) m_steps.add(float(line.split()[0])) data_full.append([float(c) for c in line.split()]) with open(os.path.join(path_dir, "boltztrap.halltens"), 'r') as f: data_hall = [] for line in f: if not line.startswith("#"): data_hall.append([float(c) for c in line.split()]) data_dos = [] with open(os.path.join(path_dir, "boltztrap.transdos"), 'r') as f: for line in f: if not line.startswith(" #"): data_dos.append([ Energy(line.split()[0], "Ry").to("eV"), 2 * Energy(line.split()[1], "eV").to("Ry") ]) with open(os.path.join(path_dir, "boltztrap.outputtrans"), 'r') as f: warning = False step = 0 for line in f: if "WARNING" in line: warning = True if line.startswith("VBM"): efermi = Energy(line.split()[1], "Ry").to("eV") if step == 2: l_tmp = line.split("-")[1:] doping.extend([-float(d) for d in l_tmp]) step = 0 if step == 1: doping.extend([float(d) for d in line.split()]) step = 2 if line.startswith("Doping levels to be output for") or \ line.startswith(" Doping levels to be output for"): step = 1 if line.startswith("Egap:"): gap = float(line.split()[1]) if len(doping) != 0: with open(os.path.join(path_dir, "fort.26"), 'r') as f: for line in f: if not line.startswith("#") and len(line) > 2: data_doping_full.append( [float(c) for c in line.split()]) with open(os.path.join(path_dir, "fort.27"), 'r') as f: for line in f: if not line.startswith("#") and len(line) > 2: data_doping_hall.append( [float(c) for c in line.split()]) with open(os.path.join(path_dir, "boltztrap.struct"), 'r') as f: tokens = f.readlines() vol = Lattice([[ Length(float(tokens[i].split()[j]), "bohr").to("ang") for j in range(3) ] for i in range(1, 4)]).volume return BoltztrapAnalyzer._make_boltztrap_analyzer_from_data( data_full, data_hall, data_dos, sorted([t for t in t_steps]), sorted([Energy(m, "Ry").to("eV") for m in m_steps]), efermi, Energy(gap, "Ry").to("eV"), doping, data_doping_full, data_doping_hall, vol, warning)
def _parse_job(self, output): energy_patt = re.compile("Total \w+ energy\s+=\s+([\.\-\d]+)") #In cosmo solvation results; gas phase energy = -152.5044774212 energy_gas_patt = re.compile("gas phase energy\s+=\s+([\.\-\d]+)") #In cosmo solvation results; sol phase energy = -152.5044774212 energy_sol_patt = re.compile("sol phase energy\s+=\s+([\.\-\d]+)") coord_patt = re.compile("\d+\s+(\w+)\s+[\.\-\d]+\s+([\.\-\d]+)\s+" "([\.\-\d]+)\s+([\.\-\d]+)") corrections_patt = re.compile("([\w\-]+ correction to \w+)\s+=" "\s+([\.\-\d]+)") preamble_patt = re.compile("(No. of atoms|No. of electrons" "|SCF calculation type|Charge|Spin " "multiplicity)\s*:\s*(\S+)") error_defs = { "calculations not reaching convergence": "Bad convergence", "Calculation failed to converge": "Bad convergence", "geom_binvr: #indep variables incorrect": "autoz error", "dft optimize failed": "Geometry optimization failed" } data = {} energies = [] frequencies = None corrections = {} molecules = [] species = [] coords = [] errors = [] basis_set = {} parse_geom = False parse_freq = False parse_bset = False job_type = "" for l in output.split("\n"): for e, v in error_defs.items(): if l.find(e) != -1: errors.append(v) if parse_geom: if l.strip() == "Atomic Mass": molecules.append(Molecule(species, coords)) species = [] coords = [] parse_geom = False else: m = coord_patt.search(l) if m: species.append(m.group(1).capitalize()) coords.append([ float(m.group(2)), float(m.group(3)), float(m.group(4)) ]) if parse_freq: if len(l.strip()) == 0: if len(frequencies[-1][1]) == 0: continue else: parse_freq = False else: vibs = [float(vib) for vib in l.strip().split()[1:]] num_vibs = len(vibs) for mode, dis in zip(frequencies[-num_vibs:], vibs): mode[1].append(dis) elif parse_bset: if l.strip() == "": parse_bset = False else: toks = l.split() if toks[0] != "Tag" and not re.match("\-+", toks[0]): basis_set[toks[0]] = dict( zip(bset_header[1:], toks[1:])) elif toks[0] == "Tag": bset_header = toks bset_header.pop(4) bset_header = [h.lower() for h in bset_header] else: m = energy_patt.search(l) if m: energies.append(Energy(m.group(1), "Ha").to("eV")) continue m = energy_gas_patt.search(l) if m: cosmo_scf_energy = energies[-1] energies[-1] = dict() energies[-1].update({"cosmo scf": cosmo_scf_energy}) energies[-1].update( {"gas phase": Energy(m.group(1), "Ha").to("eV")}) m = energy_sol_patt.search(l) if m: energies[-1].update( {"sol phase": Energy(m.group(1), "Ha").to("eV")}) m = preamble_patt.search(l) if m: try: val = int(m.group(2)) except ValueError: val = m.group(2) k = m.group(1).replace("No. of ", "n").replace(" ", "_") data[k.lower()] = val elif l.find("Geometry \"geometry\"") != -1: parse_geom = True elif l.find("Summary of \"ao basis\"") != -1: parse_bset = True elif l.find("P.Frequency") != -1: parse_freq = True if not frequencies: frequencies = [] frequencies.extend([(float(freq), []) for freq in l.strip().split()[1:]]) elif job_type == "" and l.strip().startswith("NWChem"): job_type = l.strip() if job_type == "NWChem DFT Module" and \ "COSMO solvation results" in output: job_type += " COSMO" else: m = corrections_patt.search(l) if m: corrections[m.group(1)] = FloatWithUnit( m.group(2), "kJ mol^-1").to("eV atom^-1") if frequencies: for freq, mode in frequencies: mode[:] = zip(*[iter(mode)] * 3) data.update({ "job_type": job_type, "energies": energies, "corrections": corrections, "molecules": molecules, "basis_set": basis_set, "errors": errors, "has_error": len(errors) > 0, "frequencies": frequencies }) return data
def from_files(path_dir): """ get a BoltztrapAnalyzer object from a set of files Args: path_dir: directory where the boltztrap files are Returns: a BoltztrapAnalyzer object """ t_steps = set() m_steps = set() gap = None doping = [] data_doping_full = [] data_doping_hall = [] with open(os.path.join(path_dir, "boltztrap.condtens"), 'r') as f: data_full = [] for line in f: if not line.startswith("#"): t_steps.add(int(float(line.split()[1]))) m_steps.add(float(line.split()[0])) data_full.append([float(c) for c in line.split()]) with open(os.path.join(path_dir, "boltztrap.halltens"), 'r') as f: data_hall = [] for line in f: if not line.startswith("#"): data_hall.append([float(c) for c in line.split()]) data_dos = {'total': [], 'partial':{}} with open(os.path.join(path_dir, "boltztrap.transdos"), 'r') as f: count_series = 0 for line in f: if not line.startswith(" #"): data_dos['total'].append([Energy(float(line.split()[0]), "Ry").to("eV"), float(line.split()[1])]) else: count_series += 1 if count_series>1: break #data_dos['total'].append([float(line.split()[0]), # float(line.split()[1])]) for file_name in os.listdir(path_dir): if file_name.endswith("transdos") and file_name != 'boltztrap.transdos': tokens = file_name.split(".")[1].split("_") with open(os.path.join(path_dir, file_name), 'r') as f: for line in f: if not line.startswith(" #"): if tokens[1] not in data_dos['partial']: data_dos['partial'][tokens[1]] = {} if tokens[2] not in data_dos['partial'][tokens[1]]: data_dos['partial'][tokens[1]][tokens[2]] = [] data_dos['partial'][tokens[1]][tokens[2]].append(float(line.split()[1])) with open(os.path.join(path_dir, "boltztrap.outputtrans"), 'r') as f: warning = False step = 0 for line in f: if "WARNING" in line: warning = True if line.startswith("VBM"): efermi = Energy(line.split()[1], "Ry").to("eV") if step == 2: l_tmp = line.split("-")[1:] doping.extend([-float(d) for d in l_tmp]) step = 0 if step == 1: doping.extend([float(d) for d in line.split()]) step = 2 if line.startswith("Doping levels to be output for") or \ line.startswith(" Doping levels to be output for"): step = 1 if line.startswith("Egap:"): gap = float(line.split()[1]) if len(doping) != 0: with open(os.path.join(path_dir, "boltztrap.condtens_fixdoping"), 'r') as f: for line in f: if not line.startswith("#") and len(line) > 2: data_doping_full.append([float(c) for c in line.split()]) with open(os.path.join(path_dir, "boltztrap.halltens_fixdoping"), 'r') as f: for line in f: if not line.startswith("#") and len(line) > 2: data_doping_hall.append([float(c) for c in line.split()]) with open(os.path.join(path_dir, "boltztrap.struct"), 'r') as f: tokens = f.readlines() vol = Lattice([[Length(float(tokens[i].split()[j]), "bohr").to("ang") for j in range(3)] for i in range(1, 4)]).volume return BoltztrapAnalyzer._make_boltztrap_analyzer_from_data( data_full, data_hall, data_dos, sorted([t for t in t_steps]), sorted([Energy(m, "Ry").to("eV") for m in m_steps]), efermi, Energy(gap, "Ry").to("eV"), doping, data_doping_full, data_doping_hall, vol, warning)
def _make_boltztrap_analyzer_from_data( data_full, data_hall, data_dos, temperature_steps, mu_steps, efermi, gap, doping, data_doping_full, data_doping_hall, vol, warning=False): """ Make a BoltztrapAnalyzer object from raw data typically parse from files. """ cond = {t: [] for t in temperature_steps} seebeck = {t: [] for t in temperature_steps} kappa = {t: [] for t in temperature_steps} hall = {t: [] for t in temperature_steps} carrier_conc = {t: [] for t in temperature_steps} dos_full = {'energy': [], 'density': []} warning = warning new_doping = {'p': [], 'n': []} for d in doping: if d > 0: new_doping['p'].append(d) else: new_doping['n'].append(-d) mu_doping = {'p': {t: [] for t in temperature_steps}, 'n': {t: [] for t in temperature_steps}} seebeck_doping = {'p': {t: [] for t in temperature_steps}, 'n': {t: [] for t in temperature_steps}} cond_doping = {'p': {t: [] for t in temperature_steps}, 'n': {t: [] for t in temperature_steps}} kappa_doping = {'p': {t: [] for t in temperature_steps}, 'n': {t: [] for t in temperature_steps}} hall_doping = {'p': {t: [] for t in temperature_steps}, 'n': {t: [] for t in temperature_steps}} for d in data_full: carrier_conc[d[1]].append(d[2]) tens_cond = [[d[3], d[4], d[5]], [d[6], d[7], d[8]], [d[9], d[10], d[11]]] cond[d[1]].append(tens_cond) tens_seebeck = [[d[12], d[13], d[14]], [d[15], d[16], d[17]], [d[18], d[19], d[20]]] seebeck[d[1]].append(tens_seebeck) tens_kappa = [[d[21], d[22], d[23]], [d[24], d[25], d[26]], [d[27], d[28], d[29]]] kappa[d[1]].append(tens_kappa) for d in data_hall: hall_tens = d[3:] hall[d[1]].append(hall_tens) for d in data_doping_full: tens_cond = [[d[2], d[3], d[4]], [d[5], d[6], d[7]], [d[8], d[9], d[10]]] tens_seebeck = [[d[11], d[12], d[13]], [d[14], d[15], d[16]], [d[17], d[18], d[19]]] tens_kappa = [[d[20], d[21], d[22]], [d[23], d[24], d[25]], [d[26], d[27], d[28]]] if d[1] < 0: mu_doping['n'][d[0]].append(Energy(d[-1], "Ry").to("eV")) cond_doping['n'][d[0]].append(tens_cond) seebeck_doping['n'][d[0]].append(tens_seebeck) kappa_doping['n'][d[0]].append(tens_kappa) else: mu_doping['p'][d[0]].append(Energy(d[-1], "Ry").to("eV")) cond_doping['p'][d[0]].append(tens_cond) seebeck_doping['p'][d[0]].append(tens_seebeck) kappa_doping['p'][d[0]].append(tens_kappa) for i in range(len(data_doping_hall)): hall_tens = [data_hall[i][j] for j in range(3, len(data_hall[i]))] if data_doping_hall[i][1] < 0: hall_doping['n'][data_doping_hall[i][0]].append(hall_tens) else: hall_doping['p'][data_doping_hall[i][0]].append(hall_tens) for t in data_dos['total']: dos_full['energy'].append(t[0]) dos_full['density'].append(t[1]) dos = Dos(efermi, dos_full['energy'], {Spin.up: dos_full['density']}) dos_partial = data_dos['partial'] return BoltztrapAnalyzer( gap, mu_steps, cond, seebeck, kappa, hall, new_doping, mu_doping, seebeck_doping, cond_doping, kappa_doping, hall_doping, dos, dos_partial, carrier_conc, vol, warning)