def VelocityVerletIntegrator(timestep):
    """
    Construct a velocity Verlet integrator.

    ARGUMENTS

    timestep (numpy.unit.Quantity compatible with femtoseconds) - the integration timestep

    RETURNS

    integrator (simtk.openmm.CustomIntegrator) - a velocity Verlet integrator

    NOTES

    This code is verbatim from Peter Eastman's example.

    """

    integrator = openmm.CustomIntegrator(timestep)

    integrator.addPerDofVariable("x1", 0)

    integrator.addUpdateContextState()
    integrator.addComputePerDof("v", "v+0.5*dt*f/m")
    integrator.addComputePerDof("x", "x+dt*v")
    integrator.addComputePerDof("x1", "x")
    integrator.addConstrainPositions()
    integrator.addComputePerDof("v", "v+0.5*dt*f/m+(x-x1)/dt")
    integrator.addConstrainVelocities()

    return integrator
Esempio n. 2
0
def test_pressure_with_bath_temperature():
    system, positions, topology = readSystem('q-SPC-FW')
    platform = openmm.Platform.getPlatformByName('Reference')
    computer = atomsmm.PressureComputer(system,
                                        topology,
                                        platform,
                                        temperature=300 * unit.kelvin)
    context = openmm.Context(system, openmm.CustomIntegrator(0), platform)
    context.setPositions(positions)
    state = context.getState(getPositions=True,
                             getVelocities=True,
                             getForces=True)
    computer.import_configuration(state)
    atomic_virial = computer.get_atomic_virial()
    assert atomic_virial / atomic_virial.unit == pytest.approx(
        -11661.677650154408)
    atomic_pressure = computer.get_atomic_pressure()
    assert atomic_pressure / atomic_pressure.unit == pytest.approx(
        -58.64837784125407)
    molecular_virial = computer.get_molecular_virial(state.getForces())
    assert molecular_virial / molecular_virial.unit == pytest.approx(
        -5418.629781093525)
    molecular_pressure = computer.get_molecular_pressure(state.getForces())
    assert molecular_pressure / molecular_pressure.unit == pytest.approx(
        -554.9525554206972)
Esempio n. 3
0
    def _compute_forces(self, ufed, dataframe):
        collective_variables = [
            colvar.id for v in ufed.variables for colvar in v.colvars
        ]
        extended_variables = [v.id for v in ufed.variables]
        all_variables = collective_variables + extended_variables

        force = openmm.CustomCVForce(_get_energy_function(ufed.variables))
        for key, value in _get_parameters(ufed.variables).items():
            force.addGlobalParameter(key, value)
        for variable in all_variables:
            force.addGlobalParameter(variable, 0)
        for xv in extended_variables:
            force.addEnergyParameterDerivative(xv)

        system = openmm.System()
        system.addForce(force)
        system.addParticle(0)
        platform = openmm.Platform.getPlatformByName('Reference')
        context = openmm.Context(system, openmm.CustomIntegrator(0), platform)
        context.setPositions([openmm.Vec3(0, 0, 0)])

        n = len(dataframe.index)
        forces = [np.empty(n) for xv in extended_variables]
        for j, row in dataframe.iterrows():
            for variable in all_variables:
                context.setParameter(variable, row[variable])
            state = context.getState(getParameterDerivatives=True)
            derivatives = state.getEnergyParameterDerivatives()
            for i, xv in enumerate(extended_variables):
                forces[i][j] = -derivatives[xv]
        return forces
Esempio n. 4
0
def test_inner_exceptions():
    model = ufedmm.AlanineDipeptideModel()
    nbforce = next(
        filter(lambda f: isinstance(f, openmm.NonbondedForce),
               model.system.getForces()))
    rs = 0.2
    rc = 0.4
    ufedmm.add_inner_nonbonded_force(model.system, rs, rc, 1)
    model.system.getForce(model.system.getNumForces() - 1).setForceGroup(3)
    platform = openmm.Platform.getPlatformByName('Reference')
    context = openmm.Context(model.system, openmm.CustomIntegrator(0),
                             platform)
    context.setPositions(model.positions)
    forces1 = _standardized(
        context.getState(getForces=True, groups={3}).getForces())
    forces2 = [0 * f for f in forces1]
    ONE_4PI_EPS0 = 138.93545764438198
    for index in range(nbforce.getNumExceptions()):
        i, j, chargeprod, sigma, epsilon = map(
            _standardized, nbforce.getExceptionParameters(index))
        rij = _standardized(model.positions[i] - model.positions[j])
        r = np.linalg.norm(rij)
        z = (r - rs) / (rc - rs)
        F = S(z) * (24 * epsilon * (2 * (sigma / r)**12 - (sigma / r)**6) / r +
                    ONE_4PI_EPS0 * chargeprod / r**2) * rij / r
        forces2[i] += F
        forces2[j] -= F
    for f1, f2 in zip(forces1, forces2):
        for i in range(3):
            assert f1[i] == pytest.approx(f2[i])
Esempio n. 5
0
def test_radius_of_gyration():
    model = ufedmm.AlanineDipeptideModel()

    R = model.positions._value
    N = len(R)
    Rmean = sum(R, openmm.Vec3(0, 0, 0)) / N
    RgSqVal = 0.0
    for r in R:
        dr = r - Rmean
        RgSqVal += dr.x**2 + dr.y**2 + dr.z**2
    RgSqVal /= N

    RgSq = cvlib.SquareRadiusOfGyration(range(model.topology._numAtoms))
    RgSq.setForceGroup(1)
    model.system.addForce(RgSq)
    Rg = cvlib.RadiusOfGyration(range(model.topology._numAtoms))
    Rg.setForceGroup(2)
    model.system.addForce(Rg)
    integrator = openmm.CustomIntegrator(0)
    platform = openmm.Platform.getPlatformByName('Reference')
    context = openmm.Context(model.system, integrator, platform)
    context.setPositions(model.positions)
    RgSq = context.getState(getEnergy=True,
                            groups={1}).getPotentialEnergy()._value
    assert RgSq == pytest.approx(RgSqVal)
    Rg = context.getState(getEnergy=True,
                          groups={2}).getPotentialEnergy()._value
    assert Rg * Rg == pytest.approx(RgSqVal)
Esempio n. 6
0
def DummyIntegrator():
    """
    Construct a dummy integrator that does nothing except update call the force updates.

    Returns
    -------
    integrator : simtk.openmm.CustomIntegrator
        A dummy integrator.

    Examples
    --------
    
    Create a dummy integrator.
    
    >>> integrator = DummyIntegrator()

    """

    timestep = 0.0 * units.femtoseconds
    integrator = mm.CustomIntegrator(timestep)
    integrator.addUpdateContextState()
    integrator.addConstrainPositions()
    integrator.addConstrainVelocities()

    return integrator
