Ejemplo n.º 1
0
    def __init__(self, rc=7.0, width=1.0):
        """ TIP4P potential for water.

        http://dx.doi.org/10.1063/1.445869

        Requires an atoms object of OHH,OHH, ... sequence
        Correct TIP4P charges and LJ parameters set automatically.

        Virtual interaction sites implemented in the following scheme:
        Original atoms object has no virtual sites.
        When energy/forces are requested:

        * virtual sites added to temporary xatoms object
        * energy / forces calculated
        * forces redistributed from virtual sites to actual atoms object

        This means you do not get into trouble when propagating your system
        with MD while having to skip / account for massless virtual sites.

        This also means that if using for QM/MM MD with GPAW, the EmbedTIP4P
        class must be used.
        """

        TIP3P.__init__(self, rc, width)
        self.energy = None
        self.forces = None
Ejemplo n.º 2
0
def test_combine_mm2():
    # More biased initial positions for faster test. Set
    # to false for a slower, harder test.
    fast_test = True

    atoms = make_4mer()
    atoms.constraints = FixBondLengths([(3 * i + j, 3 * i + (j + 1) % 3)
                                        for i in range(int(len(atoms) // 3))
                                        for j in [0, 1, 2]])
    atoms.calc = TIP3P(np.Inf)
    tag = '4mer_tip3_opt.'
    opt = FIRE(atoms, logfile=tag + 'log', trajectory=tag + 'traj')
    opt.run(fmax=0.05)
    tip3_pos = atoms.get_positions()

    sig = np.array([sigma0, 0, 0])
    eps = np.array([epsilon0, 0, 0])
    rc = np.Inf
    idxes = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11],
             list(range(6)),
             list(range(9)),
             list(range(6, 12))]

    for ii, idx in enumerate(idxes):
        atoms = make_4mer()
        if fast_test:
            atoms.set_positions(tip3_pos)
        atoms.constraints = FixBondLengths([(3 * i + j, 3 * i + (j + 1) % 3)
                                            for i in range(len(atoms) // 3)
                                            for j in [0, 1, 2]])

        atoms.calc = CombineMM(idx,
                               3,
                               3,
                               TIP3P(rc),
                               TIP3P(rc),
                               sig,
                               eps,
                               sig,
                               eps,
                               rc=rc)

        tag = '4mer_combtip3_opt_{0:02d}.'.format(ii)
        opt = FIRE(atoms, logfile=tag + 'log', trajectory=tag + 'traj')
        opt.run(fmax=0.05)
        assert ((abs(atoms.positions - tip3_pos) < 1e-8).all())
        print('{0}: {1!s:>28s}: Same Geometry as TIP3P'.format(
            atoms.calc.name, idx))
Ejemplo n.º 3
0
def make_dimer(constraint=True):
    """Prepare atoms object for testing"""
    dimer = s22.create_s22_system("Water_dimer")

    calc = TIP3P(rc=9.0)
    dimer.calc = calc
    if constraint:
        dimer.constraints = FixBondLengths([(3 * i + j, 3 * i + (j + 1) % 3)
                                            for i in range(2)
                                            for j in [0, 1, 2]])
    return dimer
Ejemplo n.º 4
0
def test_water_dimer(internal, order):
    internal = True
    order = 0
    rng = np.random.RandomState(1)

    atoms = atoms_ref.copy()
    atoms.calc = TIP3P()
    atoms.rattle(0.01, rng=rng)

    nwater = len(atoms) // 3
    cons = Constraints(atoms)
    for i in range(nwater):
        cons.fix_bond((3 * i, 3 * i + 1), target=rOH)
        cons.fix_bond((3 * i, 3 * i + 2), target=rOH)
        cons.fix_angle((3 * i + 1, 3 * i, 3 * i + 2), target=angleHOH)

    # Remove net translation and rotation
    try:
        cons.fix_translation()
    except DuplicateConstraintError:
        pass
    try:
        cons.fix_rotation()
    except DuplicateConstraintError:
        pass

    sella_kwargs = dict(
        order=order,
        trajectory='test.traj',
        eta=1e-6,
        delta0=1e-2,
    )
    if internal:
        sella_kwargs['internal'] = Internals(atoms,
                                             cons=cons,
                                             allow_fragments=True)
    else:
        sella_kwargs['constraints'] = cons
    opt = Sella(atoms, **sella_kwargs)

    opt.delta = 0.05
    opt.run(fmax=1e-3)
    print("First run done")

    atoms.rattle()
    opt.run(fmax=1e-3)

    Ufree = opt.pes.get_Ufree()
    g = opt.pes.get_g() @ Ufree
    np.testing.assert_allclose(g, 0, atol=1e-3)
    opt.pes.diag(gamma=1e-16)
    H = opt.pes.get_HL().project(Ufree)
    assert np.sum(H.evals < 0) == order, H.evals
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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))
Ejemplo n.º 7
0
from ase.md.langevin import Langevin
from ase.io import Trajectory
import ase.units as u

