예제 #1
0
def test_external_protocol_work_accumulation():
    """When `measure_protocol_work==True`, assert that global `protocol_work` is initialized to zero and
    reaches a zero value after integrating a few dozen steps without perturbation.

    By default (`measure_protocol_work=False`), assert that there is no global name for `protocol_work`."""

    testsystem = testsystems.HarmonicOscillator()
    system, topology = testsystem.system, testsystem.topology
    temperature = 298.0 * unit.kelvin
    integrator = integrators.ExternalPerturbationLangevinIntegrator(splitting="O V R V O", temperature=temperature)
    context = openmm.Context(system, integrator)
    context.setPositions(testsystem.positions)
    context.setVelocitiesToTemperature(temperature)
    # Check that initial step accumulates no protocol work
    assert(integrator.get_protocol_work(dimensionless=True) == 0), "Protocol work should be 0 initially"
    assert(integrator.get_protocol_work() / unit.kilojoules_per_mole == 0), "Protocol work should have units of energy"
    integrator.step(1)
    assert(integrator.get_protocol_work(dimensionless=True) == 0), "There should be no protocol work."
    # Check that a single step accumulates protocol work
    pe_1 = context.getState(getEnergy=True).getPotentialEnergy()
    perturbed_K=99.0 * unit.kilocalories_per_mole / unit.angstroms**2
    context.setParameter('testsystems_HarmonicOscillator_K', perturbed_K)
    pe_2 = context.getState(getEnergy=True).getPotentialEnergy()
    integrator.step(1)
    assert (integrator.get_protocol_work(dimensionless=True) != 0), "There should be protocol work after perturbing."
    assert (integrator.protocol_work == (pe_2 - pe_1)), "The potential energy difference should be equal to protocol work."
    del context, integrator

    integrator = integrators.VVVRIntegrator(temperature)
    context = openmm.Context(system, integrator)
    context.setPositions(testsystem.positions)
    context.setVelocitiesToTemperature(temperature)
    integrator.step(25)
    del context, integrator
예제 #2
0
    def create_system(self,
                      testsystem,
                      parameter_name,
                      parameter_initial,
                      temperature=298.0 * unit.kelvin,
                      platform_name='Reference'):
        """
        Create an example system to be used by other tests
        """
        system, topology = testsystem.system, testsystem.topology
        integrator = integrators.ExternalPerturbationLangevinIntegrator(
            splitting="O V R V O", temperature=temperature)

        # Create the context
        platform = openmm.Platform.getPlatformByName(platform_name)
        if platform_name in ['CPU', 'CUDA']:
            try:
                platform.setPropertyDefaultValue('DeterministicForces', 'true')
            except Exception as e:
                mm_min_version = '7.2.0'
                if platform_name == 'CPU' and openmm.version.short_version < mm_min_version:
                    print(
                        "Deterministic CPU forces not present in versions of OpenMM prior to {}"
                        .format(mm_min_version))
                else:
                    raise e
        context = openmm.Context(system, integrator, platform)
        context.setParameter(parameter_name, parameter_initial)
        context.setPositions(testsystem.positions)
        context.setVelocitiesToTemperature(temperature)

        return context, integrator
예제 #3
0
    def create_system(self,
                      testsystem,
                      parameter_name,
                      parameter_initial,
                      temperature=298.0 * unit.kelvin,
                      platform_name='Reference'):
        """
        Create an example system to be used by other tests
        """
        system, topology = testsystem.system, testsystem.topology
        integrator = integrators.ExternalPerturbationLangevinIntegrator(
            splitting="O V R V O", temperature=temperature)

        # Create the context
        platform = openmm.Platform.getPlatformByName(platform_name)
        if platform_name in ['CPU', 'CUDA']:
            platform.setPropertyDefaultValue('DeterministicForces', 'true')
        context = openmm.Context(system, integrator, platform)
        context.setParameter(parameter_name, parameter_initial)
        context.setPositions(testsystem.positions)
        context.setVelocitiesToTemperature(temperature)

        return context, integrator
