"wrappers/python/src/vscode:/vscode.git/clone" did not exist on "eb0d2463144fcf456c1ddbcd7f58162506cfb753"
Commit 8060c45f authored by Peter Eastman's avatar Peter Eastman
Browse files

Merge branch 'master' of https://github.com/SimTk/openmm

parents 93055791 ea65f7c2
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -250,9 +250,13 @@ public: ...@@ -250,9 +250,13 @@ public:
void integratorDeleted() { void integratorDeleted() {
integratorIsDeleted = true; integratorIsDeleted = true;
} }
/**
* This is the routine that actually computes the list of molecules returned by getMolecules(). Normally
* you should never call it. It is exposed here because the same logic is useful to other classes too.
*/
static std::vector<std::vector<int> > findMolecules(int numParticles, std::vector<std::vector<int> >& particleBonds);
private: private:
friend class Context; friend class Context;
static void tagParticlesInMolecule(int particle, int molecule, std::vector<int>& particleMolecule, std::vector<std::vector<int> >& particleBonds);
Context& owner; Context& owner;
const System& system; const System& system;
Integrator& integrator; Integrator& integrator;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -288,28 +288,56 @@ const vector<vector<int> >& ContextImpl::getMolecules() const { ...@@ -288,28 +288,56 @@ const vector<vector<int> >& ContextImpl::getMolecules() const {
particleBonds[bonds[i].second].push_back(bonds[i].first); particleBonds[bonds[i].second].push_back(bonds[i].first);
} }
// Now tag particles by which molecule they belong to. // Now identify particles by which molecule they belong to.
molecules = findMolecules(numParticles, particleBonds);
return molecules;
}
vector<vector<int> > ContextImpl::findMolecules(int numParticles, vector<vector<int> >& particleBonds) {
// This is essentially a recursive algorithm, but it is reformulated as a loop to avoid
// stack overflows. It selects a particle, marks it as a new molecule, then recursively
// marks every particle bonded to it as also being in that molecule.
vector<int> particleMolecule(numParticles, -1); vector<int> particleMolecule(numParticles, -1);
int numMolecules = 0; int numMolecules = 0;
for (int i = 0; i < numParticles; i++) for (int i = 0; i < numParticles; i++)
if (particleMolecule[i] == -1) if (particleMolecule[i] == -1) {
tagParticlesInMolecule(i, numMolecules++, particleMolecule, particleBonds); // Start a new molecule.
molecules.resize(numMolecules);
vector<int> particleStack;
vector<int> neighborStack;
particleStack.push_back(i);
neighborStack.push_back(0);
int molecule = numMolecules++;
// Recursively tag all the bonded particles.
while (particleStack.size() > 0) {
int particle = particleStack.back();
particleMolecule[particle] = molecule;
int& neighbor = neighborStack.back();
while (neighbor < particleBonds[particle].size() && particleMolecule[particleBonds[particle][neighbor]] != -1)
neighbor++;
if (neighbor < particleBonds[particle].size()) {
particleStack.push_back(particleBonds[particle][neighbor]);
neighborStack.push_back(0);
}
else {
particleStack.pop_back();
neighborStack.pop_back();
}
}
}
// Build the final output vector.
vector<vector<int> > molecules(numMolecules);
for (int i = 0; i < numParticles; i++) for (int i = 0; i < numParticles; i++)
molecules[particleMolecule[i]].push_back(i); molecules[particleMolecule[i]].push_back(i);
return molecules; return molecules;
} }
void ContextImpl::tagParticlesInMolecule(int particle, int molecule, vector<int>& particleMolecule, vector<vector<int> >& particleBonds) {
// Recursively tag particles as belonging to a particular molecule.
particleMolecule[particle] = molecule;
for (int i = 0; i < (int) particleBonds[particle].size(); i++)
if (particleMolecule[particleBonds[particle][i]] == -1)
tagParticlesInMolecule(particleBonds[particle][i], molecule, particleMolecule, particleBonds);
}
static void writeString(ostream& stream, string str) { static void writeString(ostream& stream, string str) {
int length = str.size(); int length = str.size();
stream.write((char*) &length, sizeof(int)); stream.write((char*) &length, sizeof(int));
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2009-2012 Stanford University and the Authors. * * Portions copyright (c) 2009-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -489,7 +489,6 @@ private: ...@@ -489,7 +489,6 @@ private:
struct MoleculeGroup; struct MoleculeGroup;
class VirtualSiteInfo; class VirtualSiteInfo;
void findMoleculeGroups(); void findMoleculeGroups();
static void tagAtomsInMolecule(int atom, int molecule, std::vector<int>& atomMolecule, std::vector<std::vector<int> >& atomBonds);
/** /**
* Ensure that all molecules marked as "identical" really are identical. This should be * Ensure that all molecules marked as "identical" really are identical. This should be
* called whenever force field parameters change. If necessary, it will rebuild the list * called whenever force field parameters change. If necessary, it will rebuild the list
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2009-2012 Stanford University and the Authors. * * Portions copyright (c) 2009-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "openmm/System.h" #include "openmm/System.h"
#include "openmm/VirtualSite.h" #include "openmm/VirtualSite.h"
#include "CudaExpressionUtilities.h" #include "CudaExpressionUtilities.h"
#include "openmm/internal/ContextImpl.h"
#include <algorithm> #include <algorithm>
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
...@@ -647,15 +648,6 @@ void CudaContext::clearAutoclearBuffers() { ...@@ -647,15 +648,6 @@ void CudaContext::clearAutoclearBuffers() {
} }
} }
void CudaContext::tagAtomsInMolecule(int atom, int molecule, vector<int>& atomMolecule, vector<vector<int> >& atomBonds) {
// Recursively tag atoms as belonging to a particular molecule.
atomMolecule[atom] = molecule;
for (int i = 0; i < (int) atomBonds[atom].size(); i++)
if (atomMolecule[atomBonds[atom][i]] == -1)
tagAtomsInMolecule(atomBonds[atom][i], molecule, atomMolecule, atomBonds);
}
/** /**
* This class ensures that atom reordering doesn't break virtual sites. * This class ensures that atom reordering doesn't break virtual sites.
*/ */
...@@ -750,16 +742,14 @@ void CudaContext::findMoleculeGroups() { ...@@ -750,16 +742,14 @@ void CudaContext::findMoleculeGroups() {
} }
} }
// Now tag atoms by which molecule they belong to. // Now identify atoms by which molecule they belong to.
vector<int> atomMolecule(numAtoms, -1); vector<vector<int> > atomIndices = ContextImpl::findMolecules(numAtoms, atomBonds);
int numMolecules = 0; int numMolecules = atomIndices.size();
for (int i = 0; i < numAtoms; i++) vector<int> atomMolecule(numAtoms);
if (atomMolecule[i] == -1) for (int i = 0; i < (int) atomIndices.size(); i++)
tagAtomsInMolecule(i, numMolecules++, atomMolecule, atomBonds); for (int j = 0; j < (int) atomIndices[i].size(); j++)
vector<vector<int> > atomIndices(numMolecules); atomMolecule[atomIndices[i][j]] = i;
for (int i = 0; i < numAtoms; i++)
atomIndices[atomMolecule[i]].push_back(i);
// Construct a description of each molecule. // Construct a description of each molecule.
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2009-2011 Stanford University and the Authors. * * Portions copyright (c) 2009-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -589,7 +589,6 @@ private: ...@@ -589,7 +589,6 @@ private:
struct MoleculeGroup; struct MoleculeGroup;
class VirtualSiteInfo; class VirtualSiteInfo;
void findMoleculeGroups(); void findMoleculeGroups();
static void tagAtomsInMolecule(int atom, int molecule, std::vector<int>& atomMolecule, std::vector<std::vector<int> >& atomBonds);
/** /**
* Ensure that all molecules marked as "identical" really are identical. This should be * Ensure that all molecules marked as "identical" really are identical. This should be
* called whenever force field parameters change. If necessary, it will rebuild the list * called whenever force field parameters change. If necessary, it will rebuild the list
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2009-2012 Stanford University and the Authors. * * Portions copyright (c) 2009-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "openmm/Platform.h" #include "openmm/Platform.h"
#include "openmm/System.h" #include "openmm/System.h"
#include "openmm/VirtualSite.h" #include "openmm/VirtualSite.h"
#include "openmm/internal/ContextImpl.h"
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
...@@ -618,15 +619,6 @@ void OpenCLContext::reduceBuffer(OpenCLArray& array, int numBuffers) { ...@@ -618,15 +619,6 @@ void OpenCLContext::reduceBuffer(OpenCLArray& array, int numBuffers) {
executeKernel(reduceReal4Kernel, bufferSize, 128); executeKernel(reduceReal4Kernel, bufferSize, 128);
} }
void OpenCLContext::tagAtomsInMolecule(int atom, int molecule, vector<int>& atomMolecule, vector<vector<int> >& atomBonds) {
// Recursively tag atoms as belonging to a particular molecule.
atomMolecule[atom] = molecule;
for (int i = 0; i < (int) atomBonds[atom].size(); i++)
if (atomMolecule[atomBonds[atom][i]] == -1)
tagAtomsInMolecule(atomBonds[atom][i], molecule, atomMolecule, atomBonds);
}
/** /**
* This class ensures that atom reordering doesn't break virtual sites. * This class ensures that atom reordering doesn't break virtual sites.
*/ */
...@@ -722,16 +714,14 @@ void OpenCLContext::findMoleculeGroups() { ...@@ -722,16 +714,14 @@ void OpenCLContext::findMoleculeGroups() {
} }
} }
// Now tag atoms by which molecule they belong to. // Now identify atoms by which molecule they belong to.
vector<int> atomMolecule(numAtoms, -1); vector<vector<int> > atomIndices = ContextImpl::findMolecules(numAtoms, atomBonds);
int numMolecules = 0; int numMolecules = atomIndices.size();
for (int i = 0; i < numAtoms; i++) vector<int> atomMolecule(numAtoms);
if (atomMolecule[i] == -1) for (int i = 0; i < (int) atomIndices.size(); i++)
tagAtomsInMolecule(i, numMolecules++, atomMolecule, atomBonds); for (int j = 0; j < (int) atomIndices[i].size(); j++)
vector<vector<int> > atomIndices(numMolecules); atomMolecule[atomIndices[i][j]] = i;
for (int i = 0; i < numAtoms; i++)
atomIndices[atomMolecule[i]].push_back(i);
// Construct a description of each molecule. // Construct a description of each molecule.
......
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include <iostream>
#include <vector>
using namespace OpenMM;
using namespace std;
void testFindMolecules() {
const int numMolecules = 5;
const int moleculeSize[] = {1, 10, 100, 1000, 10000};
vector<int> particleMolecule;
System system;
HarmonicBondForce* bonds = new HarmonicBondForce();
system.addForce(bonds);
for (int i = 0; i < numMolecules; i++)
for (int j = 0; j < moleculeSize[i]; j++) {
int index = system.addParticle(1.0);
particleMolecule.push_back(i);
if (j > 0)
bonds->addBond(index, index-1, 1.0, 1.0);
}
VerletIntegrator integrator(1.0);
Context context(system, integrator, Platform::getPlatformByName("Reference"));
ContextImpl* contextImpl = *reinterpret_cast<ContextImpl**>(&context);
const vector<vector<int> >& molecules = contextImpl->getMolecules();
ASSERT_EQUAL(numMolecules, molecules.size());
for (int i = 0; i < numMolecules; i++) {
ASSERT_EQUAL(moleculeSize[i], molecules[i].size());
for (int j = 0; j < moleculeSize[i]; j++)
ASSERT_EQUAL(particleMolecule[molecules[i][j]], i);
}
}
int main() {
try {
testFindMolecules();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
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