md_cls_and_kwargs = [
    (VelocityVerlet, {}),
    (Langevin, {
        "temperature": 300 * u.kB,
        "friction": 0.02
    }),
]

# prepare atoms object for testing
dimer = s22.create_s22_system("Water_dimer")

calc = TIP3P(rc=9.0)
dimer.constraints = FixBondLengths([(3 * i + j, 3 * i + (j + 1) % 3)
                                    for i in range(2) for j in [0, 1, 2]])


def fmax(forces):
    return np.sqrt((forces**2).sum(axis=1).max())


def test_opt(cls, atoms, calc, logfile="opt.log", trajectory="opt.traj"):
    """run optimization and verify that log and trajectory coincide"""

    # clean files to make sure the correct ones are tested
    for file in (*Path().glob("*.log"), *Path().glob("*.traj")):
        file.unlink()
Ejemplo n.º 8
0
    atoms2 = make_atoms()
    atoms2.translate([0., 3, 0])
    atoms2.rotate(180, 'y')
    atoms2.translate([3, 0, 0])
    atoms += atoms2
    return atoms

# More biased initial positions for faster test. Set 
# to false for a slower, harder test. 
fast_test = True  

atoms = make_4mer()
atoms.constraints = FixBondLengths([(3 * i + j, 3 * i + (j + 1) % 3)
                                    for i in range(int(len(atoms) // 3))
                                    for j in [0, 1, 2]])
atoms.calc = TIP3P(np.Inf)
tag = '4mer_tip3_opt.'
opt = FIRE(atoms, logfile=tag+'log', trajectory=tag+'traj')
opt.run(fmax=0.05)
tip3_pos = atoms.get_positions()

sig = np.array([sigma0, 0, 0 ])
eps = np.array([epsilon0, 0, 0 ])
rc = np.Inf
idxes = [[0, 1, 2], [3, 4 ,5], [6, 7, 8], [9, 10, 11],
         list(range(6)), list(range(9)), list(range(6, 12))]

for ii, idx in enumerate(idxes):
    atoms = make_4mer()
    if fast_test:
        atoms.set_positions(tip3_pos)
Ejemplo n.º 9
0
def calc():
    return TIP3P(rc=9.0)
Ejemplo n.º 10
0
import ase.units as units
from ase.calculators.tip3p import TIP3P, epsilon0, sigma0, rOH, angleHOH
from ase.calculators.qmmm import SimpleQMMM, EIQMMM, LJInteractions
from ase.data.s22 import create_s22_system as s22
from ase.md.verlet import VelocityVerlet
from ase.constraints import FixBondLengths

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,
                        2.0 * units.fs,
Ejemplo n.º 11
0
from __future__ import print_function
from ase.data import s22
from ase.calculators.tip3p import TIP3P, epsilon0, sigma0
from ase.calculators.qmmm import EIQMMM, LJInteractions, Embedding
from gpaw import GPAW

# Create system
atoms = s22.create_s22_system('Water_dimer')
atoms.center(vacuum=4.0)

# Make QM atoms selection of first water molecule:
qm_idx = range(3)

# Set up interaction & embedding object
interaction = LJInteractions({('O', 'O'): (epsilon0, sigma0)})
embedding = Embedding(rc=0.02)  # Short range analytical potential cutoff 

# Set up calculator
atoms.calc = EIQMMM(qm_idx,
                    GPAW(txt='qm.out'),
                    TIP3P(),
                    interaction,
                    embedding=embedding,
                    vacuum=None,  # if None, QM cell = MM cell
                    output='qmmm.log')

print(atoms.get_potential_energy())
Ejemplo n.º 12
0
"""Test TIP3P forces."""
from math import cos, sin

from ase import Atoms
from ase.calculators.tip3p import TIP3P, rOH, thetaHOH, set_tip3p_charges

r = rOH
a = thetaHOH

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)])
set_tip3p_charges(dimer)
dimer.calc = TIP3P(rc=4.0, width=2.0)  # put O-O distance in the cutoff range
dimer.positions[3:, 0] += 2.8
F = dimer.get_forces()
print(F)
dF = dimer.calc.calculate_numerical_forces(dimer) - F
print(dF)
assert abs(dF).max() < 2e-6
Ejemplo n.º 13
0
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)

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 = []
Ejemplo n.º 14
0
from ase import Atoms
from ase.calculators.tip3p import TIP3P, epsilon0, sigma0, rOH, angleHOH
from ase.calculators.qmmm import SimpleQMMM, EIQMMM, LJInteractions
from ase.calculators.turbomole import Turbomole
from ase.constraints import FixInternals
from ase.optimize import BFGS

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(),
Ejemplo n.º 15
0
def test_qmmm():
    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.tip3p import TIP3P, epsilon0, sigma0, rOH, angleHOH
    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 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)

        # 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, 2)), (r, (1, 2)),
                                                (r, (3, 5)), (r, (4, 5))],
                                         angles=[(a, (0, 2, 1)),
                                                 (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))
