xc=xc, kpts=kpt, nbands=-60, smearing='gaussian', sigma=sigma, convergence=convergence, spinpol=spinpol, outdir=calcdir) atoms.set_calculator(calc) #indices=[1] only allows the second N atom to be displaced #in general, you can always fix at least one atom in vibrational calculations, #which corresponds to not calculating the three zero frequency or k=0 acoustic modes #due to translational invariance (you'll often fix more atoms, because you're only #interested in a small subset of the modes) vib = Vibrations(atoms, indices=vib_atoms) vib.run() #this will dump the frequencies to the standard output of the job vib.summary() vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, electronicenergy=electronicenergy, atoms=atoms, geometry='linear', symmetrynumber=2, spin=0) G = thermo.get_free_energy(temperature=298.15, pressure=101325.) e = open('e_energy.out', 'w') g = open('g_energy.out', 'w')
def calculate(element, ref_data, p): values_dict = {} values_dict[p['xc']] = {} for XY, data in ref_data[p['xc']].items(): X = XY.split('-')[0] Y = XY.split('-')[1] if (X == Y and X == element) or (X != Y and (X == element or Y == element)): # compound contains the requested element re_ref = data['re'] we_ref = data['we'] m0_ref = data.get('m0', 0.0) # compound = Atoms(X + Y, [ (0, 0, 0.5), (0, 0, 0.5 + re_ref / a), ], pbc=0) compound.set_cell([a, b, c], scale_atoms=1) compound.center() # calculation on the reference geometry calc = Calculator(**p) compound.set_calculator(calc) e_compound = compound.get_potential_energy() finegd = calc.density.finegd dip = finegd.calculate_dipole_moment(calc.density.rhot_g) * calc.a0 vib = Vibrations(compound) vib.run() vib_compound = vib.get_frequencies(method='frederiksen').real[-1] world.barrier() vib_pckl = glob('vib.*.pckl') if rank == 0: for file in vib_pckl: remove(file) # calculation on the relaxed geometry qn = QuasiNewton(compound) #qn.attach(PickleTrajectory('compound.traj', 'w', compound).write) qn.run(fmax=0.05) e_compound_r = compound.get_potential_energy() dist_compound_r = compound.get_distance(0, 1) dip_r = finegd.calculate_dipole_moment( calc.density.rhot_g) * calc.a0 vib = Vibrations(compound) vib.run() vib_compound_r = vib.get_frequencies(method='frederiksen').real[-1] world.barrier() vib_pckl = glob('vib.*.pckl') if rank == 0: for file in vib_pckl: remove(file) del compound e = e_compound we = vib_compound m0 = dip e_r = e_compound_r we_r = vib_compound_r re_r = dist_compound_r m0_r = dip_r # values_dict[p['xc']][XY] = { 're': re_r, 'we': (we_r, we), 'm0': (m0_r, m0) } # return values_dict
ediff=1e-8, ediffg=-0.01, algo="Fast", gga="RP", xc="PBE", kpts=(4, 4, 1), # isif = 0, # ibrion = 5, # nsw = 0, # nfree = 2 ) adsorbedH.set_calculator(calc) electronicenergy = adsorbedH.get_potential_energy() print "electronic energy is %.5f" % electronicenergy vib = Vibrations(adsorbedH, indices=[23], delta=0.01, nfree=2) vib.run() print vib.get_frequencies() vib.summary() print vib.get_mode(-1) vib.write_mode(-1) vib_energies = vib.get_energies() thermo = HarmonicThermo(vib_energies=vib_energies, electronicenergy=electronicenergy) thermo.get_entropy(temperature=298.15) thermo.get_internal_energy(temperature=298.15) thermo.get_free_energy(temperature=298.15)
### At 300K and 101325 Pa ### change for your operating conditions T = 300 # K P = 101325 # Pa ######################################################################################################### ##### END ##### ######################################################################################################### energy = atoms.get_potential_energy( ) # caclulate the energy, to be used to determine G vibrateatoms = [atom.index for atom in atoms if atom.symbol in ['H', 'N'] ] # calculate the vibrational modes for all N and H atoms # Calculate vibrations vib = Vibrations(atoms, indices=vibrateatoms, delta=0.03) # define a vibration calculation vib.run() # run the vibration calculation vib.summary(method='standard') # summarize the calculated results for mode in range(len(vibrateatoms) * 3): # Make trajectory files to visualize the modes. vib.write_mode(mode) vibenergies = vib.get_energies() vibenergies = [vib for vib in vibenergies if not isinstance(vib, complex)] # only take the real modes gibbs = HarmonicThermo(vib_energies=vibenergies, electronicenergy=energy) freeenergy = gibbs.get_gibbs_energy(T, P) f = open(output_name, 'w')
En = molecule.get_potential_energy() print('***Energy as EV:', En, 'eV') from ase.units import Hartree print('***Energy as hartee:', En / Hartree, 'Hartree') print('***END OF OPT CALCULATION\n') elif sys.argv[4] == '0': print("***Without OPTIMIZITION***\n") else: print("choose only 1 or 0") print('START FREQ CALCULATION:\n') from ase.vibrations import Vibrations vib = Vibrations(molecule) vib.run() vib.combine() print('END OF FREQ CALCULATION\n') print('VIBRATIONAL SUMMARY:\n') vib.summary() print('\nWRITING NORMAL MODE\n') vib.write_jmol() print('.') print('.') print('use JMOL for viewing of the modes') print('.') print('.') print('DONE\n\n') from ase.thermochemistry import IdealGasThermo
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) 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 == 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')
import os from ase.vibrations import Vibrations from gpaw import GPAW from gpaw.mpi import world h2o = GPAW('h2o.gpw', txt=None).get_atoms() # Test restart: vib = Vibrations(h2o) vib.run() vib.summary(method='frederiksen') # Remove a displacement file and redo it: if world.rank == 0: os.remove('vib.1z-.pckl') world.barrier() vib = Vibrations(h2o) vib.run() vib.summary(method='frederiksen')
calc = espresso(pw=500., 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
def vibrate(self, atoms: Atoms, indices: list, read_only=False): ''' This method uses ase.vibrations module, see more for info. User provides the FHI-aims parameters, the Atoms object and list of indices of atoms to be vibrated. Variables related to FHI-aims are governed by the React object. Calculation folders are generated automatically and a sockets calculator is used for efficiency. Work in progress Args: atoms: Atoms object indices: list List of indices of atoms that require vibrations read_only: bool Flag for postprocessing - if True, the method only extracts information from existing files, no calculations are performed Returns: Zero-Point Energy: float ''' '''Retrieve common properties''' basis_set = self.basis_set hpc = self.hpc params = self.params parent_dir = os.getcwd() dimensions = sum(atoms.pbc) if not self.filename: '''develop a naming scheme based on chemical formula''' self.filename = atoms.get_chemical_formula() vib_dir = parent_dir + "/VibData_" + self.filename + "/Vibs" print(vib_dir) vib = Vibrations(atoms, indices=indices, name=vib_dir) '''If a calculation was terminated prematurely (e.g. time limit) empty .json files remain and the calculation of the corresponding stretch modes would be skipped on restart. The line below prevents this''' vib.clean(empty_files=True) '''Extract vibration data from existing files''' if read_only: vib.read() else: '''Calculate required vibration modes''' required_cache = [ os.path.join(vib_dir, "cache." + str(x) + y + ".json") for x in indices for y in ["x+", "x-", "y+", "y-", "y-", "z+", "z-"] ] check_required_modes_files = np.array( [os.path.exists(file) for file in required_cache]) if np.all(check_required_modes_files == True): vib.read() else: '''Set the environment variables for geometry optimisation''' set_aims_command(hpc=hpc, basis_set=basis_set, defaults=2020, nodes_per_instance=self.nodes_per_instance) '''Generate a unique folder for aims calculation''' counter, subdirectory_name = self._restart_setup( "Vib", filename=self.filename, restart=False, verbose=False) os.makedirs(subdirectory_name, exist_ok=True) os.chdir(subdirectory_name) '''Name the aims output file''' out = str(counter) + "_" + str(self.filename) + ".out" '''Calculate vibrations and write the in a separate directory''' with _calc_generator(params, out_fn=out, dimensions=dimensions)[0] as calculator: if not self.dry_run: atoms.calc = calculator else: atoms.calc = EMT() vib = Vibrations(atoms, indices=indices, name=vib_dir) vib.run() vib.summary() '''Generate a unique folder for aims calculation''' if not read_only: os.chdir(vib_dir) vib.write_mode() os.chdir(parent_dir) return vib.get_zero_point_energy()
from ase import Atoms from ase.optimize import QuasiNewton from ase.vibrations import Vibrations from gpaw import GPAW # Water molecule: d = 0.9575 t = pi / 180 * 104.51 H2O = Atoms('H2O', positions=[(0, 0, 0), (d, 0, 0), (d * cos(t), d * sin(t), 0)]) H2O.center(vacuum=3.5) calc = GPAW(h=0.2, txt='h2o.txt', mode='lcao', basis='dzp') H2O.set_calculator(calc) QuasiNewton(H2O).run(fmax=0.05) """Calculate the vibrational modes of a H2O molecule.""" # Create vibration calculator vib = Vibrations(H2O) vib.run() vib.summary(method='frederiksen') # Make trajectory files to visualize normal modes: for mode in range(9): vib.write_mode(mode)
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
H 5.320549047980879 3.220584852467720 3.974551561510350 H 7.723359150977955 3.224855971783890 4.574146712279462 H 7.580803493981530 5.034479218283977 4.877211530909463 """ h = 0.3 atoms = Cluster(read_xyz(StringIO.StringIO(butadiene))) atoms.minimal_box(3., h) atoms.set_calculator(GPAW(h=h)) if 0: dyn = FIRE(atoms) dyn.run(fmax=0.05) atoms.write('butadiene.xyz') vibname = 'fcvib' vib = Vibrations(atoms, name=vibname) vib.run() # Modul a = FranckCondon(atoms, vibname, minfreq=250) # excited state forces F = np.array([[-2.11413, 0.07317, -0.91682], [3.23569, -0.74520, 0.76758], [-3.44847, 0.63846, -0.81080], [2.77345, 0.01272, 0.74811], [-0.06544, -0.01078, -0.03209], [-0.01245, -0.01123, -0.00040], [0.00186, -0.05864, -0.00371], [-0.00151, 0.05815, 0.00141], [0.01625, 0.00781, -0.00202], [0.06253, 0.00902, 0.03381]]) # Huang-Rhys factors S, fq = a.get_Huang_Rhys_factors(F)
# isym=0, ) atoms.set_calculator(calc) #__| atoms.get_potential_energy() atoms.write("out.traj") # | - TEMP ********************************************************************* from ase.vibrations import Vibrations from ase_modules.ase_methods import thermochem_IG_corr vib = Vibrations( atoms, indices=None, ) vib.run() # print("an_ads_vib | Getting vibrational energies") vib_e_list = vib.get_energies() vib.summary(log="vib_summ.out") thermochem_IG_corr( vib_e_list, Temperature=300.0, Pressure=100000.0, potentialenergy=0., symmetrynumber=2,
import sys sys.path.append("..") from ase.build import molecule from ase.optimize import QuasiNewton from ase.calculators.emt import EMT from ase.vibrations import Vibrations from __init__ import AnharmonicModes H2 = molecule('H2') H2.set_calculator(EMT()) dyn = QuasiNewton(H2, logfile='/dev/null') dyn.run(fmax=0.05) vib = Vibrations(H2, indices=[0, 1]) vib.run() vib.summary(log='/dev/null') vib.clean() AM = AnharmonicModes(vib, settings={ 'temperature': 1000, }) vib_mode = AM.define_vibration(mode_number=-1) AM.run() AM.summary(log='/dev/null') AM.clean() assert abs(AM.get_ZPE() - 0.313) < 1e-3, AM.get_ZPE() assert abs(AM.get_entropic_energy()) < 1e-3, AM.get_entropic_energy()
dw=8000, # density cutoff nbands=-10, # number of bands kpts=(8, 8, 8), # k points xc='rpbe', # exchange correlation method sigma=0.2, # Fermi temperature dipole={'status': False}, spinpol=False, convergence={ 'energy': 0.0005, 'mixing': 0.1, 'nmix': 10, 'maxsteps': 500, 'diag': 'david' }, outdirprefix='vibdir') atoms.set_calculator(calc) vib = Vibrations(atoms, delta=0.04, indices=vib_atoms) vib.run() vib.summary(log='vibrations.txt') vib.write_jmol() realFreq = [ x * 0.00012 for x in vib.get_frequencies() if not isinstance(x, complex) ] #eV S = HarmonicThermo(realFreq).get_entropy(300) with open('vibrations.txt', 'a') as f: f.write('\nTS at 300K: ' + str(S))
# kpts={repeats}, # jobs_args='-nk {n_kpts}', balsamcalc_module = __import__('pynta.balsamcalc', fromlist=[socket_calculator]) sock_calc = getattr(balsamcalc_module, socket_calculator) atoms.calc = sock_calc(workflow='QE_Socket', job_kwargs=balsam_exe_settings, **calc_keywords) atoms.calc.set(**extra_calc_keywords) # start vibrations calculations vib = Vibrations(atoms, indices=indices, name=vib_files_loc) vib.run() vib.summary() # vib.clean() # write the first vibration mode to vib.0.traj file (default) - imaginary freq vib.write_mode(n=n, nimages=nimages) end = datetime.datetime.now() with open(os.path.join(prefix, geom[:-10] + '_time.log'), 'a+') as f: f.write(str(end)) f.write("\n") f.write(str(end - start)) f.write("\n") f.close()
images[-1].positions[-1] += (d, 0, 0) #images[-1].positions[-1] += (d, d, 0) # Relax height of Ag atom for initial and final states: dyn1 = QuasiNewton(images[0]) dyn1.run(fmax=0.01) dyn2 = QuasiNewton(images[-1]) dyn2.run(fmax=0.01) # Interpolate positions between initial and final states: neb.interpolate() for image in images: print(image.positions[-1], image.get_potential_energy()) #dyn = MDMin(neb, dt=0.4) #dyn = FIRE(neb, dt=0.4) dyn = BFGS(neb, trajectory='mep.traj') dyn.run(fmax=0.05) for image in images: print(image.positions[-1], image.get_potential_energy()) a = images[0] vib = Vibrations(a, [4]) vib.run() print(vib.get_frequencies()) vib.summary() print(vib.get_mode(-1)) vib.write_mode(-1, nimages=20)
def test_Ag_Cu100(): from math import sqrt from ase import Atom, Atoms from ase.neb import NEB from ase.constraints import FixAtoms from ase.vibrations import Vibrations from ase.visualize import view from ase.calculators.emt import EMT from ase.optimize import QuasiNewton, BFGS # Distance between Cu atoms on a (100) surface: d = 3.6 / sqrt(2) initial = Atoms('Cu', positions=[(0, 0, 0)], cell=(d, d, 1.0), pbc=(True, True, False)) initial *= (2, 2, 1) # 2x2 (100) surface-cell # Approximate height of Ag atom on Cu(100) surfece: h0 = 2.0 initial += Atom('Ag', (d / 2, d / 2, h0)) if 0: view(initial) # Make band: images = [initial.copy() for i in range(6)] neb = NEB(images, climb=True) # Set constraints and calculator: constraint = FixAtoms(range(len(initial) - 1)) for image in images: image.set_calculator(EMT()) image.set_constraint(constraint) # Displace last image: images[-1].positions[-1] += (d, 0, 0) #images[-1].positions[-1] += (d, d, 0) # Relax height of Ag atom for initial and final states: dyn1 = QuasiNewton(images[0]) dyn1.run(fmax=0.01) dyn2 = QuasiNewton(images[-1]) dyn2.run(fmax=0.01) # Interpolate positions between initial and final states: neb.interpolate() for image in images: print(image.positions[-1], image.get_potential_energy()) #dyn = MDMin(neb, dt=0.4) #dyn = FIRE(neb, dt=0.4) dyn = BFGS(neb, trajectory='mep.traj') dyn.run(fmax=0.05) for image in images: print(image.positions[-1], image.get_potential_energy()) a = images[0] vib = Vibrations(a, [4]) vib.run() print(vib.get_frequencies()) vib.summary() print(vib.get_mode(-1)) vib.write_mode(-1, nimages=20)
#!/usr/bin/env python from ase.structure import molecule from ase.calculators.cp2k import CP2K from ase.io import read, write from ase.optimize import BFGS from ase.vibrations import Vibrations import os atoms = molecule('H2O') atoms.center(vacuum=6.0) atoms.pbc = [True, True, True] calc = CP2K(label='molecules/h2o', xc='pbe') atoms.set_calculator(calc) e = atoms.get_potential_energy() print('energy: {0:1.4f} '.format(e)) BFGS(atoms).run(fmax=0.001) pos = atoms.get_positions() bondlength = sum((pos[1] - pos[0])**2)**0.5 print('bond length = {0} A'.format(bondlength)) vib = Vibrations(atoms) vib.run() vib.summary()
return self.rng.rand(3) atoms = molecule('C2H6') ir = Infrared(atoms) ir.calc = RandomCalculator() ir.run() freqs = ir.get_frequencies() ints = ir.intensities assert ir.combine() == 49 ir = Infrared(atoms) assert (freqs == ir.get_frequencies()).all() assert (ints == ir.intensities).all() vib = Vibrations(atoms, name='ir') assert (freqs == vib.get_frequencies()).all() # Read the data from other working directory dirname = os.path.basename(os.getcwd()) os.chdir('..') # Change working directory ir = Infrared(atoms, name=os.path.join(dirname, 'ir')) assert (freqs == ir.get_frequencies()).all() os.chdir(dirname) ir = Infrared(atoms) assert ir.split() == 1 assert (freqs == ir.get_frequencies()).all() assert (ints == ir.intensities).all() vib = Vibrations(atoms, name='ir')
for i in geometry: f.write( str(i.symbol) + ' ' + str(i.x) + ' ' + str(i.y) + ' ' + str(i.z) + '\n') f.close() # Calc minimized energies e = geometry.get_potential_energy() print('Total energy', e, 'eV') # Get the forces again print('Forces:') print(geometry.get_forces()) # Run the vibrational analysis vib = Vibrations(geometry, nfree=2) vib.run() print(vib.summary()) print(vib.get_zero_point_energy()) # Get freqs f = vib.get_frequencies() # Print modes + freq for i in range(0, len(f)): print('Mode(' + str(i) + ') Freq: ' + "{:.7e}".format(f[i])) print(vib.get_mode(i)) ''' # We will alse need to use these functions to get thermo-chem data thermo = IdealGasThermo(vib_energies=vib_energies, potentialenergy=potentialenergy,
Hamiltonian_PolynomialRepulsive_setForAll = '{Yes}', Analysis_ ='', Analysis_CalculateForces = 'Yes') # Mixing calculators QMMMcalc = ase.calculators.mixing.SumCalculator([DFTBcalc,SchNetcalc], atoms) atoms.set_calculator(QMMMcalc) # Optmizing geometry qn = BFGS(atoms, trajectory='mol.traj') qn.run(fmax=0.0001) write('final.xyz', atoms) # Computing vibrational modes vib = Vibrations(atoms, delta=0.01,nfree=4) vib.run() vib.summary() vb_ev = vib.get_energies() vb_cm = vib.get_frequencies() ENE = float(atoms.get_total_energy()) o1 = open('info-modes.dat', 'w') o1.write("# Potential energy: " + "{: >24}".format(ENE) + "\n") for i in range(0, len(vb_ev)): o1.write("{: >24}".format(vb_ev.real[i]) + "{: >24}".format(vb_ev.imag[i]) + "{: >24}".format(vb_cm.real[i]) + "{: >24}".format(vb_cm.imag[i]) + "\n") vib.write_jmol() o1.close() chdir(odir)
from ase.vibrations import Vibrations from __init__ import AnharmonicModes slab = fcc111('Au', size=(2, 2, 2), vacuum=4.0) H = molecule('H') add_adsorbate(slab, H, 3.0, 'ontop') constraint = FixAtoms(mask=[a.symbol == 'Au' for a in slab]) slab.set_constraint(constraint) slab.set_calculator(EMT()) dyn = QuasiNewton(slab, logfile='/dev/null') dyn.run(fmax=0.05) vib = Vibrations(slab, indices=[8]) vib.run() vib.summary(log='/dev/null') vib.clean() AM = AnharmonicModes(vibrations_object=vib) translational_mode = AM.define_translation( from_atom_to_atom=[4, 6] # move from top position on 4 to 6 ) AM.run() AM.summary(log='/dev/null') AM.clean() assert abs(AM.get_ZPE() - 0.1678) < 1e-3, AM.get_ZPE() assert abs(AM.get_entropic_energy() -
def ase_phonon_calc(struct, calc=None, kpoints=[1, 1, 1], ftol=0.01, force_clean=False): """Calculate phonon modes of a molecule using ASE and a given calculator. The system will be geometry optimized before calculating the modes. A report of the phonon modes will be written to a file and arrays of the eigenvectors and eigenvalues returned. | Args: | struct (ase.Atoms): Atoms object with to calculate modes for. | calc (ase.Calculator): Calculator for energies and forces (if not | present, use the one from struct) | kpoints (np.ndarray): Kpoint grid for phonon calculation. If None, just | do a Vibration modes calculation (default is [1,1,1]) | ftol (float): Tolerance for geometry optimisation (default | is 0.01 eV/Ang) | force_clean (bool): If True, force a deletion of all phonon files | and recalculate them | Returns: | evals (float[k-points][modes]): Eigenvalues of phonon modes | evecs (float[k-points][modes][ions][3]): Eigenvectors of phonon modes | struct (ase.Atoms): Optimised structure """ N = len(struct) if calc is None: calc = struct.calc struct = struct.copy() calc.atoms = struct struct.set_calculator(calc) dyn = BFGS(struct, trajectory='geom_opt.traj') dyn.run(fmax=ftol) # Calculate phonon modes vib_pbc = (kpoints is not None) if vib_pbc: vib = Phonons(struct, calc) else: vib = Vibrations(struct) if force_clean: vib.clean() vib.run() if vib_pbc: vib.read(acoustic=True) path = monkhorst_pack(kpoints) evals, evecs = vib.band_structure(path, True) else: vib.read() path = np.zeros((1, 3)) # One axis added since it's like the gamma point evals = np.real(vib.get_energies()[None]) evecs = np.array([vib.get_mode(i) for i in range(3 * N)])[None] # eV to cm^-1 evals *= ((cnst.electron_volt / cnst.h) / cnst.c) / 100.0 # Normalise eigenvectors evecs /= np.linalg.norm(evecs, axis=(2, 3))[:, :, None, None] return ASEPhononData(evals, evecs, path, struct)
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() print(vib.get_frequencies()) vib.summary() print(vib.get_mode(-1)) vib.write_mode(n=None, nimages=20) vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=n2, symmetrynumber=2, spin=0) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.)
ldauprint=2, lmaxmix=6, lorbit=11) #__| new_atoms.set_calculator(calc) #new_atoms.get_potential_energy() from ase.vibrations import Vibrations electronicenergy = 0.0 # new_atoms.get_potential_energy() write('final.traj', new_atoms) #write(name+'opt.traj',atoms) vibstr = 'vib_' + name #vib = Vibrations(new_atoms, name=vibstr, indices=[87,88,85]) vib = Vibrations(new_atoms, name=vibstr, indices=[34], delta=0.005) #vib = Vibrations(new_atoms, name=vibstr, indices=[88]) #vib = Vibrations(new_atoms, name=vibstr, indices=[87]) vib.run() vib.summary(method='frederiksen') # Make trajectory files to visualize normal modes: for mode in range(len(vib.modes)): vib.write_mode(mode) ##vib.PrintHessianMatrix(mass=1,precision=3,suppress_small=1) #vib.PrintFrequencies() #print 'Zero-point energy = %1.2f eV' % vib.GetZeroPointEnergy() #from ase.thermochemistry import IdealGasThermo
from ase.vibrations import Vibrations Au = read('CONTCAR') indices = [8, 9, 10, 12, 13] # Au.pbc = True calc4 = Vasp( xc='PBE', #Level of theory (density functional) encut= 400, #plane-wave kinetic energy cutoff (convergence test; I usually use about 520) kpts=[ 4, 4, 1 ], #number of k-points, e.g. [3,3,3] (convergence test; fewer kpoints are needed if lattice dimension is large) # isif=2, #relaxation method (2 = positions, 3 = positions+volume) prec='Accurate', #accuracy (don't change this) sigma=0.01, #don't need to change (smearing width) ismear=0, #don't need to change (smearing method) isym=0, #disables symmetry # ediffg=-0.03, #force tolerance, |ediffg| (eV/A) (I generally use 0.01 --> 0.03; lower is better but will take longer) # nsw=1000, #maximum number of steps ivdw=12, #enable van der Waals interactions setups='recommended') # ibrion=2) #geom opt algorithm (dont need change; default is conjugate gradient -- works fine) Au.set_calculator(calc4) vib = Vibrations(Au, indices=indices) vib.run() vib.summary() vib.write_mode() # Au.get_potential_energy()
from __init__ import AnharmonicModes slab = fcc111('Al', size=(2, 2, 2), vacuum=3.0) CH3 = molecule('CH3') add_adsorbate(slab, CH3, 2.5, 'ontop') constraint = FixAtoms(mask=[a.symbol == 'Al' for a in slab]) slab.set_constraint(constraint) slab.set_calculator(EMT()) dyn = QuasiNewton(slab) dyn.run(fmax=0.05) # Running vibrational analysis vib = Vibrations(slab, indices=[8, 9, 10, 11]) vib.run() vib.summary() AM = AnharmonicModes(vibrations_object=vib) vib_mode = AM.define_vibration(mode_number=-1) AM.inspect_anmodes() # creates trajectory file AM.run() AM.pre_summary() AM.summary() # Delete all the generated files # vib.clean() # AM.clean()
def test_gs_vibrations(): # check ground state vibrations atoms = Atoms('H2', positions=[[0, 0, 0], [0, 0, Re]]) atoms.calc = MorsePotential(epsilon=De, r0=Re, rho0=rho0) vib = Vibrations(atoms) vib.run()
gga = "PE", xc = "PBE", gamma = 1 #ivdw = 1 # not applied #kpts = (2,2,2), # isif = 0, # ibrion = 5, # nsw = 0, # nfree = 2 ) adsorbedH.set_calculator(calc) electronicenergy = adsorbedH.get_potential_energy() print "electronic energy is %.5f"%electronicenergy # for MOF vib = Vibrations(adsorbedH, indices=[49,134,135,136,173,174,175,176,177,178], delta=0.01, nfree=2) # for mol #vib = Vibrations(adsorbedH, indices=[0,1,2,3,4,5,6,7,8,9], delta=0.01, nfree=2) vib.run() print vib.get_frequencies() vib.summary() print vib.get_mode(-1) vib.write_mode(-1) vib_energies = vib.get_energies() thermo = HarmonicThermo(vib_energies=vib_energies, electronicenergy=electronicenergy) thermo.get_entropy(temperature=298.15) thermo.get_free_energy(temperature=298.15)