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.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)) # 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.calc = EMT() image.set_constraint(constraint) # Displace last image: images[-1].positions[-1] += (d, 0, 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 = 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_consistency_with_vibrationsdata(self, testdir, n2_emt): atoms = n2_emt vib = Vibrations(atoms) vib.run() vib_data = vib.get_vibrations() assert_array_almost_equal(vib.get_energies(), vib_data.get_energies()) # Compare the last mode as the others may be re-ordered by negligible # energy changes assert_array_almost_equal(vib.get_mode(5), vib_data.get_modes()[5])
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 test_vibration_on_surface(self, testdir): from ase.build import fcc111, add_adsorbate ag_slab = fcc111('Ag', (4, 4, 2), a=2) n2 = Atoms('N2', positions=[[0., 0., 0.], [0., np.sqrt(2), np.sqrt(2)]]) add_adsorbate(ag_slab, n2, height=1, position='fcc') # Add an interaction between the N atoms hessian_bottom_corner = np.zeros((2, 3, 2, 3)) hessian_bottom_corner[-1, :, -2] = [1, 1, 1] hessian_bottom_corner[-2, :, -1] = [1, 1, 1] hessian = np.zeros((34, 3, 34, 3)) hessian[32:, :, 32:, :] = hessian_bottom_corner ag_slab.calc = ForceConstantCalculator(hessian.reshape( (34 * 3, 34 * 3)), ref=ag_slab.copy(), f0=np.zeros((34, 3))) # Check that Vibrations with restricted indices returns correct Hessian vibs = Vibrations(ag_slab, indices=[-2, -1]) vibs.run() vibs.read() assert_array_almost_equal(vibs.get_vibrations().get_hessian(), hessian_bottom_corner) # These should blow up if the vectors don't match number of atoms vibs.summary() vibs.write_jmol() for i in range(6): # Frozen atoms should have zero displacement assert_array_almost_equal(vibs.get_mode(i)[0], [0., 0., 0.]) # The N atoms should have finite displacement assert np.all(vibs.get_mode(i)[-2:, :])
def get_modes(self,atm,freqname="vib."): for f in [f for f in os.listdir(".") if freqname in f and '.pckl' in f]: os.remove(f) new_target = open(os.devnull, "w") old_target, sys.stdout = sys.stdout, new_target atm.set_calculator(ANIENS(self.ens)) vib = Vibrations(atm, nfree=2, name=freqname) vib.run() freq = vib.get_frequencies() modes = np.stack(vib.get_mode(i) for i in range(freq.size)) vib.clean() sys.stdout = old_target return modes
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 test_consistency_with_vibrationsdata(self, testdir, random_dimer): vib = Vibrations(random_dimer, delta=1e-6, nfree=4) vib.run() vib_data = vib.get_vibrations() assert_array_almost_equal(vib.get_energies(), vib_data.get_energies()) for mode_index in range(3 * len(vib.atoms)): assert_array_almost_equal(vib.get_mode(mode_index), vib_data.get_modes()[mode_index]) # Hessian should be close to the ForceConstantCalculator input assert_array_almost_equal(random_dimer.calc.D, vib_data.get_hessian_2d(), decimal=6)
def test_vibrations_on_surface(self, testdir): atoms = self.n2_on_ag.copy() atoms.calc = EMT() vibs = Vibrations(atoms, indices=[-2, -1]) vibs.run() freqs = vibs.get_frequencies() assert len(freqs) == 6 vib_data = vibs.get_vibrations() assert_array_almost_equal(freqs, vib_data.get_frequencies()) # These should blow up if the vectors don't match number of atoms vibs.summary() vibs.write_jmol() for i in range(6): # Frozen atoms should have zero displacement assert_array_almost_equal(vibs.get_mode(i)[0], [0., 0., 0.]) # At least one of the N atoms should have finite displacement # (It's a strange test system, the N aren't interacting.) assert np.any(vibs.get_mode(i)[-2:, :])
from __future__ import print_function 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() 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))
from ase import * from ase.vibrations import Vibrations 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(-1, nimages=20)
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(-1, nimages=20) vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=n2, symmetrynumber=2, spin=0) thermo.get_free_energy(temperature=298.15, pressure=2*101325.)
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.)
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')
# 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, atoms=atoms, geometry='linear', symmetrynumber=2, spin=0) G = thermo.get_gibbs_energy(temperature=298.15, pressure=101325.) ''' # remove mode pckl files vib.clean()