Esempio n. 7
0
def test_pressure_with_exceptions():
    system, positions, topology = readSystem('emim_BCN4_Jiung2014')
    platform = openmm.Platform.getPlatformByName('Reference')
    computer = atomsmm.PressureComputer(system,
                                        topology,
                                        platform,
                                        temperature=300 * unit.kelvin)
    context = openmm.Context(system, openmm.CustomIntegrator(0), platform)
    context.setPositions(positions)
    state = context.getState(getPositions=True,
                             getVelocities=True,
                             getForces=True)
    computer.import_configuration(state)
    atomic_virial = computer.get_atomic_virial()
    assert atomic_virial / atomic_virial.unit == pytest.approx(
        -22827.477810819175)
    atomic_pressure = computer.get_atomic_pressure()
    assert atomic_pressure / atomic_pressure.unit == pytest.approx(
        -282.7243180164338)
    molecular_virial = computer.get_molecular_virial(state.getForces())
    assert molecular_virial / molecular_virial.unit == pytest.approx(
        -23272.958585794207)
    molecular_pressure = computer.get_molecular_pressure(state.getForces())
    assert molecular_pressure / molecular_pressure.unit == pytest.approx(
        -3283.563262288828)
Esempio n. 8
0
def CustomLangevinIntegrator(temperature=298.0*u.kelvin, collision_rate=91.0/u.picoseconds, timestep=1.0*u.femtoseconds):
    # Compute constants.
    kT = kB * temperature
    gamma = collision_rate


    # Create a new custom integrator.
    integrator = mm.CustomIntegrator(timestep)

    #
    # If dimensions == 2, set up a dummy variable to remove z-axial velocities
    #
    if dimensions == 2:
        integrator.addPerDofVariable("dumv", 1.0)
        integrator.setPerDofVariableByName("dumv", [mm.Vec3(x=1.0, y=1.0, z=0.0)])
    #
    # Integrator initialization.
    #
    integrator.addComputePerDof("sigma", "sqrt(kT/m)")
    integrator.addGlobalVariable("kT", kT) # thermal energy
    integrator.addGlobalVariable("T", temperature) # temperature
    integrator.addGlobalVariable("b", np.exp(-gamma*timestep)) # velocity mixing parameter
    integrator.addPerDofVariable("sigma", 0) 
    integrator.addPerDofVariable("x1", 0) # position before application of constraints

    #
    # Allow context updating here.
    #
    integrator.addUpdateContextState();

    # 
    # Velocity perturbation.
    #
    integrator.addComputePerDof("v", "sqrt(b)*v + sqrt(1-b)*sigma*gaussian")
    integrator.addConstrainVelocities();
    
    #
    # Metropolized symplectic step.
    #
    integrator.addComputePerDof("v", "v + 0.5*dt*f/m")
    if dimensions == 2: # To get a 2D system, make z-velocities zero when moving x
        integrator.addComputePerDof("x", "x + v*dumv*dt")
    else:
        integrator.addComputePerDof("x", "x + v*dt")
    integrator.addComputePerDof("x1", "x")
    integrator.addComputePerDof("v", "v + 0.5*dt*f/m + (x-x1)/dt")

    #
    # Velocity randomization
    #
    integrator.addComputePerDof("v", "sqrt(b)*v + sqrt(1-b)*sigma*gaussian")
    if dimensions == 2: # Remove the resulting z-velocities to get the correct Kinetic Energy
        integrator.addComputePerDof("v", "v*dumv")

    return integrator
Esempio n. 9
0
 def _create_context(self, system, positions):
     system_copy = deepcopy(system)
     for force in system_copy.getForces():
         force.setForceGroup(0)
     force_copy = deepcopy(self.force)
     force_copy.setForceGroup(1)
     system_copy.addForce(force_copy)
     platform = openmm.Platform.getPlatformByName('Reference')
     context = openmm.Context(system_copy, openmm.CustomIntegrator(0), platform)
     context.setPositions(positions)
     return context
Esempio n. 10
0
def potential_energy(system, positions, force_cls, scaling=None):
    syscopy = deepcopy(system)
    for force in syscopy.getForces():
        if isinstance(force, force_cls):
            force.setForceGroup(31)
    integrator = openmm.CustomIntegrator(0)
    platform = openmm.Platform.getPlatformByName('Reference')
    context = openmm.Context(syscopy, integrator, platform)
    context.setPositions(positions)
    if scaling is not None:
        context.setParameter('inOutCoulombScaling', scaling)
    return context.getState(getEnergy=True, groups={31}).getPotentialEnergy()
Esempio n. 11
0
 def getCollectiveVariableValues(self, context):
     if self._context is None:
         integrator = openmm.CustomIntegrator(0)
         platform = context.getPlatform()
         self._context = openmm.Context(self._system, integrator, platform)
     self._context.setState(context.getState(getPositions=True))
     energy = np.empty(self._numForces)
     for index in range(self._numForces):
         state = self._context.getState(getEnergy=True, groups=set([index]))
         energy[index] = state.getPotentialEnergy().value_in_unit(
             unit.kilojoules_per_mole)
     return energy
Esempio n. 12
0
 def __init__(self,
              system,
              topology,
              platform,
              properties=dict(),
              temperature=None):
     self._system = atomsmm.ComputingSystem(system)
     super().__init__(self._system, openmm.CustomIntegrator(0), platform,
                      properties)
     self._mols = _MoleculeTotalizer(self, topology)
     self._kT = None if temperature is None else unit.MOLAR_GAS_CONSTANT_R * temperature
     self._make_obsolete()
def AndersenVelocityVerletIntegrator(timestep, friction, temperature):
    """
    Construct a velocity Verlet integrator.

    ARGUMENTS

    timestep (numpy.unit.Quantity compatible with femtoseconds) - the integration timestep

    RETURNS

    integrator (simtk.openmm.CustomIntegrator) - a velocity Verlet integrator

    NOTES

    This code is verbatim from Peter Eastman's example.

    """

    integrator = openmm.CustomIntegrator(timestep)

    #
    # Integrator setup.
    #
    kT = kB * temperature
    integrator.addGlobalVariable("kT", kT)  # thermal energy
    integrator.addPerDofVariable(
        "sigma_v",
        0)  # velocity distribution stddev for Maxwell-Boltzmann (set later)
    integrator.addPerDofVariable("x1", 0)  # for constraints

    #
    # Update velocities from Maxwell-Boltzmann distribution.
    #
    integrator.addComputePerDof("sigma_v", "sqrt(kT/m)")
    integrator.addComputePerDof("v", "sigma_v*gaussian")

    #
    # Velocity Verlet
    #
    integrator.addUpdateContextState()
    integrator.addComputePerDof("v", "v+0.5*dt*f/m")
    integrator.addComputePerDof("x", "x+dt*v")
    integrator.addComputePerDof("x1", "x")
    integrator.addConstrainPositions()
    integrator.addComputePerDof("v", "v+0.5*dt*f/m+(x-x1)/dt")
    integrator.addConstrainVelocities()

    return integrator
Esempio n. 14
0
    def evaluate(self, system, positions):
        """
        Computes the value of the collective variable for a given set of particle coordinates
        and box vectors. Whether periodic boundary conditions will be used or not depends on
        the corresponding attribute of the Force_ object specified as the collective variable.

        Parameters
        ----------
            system : openmm.System
                The system.
            positions : list of openmm.Vec3
                A list whose length equals the number of particles in the system and which contains
                the coordinates of these particles.

        Returns
        -------
            float

        Example
        -------
            >>> import ufedmm
            >>> from simtk import unit
            >>> model = ufedmm.AlanineDipeptideModel()
            >>> mass = 50*unit.dalton*(unit.nanometer/unit.radians)**2
            >>> K = 1000*unit.kilojoules_per_mole/unit.radians**2
            >>> Ts = 1500*unit.kelvin
            >>> bound = 180*unit.degrees
            >>> phi = ufedmm.CollectiveVariable('phi', model.phi, -bound, bound, mass, K, Ts)
            >>> psi = ufedmm.CollectiveVariable('psi', model.psi, -bound, bound, mass, K, Ts)
            >>> phi.evaluate(model.system, model.positions)
            3.141592653589793
            >>> psi.evaluate(model.system, model.positions)
            3.141592653589793

        """
        new_system = openmm.System()
        new_system.setDefaultPeriodicBoxVectors(
            *system.getDefaultPeriodicBoxVectors())
        for index in range(len(positions)):
            new_system.addParticle(system.getParticleMass(index))
        new_system.addForce(copy.deepcopy(self.openmm_force))
        platform = openmm.Platform.getPlatformByName('Reference')
        context = openmm.Context(new_system, openmm.CustomIntegrator(0),
                                 platform)
        context.setPositions(positions)
        energy = context.getState(getEnergy=True).getPotentialEnergy()
        return energy.value_in_unit(unit.kilojoules_per_mole)
Esempio n. 15
0
    def setPositions(self, positions, extended_positions=None):
        """
        Sets the positions of all particles and extended-space variables in
        this context. If the latter are not provided, then suitable values
        are automatically determined from the particle positions.

        Parameters
        ----------
            positions : list of openmm.Vec3
                The positions of physical particles.

        Keyword Args
        ------------
            extended_positions : list of float or unit.Quantity
                The positions of extended-space particles.

        """
        a, b, _ = self.getState().getPeriodicBoxVectors()
        nvars = len(self.variables)
        particle_positions = _standardized(positions)
        if extended_positions is None:
            extra_positions = [openmm.Vec3(0, b.y*(i + 1)/(nvars + 2), 0) for i in range(nvars)]
            minisystem = openmm.System()
            expression = _get_energy_function(self.variables)
            for i, v in enumerate(self.variables):
                expression += f'; {v.id}={v._get_energy_function(index=i+1)}'
            force = openmm.CustomCompoundBondForce(nvars, expression)
            force.addBond(range(nvars), [])
            for name, value in _get_parameters(self.variables).items():
                force.addGlobalParameter(name, value)
            force.addGlobalParameter('Lx', a.x)
            for v in self.variables:
                minisystem.addParticle(v._particle_mass(a.x))
                for cv in v.colvars:
                    value = cv.evaluate(self.getSystem(), particle_positions + extra_positions)
                    force.addGlobalParameter(cv.id, value)
            minisystem.addForce(force)
            minicontext = openmm.Context(minisystem, openmm.CustomIntegrator(0),
                                         openmm.Platform.getPlatformByName('Reference'))
            minicontext.setPositions(extra_positions)
            openmm.LocalEnergyMinimizer.minimize(minicontext, 1*unit.kilojoules_per_mole, 0)
            ministate = minicontext.getState(getPositions=True)
            extra_positions = ministate.getPositions().value_in_unit(unit.nanometers)
        else:
            extra_positions = [openmm.Vec3(x, b.y*(i + 1)/(nvars + 2), 0)
                               for i, x in enumerate(extended_positions)]
        super().setPositions(particle_positions + extra_positions)
Esempio n. 16
0
def VelocityVerletIntegrator(timestep=1.0 * simtk.unit.femtoseconds):
    """
    Construct a velocity Verlet integrator.

    Parameters
    ----------
    timestep : numpy.unit.Quantity compatible with femtoseconds, default: 1*simtk.unit.femtoseconds
        The integration timestep.

    Returns
    -------
    integrator : simtk.openmm.CustomIntegrator
        A velocity Verlet integrator.

    Notes
    -----
    This integrator is taken verbatim from Peter Eastman's example appearing in the CustomIntegrator header file documentation.

    References
    ----------
    W. C. Swope, H. C. Andersen, P. H. Berens, and K. R. Wilson, J. Chem. Phys. 76, 637 (1982)

    Examples
    --------
    
    Create a velocity Verlet integrator.
    
    >>> timestep = 1.0 * simtk.unit.femtoseconds
    >>> integrator = VelocityVerletIntegrator(timestep)

    """

    integrator = mm.CustomIntegrator(timestep)

    integrator.addPerDofVariable("x1", 0)

    integrator.addUpdateContextState()
    integrator.addComputePerDof("v", "v+0.5*dt*f/m")
    integrator.addComputePerDof("x", "x+dt*v")
    integrator.addComputePerDof("x1", "x")
    integrator.addConstrainPositions()
    integrator.addComputePerDof("v", "v+0.5*dt*f/m+(x-x1)/dt")
    integrator.addConstrainVelocities()

    return integrator
Esempio n. 17
0
def test_AlchemicalRespaSystem_with_softcore():
    system, positions, topology, solute = readSystem('phenol-in-water')
    respa_info = dict(rcutIn=7 * unit.angstroms, rswitchIn=5 * unit.angstroms)
    solvation_system = atomsmm.systems.AlchemicalRespaSystem(
        system,
        *respa_info.values(),
        solute,
        use_softcore=True,
    )
    state = {'lambda': 0.5, 'respa_switch': 1}
    components = atomsmm.splitPotentialEnergy(solvation_system, topology,
                                              positions, **state)
    platform = openmm.Platform.getPlatformByName('Reference')
    context = openmm.Context(system, openmm.CustomIntegrator(0), platform)
    context.setPositions(positions)
    force = solvation_system.get_alchemical_vdw_force(
        [i / 5 for i in range(6)])
    values = force.getCollectiveVariableValues(
        context) * unit.kilojoules_per_mole
    for index in range(force.getNumCollectiveVariables()):
        name = force.getCollectiveVariableName(index)
        components[name] = values[index]
    for item in components.items():
        print(*item)
    potential = {}
    potential['HarmonicBondForce'] = 2621.3223922886677  # kJ/mol
    potential['HarmonicAngleForce'] = 1525.1006876561419  # kJ/mol
    potential['PeriodicTorsionForce'] = 18.767576693568476  # kJ/mol
    potential['Real-Space'] = 80089.51116719692  # kJ/mol
    potential['Reciprocal-Space'] = -107038.52551657759  # kJ/mol
    potential['CustomNonbondedForce'] = 5037.152491649265  # kJ/mol
    potential['CustomBondForce'] = -53.526446723139806  # kJ/mol
    potential['CustomBondForce(1)'] = -53.374675325650806  # kJ/mol
    potential['CustomNonbondedForce(1)'] = -24.140118811594814  # kJ/mol
    potential['CustomNonbondedForce(2)'] = -24.140118811594814  # kJ/mol
    potential['Total'] = -17901.852560765  # kJ/mol
    potential['E0'] = 0.0  # kJ/mol
    potential['E1'] = -10.071581499620784  # kJ/mol
    potential['E2'] = -19.66450283710424  # kJ/mol
    potential['E3'] = -28.284595753200428  # kJ/mol
    potential['E4'] = -35.004158250494505  # kJ/mol
    potential['E5'] = -37.9416812137183  # kJ/mol
    for term, value in components.items():
        assert value / value.unit == pytest.approx(potential[term])
Esempio n. 18
0
    def evaluate(self, positions, boxVectors=None):
        """
        Computes the value of the collective variable for a given set of particle coordinates
        and box vectors. Whether periodic boundary conditions will be used or not depends on
        the corresponding attribute of the Force_ object specified as the collective variable.

        Parameters
        ----------
            positions : list(openmm.Vec3)
                A list whose length equals the number of particles in the system and which contains
                the coordinates of these particles.
            boxVectors : list(openmm.Vec3), optional, default=None
                A list with three vectors which describe the edges of the simulation box.

        Returns
        -------
            unit.Quantity

        Example
        -------
            >>> import afed
            >>> from simtk import unit
            >>> model = afed.AlanineDipeptideModel()
            >>> psi_angle, _ = model.getDihedralAngles()
            >>> psi = afed.DrivenCollectiveVariable('psi', psi_angle, unit.radians, period=360*unit.degrees)
            >>> psi.evaluate(model.getPositions())
            Quantity(value=3.141592653589793, unit=radian)

        """

        system = openmm.System()
        for i in range(len(positions)):
            system.addParticle(0)
        if boxVectors is not None:
            system.setDefaultPeriodicBoxVectors(*boxVectors)
        system.addForce(copy.deepcopy(self._variable))
        platform = openmm.Platform.getPlatformByName('Reference')
        context = openmm.Context(system, openmm.CustomIntegrator(0), platform)
        context.setPositions(positions)
        energy = context.getState(getEnergy=True).getPotentialEnergy()
        return energy.value_in_unit(unit.kilojoules_per_mole) * self._dimension
Esempio n. 19
0
def test_AlchemicalRespaSystem_with_coulomb_scaling():
    system, positions, topology, solute = readSystem('phenol-in-water')
    respa_info = dict(rcutIn=7 * unit.angstroms, rswitchIn=5 * unit.angstroms)
    solvation_system = atomsmm.systems.AlchemicalRespaSystem(
        system,
        *respa_info.values(),
        solute,
        coupling_function='lambda^4*(5-4*lambda)',
        coulomb_scaling=True,
        lambda_coul=0.5,
        # middle_scale=True,
    )
    state = {'lambda': 0.5, 'respa_switch': 1}
    components = atomsmm.splitPotentialEnergy(solvation_system, topology,
                                              positions, **state)
    integrator = openmm.CustomIntegrator(0)
    platform = openmm.Platform.getPlatformByName('Reference')
    simulation = openmm.app.Simulation(topology, solvation_system, integrator,
                                       platform)
    simulation.context.setPositions(positions)
    force = solvation_system.get_alchemical_coul_force()
    Ecoul = force.getCollectiveVariableValues(simulation.context)
    components['Ecoul'] = Ecoul[0] * unit.kilojoule_per_mole
    for item in components.items():
        print(*item)
    potential = {}
    potential['HarmonicBondForce'] = 2621.3223922886677  # kJ/mol
    potential['HarmonicAngleForce'] = 1525.1006876561419  # kJ/mol
    potential['PeriodicTorsionForce'] = 18.767576693568476  # kJ/mol
    potential['Real-Space'] = 80078.91697014398  # kJ/mol
    potential['Reciprocal-Space'] = -107074.49398119976  # kJ/mol
    potential['CustomNonbondedForce'] = 5037.152491649265  # kJ/mol
    potential['CustomBondForce'] = -53.526446723139806  # kJ/mol
    potential['CustomBondForce(1)'] = -53.374675325650806  # kJ/mol
    potential['CustomNonbondedForce(1)'] = -23.447733015522058  # kJ/mol
    potential['CustomCVForce'] = -7.114065227572182  # kJ/mol
    potential['CustomCVForce(1)'] = -6.301336948673654  # kJ/mol
    potential['Total'] = -17936.998120008684  # kJ/mol
    potential['Ecoul'] = -93.14060537915793  # kJ/mol
    for term, value in components.items():
        assert value / value.unit == pytest.approx(potential[term])
Esempio n. 20
0
def perform_test(sigma, epsilon, charge0, charge1, rs, rc):
    nonbonded = openmm.NonbondedForce()
    nonbonded.addParticle(charge0, sigma, epsilon)
    nonbonded.addParticle(charge1, sigma, epsilon)
    nonbonded.setNonbondedMethod(nonbonded.CutoffNonPeriodic)
    platform = openmm.Platform.getPlatformByName('Reference')
    system = openmm.System()
    system.addParticle(1)
    system.addParticle(1)
    system.addForce(nonbonded)
    ufedmm.add_inner_nonbonded_force(system, rs, rc, 1)
    context = openmm.Context(system, openmm.CustomIntegrator(0), platform)
    ONE_4PI_EPS0 = 138.93545764438198
    for r in np.linspace(sigma, rc, 101):
        context.setPositions([[0, 0, 0], [r, 0, 0]])
        state = context.getState(getForces=True, groups={1})
        force = state.getForces()[1].x
        F = 24 * epsilon * (
            2 * (sigma / r)**12 -
            (sigma / r)**6) / r + ONE_4PI_EPS0 * charge0 * charge1 / r**2
        assert force == pytest.approx(F * S((r - rs) / (rc - rs)))
Esempio n. 21
0
def test_pressure_with_kinetic_temperature():
    system, positions, topology = readSystem('q-SPC-FW')
    platform = openmm.Platform.getPlatformByName('Reference')
    computer = atomsmm.PressureComputer(system, topology, platform)
    context = openmm.Context(system, openmm.CustomIntegrator(0), platform)
    context.setPositions(positions)
    context.setVelocitiesToTemperature(300 * unit.kelvin, 1234)
    state = context.getState(getPositions=True,
                             getVelocities=True,
                             getForces=True)
    computer.import_configuration(state)
    atomic_virial = computer.get_atomic_virial()
    assert atomic_virial / atomic_virial.unit == pytest.approx(
        -11661.677650154408)
    atomic_pressure = computer.get_atomic_pressure()
    assert atomic_pressure / atomic_pressure.unit == pytest.approx(
        -86.95921953101447)
    molecular_virial = computer.get_molecular_virial(state.getForces())
    assert molecular_virial / molecular_virial.unit == pytest.approx(
        -5418.629781093525)
    molecular_pressure = computer.get_molecular_pressure(state.getForces())
    assert molecular_pressure / molecular_pressure.unit == pytest.approx(
        -539.0081647715243)
Esempio n. 22
0
    def __init__(self, variables, variances, centers, weights, platform,
                 properties):
        num_particles = len(variables) // 3 + 1
        coordinates = [
            f'{x}{i+1}' for i in range(num_particles) for x in 'xyz'
        ]
        exponents = []
        for v, variance, x in zip(variables, variances, coordinates):
            if v.periodic:  # von Mises
                factor = 2 * np.pi / v._range
                exponents.append(
                    f'{1.0/(variance*factor**2)}*(cos({factor}*({v.id}-{x}))-1)'
                )
            else:  # Gauss
                exponents.append(f'(-{0.5/variance})*({v.id}-{x})^2')
        expression = f'weight*exp({"+".join(exponents)})'

        force = openmm.CustomCompoundBondForce(num_particles, expression)
        force.addPerBondParameter('weight')
        for v in variables:
            force.addGlobalParameter(v.id, 0)
            force.addEnergyParameterDerivative(v.id)

        system = openmm.System()
        positions = []
        for i, (center, weight) in enumerate(zip(centers, weights)):
            for position in np.resize(center, (num_particles, 3)):
                system.addParticle(1.0)
                positions.append(openmm.Vec3(*position))
            force.addBond(range(i * num_particles, (i + 1) * num_particles),
                          [weight])

        system.addForce(force)
        integrator = openmm.CustomIntegrator(0)
        super().__init__(system, integrator, platform, properties)
        self.parameters = [v.id for v in variables]
        self.setPositions(positions)
Esempio n. 23
0
def GradientDescentMinimizationIntegrator(initial_step_size=0.01 *
                                          units.angstroms):
    """
    Construct a simple gradient descent minimization integrator.

    Parameters
    ----------
    initial_step_size : numpy.unit.Quantity compatible with nanometers, default: 0.01*simtk.unit.angstroms
        The norm of the initial step size guess.

    Returns
    -------
    integrator : simtk.openmm.CustomIntegrator
        A velocity Verlet integrator.

    Notes
    -----
    An adaptive step size is used.

    References
    ----------

    Examples
    --------
    
    Create a gradient descent minimization integrator.
    
    >>> integrator = GradientDescentMinimizationIntegrator()

    """

    timestep = 1.0 * units.femtoseconds
    integrator = mm.CustomIntegrator(timestep)

    integrator.addGlobalVariable("step_size",
                                 initial_step_size / units.nanometers)
    integrator.addGlobalVariable("energy_old", 0)
    integrator.addGlobalVariable("energy_new", 0)
    integrator.addGlobalVariable("delta_energy", 0)
    integrator.addGlobalVariable("accept", 0)
    integrator.addGlobalVariable("fnorm2", 0)
    integrator.addPerDofVariable("x_old", 0)

    # Update context state.
    integrator.addUpdateContextState()

    # Constrain positions.
    integrator.addConstrainPositions()

    # Store old energy and positions.
    integrator.addComputeGlobal("energy_old", "energy")
    integrator.addComputePerDof("x_old", "x")

    # Compute sum of squared norm.
    integrator.addComputeSum("fnorm2", "f^2")

    # Take step.
    integrator.addComputePerDof("x",
                                "x+step_size*f/sqrt(fnorm2 + delta(fnorm2))")
    integrator.addConstrainPositions()

    # Ensure we only keep steps that go downhill in energy.
    integrator.addComputeGlobal("energy_new", "energy")
    integrator.addComputeGlobal("delta_energy", "energy_new-energy_old")
    # Accept also checks for NaN
    integrator.addComputeGlobal(
        "accept", "step(-delta_energy) * delta(energy - energy_new)")

    integrator.addComputePerDof("x", "accept*x + (1-accept)*x_old")

    # Update step size.
    integrator.addComputeGlobal("step_size",
                                "step_size * (2.0*accept + 0.5*(1-accept))")

    return integrator
Esempio n. 24
0
def VVVRIntegrator(temperature=298.0 * simtk.unit.kelvin,
                   collision_rate=91.0 / simtk.unit.picoseconds,
                   timestep=1.0 * simtk.unit.femtoseconds):
    """
    Create a velocity verlet with velocity randomization (VVVR) integrator.
    
    Parameters
    ----------
    temperature : numpy.unit.Quantity compatible with kelvin, default: 298.0*simtk.unit.kelvin
        The temperature.
    collision_rate : numpy.unit.Quantity compatible with 1/picoseconds, default: 91.0/simtk.unit.picoseconds
        The collision rate.
    timestep : numpy.unit.Quantity compatible with femtoseconds, default: 1.0*simtk.unit.femtoseconds
        The integration timestep.

    Returns
    -------
    integrator : simtk.openmm.CustomIntegrator
        VVVR integrator.

    Notes
    -----
    This integrator is equivalent to a Langevin integrator in the velocity Verlet discretization with a
    timestep correction to ensure that the field-free diffusion constant is timestep invariant.

    The global 'pseudowork' keeps track of the pseudowork accumulated during integration, and can be
    used to correct the sampled statistics or in a Metropolization scheme.
    
    TODO
    ----
    Move initialization of 'sigma' to setting the per-particle variables.
    We can ditch pseudowork and instead use total energy difference - heat.
    
    References
    ----------
    David A. Sivak, John D. Chodera, and Gavin E. Crooks. 
    Time step rescaling recovers continuous-time dynamical properties for discrete-time Langevin integration of nonequilibrium systems 
    http://arxiv.org/abs/1301.3800

    Examples
    --------

    Create a VVVR integrator.

    >>> temperature = 298.0 * simtk.unit.kelvin
    >>> collision_rate = 91.0 / simtk.unit.picoseconds
    >>> timestep = 1.0 * simtk.unit.femtoseconds
    >>> integrator = VVVRIntegrator(temperature, collision_rate, timestep)

    """

    # Compute constants.
    kT = kB * temperature
    gamma = collision_rate

    # Create a new custom integrator.
    integrator = mm.CustomIntegrator(timestep)

    #
    # Integrator initialization.
    #
    integrator.addGlobalVariable("kT", kT)  # thermal energy
    integrator.addGlobalVariable("b", numpy.exp(
        -gamma * timestep))  # velocity mixing parameter
    integrator.addPerDofVariable("sigma", 0)
    integrator.addPerDofVariable(
        "x1", 0)  # position before application of constraints

    #
    # Allow context updating here.
    #
    integrator.addUpdateContextState()

    #
    # Pre-computation.
    # This only needs to be done once, but it needs to be done for each degree of freedom.
    # Could move this to initialization?
    #
    integrator.addComputePerDof("sigma", "sqrt(kT/m)")

    #
    # Velocity perturbation.
    #
    integrator.addComputePerDof("v", "sqrt(b)*v + sqrt(1-b)*sigma*gaussian")
    integrator.addConstrainVelocities()

    #
    # Metropolized symplectic step.
    #
    integrator.addComputePerDof("v", "v + 0.5*dt*f/m")
    integrator.addComputePerDof("x", "x + v*dt")
    integrator.addComputePerDof("x1", "x")
    integrator.addConstrainPositions()
    integrator.addComputePerDof("v", "v + 0.5*dt*f/m + (x-x1)/dt")
    integrator.addConstrainVelocities()

    #
    # Velocity randomization
    #
    integrator.addComputePerDof("v", "sqrt(b)*v + sqrt(1-b)*sigma*gaussian")
    integrator.addConstrainVelocities()

    return integrator
