def test_rattle(): i = LJInteractions({('O', 'O'): (epsilon0, sigma0)}) for calc in [ TIP3P(), SimpleQMMM([0, 1, 2], TIP3P(), TIP3P(), TIP3P()), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), i) ]: dimer = s22('Water_dimer') for m in [0, 3]: dimer.set_angle(m + 1, m, m + 2, angleHOH) dimer.set_distance(m, m + 1, rOH, fix=0) dimer.set_distance(m, m + 2, rOH, fix=0) fixOH1 = [(3 * i, 3 * i + 1) for i in range(2)] fixOH2 = [(3 * i, 3 * i + 2) for i in range(2)] fixHH = [(3 * i + 1, 3 * i + 2) for i in range(2)] dimer.set_constraint(FixBondLengths(fixOH1 + fixOH2 + fixHH)) dimer.calc = calc e = dimer.get_potential_energy() md = VelocityVerlet(dimer, 8.0 * units.fs, trajectory=calc.name + '.traj', logfile=calc.name + '.log', loginterval=5) md.run(25) de = dimer.get_potential_energy() - e assert abs(de - -0.028) < 0.001
def test_orca_qmmm(): from ase.calculators.tip4p import TIP4P, epsilon0, sigma0 from ase.calculators.orca import ORCA from ase.calculators.qmmm import EIQMMM, LJInteractions from ase.data import s22 atoms = s22.create_s22_system('Water_dimer') qmcalc = ORCA(label='water', orcasimpleinput='BLYP def2-SVP') lj = LJInteractions({('O', 'O'): (epsilon0, sigma0)}) atoms.calc = EIQMMM(selection=[0, 1, 2], qmcalc=qmcalc, mmcalc=TIP4P(), interaction=lj, output='orca_qmmm.log') e = atoms.get_potential_energy() assert abs(e + 2077.45445852) < 1.0
def test_qmmm_tip4p(): from math import cos, sin, pi import numpy as np #import matplotlib.pyplot as plt import ase.units as units from ase import Atoms from ase.calculators.tip4p import TIP4P, epsilon0, sigma0, rOH, angleHOH from ase.calculators.qmmm import (SimpleQMMM, EIQMMM, LJInteractions, LJInteractionsGeneral) from ase.constraints import FixInternals from ase.optimize import BFGS r = rOH a = angleHOH * pi / 180 # From https://doi.org/10.1063/1.445869 eexp = 6.24 * units.kcal / units.mol dexp = 2.75 aexp = 46 D = np.linspace(2.5, 3.5, 30) i = LJInteractions({('O', 'O'): (epsilon0, sigma0)}) # General LJ interaction object sigma_mm = np.array([sigma0, 0, 0]) epsilon_mm = np.array([epsilon0, 0, 0]) sigma_qm = np.array([sigma0, 0, 0]) epsilon_qm = np.array([epsilon0, 0, 0]) ig = LJInteractionsGeneral(sigma_qm, epsilon_qm, sigma_mm, epsilon_mm, 3) for calc in [ TIP4P(), SimpleQMMM([0, 1, 2], TIP4P(), TIP4P(), TIP4P()), SimpleQMMM([0, 1, 2], TIP4P(), TIP4P(), TIP4P(), vacuum=3.0), EIQMMM([0, 1, 2], TIP4P(), TIP4P(), i), EIQMMM([3, 4, 5], TIP4P(), TIP4P(), i, vacuum=3.0), EIQMMM([0, 1, 2], TIP4P(), TIP4P(), i, vacuum=3.0), EIQMMM([0, 1, 2], TIP4P(), TIP4P(), ig), EIQMMM([3, 4, 5], TIP4P(), TIP4P(), ig, vacuum=3.0), EIQMMM([0, 1, 2], TIP4P(), TIP4P(), ig, vacuum=3.0) ]: dimer = Atoms('OH2OH2', [(0, 0, 0), (r * cos(a), 0, r * sin(a)), (r, 0, 0), (0, 0, 0), (r * cos(a / 2), r * sin(a / 2), 0), (r * cos(a / 2), -r * sin(a / 2), 0)]) dimer.calc = calc E = [] F = [] for d in D: dimer.positions[3:, 0] += d - dimer.positions[3, 0] E.append(dimer.get_potential_energy()) F.append(dimer.get_forces()) F = np.array(F) #plt.plot(D, E) F1 = np.polyval(np.polyder(np.polyfit(D, E, 7)), D) F2 = F[:, :3, 0].sum(1) error = abs(F1 - F2).max() assert error < 0.01 dimer.constraints = FixInternals(bonds=[(r, (0, 1)), (r, (0, 2)), (r, (3, 4)), (r, (3, 5))], angles=[(a, (2, 0, 1)), (a, (5, 3, 4))]) opt = BFGS(dimer, maxstep=0.04, trajectory=calc.name + '.traj', logfile=calc.name + 'd.log') opt.run(0.01) e0 = dimer.get_potential_energy() d0 = dimer.get_distance(0, 3) R = dimer.positions v1 = R[2] - R[3] v2 = R[3] - (R[5] + R[4]) / 2 a0 = np.arccos( np.dot(v1, v2) / (np.dot(v1, v1) * np.dot(v2, v2))**0.5) / np.pi * 180 fmt = '{0:>23}: {1:.3f} {2:.3f} {3:.3f} {4:.1f}' print(fmt.format(calc.name, -min(E), -e0, d0, a0)) assert abs(e0 + eexp) < 0.002 assert abs(d0 - dexp) < 0.006 assert abs(a0 - aexp) < 2.5 print(fmt.format('reference', 9.999, eexp, dexp, aexp))
from ase.calculators.qmmm import (SimpleQMMM, EIQMMM, LJInteractions, LJInteractionsGeneral) from ase.constraints import FixInternals from ase.optimize import GPMin r = rOH a = angleHOH * pi / 180 # From http://dx.doi.org/10.1063/1.445869 eexp = 6.50 * units.kcal / units.mol dexp = 2.74 aexp = 27 D = np.linspace(2.5, 3.5, 30) i = LJInteractions({('O', 'O'): (epsilon0, sigma0)}) # General LJ interaction object sigma_mm = np.array([0, 0, sigma0]) epsilon_mm = np.array([0, 0, epsilon0]) sigma_qm = np.array([0, 0, sigma0]) epsilon_qm = np.array([0, 0, epsilon0]) ig = LJInteractionsGeneral(sigma_qm, epsilon_qm, sigma_mm, epsilon_mm, 3) for calc in [TIP3P(), SimpleQMMM([0, 1, 2], TIP3P(), TIP3P(), TIP3P()), SimpleQMMM([0, 1, 2], TIP3P(), TIP3P(), TIP3P(), vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), i), EIQMMM([3, 4, 5], TIP3P(), TIP3P(), i, vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), i, vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), ig),
def test_qmmm(testdir): r = rOH a = angleHOH * pi / 180 # From https://doi.org/10.1063/1.445869 eexp = 6.50 * units.kcal / units.mol dexp = 2.74 aexp = 27 D = np.linspace(2.5, 3.5, 30) i = LJInteractions({('O', 'O'): (epsilon0, sigma0)}) # General LJ interaction object sigma_mm = np.array([0, 0, sigma0]) epsilon_mm = np.array([0, 0, epsilon0]) sigma_qm = np.array([0, 0, sigma0]) epsilon_qm = np.array([0, 0, epsilon0]) ig = LJInteractionsGeneral(sigma_qm, epsilon_qm, sigma_mm, epsilon_mm, 3) for calc in [ TIP3P(), SimpleQMMM([0, 1, 2], TIP3P(), TIP3P(), TIP3P()), SimpleQMMM([0, 1, 2], TIP3P(), TIP3P(), TIP3P(), vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), i), EIQMMM([3, 4, 5], TIP3P(), TIP3P(), i, vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), i, vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), ig), EIQMMM([3, 4, 5], TIP3P(), TIP3P(), ig, vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), ig, vacuum=3.0) ]: dimer = Atoms('H2OH2O', [(r * cos(a), 0, r * sin(a)), (r, 0, 0), (0, 0, 0), (r * cos(a / 2), r * sin(a / 2), 0), (r * cos(a / 2), -r * sin(a / 2), 0), (0, 0, 0)]) dimer.calc = calc E = [] F = [] for d in D: dimer.positions[3:, 0] += d - dimer.positions[5, 0] E.append(dimer.get_potential_energy()) F.append(dimer.get_forces()) F = np.array(F) F1 = np.polyval(np.polyder(np.polyfit(D, E, 7)), D) F2 = F[:, :3, 0].sum(1) error = abs(F1 - F2).max() assert error < 0.01 dimer.constraints = FixInternals(bonds=[(r, (0, 2)), (r, (1, 2)), (r, (3, 5)), (r, (4, 5))], angles_deg=[ (np.degrees(a), (0, 2, 1)), (np.degrees(a), (3, 5, 4)) ]) opt = GPMin(dimer, trajectory=calc.name + '.traj', logfile=calc.name + 'd.log') opt.run(0.01) e0 = dimer.get_potential_energy() d0 = dimer.get_distance(2, 5) R = dimer.positions v1 = R[1] - R[5] v2 = R[5] - (R[3] + R[4]) / 2 a0 = np.arccos( np.dot(v1, v2) / (np.dot(v1, v1) * np.dot(v2, v2))**0.5) / np.pi * 180 fmt = '{0:>20}: {1:.3f} {2:.3f} {3:.3f} {4:.1f}' print(fmt.format(calc.name, -min(E), -e0, d0, a0)) assert abs(e0 + eexp) < 0.002 assert abs(d0 - dexp) < 0.01 assert abs(a0 - aexp) < 4 print(fmt.format('reference', 9.999, eexp, dexp, aexp))
def test_turbomole_qmmm(): """Test the Turbomole calculator in simple QMMM and explicit interaction QMMM simulations.""" r = rOH a = angleHOH * pi / 180 D = np.linspace(2.5, 3.5, 30) interaction = LJInteractions({('O', 'O'): (epsilon0, sigma0)}) qm_par = {'esp fit': 'kollman', 'multiplicity': 1} for calc in [ TIP3P(), SimpleQMMM([0, 1, 2], Turbomole(**qm_par), TIP3P(), TIP3P()), SimpleQMMM([0, 1, 2], Turbomole(**qm_par), TIP3P(), TIP3P(), vacuum=3.0), EIQMMM([0, 1, 2], Turbomole(**qm_par), TIP3P(), interaction), EIQMMM([3, 4, 5], Turbomole(**qm_par), TIP3P(), interaction, vacuum=3.0), EIQMMM([0, 1, 2], Turbomole(**qm_par), TIP3P(), interaction, vacuum=3.0) ]: dimer = Atoms('H2OH2O', [(r * cos(a), 0, r * sin(a)), (r, 0, 0), (0, 0, 0), (r * cos(a / 2), r * sin(a / 2), 0), (r * cos(a / 2), -r * sin(a / 2), 0), (0, 0, 0)]) dimer.calc = calc E = [] F = [] for d in D: dimer.positions[3:, 0] += d - dimer.positions[5, 0] E.append(dimer.get_potential_energy()) F.append(dimer.get_forces()) F = np.array(F) F1 = np.polyval(np.polyder(np.polyfit(D, E, 7)), D) F2 = F[:, :3, 0].sum(1) error = abs(F1 - F2).max() assert error < 0.9 dimer.set_constraint( FixInternals(bonds=[(r, (0, 2)), (r, (1, 2)), (r, (3, 5)), (r, (4, 5))], angles_deg=[(angleHOH, (0, 2, 1)), (angleHOH, (3, 5, 4))])) opt = BFGS(dimer, trajectory=calc.name + '.traj', logfile=calc.name + 'd.log') opt.run(0.01) e0 = dimer.get_potential_energy() d0 = dimer.get_distance(2, 5) R = dimer.positions v1 = R[1] - R[5] v2 = R[5] - (R[3] + R[4]) / 2 a0 = np.arccos( np.dot(v1, v2) / (np.dot(v1, v1) * np.dot(v2, v2))**0.5) / np.pi * 180 fmt = '{0:>20}: {1:.3f} {2:.3f} {3:.3f} {4:.1f}' print(fmt.format(calc.name, -min(E), -e0, d0, a0))