def test_au111(wrap): zpos = cos(134.3 / 2.0 * pi / 180.0) * 1.197 xpos = sin(134.3 / 2.0 * pi / 180.0) * 1.19 co2 = Atoms('COO', positions=[(-xpos + 1.2, 0, -zpos), (-xpos + 1.2, -1.1, -zpos), (-xpos + 1.2, 1.1, -zpos)]) slab = fcc111('Au', size=(2, 2, 4), vacuum=2 * 5, orthogonal=True) slab.center() add_adsorbate(slab, co2, 1.5, 'bridge') slab.set_pbc((True, True, False)) d0 = co2.get_distance(-3, -2) d1 = co2.get_distance(-3, -1) d2 = co2.get_distance(-2, -1) calc = EMT() slab.set_calculator(calc) if wrap: # Remap into the cell so bond is actually wrapped: slab.set_scaled_positions(slab.get_scaled_positions() % 1.0) constraint = FixLinearTriatomic(triples=[(-2, -3, -1)]) slab.set_constraint(constraint) dyn = BFGS(slab, trajectory='relax_%d.traj' % wrap) dyn.run(fmax=0.05) assert abs(slab.get_distance(-3, -2, mic=1) - d0) < 1e-9 assert abs(slab.get_distance(-3, -1, mic=1) - d1) < 1e-9 assert abs(slab.get_distance(-2, -1, mic=1) - d2) < 1e-9
def test_qmmm_acn(): import numpy as np import ase.units as units from ase import Atoms from ase.calculators.acn import (ACN, m_me, r_cn, r_mec, sigma_me, sigma_c, sigma_n, epsilon_me, epsilon_c, epsilon_n) from ase.calculators.qmmm import SimpleQMMM, LJInteractionsGeneral, EIQMMM from ase.constraints import FixLinearTriatomic from ase.optimize import BFGS # From https://www.sciencedirect.com/science/article/pii/S0166128099002079 eref = 4.9 * units.kcal / units.mol dref = 3.368 aref = 79.1 sigma = np.array([sigma_me, sigma_c, sigma_n]) epsilon = np.array([epsilon_me, epsilon_c, epsilon_n]) inter = LJInteractionsGeneral(sigma, epsilon, sigma, epsilon, 3) for calc in [ACN(), SimpleQMMM([0, 1, 2], ACN(), ACN(), ACN()), SimpleQMMM([0, 1, 2], ACN(), ACN(), ACN(), vacuum=3.0), EIQMMM([0, 1, 2], ACN(), ACN(), inter), EIQMMM([0, 1, 2], ACN(), ACN(), inter, vacuum=3.0), EIQMMM([3, 4, 5], ACN(), ACN(), inter, vacuum=3.0)]: dimer = Atoms('CCNCCN', [(-r_mec, 0, 0), (0, 0, 0), (r_cn, 0, 0), (r_mec, 3.7, 0), (0, 3.7, 0), (-r_cn, 3.7, 0)]) masses = dimer.get_masses() masses[::3] = m_me dimer.set_masses(masses) dimer.calc = calc fixd = FixLinearTriatomic(triples=[(0, 1, 2), (3, 4, 5)]) dimer.set_constraint(fixd) opt = BFGS(dimer, maxstep=0.04, trajectory=calc.name + '.traj', logfile=calc.name + 'd.log') opt.run(0.001, steps=1000) e0 = dimer.get_potential_energy() d0 = dimer.get_distance(1, 4) a0 = dimer.get_angle(2, 1, 4) fmt = '{0:>25}: {1:.3f} {2:.3f} {3:.1f}' print(fmt.format(calc.name, -e0, d0, a0)) assert abs(e0 + eref) < 0.013 assert abs(d0 - dref) < 0.224 assert abs(a0 - aref) < 2.9 print(fmt.format('reference', eref, dref, aref))
def test_rattle_linear(): """Test RATTLE and QM/MM for rigid linear acetonitrile.""" import numpy as np from ase import Atoms from ase.calculators.acn import (ACN, m_me, r_cn, r_mec, sigma_me, sigma_c, sigma_n, epsilon_me, epsilon_c, epsilon_n) from ase.calculators.qmmm import SimpleQMMM, EIQMMM, LJInteractionsGeneral from ase.md.verlet import VelocityVerlet from ase.constraints import FixLinearTriatomic import ase.units as units sigma = np.array([sigma_me, sigma_c, sigma_n]) epsilon = np.array([epsilon_me, epsilon_c, epsilon_n]) i = LJInteractionsGeneral(sigma, epsilon, sigma, epsilon, 3) for calc in [ ACN(), SimpleQMMM([0, 1, 2], ACN(), ACN(), ACN()), EIQMMM([0, 1, 2], ACN(), ACN(), i) ]: dimer = Atoms('CCNCCN', [(-r_mec, 0, 0), (0, 0, 0), (r_cn, 0, 0), (r_mec, 3.7, 0), (0, 3.7, 0), (-r_cn, 3.7, 0)]) masses = dimer.get_masses() masses[::3] = m_me dimer.set_masses(masses) fixd = FixLinearTriatomic(triples=[(0, 1, 2), (3, 4, 5)]) dimer.set_constraint(fixd) dimer.calc = calc d1 = dimer[:3].get_all_distances() d2 = dimer[3:].get_all_distances() e = dimer.get_potential_energy() md = VelocityVerlet(dimer, 2.0 * units.fs, trajectory=calc.name + '.traj', logfile=calc.name + '.log', loginterval=20) md.run(100) de = dimer.get_potential_energy() - e assert np.all(abs(dimer[:3].get_all_distances() - d1) < 1e-10) assert np.all(abs(dimer[3:].get_all_distances() - d2) < 1e-10) assert abs(de - -0.005) < 0.001
def test_CO2linear_Au111_langevin(testdir): """Test Langevin with constraints for rigid linear triatomic molecules""" rng = np.random.RandomState(0) eref = 3.133526 zpos = cos(134.3 / 2.0 * pi / 180.0) * 1.197 xpos = sin(134.3 / 2.0 * pi / 180.0) * 1.19 co2 = Atoms('COO', positions=[(-xpos + 1.2, 0, -zpos), (-xpos + 1.2, -1.1, -zpos), (-xpos + 1.2, 1.1, -zpos)]) slab = fcc111('Au', size=(2, 2, 4), vacuum=2 * 5, orthogonal=True) slab.center() add_adsorbate(slab, co2, 1.5, 'bridge') slab.set_pbc((True, True, False)) d0 = co2.get_distance(-3, -2) d1 = co2.get_distance(-3, -1) d2 = co2.get_distance(-2, -1) calc = EMT() slab.calc = calc constraint = FixLinearTriatomic(triples=[(-2, -3, -1)]) slab.set_constraint(constraint) fr = 0.1 dyn = Langevin(slab, 2.0 * units.fs, temperature_K=300, friction=fr, trajectory='langevin_%.1f.traj' % fr, logfile='langevin_%.1f.log' % fr, loginterval=20, rng=rng) dyn.run(100) # Check that the temperature is within a reasonable range T = slab.get_temperature() assert T > 100 assert T < 500 # Check that the constraints work assert abs(slab.get_distance(-3, -2, mic=1) - d0) < 1e-9 assert abs(slab.get_distance(-3, -1, mic=1) - d1) < 1e-9 assert abs(slab.get_distance(-2, -1, mic=1) - d2) < 1e-9 # If the energy differs from the reference energy # it is most probable that the redistribution of # random forces in Langevin is not working properly assert abs(slab.get_potential_energy() - eref) < 1e-4
def test_getindices(): from ase.build import fcc111 from ase.constraints import (FixAtoms, FixBondLengths, FixLinearTriatomic, FixInternals, Hookean, constrained_indices) slab = fcc111('Pt', (4, 4, 4)) C1 = FixAtoms([0, 2, 4]) C2 = FixBondLengths([[0, 1], [0, 2]]) C3 = FixInternals(bonds=[[1, [7, 8]], [1, [8, 9]]]) C4 = Hookean(a1=30, a2=40, rt=1.79, k=5.) C5 = FixLinearTriatomic(triples=[(0, 1, 2), (3, 4, 5)]) slab.set_constraint([C1, C2, C3, C4, C5]) assert all( constrained_indices(slab, (FixAtoms, FixBondLengths)) == [0, 1, 2, 4]) assert all( constrained_indices(slab, (FixBondLengths, FixLinearTriatomic)) == [0, 1, 2, 3, 4, 5]) assert all( constrained_indices(slab) == [0, 1, 2, 3, 4, 5, 7, 8, 9, 30, 40])
masses = atoms.get_masses() masses[::3] = m_me atoms.set_masses(masses) # Determine side length of a box with the density of acetonitrile at 298 K d = 0.776 / 1e24 # Density in g/Ang3 (https://pubs.acs.org/doi/10.1021/je00001a006) L = ((masses.sum() / units.mol) / d)**(1 / 3.) # Set up box of 27 acetonitrile molecules atoms.set_cell((L, L, L)) atoms.center() atoms = atoms.repeat((3, 3, 3)) atoms.set_pbc(True) # Set constraints for rigid triatomic molecules nm = 27 atoms.constraints = FixLinearTriatomic(triples=[(3 * i, 3 * i + 1, 3 * i + 2) for i in range(nm)]) tag = 'acn_27mol_300K' atoms.calc = ACN(rc=np.min(np.diag(atoms.cell)) / 2) # Create Langevin object md = Langevin(atoms, 1 * units.fs, temperature=300 * units.kB, friction=0.01, logfile=tag + '.log') traj = Trajectory(tag + '.traj', 'w', atoms) md.attach(traj.write, interval=1) md.run(5000)
i = LJInteractionsGeneral(sigma, epsilon, sigma, epsilon, 3) for calc in [ ACN(), SimpleQMMM([0, 1, 2], ACN(), ACN(), ACN()), EIQMMM([0, 1, 2], ACN(), ACN(), i) ]: dimer = Atoms('CCNCCN', [(-r_mec, 0, 0), (0, 0, 0), (r_cn, 0, 0), (r_mec, 3.7, 0), (0, 3.7, 0), (-r_cn, 3.7, 0)]) masses = dimer.get_masses() masses[::3] = m_me dimer.set_masses(masses) fixd = FixLinearTriatomic(triples=[(0, 1, 2), (3, 4, 5)]) dimer.set_constraint(fixd) dimer.calc = calc d1 = dimer[:3].get_all_distances() d2 = dimer[3:].get_all_distances() e = dimer.get_potential_energy() md = VelocityVerlet(dimer, 2.0 * units.fs, trajectory=calc.name + '.traj', logfile=calc.name + '.log', loginterval=20) md.run(100)
xpos = sin(134.3 / 2.0 * pi / 180.0) * 1.19 co2 = Atoms('COO', positions=[(-xpos + 1.2, 0, -zpos), (-xpos + 1.2, -1.1, -zpos), (-xpos + 1.2, 1.1, -zpos)]) slab = fcc111('Au', size=(2, 2, 4), vacuum=2 * 5, orthogonal=True) slab.center() add_adsorbate(slab, co2, 1.5, 'bridge') slab.set_pbc((True, True, False)) d0 = co2.get_distance(-3, -2) d1 = co2.get_distance(-3, -1) d2 = co2.get_distance(-2, -1) calc = EMT() slab.set_calculator(calc) constraint = FixLinearTriatomic(triples=[(-2, -3, -1)]) slab.set_constraint(constraint) fr = 0.1 dyn = Langevin(slab, 2.0 * units.fs, 300 * units.kB, fr, trajectory='langevin_%.1f.traj' % fr, logfile='langevin_%.1f.log' % fr, loginterval=20, rng=rng) dyn.run(100) # Check that the temperature is within a reasonable range T = slab.get_temperature()