Ejemplo n.º 16
0
    atoms2.translate([0., 3, 0])
    atoms2.rotate(180, 'y')
    atoms2.translate([3, 0, 0])
    atoms += atoms2
    return atoms


# More biased initial positions for faster test. Set
# to false for a slower, harder test.
fast_test = True

atoms = make_4mer()
atoms.constraints = FixBondLengths([(3 * i + j, 3 * i + (j + 1) % 3)
                                    for i in range(int(len(atoms) // 3))
                                    for j in [0, 1, 2]])
atoms.calc = TIP3P(np.Inf)
tag = '4mer_tip3_opt.'
opt = FIRE(atoms, logfile=tag + 'log', trajectory=tag + 'traj')
opt.run(fmax=0.05)
tip3_pos = atoms.get_positions()

sig = np.array([sigma0, 0, 0])
eps = np.array([epsilon0, 0, 0])
rc = np.Inf
idxes = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11],
         list(range(6)),
         list(range(9)),
         list(range(6, 12))]

for ii, idx in enumerate(idxes):
    atoms = make_4mer()
Ejemplo n.º 17
0
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)])
Ejemplo n.º 18
0
def test_combine_mm():
    """Test CombineMM forces by combining tip3p and tip4p with them selves, and
       by combining tip3p with tip4p and testing against numerical forces.

       Also test LJInterationsGeneral with CombineMM """

    from math import cos, sin, pi
    import numpy as np
    from ase import Atoms
    from ase import units
    from ase.calculators.counterions import AtomicCounterIon as ACI
    from ase.calculators.combine_mm import CombineMM
    from ase.calculators.qmmm import LJInteractionsGeneral
    from ase.calculators.tip3p import TIP3P, rOH, angleHOH
    from ase.calculators.tip4p import TIP4P
    from ase.calculators.tip3p import epsilon0 as eps3
    from ase.calculators.tip3p import sigma0 as sig3
    from ase.calculators.tip4p import epsilon0 as eps4
    from ase.calculators.tip4p import sigma0 as sig4

    def make_atoms():
        r = rOH
        a = angleHOH * pi / 180
        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 = dimer[[2, 0, 1, 5, 3, 4]]
        # put O-O distance in the cutoff range
        dimer.positions[3:, 0] += 2.8

        return dimer

    dimer = make_atoms()
    rc = 3.0
    for (TIPnP, (eps, sig), nm) in zip([TIP3P, TIP4P],
                                       ((eps3, sig3), (eps4, sig4)), [3, 3]):
        dimer.calc = TIPnP(rc=rc, width=1.0)
        F1 = dimer.get_forces()

        sigma = np.array([sig, 0, 0])
        epsilon = np.array([eps, 0, 0])

        dimer.calc = CombineMM([0, 1, 2],
                               nm,
                               nm,
                               TIPnP(rc=rc, width=1.0),
                               TIPnP(rc=rc, width=1.0),
                               sigma,
                               epsilon,
                               sigma,
                               epsilon,
                               rc=rc,
                               width=1.0)

        F2 = dimer.get_forces()
        dF = F1 - F2
        print(TIPnP)
        print(dF)
        assert abs(dF).max() < 1e-8

    # Also check a TIP3P/TIP4P combination against numerical forces:
    eps1 = np.array([eps3, 0, 0])
    sig1 = np.array([sig3, 0, 0])
    eps2 = np.array([eps4, 0, 0])
    sig2 = np.array([sig4, 0, 0])
    dimer.calc = CombineMM([0, 1, 2], 3, 3, TIP3P(rc, 1.0), TIP4P(rc, 1.0),
                           sig1, eps1, sig2, eps2, rc, 1.0)

    F2 = dimer.get_forces()
    Fn = dimer.calc.calculate_numerical_forces(dimer, 1e-7)
    dF = F2 - Fn
    print('TIP3P/TIP4P')
    print(dF)
    assert abs(dF).max() < 1e-8

    # LJInteractionsGeneral with CombineMM.
    # As it is used within EIQMMM, but avoiding long calculations for tests.
    # Total system is a unit test system comprised of:
    #    2 Na ions playing the role of a 'QM' subsystem
    #    2 Na ions as the 'Counterions'
    #    2 Water molecules

    dimer.calc = []
    faux_qm = Atoms('2Na', positions=np.array([[1.4, -4, 0], [1.4, 4, 0]]))
    ions = Atoms('2Na', positions=np.array([[1.4, 0, -4], [1.4, 0, 4]]))

    mmatoms = ions + dimer

    sigNa = 1.868 * (1.0 / 2.0)**(1.0 / 6.0) * 10
    epsNa = 0.00277 * units.kcal / units.mol

    # ACI for atoms 0 and 1 of the MM subsystem (2 and 3 for the total system)
    # 1 atom 'per molecule'. The rest is TIP4P, 3 atoms per molecule:
    calc = CombineMM(
        [0, 1],
        1,
        3,
        ACI(1, epsNa, sigNa),  # calc 1
        TIP4P(),  # calc 2
        [sigNa],
        [epsNa],  # LJs for subsystem 1
        sig2,
        eps2,  # arrays for TIP4P from earlier
        rc=7.5)

    mmatoms.calc = calc
    mmatoms.calc.initialize(mmatoms)

    # LJ arrays for the 'QM' subsystem
    sig_qm = np.array([sigNa, sigNa])
    eps_qm = np.array([epsNa, epsNa])

    # For the MM subsystem, tuple of arrays (counterion, water)
    sig_mm = (np.array([sigNa]), sig2)
    eps_mm = (np.array([epsNa]), eps2)

    lj = LJInteractionsGeneral(sig_qm, eps_qm, sig_mm, eps_mm, 2)

    ecomb, fcomb1, fcomb2 = lj.calculate(faux_qm, mmatoms, np.array([0, 0, 0]))

    # This should give the same result as if not using CombineMM, on a sum
    # of these systems:
    # A: All the Na atoms in the 'QM' region
    # B: LJInteractions between the 'QM' Na and the 'MM' Na
    # C: -LJinteractions between the 'MM' Na and the 'MM' Water

    # A:
    mmatoms = dimer
    mmatoms.calc = []
    sig_qm = np.concatenate((sig_qm, sig_qm))
    eps_qm = np.concatenate((eps_qm, eps_qm))
    sig_mm = sig_mm[1]
    eps_mm = eps_mm[1]
    lj = LJInteractionsGeneral(sig_qm, eps_qm, sig_mm, eps_mm, 4)
    ea, fa1, fa2 = lj.calculate(faux_qm + ions, mmatoms, np.array([0, 0, 0]))

    # B:
    lj = LJInteractionsGeneral(sig_qm[:2], eps_qm[:2], sig_qm[:2], eps_qm[:2],
                               2, 2)

    eb, fb1, fb2, = lj.calculate(faux_qm, ions, np.array([0, 0, 0]))

    # C:
    lj = LJInteractionsGeneral(sig_qm[:2], eps_qm[:2], sig_mm, eps_mm, 2, 3)

    ec, fc1, fc2, = lj.calculate(ions, dimer, np.array([0, 0, 0]))

    assert ecomb - (ea + eb) + ec == 0