Esempio n. 25
0
def GHMCIntegrator(temperature=298.0 * simtk.unit.kelvin,
                   collision_rate=91.0 / simtk.unit.picoseconds,
                   timestep=1.0 * simtk.unit.femtoseconds):
    """
    Create a generalized hybrid Monte Carlo (GHMC) integrator.
    
    Parameters
    ----------
    temperature : numpy.unit.Quantity compatible with kelvin, default: 298*simtk.unit.kelvin
        The temperature.
    collision_rate : numpy.unit.Quantity compatible with 1/picoseconds, default: 91.0/simtk.unit.picoseconds
        The collision rate.
    timestep : numpy.unit.Quantity compatible with femtoseconds, default: 1.0*simtk.unit.femtoseconds
        The integration timestep.
    
    Returns
    -------
    integrator : simtk.openmm.CustomIntegrator
        A GHMC integrator.

    Notes
    -----
    This integrator is equivalent to a Langevin integrator in the velocity Verlet discretization with a
    Metrpolization step to ensure sampling from the appropriate distribution.

    Additional global variables 'ntrials' and  'naccept' keep track of how many trials have been attempted and
    accepted, respectively.

    TODO
    ----
    Move initialization of 'sigma' to setting the per-particle variables.

    Examples
    --------

    Create a GHMC integrator.

    >>> temperature = 298.0 * simtk.unit.kelvin
    >>> collision_rate = 91.0 / simtk.unit.picoseconds
    >>> timestep = 1.0 * simtk.unit.femtoseconds
    >>> integrator = GHMCIntegrator(temperature, collision_rate, timestep)

    References
    ----------
    Lelievre T, Stoltz G, and Rousset M. Free Energy Computations: A Mathematical Perspective
    http://www.amazon.com/Free-Energy-Computations-Mathematical-Perspective/dp/1848162472

    """

    # Initialize constants.
    kT = kB * temperature
    gamma = collision_rate

    # Create a new custom integrator.
    integrator = mm.CustomIntegrator(timestep)

    #
    # Integrator initialization.
    #
    b = numpy.exp(-gamma * timestep)
    integrator.addGlobalVariable("kT", kT)  # thermal energy
    integrator.addGlobalVariable("b", b)  # velocity mixing parameter
    integrator.addPerDofVariable("sigma", 0)
    integrator.addGlobalVariable("ke", 0)  # kinetic energy
    integrator.addPerDofVariable("vold", 0)  # old velocities
    integrator.addPerDofVariable("xold", 0)  # old positions
    integrator.addGlobalVariable("Eold", 0)  # old energy
    integrator.addGlobalVariable("Enew", 0)  # new energy
    integrator.addGlobalVariable("accept", 0)  # accept or reject
    integrator.addGlobalVariable("naccept", 0)  # number accepted
    integrator.addGlobalVariable("ntrials",
                                 0)  # number of Metropolization trials
    integrator.addPerDofVariable(
        "x1", 0)  # position before application of constraints
    integrator.addGlobalVariable("alpha", numpy.sqrt(b))
    integrator.addGlobalVariable("beta", numpy.sqrt(1 - b))
    integrator.addPerDofVariable("zeta", 0)

    #
    # Pre-computation.
    # This only needs to be done once, but it needs to be done for each degree of freedom.
    # Could move this to initialization?
    #
    integrator.addComputePerDof("sigma", "sqrt(kT/m)")

    #
    # Allow context updating here.
    #
    integrator.addUpdateContextState()

    #
    # Constrain positions.
    #
    integrator.addConstrainPositions()

    #
    # Velocity perturbation.
    #
    integrator.addComputePerDof("v", "sqrt(b)*v + sqrt(1-b)*sigma*gaussian")
    #integrator.addComputePerDof("v", "sqrt(b)*v")
    #integrator.addComputePerDof("v", "v + sqrt(1-b)*sigma*gaussian")
    #integrator.addComputePerDof("v", "alpha*v + beta*sigma*gaussian")
    #integrator.addComputePerDof("v", "alpha*v")
    #integrator.addComputePerDof("v", "v + beta*sigma*gaussian")
    #integrator.addComputePerDof("zeta", "gaussian")
    #integrator.addComputePerDof("v", "alpha*v + beta*sigma*zeta")
    integrator.addConstrainVelocities()

    #
    # Metropolized symplectic step.
    #
    integrator.addComputeSum("ke", "0.5*m*v*v")
    integrator.addComputeGlobal("Eold", "ke + energy")
    integrator.addComputePerDof("xold", "x")
    integrator.addComputePerDof("vold", "v")
    integrator.addComputePerDof("v", "v + 0.5*dt*f/m")
    integrator.addComputePerDof("x", "x + v*dt")
    integrator.addComputePerDof("x1", "x")
    integrator.addConstrainPositions()
    integrator.addComputePerDof("v", "v + 0.5*dt*f/m + (x-x1)/dt")
    integrator.addConstrainVelocities()
    integrator.addComputeSum("ke", "0.5*m*v*v")
    integrator.addComputeGlobal("Enew", "ke + energy")
    integrator.addComputeGlobal("accept",
                                "step(exp(-(Enew-Eold)/kT) - uniform)")
    integrator.addComputePerDof("x", "x*accept + xold*(1-accept)")
    integrator.addComputePerDof("v", "v*accept - vold*(1-accept)")

    #
    # Velocity randomization
    #
    integrator.addComputePerDof("v", "sqrt(b)*v + sqrt(1-b)*sigma*gaussian")
    #integrator.addComputePerDof("zeta", "gaussian")
    #integrator.addComputePerDof("v", "alpha*v + beta*sigma*zeta")
    integrator.addConstrainVelocities()

    #
    # Accumulate statistics.
    #
    integrator.addComputeGlobal("naccept", "naccept + accept")
    integrator.addComputeGlobal("ntrials", "ntrials + 1")

    return integrator
