Exemplo n.º 1
0
 def __init__(self, repeat):
     nmol = repeat[0] * repeat[1] * repeat[2]
     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)
     x = angleHOH * np.pi / 180 / 2
     pos = [[0, 0, 0], [0, rOH * np.cos(x), rOH * np.sin(x)],
            [0, rOH * np.cos(x), -rOH * np.sin(x)]]
     calc = TIP4P()
     self.h2o = Atoms('OH2', [(0, 0, 0), (r * cos(a), 0, r * sin(a)),
                              (r, 0, 0)])
     vol = ((18.01528 / 6.022140857e23) / (0.9982 / 1e24))**(1 / 3.)
     self.h2o.set_cell((1.1 * r, 1.1 * r, 1.1 * r))
     self.h2o = self.h2o.repeat(repeat)
     self.h2o.set_cell((0, 0, 0))
     nmol = int(self.h2o.positions.shape[0] / 3)
     bonds = [(3 * i, 3 * i + 1) for i in range(nmol)]
     for i in range(nmol):
         bonds.append((3 * i, 3 * i + 2))
     bonds_rOH = []
     for bond in bonds:
         bonds_rOH.append((rOH, (bond)))
     angles = [(a, (3 * i + 2, 3 * i, 3 * i + 1)) for i in range(nmol)]
     self.h2o.constraints = FixInternals(bonds=bonds_rOH,
                                         angles=angles,
                                         epsilon=epsilon0)
     calc = TIP4P()
     self.h2o.calc = calc
Exemplo n.º 2
0
def test_tip4p():
    """Test TIP4P forces."""
    from math import cos, sin

    from ase import Atoms
    from ase.calculators.tip4p import TIP4P, rOH, angleHOH

    r = rOH
    a = angleHOH

    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)])

    # tip4p sequence OHH, OHH, ..
    dimer = dimer[[2]] + dimer[:2] + dimer[[-1]] + dimer[3:5]
    dimer.positions[3:, 0] += 2.8

    dimer.calc = TIP4P(rc=4.0,
                       width=2.0)  # put O-O distance in the cutoff range
    F = dimer.get_forces()
    print(F)
    dF = dimer.calc.calculate_numerical_forces(dimer) - F
    print(dF)
    assert abs(dF).max() < 2e-6
Exemplo n.º 3
0
    def __init__(self, nmol=5, size=3):
        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)
        x = angleHOH * np.pi / 180 / 2
        pos = [[0, 0, 0], [0, rOH * np.cos(x), rOH * np.sin(x)],
               [0, rOH * np.cos(x), -rOH * np.sin(x)]]
        pos = pos * nmol
        calc = TIP4P()
        self.h2o = Atoms('OH2' * nmol, pos)
        disp = np.random.uniform(-size, size, (nmol, 3))
        final_dis = []
        for i in range(nmol):
            d = disp[i].tolist()
            for i in range(3):
                final_dis.append(d)

        self.h2o.set_positions(pos + np.array(final_dis))
        #vol = ((18.01528 / 6.022140857e23) / (0.9982 / 1e24))**(1 / 3.)
        #self.h2o.set_cell((1.1*r , 1.1*r , 1.1*r ))
        #nmol = int(self.h2o.positions.shape[0] / 3)
        bonds = [(3 * i, 3 * i + 1) for i in range(nmol)]
        for i in range(nmol):
            bonds.append((3 * i, 3 * i + 2))
        bonds_rOH = []
        for bond in bonds:
            bonds_rOH.append((rOH, (bond)))
        angles = [(a, (3 * i + 2, 3 * i, 3 * i + 1)) for i in range(nmol)]
        self.h2o.constraints = FixInternals(bonds=bonds_rOH,
                                            angles=angles,
                                            epsilon=epsilon0)
        calc = TIP4P()
        self.h2o.calc = calc