예제 #4
0
    def __init__(self,
                 alchemical_functions: dict,
                 nsteps_neq: int,
                 timestep: unit.Quantity,
                 temperature: unit.Quantity,
                 work_configuration_save_interval: int = 1,
                 splitting: str = "V R O R V",
                 **kwargs):

        super(ExternalNonequilibriumSwitchingMove,
              self).__init__(n_steps=nsteps_neq, **kwargs)

        self._integrator = integrators.ExternalPerturbationLangevinIntegrator(
            timestep=timestep, temperature=temperature, splitting=splitting)
        self._work_configuration_save_interval = work_configuration_save_interval
        self._alchemical_functions = alchemical_functions
        self._nsteps_neq = nsteps_neq
        if nsteps_neq % work_configuration_save_interval != 0:
            raise ValueError(
                "Please use a saving interval that is a divisor of the total number of steps"
            )
        #self._number_of_step_moves = self._nsteps_neq // self._work_configuration_save_interval
        self._cumulative_work = np.zeros([self._nsteps_neq + 1])
        self._current_protocol_work = 0.0
예제 #5
0
                    nonbondedMethod=app.PME,
                    cutoff=10 * unit.angstrom,
                    ewaldErrorTolerance=1E-4)
    wbox.system.addForce(openmm.MonteCarloBarostat(pressure, temperature))

    # Create the compound integrator
    langevin = integrators.LangevinIntegrator(splitting=splitting,
                                              temperature=temperature,
                                              timestep=timestep,
                                              collision_rate=collision_rate,
                                              measure_shadow_work=False,
                                              measure_heat=False)
    ncmc_langevin = integrators.ExternalPerturbationLangevinIntegrator(
        splitting=splitting,
        temperature=temperature,
        timestep=timestep,
        collision_rate=collision_rate,
        measure_shadow_work=False,
        measure_heat=False)
    integrator = openmm.CompoundIntegrator()
    integrator.addIntegrator(langevin)
    integrator.addIntegrator(ncmc_langevin)

    # Create context
    if args.platform == 'CUDA':
        platform = openmm.Platform.getPlatformByName('CUDA')
        platform.setPropertyDefaultValue('DeterministicForces', 'true')
        properties = {'CudaPrecision': 'mixed'}
        context = openmm.Context(wbox.system, integrator, platform, properties)
    elif args.platform == 'OpenCL':
        platform = openmm.Platform.getPlatformByName('OpenCL')