Ejemplo n.º 19
0
                           epsilon,
                           rc=rc,
                           width=1.0)

    F2 = dimer.get_forces()
    dF = F1 - F2
    print(TIPnP)
    print(dF)
    assert abs(dF).max() < 1e-8

# Also check a TIP3P/TIP4P combination against numerical forces:
eps1 = np.array([eps3, 0, 0])
sig1 = np.array([sig3, 0, 0])
eps2 = np.array([eps4, 0, 0])
sig2 = np.array([sig4, 0, 0])
dimer.calc = CombineMM([0, 1, 2], 3, 3, TIP3P(rc, 1.0), TIP4P(rc, 1.0), sig1,
                       eps1, sig2, eps2, rc, 1.0)

F2 = dimer.get_forces()
Fn = dimer.calc.calculate_numerical_forces(dimer, 1e-7)
dF = F2 - Fn
print('TIP3P/TIP4P')
print(dF)
assert abs(dF).max() < 1e-8

# LJInteractionsGeneral with CombineMM.
# As it is used within EIQMMM, but avoiding long calculations for tests.
# Total system is a unit test system comprised of:
#    2 Na ions playing the role of a 'QM' subsystem
#    2 Na ions as the 'Counterions'
#    2 Water molecules
Ejemplo n.º 20
0
       [0, rOH * np.cos(x), -rOH * np.sin(x)]]
atoms = Atoms('OH2', positions=pos)

vol = ((18.01528 / 6.022140857e23) / (0.9982 / 1e24))**(1 / 3.)
atoms.set_cell((vol, vol, vol))
atoms.center()

atoms = atoms.repeat((3, 3, 3))
atoms.set_pbc(True)

# RATTLE-type constraints on O-H1, O-H2, H1-H2.
atoms.constraints = FixBondLengths([(3 * i + j, 3 * i + (j + 1) % 3)
                                    for i in range(3**3) for j in [0, 1, 2]])

tag = 'tip3p_27mol_equil'
atoms.calc = TIP3P(rc=4.5)
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(4000)

# Repeat box and equilibrate further.
tag = 'tip3p_216mol_equil'
atoms.set_constraint()  # repeat not compatible with FixBondLengths currently.
atoms = atoms.repeat((2, 2, 2))
atoms.constraints = FixBondLengths([(3 * i + j, 3 * i + (j + 1) % 3)