Exemplo n.º 4
0
def add_tip4p_const(water):
    nmol = int(water.positions.shape[0] / 3)
    a = angleHOH * pi / 180
    bonds = [(3 * i, 3 * i + 1) for i in range(nmol)]
    for i in range(nmol):
        bonds.append((3 * i, 3 * i + 2))
    bonds_rOH = []
    for bond in bonds:
        bonds_rOH.append((rOH, (bond)))
    angles = [(a, (3 * i + 2, 3 * i, 3 * i + 1)) for i in range(nmol)]
    water.constraints = FixInternals(bonds=bonds_rOH,
                                     angles=angles,
                                     epsilon=epsilon0)
    calc = TIP4P()
    water.calc = calc
    return water
Exemplo n.º 5
0
def saddlepoint(min1, min2, name):
    images=[LM[min1]]
    images += [LM[min1].copy() for i in range(5)]
    images += [LM[min2]]
    for image in images:
        image.set_calculator(TIP4P())
        add_tip4p_const(image)
    neb = NEB(images, climb=True, parallel=True) 
    try:
        neb.interpolate()
    except:
        try:
            print("try idpp interpolate")
            neb.interpolate(method="idpp")
        except:
            return
    optimize(neb, name)
Exemplo n.º 6
0
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
Exemplo n.º 7
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
Exemplo n.º 8
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))
Exemplo n.º 9
0
interaction = LJInteractions({('O', 'O'): (epsilon0, sigma0)})

for selection in [[0, 1, 2], [3, 4, 5]]:
    name = ''.join(str(i) for i in selection)
    dimer = Atoms('OH2OH2', [(0, 0, 0), (-r * cos(a / 2), r * sin(a / 2), 0),
                             (-r * cos(a / 2), -r * sin(a / 2), 0), (0, 0, 0),
                             (-r * cos(a), 0, r * sin(a)), (-r, 0, 0)])
    dimer.positions[3:, 0] += 2.8
    dimer.constraints = FixBondLengths([
        ((selection[i] + 3) % 6, (selection[i - 1] + 3) % 6) for i in range(3)
    ])

    dimer.calc = EIQMMM(selection,
                        GPAW(txt=name + '.txt', h=0.16),
                        TIP4P(),
                        interaction,
                        vacuum=4,
                        embedding=Embedding(rc=0.2, rc2=20, width=1),
                        output=name + '.out')
    opt = LBFGS(dimer, trajectory=name + '.traj')
    opt.run(0.02)

    monomer = dimer[selection]
    monomer.center(vacuum=4)
    monomer.calc = GPAW(txt=name + 'M.txt', h=0.16)
    opt = PreconLBFGS(monomer, precon=Exp(A=3), trajectory=name + 'M.traj')
    opt.run(0.02)
    e0 = monomer.get_potential_energy()
    be = dimer.get_potential_energy() - e0
    d = dimer.get_distance(0, 3)
Exemplo n.º 10
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
Exemplo n.º 11
0
from ase.optimize import BFGS

r = rOH
a = angleHOH * np.pi / 180

# From http://dx.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)

inter = LJInteractions({('O', 'O'): (epsilon0, sigma0)})

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(), inter),
        EIQMMM([0, 1, 2], TIP4P(), TIP4P(), inter, vacuum=3.0),
        EIQMMM([3, 4, 5], TIP4P(), TIP4P(), inter, 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())
Exemplo n.º 12
0
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 = []
Exemplo n.º 13
0
"""Test TIP4P forces."""
from math import cos, sin

from ase import Atoms
from ase.calculators.tip4p import TIP4P, rOH, angleHOH

r = rOH
a = angleHOH

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)])

# tip4p sequence OHH, OHH, ..
dimer = dimer[[2]]+dimer[:2]+dimer[[-1]]+dimer[3:5]
dimer.positions[3:, 0] += 2.8

dimer.calc = TIP4P(rc=4.0, width=2.0)  # put O-O distance in the cutoff range
F = dimer.get_forces()
print(F)
dF = dimer.calc.calculate_numerical_forces(dimer) - F
print(dF)
assert abs(dF).max() < 2e-6