예제 #6
0
def create_ideal_system(npert=50, nprop=1, deltachem=0.0, platform='CPU'):
    """
    Create small box of water that can impliment ideal mixing with the SaltSwap osmostat.

    Parameters
    ----------
    npert: int
        the number of NCMC perturbations
    nprop: int
        the number of Langevin propagation steps per NCMC perturbation.
    deltachem: float
        the difference in chemical potential between two water molecules and NaCl that has the same nonbonded parameters
        as two water molecules.
    platform: str
        The computational platform. Either 'CPU', 'CUDA', or 'OpenCL'.

    Returns
    -------
    ncmc_swapper: saltswap.swapper
        the driver that can perform NCMC exchanges
    langevin: openmmtools.integrator
        the integrator for equilibrium sampling.
    """
    # Setting the parameters of the simulation
    timestep = 2.0 * unit.femtoseconds
    box_edge = 25.0 * unit.angstrom
    splitting = 'V R O R V'
    temperature = 300. * unit.kelvin
    collision_rate = 1. / unit.picoseconds
    pressure = 1. * unit.atmospheres

    # Make the water box test system with a fixed pressure
    wbox = WaterBox(box_edge=box_edge,
                    model='tip3p',
                    nonbondedMethod=app.PME,
                    cutoff=10 * unit.angstrom,
                    ewaldErrorTolerance=1E-4)
    wbox.system.addForce(openmm.MonteCarloBarostat(pressure, temperature))

    # Create the compound integrator
    langevin = integrators.LangevinIntegrator(splitting=splitting,
                                              temperature=temperature,
                                              timestep=timestep,
                                              collision_rate=collision_rate,
                                              measure_shadow_work=False,
                                              measure_heat=False)
    ncmc_langevin = integrators.ExternalPerturbationLangevinIntegrator(
        splitting=splitting,
        temperature=temperature,
        timestep=timestep,
        collision_rate=collision_rate,
        measure_shadow_work=False,
        measure_heat=False)
    integrator = openmm.CompoundIntegrator()
    integrator.addIntegrator(langevin)
    integrator.addIntegrator(ncmc_langevin)

    # Create context
    if platform == 'CUDA':
        platform = openmm.Platform.getPlatformByName('CUDA')
        platform.setPropertyDefaultValue('DeterministicForces', 'true')
        properties = {'CudaPrecision': 'mixed'}
        context = openmm.Context(wbox.system, integrator, platform, properties)
    elif platform == 'OpenCL':
        platform = openmm.Platform.getPlatformByName('OpenCL')
        properties = {'OpenCLPrecision': 'mixed'}
        context = openmm.Context(wbox.system, integrator, platform, properties)
    elif platform == 'CPU':
        platform = openmm.Platform.getPlatformByName('CPU')
        context = openmm.Context(wbox.system, integrator, platform)
    else:
        raise Exception('Platform name {0} not recognized.'.format(
            args.platform))

    context.setPositions(wbox.positions)
    context.setVelocitiesToTemperature(temperature)

    # Create the swapper object for the insertion and deletion of salt
    ncmc_swapper = Swapper(system=wbox.system,
                           topology=wbox.topology,
                           temperature=temperature,
                           delta_chem=deltachem,
                           ncmc_integrator=ncmc_langevin,
                           pressure=pressure,
                           npert=npert,
                           nprop=nprop)

    # Set the nonbonded parameters of the ions to be the same as water. This is critical for ideal mixing.
    ncmc_swapper.cation_parameters = ncmc_swapper.water_parameters
    ncmc_swapper.anion_parameters = ncmc_swapper.water_parameters
    ncmc_swapper._set_parampath()

    return context, ncmc_swapper, langevin
예제 #7
0
    def test_ncmc_update_parameters_in_context(self):
        """
        Testing that the protocol work is correctly calculated in cases when the parameters are updated using
        context.updateParametersInContext() and the integrator is a compound integrator. The NCMC scheme tested below
        is based on the one used by the saltswap and protons code-bases.
        """
        from simtk.openmm import app
        from openmmtools.constants import kB

        size = 20.0
        temperature = 298.0 * unit.kelvin
        kT = kB * temperature
        nonbonded_method = 'CutoffPeriodic'
        platform_name = 'CPU'
        timestep = 1. * unit.femtoseconds
        collision_rate = 90. / unit.picoseconds

        wbox = testsystems.WaterBox(box_edge=size*unit.angstrom, cutoff=9.*unit.angstrom, nonbondedMethod=getattr(app, nonbonded_method))

        integrator = integrators.ExternalPerturbationLangevinIntegrator(splitting="V R O R V", temperature=temperature, timestep=timestep, collision_rate=collision_rate)

        # Create context
        platform = openmm.Platform.getPlatformByName(platform_name)
        context = openmm.Context(wbox.system, integrator, platform)
        context.setPositions(wbox.positions)
        context.setPositions(wbox.positions)
        context.setVelocitiesToTemperature(temperature)

        def switchoff(force, context, frac=0.9):
            force.setParticleParameters(0, charge=-0.834 * frac, sigma=0.3150752406575124*frac, epsilon=0.635968 * frac)
            force.setParticleParameters(1, charge=0.417 * frac, sigma=0, epsilon=1 * frac)
            force.setParticleParameters(2, charge=0.417 * frac, sigma=0, epsilon=1 * frac)
            force.updateParametersInContext(context)

        def switchon(force, context):
            force.setParticleParameters(0, charge=-0.834, sigma=0.3150752406575124, epsilon=0.635968)
            force.setParticleParameters(1, charge=0.417, sigma=0, epsilon=1)
            force.setParticleParameters(2, charge=0.417, sigma=0, epsilon=1)
            force.updateParametersInContext(context)

        force = wbox.system.getForce(2)  # Non-bonded force.

        # Number of NCMC steps
        nsteps = 20
        niterations = 3

        for i in range(niterations):
            external_protocol_work = 0.0
            integrator.reset_protocol_work()
            integrator.step(1)
            for step in range(nsteps):
                fraction = float(step + 1) / float(nsteps)
                initial_energy = context.getState(getEnergy=True).getPotentialEnergy()
                switchoff(force, context, frac=fraction)
                final_energy = context.getState(getEnergy=True).getPotentialEnergy()
                external_protocol_work += (final_energy - initial_energy) / kT
                integrator.step(1)
            integrator_protocol_work = integrator.get_protocol_work(dimensionless=True)
            assert abs(external_protocol_work - integrator_protocol_work) < 1.E-5
            # Return to unperturbed state
            switchon(force, context)