Esempio n. 26
0
def HMCIntegrator(temperature=298.0 * simtk.unit.kelvin,
                  nsteps=10,
                  timestep=1 * simtk.unit.femtoseconds):
    """
    Create a hybrid Monte Carlo (HMC) integrator.

    Parameters
    ----------
    temperature : numpy.unit.Quantity compatible with kelvin, default: 298*simtk.unit.kelvin
        The temperature.
    nsteps : int, default: 10
        The number of velocity Verlet steps to take per HMC trial.
    timestep : numpy.unit.Quantity compatible with femtoseconds, default: 1*simtk.unit.femtoseconds
        The integration timestep.

    Returns
    -------
    integrator : simtk.openmm.CustomIntegrator
        A hybrid Monte Carlo integrator.

    Warning
    -------
    Because 'nsteps' sets the number of steps taken, a call to integrator.step(1) actually takes 'nsteps' steps.

    Notes
    -----    
    The velocity is drawn from a Maxwell-Boltzmann distribution, then 'nsteps' steps are taken,
    and the new configuration is either accepted or rejected.

    Additional global variables 'ntrials' and  'naccept' keep track of how many trials have been attempted and
    accepted, respectively.

    TODO
    ----
    Currently, the simulation timestep is only advanced by 'timestep' each step, rather than timestep*nsteps.  Fix this.

    Examples
    --------
    
    Create an HMC integrator.
    
    >>> timestep = 1.0 * simtk.unit.femtoseconds # fictitious timestep
    >>> temperature = 298.0 * simtk.unit.kelvin
    >>> nsteps = 10 # number of steps per call
    >>> integrator = HMCIntegrator(temperature, nsteps, timestep)

    """

    # Create a new custom integrator.
    integrator = mm.CustomIntegrator(timestep)

    # Compute the thermal energy.
    kT = kB * temperature

    #
    # Integrator initialization.
    #
    integrator.addGlobalVariable("naccept", 0)  # number accepted
    integrator.addGlobalVariable("ntrials",
                                 0)  # number of Metropolization trials

    integrator.addGlobalVariable("kT", kT)  # thermal energy
    integrator.addPerDofVariable("sigma", 0)
    integrator.addGlobalVariable("ke", 0)  # kinetic energy
    integrator.addPerDofVariable("xold", 0)  # old positions
    integrator.addGlobalVariable("Eold", 0)  # old energy
    integrator.addGlobalVariable("Enew", 0)  # new energy
    integrator.addGlobalVariable("accept", 0)  # accept or reject
    integrator.addPerDofVariable("x1", 0)  # for constraints

    #
    # Pre-computation.
    # This only needs to be done once, but it needs to be done for each degree of freedom.
    # Could move this to initialization?
    #
    integrator.addComputePerDof("sigma", "sqrt(kT/m)")

    #
    # Allow Context updating here, outside of inner loop only.
    #
    integrator.addUpdateContextState()

    #
    # Draw new velocity.
    #
    integrator.addComputePerDof("v", "sigma*gaussian")
    integrator.addConstrainVelocities()

    #
    # Store old position and energy.
    #
    integrator.addComputeSum("ke", "0.5*m*v*v")
    integrator.addComputeGlobal("Eold", "ke + energy")
    integrator.addComputePerDof("xold", "x")

    #
    # Inner symplectic steps using velocity Verlet.
    #
    for step in range(nsteps):
        integrator.addComputePerDof("v", "v+0.5*dt*f/m")
        integrator.addComputePerDof("x", "x+dt*v")
        integrator.addComputePerDof("x1", "x")
        integrator.addConstrainPositions()
        integrator.addComputePerDof("v", "v+0.5*dt*f/m+(x-x1)/dt")
        integrator.addConstrainVelocities()

    #
    # Accept/reject step.
    #
    integrator.addComputeSum("ke", "0.5*m*v*v")
    integrator.addComputeGlobal("Enew", "ke + energy")
    integrator.addComputeGlobal("accept",
                                "step(exp(-(Enew-Eold)/kT) - uniform)")
    integrator.addComputePerDof("x", "x*accept + xold*(1-accept)")

    #
    # Accumulate statistics.
    #
    integrator.addComputeGlobal("naccept", "naccept + accept")
    integrator.addComputeGlobal("ntrials", "ntrials + 1")

    return integrator
Esempio n. 27
0
def MetropolisMonteCarloIntegrator(temperature=298.0 * simtk.unit.kelvin,
                                   sigma=0.1 * simtk.unit.angstroms,
                                   timestep=1 * simtk.unit.femtoseconds):
    """
    Create a simple Metropolis Monte Carlo integrator that uses Gaussian displacement trials.

    Parameters
    ----------
    temperature : numpy.unit.Quantity compatible with kelvin, default: 298*simtk.unit.kelvin
        The temperature.
    sigma : numpy.unit.Quantity compatible with nanometers, default: 0.1*simtk.unit.angstroms
        The displacement standard deviation for each degree of freedom.
    timestep : numpy.unit.Quantity compatible with femtoseconds, default: 1.0*simtk.unit.femtoseconds
        The integration timestep, which is purely fictitious---it is just used to advance the simulation clock.

    Returns
    -------
    integrator : simtk.openmm.CustomIntegrator
        A Metropolis Monte Carlo integrator.

    Warning
    -------
    This integrator does not respect constraints.

    Notes
    -----
    The timestep is purely fictitious, and just used to advance the simulation clock.
    Velocities are drawn from a Maxwell-Boltzmann distribution each timestep to generate correct (x,v) statistics.
    Additional global variables 'ntrials' and  'naccept' keep track of how many trials have been attempted and accepted, respectively.
    
    Examples
    --------

    Create a Metropolis Monte Carlo integrator with specified random displacement standard deviation.
    
    >>> timestep = 1.0 * simtk.unit.femtoseconds # fictitious timestep
    >>> temperature = 298.0 * simtk.unit.kelvin
    >>> sigma = 1.0 * simtk.unit.angstroms
    >>> integrator = MetropolisMonteCarloIntegrator(temperature, sigma, timestep)

    """

    # Create a new Custom integrator.
    integrator = mm.CustomIntegrator(timestep)

    # Compute the thermal energy.
    kT = kB * temperature

    #
    # Integrator initialization.
    #
    integrator.addGlobalVariable("naccept", 0)  # number accepted
    integrator.addGlobalVariable("ntrials",
                                 0)  # number of Metropolization trials

    integrator.addGlobalVariable("kT", kT)  # thermal energy
    integrator.addPerDofVariable("sigma_x", sigma)  # perturbation size
    integrator.addPerDofVariable(
        "sigma_v",
        0)  # velocity distribution stddev for Maxwell-Boltzmann (set later)
    integrator.addPerDofVariable("xold", 0)  # old positions
    integrator.addGlobalVariable("Eold", 0)  # old energy
    integrator.addGlobalVariable("Enew", 0)  # new energy
    integrator.addGlobalVariable("accept", 0)  # accept or reject

    #
    # Context state update.
    #
    integrator.addUpdateContextState()

    #
    # Update velocities from Maxwell-Boltzmann distribution.
    #
    integrator.addComputePerDof("sigma_v", "sqrt(kT/m)")
    integrator.addComputePerDof("v", "sigma_v*gaussian")
    integrator.addConstrainVelocities()

    #
    # propagation steps
    #
    # Store old positions and energy.
    integrator.addComputePerDof("xold", "x")
    integrator.addComputeGlobal("Eold", "energy")
    # Gaussian particle displacements.
    integrator.addComputePerDof("x", "x + sigma_x*gaussian")
    # Accept or reject with Metropolis criteria.
    integrator.addComputeGlobal("accept",
                                "step(exp(-(energy-Eold)/kT) - uniform)")
    integrator.addComputePerDof("x", "(1-accept)*xold + x*accept")
    # Accumulate acceptance statistics.
    integrator.addComputeGlobal("naccept", "naccept + accept")
    integrator.addComputeGlobal("ntrials", "ntrials + 1")

    return integrator
