"...ssh:/git@developer.sourcefind.cn:2222/tsoc/openmm.git" did not exist on "c5329db5348cb1a6c8e747d3813bc3f3d40c05f5"
Commit 1aa2ccb7 authored by peastman's avatar peastman
Browse files

Created option so virtual sites can share the exclusions of their parent

parent 1893e517
...@@ -218,6 +218,7 @@ class ForceField(object): ...@@ -218,6 +218,7 @@ class ForceField(object):
def __init__(self): def __init__(self):
self.atomType = {} self.atomType = {}
self.atoms = [] self.atoms = []
self.excludeAtomWith = []
self.virtualSites = {} self.virtualSites = {}
self.bonds = [] self.bonds = []
self.angles = [] self.angles = []
...@@ -275,6 +276,10 @@ class ForceField(object): ...@@ -275,6 +276,10 @@ class ForceField(object):
self.localPos = [float(attrib['p1']), float(attrib['p2']), float(attrib['p3'])] self.localPos = [float(attrib['p1']), float(attrib['p2']), float(attrib['p3'])]
else: else:
raise ValueError('Unknown virtual site type: %s' % self.type) raise ValueError('Unknown virtual site type: %s' % self.type)
if 'excludeWith' in attrib:
self.excludeWith = int(attrib['excludeWith'])
else:
self.excludeWith = self.atoms[0]
def createSystem(self, topology, nonbondedMethod=NoCutoff, nonbondedCutoff=1.0*unit.nanometer, def createSystem(self, topology, nonbondedMethod=NoCutoff, nonbondedCutoff=1.0*unit.nanometer,
constraints=None, rigidWater=True, removeCMMotion=True, hydrogenMass=None, **args): constraints=None, rigidWater=True, removeCMMotion=True, hydrogenMass=None, **args):
...@@ -297,6 +302,8 @@ class ForceField(object): ...@@ -297,6 +302,8 @@ class ForceField(object):
""" """
data = ForceField._SystemData() data = ForceField._SystemData()
data.atoms = list(topology.atoms()) data.atoms = list(topology.atoms())
for atom in data.atoms:
data.excludeAtomWith.append([])
# Make a list of all bonds # Make a list of all bonds
...@@ -336,7 +343,7 @@ class ForceField(object): ...@@ -336,7 +343,7 @@ class ForceField(object):
data.atomType[atom] = template.atoms[match].type data.atomType[atom] = template.atoms[match].type
for site in template.virtualSites: for site in template.virtualSites:
if match == site.index: if match == site.index:
data.virtualSites[atom] = (site, [matchAtoms[i].index for i in site.atoms]) data.virtualSites[atom] = (site, [matchAtoms[i].index for i in site.atoms], matchAtoms[site.excludeWith].index)
# Create the System and add atoms # Create the System and add atoms
...@@ -451,8 +458,9 @@ class ForceField(object): ...@@ -451,8 +458,9 @@ class ForceField(object):
# Add virtual sites # Add virtual sites
for atom in data.virtualSites: for atom in data.virtualSites:
(site, atoms) = data.virtualSites[atom] (site, atoms, excludeWith) = data.virtualSites[atom]
index = atom.index index = atom.index
data.excludeAtomWith[excludeWith].append(index)
if site.type == 'average2': if site.type == 'average2':
sys.setVirtualSite(index, mm.TwoParticleAverageSite(atoms[0], atoms[1], site.weights[0], site.weights[1])) sys.setVirtualSite(index, mm.TwoParticleAverageSite(atoms[0], atoms[1], site.weights[0], site.weights[1]))
elif site.type == 'average3': elif site.type == 'average3':
...@@ -1120,33 +1128,33 @@ class NonbondedGenerator: ...@@ -1120,33 +1128,33 @@ class NonbondedGenerator:
sys.addForce(force) sys.addForce(force)
def postprocessSystem(self, sys, data, args): def postprocessSystem(self, sys, data, args):
# Create exceptions based on bonds, virtual sites, and Drude particles. # Create exceptions based on bonds.
bondIndices = [] bondIndices = []
for bond in data.bonds: for bond in data.bonds:
bondIndices.append((bond.atom1, bond.atom2)) bondIndices.append((bond.atom1, bond.atom2))
# If a virtual site does *not* share exclusions with another atom, add a bond between it and its first parent atom.
for i in range(sys.getNumParticles()): for i in range(sys.getNumParticles()):
if sys.isVirtualSite(i): if sys.isVirtualSite(i):
site = sys.getVirtualSite(i) (site, atoms, excludeWith) = data.virtualSites[data.atoms[i]]
for j in range(site.getNumParticles()): if excludeWith is None:
bondIndices.append((i, site.getParticle(j))) bondIndices.append((i, site.getParticle(0)))
drude = [f for f in sys.getForces() if isinstance(f, mm.DrudeForce)]
if len(drude) > 0: # Certain particles, such as lone pairs and Drude particles, share exclusions with a parent atom.
drude = drude[0] # If the parent atom does not interact with an atom, the child particle does not either.
# For purposes of creating exceptions, a Drude particle is "bonded" to anything
# its parent atom is bonded to.
drudeMap = {}
for i in range(drude.getNumParticles()):
params = drude.getParticleParameters(i)
drudeMap[params[1]] = params[0]
for atom1, atom2 in bondIndices: for atom1, atom2 in bondIndices:
drude1 = drudeMap[atom1] if atom1 in drudeMap else None for child1 in data.excludeAtomWith[atom1]:
drude2 = drudeMap[atom2] if atom2 in drudeMap else None bondIndices.append((child1, atom2))
if drude1 is not None: for child2 in data.excludeAtomWith[atom2]:
bondIndices.append((drude1, atom2)) bondIndices.append((child1, child2))
if drude2 is not None: for child2 in data.excludeAtomWith[atom2]:
bondIndices.append((drude1, drude2)) bondIndices.append((atom1, child2))
if drude2 is not None:
bondIndices.append((atom1, drude2)) # Create the exceptions.
nonbonded = [f for f in sys.getForces() if isinstance(f, mm.NonbondedForce)][0] nonbonded = [f for f in sys.getForces() if isinstance(f, mm.NonbondedForce)][0]
nonbonded.createExceptionsFromBonds(bondIndices, self.coulomb14scale, self.lj14scale) nonbonded.createExceptionsFromBonds(bondIndices, self.coulomb14scale, self.lj14scale)
...@@ -4153,8 +4161,6 @@ class DrudeGenerator: ...@@ -4153,8 +4161,6 @@ class DrudeGenerator:
# Add Drude particles. # Add Drude particles.
drudeMap = {}
parentMap = {}
for atom in data.atoms: for atom in data.atoms:
t = data.atomType[atom] t = data.atomType[atom]
if t in self.typeMap: if t in self.typeMap:
...@@ -4171,9 +4177,8 @@ class DrudeGenerator: ...@@ -4171,9 +4177,8 @@ class DrudeGenerator:
p[2] = atom2.index p[2] = atom2.index
elif values[3] is not None and type2 in values[3]: elif values[3] is not None and type2 in values[3]:
p[3] = atom2.index p[3] = atom2.index
drudeIndex = force.addParticle(atom.index, p[0], p[1], p[2], p[3], values[4], values[5], values[6], values[7]) force.addParticle(atom.index, p[0], p[1], p[2], p[3], values[4], values[5], values[6], values[7])
drudeMap[atom.index] = p[0] data.excludeAtomWith[p[0]].append(atom.index)
parentMap[p[0]] = (atom.index, drudeIndex)
sys.addForce(force) sys.addForce(force)
def postprocessSystem(self, sys, data, args): def postprocessSystem(self, sys, data, args):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment