def gas_chemical_potential(species, temperature, fugacity): """For a gas, given its temperature (K) and fugacity (Pa), returns its chemical potential. Args: species (string) temperature (float) fugacity (float) Raises: RuntimeError """ if not gasprops.has_key(species): raise RuntimeError('Data for this gas (%s) is not in gasprops' 'dictionary. Add to hori.thermo.gasprops' % species) d = io.gasdata(species) p = gasprops[species] electronic_energy = (d['electronic energy'] + p['electronic energy correction']) thermo = IdealGasThermo(vib_energies=d['vibrations'], electronicenergy=electronic_energy, geometry=p['geometry'], atoms=d['atoms'], symmetrynumber=p['symmetrynumber'], spin=p['spin']) mu = thermo.get_gibbs_energy(temperature=temperature, pressure=fugacity) #mu = thermo.get_gibbs_energy(temperature=temperature,pressure=fugacity) return mu
def get_enthalpy(self, temperature=T_std, electronic_energy='Default'): """Returns the internal energy of an adsorbed molecule. Parameters ---------- temperature : numeric temperature in K electronic_energy : numeric energy in eV Returns ------- internal_energy : numeric Internal energy in eV """ if not temperature: # either None or 0 return (0, 0, 0) if electronic_energy == 'Default': electronic_energy = molecule_dict[self.name]['electronic_energy'] else: ideal_gas_object = IdealGasThermo( vib_energies=self.get_vib_energies(), potentialenergy=electronic_energy, atoms=self.atom_object, geometry=molecule_dict[self.name]['geometry'], symmetrynumber=molecule_dict[self.name]['symmetrynumber'], spin=molecule_dict[self.name]['spin']) energy = ideal_gas_object.get_enthalpy(temperature=temperature, verbose=False) self.enthalpy = energy return (self.enthalpy)
def setUp(self): unittest.TestCase.setUp(self) # Testing Ideal Gas Model CO2 = molecule('CO2') CO2_pmutt_parameters = { 'name': 'CO2', 'elements': { 'C': 1, 'O': 2 }, 'trans_model': trans.FreeTrans, 'n_degrees': 3, 'molecular_weight': get_molecular_weight('CO2'), 'rot_model': rot.RigidRotor, 'rot_temperatures': rot.get_rot_temperatures_from_atoms(CO2, geometry='linear'), 'geometry': 'linear', 'symmetrynumber': 2, 'elec_model': elec.GroundStateElec, 'potentialenergy': -22.994202, 'spin': 0., 'vib_model': vib.HarmonicVib, 'vib_wavenumbers': [3360., 954., 954., 1890.], } CO2_ase_parameters = { 'atoms': CO2, 'potentialenergy': -22.994202, 'vib_energies': [ c.wavenumber_to_energy(x) * c.convert_unit(initial='J', final='eV') for x in CO2_pmutt_parameters['vib_wavenumbers'] ], 'geometry': 'linear', 'symmetrynumber': 2, 'spin': 0. } self.CO2_pmutt = StatMech(**CO2_pmutt_parameters) self.CO2_ASE = IdealGasThermo(**CO2_ase_parameters) self.T0 = c.T0('K') # K self.P0 = c.P0('Pa') self.V0 = c.V0('m3') self.mw = get_molecular_weight({'C': 1, 'O': 2})
def get_thermo_correction( self, coords: simtk.unit.quantity.Quantity) -> unit.quantity.Quantity: """ Returns the thermochemistry correction. This calls: https://wiki.fysik.dtu.dk/ase/ase/thermochemistry/thermochemistry.html and uses the Ideal gas rigid rotor harmonic oscillator approximation to calculate the Gibbs free energy correction that needs to be added to the single point energy to obtain the Gibb's free energy coords: [K][3] Raises: verror: if imaginary frequencies are detected a ValueError is raised Returns: float -- temperature correct [kT] """ if not (len(coords.shape) == 3 and coords.shape[2] == 3 and coords.shape[0] == 1): raise RuntimeError( f"Something is wrong with the shape of the provided coordinates: {coords.shape}. Only x.shape[0] == 1 is possible." ) ase_mol = copy.deepcopy(self.ase_mol) for atom, c in zip(ase_mol, coords[0]): atom.x = c[0].value_in_unit(unit.angstrom) atom.y = c[1].value_in_unit(unit.angstrom) atom.z = c[2].value_in_unit(unit.angstrom) calculator = self.model.ase() ase_mol.set_calculator(calculator) vib = Vibrations(ase_mol, name=f"/tmp/vib{random.randint(1,10000000)}") vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo( vib_energies=vib_energies, atoms=ase_mol, geometry="nonlinear", symmetrynumber=1, spin=0, ) try: G = thermo.get_gibbs_energy( temperature=temperature.value_in_unit(unit.kelvin), pressure=pressure.value_in_unit(unit.pascal), ) except ValueError as verror: logger.critical(verror) vib.clean() raise verror # removes the vib tmp files vib.clean() return ( G * eV_to_kJ_mol ) * unit.kilojoule_per_mole # eV * conversion_factor(eV to kJ/mol)
def test_vib(): import os from ase import Atoms from ase.calculators.emt import EMT from ase.optimize import QuasiNewton from ase.vibrations import Vibrations from ase.thermochemistry import IdealGasThermo n2 = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) QuasiNewton(n2).run(fmax=0.01) vib = Vibrations(n2) vib.run() freqs = vib.get_frequencies() print(freqs) vib.summary() print(vib.get_mode(-1)) vib.write_mode(n=None, nimages=20) vib_energies = vib.get_energies() for image in vib.iterimages(): assert len(image) == 2 thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=n2, symmetrynumber=2, spin=0) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.) assert vib.clean(empty_files=True) == 0 assert vib.clean() == 13 assert len(list(vib.iterimages())) == 13 d = dict(vib.iterdisplace(inplace=False)) for name, atoms in vib.iterdisplace(inplace=True): assert d[name] == atoms vib = Vibrations(n2) vib.run() assert vib.combine() == 13 assert (freqs == vib.get_frequencies()).all() vib = Vibrations(n2) assert vib.split() == 1 assert (freqs == vib.get_frequencies()).all() assert vib.combine() == 13 # Read the data from other working directory dirname = os.path.basename(os.getcwd()) os.chdir('..') # Change working directory vib = Vibrations(n2, name=os.path.join(dirname, 'vib')) assert (freqs == vib.get_frequencies()).all() assert vib.clean() == 1
def _calculate_one_G(self, gas, verbose=False): d = self.gas_dict[gas] thermo = IdealGasThermo(vib_energies=d['vibrations'], electronicenergy=(d['electronic energy'] + d['electronic energy correction']), geometry=d['geometry'], atoms=d['atoms'], symmetrynumber=d['symmetrynumber'], spin=d['spin']) self.G[gas] = thermo.get_gibbs_energy(d['temperature'], d['fugacity'], verbose=verbose)
def _calculate_one_G(self, gas, verbose=False): d = self.gas_dict[gas] thermo = IdealGasThermo( vib_energies=d['vibrations'], electronicenergy=(d['electronic energy'] + d['electronic energy correction']), geometry=d['geometry'], atoms=d['atoms'], symmetrynumber=d['symmetrynumber'], spin=d['spin']) self.G[gas] = thermo.get_gibbs_energy(d['temperature'], d['fugacity'], verbose=verbose)
def get_free_energy(self, temperature, pressure='Default', electronic_energy='Default', overbinding=True): """Returns the internal energy of an adsorbed molecule. Parameters ---------- temperature : numeric temperature in K electronic_energy : numeric energy in eV pressure : numeric pressure in mbar Returns ------- internal_energy : numeric Internal energy in eV """ if not temperature or not pressure: # either None or 0 return (0) else: if electronic_energy == 'Default': electronic_energy = molecule_dict[ self.name]['electronic_energy'] if overbinding == True: electronic_energy += molecule_dict[ self.name]['overbinding'] else: pass if pressure == 'Default': pressure = molecule_dict[self.name]['pressure'] else: pass pressure = pressure * 100 # gives Pa ideal_gas_object = IdealGasThermo( vib_energies=self.get_vib_energies(), potentialenergy=electronic_energy, atoms=self.atom_object, geometry=molecule_dict[self.name]['geometry'], symmetrynumber=molecule_dict[self.name]['symmetrynumber'], spin=molecule_dict[self.name]['spin']) # Returns the Gibbs free energy, in eV, in the ideal gas # approximation at a specified temperature (K) and pressure (Pa). self.free_energy = ideal_gas_object.get_gibbs_energy( temperature=temperature, pressure=pressure, verbose=False) return self.free_energy
def test_vibrations_methods(self, testdir, random_dimer): vib = Vibrations(random_dimer) vib.run() vib_energies = vib.get_energies() for image in vib.iterimages(): assert len(image) == 2 thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=vib.atoms, symmetrynumber=2, spin=0) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325., verbose=False) with open(self.logfile, 'w') as fd: vib.summary(log=fd) with open(self.logfile, 'rt') as fd: log_txt = fd.read() assert log_txt == '\n'.join( VibrationsData._tabulate_from_energies(vib_energies)) + '\n' last_mode = vib.get_mode(-1) scale = 0.5 assert_array_almost_equal( vib.show_as_force(-1, scale=scale, show=False).get_forces(), last_mode * 3 * len(vib.atoms) * scale) vib.write_mode(n=3, nimages=5) for i in range(3): assert not Path('vib.{}.traj'.format(i)).is_file() mode_traj = ase.io.read('vib.3.traj', index=':') assert len(mode_traj) == 5 assert_array_almost_equal(mode_traj[0].get_all_distances(), random_dimer.get_all_distances()) with pytest.raises(AssertionError): assert_array_almost_equal(mode_traj[4].get_all_distances(), random_dimer.get_all_distances()) assert vib.clean(empty_files=True) == 0 assert vib.clean() == 13 assert len(list(vib.iterimages())) == 13 d = dict(vib.iterdisplace(inplace=False)) for name, image in vib.iterdisplace(inplace=True): assert d[name] == random_dimer
def get_mu(p, T): # calculates mu for a given pressure and temperature os.chdir('vibO2') atoms = read('relax.traj') vib = InfraRed(atoms) vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, atoms=atoms, geometry='linear', symmetrynumber=2, spin=1) G = thermo.get_gibbs_energy(temperature=T, pressure=p, verbose=False) delta_mu = 0.5*G#-thermo.get_ZPE_correction()) os.chdir('..') return delta_mu+en_o
def test_ideal_gas_thermo(): atoms = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)]) atoms.calc = EMT() QuasiNewton(atoms).run(fmax=0.01) energy = atoms.get_potential_energy() vib = Vibrations(atoms, name='idealgasthermo-vib') vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=atoms, symmetrynumber=2, spin=0, potentialenergy=energy) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.)
def get_p(mu, T): # calculates p for a given mu and temperature os.chdir('vibO2') atoms = read('relax.traj') vib = InfraRed(atoms) vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, atoms=atoms, geometry='linear', symmetrynumber=2, spin=1) G = thermo.get_gibbs_energy(temperature=T, pressure=thermo.referencepressure, verbose=False) mu_0 = 0.5*G+en_o p=thermo.referencepressure*np.exp(2*(mu-mu_0)/(T*kB)) os.chdir('..') return p
def __init__(self, temperature, voltage, functional): self.temperature = temperature self.voltage = voltage self.functional = functional d = io.gasdata('H2') # hydrogen electrode d['electronic energy correction'] = gasprops['H2'][ 'electronic energy correction'] d['geometry'] = gasprops['H2']['geometry'] d['symmetrynumber'] = gasprops['H2']['symmetrynumber'] d['spin'] = gasprops['H2']['spin'] if functional == 'BEEF': d['electronic energy correction'] = gasprops_BEEF['H2'][ 'electronic energy correction'] self.referencepressure = 101325. # Pa, RHE definition self._previous = {'temperature': None, 'voltage': None} thermo = IdealGasThermo( vib_energies=d['vibrations'], electronicenergy=(d['electronic energy'] + d['electronic energy correction']), geometry=d['geometry'], atoms=d['atoms'], symmetrynumber=d['symmetrynumber'], spin=d['spin']) self._thermo = thermo self._calculate_G()
def get_gas_Gcorr(self,atoms,vibs,symmetrynumber,spin,geometry,verbose=False): gibbs = IdealGasThermo(vib_energies=vibs, potentialenergy=0, atoms=atoms, geometry=geometry, symmetrynumber=symmetrynumber, spin=spin, ) return gibbs
def setUp(self): unittest.TestCase.setUp(self) # Testing Ideal Gas Model CO2 = molecule('CO2') CO2_PyMuTT_parameters = { 'trans_model': trans.IdealTrans, 'n_degrees': 3, 'molecular_weight': get_molecular_weight('CO2'), 'rot_model': rot.RigidRotor, 'rot_temperatures': rot.get_rot_temperatures_from_atoms(CO2, geometry='linear'), 'geometry': 'linear', 'symmetrynumber': 2, 'elec_model': elec.IdealElec, 'potentialenergy': -22.994202, 'spin': 0., 'vib_model': vib.HarmonicVib, 'vib_wavenumbers': [3360., 954., 954., 1890.], } CO2_ase_parameters = { 'atoms': CO2, 'potentialenergy': -22.994202, 'vib_energies': [c.wavenumber_to_energy(x) \ for x in CO2_PyMuTT_parameters['vib_wavenumbers']], 'geometry':'linear', 'symmetrynumber': 2, 'spin': 0. } self.CO2_PyMuTT = StatMech(**CO2_PyMuTT_parameters) self.CO2_ASE = IdealGasThermo(**CO2_ase_parameters) self.T0 = c.T0('K') # K self.P0 = c.P0('Pa') self.V0 = c.V0('m3')
def __init__( self, surf_name=None, surf_class=None, #type species_name=None, species_type=None, traj_loc=None, vib_loc=None, symmetrynumber=None, geometry=None, spin=None, calc_params=None, tag='', ): self.surf_name = surf_name self.surf_class = surf_class self.species_name = species_name self.species_type = species_type self.traj_loc = traj_loc self.symmetrynumber = symmetrynumber self.geometry = geometry self.spin = spin self.tag = tag if calc_params != None: self.calc_params = calc_params if traj_loc != None: self.atoms = read(traj_loc) self.calc_params = self.get_calc_params() if self.calc_params['xc'] == 'BEEF': self.beef = self.beef_reader() else: self.atoms = [] self.calc_params = {} if vib_loc != None: self.vibs = self.vibs_reader(vib_loc) if self.species_type == 'slab': self.gibbs = None elif self.species_type == 'gas': self.gibbs = IdealGasThermo( vib_energies=self.vibs, potentialenergy=0, atoms=self.atoms, geometry=self.geometry, symmetrynumber=self.symmetrynumber, spin=self.spin, ) elif self.species_type == 'adsorbate': self.gibbs = HarmonicThermo(vib_energies=self.vibs, potentialenergy=0) else: print "Warning: unrecognized species_type: ", self.species_type self.gibbs = None
def GibbsGas(self, energy, T, p): #Expecting T in Kelvin, p in bar #note that frequencies should have a lower bound, e.g. 56 cm-1, in order to bound entropic contributions. if self.gas: cm_to_eV = 1.23981e-4 vib_energies = list(self.frequencies) for i in range(len(vib_energies)): vib_energies[i] = vib_energies[i] * cm_to_eV thermo_gas = IdealGasThermo(vib_energies=vib_energies, electronicenergy=energy, atoms=self.atoms, geometry=self.geometry, symmetrynumber=self.symmetrynumber, spin=self.spin) bar_to_Pa = 1e5 pressure = p * bar_to_Pa val = thermo_gas.get_gibbs_energy(temperature=T, pressure=pressure, verbose=False) return val else: raise UserWarning('%s is no gas-phase species.' % self.name)
def get_zpe_energy(self, path_to_vib_species): zpe_energy_dict = {} atoms = read(path_to_vib_species) vib_path = os.path.dirname(path_to_vib_species) os.chdir(vib_path) prefix, species = os.path.basename(path_to_vib_species).split( '.')[0].split('_') indices = [ atom.index for atom in atoms if atom.position[2] > atoms.cell[2, 2] / 2. ] vib = Vibrations(atoms, indices=indices) vib_energies = vib.get_energies() key = prefix + '_' + species try: thermo = IdealGasThermo(vib_energies, atoms) zpe_energy = thermo.get_ZPE_correction() zpe_energy_dict[key] = zpe_energy except ValueError: pass return zpe_energy_dict
class TestStatMech(unittest.TestCase): def setUp(self): unittest.TestCase.setUp(self) # Testing Ideal Gas Model CO2 = molecule('CO2') CO2_pMuTT_parameters = { 'name': 'CO2', 'trans_model': trans.IdealTrans, 'n_degrees': 3, 'molecular_weight': get_molecular_weight('CO2'), 'rot_model': rot.RigidRotor, 'rot_temperatures': rot.get_rot_temperatures_from_atoms(CO2, geometry='linear'), 'geometry': 'linear', 'symmetrynumber': 2, 'elec_model': elec.IdealElec, 'potentialenergy': -22.994202, 'spin': 0., 'vib_model': vib.HarmonicVib, 'vib_wavenumbers': [3360., 954., 954., 1890.], } CO2_ase_parameters = { 'atoms': CO2, 'potentialenergy': -22.994202, 'vib_energies': [c.wavenumber_to_energy(x) for x in CO2_pMuTT_parameters['vib_wavenumbers']], 'geometry': 'linear', 'symmetrynumber': 2, 'spin': 0. } self.CO2_pMuTT = StatMech(**CO2_pMuTT_parameters) self.CO2_ASE = IdealGasThermo(**CO2_ase_parameters) self.T0 = c.T0('K') # K self.P0 = c.P0('Pa') self.V0 = c.V0('m3') def test_get_q(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_q(T=self.T0, ignore_q_elec=True, V=self.V0), 6.083051624373337e+25) def test_get_CvoR(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_CvoR(T=self.T0, V=self.V0), 2.9422622359004853) def test_get_Cv(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_Cv(T=self.T0, V=self.V0, units='J/mol/K'), 2.9422622359004853*c.R('J/mol/K')) def test_get_CpoR(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_CpoR(T=self.T0, V=self.V0), 3.9422622359004853) def test_get_Cp(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_Cp(T=self.T0, V=self.V0, units='J/mol/K'), 3.9422622359004853*c.R('J/mol/K')) def test_get_EoRT(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_EoRT(T=self.T0), -894.97476277965) np.testing.assert_almost_equal( self.CO2_pMuTT.get_EoRT(T=self.T0, include_ZPE=True), -877.703643641077) def test_get_E(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_E(T=self.T0, units='J/mol'), -894.97476277965*c.R('J/mol/K')*self.T0) np.testing.assert_almost_equal( self.CO2_pMuTT.get_E(T=self.T0, units='J/mol', include_ZPE=True), -877.703643641077*c.R('J/mol/K')*self.T0, decimal=2) def test_get_UoRT(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_UoRT(T=self.T0, V=self.V0), -875.1095022368354) def test_get_U(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_U(T=self.T0, V=self.V0, units='J/mol'), -875.1095022368354*c.R('J/mol/K')*self.T0) def test_get_HoRT(self): expected_HoRT_CO2 = \ self.CO2_ASE.get_enthalpy(temperature=self.T0, verbose=False) \ / c.R('eV/K')/self.T0 calc_HoRT_CO2 = self.CO2_pMuTT.get_HoRT(T=self.T0) np.testing.assert_almost_equal(expected_HoRT_CO2, calc_HoRT_CO2) def test_get_H(self): expected_H_CO2 = \ self.CO2_ASE.get_enthalpy(temperature=self.T0, verbose=False) calc_H_CO2 = self.CO2_pMuTT.get_H(T=self.T0, units='eV') np.testing.assert_almost_equal(expected_H_CO2, calc_H_CO2) def test_get_SoR(self): expected_SoR_CO2 = \ self.CO2_ASE.get_entropy(temperature=self.T0, pressure=self.P0, verbose=False)/c.R('eV/K') calc_SoR_CO2 = self.CO2_pMuTT.get_SoR(T=self.T0, V=self.V0) np.testing.assert_almost_equal(expected_SoR_CO2, calc_SoR_CO2, 3) def test_get_S(self): expected_S_CO2 = \ self.CO2_ASE.get_entropy(temperature=self.T0, pressure=self.P0, verbose=False) calc_S_CO2 = self.CO2_pMuTT.get_S( T=self.T0, V=self.V0, units='eV/K') np.testing.assert_almost_equal(expected_S_CO2, calc_S_CO2, 1) def test_get_FoRT(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_FoRT(T=self.T0, V=self.V0), -900.5899966269182) def test_get_F(self): np.testing.assert_almost_equal( self.CO2_pMuTT.get_F(T=self.T0, V=self.V0, units='J/mol'), -900.5899966269182*c.R('J/mol/K')*self.T0) def test_get_GoRT(self): expected_GoRT_CO2 = \ self.CO2_ASE.get_gibbs_energy(temperature=self.T0, pressure=self.P0, verbose=False)/c.R('eV/K')/self.T0 calc_GoRT_CO2 = self.CO2_pMuTT.get_GoRT(T=self.T0, V=self.V0) np.testing.assert_almost_equal(expected_GoRT_CO2, calc_GoRT_CO2, 3) def test_get_G(self): expected_G_CO2 = \ self.CO2_ASE.get_gibbs_energy(temperature=self.T0, pressure=self.P0, verbose=False) calc_G_CO2 = self.CO2_pMuTT.get_G( T=self.T0, V=self.V0, units='eV') np.testing.assert_almost_equal(expected_G_CO2, calc_G_CO2, 5)
#electronic energy in eV energy = -553.610395 #vibrational energies in meV vibenergies = [0, 0, 0, 7.6, 7.6, 299.2] #convert from meV to eV for each mode vibenergies[:] = [ve / 1000. for ve in vibenergies] #list of temperatures temperatures = [298.15, 400, 500] #operating pressure pressures = [101325] f = open(name + '_free.energy', 'w') for temperature in temperatures: for pressure in pressures: gibbs = IdealGasThermo(vib_energies=vibenergies, electronicenergy=energy, atoms=atoms, geometry=geometry, symmetrynumber=2, spin=0) freeenergy = gibbs.get_gibbs_energy(temperature, pressure) f.write('Temperature: ' + str(temperature) + '\t' + 'Pressure: ' + str(pressure) + '\t' + 'Free energy: ' + str(freeenergy) + '\n') f.close
# -*- coding: utf-8 -*- """ Created on Mon Jul 25 14:20:17 2016 @author: lansford """ from __future__ import division from ase.thermochemistry import IdealGasThermo from ase import Atoms OOH = Atoms('OOH') OOHfreqs = [.484418503,.146088952,.003153291,.002971872] OOHThermo = IdealGasThermo(OOHfreqs,'linear',atoms=OOH,symmetrynumber=1,spin=0.5,natoms=3) OOHgibbs = OOHThermo.get_gibbs_energy(298,101325); OOHZPE = OOHThermo.get_enthalpy(0); print(OOHgibbs) print(OOHZPE)
def test_vibrations(self, testdir, n2_emt, n2_optimized): atoms = n2_emt vib = Vibrations(atoms) vib.run() freqs = vib.get_frequencies() vib.write_mode(n=None, nimages=5) vib.write_jmol() vib_energies = vib.get_energies() for image in vib.iterimages(): assert len(image) == 2 thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=atoms, symmetrynumber=2, spin=0) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325., verbose=False) vib.summary(log=self.logfile) with open(self.logfile, 'rt') as f: log_txt = f.read() assert log_txt == vibrations_n2_log mode1 = vib.get_mode(-1) assert_array_almost_equal(mode1, [[0., 0., -0.188935], [0., 0., 0.188935]]) assert_array_almost_equal( vib.show_as_force(-1, show=False).get_forces(), [[0., 0., -2.26722e-1], [0., 0., 2.26722e-1]]) for i in range(3): assert not os.path.isfile('vib.{}.traj'.format(i)) mode_traj = ase.io.read('vib.3.traj', index=':') assert len(mode_traj) == 5 assert_array_almost_equal(mode_traj[0].get_all_distances(), atoms.get_all_distances()) with pytest.raises(AssertionError): assert_array_almost_equal(mode_traj[4].get_all_distances(), atoms.get_all_distances()) with open('vib.xyz', 'rt') as f: jmol_txt = f.read() assert jmol_txt == jmol_txt_ref assert vib.clean(empty_files=True) == 0 assert vib.clean() == 13 assert len(list(vib.iterimages())) == 13 d = dict(vib.iterdisplace(inplace=False)) for name, image in vib.iterdisplace(inplace=True): assert d[name] == atoms atoms2 = n2_emt vib2 = Vibrations(atoms2) vib2.run() assert_array_almost_equal(freqs, vib.get_frequencies()) # write/read the data from another working directory atoms3 = n2_optimized.copy() # No calculator needed! workdir = os.path.abspath(os.path.curdir) try: os.mkdir('run_from_here') os.chdir('run_from_here') vib = Vibrations(atoms3, name=os.path.join(os.pardir, 'vib')) assert_array_almost_equal(freqs, vib.get_frequencies()) assert vib.clean() == 13 finally: os.chdir(workdir) if os.path.isdir('run_from_here'): os.rmdir('run_from_here')
from ase.vibrations import Vibrations from ase.thermochemistry import IdealGasThermo n2 = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) QuasiNewton(n2).run(fmax=0.01) vib = Vibrations(n2) vib.run() print(vib.get_frequencies()) vib.summary() print(vib.get_mode(-1)) vib.write_mode(n=None, nimages=20) vib_energies = vib.get_energies() for image in vib.iterimages(): assert len(image) == 2 thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=n2, symmetrynumber=2, spin=0) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.) assert vib.clean(empty_files=True) == 0 assert vib.clean() == 13 assert len(list(vib.iterimages())) == 13 d = dict(vib.iterdisplace(inplace=False)) for name, atoms in vib.iterdisplace(inplace=True): assert d[name] == atoms
dw = 5000., nbands = -10, kpts=(1, 1, 1), xc = 'BEEF', outdir='outdir', psppath = "/scratch/users/colinfd/psp/gbrv", sigma = 10e-4) atoms.set_calculator(calc) dyn = QuasiNewton(atoms,logfile='out.log',trajectory='out.traj') dyn.run(fmax=0.01) electronicenergy = atoms.get_potential_energy() vib = Vibrations(atoms) # run vibrations on all atoms vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, electronicenergy=electronicenergy, atoms=atoms, geometry='linear', # linear/nonlinear symmetrynumber=2, spin=0) # symmetry numbers from point group G = thermo.get_free_energy(temperature=300, pressure=101325.) # vapor pressure of water at room temperature e = open('e_energy.out','w') g = open('g_energy.out','w') e.write(str(electronicenergy)) g.write(str(G))
colors = {} for i, atoms in enumerate(ga): N_Sn = len([a for a in atoms if a.number == 50]) N_O = len([a for a in atoms if a.number == 8]) e = atoms.get_potential_energy() Gs_slab[(N_Sn, N_O)] = e colors[(N_Sn, N_O)] = color_lib[i] cwd = os.getcwd() os.chdir('/home/matjoerg/phd/ga/SnO2/ref_structures/O2/vib/') O2 = read('optimisation.traj') O2vib = InfraRed(O2) e_O2vib = O2vib.get_energies() thermo = IdealGasThermo(vib_energies=e_O2vib, atoms=O2, geometry='linear', symmetrynumber=2, spin=1) os.chdir(cwd) #mu0s = {100: -0.08, 200: -0.17, 300: -0.27, 400: -0.38, 500: -0.50, 600: -0.61, 700: -0.73, 800: -0.85, 900: -0.98, 1000: -1.10} def free_e(mu, N_Sn, N_O): G_slab = Gs_slab[(N_Sn, N_O)] gamma_Opoor = 1 / A * (G_slab - 0.5 * N_O * e_SnO2 - (N_Sn - 0.5 * N_O) * (e_Sn)) - e_surfb gamma_Orich = gamma_Opoor - 1 / A * (N_Sn - 0.5 * N_O) * e_SnO2_formation slope = (gamma_Orich - gamma_Opoor) / (e_O - e_SnO2_formation)
class TestStatMech(unittest.TestCase): def setUp(self): unittest.TestCase.setUp(self) # Testing Ideal Gas Model CO2 = molecule('CO2') CO2_PyMuTT_parameters = { 'trans_model': trans.IdealTrans, 'n_degrees': 3, 'molecular_weight': get_molecular_weight('CO2'), 'rot_model': rot.RigidRotor, 'rot_temperatures': rot.get_rot_temperatures_from_atoms(CO2, geometry='linear'), 'geometry': 'linear', 'symmetrynumber': 2, 'elec_model': elec.IdealElec, 'potentialenergy': -22.994202, 'spin': 0., 'vib_model': vib.HarmonicVib, 'vib_wavenumbers': [3360., 954., 954., 1890.], } CO2_ase_parameters = { 'atoms': CO2, 'potentialenergy': -22.994202, 'vib_energies': [c.wavenumber_to_energy(x) \ for x in CO2_PyMuTT_parameters['vib_wavenumbers']], 'geometry':'linear', 'symmetrynumber': 2, 'spin': 0. } self.CO2_PyMuTT = StatMech(**CO2_PyMuTT_parameters) self.CO2_ASE = IdealGasThermo(**CO2_ase_parameters) self.T0 = c.T0('K') # K self.P0 = c.P0('Pa') self.V0 = c.V0('m3') def test_get_q(self): self.assertAlmostEqual( self.CO2_PyMuTT.get_q(T=self.T0, ignore_q_elec=True, V=self.V0), 6.083051624373337e+25) def test_get_CvoR(self): self.assertAlmostEqual(self.CO2_PyMuTT.get_CvoR(T=self.T0, V=self.V0), 2.9422622359004853) def test_get_CpoR(self): self.assertAlmostEqual(self.CO2_PyMuTT.get_CpoR(T=self.T0, V=self.V0), 3.9422622359004853) def test_get_UoRT(self): self.assertAlmostEqual(self.CO2_PyMuTT.get_UoRT(T=self.T0, V=self.V0), -875.1095022368354) def test_get_HoRT(self): expected_HoRT_CO2 = \ self.CO2_ASE.get_enthalpy(temperature=self.T0, verbose=False) \ /c.R('eV/K')/self.T0 calc_HoRT_CO2 = self.CO2_PyMuTT.get_HoRT(T=self.T0) self.assertTrue(np.isclose(expected_HoRT_CO2, calc_HoRT_CO2)) def test_get_SoR(self): expected_SoR_CO2 = \ self.CO2_ASE.get_entropy(temperature=self.T0, pressure=self.P0, verbose=False)/c.R('eV/K') calc_SoR_CO2 = self.CO2_PyMuTT.get_SoR(T=self.T0, V=self.V0) self.assertTrue(np.isclose(expected_SoR_CO2, calc_SoR_CO2)) def test_get_AoRT(self): self.assertAlmostEqual(self.CO2_PyMuTT.get_AoRT(T=self.T0, V=self.V0), -900.5899966269182) def test_get_GoRT(self): expected_GoRT_CO2 = \ self.CO2_ASE.get_gibbs_energy(temperature=self.T0, pressure=self.P0, verbose=False)/c.R('eV/K')/self.T0 calc_GoRT_CO2 = self.CO2_PyMuTT.get_GoRT(T=self.T0, V=self.V0) self.assertTrue(np.isclose(expected_GoRT_CO2, calc_GoRT_CO2))
calc = Vasp('molecules/wgs/CO-vib') vib_freq = calc.get_vibrational_frequencies() CO_vib_energies = [h * c * nu for nu in vib_freq] calc = Vasp('molecules/wgs/CO2-vib') vib_freq = calc.get_vibrational_frequencies() CO2_vib_energies = [h * c * nu for nu in vib_freq] calc = Vasp('molecules/wgs/H2-vib') vib_freq = calc.get_vibrational_frequencies() H2_vib_energies = [h * c * nu for nu in vib_freq] calc = Vasp('molecules/wgs/H2O-vib') vib_freq = calc.get_vibrational_frequencies() H2O_vib_energies = [h * c * nu for nu in vib_freq] # now we make a thermo object for each molecule CO_t = IdealGasThermo(vib_energies=CO_vib_energies[0:0], potentialenergy=E_CO, atoms=CO, geometry='linear', symmetrynumber=1, spin=0) CO2_t = IdealGasThermo(vib_energies=CO2_vib_energies[0:4], potentialenergy=E_CO2, atoms=CO2, geometry='linear', symmetrynumber=2, spin=0) H2_t = IdealGasThermo(vib_energies=H2_vib_energies[0:0], potentialenergy=E_H2, atoms=H2, geometry='linear', symmetrynumber=2, spin=0) H2O_t = IdealGasThermo(vib_energies=H2O_vib_energies[0:3],
atoms = read('N2.traj') #electronic energy in eV energy = -553.610395 #vibrational energies in meV vibenergies = [0, 0, 0, 7.6, 7.6, 299.2] #convert from meV to eV for each mode vibenergies[:] = [ve/1000. for ve in vibenergies] #list of temperatures temperatures = [298.15, 400, 500] #operating pressure pressures = [101325] f=open(name+'_free.energy','w') for temperature in temperatures: for pressure in pressures: gibbs = IdealGasThermo(vib_energies=vibenergies, electronicenergy=energy, atoms=atoms, geometry=geometry, symmetrynumber=2, spin=0) freeenergy = gibbs.get_gibbs_energy(temperature,pressure) f.write('Temperature: '+str(temperature)+'\t'+'Pressure: '+str(pressure)+'\t'+'Free energy: '+str(freeenergy)+'\n') f.close
from ase.vibrations import Vibrations from ase.phonons import Phonons from ase.thermochemistry import (IdealGasThermo, HarmonicThermo, CrystalThermo) from ase.calculators.emt import EMT # Ideal gas thermo. atoms = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) QuasiNewton(atoms).run(fmax=0.01) energy = atoms.get_potential_energy() vib = Vibrations(atoms, name='idealgasthermo-vib') vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=atoms, symmetrynumber=2, spin=0, potentialenergy=energy) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.) # Harmonic thermo. atoms = fcc100('Cu', (2, 2, 2), vacuum=10.) atoms.set_calculator(EMT()) add_adsorbate(atoms, 'Pt', 1.5, 'hollow') atoms.set_constraint( FixAtoms(indices=[atom.index for atom in atoms if atom.symbol == 'Cu'])) QuasiNewton(atoms).run(fmax=0.01) vib = Vibrations(atoms, name='harmonicthermo-vib', indices=[atom.index for atom in atoms if atom.symbol != 'Cu'])
encut=300, ibrion=2, nsw=5, atoms=atoms) as calc: electronicenergy = atoms.get_potential_energy() # next, we get vibrational modes with jasp('molecules/n2-vib', xc='PBE', encut=300, ibrion=6, nfree=2, potim=0.15, nsw=1, atoms=atoms) as calc: calc.calculate() vib_freq = calc.get_vibrational_frequencies() # in cm^1 #convert wavenumbers to energy h = 4.1356675e-15 # eV*s c = 3.0e10 #cm/s vib_energies = [h*c*nu for nu in vib_freq] print('vibrational energies\n====================') for i,e in enumerate(vib_energies): print('{0:02d}: {1} eV'.format(i,e)) # # now we can get some properties. Note we only need one vibrational # energy since there is only one mode. This example does not work if # you give all the energies because one energy is zero. thermo = IdealGasThermo(vib_energies=vib_energies[0:0], electronicenergy=electronicenergy, atoms=atoms, geometry='linear', symmetrynumber=2, spin=0) # temperature in K, pressure in Pa, G in eV G = thermo.get_free_energy(temperature=298.15, pressure=101325.)
atoms.set_calculator(calcvib) vib = Vibrations(atoms, indices=vibrateatoms, delta=0.03) vib.run() vib.summary(method='standard') # Make trajectory files to visualize the modes. for mode in range(len(vibrateatoms) * 3): vib.write_mode(mode) # Calculate free energy vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, electronicenergy=energy, atoms=atoms, geometry='linear', symmetrynumber=2, spin=0) # At 300K and 101325 Pa # change for your operating conditions freeenergy = thermo.get_gibbs_energy(temperature=300, pressure=101325) f = open(name + '.energy', 'w') f.write('Potential energy: ' + str(energy) + '\n' + 'Free energy: ' + str(freeenergy) + '\n') f.close ens = BEEF_Ensemble(calc) ens_e = ens.get_ensemble_energies() ens.write('ensemble.bee')
MetalLabels = list(Data.Substrate[Data.index.isin(idx111) & (Data.Adsorbate=='O')]) EO = np.array(Data.Eads[Data.index.isin(idx111) & (Data.Adsorbate=='O')]) ECO = np.array(Data.Eads[Data.index.isin(idx111) & (Data.Adsorbate=='CO')]) GO = np.array(Data.vibGibbs[Data.index.isin(idx111) & (Data.Adsorbate=='O')]) GCO = np.array(Data.vibGibbs[Data.index.isin(idx111) & (Data.Adsorbate=='CO')]) O2r = (0.5149910055-0.4850089945)*41.3427602451982 O2freq = 0.1904905 #eV COr = (0.51388868234-0.486111317659)*41.3427602451982 COfreq = 0.260119879 O2 = Atoms('O2') O2[1].z = O2r CO = Atoms('CO') CO[1].z = COr Temp = 400 O2Thermo = IdealGasThermo([O2freq],'linear',atoms=O2,symmetrynumber=2,spin=1,natoms=2) O2gibbs = O2Thermo.get_gibbs_energy(Temp,1*101325); COThermo = IdealGasThermo([COfreq],'linear',atoms=CO,symmetrynumber=1,spin=0,natoms=2) COgibbs = COThermo.get_gibbs_energy(Temp,1*101325); PtI = MetalLabels.index('Pt') AgI = MetalLabels.index('Ag') CuI = MetalLabels.index('Cu') PdI = MetalLabels.index('Pd') #redefining O2 eenergy change from molecular oxygen EO = EO+9.5884297/2-1.9555224 delGCOPt = GCO[PtI]+ECO[PtI]-COgibbs delGCOAg = GCO[AgI]+ECO[AgI]-COgibbs delGCOPtAg = GCO[PtI]+ECO[AgI]-COgibbs
from ase.thermochemistry import (IdealGasThermo, HarmonicThermo, CrystalThermo) from ase.calculators.emt import EMT # Ideal gas thermo. atoms = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) QuasiNewton(atoms).run(fmax=0.01) energy = atoms.get_potential_energy() vib = Vibrations(atoms, name='idealgasthermo-vib') vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=atoms, symmetrynumber=2, spin=0, potentialenergy=energy) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.) # Harmonic thermo. atoms = fcc100('Cu', (2, 2, 2), vacuum=10.) atoms.set_calculator(EMT()) add_adsorbate(atoms, 'Pt', 1.5, 'hollow') atoms.set_constraint(FixAtoms(indices=[atom.index for atom in atoms if atom.symbol == 'Cu'])) QuasiNewton(atoms).run(fmax=0.01) vib = Vibrations(atoms, name='harmonicthermo-vib', indices=[atom.index for atom in atoms if atom.symbol != 'Cu']) vib.run()
encut=300, ibrion=2, nsw=5, atoms=atoms) electronicenergy = atoms.get_potential_energy() # next, we get vibrational modes calc2 = Vasp('molecules/n2-vib', xc='PBE', encut=300, ibrion=6, nfree=2, potim=0.15, nsw=1, atoms=atoms) calc2.wait() vib_freq = calc2.get_vibrational_frequencies() # in cm^1 #convert wavenumbers to energy h = 4.1356675e-15 # eV*s c = 3.0e10 #cm/s vib_energies = [h*c*nu for nu in vib_freq] print('vibrational energies\n====================') for i,e in enumerate(vib_energies): print('{0:02d}: {1} eV'.format(i,e)) # # now we can get some properties. Note we only need one vibrational # energy since there is only one mode. This example does not work if # you give all the energies because one energy is zero. thermo = IdealGasThermo(vib_energies=vib_energies[0:0], potentialenergy=electronicenergy, atoms=atoms, geometry='linear', symmetrynumber=2, spin=0) # temperature in K, pressure in Pa, G in eV G = thermo.get_gibbs_energy(temperature=298.15, pressure=101325.)
atoms=atoms) electronicenergy = atoms.get_potential_energy() # next, we get vibrational modes calc2 = Vasp('molecules/n2-vib', xc='PBE', encut=300, ibrion=6, nfree=2, potim=0.15, nsw=1, atoms=atoms) calc2.wait() vib_freq = calc2.get_vibrational_frequencies() # in cm^1 #convert wavenumbers to energy h = 4.1356675e-15 # eV*s c = 3.0e10 #cm/s vib_energies = [h * c * nu for nu in vib_freq] print('vibrational energies\n====================') for i, e in enumerate(vib_energies): print('{0:02d}: {1} eV'.format(i, e)) # # now we can get some properties. Note we only need one vibrational # energy since there is only one mode. This example does not work if # you give all the energies because one energy is zero. thermo = IdealGasThermo(vib_energies=vib_energies[0:0], potentialenergy=electronicenergy, atoms=atoms, geometry='linear', symmetrynumber=2, spin=0) # temperature in K, pressure in Pa, G in eV G = thermo.get_gibbs_energy(temperature=298.15, pressure=101325.)
freq_remove = [] if RMFREQ_KbT == "True": for i in Freq: if i <= freq_kbt_cutoff: freq_remove.append(i) for i in freq_remove: if i in Freq: Freq.remove(i) ## get the strucuter from the output file struc = read(log_file,format='gaussian-out') ## get the ideal gas limit thermodynamic values thermo = IdealGasThermo(vib_energies=Freq, potentialenergy=scf_energy_eV, atoms=struc, geometry=shape, symmetrynumber=symnum, spin=spin) print "Ideal Gas Limit" ZPE = thermo.get_ZPE_correction() H = thermo.get_enthalpy(temperature=temp) S = thermo.get_entropy(temperature=temp,pressure=pres) G = thermo.get_gibbs_energy(temperature=temp,pressure=pres) print " " print "ZPE correction (ZPE) = ", ZPE, " eV" print "Ethalpy (H) = ", H, " eV" print "Entropy (S) = ", S, " eV/K" print "Gibbs Energy (G) = ", G, " eV"
vO2N = np.concatenate((Data2['v(M-O2)'][idx1],Data2['v(M-N)'][idx2])) for x, y, s in zip(vOO, vO2N, M3): texts.append(plt.text(x, y, s, bbox={'pad':0, 'alpha':0}, size=22, fontweight='bold',style='normal',name ='Calibri')) adjustText.adjust_text(texts,autoalign=True,only_move={'points':'y','text':'y'}, arrowprops=dict(arrowstyle="-", color='k', lw=2)) plt.show() O2r = (0.5149910055-0.4850089945)*41.3427602451982 O2freq = 0.1904905 #eV COr = (0.51388868234-0.486111317659)*41.3427602451982 COfreq = 0.260119879 O2 = Atoms('O2') O2[1].z = O2r CO = Atoms('CO') CO[1].z = COr O2Thermo = IdealGasThermo([O2freq],'linear',atoms=O2,symmetrynumber=2,spin=1,natoms=2) O2gibbs = O2Thermo.get_gibbs_energy(298,101325); COThermo = IdealGasThermo([COfreq],'linear',atoms=CO,symmetrynumber=1,spin=0,natoms=2) COgibbs = COThermo.get_gibbs_energy(298,101325); PtI = MetalLabels.index('Pt') AgI = MetalLabels.index('Ag') delGCOPt = G3[PtI]+E3[PtI]-COgibbs delGCOAg = G3[AgI]+E3[AgI]-COgibbs delGCOPtAg = G3[PtI]+E3[AgI]-COgibbs delGOPt = G1[PtI]+E1[PtI]-O2gibbs/2 delGOAg = G1[AgI]+E1[AgI]-O2gibbs/2 delGOPtAg = G1[PtI]+E1[AgI]-O2gibbs/2
c = 3.0e10 # cm / s calc = Vasp('molecules/wgs/CO-vib') vib_freq = calc.get_vibrational_frequencies() CO_vib_energies = [h * c * nu for nu in vib_freq] calc = Vasp('molecules/wgs/CO2-vib') vib_freq = calc.get_vibrational_frequencies() CO2_vib_energies = [h * c * nu for nu in vib_freq] calc = Vasp('molecules/wgs/H2-vib') vib_freq = calc.get_vibrational_frequencies() H2_vib_energies = [h * c * nu for nu in vib_freq] calc = Vasp('molecules/wgs/H2O-vib') vib_freq = calc.get_vibrational_frequencies() H2O_vib_energies = [h * c * nu for nu in vib_freq] # now we make a thermo object for each molecule CO_t = IdealGasThermo(vib_energies=CO_vib_energies[0:0], potentialenergy=E_CO, atoms=CO, geometry='linear', symmetrynumber=1, spin=0) CO2_t = IdealGasThermo(vib_energies=CO2_vib_energies[0:4], potentialenergy=E_CO2, atoms=CO2, geometry='linear', symmetrynumber=2, spin=0) H2_t = IdealGasThermo(vib_energies=H2_vib_energies[0:0], potentialenergy=E_H2, atoms=H2, geometry='linear', symmetrynumber=2, spin=0) H2O_t = IdealGasThermo(vib_energies=H2O_vib_energies[0:3], potentialenergy=E_H2O, atoms=H2O, geometry='nonlinear', symmetrynumber=2, spin=0) # now we can compute G_rxn for a range of temperatures from 298 to 1000 K Trange = np.linspace(298, 1000, 20) # K
import statmech from ase.thermochemistry import IdealGasThermo from ase import Atoms mat.rcParams['mathtext.default'] = 'regular' mat.rcParams['legend.numpoints'] = 1 mat.rcParams['lines.linewidth'] = 3 mat.rcParams['lines.markersize'] = 20 c = 29979245800 #cm/s h = 6.6260693*10**(-34) #planks constant kB = 1.3806505*10**(-23) #boltzman's constant JeV = 1.60217653*10**(-19) #eV to Joules COr = (0.51388868234-0.486111317659)*41.3427602451982 COfreq = 0.260119879 CO = Atoms('CO') CO[1].z = COr COThermo = IdealGasThermo([COfreq],'linear',atoms=CO,symmetrynumber=1,spin=0,natoms=2) COh100 = COThermo.get_enthalpy(100) COh100 = COThermo.get_enthalpy(145) COh100 = COThermo.get_enthalpy(130) COh100 = COThermo.get_enthalpy(420) COh100 = COThermo.get_enthalpy(350) COh100 = COThermo.get_enthalpy(450) COh100 = COThermo.get_enthalpy(340) COh100 = COThermo.get_enthalpy(500) H_Ag=np.array([234.060289,22.823011,16.915597,16.786227,3.576371,2.197334])*8.06573 vibAg = statmech.vibenergy(H_Ag,100) print(vibAg) H_Cu=np.array([223.437829,31.524364,27.338489,27.112873,13.374554,12.939494])*8.06573 vibCu = statmech.vibenergy(H_Cu,130) print(vibCu)
def test_thermochemistry(): """Tests of the major methods (HarmonicThermo, IdealGasThermo, CrystalThermo) from the thermochemistry module.""" # Ideal gas thermo. atoms = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) QuasiNewton(atoms).run(fmax=0.01) energy = atoms.get_potential_energy() vib = Vibrations(atoms, name='idealgasthermo-vib') vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=atoms, symmetrynumber=2, spin=0, potentialenergy=energy) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.) # Harmonic thermo. atoms = fcc100('Cu', (2, 2, 2), vacuum=10.) atoms.set_calculator(EMT()) add_adsorbate(atoms, 'Pt', 1.5, 'hollow') atoms.set_constraint( FixAtoms(indices=[atom.index for atom in atoms if atom.symbol == 'Cu'])) QuasiNewton(atoms).run(fmax=0.01) vib = Vibrations( atoms, name='harmonicthermo-vib', indices=[atom.index for atom in atoms if atom.symbol != 'Cu']) vib.run() vib.summary() vib_energies = vib.get_energies() thermo = HarmonicThermo(vib_energies=vib_energies, potentialenergy=atoms.get_potential_energy()) thermo.get_helmholtz_energy(temperature=298.15) # Crystal thermo. atoms = bulk('Al', 'fcc', a=4.05) calc = EMT() atoms.set_calculator(calc) energy = atoms.get_potential_energy() # Phonon calculator N = 7 ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05) ph.run() ph.read(acoustic=True) phonon_energies, phonon_DOS = ph.dos(kpts=(4, 4, 4), npts=30, delta=5e-4) thermo = CrystalThermo(phonon_energies=phonon_energies, phonon_DOS=phonon_DOS, potentialenergy=energy, formula_units=4) thermo.get_helmholtz_energy(temperature=298.15) # Hindered translator / rotor. # (Taken directly from the example given in the documentation.) vibs = np.array([ 3049.060670, 3040.796863, 3001.661338, 2997.961647, 2866.153162, 2750.855460, 1436.792655, 1431.413595, 1415.952186, 1395.726300, 1358.412432, 1335.922737, 1167.009954, 1142.126116, 1013.918680, 803.400098, 783.026031, 310.448278, 136.112935, 112.939853, 103.926392, 77.262869, 60.278004, 25.825447 ]) vib_energies = vibs / 8065.54429 # Convert to eV from cm^-1. trans_barrier_energy = 0.049313 # eV rot_barrier_energy = 0.017675 # eV sitedensity = 1.5e15 # cm^-2 rotationalminima = 6 symmetrynumber = 1 mass = 30.07 # amu inertia = 73.149 # amu Ang^-2 thermo = HinderedThermo(vib_energies=vib_energies, trans_barrier_energy=trans_barrier_energy, rot_barrier_energy=rot_barrier_energy, sitedensity=sitedensity, rotationalminima=rotationalminima, symmetrynumber=symmetrynumber, mass=mass, inertia=inertia) helmholtz = thermo.get_helmholtz_energy(temperature=298.15) target = 1.593 # Taken from documentation example. assert (helmholtz - target) < 0.001
outdir='calcdir', psppath="/scratch/users/colinfd/psp/gbrv", sigma=10e-4) atoms.set_calculator(calc) dyn = QuasiNewton(atoms, logfile='out.log', trajectory='out.traj') dyn.run(fmax=0.01) electronicenergy = atoms.get_potential_energy() vib = Vibrations(atoms) # run vibrations on all atoms vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo( vib_energies=vib_energies, electronicenergy=electronicenergy, atoms=atoms, geometry='linear', # linear/nonlinear symmetrynumber=2, spin=0) # symmetry numbers from point group G = thermo.get_free_energy( temperature=300, pressure=101325.) # vapor pressure of water at room temperature e = open('e_energy.out', 'w') g = open('g_energy.out', 'w') e.write(str(electronicenergy)) g.write(str(G))
c = 3.0e10 # cm / s with jasp('molecules/wgs/CO-vib') as calc: vib_freq = calc.get_vibrational_frequencies() CO_vib_energies = [h * c * nu for nu in vib_freq] with jasp('molecules/wgs/CO2-vib') as calc: vib_freq = calc.get_vibrational_frequencies() CO2_vib_energies = [h * c * nu for nu in vib_freq] with jasp('molecules/wgs/H2-vib') as calc: vib_freq = calc.get_vibrational_frequencies() H2_vib_energies = [h * c * nu for nu in vib_freq] with jasp('molecules/wgs/H2O-vib') as calc: vib_freq = calc.get_vibrational_frequencies() H2O_vib_energies = [h * c * nu for nu in vib_freq] # now we make a thermo object for each molecule CO_t = IdealGasThermo(vib_energies=CO_vib_energies[0:0], electronicenergy=E_CO, atoms=CO, geometry='linear', symmetrynumber=1, spin=0) CO2_t = IdealGasThermo(vib_energies=CO2_vib_energies[0:4], electronicenergy=E_CO2, atoms=CO2, geometry='linear', symmetrynumber=2, spin=0) H2_t = IdealGasThermo(vib_energies=H2_vib_energies[0:0], electronicenergy=E_H2, atoms=H2, geometry='linear', symmetrynumber=2, spin=0) H2O_t = IdealGasThermo(vib_energies=H2O_vib_energies[0:3], electronicenergy=E_H2O, atoms=H2O, geometry='nonlinear', symmetrynumber=2, spin=0) # now we can compute G_rxn for a range of temperatures from 298 to 1000 K Trange = np.linspace(298, 1000, 20) # K
def get_chemical_potential(atoms, freq, geometry, potentialenergy, symmetrynumber, spin, T, nasa_liq=None, H_gas=None, S_gas=None, x=None, gas_phase=False, verbose=False): """ Calculates the chemical potential of the toluene-phase species atoms - ASE Atoms object freq - Numpy array of floats Frequencies of the species in 1/cm geometry - string Geometry of the species (monatomic, linear, nonlinear) potentialenergy - float DFT Energy of the species in eV symmetrynumber - float Symmetry number of the species spin - int Number of unpaired electrons in the species nasa_liq - NASA object NASA polynomial of the species in the liquid phase H_gas - float Enthalpy of the gas in kJ/mol/K S_gas - float Entropy of the gas in J/mol/K T - float Temperature to perform analysis x - float Mole fraction of species in liquid """ #DFT Delta G DFT_thermo = IdealGasThermo(vib_energies=freq * c.h('eV s') * c.c('cm/s'), geometry=geometry, potentialenergy=potentialenergy, natoms=len(atoms), atoms=atoms, symmetrynumber=symmetrynumber, spin=spin) G_DFT = DFT_thermo.get_gibbs_energy(temperature=298., pressure=1.e5, verbose=verbose) if gas_phase: return np.array([ DFT_thermo.get_gibbs_energy(temperature=T_i, pressure=1.e5, verbose=verbose) for T_i in T ]) else: #ASPEN Liquid Data G_liq = nasa_liq.get_GoRT(T=T, verbose=False) * c.kb('eV/K') * T #NIST Gas Phase Data G_gas = H_gas * c.convert_unit( from_='kJ/mol', to='eV/molecule') - T * S_gas * c.convert_unit( from_='J/mol', to='eV/molecule') return G_DFT + G_liq - G_gas + c.kb('eV/K') * T * np.log(x)