Commit b20fe9a6 authored by peastman's avatar peastman
Browse files

Added AmoebaMultipoleForce::getPMEParametersInContext()

parent 0f5f5334
......@@ -175,6 +175,20 @@ public:
*/
void setPmeGridDimensions(const std::vector<int>& gridDimension);
/**
* Get the parameters being used for PME in a particular Context. Because some platforms have restrictions
* on the allowed grid sizes, the values that are actually used may be slightly different from those
* specified with setPmeGridDimensions(), or the standard values calculated based on the Ewald error tolerance.
* See the manual for details.
*
* @param context the Context for which to get the parameters
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
*/
void getPMEParametersInContext(const Context& context, double& alpha, int& nx, int& ny, int& nz) const;
/**
* Add multipole-related info for a particle
*
......
......@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2012 Stanford University and the Authors. *
* Portions copyright (c) 2008-2015 Stanford University and the Authors. *
* Authors: *
* Contributors: *
* *
......@@ -361,6 +361,16 @@ public:
* @param force the AmoebaMultipoleForce to copy the parameters from
*/
virtual void copyParametersToContext(ContextImpl& context, const AmoebaMultipoleForce& force) = 0;
/**
* Get the parameters being used for PME.
*
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
*/
virtual void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const = 0;
};
/**
......
......@@ -89,6 +89,7 @@ public:
void getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments);
void updateParametersInContext(ContextImpl& context);
void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const;
private:
......
......@@ -103,6 +103,10 @@ void AmoebaMultipoleForce::setPmeGridDimensions(const std::vector<int>& gridDime
return;
}
void AmoebaMultipoleForce::getPMEParametersInContext(const Context& context, double& alpha, int& nx, int& ny, int& nz) const {
dynamic_cast<const AmoebaMultipoleForceImpl&>(getImplInContext(context)).getPMEParameters(alpha, nx, ny, nz);
}
int AmoebaMultipoleForce::getMutualInducedMaxIterations() const {
return mutualInducedMaxIterations;
}
......
......@@ -199,3 +199,7 @@ void AmoebaMultipoleForceImpl::getSystemMultipoleMoments(ContextImpl& context, s
void AmoebaMultipoleForceImpl::updateParametersInContext(ContextImpl& context) {
kernel.getAs<CalcAmoebaMultipoleForceKernel>().copyParametersToContext(context, owner);
}
void AmoebaMultipoleForceImpl::getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const {
kernel.getAs<CalcAmoebaMultipoleForceKernel>().getPMEParameters(alpha, nx, ny, nz);
}
......@@ -37,6 +37,7 @@
#include "openmm/internal/AmoebaVdwForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "CudaBondedUtilities.h"
#include "CudaFFT3D.h"
#include "CudaForceInfo.h"
#include "CudaKernelSources.h"
#include "CudaNonbondedUtilities.h"
......@@ -902,26 +903,6 @@ CudaCalcAmoebaMultipoleForceKernel::~CudaCalcAmoebaMultipoleForceKernel() {
cufftDestroy(fft);
}
/**
* Select a size for an FFT that is a multiple of 2, 3, 5, and 7.
*/
static int findFFTDimension(int minimum) {
if (minimum < 1)
return 1;
while (true) {
// Attempt to factor the current value.
int unfactored = minimum;
for (int factor = 2; factor < 8; factor++) {
while (unfactored > 1 && unfactored%factor == 0)
unfactored /= factor;
}
if (unfactored == 1)
return minimum;
minimum++;
}
}
void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const AmoebaMultipoleForce& force) {
cu.setAsCurrent();
......@@ -1063,7 +1044,7 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const
}
else
maxInducedIterations = 0;
bool usePME = (force.getNonbondedMethod() == AmoebaMultipoleForce::PME);
usePME = (force.getNonbondedMethod() == AmoebaMultipoleForce::PME);
// See whether there's an AmoebaGeneralizedKirkwoodForce in the System.
......@@ -1099,8 +1080,7 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const
int endExclusionIndex = (cu.getContextIndex()+1)*numExclusionTiles/numContexts;
defines["FIRST_EXCLUSION_TILE"] = cu.intToString(startExclusionIndex);
defines["LAST_EXCLUSION_TILE"] = cu.intToString(endExclusionIndex);
double alpha = force.getAEwald();
int gridSizeX, gridSizeY, gridSizeZ;
alpha = force.getAEwald();
if (usePME) {
vector<int> pmeGridDimension;
force.getPmeGridDimensions(pmeGridDimension);
......@@ -1109,13 +1089,13 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const
nb.setEwaldErrorTolerance(force.getEwaldErrorTolerance());
nb.setCutoffDistance(force.getCutoffDistance());
NonbondedForceImpl::calcPMEParameters(system, nb, alpha, gridSizeX, gridSizeY, gridSizeZ);
gridSizeX = findFFTDimension(gridSizeX);
gridSizeY = findFFTDimension(gridSizeY);
gridSizeZ = findFFTDimension(gridSizeZ);
gridSizeX = CudaFFT3D::findLegalDimension(gridSizeX);
gridSizeY = CudaFFT3D::findLegalDimension(gridSizeY);
gridSizeZ = CudaFFT3D::findLegalDimension(gridSizeZ);
} else {
gridSizeX = pmeGridDimension[0];
gridSizeY = pmeGridDimension[1];
gridSizeZ = pmeGridDimension[2];
gridSizeX = CudaFFT3D::findLegalDimension(pmeGridDimension[0]);
gridSizeY = CudaFFT3D::findLegalDimension(pmeGridDimension[1]);
gridSizeZ = CudaFFT3D::findLegalDimension(pmeGridDimension[2]);
}
defines["EWALD_ALPHA"] = cu.doubleToString(alpha);
defines["SQRT_PI"] = cu.doubleToString(sqrt(M_PI));
......@@ -2035,6 +2015,15 @@ void CudaCalcAmoebaMultipoleForceKernel::copyParametersToContext(ContextImpl& co
multipolesAreValid = false;
}
void CudaCalcAmoebaMultipoleForceKernel::getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const {
if (!usePME)
throw OpenMMException("getPMEParametersInContext: This Context is not using PME");
alpha = this->alpha;
nx = gridSizeX;
ny = gridSizeY;
nz = gridSizeZ;
}
/* -------------------------------------------------------------------------- *
* AmoebaGeneralizedKirkwood *
* -------------------------------------------------------------------------- */
......
......@@ -363,6 +363,15 @@ public:
* @param force the AmoebaMultipoleForce to copy the parameters from
*/
void copyParametersToContext(ContextImpl& context, const AmoebaMultipoleForce& force);
/**
* Get the parameters being used for PME.
*
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
*/
void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const;
private:
class ForceInfo;
class SortTrait : public CudaSort::SortTrait {
......@@ -381,8 +390,9 @@ private:
template <class T, class T4, class M4> void computeSystemMultipoleMoments(ContextImpl& context, std::vector<double>& outputMultipoleMoments);
int numMultipoles, maxInducedIterations;
int fixedFieldThreads, inducedFieldThreads, electrostaticsThreads;
double inducedEpsilon;
bool hasQuadrupoles, hasInitializedScaleFactors, hasInitializedFFT, multipolesAreValid;
int gridSizeX, gridSizeY, gridSizeZ;
double alpha, inducedEpsilon;
bool usePME, hasQuadrupoles, hasInitializedScaleFactors, hasInitializedFFT, multipolesAreValid;
CudaContext& cu;
const System& system;
std::vector<int3> covalentFlagValues;
......
......@@ -1943,7 +1943,16 @@ static void setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::Non
energy = state.getPotentialEnergy();
}
return;
if (nonbondedMethod == AmoebaMultipoleForce::PME) {
double actualAlpha;
int actualSize[3];
amoebaMultipoleForce->getPMEParametersInContext(context, actualAlpha, actualSize[0], actualSize[1], actualSize[2]);
ASSERT_EQUAL_TOL(amoebaMultipoleForce->getAEwald(), actualAlpha, 1e-5);
for (int i = 0; i < 3; i++) {
ASSERT(actualSize[i] >= inputPmeGridDimension);
ASSERT(actualSize[i] < inputPmeGridDimension+10);
}
}
}
// test multipole mutual polarization using PME for box of water
......
......@@ -790,6 +790,15 @@ void ReferenceCalcAmoebaMultipoleForceKernel::copyParametersToContext(ContextImp
}
}
void ReferenceCalcAmoebaMultipoleForceKernel::getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const {
if (!usePme)
throw OpenMMException("getPMEParametersInContext: This Context is not using PME");
alpha = alphaEwald;
nx = pmeGridDimension[0];
ny = pmeGridDimension[1];
nz = pmeGridDimension[2];
}
/* -------------------------------------------------------------------------- *
* AmoebaGeneralizedKirkwood *
* -------------------------------------------------------------------------- */
......
......@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008 Stanford University and the Authors. *
* Portions copyright (c) 2008-2015 Stanford University and the Authors. *
* Authors: *
* Contributors: *
* *
......@@ -403,6 +403,15 @@ public:
* @param force the AmoebaMultipoleForce to copy the parameters from
*/
void copyParametersToContext(ContextImpl& context, const AmoebaMultipoleForce& force);
/**
* Get the parameters being used for PME.
*
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
*/
void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const;
private:
......
......@@ -1864,7 +1864,16 @@ static void setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::Non
energy = state.getPotentialEnergy();
}
return;
if (nonbondedMethod == AmoebaMultipoleForce::PME) {
double actualAlpha;
int actualSize[3];
amoebaMultipoleForce->getPMEParametersInContext(context, actualAlpha, actualSize[0], actualSize[1], actualSize[2]);
ASSERT_EQUAL_TOL(amoebaMultipoleForce->getAEwald(), actualAlpha, 1e-5);
for (int i = 0; i < 3; i++) {
ASSERT(actualSize[i] >= inputPmeGridDimension);
ASSERT(actualSize[i] < inputPmeGridDimension+10);
}
}
}
// test multipole mutual polarization using PME for box of water
......
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