def eosfit_spec(atoms, calc, rg, method="birchmurnaghan"): from ase.eos import EquationOfState from numpy import linspace rootdir = os.getcwd() if not os.path.exists('eosfit'): os.mkdir('eosfit') os.chdir('eosfit') cell = atoms.get_cell() atoms.set_calculator(calc) traj = Trajectory('eosfit.traj', 'w') for x in rg: print(str(x)) atoms.set_cell(cell * x, scale_atoms=True) atoms.get_potential_energy() traj.write(atoms) configs = Trajectory('eosfit.traj', 'r') volumes = [at.get_volume() for at in configs] energies = [at.get_potential_energy() for at in configs] eos = EquationOfState(volumes, energies, eos=method) v0, e0, B = eos.fit() eos.plot('eosfit.svg') fp = open('eosdata.dat', 'w') fp.write('Volume\t\tEnergy') for i in range(len(configs)): fp.write(str(volumes[i]) + '\t' + str(energies[i]) + '\n') os.chdir(rootdir)
def run_task(self,fw_spec): jobID,latticeParams = fw_spec['jobID'],fw_spec['latticeParams'] # WHY IS LATTICEPARAMS [[FLOAT]] INSTEAD OF [FLOAT]? job = db2object(jobID) existsPrecalc = job.precalc != 'None' optAtoms = job.fromParams(latticeParams[0]) optCell = optAtoms.get_cell() strains = np.linspace(1-job.strain,1+job.strain,9) calc = job.calc(restart=True) if existsPrecalc else job.calc() vol,eng = [],[] for i, strain in enumerate(strains): atoms = optAtoms.copy() atoms.set_cell(optCell*strain,scale_atoms=True) if existsPrecalc: preCalc = job.calc(precalc=True) job.optimizePos(atoms,preCalc,saveWF = True) if job.dftcode =='gpaw': atoms,calc = job.gpawRestart() job.optimizePos(atoms,calc) energy = atoms.get_potential_energy() volume = atoms.get_volume() vol.append(deepcopy(volume)) eng.append(deepcopy(energy)) parprint('%f %f'%(strain,energy)) with paropen('bulkmod.log','a') as logfile: logfile.write('%s\t%s\n' %(strain,energy)) parprint('%f %f'%(strain,energy)) aHat,quadR2 = quadFit(np.array(deepcopy(vol)),np.array(deepcopy(eng))) try: eos = EquationOfState(vol,eng) v0, e0, b = eos.fit() eos.plot(filename='bulk-eos.png',show=False) b0= b/kJ*1e24 #GPa use this value if EOS doesn't fail except ValueError: # too bad of a fit for ASE to handle b0 = aHat*2*vol[4]*160.2 # units: eV/A^6 * A^3 * 1, where 1 === 160.2 GPa*A^3/eV return FWAction( stored_data= {'b0':b0,'quadR2':quadR2} ,mod_spec=[{'_push': {'b0':b0,'quadR2':quadR2}}])
def ev_bulk(volumes, energies, plot_name): """Plot volume energy curve and calculates bulk modulus Args: volumes (list of float): The volumes correlated to the energies calculated. energies (list of float): The energies the cell calculated by gfn0 xtb. plot_name (str): The file name the plot is saved to. Returns: v0 (float): The volume of minimum energy. e0 (float): The fitted minimum energy of the V/E curve. B (float): The calculated bulk modulus. """ volumes = np.array(volumes) energies = np.array(energies) * Hartree / eV eos = EquationOfState(volumes, energies, eos="murnaghan") v0, e0, B = eos.fit() print(B / kJ * 1.0e24, "GPa") # Converts into GPa ax = eos.plot() fig = plt.gcf() fig.set_size_inches(8, 5) fig.savefig(plot_name) return v0, e0, B
def fit_a(conv, n, description_for_archive, analysis_type, show, push2archive): """Fit equation of state for bulk systems. The following equation is used:: sjeos (default) A third order inverse polynomial fit 10.1103/PhysRevB.67.026103 2 3 -1/3 E(V) = c + c t + c t + c t , t = V 0 1 2 3 taylor A third order Taylor series expansion about the minimum volume murnaghan PRB 28, 5480 (1983) birch Intermetallic compounds: Principles and Practice, Vol I: Principles. pages 195-210 birchmurnaghan PRB 70, 224107 pouriertarantola PRB 70, 224107 vinet PRB 70, 224107 antonschmidt Intermetallics 11, 23-32 (2003) p3 A third order polynomial fit Use:: eos = EquationOfState(volumes, energies, eos='sjeos') v0, e0, B = eos.fit() eos.plot() """ # e, v, emin, vmin = plot_conv( conv[n], calc, "fit_gb_volume2") alist = [] vlist = [] etotlist = [] magn1 = [] magn2 = [] alphas = [] for id in conv[n]: cl = db[id] st = cl.end alist.append(cl.end.rprimd[0][0]) etotlist.append(cl.energy_sigma0) vlist.append(cl.end.vol) magn1.append(cl.magn1) magn2.append(cl.magn2) alpha, beta, gamma = st.get_angles() alphas.append(alpha) print('alpha, energy: {:4.2f}, {:6.3f}'.format(alpha, cl.energy_sigma0)) fit_and_plot(U1=(alphas, etotlist, 'o-r'), image_name='figs/angle', ylabel='Total energy, eV', xlabel='Angle, deg', xlim=(89, 92.6)) if ase_flag: if 'angle' in analysis_type: eos = EquationOfState(alphas, etotlist, eos='sjeos') else: eos = EquationOfState(vlist, etotlist, eos='sjeos') # import inspect # print (inspect.getfile(EquationOfState)) v0, e0, B = eos.fit() #print "c = ", clist[2] printlog(''' v0 = {0} A^3 a0 = {1} A E0 = {2} eV B = {3} eV/A^3'''.format(v0, v0**(1. / 3), e0, B), imp='Y') savedpath = 'figs/' + cl.name + '.png' makedir(savedpath) cl.B = B * 160.218 # plt.close() # plt.clf() # plt.close('all') if 'fit' in show: mpl.rcParams.update({'font.size': 14}) eos.plot(savedpath, show=True) printlog('fit results are saved in ', savedpath, imp='y') else: printlog('To use fitting install ase: pip install ase') # plt.clf() if push2archive: push_figure_to_archive(local_figure_path=savedpath, caption=description_for_archive) return
from ase.units import kJ, Bohr, Hartree from ase.eos import EquationOfState import numpy as np filename = "TEMP_EOS_data.dat" dat = np.loadtxt(filename) # dont forget to convert to Angstrom and eV volumes = dat[:,0]**3/2.0 * Bohr**3 # only for bcc energies = dat[:,1]*Hartree energies_abinit = dat[:,2]*Hartree energies_pwscf = dat[:,3]*Hartree eos = EquationOfState(volumes, energies) v0, e0, B = eos.fit() print("PWDFT.jl: B = %18.10f GPa" % (B/kJ * 1.0e24)) eos.plot("pwdft-eos-ase.pdf") eos = EquationOfState(volumes, energies_abinit) v0, e0, B = eos.fit() print("ABINIT : B = %18.10f GPa" % (B/kJ * 1.0e24)) eos.plot("abinit-eos-ase.pdf") eos = EquationOfState(volumes, energies_pwscf) v0, e0, B = eos.fit() print("PWSCF : B = %18.10f GPa" % (B/kJ * 1.0e24)) eos.plot("pwscf-eos-ase.pdf")
INP_FILELIST.append(pwinput.filename) pwinput.write() # run commands OUT_FILELIST = [] for i, f in enumerate(INP_FILELIST): fileout = "OUT_PW_" + str(i) OUT_FILELIST.append(fileout) # Uncomment this if the run is already done os.system("pw.x < " + f + " > " + fileout) print("Running " + str(i) + " is done") ene = np.zeros(len(OUT_FILELIST)) for i, f in enumerate(OUT_FILELIST): ene[i] = read_pwscf_energy(f) print("ene[i] = ", ene[i]) from ase.units import Bohr, kJ from ase.eos import EquationOfState volumes = A_LIST[:]**3 / 4.0 # fcc volumes (in Angstrom^3) ene[:] = ene[:] * Ry # convert to eV eos = EquationOfState(volumes, ene) v0, e0, B = eos.fit() print("B = %18.10f GPa" % (B / kJ * 1.0e24)) eos.plot("IMG_fit_EOS.pdf") a_calc = (4 * v0)**(1 / 3) print("a_exp = ", a_exp) print("a_calc = ", a_calc)
def genstr(scale): atoms = read('str.cif') # Scale the cell cell = atoms.get_cell() cell[2][2] = scale * cell[2][2] atoms.set_cell(cell, scale_atoms=False) # Translate Li, F atoms vertically for j in range(len(atoms)): if atoms[j].symbol != 'C': atoms[j].position[2] += (scale - 1) * 11.08 / 2 return atoms # Main for i, scale in enumerate(np.linspace(0.85, 1.0, num=5)): atoms = genstr(scale) atoms.calc = GPAW(xc=xc, kpts=kpoints, gpts=gpoints, txt=str(i) + '.txt') e.append(atoms.get_potential_energy()) v.append(atoms.get_volume()) eos = EquationOfState(v, e, eos='birchmurnaghan') v0, e0, B = eos.fit() eos.plot('eos.png', show=False) opt_scale = v0 / read('str.cif').get_volume() write('opt_str.cif', genstr(opt_scale))
cell_0 = al.cell # Unit cell object of the Al bulk for eps in np.linspace(-0.02, 0.02, N_lattice_spacings): al.cell = ( 1 + eps) * cell_0 # Adjust lattice constant of unit cell # Calculate the potential energy for the Al bulk energies.append(al.get_potential_energy()) volumes.append(al.get_volume()) # # confs = read('out.txt@0:' + str(N_lattice_spacings)) # Read the configurations # # Extract volumes and energies: # volumes = [atoms.get_volume() for atoms in confs] # energies = [atoms.get_potential_energy() for atoms in confs] # # if rank == 0: # # print energies, shape(energies) # if rank == 0: print 'Energies: ' + str(energies) print 'Volumes: ' + str(volumes) # Plot energies as a function of unit cell volume (directly related to latt. const.) eos = EquationOfState(volumes, energies) v0, E_bulk, B = eos.fit() eos.plot('Al_eos.png') # Latt. const. acc. to ASE doc., but why is this correct? a_calc = (4 * v0)**(1 / 3.0) print 'a_calc: ' + str(a_calc) else: al.get_potential_energy()
def getBulkModulus(jobID, latticeParams): """ Use optimized lattice parameters from fmin(getEnergy). Calculate energies around the minimum. Returns optimized atomic positions, energy of minimum, calculated bulk modulus, and writes wavefunctions to file inp.gpw """ ### INITIALIZE vol, eng = [], [] jobObject, bulkObject, calcObject, dft, preCalcObject, preCalcObject, existsPrecalc, optAtoms, magmoms = initialize( jobID, latticeParams) with open('lattice_opt.log', 'r') as f: nIter = len(f.readlines()) + 9 #count number of ionic steps taken optCell = optAtoms.get_cell() strains = np.linspace(0.99, 1.01, 9) ### GENERATE dE/dV plot for i, strain in enumerate(strains): atoms = deepcopy(optAtoms) atoms.set_cell(optCell * strain, scale_atoms=True) ### PRECALCULATE if existsPrecalc: optimizePos(atoms, dft, preCalcObject, magmoms, restart=False, saveWF=True) ### CALCULATE optimizePos(atoms, dft, calcObject, magmoms, restart=existsPrecalc, saveWF=False) ### COLLECT RESULTS energy = atoms.get_potential_energy() volume = atoms.get_volume() vol.append(deepcopy(volume)) eng.append(deepcopy(energy)) parprint('%f %f' % (strain, energy)) ### COLLECT DETAILED DATA ABOUT MINIMUM ENERGY STATE if i == 4: pos = atoms.get_scaled_positions() vMin = deepcopy(volume) io.write('optimized.traj', atoms) magmom = atoms.get_magnetic_moments( ) if calcObject.magmom > 0 else np.zeros(len(atoms)) if dft == 'gpaw': atoms.calc.write('inp.gpw', mode='all') #for use in getXCContribs aHat, quadR2 = quadFit(np.array(deepcopy(vol)), np.array(deepcopy(eng))) b0 = aHat * 2 * vMin * 160.2 # units: eV/A^6 * A^3 * 1, where 1 === 160.2 GPa*A^3/eV parprint('quadR2 = ' + str(quadR2)) try: eos = EquationOfState(vol, eng) v0, e0, b = eos.fit() eos.plot(filename='bulk-eos.png', show=False) b0 = b / kJ * 1e24 #GPa use this value if EOS doesn't fail except ValueError: e0 = eng[4] return (optCell, nIter, pos, magmom, e0, b0, quadR2) #GPa
from ase.io import read from ase.units import kJ from ase.eos import EquationOfState configs = read('Ag.traj@0:5') # read 5 configurations # Extract volumes and energies: volumes = [ag.get_volume() for ag in configs] energies = [ag.get_potential_energy() for ag in configs] eos = EquationOfState(volumes, energies) v0, e0, B = eos.fit() print(B / kJ * 1.0e24, 'GPa') eos.plot('Ag-eos.png')
#!/usr/bin/env python import numpy as np import matplotlib.pyplot as plt from ase.io import read from pprint import pprint from ase.eos import EquationOfState path = '../hebbe_import/bulk/' atoms = read(path + 'bulk.txt@:') volumes = [atom.get_volume() for atom in atoms] energies = [atom.get_potential_energy() for atom in atoms] eos = EquationOfState(volumes, energies) v0, e0, B = eos.fit() a = (4 * v0)**(1 / 3) # there are 4 atoms per unit cell in an fcc print(a) eos.plot() eos.plot('images/Al-eos.png')
""" cell = bulk.get_cell() traj = Trajectory('bulk.traj', 'w') for x in np.linspace(0.90, 1.10, 5): bulk.set_cell(cell * x, scale_atoms=True) bulk.get_potential_energy() traj.write(bulk) ########## EOS ############# from ase.io import read from ase.units import kJ from ase.eos import EquationOfState configs = read('bulk.traj@0:5') # read 10 configurations # Extract volumes and energies: volumes = [bulk.get_volume() for bulk in configs] energies = [bulk.get_potential_energy() for bulk in configs] eos = EquationOfState(volumes, energies, eos='birchmurnaghan') v0, e0, B = eos.fit() # Return info on optimised system print("Volume: ", v0 + " Angstrom^3") print("Total energy at a0: " + e0 + " eV") print("FCC Lattice parameter a0: ", (4*v0)**(1/3), "Angstrom") #print("FCC Lattice parameter a0: ", (4*v0/NUMBER_OF_ATOMS_IN_UNIT_CELL)**(1/3), "Angstrom") print("Bulk modulus: ", B / kJ * 1.0e24, 'GPa') eos.plot('bulk-eos.png') #view('bulk.traj')
'{0: <4.4f}'.format(B / kJ * 1e24), 'GPa', file=f) print('Bulk modulus found using DFT = 211 GPa', file=f) print( '--------------------------------------------------------------------------------------------', file=f) print( '\n-----------------Birch-Murnaghan Equation of states of rutile TiO2-------------------------' ) print('Equilibrium volume = ', '{0: <4.4f}'.format(v0), 'eV') print('Equilibrium energy = ', '{0: <4.4f}'.format(e0), 'ij') print('Bulk modulus predicted by NN model = ', '{0: <4.4f}'.format(B / kJ * 1e24), 'GPa') print('Bulk modulus found using DFT = 211 GPa') print( '--------------------------------------------------------------------------------------------' ) #print(v0,e0,B/kJ * 1e24) fig = plt.figure(figsize=(7, 4), dpi=150) plt.xlabel('volume[ij]') plt.ylabel('energy [eV]') plt.title('Equation of states of rutile TiO2') fig.tight_layout() plt.grid('True') eos.plot('eos.png') fig.savefig('plots/eos') plt.show()
f = open('volumes_energies.txt', 'rU') energies = [] volumes = [] lines = f.readlines() for i in range(len(lines) - 1): volumes.append(float(lines[i + 1].split()[0])) energies.append(float(lines[i + 1].split()[1])) f.close() eos = EquationOfState(volumes, energies, eos='birchmurnaghan') volume, energy, bulkmodulus = eos.fit() latticeconstant = volume**(1. / 3.) f = open('log.txt', 'w+') f.write('lattice constant = {0:18.7f} A\n'.format(latticeconstant)) f.write('bulk energy = {0:18.7f} eV\n'.format(energy)) f.write('bulk modulus = {0:18.7f} eV/A^3\n'.format(bulkmodulus)) f.close() if plot_eos is True: eos.plot(show=True) ################################################################################ # END ################################################################################
e = atoms.get_potential_energy() v = atoms.get_volume() datas.append([latt, v, e]) print('$data {0:1.2f} {1:1.4f} {2:1.4f}'.format(latt, v, e)) latts=np.linspace(3.75, 4.00, num=6) print('------------------------------------------') print('latt volume energy (eV) bond length (A)') pool = Pool(processes=10) for latt in latts: pool.apply_async(run, (latt, atoms, datas)) pool.close() pool.join() energies = [] volumes = [] f = open('datas/relax.dat') lines = f.readlines() for line in lines: if line[0:5] == '$data': latt, v, e = line.split()[1:4] energies.append(float(e)) volumes.append(float(v)) eos = EquationOfState(volumes, energies) v0, e0, B = eos.fit() print(B * 162, 'GPa') eos.plot('pt-eos.png')