Commit 3d750e85 authored by Peter Eastman's avatar Peter Eastman
Browse files

Modified the initialization order of ForceImpls to prevent them from trying to...

Modified the initialization order of ForceImpls to prevent them from trying to initialize themselves before the Platform had been chosen
parent a5288d55
......@@ -208,6 +208,7 @@ ENDFOREACH(subdir)
INCLUDE_DIRECTORIES(BEFORE ${PROJECT_SOURCE_DIR}/src)
ADD_LIBRARY(${SHARED_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES})
ADD_LIBRARY(${STATIC_TARGET} STATIC ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES})
#
# Allow automated build and dashboard.
......
......@@ -72,7 +72,7 @@ public:
return defaultFreq;
}
protected:
ForceImpl* createImpl(OpenMMContextImpl& context);
ForceImpl* createImpl();
private:
double defaultTemp, defaultFreq;
};
......
......@@ -62,7 +62,7 @@ protected:
* It should create a new ForceImpl object which can be used by the context for calculating forces.
* The ForceImpl will be deleted automatically when the OpenMMContext is deleted.
*/
virtual ForceImpl* createImpl(OpenMMContextImpl& context) = 0;
virtual ForceImpl* createImpl() = 0;
};
} // namespace OpenMM
......
......@@ -98,7 +98,7 @@ public:
soluteDielectric = dielectric;
}
protected:
ForceImpl* createImpl(OpenMMContextImpl& context);
ForceImpl* createImpl();
private:
class AtomInfo;
double solventDielectric, soluteDielectric;
......
......@@ -209,7 +209,7 @@ public:
*/
void setRBTorsionParameters(int index, int atom1, int atom2, int atom3, int atom4, double c0, double c1, double c2, double c3, double c4, double c5);
protected:
ForceImpl* createImpl(OpenMMContextImpl& context);
ForceImpl* createImpl();
private:
class AtomInfo;
class BondInfo;
......
......@@ -45,7 +45,8 @@ namespace OpenMM {
class AndersenThermostatImpl : public ForceImpl {
public:
AndersenThermostatImpl(AndersenThermostat& owner, OpenMMContextImpl& context);
AndersenThermostatImpl(AndersenThermostat& owner);
void initialize(OpenMMContextImpl& context);
AndersenThermostat& getOwner() {
return owner;
}
......
......@@ -56,6 +56,11 @@ class ForceImpl {
public:
virtual ~ForceImpl() {
}
/**
* This is called after the ForceImpl is created and before updateContextState(), calcForces(),
* or calcEnergy() is called on it. This allows it to do any necessary initialization.
*/
virtual void initialize(OpenMMContextImpl& context) = 0;
/**
* Get the Force object from which this ForceImpl was created.
*/
......
......@@ -45,7 +45,8 @@ namespace OpenMM {
class GBSAOBCForceFieldImpl : public ForceImpl {
public:
GBSAOBCForceFieldImpl(GBSAOBCForceField& owner, OpenMMContextImpl& context);
GBSAOBCForceFieldImpl(GBSAOBCForceField& owner);
void initialize(OpenMMContextImpl& context);
GBSAOBCForceField& getOwner() {
return owner;
}
......@@ -59,10 +60,8 @@ public:
}
std::vector<std::string> getKernelNames();
private:
void initialize(OpenMMContextImpl& context);
GBSAOBCForceField& owner;
Kernel kernel;
bool hasInitialized;
};
} // namespace OpenMM
......
......@@ -47,8 +47,9 @@ namespace OpenMM {
class StandardMMForceFieldImpl : public ForceImpl {
public:
StandardMMForceFieldImpl(StandardMMForceField& owner, OpenMMContextImpl& context);
StandardMMForceFieldImpl(StandardMMForceField& owner);
~StandardMMForceFieldImpl();
void initialize(OpenMMContextImpl& context);
StandardMMForceField& getOwner() {
return owner;
}
......
......@@ -41,6 +41,6 @@ AndersenThermostat::AndersenThermostat(double defaultTemperature, double default
defaultTemp(defaultTemperature), defaultFreq(defaultCollisionFrequency) {
}
ForceImpl* AndersenThermostat::createImpl(OpenMMContextImpl& context) {
return new AndersenThermostatImpl(*this, context);
ForceImpl* AndersenThermostat::createImpl() {
return new AndersenThermostatImpl(*this);
}
......@@ -39,7 +39,10 @@
using namespace OpenMM;
using std::vector;
AndersenThermostatImpl::AndersenThermostatImpl(AndersenThermostat& owner, OpenMMContextImpl& context) : owner(owner) {
AndersenThermostatImpl::AndersenThermostatImpl(AndersenThermostat& owner) : owner(owner) {
}
void AndersenThermostatImpl::initialize(OpenMMContextImpl& context) {
kernel = context.getPlatform().createKernel(ApplyAndersenThermostatKernel::Name());
const System& system = context.getSystem();
vector<double> masses(system.getNumAtoms());
......
......@@ -51,6 +51,6 @@ void GBSAOBCForceField::setAtomParameters(int index, double charge, double radiu
atoms[index].scalingFactor = scalingFactor;
}
ForceImpl* GBSAOBCForceField::createImpl(OpenMMContextImpl& context) {
return new GBSAOBCForceFieldImpl(*this, context);
ForceImpl* GBSAOBCForceField::createImpl() {
return new GBSAOBCForceFieldImpl(*this);
}
......@@ -37,11 +37,10 @@
using namespace OpenMM;
using std::vector;
GBSAOBCForceFieldImpl::GBSAOBCForceFieldImpl(GBSAOBCForceField& owner, OpenMMContextImpl& context) : owner(owner), hasInitialized(false) {
GBSAOBCForceFieldImpl::GBSAOBCForceFieldImpl(GBSAOBCForceField& owner) : owner(owner) {
}
void GBSAOBCForceFieldImpl::initialize(OpenMMContextImpl& context) {
hasInitialized = true;
kernel = context.getPlatform().createKernel(CalcGBSAOBCForceFieldKernel::Name());
vector<vector<double> > atomParameters(owner.getNumAtoms());
for (int i = 0; i < owner.getNumAtoms(); ++i) {
......@@ -55,14 +54,10 @@ void GBSAOBCForceFieldImpl::initialize(OpenMMContextImpl& context) {
}
void GBSAOBCForceFieldImpl::calcForces(OpenMMContextImpl& context, Stream& forces) {
if (!hasInitialized)
initialize(context);
dynamic_cast<CalcGBSAOBCForceFieldKernel&>(kernel.getImpl()).executeForces(context.getPositions(), forces);
}
double GBSAOBCForceFieldImpl::calcEnergy(OpenMMContextImpl& context) {
if (!hasInitialized)
initialize(context);
return dynamic_cast<CalcGBSAOBCForceFieldKernel&>(kernel.getImpl()).executeEnergy(context.getPositions());
}
......
......@@ -49,7 +49,7 @@ OpenMMContextImpl::OpenMMContextImpl(OpenMMContext& owner, System& system, Integ
vector<string> kernelNames;
kernelNames.push_back(CalcKineticEnergyKernel::Name());
for (int i = 0; i < system.getNumForces(); ++i) {
forceImpls.push_back(system.getForce(i).createImpl(*this));
forceImpls.push_back(system.getForce(i).createImpl());
map<string, double> forceParameters = forceImpls[forceImpls.size()-1]->getDefaultParameters();
parameters.insert(forceParameters.begin(), forceParameters.end());
vector<string> forceKernels = forceImpls[forceImpls.size()-1]->getKernelNames();
......@@ -58,7 +58,7 @@ OpenMMContextImpl::OpenMMContextImpl(OpenMMContext& owner, System& system, Integ
vector<string> integratorKernels = integrator.getKernelNames();
kernelNames.insert(kernelNames.begin(), integratorKernels.begin(), integratorKernels.end());
if (platform == 0)
platform = &Platform::findPlatform(kernelNames);
this->platform = platform = &Platform::findPlatform(kernelNames);
else if (!platform->supportsKernels(kernelNames))
throw OpenMMException("Specified a Platform for an OpenMMContext which does not support all required kernels");
positions = platform->createStream("atomPositions", system.getNumAtoms(), Stream::Double3);
......@@ -71,6 +71,8 @@ OpenMMContextImpl::OpenMMContextImpl(OpenMMContext& owner, System& system, Integ
for (int i = 0; i < masses.size(); ++i)
masses[i] = system.getAtomMass(i);
dynamic_cast<CalcKineticEnergyKernel&>(kineticEnergyKernel.getImpl()).initialize(masses);
for (int i = 0; i < forceImpls.size(); ++i)
forceImpls[i]->initialize(*this);
integrator.initialize(*this);
}
......@@ -118,7 +120,9 @@ void OpenMMContextImpl::reinitialize() {
for (int i = 0; i < (int) forceImpls.size(); ++i)
delete forceImpls[i];
forceImpls.resize(0);
for (int i = 0; i < system.getNumForces(); ++i)
forceImpls.push_back(system.getForce(i).createImpl(*this));
for (int i = 0; i < system.getNumForces(); ++i) {
forceImpls.push_back(system.getForce(i).createImpl());
forceImpls[i]->initialize(*this);
}
integrator.initialize(*this);
}
......@@ -128,6 +128,6 @@ void StandardMMForceField::setRBTorsionParameters(int index, int atom1, int atom
rbTorsions[index].c[5] = c5;
}
ForceImpl* StandardMMForceField::createImpl(OpenMMContextImpl& context) {
return new StandardMMForceFieldImpl(*this, context);
ForceImpl* StandardMMForceField::createImpl() {
return new StandardMMForceFieldImpl(*this);
}
......@@ -38,7 +38,13 @@ using std::pair;
using std::vector;
using std::set;
StandardMMForceFieldImpl::StandardMMForceFieldImpl(StandardMMForceField& owner, OpenMMContextImpl& context) : owner(owner) {
StandardMMForceFieldImpl::StandardMMForceFieldImpl(StandardMMForceField& owner) : owner(owner) {
}
StandardMMForceFieldImpl::~StandardMMForceFieldImpl() {
}
void StandardMMForceFieldImpl::initialize(OpenMMContextImpl& context) {
kernel = context.getPlatform().createKernel(CalcStandardMMForceFieldKernel::Name());
vector<vector<int> > bondIndices(owner.getNumBonds());
vector<vector<double> > bondParameters(owner.getNumBonds());
......@@ -116,9 +122,6 @@ StandardMMForceFieldImpl::StandardMMForceFieldImpl(StandardMMForceField& owner,
periodicTorsionIndices, periodicTorsionParameters, rbTorsionIndices, rbTorsionParameters, bonded14Indices, 0.5, 1.0/1.2, exclusions, nonbondedParameters);
}
StandardMMForceFieldImpl::~StandardMMForceFieldImpl() {
}
void StandardMMForceFieldImpl::calcForces(OpenMMContextImpl& context, Stream& forces) {
dynamic_cast<CalcStandardMMForceFieldKernel&>(kernel.getImpl()).executeForces(context.getPositions(), forces);
}
......
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