Esempio n. 28
0
def AndersenVelocityVerletIntegrator(temperature=298 * simtk.unit.kelvin,
                                     collision_rate=91.0 /
                                     simtk.unit.picoseconds,
                                     timestep=1.0 * simtk.unit.femtoseconds):
    """
    Construct a velocity Verlet integrator with Andersen thermostat, implemented as per-particle collisions (rather than massive collisions).

    Parameters
    ----------
    temperature : numpy.unit.Quantity compatible with kelvin, default: 298*simtk.unit.kelvin
        The temperature of the fictitious bath.
    collision_rate : numpy.unit.Quantity compatible with 1/picoseconds, default: 91/simtk.unit.picoseconds
        The collision rate with fictitious bath particles.
    timestep : numpy.unit.Quantity compatible with femtoseconds, default: 1*simtk.unit.femtoseconds
        The integration timestep.

    Returns
    -------
    integrator : simtk.openmm.CustomIntegrator
        A velocity Verlet integrator with periodic Andersen thermostat.

    References
    ----------
    Hans C. Andersen "Molecular dynamics simulations at constant pressure and/or temperature", Journal of Chemical Physics 72, 2384-2393 (1980)
    http://dx.doi.org/10.1063/1.439486

    Examples
    --------
    
    Create a velocity Verlet integrator with Andersen thermostat.
    
    >>> timestep = 1.0 * simtk.unit.femtoseconds
    >>> collision_rate = 91.0 / simtk.unit.picoseconds
    >>> temperature = 298.0 * simtk.unit.kelvin
    >>> integrator = AndersenVelocityVerletIntegrator(temperature, collision_rate, timestep)

    Notes
    ------
    The velocity Verlet integrator is taken verbatim from Peter Eastman's example in the CustomIntegrator header file documentation.
    The efficiency could be improved by avoiding recomputation of sigma_v every timestep.

    """

    integrator = mm.CustomIntegrator(timestep)

    #
    # Integrator initialization.
    #
    kT = kB * temperature
    integrator.addGlobalVariable("kT", kT)  # thermal energy
    integrator.addGlobalVariable(
        "p_collision", timestep *
        collision_rate)  # per-particle collision probability per timestep
    integrator.addPerDofVariable(
        "sigma_v", 0
    )  # velocity distribution stddev for Maxwell-Boltzmann (computed later)
    integrator.addPerDofVariable(
        "collision",
        0)  # 1 if collision has occured this timestep, 0 otherwise
    integrator.addPerDofVariable("x1", 0)  # for constraints

    #
    # Update velocities from Maxwell-Boltzmann distribution for particles that collide.
    #
    integrator.addComputePerDof("sigma_v", "sqrt(kT/m)")
    integrator.addComputePerDof(
        "collision", "step(p_collision-uniform)"
    )  # if collision has occured this timestep, 0 otherwise
    integrator.addComputePerDof(
        "v", "(1-collision)*v + collision*sigma_v*gaussian"
    )  # randomize velocities of particles that have collided

    #
    # Velocity Verlet step
    #
    integrator.addUpdateContextState()
    integrator.addComputePerDof("v", "v+0.5*dt*f/m")
    integrator.addComputePerDof("x", "x+dt*v")
    integrator.addComputePerDof("x1", "x")
    integrator.addConstrainPositions()
    integrator.addComputePerDof("v", "v+0.5*dt*f/m+(x-x1)/dt")
    integrator.addConstrainVelocities()

    return integrator
Esempio n. 29
0
from simtk import unit as u
import simtk.openmm as mm
import openmmtools

testsystem = openmmtools.testsystems.WaterBox()
system, positions = testsystem.system, testsystem.positions

integrator = mm.CustomIntegrator(1.75 * u.femtoseconds)

temperature = 300 * u.kelvin

integrator.addPerDofVariable("x1", 0)
integrator.addPerDofVariable("x2", 0)
integrator.addPerDofVariable("x3", 0)
integrator.addGlobalVariable("e1", 0)
integrator.addGlobalVariable("e2", 0)
integrator.addGlobalVariable("e3", 0)
integrator.addGlobalVariable("e4", 0)
integrator.addGlobalVariable("e5", 0)
integrator.addGlobalVariable("one", 1.0)
integrator.addGlobalVariable("e2m", 0.0)

integrator.addUpdateContextState()
integrator.addComputePerDof("v", "v+0.5*dt*f/m")
integrator.addComputePerDof("x", "x+dt*v")
integrator.addComputePerDof("x1", "x")
integrator.addConstrainPositions()
integrator.addComputePerDof("v", "v+0.5*dt*f/m+(x-x1)/dt")
integrator.addConstrainVelocities()

integrator.addComputePerDof("x2", "x")
Esempio n. 30
0
def PrecisionTestIntegrator(dx):
    integrator = openmm.CustomIntegrator(1.0)
    integrator.addPerDofVariable('dx', dx)
    integrator.addComputePerDof('x', 'x + dx')
    return integrator