def test_1(self): # This tests for a refcounting bug in the swig wrappers # that was previously problematic. # See https://github.com/pandegroup/openmm/issues/1214 for cycle in range(10): system = mm.System() system.getDefaultPeriodicBoxVectors()
def testForce(model_file, output_forces): # Create a random cloud of particles. numParticles = 10 system = mm.System() positions = np.random.rand(numParticles, 3) for i in range(numParticles): system.addParticle(1.0) # Create a force force = ot.TorchForce(model_file) assert not force.getOutputsForces() # Check the default force.setOutputsForces(output_forces) assert force.getOutputsForces() == output_forces system.addForce(force) # Compute the forces and energy. integ = mm.VerletIntegrator(1.0) context = mm.Context(system, integ, mm.Platform.getPlatformByName('Reference')) context.setPositions(positions) state = context.getState(getEnergy=True, getForces=True) # See if the energy and forces are correct. The network defines a potential of the form E(r) = |r|^2 expectedEnergy = np.sum(positions * positions) assert np.allclose( expectedEnergy, state.getPotentialEnergy().value_in_unit(unit.kilojoules_per_mole)) assert np.allclose(-2 * positions, state.getForces(asNumpy=True))
def make_toy_system_object(model): """ Make openmm system and topology files for use with a toy system. """ system = openmm.System() topology = openmm_app.Topology() num_particles = model.toy_settings.num_particles assert model.toy_settings.num_particles == len(model.toy_settings.masses) new_expression = "k*(" + model.toy_settings.potential_energy_expression + ")" force = openmm.CustomCentroidBondForce(num_particles, new_expression) force.addGlobalParameter("k", 1.0 * openmm.unit.kilocalories_per_mole) groups_list = [] for i in range(num_particles): mass = model.toy_settings.masses[i] * openmm.unit.amu system.addParticle(mass) atom_name = "X{}".format(i) if not atom_name in openmm_app.element.Element._elements_by_symbol: element = openmm_app.element.Element(0, atom_name, atom_name, mass) else: element = openmm_app.element.Element._elements_by_symbol[atom_name] chain = topology.addChain() residue = topology.addResidue("UNK", chain) topology.addAtom(atom_name, element, residue) groups_list.append(force.addGroup([i])) force.addBond(groups_list, []) system.addForce(force) return system, topology
def setUp(self): system = mm.System() system.addParticle(1.0) for i in range(32): force = mm.CustomExternalForce(str(i)) force.addParticle(0, []) force.setForceGroup(i) system.addForce(force) platform = mm.Platform.getPlatformByName('Reference') context = mm.Context(system, mm.VerletIntegrator(0), platform) context.setPositions([(0, 0, 0)]) self.context = context
def testModuleArguments(deviceString, precision): if pt.cuda.device_count() < 1 and deviceString == 'cuda:0': pytest.skip('A CUDA device is not available') if pt.cuda.device_count() < 2 and deviceString == 'cuda:1': pytest.skip('Two CUDA devices are not available') class TestModule(pt.nn.Module): def __init__(self, device, dtype, positions): super().__init__() self.device = device self.dtype = dtype self.register_buffer('positions', pt.tensor(positions).to(dtype)) def forward(self, positions): assert self.positions.device == self.device assert positions.device == self.device assert positions.dtype == self.dtype assert pt.all(positions == self.positions) return pt.sum(positions) with NamedTemporaryFile() as fd: numParticles = 10 system = mm.System() positions = np.random.rand(numParticles, 3) for _ in range(numParticles): system.addParticle(1.0) device = pt.device(deviceString) if device.type == 'cpu' or precision == 'double': dtype = pt.float64 else: dtype = pt.float32 module = TestModule(device, dtype, positions) pt.jit.script(module).save(fd.name) force = ot.TorchForce(fd.name) system.addForce(force) integrator = mm.VerletIntegrator(1.0) platform = mm.Platform.getPlatformByName(device.type.upper()) properties = {} if device.type == 'cuda': properties['DeviceIndex'] = str(device.index) properties['Precision'] = precision context = mm.Context(system, integrator, platform, properties) context.setPositions(positions) context.getState(getEnergy=True, getForces=True)
def test_createCheckpoint(self): system = mm.System() system.addParticle(1.0) refPositions = [(0,0,0)] platform = mm.Platform.getPlatformByName('Reference') context = mm.Context(system, mm.VerletIntegrator(0), platform) context.setPositions(refPositions) chk = context.createCheckpoint() # check that the return value of createCheckpoint is of type bytes (non-unicode) assert isinstance(chk, bytes) # set the positions to something random then reload the checkpoint, and # make sure that the positions get restored correctly context.setPositions([(12345, 12345, 123451)]) context.loadCheckpoint(chk) newPositions = context.getState(getPositions=True).getPositions()._value assert newPositions == refPositions
def createSystem(self, topology: openmm.app.Topology, **args) -> openmm.System: """Create a System for running a simulation with this potential function. Parameters ---------- topology: Topology the Topology for which to create a System args: particular potential functions may define additional arguments that can be used to customize them. See the documentation on the specific potential functions for more information. Returns ------- a newly created System object that uses this potential function to model the Topology """ system = openmm.System() for atom in topology.atoms(): if atom.element is None: system.addParticle(0) else: system.addParticle(atom.element.mass) self._impl.addForces(topology, system, None, 0, **args) return system
def createSystem(self, nonbondedMethod=ff.NoCutoff, nonbondedCutoff=1.0 * nanometer, ewaldErrorTolerance=0.0005, removeCMMotion=True, hydrogenMass=None, OPLS=False, implicitSolvent=None, AGBNPVersion=1): """Construct an OpenMM System representing the topology described by this DMS file Parameters ---------- nonbondedMethod : object=NoCutoff The method to use for nonbonded interactions. Allowed values are NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, PME, or LJPME. nonbondedCutoff : distance=1*nanometer The cutoff distance to use for nonbonded interactions ewaldErrorTolerance : float=0.0005 The error tolerance to use if nonbondedMethod is Ewald, PME, or LJPME. removeCMMotion : boolean=True If true, a CMMotionRemover will be added to the System hydrogenMass : mass=None The mass to use for hydrogen atoms bound to heavy atoms. Any mass added to a hydrogen is subtracted from the heavy atom to keep their total mass the same. OPLS : boolean=False If True, forces OPLS combining rules implicitSolvent: string=None If not None, creates implicit solvent force of the given name Allowed values are: HCT and 'AGBNP' (the corresponding tables must be present in the DMS file) AGBNPVersion: int=1 AGBNP implicit solvent version """ self._checkForUnsupportedTerms() sys = mm.System() # Build the box dimensions boxSize = self.topology.getUnitCellDimensions() if boxSize is not None: sys.setDefaultPeriodicBoxVectors( (boxSize[0], 0, 0), (0, boxSize[1], 0), (0, 0, boxSize[2])) elif nonbondedMethod in (ff.CutoffPeriodic, ff.Ewald, ff.PME, ff.LJPME): raise ValueError( 'Illegal nonbonded method for a non-periodic system') # Create all of the particles for (fcounter, conn, tables, offset) in self._localVars(): for mass in conn.execute('SELECT mass FROM particle ORDER BY id'): sys.addParticle(mass[0] * dalton) # Add all of the forces self._addBondsToSystem(sys) self._addAnglesToSystem(sys) self._addConstraintsToSystem(sys) self._addPeriodicTorsionsToSystem(sys, OPLS) self._addImproperHarmonicTorsionsToSystem(sys) self._addCMAPToSystem(sys) self._addVirtualSitesToSystem(sys) self._addPositionalHarmonicRestraints(sys) nb, cnb = self._addNonbondedForceToSystem(sys, OPLS) # Finish configuring the NonbondedForce. methodMap = { ff.NoCutoff: mm.NonbondedForce.NoCutoff, ff.CutoffNonPeriodic: mm.NonbondedForce.CutoffNonPeriodic, ff.CutoffPeriodic: mm.NonbondedForce.CutoffPeriodic, ff.Ewald: mm.NonbondedForce.Ewald, ff.PME: mm.NonbondedForce.PME, ff.LJPME: mm.NonbondedForce.LJPME } nb.setNonbondedMethod(methodMap[nonbondedMethod]) nb.setCutoffDistance(nonbondedCutoff) nb.setEwaldErrorTolerance(ewaldErrorTolerance) if cnb is not None: nb.setUseDispersionCorrection(False) if nonbondedMethod in (ff.CutoffPeriodic, ff.Ewald, ff.PME, ff.LJPME): cnb.setNonbondedMethod(methodMap[ff.CutoffPeriodic]) cnb.setCutoffDistance(nonbondedCutoff) elif nonbondedMethod == ff.CutoffNonPeriodic: cnb.setNonbondedMethod(methodMap[ff.CutoffNonPeriodic]) cnb.setCutoffDistance(nonbondedCutoff) else: cnb.setNonbondedMethod(methodMap[ff.NoCutoff]) cnb.setUseSwitchingFunction(False) cnb.setUseLongRangeCorrection(False) #add implicit solvent model. if implicitSolvent is not None: if not (implicitSolvent in (HCT, 'AGBNP', 'GVolSA', 'AGBNP3')): raise ValueError('Illegal implicit solvent method') if self._verbose: print('Adding implicit solvent ...') #with implicit solvent turn off native reaction field #However note that this does not affect the shifted Coulomb potential of the Nonbonded force #(it affects the only the energy, not the forces and equation of motion) nb.setReactionFieldDielectric(1.0) if implicitSolvent is HCT: gb_parms = self._get_gb_params() if gb_parms: if self._verbose: print('Adding HCT GB force ...') gb = GBSAHCTForce(SA='ACE') for i in range(len(gb_parms)): gb.addParticle(list(gb_parms[i])) gb.finalize() sys.addForce(gb) else: raise IOError("No HCT parameters found in DMS file") if implicitSolvent == 'AGBNP3': #load AGBNP3 plugin if available try: from AGBNP3plugin import AGBNP3Force except ImportError: raise NotImplementedError( 'AGBNP3 is not supported in this version') #sets up AGBNP3 gb_parms = self._get_agbnp2_params() if gb_parms: if self._verbose: print('Adding AGBNP3 force ...') gb = AGBNP3Force() # add particles for i in range(len(gb_parms)): p = gb_parms[i] gb.addParticle(p[0], p[1], p[2], p[3], p[4], p[5], p[6]) # connection table (from bonds) self._add_agbnp2_ct(gb) sys.addForce(gb) else: raise IOError("No AGBNP parameters found in DMS file") if implicitSolvent == 'GVolSA': #implemented as AGBNP version 0 implicitSolvent = 'AGBNP' AGBNPVersion = 0 if self._verbose: print('Using GVolSA') if implicitSolvent == 'AGBNP': #load AGBNP plugin if available try: from AGBNPplugin import AGBNPForce except ImportError: raise NotImplementedError( 'AGBNP is not supported in this version') #sets up AGBNP gb_parms = self._get_agbnp2_params() if gb_parms: gb = AGBNPForce() gb.setNonbondedMethod(methodMap[nonbondedMethod]) gb.setCutoffDistance(nonbondedCutoff) gb.setVersion(AGBNPVersion) if self._verbose: print('Using AGBNP force version %d ...' % AGBNPVersion) # add particles for i in range(len(gb_parms)): [ radiusN, chargeN, gammaN, alphaN, hbtype, hbwN, ishydrogenN ] = gb_parms[i] h_flag = ishydrogenN > 0 gb.addParticle(radiusN, gammaN, alphaN, chargeN, h_flag) sys.addForce(gb) self.gb_parms = gb_parms self.agbnp = gb else: raise IOError("No AGBNP parameters found in DMS file") # Adjust masses. if hydrogenMass is not None: for atom1, atom2 in self.topology.bonds(): if atom1.element == hydrogen: (atom1, atom2) = (atom2, atom1) if atom2.element == hydrogen and atom1.element not in ( hydrogen, None): transferMass = hydrogenMass - sys.getParticleMass( atom2.index) sys.setParticleMass(atom2.index, hydrogenMass) sys.setParticleMass( atom1.index, sys.getParticleMass(atom1.index) - transferMass) # Add a CMMotionRemover. if removeCMMotion: sys.addForce(mm.CMMotionRemover()) return sys
def test_int64(self): indices = np.array([0, 1, 2]) sys = mm.System() sys.addParticle(2.0) assert sys.getParticleMass(indices[0]) == 2.0 * unit.amu
if os.path.isfile(filename): os.remove(filename) # simulation mass_1 = 39.948 * unit.amu sigma_1 = 3.404 * unit.angstroms epsilon_1 = 0.238 * unit.kilocalories_per_mole charge_1 = 0.0 * unit.elementary_charge mass_2 = 131.293 * unit.amu sigma_2 = 3.961 * unit.angstroms epsilon_2 = 0.459 * unit.kilocalories_per_mole charge_2 = 0.0 * unit.elementary_charge system = mm.System() non_bonded_force = mm.NonbondedForce() reduced_sigma = 0.5 * (sigma_1 + sigma_2) cutoff_distance = 4.0 * reduced_sigma switching_distance = 3.0 * reduced_sigma non_bonded_force.setNonbondedMethod(mm.NonbondedForce.CutoffPeriodic) non_bonded_force.setUseSwitchingFunction(True) non_bonded_force.setCutoffDistance(cutoff_distance) non_bonded_force.setSwitchingDistance(switching_distance) system.addParticle(mass_1) non_bonded_force.addParticle(charge_1, sigma_1, epsilon_1) system.addParticle(mass_2)