예제 #8
0
    def create_system(args, splitting):
        """
        Create a test system that's able to run saltswap.

        Parameters
        ----------
        args:
        splitting:
        """
        # Fixed simulation parameters
        temperature = 300.0 * unit.kelvin
        collision_rate = 1.0 / unit.picoseconds
        pressure = 1.0 * unit.atmospheres
        salt_concentration = args.conc * unit.molar

        # Get the test system and add the barostat.
        testobj = getattr(testsystems, args.testsystem)
        testsys = testobj(nonbondedMethod=app.PME,
                          cutoff=10 * unit.angstrom,
                          ewaldErrorTolerance=1E-4,
                          switch_width=1.5 * unit.angstrom)
        testsys.system.addForce(
            openmm.MonteCarloBarostat(pressure, temperature))

        # Create the compound integrator
        langevin = integrators.LangevinIntegrator(
            splitting=splitting,
            temperature=temperature,
            timestep=timestep,
            collision_rate=collision_rate,
            measure_shadow_work=False,
            measure_heat=False)
        ncmc_langevin = integrators.ExternalPerturbationLangevinIntegrator(
            splitting=splitting,
            temperature=temperature,
            timestep=timestep,
            collision_rate=collision_rate,
            measure_shadow_work=False,
            measure_heat=False)
        integrator = openmm.CompoundIntegrator()
        integrator.addIntegrator(langevin)
        integrator.addIntegrator(ncmc_langevin)

        # Create context
        if args.platform == 'CUDA':
            platform = openmm.Platform.getPlatformByName('CUDA')
            platform.setPropertyDefaultValue('DeterministicForces', 'true')
            properties = {'CudaPrecision': 'mixed'}
            context = openmm.Context(testsys.system, integrator, platform,
                                     properties)
        elif args.platform == 'OpenCL':
            platform = openmm.Platform.getPlatformByName('OpenCL')
            properties = {'OpenCLPrecision': 'mixed'}
            context = openmm.Context(testsys.system, integrator, platform,
                                     properties)
        elif args.platform == 'CPU':
            platform = openmm.Platform.getPlatformByName('CPU')
            context = openmm.Context(testsys.system, integrator, platform)
        else:
            raise Exception('Platform name {0} not recognized.'.format(
                args.platform))

        context.setPositions(testsys.positions)
        context.setVelocitiesToTemperature(temperature)

        # Create the swapper object for the insertion and deletion of salt
        salinator = wrappers.Salinator(context=context,
                                       system=testsys.system,
                                       topology=testsys.topology,
                                       ncmc_integrator=ncmc_langevin,
                                       salt_concentration=salt_concentration,
                                       pressure=pressure,
                                       temperature=temperature,
                                       npert=npert,
                                       water_name=args.water_name)

        # Neutralize the system and initialize the number of salt pairs.
        salinator.neutralize()
        salinator.initialize_concentration()

        return salinator, langevin, integrator