"wrappers/vscode:/vscode.git/clone" did not exist on "23522479032df875cfeba5d2498d86383220be42"
Commit 7a60fd73 authored by Peter Eastman's avatar Peter Eastman
Browse files

Continuing to convert AmoebaMultipoleForce

parent 5209c1cd
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "openmm/internal/AmoebaMultipoleForceImpl.h" #include "openmm/internal/AmoebaMultipoleForceImpl.h"
#include "openmm/internal/AmoebaWcaDispersionForceImpl.h" #include "openmm/internal/AmoebaWcaDispersionForceImpl.h"
#include "openmm/internal/AmoebaTorsionTorsionForceImpl.h" #include "openmm/internal/AmoebaTorsionTorsionForceImpl.h"
#include "openmm/internal/AmoebaVdwForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h" #include "openmm/internal/NonbondedForceImpl.h"
#include "CudaBondedUtilities.h" #include "CudaBondedUtilities.h"
#include "CudaForceInfo.h" #include "CudaForceInfo.h"
...@@ -864,11 +865,12 @@ private: ...@@ -864,11 +865,12 @@ private:
}; };
CudaCalcAmoebaMultipoleForceKernel::CudaCalcAmoebaMultipoleForceKernel(std::string name, const Platform& platform, CudaContext& cu, System& system) : CudaCalcAmoebaMultipoleForceKernel::CudaCalcAmoebaMultipoleForceKernel(std::string name, const Platform& platform, CudaContext& cu, System& system) :
CalcAmoebaMultipoleForceKernel(name, platform), cu(cu), system(system), hasInitializedScaleFactors(false), CalcAmoebaMultipoleForceKernel(name, platform), cu(cu), system(system), hasInitializedScaleFactors(false), hasInitializedFFT(false),
multipoleParticles(NULL), molecularDipoles(NULL), molecularQuadrupoles(NULL), labFrameDipoles(NULL), labFrameQuadrupoles(NULL), multipoleParticles(NULL), molecularDipoles(NULL), molecularQuadrupoles(NULL), labFrameDipoles(NULL), labFrameQuadrupoles(NULL),
field(NULL), fieldPolar(NULL), inducedField(NULL), inducedFieldPolar(NULL), torque(NULL), dampingAndThole(NULL), field(NULL), fieldPolar(NULL), inducedField(NULL), inducedFieldPolar(NULL), torque(NULL), dampingAndThole(NULL),
inducedDipole(NULL), inducedDipolePolar(NULL), inducedDipoleErrors(NULL), polarizability(NULL), covalentFlags(NULL), polarizationGroupFlags(NULL), inducedDipole(NULL), inducedDipolePolar(NULL), inducedDipoleErrors(NULL), polarizability(NULL), covalentFlags(NULL), polarizationGroupFlags(NULL),
pmeGrid(NULL) { pmeGrid(NULL), pmeBsplineModuliX(NULL), pmeBsplineModuliY(NULL), pmeBsplineModuliZ(NULL), pmeTheta1(NULL), pmeTheta2(NULL), pmeTheta3(NULL),
pmeIgrid(NULL), pmePhi(NULL), pmePhid(NULL), pmePhip(NULL), pmePhidp(NULL), pmeAtomRange(NULL), pmeAtomGridIndex(NULL), sort(NULL) {
} }
CudaCalcAmoebaMultipoleForceKernel::~CudaCalcAmoebaMultipoleForceKernel() { CudaCalcAmoebaMultipoleForceKernel::~CudaCalcAmoebaMultipoleForceKernel() {
...@@ -907,6 +909,58 @@ CudaCalcAmoebaMultipoleForceKernel::~CudaCalcAmoebaMultipoleForceKernel() { ...@@ -907,6 +909,58 @@ CudaCalcAmoebaMultipoleForceKernel::~CudaCalcAmoebaMultipoleForceKernel() {
delete covalentFlags; delete covalentFlags;
if (polarizationGroupFlags != NULL) if (polarizationGroupFlags != NULL)
delete polarizationGroupFlags; delete polarizationGroupFlags;
if (pmeGrid != NULL)
delete pmeGrid;
if (pmeBsplineModuliX != NULL)
delete pmeBsplineModuliX;
if (pmeBsplineModuliY != NULL)
delete pmeBsplineModuliY;
if (pmeBsplineModuliZ != NULL)
delete pmeBsplineModuliZ;
if (pmeTheta1 != NULL)
delete pmeTheta1;
if (pmeTheta2 != NULL)
delete pmeTheta2;
if (pmeTheta3 != NULL)
delete pmeTheta3;
if (pmeIgrid != NULL)
delete pmeIgrid;
if (pmePhi != NULL)
delete pmePhi;
if (pmePhid != NULL)
delete pmePhid;
if (pmePhip != NULL)
delete pmePhip;
if (pmePhidp != NULL)
delete pmePhidp;
if (pmeAtomRange != NULL)
delete pmeAtomRange;
if (pmeAtomGridIndex != NULL)
delete pmeAtomGridIndex;
if (sort != NULL)
delete sort;
if (hasInitializedFFT)
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) { void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const AmoebaMultipoleForce& force) {
...@@ -969,7 +1023,7 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const ...@@ -969,7 +1023,7 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const
int elementSize = (cu.getUseDoublePrecision() ? sizeof(double) : sizeof(float)); int elementSize = (cu.getUseDoublePrecision() ? sizeof(double) : sizeof(float));
labFrameDipoles = new CudaArray(cu, 3*paddedNumAtoms, elementSize, "labFrameDipoles"); labFrameDipoles = new CudaArray(cu, 3*paddedNumAtoms, elementSize, "labFrameDipoles");
labFrameQuadrupoles = new CudaArray(cu, 5*paddedNumAtoms, elementSize, "labFrameQuadrupoles"); labFrameQuadrupoles = new CudaArray(cu, 9*paddedNumAtoms, elementSize, "labFrameQuadrupoles");
field = new CudaArray(cu, 3*paddedNumAtoms, sizeof(long long), "field"); field = new CudaArray(cu, 3*paddedNumAtoms, sizeof(long long), "field");
fieldPolar = new CudaArray(cu, 3*paddedNumAtoms, sizeof(long long), "fieldPolar"); fieldPolar = new CudaArray(cu, 3*paddedNumAtoms, sizeof(long long), "fieldPolar");
torque = new CudaArray(cu, 3*paddedNumAtoms, sizeof(long long), "torque"); torque = new CudaArray(cu, 3*paddedNumAtoms, sizeof(long long), "torque");
...@@ -1019,12 +1073,10 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const ...@@ -1019,12 +1073,10 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const
} }
else else
maxInducedIterations = 0; maxInducedIterations = 0;
bool usePME = (force.getNonbondedMethod() == AmoebaMultipoleForce::PME);
// Create the kernels. // Create the kernels.
// Create the other kernels.
map<string, string> defines; map<string, string> defines;
defines["NUM_ATOMS"] = cu.intToString(numMultipoles); defines["NUM_ATOMS"] = cu.intToString(numMultipoles);
defines["PADDED_NUM_ATOMS"] = cu.intToString(cu.getPaddedNumAtoms()); defines["PADDED_NUM_ATOMS"] = cu.intToString(cu.getPaddedNumAtoms());
...@@ -1033,6 +1085,32 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const ...@@ -1033,6 +1085,32 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const
defines["ENERGY_SCALE_FACTOR"] = cu.doubleToString(138.9354558456); // DIVIDE BY INNER DIELECTRIC!!! defines["ENERGY_SCALE_FACTOR"] = cu.doubleToString(138.9354558456); // DIVIDE BY INNER DIELECTRIC!!!
if (force.getPolarizationType() == AmoebaMultipoleForce::Direct) if (force.getPolarizationType() == AmoebaMultipoleForce::Direct)
defines["DIRECT_POLARIZATION"] = ""; defines["DIRECT_POLARIZATION"] = "";
double alpha;
int gridSizeX, gridSizeY, gridSizeZ;
if (usePME) {
vector<int> pmeGridDimension;
force.getPmeGridDimensions(pmeGridDimension);
if (pmeGridDimension[0] == 0 || alpha == 0.0) {
NonbondedForce nb;
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);
} else {
alpha = force.getAEwald();
gridSizeX = pmeGridDimension[0];
gridSizeY = pmeGridDimension[1];
gridSizeZ = pmeGridDimension[2];
}
defines["EWALD_ALPHA"] = cu.doubleToString(alpha);
defines["SQRT_PI"] = cu.doubleToString(sqrt(M_PI));
defines["USE_EWALD"] = "";
defines["USE_CUTOFF"] = "";
defines["USE_PERIODIC"] = "";
defines["CUTOFF_SQUARED"] = cu.doubleToString(force.getCutoffDistance()*force.getCutoffDistance());
}
CUmodule module = cu.createModule(CudaKernelSources::vectorOps+CudaAmoebaKernelSources::multipoles, defines); CUmodule module = cu.createModule(CudaKernelSources::vectorOps+CudaAmoebaKernelSources::multipoles, defines);
computeMomentsKernel = cu.getKernel(module, "computeLabFrameMoments"); computeMomentsKernel = cu.getKernel(module, "computeLabFrameMoments");
recordInducedDipolesKernel = cu.getKernel(module, "recordInducedDipoles"); recordInducedDipolesKernel = cu.getKernel(module, "recordInducedDipoles");
...@@ -1045,323 +1123,181 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const ...@@ -1045,323 +1123,181 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const
updateInducedFieldKernel = cu.getKernel(module, "updateInducedFieldBySOR"); updateInducedFieldKernel = cu.getKernel(module, "updateInducedFieldBySOR");
} }
stringstream electrostaticsSource; stringstream electrostaticsSource;
electrostaticsSource << CudaKernelSources::vectorOps; if (usePME) {
electrostaticsSource << CudaAmoebaKernelSources::multipoleElectrostatics; electrostaticsSource << CudaKernelSources::vectorOps;
electrostaticsSource << "#define F1\n"; electrostaticsSource << CudaAmoebaKernelSources::pmeMultipoleElectrostatics;
electrostaticsSource << CudaAmoebaKernelSources::electrostaticPairForce; electrostaticsSource << CudaAmoebaKernelSources::pmeElectrostaticPairForce;
electrostaticsSource << "#undef F1\n"; }
electrostaticsSource << "#define T1\n"; else {
electrostaticsSource << CudaAmoebaKernelSources::electrostaticPairForce; electrostaticsSource << CudaKernelSources::vectorOps;
electrostaticsSource << "#undef T1\n"; electrostaticsSource << CudaAmoebaKernelSources::multipoleElectrostatics;
electrostaticsSource << "#define T2\n"; electrostaticsSource << "#define F1\n";
electrostaticsSource << CudaAmoebaKernelSources::electrostaticPairForce; electrostaticsSource << CudaAmoebaKernelSources::electrostaticPairForce;
electrostaticsSource << "#undef F1\n";
electrostaticsSource << "#define T1\n";
electrostaticsSource << CudaAmoebaKernelSources::electrostaticPairForce;
electrostaticsSource << "#undef T1\n";
electrostaticsSource << "#define T2\n";
electrostaticsSource << CudaAmoebaKernelSources::electrostaticPairForce;
}
module = cu.createModule(electrostaticsSource.str(), defines); module = cu.createModule(electrostaticsSource.str(), defines);
electrostaticsKernel = cu.getKernel(module, "computeElectrostatics"); electrostaticsKernel = cu.getKernel(module, "computeElectrostatics");
// Set up PME. // Set up PME.
bool usePME = (force.getNonbondedMethod() == AmoebaMultipoleForce::PME); if (usePME) {
// map<string, string> defines; // Create the PME kernels.
// alpha = 0;
// if (usePME) { map<string, string> pmeDefines;
// // Compute the PME parameters. pmeDefines["EWALD_ALPHA"] = cu.doubleToString(alpha);
// pmeDefines["PME_ORDER"] = cu.intToString(PmeOrder);
// int gridSizeX, gridSizeY, gridSizeZ; pmeDefines["NUM_ATOMS"] = cu.intToString(numMultipoles);
// NonbondedForceImpl::calcPMEParameters(system, force, alpha, gridSizeX, gridSizeY, gridSizeZ); pmeDefines["PADDED_NUM_ATOMS"] = cu.intToString(cu.getPaddedNumAtoms());
// gridSizeX = findFFTDimension(gridSizeX); pmeDefines["EPSILON_FACTOR"] = cu.doubleToString(138.9354558456);
// gridSizeY = findFFTDimension(gridSizeY);
// gridSizeZ = findFFTDimension(gridSizeZ);
// defines["EWALD_ALPHA"] = cu.doubleToString(alpha);
// defines["TWO_OVER_SQRT_PI"] = cu.doubleToString(2.0/sqrt(M_PI));
// defines["USE_EWALD"] = "1";
// pmeDefines["PME_ORDER"] = cu.intToString(PmeOrder);
// pmeDefines["NUM_ATOMS"] = cu.intToString(numMultipoles);
// pmeDefines["PADDED_NUM_ATOMS"] = cu.intToString(cu.getPaddedNumAtoms());
// pmeDefines["RECIP_EXP_FACTOR"] = cu.doubleToString(M_PI*M_PI/(alpha*alpha)); // pmeDefines["RECIP_EXP_FACTOR"] = cu.doubleToString(M_PI*M_PI/(alpha*alpha));
// pmeDefines["GRID_SIZE_X"] = cu.intToString(gridSizeX); pmeDefines["GRID_SIZE_X"] = cu.intToString(gridSizeX);
// pmeDefines["GRID_SIZE_Y"] = cu.intToString(gridSizeY); pmeDefines["GRID_SIZE_Y"] = cu.intToString(gridSizeY);
// pmeDefines["GRID_SIZE_Z"] = cu.intToString(gridSizeZ); pmeDefines["GRID_SIZE_Z"] = cu.intToString(gridSizeZ);
// pmeDefines["EPSILON_FACTOR"] = cu.doubleToString(sqrt(ONE_4PI_EPS0)); // pmeDefines["EPSILON_FACTOR"] = cu.doubleToString(sqrt(ONE_4PI_EPS0));
// pmeDefines["M_PI"] = cu.doubleToString(M_PI); pmeDefines["M_PI"] = cu.doubleToString(M_PI);
// if (cu.getUseDoublePrecision()) // if (cu.getUseDoublePrecision())
// pmeDefines["USE_DOUBLE_PRECISION"] = "1"; // pmeDefines["USE_DOUBLE_PRECISION"] = "1";
// CUmodule module = cu.createModule(CudaKernelSources::vectorOps+CudaKernelSources::pme, pmeDefines); CUmodule module = cu.createModule(CudaKernelSources::vectorOps+CudaAmoebaKernelSources::multipolePme, pmeDefines);
// pmeUpdateBsplinesKernel = cu.getKernel(module, "updateBsplines"); pmeUpdateBsplinesKernel = cu.getKernel(module, "updateBsplines");
// pmeAtomRangeKernel = cu.getKernel(module, "findAtomRangeForGrid"); pmeAtomRangeKernel = cu.getKernel(module, "findAtomRangeForGrid");
// pmeSpreadChargeKernel = cu.getKernel(module, "gridSpreadCharge"); pmeSpreadFixedMultipolesKernel = cu.getKernel(module, "gridSpreadFixedMultipoles");
// pmeConvolutionKernel = cu.getKernel(module, "reciprocalConvolution"); pmeConvolutionKernel = cu.getKernel(module, "reciprocalConvolution");
pmeFixedPotentialKernel = cu.getKernel(module, "computeFixedPotentialFromGrid");
pmeFixedForceKernel = cu.getKernel(module, "computeFixedMultipoleForceAndEnergy");
// pmeInterpolateForceKernel = cu.getKernel(module, "gridInterpolateForce"); // pmeInterpolateForceKernel = cu.getKernel(module, "gridInterpolateForce");
// pmeFinishSpreadChargeKernel = cu.getKernel(module, "finishSpreadCharge"); // pmeFinishSpreadChargeKernel = cu.getKernel(module, "finishSpreadCharge");
// cuFuncSetCacheConfig(pmeInterpolateForceKernel, CU_FUNC_CACHE_PREFER_L1); // cuFuncSetCacheConfig(pmeInterpolateForceKernel, CU_FUNC_CACHE_PREFER_L1);
//
// // Create required data structures. // Create required data structures.
//
// int elementSize = (cu.getUseDoublePrecision() ? sizeof(double) : sizeof(float)); int elementSize = (cu.getUseDoublePrecision() ? sizeof(double) : sizeof(float));
// pmeGrid = new CudaArray(cu, gridSizeX*gridSizeY*gridSizeZ, 2*elementSize, "pmeGrid"); pmeGrid = new CudaArray(cu, gridSizeX*gridSizeY*gridSizeZ, 2*elementSize, "pmeGrid");
// cu.addAutoclearBuffer(*pmeGrid); cu.addAutoclearBuffer(*pmeGrid);
// pmeBsplineModuliX = new CudaArray(cu, gridSizeX, elementSize, "pmeBsplineModuliX"); pmeBsplineModuliX = new CudaArray(cu, gridSizeX, elementSize, "pmeBsplineModuliX");
// pmeBsplineModuliY = new CudaArray(cu, gridSizeY, elementSize, "pmeBsplineModuliY"); pmeBsplineModuliY = new CudaArray(cu, gridSizeY, elementSize, "pmeBsplineModuliY");
// pmeBsplineModuliZ = new CudaArray(cu, gridSizeZ, elementSize, "pmeBsplineModuliZ"); pmeBsplineModuliZ = new CudaArray(cu, gridSizeZ, elementSize, "pmeBsplineModuliZ");
// pmeBsplineTheta = new CudaArray(cu, PmeOrder*numMultipoles, 4*elementSize, "pmeBsplineTheta"); pmeTheta1 = new CudaArray(cu, PmeOrder*numMultipoles, 4*elementSize, "pmeTheta1");
// pmeAtomRange = CudaArray::create<int>(cu, gridSizeX*gridSizeY*gridSizeZ+1, "pmeAtomRange"); pmeTheta2 = new CudaArray(cu, PmeOrder*numMultipoles, 4*elementSize, "pmeTheta2");
// pmeAtomGridIndex = CudaArray::create<int2>(cu, numMultipoles, "pmeAtomGridIndex"); pmeTheta3 = new CudaArray(cu, PmeOrder*numMultipoles, 4*elementSize, "pmeTheta3");
// sort = new CudaSort(cu, new SortTrait(), cu.getNumAtoms()); pmeIgrid = CudaArray::create<int4>(cu, numMultipoles, "pmeIgrid");
// cufftResult result = cufftPlan3d(&fft, gridSizeX, gridSizeY, gridSizeZ, cu.getUseDoublePrecision() ? CUFFT_Z2Z : CUFFT_C2C); pmePhi = new CudaArray(cu, 20*numMultipoles, elementSize, "pmePhi");
// if (result != CUFFT_SUCCESS) pmePhid = new CudaArray(cu, 10*numMultipoles, elementSize, "pmePhid");
// throw OpenMMException("Error initializing FFT: "+cu.intToString(result)); pmePhip = new CudaArray(cu, 10*numMultipoles, elementSize, "pmePhip");
// hasInitializedFFT = true; pmePhidp = new CudaArray(cu, 20*numMultipoles, elementSize, "pmePhidp");
// pmeAtomRange = CudaArray::create<int>(cu, gridSizeX*gridSizeY*gridSizeZ+1, "pmeAtomRange");
// // Initialize the b-spline moduli. pmeAtomGridIndex = CudaArray::create<int2>(cu, numMultipoles, "pmeAtomGridIndex");
// sort = new CudaSort(cu, new SortTrait(), cu.getNumAtoms());
// int maxSize = max(max(gridSizeX, gridSizeY), gridSizeZ); cufftResult result = cufftPlan3d(&fft, gridSizeX, gridSizeY, gridSizeZ, cu.getUseDoublePrecision() ? CUFFT_Z2Z : CUFFT_C2C);
// vector<double> data(PmeOrder); if (result != CUFFT_SUCCESS)
// vector<double> ddata(PmeOrder); throw OpenMMException("Error initializing FFT: "+cu.intToString(result));
// vector<double> bsplines_data(maxSize); hasInitializedFFT = true;
// data[PmeOrder-1] = 0.0;
// data[1] = 0.0; // Initialize the b-spline moduli.
// data[0] = 1.0;
// for (int i = 3; i < PmeOrder; i++) { double data[PmeOrder];
// double div = 1.0/(i-1.0); double x = 0.0;
// data[i-1] = 0.0; data[0] = 1.0 - x;
// for (int j = 1; j < (i-1); j++) data[1] = x;
// data[i-j-1] = div*(j*data[i-j-2]+(i-j)*data[i-j-1]); for (int i = 2; i < PmeOrder; i++) {
// data[0] = div*data[0]; double denom = 1.0/i;
// } data[i] = x*data[i-1]*denom;
// for (int j = 1; j < i; j++)
// // Differentiate. data[i-j] = ((x+j)*data[i-j-1] + ((i-j+1)-x)*data[i-j])*denom;
// data[0] = (1.0-x)*data[0]*denom;
// ddata[0] = -data[0]; }
// for (int i = 1; i < PmeOrder; i++) int maxSize = max(max(gridSizeX, gridSizeY), gridSizeZ);
// ddata[i] = data[i-1]-data[i]; vector<double> bsplines_data(maxSize+1, 0.0);
// double div = 1.0/(PmeOrder-1); for (int i = 2; i <= PmeOrder+1; i++)
// data[PmeOrder-1] = 0.0; bsplines_data[i] = data[i-2];
// for (int i = 1; i < (PmeOrder-1); i++) for (int dim = 0; dim < 3; dim++) {
// data[PmeOrder-i-1] = div*(i*data[PmeOrder-i-2]+(PmeOrder-i)*data[PmeOrder-i-1]); int ndata = (dim == 0 ? gridSizeX : dim == 1 ? gridSizeY : gridSizeZ);
// data[0] = div*data[0]; vector<double> moduli(ndata);
// for (int i = 0; i < maxSize; i++)
// bsplines_data[i] = 0.0; // get the modulus of the discrete Fourier transform
// for (int i = 1; i <= PmeOrder; i++)
// bsplines_data[i] = data[i-1]; double factor = 2.0*M_PI/ndata;
// for (int i = 0; i < ndata; i++) {
// // Evaluate the actual bspline moduli for X/Y/Z. double sc = 0.0;
// double ss = 0.0;
// for(int dim = 0; dim < 3; dim++) { for (int j = 1; j <= ndata; j++) {
// int ndata = (dim == 0 ? gridSizeX : dim == 1 ? gridSizeY : gridSizeZ); double arg = factor*i*(j-1);
// vector<double> moduli(ndata); sc += bsplines_data[j]*cos(arg);
// for (int i = 0; i < ndata; i++) { ss += bsplines_data[j]*sin(arg);
// double sc = 0.0; }
// double ss = 0.0; moduli[i] = sc*sc+ss*ss;
// for (int j = 0; j < ndata; j++) { }
// double arg = (2.0*M_PI*i*j)/ndata;
// sc += bsplines_data[j]*cos(arg); // Fix for exponential Euler spline interpolation failure.
// ss += bsplines_data[j]*sin(arg);
// } double eps = 1.0e-7;
// moduli[i] = sc*sc+ss*ss; if (moduli[0] < eps)
// } moduli[0] = 0.9*moduli[1];
// for (int i = 0; i < ndata; i++) for (int i = 1; i < ndata-1; i++)
// if (moduli[i] < 1.0e-7) if (moduli[i] < eps)
// moduli[i] = (moduli[i-1]+moduli[i+1])*0.5; moduli[i] = 0.9*(moduli[i-1]+moduli[i+1]);
// if (cu.getUseDoublePrecision()) { if (moduli[ndata-1] < eps)
// if (dim == 0) moduli[ndata-1] = 0.9*moduli[ndata-2];
// pmeBsplineModuliX->upload(moduli);
// else if (dim == 1) // Compute and apply the optimal zeta coefficient.
// pmeBsplineModuliY->upload(moduli);
// else int jcut = 50;
// pmeBsplineModuliZ->upload(moduli); for (int i = 1; i <= ndata; i++) {
// } int k = i - 1;
// else { if (i > ndata/2)
// vector<float> modulif(ndata); k = k - ndata;
// for (int i = 0; i < ndata; i++) double zeta;
// modulif[i] = (float) moduli[i]; if (k == 0)
// if (dim == 0) zeta = 1.0;
// pmeBsplineModuliX->upload(modulif); else {
// else if (dim == 1) double sum1 = 1.0;
// pmeBsplineModuliY->upload(modulif); double sum2 = 1.0;
// else factor = M_PI*k/ndata;
// pmeBsplineModuliZ->upload(modulif); for (int j = 1; j <= jcut; j++) {
// } double arg = factor/(factor+M_PI*j);
// } sum1 += pow(arg, PmeOrder);
// } sum2 += pow(arg, 2*PmeOrder);
}
for (int j = 1; j <= jcut; j++) {
double arg = factor/(factor-M_PI*j);
sum1 += pow(arg, PmeOrder);
sum2 += pow(arg, 2*PmeOrder);
}
zeta = sum2/sum1;
}
moduli[i-1] = moduli[i-1]*zeta*zeta;
}
if (cu.getUseDoublePrecision()) {
if (dim == 0)
pmeBsplineModuliX->upload(moduli);
else if (dim == 1)
pmeBsplineModuliY->upload(moduli);
else
pmeBsplineModuliZ->upload(moduli);
}
else {
vector<float> modulif(ndata);
for (int i = 0; i < ndata; i++)
modulif[i] = (float) moduli[i];
if (dim == 0)
pmeBsplineModuliX->upload(modulif);
else if (dim == 1)
pmeBsplineModuliY->upload(modulif);
else
pmeBsplineModuliZ->upload(modulif);
}
}
}
// Add an interaction to the default nonbonded kernel. This doesn't actually do any calculations. It's // Add an interaction to the default nonbonded kernel. This doesn't actually do any calculations. It's
// just so that CudaNonbondedUtilities will build the exclusion flags and maintain the neighbor list. // just so that CudaNonbondedUtilities will build the exclusion flags and maintain the neighbor list.
cu.getNonbondedUtilities().addInteraction(usePME, usePME, true, force.getCutoffDistance(), exclusions, "", force.getForceGroup()); cu.getNonbondedUtilities().addInteraction(usePME, usePME, true, force.getCutoffDistance(), exclusions, "", force.getForceGroup());
cu.addForce(new ForceInfo(force)); cu.addForce(new ForceInfo(force));
// numMultipoles = force.getNumMultipoles();
//
// data.setHasAmoebaMultipole( true );
//
// std::vector<float> charges(numMultipoles);
// std::vector<float> dipoles(3*numMultipoles);
// std::vector<float> quadrupoles(9*numMultipoles);
// std::vector<float> tholes(numMultipoles);
// std::vector<float> dampingFactors(numMultipoles);
// std::vector<float> polarity(numMultipoles);
// std::vector<int> axisTypes(numMultipoles);
// std::vector<int> multipoleAtomZs(numMultipoles);
// std::vector<int> multipoleAtomXs(numMultipoles);
// std::vector<int> multipoleAtomYs(numMultipoles);
// std::vector< std::vector< std::vector<int> > > multipoleAtomCovalentInfo(numMultipoles);
// std::vector<int> minCovalentIndices(numMultipoles);
// std::vector<int> minCovalentPolarizationIndices(numMultipoles);
//
// //float scalingDistanceCutoff = static_cast<float>(force.getScalingDistanceCutoff());
// float scalingDistanceCutoff = 50.0f;
//
// std::vector<AmoebaMultipoleForce::CovalentType> covalentList;
// covalentList.push_back( AmoebaMultipoleForce::Covalent12 );
// covalentList.push_back( AmoebaMultipoleForce::Covalent13 );
// covalentList.push_back( AmoebaMultipoleForce::Covalent14 );
// covalentList.push_back( AmoebaMultipoleForce::Covalent15 );
//
// std::vector<AmoebaMultipoleForce::CovalentType> polarizationCovalentList;
// polarizationCovalentList.push_back( AmoebaMultipoleForce::PolarizationCovalent11 );
// polarizationCovalentList.push_back( AmoebaMultipoleForce::PolarizationCovalent12 );
// polarizationCovalentList.push_back( AmoebaMultipoleForce::PolarizationCovalent13 );
// polarizationCovalentList.push_back( AmoebaMultipoleForce::PolarizationCovalent14 );
//
// std::vector<int> covalentDegree;
// AmoebaMultipoleForceImpl::getCovalentDegree( force, covalentDegree );
// int dipoleIndex = 0;
// int quadrupoleIndex = 0;
// int maxCovalentRange = 0;
// double totalCharge = 0.0;
// for (int i = 0; i < numMultipoles; i++) {
//
// // multipoles
//
// int axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY;
// double charge, tholeD, dampingFactorD, polarityD;
// std::vector<double> dipolesD;
// std::vector<double> quadrupolesD;
// force.getMultipoleParameters(i, charge, dipolesD, quadrupolesD, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY,
// tholeD, dampingFactorD, polarityD );
//
// totalCharge += charge;
// axisTypes[i] = axisType;
// multipoleAtomZs[i] = multipoleAtomZ;
// multipoleAtomXs[i] = multipoleAtomX;
// multipoleAtomYs[i] = multipoleAtomY;
//
// charges[i] = static_cast<float>(charge);
// tholes[i] = static_cast<float>(tholeD);
// dampingFactors[i] = static_cast<float>(dampingFactorD);
// polarity[i] = static_cast<float>(polarityD);
//
// dipoles[dipoleIndex++] = static_cast<float>(dipolesD[0]);
// dipoles[dipoleIndex++] = static_cast<float>(dipolesD[1]);
// dipoles[dipoleIndex++] = static_cast<float>(dipolesD[2]);
//
// quadrupoles[quadrupoleIndex++] = static_cast<float>(quadrupolesD[0]);
// quadrupoles[quadrupoleIndex++] = static_cast<float>(quadrupolesD[1]);
// quadrupoles[quadrupoleIndex++] = static_cast<float>(quadrupolesD[2]);
// quadrupoles[quadrupoleIndex++] = static_cast<float>(quadrupolesD[3]);
// quadrupoles[quadrupoleIndex++] = static_cast<float>(quadrupolesD[4]);
// quadrupoles[quadrupoleIndex++] = static_cast<float>(quadrupolesD[5]);
// quadrupoles[quadrupoleIndex++] = static_cast<float>(quadrupolesD[6]);
// quadrupoles[quadrupoleIndex++] = static_cast<float>(quadrupolesD[7]);
// quadrupoles[quadrupoleIndex++] = static_cast<float>(quadrupolesD[8]);
//
// // covalent info
//
// std::vector< std::vector<int> > covalentLists;
// force.getCovalentMaps(i, covalentLists );
// multipoleAtomCovalentInfo[i] = covalentLists;
//
// int minCovalentIndex, maxCovalentIndex;
// AmoebaMultipoleForceImpl::getCovalentRange( force, i, covalentList, &minCovalentIndex, &maxCovalentIndex );
// minCovalentIndices[i] = minCovalentIndex;
// if( maxCovalentRange < (maxCovalentIndex - minCovalentIndex) ){
// maxCovalentRange = maxCovalentIndex - minCovalentIndex;
// }
//
// AmoebaMultipoleForceImpl::getCovalentRange( force, i, polarizationCovalentList, &minCovalentIndex, &maxCovalentIndex );
// minCovalentPolarizationIndices[i] = minCovalentIndex;
// if( maxCovalentRange < (maxCovalentIndex - minCovalentIndex) ){
// maxCovalentRange = maxCovalentIndex - minCovalentIndex;
// }
// }
//
// int polarizationType = static_cast<int>(force.getPolarizationType());
// int nonbondedMethod = static_cast<int>(force.getNonbondedMethod());
// if( nonbondedMethod != 0 && nonbondedMethod != 1 ){
// throw OpenMMException("AmoebaMultipoleForce nonbonded method not recognized.\n");
// }
//
// if( polarizationType != 0 && polarizationType != 1 ){
// throw OpenMMException("AmoebaMultipoleForce polarization type not recognized.\n");
// }
//
// gpuSetAmoebaMultipoleParameters(data.getAmoebaGpu(), charges, dipoles, quadrupoles, axisTypes, multipoleAtomZs, multipoleAtomXs, multipoleAtomYs,
// tholes, scalingDistanceCutoff, dampingFactors, polarity,
// multipoleAtomCovalentInfo, covalentDegree, minCovalentIndices, minCovalentPolarizationIndices, (maxCovalentRange+2),
// 0, force.getMutualInducedMaxIterations(),
// static_cast<float>( force.getMutualInducedTargetEpsilon()),
// nonbondedMethod, polarizationType,
// static_cast<float>( force.getCutoffDistance()),
// static_cast<float>( force.getAEwald()) );
// if (nonbondedMethod == AmoebaMultipoleForce::PME) {
// double alpha = force.getAEwald();
// int xsize, ysize, zsize;
// NonbondedForce nb;
// nb.setEwaldErrorTolerance(force.getEwaldErrorTolerance());
// nb.setCutoffDistance(force.getCutoffDistance());
// std::vector<int> pmeGridDimension;
// force.getPmeGridDimensions( pmeGridDimension );
// int pmeParametersSetBasedOnEwaldErrorTolerance;
// if( pmeGridDimension[0] == 0 || alpha == 0.0 ){
// NonbondedForceImpl::calcPMEParameters(system, nb, alpha, xsize, ysize, zsize);
// pmeParametersSetBasedOnEwaldErrorTolerance = 1;
// } else {
// alpha = force.getAEwald();
// xsize = pmeGridDimension[0];
// ysize = pmeGridDimension[1];
// zsize = pmeGridDimension[2];
// pmeParametersSetBasedOnEwaldErrorTolerance = 0;
// }
//
// gpuSetAmoebaPMEParameters(data.getAmoebaGpu(), (float) alpha, xsize, ysize, zsize);
//
// if( data.getLog() ){
// (void) fprintf( data.getLog(), "AmoebaMultipoleForce: PME parameters tol=%12.3e cutoff=%12.3f alpha=%12.3f [%d %d %d]\n",
// force.getEwaldErrorTolerance(), force.getCutoffDistance(), alpha, xsize, ysize, zsize );
// if( pmeParametersSetBasedOnEwaldErrorTolerance ){
// (void) fprintf( data.getLog(), "Parameters based on error tolerance and OpenMM algorithm.\n" );
// } else {
// double alphaT;
// int xsizeT, ysizeT, zsizeT;
// NonbondedForceImpl::calcPMEParameters(system, nb, alphaT, xsizeT, ysizeT, zsizeT);
// double impliedTolerance = alpha*force.getCutoffDistance();
// impliedTolerance = 0.5*exp( -(impliedTolerance*impliedTolerance) );
// (void) fprintf( data.getLog(), "Using input parameters implied tolerance=%12.3e;", impliedTolerance );
// (void) fprintf( data.getLog(), "OpenMM param: aEwald=%12.3f [%6d %6d %6d]\n", alphaT, xsizeT, ysizeT, zsizeT);
// }
// (void) fprintf( data.getLog(), "\n" );
// (void) fflush( data.getLog() );
// }
//
// data.setApplyMultipoleCutoff( 1 );
//
// data.cudaPlatformData.nonbondedMethod = PARTICLE_MESH_EWALD;
// amoebaGpuContext amoebaGpu = data.getAmoebaGpu();
// gpuContext gpu = amoebaGpu->gpuContext;
// gpu->sim.nonbondedCutoffSqr = static_cast<float>(force.getCutoffDistance()*force.getCutoffDistance());
// gpu->sim.nonbondedMethod = PARTICLE_MESH_EWALD;
// }
// data.getAmoebaGpu()->gpuContext->forces.push_back(new ForceInfo(force));
} }
void CudaCalcAmoebaMultipoleForceKernel::initializeScaleFactors() { void CudaCalcAmoebaMultipoleForceKernel::initializeScaleFactors() {
...@@ -1437,6 +1373,7 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in ...@@ -1437,6 +1373,7 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in
int numTileIndices = nb.getNumTiles(); int numTileIndices = nb.getNumTiles();
int numForceThreadBlocks = nb.getNumForceThreadBlocks(); int numForceThreadBlocks = nb.getNumForceThreadBlocks();
int forceThreadBlockSize = nb.getForceThreadBlockSize(); int forceThreadBlockSize = nb.getForceThreadBlockSize();
int elementSize = (cu.getUseDoublePrecision() ? sizeof(double) : sizeof(float));
if (pmeGrid == NULL) { if (pmeGrid == NULL) {
// Compute induced dipoles. // Compute induced dipoles.
...@@ -1482,6 +1419,137 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in ...@@ -1482,6 +1419,137 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in
&cu.getPosq().getDevicePointer(), &multipoleParticles->getDevicePointer()}; &cu.getPosq().getDevicePointer(), &multipoleParticles->getDevicePointer()};
cu.executeKernel(mapTorqueKernel, mapTorqueArgs, cu.getNumAtoms()); cu.executeKernel(mapTorqueKernel, mapTorqueArgs, cu.getNumAtoms());
} }
else {
// Compute induced dipoles.
unsigned int maxTiles = nb.getInteractingTiles().getSize();
void* pmeUpdateBsplinesArgs[] = {&cu.getPosq().getDevicePointer(), &pmeIgrid->getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(),
&pmeTheta1->getDevicePointer(), &pmeTheta2->getDevicePointer(), &pmeTheta3->getDevicePointer(), cu.getPeriodicBoxSizePointer(),
cu.getInvPeriodicBoxSizePointer()};
cu.executeKernel(pmeUpdateBsplinesKernel, pmeUpdateBsplinesArgs, cu.getNumAtoms(), cu.ThreadBlockSize, cu.ThreadBlockSize*PmeOrder*PmeOrder*elementSize);
sort->sort(*pmeAtomGridIndex);
void* pmeAtomRangeArgs[] = {&pmeAtomGridIndex->getDevicePointer(), &pmeAtomRange->getDevicePointer(),
&cu.getPosq().getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()};
cu.executeKernel(pmeAtomRangeKernel, pmeAtomRangeArgs, cu.getNumAtoms(), cu.ThreadBlockSize, cu.ThreadBlockSize*PmeOrder*PmeOrder*elementSize);
void* pmeSpreadFixedMultipolesArgs[] = {&cu.getPosq().getDevicePointer(), &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(),
&pmeGrid->getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), &pmeAtomRange->getDevicePointer(),
&pmeTheta1->getDevicePointer(), &pmeTheta2->getDevicePointer(), &pmeTheta3->getDevicePointer(), cu.getPeriodicBoxSizePointer(),
cu.getInvPeriodicBoxSizePointer()};
cu.executeKernel(pmeSpreadFixedMultipolesKernel, pmeSpreadFixedMultipolesArgs, cu.getNumAtoms(), cu.ThreadBlockSize, cu.ThreadBlockSize*PmeOrder*PmeOrder*elementSize);
if (cu.getUseDoublePrecision())
cufftExecZ2Z(fft, (double2*) pmeGrid->getDevicePointer(), (double2*) pmeGrid->getDevicePointer(), CUFFT_FORWARD);
else
cufftExecC2C(fft, (float2*) pmeGrid->getDevicePointer(), (float2*) pmeGrid->getDevicePointer(), CUFFT_FORWARD);
void* pmeConvolutionArgs[] = {&pmeGrid->getDevicePointer(), &pmeBsplineModuliX->getDevicePointer(), &pmeBsplineModuliY->getDevicePointer(),
&pmeBsplineModuliZ->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()};
cu.executeKernel(pmeConvolutionKernel, pmeConvolutionArgs, cu.getNumAtoms());
if (cu.getUseDoublePrecision())
cufftExecZ2Z(fft, (double2*) pmeGrid->getDevicePointer(), (double2*) pmeGrid->getDevicePointer(), CUFFT_INVERSE);
else
cufftExecC2C(fft, (float2*) pmeGrid->getDevicePointer(), (float2*) pmeGrid->getDevicePointer(), CUFFT_INVERSE);
void* pmeFixedPotentialArgs[] = {&pmeGrid->getDevicePointer(), &pmePhi->getDevicePointer(), &field->getDevicePointer(),
&pmeIgrid->getDevicePointer(), &pmeTheta1->getDevicePointer(), &pmeTheta2->getDevicePointer(), &pmeTheta3->getDevicePointer(),
&labFrameDipoles->getDevicePointer(), cu.getInvPeriodicBoxSizePointer()};
cu.executeKernel(pmeFixedPotentialKernel, pmeFixedPotentialArgs, cu.getNumAtoms());
void* pmeFixedForceArgs[] = {&cu.getPosq().getDevicePointer(), &cu.getForce().getDevicePointer(), &torque->getDevicePointer(),
&cu.getEnergyBuffer().getDevicePointer(), &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(),
&pmePhi->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()};
cu.executeKernel(pmeFixedForceKernel, pmeFixedForceArgs, cu.getNumAtoms());
printf("reciprocal:\n");
vector<long long> f;
printf("force\n");
cu.getForce().download(f);
for (int i = 0; i < cu.getNumAtoms(); i++)
printf("%d: %g %g %g\n", i, f[i]/(double) 0xFFFFFFFF, f[i+cu.getPaddedNumAtoms()]/(double) 0xFFFFFFFF, f[i+cu.getPaddedNumAtoms()*2]/(double) 0xFFFFFFFF);
// printf("torque\n");
// torque->download(f);
// for (int i = 0; i < cu.getNumAtoms(); i++)
// printf("%d: %g %g %g\n", i, f[i]/(double) 0xFFFFFFFF, f[i+cu.getPaddedNumAtoms()]/(double) 0xFFFFFFFF, f[i+cu.getPaddedNumAtoms()*2]/(double) 0xFFFFFFFF);
void* computeFixedFieldArgs[] = {&field->getDevicePointer(), &fieldPolar->getDevicePointer(), &cu.getPosq().getDevicePointer(),
&nb.getExclusionIndices().getDevicePointer(), &nb.getExclusionRowIndices().getDevicePointer(),
&covalentFlags->getDevicePointer(), &polarizationGroupFlags->getDevicePointer(), &startTileIndex, &numTileIndices,
&nb.getInteractingTiles().getDevicePointer(), &nb.getInteractionCount().getDevicePointer(), cu.getPeriodicBoxSizePointer(),
cu.getInvPeriodicBoxSizePointer(), &maxTiles, &nb.getInteractionFlags().getDevicePointer(),
&labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), &dampingAndThole->getDevicePointer()};
cu.executeKernel(computeFixedFieldKernel, computeFixedFieldArgs, numForceThreadBlocks*forceThreadBlockSize, forceThreadBlockSize);
void* recordInducedDipolesArgs[] = {&field->getDevicePointer(), &fieldPolar->getDevicePointer(),
&inducedDipole->getDevicePointer(), &inducedDipolePolar->getDevicePointer(), &polarizability->getDevicePointer()};
cu.executeKernel(recordInducedDipolesKernel, recordInducedDipolesArgs, cu.getNumAtoms());
printf("direct:\n");
printf("force\n");
cu.getForce().download(f);
for (int i = 0; i < cu.getNumAtoms(); i++)
printf("%d: %g %g %g\n", i, f[i]/(double) 0xFFFFFFFF, f[i+cu.getPaddedNumAtoms()]/(double) 0xFFFFFFFF, f[i+cu.getPaddedNumAtoms()*2]/(double) 0xFFFFFFFF);
// printf("torque\n");
// torque->download(f);
// for (int i = 0; i < cu.getNumAtoms(); i++)
// printf("%d: %g %g %g\n", i, f[i]/(double) 0xFFFFFFFF, f[i+cu.getPaddedNumAtoms()]/(double) 0xFFFFFFFF, f[i+cu.getPaddedNumAtoms()*2]/(double) 0xFFFFFFFF);
// vector<float> d, dp;
// printf("phi\n");
// pmePhi->download(d);
// for (int i = 0; i < d.size(); i++)
// printf("%d: %g\n", i, d[i]);
// printf("dipoles\n");
// labFrameDipoles->download(d);
// for (int i = 0; i < cu.getNumAtoms(); i++)
// printf("%d: %g %g %g\n", i, d[3*i], d[3*i+1], d[3*i+2]);
// printf("quadrupoles\n");
// labFrameQuadrupoles->download(d);
// for (int i = 0; i < cu.getNumAtoms(); i++)
// printf("%d: %g %g %g %g %g %g\n", i, d[5*i], d[5*i+1], d[5*i+2], d[5*i+3], d[5*i+4], -(d[5*i]+d[5*i+3]));
// printf("induced dipoles\n");
// inducedDipole->download(d);
// inducedDipolePolar->download(dp);
// for (int i = 0; i < cu.getNumAtoms(); i++)
// printf("%d: %g %g %g, %g %g %g\n", i, d[3*i], d[3*i+1], d[3*i+2], dp[3*i], dp[3*i+1], dp[3*i+2]);
// printf("positions\n");
// vector<float4> p;
// cu.getPosq().download(p);
// for (int i = 0; i < cu.getNumAtoms(); i++)
// printf("%d: %g %g %g %g\n", i, p[i].x, p[i].y, p[i].z, p[i].w);
// vector<float2> errors;
// for (int i = 0; i < maxInducedIterations; i++) {
// cu.clearBuffer(*inducedField);
// cu.clearBuffer(*inducedFieldPolar);
// void* computeInducedFieldArgs[] = {&inducedField->getDevicePointer(), &inducedFieldPolar->getDevicePointer(), &cu.getPosq().getDevicePointer(),
// &inducedDipole->getDevicePointer(), &inducedDipolePolar->getDevicePointer(), &startTileIndex, &numTileIndices,
// &dampingAndThole->getDevicePointer()};
// cu.executeKernel(computeInducedFieldKernel, computeInducedFieldArgs, numForceThreadBlocks*forceThreadBlockSize, forceThreadBlockSize);
// void* updateInducedFieldArgs[] = {&field->getDevicePointer(), &fieldPolar->getDevicePointer(), &inducedField->getDevicePointer(),
// &inducedFieldPolar->getDevicePointer(), &inducedDipole->getDevicePointer(), &inducedDipolePolar->getDevicePointer(),
// &polarizability->getDevicePointer(), &inducedDipoleErrors->getDevicePointer()};
// cu.executeKernel(updateInducedFieldKernel, updateInducedFieldArgs, cu.getNumThreadBlocks()*cu.ThreadBlockSize);
// inducedDipoleErrors->download(errors);
// double total1 = 0.0, total2 = 0.0;
// for (int j = 0; j < (int) errors.size(); j++) {
// total1 += errors[j].x;
// total2 += errors[j].y;
// }
// if (48.033324*sqrt(max(total1, total2)/cu.getNumAtoms()) < inducedEpsilon)
// break;
// }
// Compute electrostatic force.
void* electrostaticsArgs[] = {&cu.getForce().getDevicePointer(), &torque->getDevicePointer(), &cu.getEnergyBuffer().getDevicePointer(),
&cu.getPosq().getDevicePointer(), &nb.getExclusionIndices().getDevicePointer(), &nb.getExclusionRowIndices().getDevicePointer(),
&covalentFlags->getDevicePointer(), &polarizationGroupFlags->getDevicePointer(), &startTileIndex, &numTileIndices,
&nb.getInteractingTiles().getDevicePointer(), &nb.getInteractionCount().getDevicePointer(),
cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), &maxTiles, &nb.getInteractionFlags().getDevicePointer(),
&labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), &inducedDipole->getDevicePointer(),
&inducedDipolePolar->getDevicePointer(), &dampingAndThole->getDevicePointer()};
cu.executeKernel(electrostaticsKernel, electrostaticsArgs, numForceThreadBlocks*forceThreadBlockSize, forceThreadBlockSize);
printf("electrostatic:\n");
printf("force\n");
cu.getForce().download(f);
for (int i = 0; i < cu.getNumAtoms(); i++)
printf("%d: %g %g %g\n", i, f[i]/(double) 0xFFFFFFFF, f[i+cu.getPaddedNumAtoms()]/(double) 0xFFFFFFFF, f[i+cu.getPaddedNumAtoms()*2]/(double) 0xFFFFFFFF);
void* mapTorqueArgs[] = {&cu.getForce().getDevicePointer(), &torque->getDevicePointer(),
&cu.getPosq().getDevicePointer(), &multipoleParticles->getDevicePointer()};
cu.executeKernel(mapTorqueKernel, mapTorqueArgs, cu.getNumAtoms());
}
return 0.0; return 0.0;
} }
...@@ -1644,6 +1712,10 @@ void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const Amoeba ...@@ -1644,6 +1712,10 @@ void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const Amoeba
sigmaEpsilon->upload(sigmaEpsilonVec); sigmaEpsilon->upload(sigmaEpsilonVec);
bondReductionAtoms->upload(bondReductionAtomsVec); bondReductionAtoms->upload(bondReductionAtomsVec);
bondReductionFactors->upload(bondReductionFactorsVec); bondReductionFactors->upload(bondReductionFactorsVec);
if (force.getUseDispersionCorrection())
dispersionCoefficient = AmoebaVdwForceImpl::calcDispersionCorrection(system, force);
else
dispersionCoefficient = 0.0;
// This force is applied based on modified atom positions, where hydrogens have been moved slightly // This force is applied based on modified atom positions, where hydrogens have been moved slightly
// closer to their parent atoms. We therefore create a separate CudaNonbondedUtilities just for // closer to their parent atoms. We therefore create a separate CudaNonbondedUtilities just for
...@@ -1711,7 +1783,8 @@ double CudaCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool includeF ...@@ -1711,7 +1783,8 @@ double CudaCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool includeF
cu.executeKernel(spreadKernel, spreadArgs, cu.getPaddedNumAtoms()); cu.executeKernel(spreadKernel, spreadArgs, cu.getPaddedNumAtoms());
tempPosq->copyTo(cu.getPosq()); tempPosq->copyTo(cu.getPosq());
tempForces->copyTo(cu.getForce()); tempForces->copyTo(cu.getForce());
return 0.0; double4 box = cu.getPeriodicBoxSize();
return dispersionCoefficient/(box.x*box.y*box.z);
} }
///* -------------------------------------------------------------------------- * ///* -------------------------------------------------------------------------- *
......
...@@ -373,10 +373,20 @@ public: ...@@ -373,10 +373,20 @@ public:
private: private:
class ForceInfo; class ForceInfo;
class SortTrait : public CudaSort::SortTrait {
int getDataSize() const {return 8;}
int getKeySize() const {return 4;}
const char* getDataType() const {return "int2";}
const char* getKeyType() const {return "int";}
const char* getMinKey() const {return "INT_MIN";}
const char* getMaxKey() const {return "INT_MAX";}
const char* getMaxValue() const {return "make_int2(INT_MAX, INT_MAX)";}
const char* getSortKey() const {return "value.y";}
};
void initializeScaleFactors(); void initializeScaleFactors();
int numMultipoles, maxInducedIterations; int numMultipoles, maxInducedIterations;
double inducedEpsilon; double inducedEpsilon;
bool hasInitializedScaleFactors; bool hasInitializedScaleFactors, hasInitializedFFT;
CudaContext& cu; CudaContext& cu;
System& system; System& system;
std::vector<int3> covalentFlagValues; std::vector<int3> covalentFlagValues;
...@@ -404,18 +414,19 @@ private: ...@@ -404,18 +414,19 @@ private:
CudaArray* pmeBsplineModuliZ; CudaArray* pmeBsplineModuliZ;
CudaArray* pmeTheta1; CudaArray* pmeTheta1;
CudaArray* pmeTheta2; CudaArray* pmeTheta2;
CudaArray* pmeTheta3;
CudaArray* pmeIgrid; CudaArray* pmeIgrid;
CudaArray* pmePhi; CudaArray* pmePhi;
CudaArray* pmePhid; CudaArray* pmePhid;
CudaArray* pmePhip; CudaArray* pmePhip;
CudaArray* pmePhidp; CudaArray* pmePhidp;
CudaArray* pmeBsplineTheta;
CudaArray* pmeBsplineDTheta;
CudaArray* pmeAtomRange; CudaArray* pmeAtomRange;
CudaArray* pmeAtomGridIndex; CudaArray* pmeAtomGridIndex;
CudaSort* sort; CudaSort* sort;
cufftHandle fft; cufftHandle fft;
CUfunction computeMomentsKernel, recordInducedDipolesKernel, computeFixedFieldKernel, computeInducedFieldKernel, updateInducedFieldKernel, electrostaticsKernel, mapTorqueKernel; CUfunction computeMomentsKernel, recordInducedDipolesKernel, computeFixedFieldKernel, computeInducedFieldKernel, updateInducedFieldKernel, electrostaticsKernel, mapTorqueKernel;
CUfunction pmeUpdateBsplinesKernel, pmeAtomRangeKernel, pmeSpreadFixedMultipolesKernel, pmeConvolutionKernel, pmeFixedPotentialKernel, pmeFixedForceKernel;
static const int PmeOrder = 5;
}; };
/** /**
...@@ -475,6 +486,7 @@ private: ...@@ -475,6 +486,7 @@ private:
CudaContext& cu; CudaContext& cu;
System& system; System& system;
bool hasInitializedNonbonded; bool hasInitializedNonbonded;
double dispersionCoefficient;
CudaArray* sigmaEpsilon; CudaArray* sigmaEpsilon;
CudaArray* bondReductionAtoms; CudaArray* bondReductionAtoms;
CudaArray* bondReductionFactors; CudaArray* bondReductionFactors;
......
...@@ -205,64 +205,114 @@ extern "C" __global__ void computeElectrostatics( ...@@ -205,64 +205,114 @@ extern "C" __global__ void computeElectrostatics(
for (j = 0; j < TILE_SIZE; j++) { for (j = 0; j < TILE_SIZE; j++) {
if ((flags&(1<<j)) != 0) { if ((flags&(1<<j)) != 0) {
int atom2 = tbx+j; int atom2 = tbx+j;
int bufferIndex = 3*threadIdx.x;
real3 dEdR1 = make_real3(0);
real3 dEdR2 = make_real3(0);
real3 delta = make_real3(localData[atom2].posq.x-data.posq.x, localData[atom2].posq.y-data.posq.y, localData[atom2].posq.z-data.posq.z); real3 delta = make_real3(localData[atom2].posq.x-data.posq.x, localData[atom2].posq.y-data.posq.y, localData[atom2].posq.z-data.posq.z);
#ifdef USE_PERIODIC #ifdef USE_PERIODIC
delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x;
delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y;
delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;
#endif #endif
real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; real3 tempForce;
#ifdef USE_CUTOFF real tempEnergy;
if (r2 < CUTOFF_SQUARED) { computeOneInteractionF1(data, localData[atom2], 1, 1, 1, tempEnergy, tempForce);
data.force += tempForce;
localData[atom2].force -= tempForce;
energy += tempEnergy;
if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) {
#ifdef ENABLE_SHUFFLE
for (int i = 16; i >= 1; i /= 2) {
tempForce.x += __shfl_xor(tempForce.x, i, 32);
tempForce.y += __shfl_xor(tempForce.y, i, 32);
tempForce.z += __shfl_xor(tempForce.z, i, 32);
}
if (tgx == 0)
localData[atom2].force -= tempForce;
#else
int bufferIndex = 3*threadIdx.x;
tempBuffer[bufferIndex] = tempForce.x;
tempBuffer[bufferIndex+1] = tempForce.y;
tempBuffer[bufferIndex+2] = tempForce.z;
if (tgx % 4 == 0) {
tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9];
tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10];
tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11];
}
if (tgx == 0) {
localData[atom2].force.x -= tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84];
localData[atom2].force.y -= tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85];
localData[atom2].force.z -= tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86];
}
#endif #endif
real invR = RSQRT(r2);
real r = RECIP(invR);
LOAD_ATOM2_PARAMETERS
atom2 = y*TILE_SIZE+j;
COMPUTE_INTERACTION
#ifdef USE_CUTOFF
} }
}
}
data.force *= ENERGY_SCALE_FACTOR;
localData[threadIdx.x].force *= ENERGY_SCALE_FACTOR;
if (pos < end) {
unsigned int offset = x*TILE_SIZE + tgx;
atomicAdd(&forceBuffers[offset], static_cast<unsigned long long>((long long) (data.force.x*0xFFFFFFFF)));
atomicAdd(&forceBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.y*0xFFFFFFFF)));
atomicAdd(&forceBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.z*0xFFFFFFFF)));
offset = y*TILE_SIZE + tgx;
atomicAdd(&forceBuffers[offset], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.x*0xFFFFFFFF)));
atomicAdd(&forceBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.y*0xFFFFFFFF)));
atomicAdd(&forceBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.z*0xFFFFFFFF)));
}
// Compute torques.
for (j = 0; j < TILE_SIZE; j++) {
if ((flags&(1<<j)) != 0) {
int atom2 = tbx+j;
real3 delta = make_real3(localData[atom2].posq.x-data.posq.x, localData[atom2].posq.y-data.posq.y, localData[atom2].posq.z-data.posq.z);
#ifdef USE_PERIODIC
delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x;
delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y;
delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;
#endif #endif
real3 tempForce;
computeOneInteractionT1(data, localData[atom2], 1, 1, 1, tempForce);
data.force += tempForce;
computeOneInteractionT3(data, localData[atom2], 1, 1, 1, tempForce);
if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) {
#ifdef ENABLE_SHUFFLE #ifdef ENABLE_SHUFFLE
force.x -= dEdR1.x; for (int i = 16; i >= 1; i /= 2) {
force.y -= dEdR1.y; tempForce.x += __shfl_xor(tempForce.x, i, 32);
force.z -= dEdR1.z; tempForce.y += __shfl_xor(tempForce.y, i, 32);
for (int i = 16; i >= 1; i /= 2) { tempForce.z += __shfl_xor(tempForce.z, i, 32);
dEdR2.x += __shfl_xor(dEdR2.x, i, 32); }
dEdR2.y += __shfl_xor(dEdR2.y, i, 32); if (tgx == 0)
dEdR2.z += __shfl_xor(dEdR2.z, i, 32); localData[atom2].force -= tempForce;
}
if (tgx == 0) {
localData[tbx+j].fx += dEdR2.x;
localData[tbx+j].fy += dEdR2.y;
localData[tbx+j].fz += dEdR2.z;
}
#else #else
force.x -= dEdR1.x; int bufferIndex = 3*threadIdx.x;
force.y -= dEdR1.y; tempBuffer[bufferIndex] = tempForce.x;
force.z -= dEdR1.z; tempBuffer[bufferIndex+1] = tempForce.y;
tempBuffer[bufferIndex] = dEdR2.x; tempBuffer[bufferIndex+2] = tempForce.z;
tempBuffer[bufferIndex+1] = dEdR2.y; if (tgx % 4 == 0) {
tempBuffer[bufferIndex+2] = dEdR2.z; tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9];
tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10];
// Sum the forces on atom2. tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11];
}
if (tgx % 4 == 0) { if (tgx == 0) {
tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9]; localData[atom2].force.x += tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84];
tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10]; localData[atom2].force.y += tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85];
tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11]; localData[atom2].force.z += tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86];
} }
if (tgx == 0) {
localData[tbx+j].fx += tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84];
localData[tbx+j].fy += tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85];
localData[tbx+j].fz += tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86];
}
#endif #endif
}
} }
} }
data.force *= ENERGY_SCALE_FACTOR;
localData[threadIdx.x].force *= ENERGY_SCALE_FACTOR;
if (pos < end) {
unsigned int offset = x*TILE_SIZE + tgx;
atomicAdd(&torqueBuffers[offset], static_cast<unsigned long long>((long long) (data.force.x*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.y*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.z*0xFFFFFFFF)));
offset = y*TILE_SIZE + tgx;
atomicAdd(&torqueBuffers[offset], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.x*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.y*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.z*0xFFFFFFFF)));
}
} }
} }
else else
......
...@@ -25,7 +25,101 @@ inline __device__ void loadAtomData(AtomData& data, int atom, const real4* __res ...@@ -25,7 +25,101 @@ inline __device__ void loadAtomData(AtomData& data, int atom, const real4* __res
data.thole = temp.y; data.thole = temp.y;
} }
__device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, real3 deltaR, real3& field1, real3& field2) { #ifdef USE_EWALD
__device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, real3 deltaR, float dScale, float pScale, real3* fields) {
real r2 = dot(deltaR, deltaR);
if (r2 <= CUTOFF_SQUARED) {
// calculate the error function damping terms
real r = SQRT(r2);
real ralpha = EWALD_ALPHA*r;
real bn0 = erfc(ralpha)/r;
real alsq2 = 2*EWALD_ALPHA*EWALD_ALPHA;
real alsq2n = RECIP(SQRT_PI*EWALD_ALPHA);
real exp2a = EXP(-(ralpha*ralpha));
alsq2n *= alsq2;
real bn1 = (bn0+alsq2n*exp2a)/r2;
alsq2n *= alsq2;
real bn2 = (3*bn1+alsq2n*exp2a)/r2;
alsq2n *= alsq2;
real bn3 = (5*bn2+alsq2n*exp2a)/r2;
// compute the error function scaled and unscaled terms
real scale3 = 1;
real scale5 = 1;
real scale7 = 1;
real damp = atom1.damp*atom2.damp;
if (damp != 0) {
real ratio = (r/damp);
ratio = ratio*ratio*ratio;
real pgamma = (atom1.thole < atom2.thole ? atom1.thole : atom2.thole);
damp = -pgamma*ratio;
if (damp > -50) {
real expdamp = EXP(damp);
scale3 = 1 - expdamp;
scale5 = 1 - expdamp*(1-damp);
scale7 = 1 - expdamp*(1-damp+(0.6f*damp*damp));
}
}
real dsc3 = dScale*scale3;
real dsc5 = dScale*scale5;
real dsc7 = dScale*scale7;
real psc3 = pScale*scale3;
real psc5 = pScale*scale5;
real psc7 = pScale*scale7;
real r3 = r*r2;
real r5 = r3*r2;
real r7 = r5*r2;
real drr3 = (1-dsc3)/r3;
real drr5 = 3*(1-dsc5)/r5;
real drr7 = 15*(1-dsc7)/r7;
real prr3 = (1-psc3)/r3;
real prr5 = 3*(1-psc5)/r5;
real prr7 = 15*(1-psc7)/r7;
real dir = dot(atom1.dipole, deltaR);
real3 qi;
qi.x = atom1.quadrupoleXX*deltaR.x + atom1.quadrupoleXY*deltaR.y + atom1.quadrupoleXZ*deltaR.z;
qi.y = atom1.quadrupoleXY*deltaR.x + atom1.quadrupoleYY*deltaR.y + atom1.quadrupoleYZ*deltaR.z;
qi.z = atom1.quadrupoleXZ*deltaR.x + atom1.quadrupoleYZ*deltaR.y + atom1.quadrupoleZZ*deltaR.z;
real qir = dot(qi, deltaR);
real dkr = dot(atom2.dipole, deltaR);
real3 qk;
qk.x = atom2.quadrupoleXX*deltaR.x + atom2.quadrupoleXY*deltaR.y + atom2.quadrupoleXZ*deltaR.z;
qk.y = atom2.quadrupoleXY*deltaR.x + atom2.quadrupoleYY*deltaR.y + atom2.quadrupoleYZ*deltaR.z;
qk.z = atom2.quadrupoleXZ*deltaR.x + atom2.quadrupoleYZ*deltaR.y + atom2.quadrupoleZZ*deltaR.z;
real qkr = dot(qk, deltaR);
real3 fim = -deltaR*(bn1*atom2.posq.w-bn2*dkr+bn3*qkr) - bn1*atom2.dipole + 2*bn2*qk;
real3 fkm = deltaR*(bn1*atom1.posq.w+bn2*dir+bn3*qir) - bn1*atom1.dipole - 2*bn2*qi;
real3 fid = -deltaR*(drr3*atom2.posq.w-drr5*dkr+drr7*qkr) - drr3*atom2.dipole + 2*drr5*qk;
real3 fkd = deltaR*(drr3*atom1.posq.w+drr5*dir+drr7*qir) - drr3*atom1.dipole - 2*drr5*qi;
real3 fip = -deltaR*(prr3*atom2.posq.w-prr5*dkr+prr7*qkr) - prr3*atom2.dipole + 2*prr5*qk;
real3 fkp = deltaR*(prr3*atom1.posq.w+prr5*dir+prr7*qir) - prr3*atom1.dipole - 2*prr5*qi;
// increment the field at each site due to this interaction
fields[0] = fim-fid;
fields[1] = fim-fip;
fields[2] = fkm-fkd;
fields[3] = fkm-fkp;
}
else {
fields[0] = make_real3(0);
fields[1] = make_real3(0);
fields[2] = make_real3(0);
fields[3] = make_real3(0);
}
}
#else
__device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, real3 deltaR, float dScale, float pScale, real3* fields) {
real rI = RSQRT(dot(deltaR, deltaR)); real rI = RSQRT(dot(deltaR, deltaR));
real r = RECIP(rI); real r = RECIP(rI);
real r2I = rI*rI; real r2I = rI*rI;
...@@ -66,7 +160,9 @@ __device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, real3 de ...@@ -66,7 +160,9 @@ __device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, real3 de
real factor = -rr3*atom2.posq.w + rr5*dotdd - rr7*dotqd; real factor = -rr3*atom2.posq.w + rr5*dotdd - rr7*dotqd;
field1 = deltaR*factor - rr3*atom2.dipole + rr5_2*qDotDelta; real3 field1 = deltaR*factor - rr3*atom2.dipole + rr5_2*qDotDelta;
fields[0] = dScale*field1;
fields[1] = pScale*field1;
qDotDelta.x = deltaR.x*atom1.quadrupoleXX + deltaR.y*atom1.quadrupoleXY + deltaR.z*atom1.quadrupoleXZ; qDotDelta.x = deltaR.x*atom1.quadrupoleXX + deltaR.y*atom1.quadrupoleXY + deltaR.z*atom1.quadrupoleXZ;
qDotDelta.y = deltaR.x*atom1.quadrupoleXY + deltaR.y*atom1.quadrupoleYY + deltaR.z*atom1.quadrupoleYZ; qDotDelta.y = deltaR.x*atom1.quadrupoleXY + deltaR.y*atom1.quadrupoleYY + deltaR.z*atom1.quadrupoleYZ;
...@@ -76,24 +172,16 @@ __device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, real3 de ...@@ -76,24 +172,16 @@ __device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, real3 de
dotqd = dot(deltaR, qDotDelta); dotqd = dot(deltaR, qDotDelta);
factor = rr3*atom1.posq.w + rr5*dotdd + rr7*dotqd; factor = rr3*atom1.posq.w + rr5*dotdd + rr7*dotqd;
field2 = deltaR*factor - rr3*atom1.dipole - rr5_2*qDotDelta; real3 field2 = deltaR*factor - rr3*atom1.dipole - rr5_2*qDotDelta;
fields[2] = dScale*field2;
fields[3] = pScale*field2;
} }
#endif
__device__ real computeDScaleFactor(unsigned int polarizationGroup) { __device__ real computeDScaleFactor(unsigned int polarizationGroup) {
return (polarizationGroup & 1 ? 0 : 1); return (polarizationGroup & 1 ? 0 : 1);
} }
__device__ float computeMScaleFactor(uint2 covalent) {
// int f1 = (value == 0 || value == 1 ? 1 : 0);
// int f2 = (value == 0 || value == 2 ? 1 : 0);
// 0 = 12 or 13: x and y: 0
// 1 = 14: x: 0.4
// 2 = 15: y: 0.8
bool x = (covalent.x & 1);
bool y = (covalent.y & 1);
return (x ? (y ? 0.0f : 0.4f) : (y ? 0.8f : 1.0f));
}
__device__ float computePScaleFactor(uint2 covalent, unsigned int polarizationGroup) { __device__ float computePScaleFactor(uint2 covalent, unsigned int polarizationGroup) {
bool x = (covalent.x & 1); bool x = (covalent.x & 1);
bool y = (covalent.y & 1); bool y = (covalent.y & 1);
...@@ -195,15 +283,14 @@ extern "C" __global__ void computeFixedField( ...@@ -195,15 +283,14 @@ extern "C" __global__ void computeFixedField(
delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y;
delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;
#endif #endif
real3 field1; real3 fields[4];
real3 field2; float d = computeDScaleFactor(polarizationGroup);
computeOneInteraction(data, localData[atom2], delta, field1, field2); float p = computePScaleFactor(covalent, polarizationGroup);
computeOneInteraction(data, localData[atom2], delta, d, p, fields);
atom2 = y*TILE_SIZE+j; atom2 = y*TILE_SIZE+j;
if (atom1 != atom2 && atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) { if (atom1 != atom2 && atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) {
float d = computeDScaleFactor(polarizationGroup); data.field += fields[0];
data.field += d*field1; data.fieldPolar += fields[1];
float p = computePScaleFactor(covalent, polarizationGroup);
data.fieldPolar += p*field1;
} }
covalent.x >>= 1; covalent.x >>= 1;
covalent.y >>= 1; covalent.y >>= 1;
...@@ -230,62 +317,58 @@ extern "C" __global__ void computeFixedField( ...@@ -230,62 +317,58 @@ extern "C" __global__ void computeFixedField(
for (j = 0; j < TILE_SIZE; j++) { for (j = 0; j < TILE_SIZE; j++) {
if ((flags&(1<<j)) != 0) { if ((flags&(1<<j)) != 0) {
int atom2 = tbx+j; int atom2 = tbx+j;
int bufferIndex = 3*threadIdx.x;
real3 dEdR1 = make_real3(0);
real3 dEdR2 = make_real3(0);
real3 delta = make_real3(localData[atom2].posq.x-data.posq.x, localData[atom2].posq.y-data.posq.y, localData[atom2].posq.z-data.posq.z); real3 delta = make_real3(localData[atom2].posq.x-data.posq.x, localData[atom2].posq.y-data.posq.y, localData[atom2].posq.z-data.posq.z);
#ifdef USE_PERIODIC #ifdef USE_PERIODIC
delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x;
delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y;
delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;
#endif #endif
real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; real3 fields[4];
#ifdef USE_CUTOFF computeOneInteraction(data, localData[atom2], delta, 1, 1, fields);
if (r2 < CUTOFF_SQUARED) { if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) {
#endif
real invR = RSQRT(r2);
real r = RECIP(invR);
LOAD_ATOM2_PARAMETERS
atom2 = y*TILE_SIZE+j;
COMPUTE_INTERACTION
#ifdef USE_CUTOFF
}
#endif
#ifdef ENABLE_SHUFFLE #ifdef ENABLE_SHUFFLE
force.x -= dEdR1.x; for (int i = 16; i >= 1; i /= 2) {
force.y -= dEdR1.y; fields[2].x += __shfl_xor(fields[2].x, i, 32);
force.z -= dEdR1.z; fields[2].y += __shfl_xor(fields[2].y, i, 32);
for (int i = 16; i >= 1; i /= 2) { fields[2].z += __shfl_xor(fields[2].z, i, 32);
dEdR2.x += __shfl_xor(dEdR2.x, i, 32); fields[3].x += __shfl_xor(fields[3].x, i, 32);
dEdR2.y += __shfl_xor(dEdR2.y, i, 32); fields[3].y += __shfl_xor(fields[3].y, i, 32);
dEdR2.z += __shfl_xor(dEdR2.z, i, 32); fields[3].z += __shfl_xor(fields[3].z, i, 32);
} }
if (tgx == 0) { if (tgx == 0) {
localData[tbx+j].fx += dEdR2.x; localData[atom2].field += fields[2];
localData[tbx+j].fy += dEdR2.y; localData[atom2].fieldPolar += fields[3];
localData[tbx+j].fz += dEdR2.z; }
}
#else #else
force.x -= dEdR1.x; int bufferIndex = 3*threadIdx.x;
force.y -= dEdR1.y; tempBuffer[bufferIndex] = fields[2].x;
force.z -= dEdR1.z; tempBuffer[bufferIndex+1] = fields[2].y;
tempBuffer[bufferIndex] = dEdR2.x; tempBuffer[bufferIndex+2] = fields[2].z;
tempBuffer[bufferIndex+1] = dEdR2.y; if (tgx % 4 == 0) {
tempBuffer[bufferIndex+2] = dEdR2.z; tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9];
tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10];
// Sum the forces on atom2. tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11];
}
if (tgx % 4 == 0) { if (tgx == 0) {
tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9]; localData[atom2].field.x += tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84];
tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10]; localData[atom2].field.y += tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85];
tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11]; localData[atom2].field.z += tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86];
} }
if (tgx == 0) { tempBuffer[bufferIndex] = fields[3].x;
localData[tbx+j].fx += tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84]; tempBuffer[bufferIndex+1] = fields[3].y;
localData[tbx+j].fy += tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85]; tempBuffer[bufferIndex+2] = fields[3].z;
localData[tbx+j].fz += tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86]; if (tgx % 4 == 0) {
} tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9];
tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10];
tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11];
}
if (tgx == 0) {
localData[atom2].fieldPolar.x += tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84];
localData[atom2].fieldPolar.y += tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85];
localData[atom2].fieldPolar.z += tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86];
}
#endif #endif
}
} }
} }
} }
...@@ -309,16 +392,15 @@ extern "C" __global__ void computeFixedField( ...@@ -309,16 +392,15 @@ extern "C" __global__ void computeFixedField(
delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y;
delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;
#endif #endif
real3 field1; real3 fields[4];
real3 field2; float d = computeDScaleFactor(polarizationGroup);
computeOneInteraction(data, localData[atom2], delta, field1, field2); float p = computePScaleFactor(covalent, polarizationGroup);
computeOneInteraction(data, localData[atom2], delta, d, p, fields);
if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) { if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) {
float d = computeDScaleFactor(polarizationGroup); data.field += fields[0];
data.field += d*field1; data.fieldPolar += fields[1];
localData[atom2].field += d*field2; localData[atom2].field += fields[2];
float p = computePScaleFactor(covalent, polarizationGroup); localData[atom2].fieldPolar += fields[3];
data.fieldPolar += p*field1;
localData[atom2].fieldPolar += p*field2;
} }
covalent.x >>= 1; covalent.x >>= 1;
covalent.y >>= 1; covalent.y >>= 1;
......
...@@ -139,65 +139,61 @@ extern "C" __global__ void computeInducedField( ...@@ -139,65 +139,61 @@ extern "C" __global__ void computeInducedField(
else { else {
// Compute only a subset of the interactions in this tile. // Compute only a subset of the interactions in this tile.
for (unsigned int j = 0; j < TILE_SIZE; j++) { for (j = 0; j < TILE_SIZE; j++) {
if ((flags&(1<<j)) != 0) { if ((flags&(1<<j)) != 0) {
int atom2 = tbx+j; int atom2 = tbx+j;
int bufferIndex = 3*threadIdx.x; real3 delta = make_real3(localData[atom2].posq.x-data.posq.x, localData[atom2].posq.y-data.posq.y, localData[atom2].posq.z-data.posq.z);
real3 dEdR1 = make_real3(0);
real3 dEdR2 = make_real3(0);
real3 delta = localData[atom2].pos-data.pos;
#ifdef USE_PERIODIC #ifdef USE_PERIODIC
delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x;
delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y;
delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;
#endif #endif
real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; real3 fields[4];
#ifdef USE_CUTOFF computeOneInteraction(data, localData[atom2], delta, fields);
if (r2 < CUTOFF_SQUARED) { if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) {
#endif
real invR = RSQRT(r2);
real r = RECIP(invR);
LOAD_ATOM2_PARAMETERS
atom2 = y*TILE_SIZE+j;
COMPUTE_INTERACTION
#ifdef USE_CUTOFF
}
#endif
#ifdef ENABLE_SHUFFLE #ifdef ENABLE_SHUFFLE
force.x -= dEdR1.x; for (int i = 16; i >= 1; i /= 2) {
force.y -= dEdR1.y; fields[2].x += __shfl_xor(fields[2].x, i, 32);
force.z -= dEdR1.z; fields[2].y += __shfl_xor(fields[2].y, i, 32);
for (int i = 16; i >= 1; i /= 2) { fields[2].z += __shfl_xor(fields[2].z, i, 32);
dEdR2.x += __shfl_xor(dEdR2.x, i, 32); fields[3].x += __shfl_xor(fields[3].x, i, 32);
dEdR2.y += __shfl_xor(dEdR2.y, i, 32); fields[3].y += __shfl_xor(fields[3].y, i, 32);
dEdR2.z += __shfl_xor(dEdR2.z, i, 32); fields[3].z += __shfl_xor(fields[3].z, i, 32);
} }
if (tgx == 0) { if (tgx == 0) {
localData[tbx+j].fx += dEdR2.x; localData[atom2].field += fields[2];
localData[tbx+j].fy += dEdR2.y; localData[atom2].fieldPolar += fields[3];
localData[tbx+j].fz += dEdR2.z; }
}
#else #else
force.x -= dEdR1.x; int bufferIndex = 3*threadIdx.x;
force.y -= dEdR1.y; tempBuffer[bufferIndex] = fields[2].x;
force.z -= dEdR1.z; tempBuffer[bufferIndex+1] = fields[2].y;
tempBuffer[bufferIndex] = dEdR2.x; tempBuffer[bufferIndex+2] = fields[2].z;
tempBuffer[bufferIndex+1] = dEdR2.y; if (tgx % 4 == 0) {
tempBuffer[bufferIndex+2] = dEdR2.z; tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9];
tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10];
// Sum the forces on atom2. tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11];
}
if (tgx % 4 == 0) { if (tgx == 0) {
tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9]; localData[atom2].field.x += tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84];
tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10]; localData[atom2].field.y += tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85];
tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11]; localData[atom2].field.z += tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86];
} }
if (tgx == 0) { tempBuffer[bufferIndex] = fields[3].x;
localData[tbx+j].fx += tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84]; tempBuffer[bufferIndex+1] = fields[3].y;
localData[tbx+j].fy += tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85]; tempBuffer[bufferIndex+2] = fields[3].z;
localData[tbx+j].fz += tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86]; if (tgx % 4 == 0) {
} tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9];
tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10];
tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11];
}
if (tgx == 0) {
localData[atom2].fieldPolar.x += tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84];
localData[atom2].fieldPolar.y += tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85];
localData[atom2].fieldPolar.z += tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86];
}
#endif #endif
}
} }
} }
} }
......
#define ARRAY(x,y) array[(x)-1+((y)-1)*PME_ORDER]
/**
* This is called from updateBsplines(). It calculates the spline coefficients for a single atom along a single axis.
*/
__device__ void computeBSplinePoint(real4* thetai, real w, real* array) {
// initialization to get to 2nd order recursion
ARRAY(2,2) = w;
ARRAY(2,1) = 1 - w;
// perform one pass to get to 3rd order recursion
ARRAY(3,3) = 0.5f * w * ARRAY(2,2);
ARRAY(3,2) = 0.5f * ((1+w)*ARRAY(2,1)+(2-w)*ARRAY(2,2));
ARRAY(3,1) = 0.5f * (1-w) * ARRAY(2,1);
// compute standard B-spline recursion to desired order
for (int i = 4; i <= PME_ORDER; i++)
{
int k = i - 1;
real denom = RECIP(k);
ARRAY(i,i) = denom * w * ARRAY(k,k);
for (int j = 1; j <= i-2; j++)
ARRAY(i,i-j) = denom * ((w+j)*ARRAY(k,i-j-1)+(i-j-w)*ARRAY(k,i-j));
ARRAY(i,1) = denom * (1-w) * ARRAY(k,1);
}
// get coefficients for the B-spline first derivative
int k = PME_ORDER - 1;
ARRAY(k,PME_ORDER) = ARRAY(k,PME_ORDER-1);
for (int i = PME_ORDER-1; i >= 2; i--)
ARRAY(k,i) = ARRAY(k,i-1) - ARRAY(k,i);
ARRAY(k,1) = -ARRAY(k,1);
// get coefficients for the B-spline second derivative
k = PME_ORDER - 2;
ARRAY(k,PME_ORDER-1) = ARRAY(k,PME_ORDER-2);
for (int i = PME_ORDER-2; i >= 2; i--)
ARRAY(k,i) = ARRAY(k,i-1) - ARRAY(k,i);
ARRAY(k,1) = -ARRAY(k,1);
ARRAY(k,PME_ORDER) = ARRAY(k,PME_ORDER-1);
for (int i = PME_ORDER-1; i >= 2; i--)
ARRAY(k,i) = ARRAY(k,i-1) - ARRAY(k,i);
ARRAY(k,1) = -ARRAY(k,1);
// get coefficients for the B-spline third derivative
k = PME_ORDER - 3;
ARRAY(k,PME_ORDER-2) = ARRAY(k,PME_ORDER-3);
for (int i = PME_ORDER-3; i >= 2; i--)
ARRAY(k,i) = ARRAY(k,i-1) - ARRAY(k,i);
ARRAY(k,1) = -ARRAY(k,1);
ARRAY(k,PME_ORDER-1) = ARRAY(k,PME_ORDER-2);
for (int i = PME_ORDER-2; i >= 2; i--)
ARRAY(k,i) = ARRAY(k,i-1) - ARRAY(k,i);
ARRAY(k,1) = -ARRAY(k,1);
ARRAY(k,PME_ORDER) = ARRAY(k,PME_ORDER-1);
for (int i = PME_ORDER-1; i >= 2; i--)
ARRAY(k,i) = ARRAY(k,i-1) - ARRAY(k,i);
ARRAY(k,1) = -ARRAY(k,1);
// copy coefficients from temporary to permanent storage
for (int i = 1; i <= PME_ORDER; i++)
thetai[i-1] = make_real4(ARRAY(PME_ORDER,i), ARRAY(PME_ORDER-1,i), ARRAY(PME_ORDER-2,i), ARRAY(PME_ORDER-3,i));
}
/**
* Compute bspline coefficients.
*/
extern "C" __global__ void updateBsplines(const real4* __restrict__ posq, int4* __restrict__ igrid, int2* __restrict__ pmeAtomGridIndex,
real4* __restrict__ theta1, real4* __restrict__ theta2, real4* __restrict__ theta3, real4 periodicBoxSize, real4 invPeriodicBoxSize) {
extern __shared__ real bsplines_cache[]; // size = block_size*pme_order*pme_order
real* array = &bsplines_cache[threadIdx.x*PME_ORDER*PME_ORDER];
// get the B-spline coefficients for each multipole site
for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) {
real4 pos = posq[i];
pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x;
pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y;
pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z;
// First axis.
real w = pos.x*invPeriodicBoxSize.x;
real fr = GRID_SIZE_X*(w-(int)(w+0.5f)+0.5f);
int ifr = (int) fr;
w = fr - ifr;
int igrid1 = ifr-PME_ORDER+1;
computeBSplinePoint(&theta1[i*PME_ORDER], w, array);
// Second axis.
w = pos.y*invPeriodicBoxSize.y;
fr = GRID_SIZE_Y*(w-(int)(w+0.5f)+0.5f);
ifr = (int) fr;
w = fr - ifr;
int igrid2 = ifr-PME_ORDER+1;
computeBSplinePoint(&theta2[i*PME_ORDER], w, array);
// Third axis.
w = pos.z*invPeriodicBoxSize.z;
fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f);
ifr = (int) fr;
w = fr - ifr;
int igrid3 = ifr-PME_ORDER+1;
computeBSplinePoint(&theta3[i*PME_ORDER], w, array);
// Record the grid point.
igrid1 += (igrid1 < 0 ? GRID_SIZE_X : 0);
igrid2 += (igrid2 < 0 ? GRID_SIZE_Y : 0);
igrid3 += (igrid3 < 0 ? GRID_SIZE_Z : 0);
igrid[i] = make_int4(igrid1, igrid2, igrid3, 0);
pmeAtomGridIndex[i] = make_int2(i, igrid1*GRID_SIZE_Y*GRID_SIZE_Z+igrid2*GRID_SIZE_Z+igrid3);
}
}
/**
* For each grid point, find the range of sorted atoms associated with that point.
*/
extern "C" __global__ void findAtomRangeForGrid(int2* __restrict__ pmeAtomGridIndex, int* __restrict__ pmeAtomRange,
const real4* __restrict__ posq, real4 periodicBoxSize, real4 invPeriodicBoxSize) {
int thread = blockIdx.x*blockDim.x+threadIdx.x;
int start = (NUM_ATOMS*thread)/(blockDim.x*gridDim.x);
int end = (NUM_ATOMS*(thread+1))/(blockDim.x*gridDim.x);
int last = (start == 0 ? -1 : pmeAtomGridIndex[start-1].y);
for (int i = start; i < end; ++i) {
int2 atomData = pmeAtomGridIndex[i];
int gridIndex = atomData.y;
if (gridIndex != last) {
for (int j = last+1; j <= gridIndex; ++j)
pmeAtomRange[j] = i;
last = gridIndex;
}
// The grid index won't be needed again. Reuse that component to hold the z index, thus saving
// some work in the charge spreading kernel.
real posz = posq[atomData.x].z;
posz -= floor(posz*invPeriodicBoxSize.z)*periodicBoxSize.z;
real w = posz*invPeriodicBoxSize.z;
real fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f);
int z = ((int) fr)-PME_ORDER+1;
pmeAtomGridIndex[i].y = z;
}
// Fill in values beyond the last atom.
if (thread == blockDim.x*gridDim.x-1) {
int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z;
for (int j = last+1; j <= gridSize; ++j)
pmeAtomRange[j] = NUM_ATOMS;
}
}
extern "C" __global__ void gridSpreadFixedMultipoles(const real4* __restrict__ posq, const real* __restrict__ labFrameDipole,
const real* __restrict__ labFrameQuadrupole, real2* __restrict__ pmeGrid, int2* __restrict__ pmeAtomGridIndex, int* __restrict__ pmeAtomRange,
const real4* __restrict__ theta1, const real4* __restrict__ theta2, const real4* __restrict__ theta3,
real4 periodicBoxSize, real4 invPeriodicBoxSize) {
const real xscale = GRID_SIZE_X*invPeriodicBoxSize.x;
const real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y;
const real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z;
unsigned int numGridPoints = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z;
unsigned int numThreads = gridDim.x*blockDim.x;
for (int gridIndex = blockIdx.x*blockDim.x+threadIdx.x; gridIndex < numGridPoints; gridIndex += numThreads) {
int3 gridPoint;
gridPoint.x = gridIndex/(GRID_SIZE_Y*GRID_SIZE_Z);
int remainder = gridIndex-gridPoint.x*GRID_SIZE_Y*GRID_SIZE_Z;
gridPoint.y = remainder/GRID_SIZE_Z;
gridPoint.z = remainder-gridPoint.y*GRID_SIZE_Z;
real result = 0;
for (int ix = 0; ix < PME_ORDER; ++ix) {
int x = gridPoint.x-ix+(gridPoint.x >= ix ? 0 : GRID_SIZE_X);
for (int iy = 0; iy < PME_ORDER; ++iy) {
int y = gridPoint.y-iy+(gridPoint.y >= iy ? 0 : GRID_SIZE_Y);
int z1 = gridPoint.z-PME_ORDER+1;
z1 += (z1 >= 0 ? 0 : GRID_SIZE_Z);
int z2 = (z1 < gridPoint.z ? gridPoint.z : GRID_SIZE_Z-1);
int gridIndex1 = x*GRID_SIZE_Y*GRID_SIZE_Z+y*GRID_SIZE_Z+z1;
int gridIndex2 = x*GRID_SIZE_Y*GRID_SIZE_Z+y*GRID_SIZE_Z+z2;
int firstAtom = pmeAtomRange[gridIndex1];
int lastAtom = pmeAtomRange[gridIndex2+1];
for (int i = firstAtom; i < lastAtom; ++i) {
int2 atomData = pmeAtomGridIndex[i];
int atomIndex = atomData.x;
int z = atomData.y;
int iz = gridPoint.z-z+(gridPoint.z >= z ? 0 : GRID_SIZE_Z);
if (iz >= GRID_SIZE_Z)
iz -= GRID_SIZE_Z;
real atomCharge = posq[atomIndex].w;
real atomDipoleX = xscale*labFrameDipole[atomIndex*3];
real atomDipoleY = yscale*labFrameDipole[atomIndex*3+1];
real atomDipoleZ = zscale*labFrameDipole[atomIndex*3+2];
real atomQuadrupoleXX = xscale*xscale*labFrameQuadrupole[atomIndex*5];
real atomQuadrupoleXY = 2*xscale*yscale*labFrameQuadrupole[atomIndex*5+1];
real atomQuadrupoleXZ = 2*xscale*zscale*labFrameQuadrupole[atomIndex*5+2];
real atomQuadrupoleYY = yscale*yscale*labFrameQuadrupole[atomIndex*5+3];
real atomQuadrupoleYZ = 2*yscale*zscale*labFrameQuadrupole[atomIndex*5+4];
real atomQuadrupoleZZ = -zscale*zscale*(labFrameQuadrupole[atomIndex*5]+labFrameQuadrupole[atomIndex*5+3]);
real4 t = theta1[atomIndex*PME_ORDER+ix];
real4 u = theta2[atomIndex*PME_ORDER+iy];
real4 v = theta3[atomIndex*PME_ORDER+iz];
real term0 = atomCharge*u.x*v.x + atomDipoleY*u.y*v.x + atomDipoleZ*u.x*v.y + atomQuadrupoleYY*u.z*v.x + atomQuadrupoleZZ*u.x*v.z + atomQuadrupoleYZ*u.y*v.y;
real term1 = atomDipoleX*u.x*v.x + atomQuadrupoleXY*u.y*v.x + atomQuadrupoleXZ*u.x*v.y;
real term2 = atomQuadrupoleXX * u.x * v.x;
result += term0*t.x + term1*t.y + term2*t.z;
}
if (z1 > gridPoint.z) {
gridIndex1 = x*GRID_SIZE_Y*GRID_SIZE_Z+y*GRID_SIZE_Z;
gridIndex2 = x*GRID_SIZE_Y*GRID_SIZE_Z+y*GRID_SIZE_Z+gridPoint.z;
firstAtom = pmeAtomRange[gridIndex1];
lastAtom = pmeAtomRange[gridIndex2+1];
for (int i = firstAtom; i < lastAtom; ++i) {
int2 atomData = pmeAtomGridIndex[i];
int atomIndex = atomData.x;
int z = atomData.y;
int iz = gridPoint.z-z+(gridPoint.z >= z ? 0 : GRID_SIZE_Z);
if (iz >= GRID_SIZE_Z)
iz -= GRID_SIZE_Z;
real atomCharge = posq[atomIndex].w;
real atomDipoleX = xscale*labFrameDipole[atomIndex*3];
real atomDipoleY = yscale*labFrameDipole[atomIndex*3+1];
real atomDipoleZ = zscale*labFrameDipole[atomIndex*3+2];
real atomQuadrupoleXX = xscale*xscale*labFrameQuadrupole[atomIndex*5];
real atomQuadrupoleXY = 2*xscale*yscale*labFrameQuadrupole[atomIndex*5+1];
real atomQuadrupoleXZ = 2*xscale*zscale*labFrameQuadrupole[atomIndex*5+2];
real atomQuadrupoleYY = yscale*yscale*labFrameQuadrupole[atomIndex*5+3];
real atomQuadrupoleYZ = 2*yscale*zscale*labFrameQuadrupole[atomIndex*5+4];
real atomQuadrupoleZZ = -zscale*zscale*(labFrameQuadrupole[atomIndex*5]+labFrameQuadrupole[atomIndex*5+3]);
real4 t = theta1[atomIndex*PME_ORDER+ix];
real4 u = theta2[atomIndex*PME_ORDER+iy];
real4 v = theta3[atomIndex*PME_ORDER+iz];
real term0 = atomCharge*u.x*v.x + atomDipoleY*u.y*v.x + atomDipoleZ*u.x*v.y + atomQuadrupoleYY*u.z*v.x + atomQuadrupoleZZ*u.x*v.z + atomQuadrupoleYZ*u.y*v.y;
real term1 = atomDipoleX*u.x*v.x + atomQuadrupoleXY*u.y*v.x + atomQuadrupoleXZ*u.x*v.y;
real term2 = atomQuadrupoleXX * u.x * v.x;
result += term0*t.x + term1*t.y + term2*t.z;
}
}
}
}
pmeGrid[gridIndex] = make_real2(result, 0);
}
}
//extern "C" __global__ void kGridSpreadInducedDipoles_kernel() {
// const real xscale = GRID_SIZE_X*invPeriodicBoxSize.x;
// const real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y;
// const real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z;
// unsigned int numGridPoints = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z;
// unsigned int numThreads = gridDim.x*blockDim.x;
// for (int gridIndex = blockIdx.x*blockDim.x+threadIdx.x; gridIndex < numGridPoints; gridIndex += numThreads) {
// int3 gridPoint;
// gridPoint.x = gridIndex/(GRID_SIZE_Y*GRID_SIZE_Z);
// int remainder = gridIndex-gridPoint.x*GRID_SIZE_Y*GRID_SIZE_Z;
// gridPoint.y = remainder/GRID_SIZE_Z;
// gridPoint.z = remainder-gridPoint.y*GRID_SIZE_Z;
// real2 result = make_real2(0, 0);
// for (int ix = 0; ix < PME_ORDER; ++ix) {
// int x = gridPoint.x-ix+(gridPoint.x >= ix ? 0 : GRID_SIZE_X);
// for (int iy = 0; iy < PME_ORDER; ++iy) {
// int y = gridPoint.y-iy+(gridPoint.y >= iy ? 0 : GRID_SIZE_Y);
// int z1 = gridPoint.z-PME_ORDER+1;
// z1 += (z1 >= 0 ? 0 : GRID_SIZE_Z);
// int z2 = (z1 < gridPoint.z ? gridPoint.z : GRID_SIZE_Z-1);
// int gridIndex1 = x*GRID_SIZE_Y*GRID_SIZE_Z+y*GRID_SIZE_Z+z1;
// int gridIndex2 = x*GRID_SIZE_Y*GRID_SIZE_Z+y*GRID_SIZE_Z+z2;
// int firstAtom = pmeAtomRange[gridIndex1];
// int lastAtom = pmeAtomRange[gridIndex2+1];
// for (int i = firstAtom; i < lastAtom; ++i) {
// int2 atomData = pmeAtomGridIndex[i];
// int atomIndex = atomData.x;
// int z = atomData.y;
// int iz = gridPoint.z-z+(gridPoint.z >= z ? 0 : GRID_SIZE_Z);
// if (iz >= GRID_SIZE_Z)
// iz -= GRID_SIZE_Z;
// real inducedDipoleX = xscale*cAmoebaSim.pInducedDipole[atomIndex*3];
// real inducedDipoleY = yscale*cAmoebaSim.pInducedDipole[atomIndex*3+1];
// real inducedDipoleZ = zscale*cAmoebaSim.pInducedDipole[atomIndex*3+2];
// real inducedDipolePolarX = xscale*cAmoebaSim.pInducedDipolePolar[atomIndex*3];
// real inducedDipolePolarY = yscale*cAmoebaSim.pInducedDipolePolar[atomIndex*3+1];
// real inducedDipolePolarZ = zscale*cAmoebaSim.pInducedDipolePolar[atomIndex*3+2];
// real4 t = theta1[atomIndex*PME_ORDER+ix];
// real4 u = theta2[atomIndex*PME_ORDER+iy];
// real4 v = theta3[atomIndex*PME_ORDER+iz];
// real term01 = inducedDipoleY*u.y*v.x + inducedDipoleZ*u.x*v.y;
// real term11 = inducedDipoleX*u.x*v.x;
// real term02 = inducedDipolePolarY*u.y*v.x + inducedDipolePolarZ*u.x*v.y;
// real term12 = inducedDipolePolarX*u.x*v.x;
// result.x += term01*t.x + term11*t.y;
// result.y += term02*t.x + term12*t.y;
// }
// if (z1 > gridPoint.z) {
// gridIndex1 = x*GRID_SIZE_Y*GRID_SIZE_Z+y*GRID_SIZE_Z;
// gridIndex2 = x*GRID_SIZE_Y*GRID_SIZE_Z+y*GRID_SIZE_Z+gridPoint.z;
// firstAtom = pmeAtomRange[gridIndex1];
// lastAtom = pmeAtomRange[gridIndex2+1];
// for (int i = firstAtom; i < lastAtom; ++i) {
// int2 atomData = pmeAtomGridIndex[i];
// int atomIndex = atomData.x;
// int z = atomData.y;
// int iz = gridPoint.z-z+(gridPoint.z >= z ? 0 : GRID_SIZE_Z);
// if (iz >= GRID_SIZE_Z)
// iz -= GRID_SIZE_Z;
// real inducedDipoleX = xscale*cAmoebaSim.pInducedDipole[atomIndex*3];
// real inducedDipoleY = yscale*cAmoebaSim.pInducedDipole[atomIndex*3+1];
// real inducedDipoleZ = zscale*cAmoebaSim.pInducedDipole[atomIndex*3+2];
// real inducedDipolePolarX = xscale*cAmoebaSim.pInducedDipolePolar[atomIndex*3];
// real inducedDipolePolarY = yscale*cAmoebaSim.pInducedDipolePolar[atomIndex*3+1];
// real inducedDipolePolarZ = zscale*cAmoebaSim.pInducedDipolePolar[atomIndex*3+2];
// real4 t = theta1[atomIndex*PME_ORDER+ix];
// real4 u = theta2[atomIndex*PME_ORDER+iy];
// real4 v = theta3[atomIndex*PME_ORDER+iz];
// real term01 = inducedDipoleY*u.y*v.x + inducedDipoleZ*u.x*v.y;
// real term11 = inducedDipoleX*u.x*v.x;
// real term02 = inducedDipolePolarY*u.y*v.x + inducedDipolePolarZ*u.x*v.y;
// real term12 = inducedDipolePolarX*u.x*v.x;
// result.x += term01*t.x + term11*t.y;
// result.y += term02*t.x + term12*t.y;
// }
// }
// }
// }
// pmeGrid[gridIndex] = result;
// }
//}
//
extern "C" __global__ void reciprocalConvolution(real2* __restrict__ pmeGrid, const real* __restrict__ pmeBsplineModuliX,
const real* __restrict__ pmeBsplineModuliY, const real* __restrict__ pmeBsplineModuliZ, real4 periodicBoxSize, real4 invPeriodicBoxSize) {
const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z;
real expFactor = M_PI*M_PI/(EWALD_ALPHA*EWALD_ALPHA);
real scaleFactor = RECIP(M_PI*periodicBoxSize.x*periodicBoxSize.y*periodicBoxSize.z);
for (int index = blockIdx.x*blockDim.x+threadIdx.x; index < gridSize; index += blockDim.x*gridDim.x) {
int kx = index/(GRID_SIZE_Y*GRID_SIZE_Z);
int remainder = index-kx*GRID_SIZE_Y*GRID_SIZE_Z;
int ky = remainder/GRID_SIZE_Z;
int kz = remainder-ky*GRID_SIZE_Z;
if (kx == 0 && ky == 0 && kz == 0) {
pmeGrid[index] = make_real2(0, 0);
continue;
}
int mx = (kx < (GRID_SIZE_X+1)/2) ? kx : (kx-GRID_SIZE_X);
int my = (ky < (GRID_SIZE_Y+1)/2) ? ky : (ky-GRID_SIZE_Y);
int mz = (kz < (GRID_SIZE_Z+1)/2) ? kz : (kz-GRID_SIZE_Z);
real mhx = mx*invPeriodicBoxSize.x;
real mhy = my*invPeriodicBoxSize.y;
real mhz = mz*invPeriodicBoxSize.z;
real bx = pmeBsplineModuliX[kx];
real by = pmeBsplineModuliY[ky];
real bz = pmeBsplineModuliZ[kz];
real2 grid = pmeGrid[index];
real m2 = mhx*mhx+mhy*mhy+mhz*mhz;
real denom = m2*bx*by*bz;
real eterm = scaleFactor*EXP(-expFactor*m2)/denom;
pmeGrid[index] = make_real2(grid.x*eterm, grid.y*eterm);
}
}
extern "C" __global__ void computeFixedPotentialFromGrid(const real2* __restrict__ pmeGrid, real* __restrict__ phi,
long long* __restrict__ fieldBuffers, const int4* __restrict__ igrid, const real4* __restrict__ theta1,
const real4* __restrict__ theta2, const real4* __restrict__ theta3, const real* __restrict__ labFrameDipole, real4 invPeriodicBoxSize) {
// extract the permanent multipole field at each site
for (int m = blockIdx.x*blockDim.x+threadIdx.x; m < NUM_ATOMS; m += blockDim.x*gridDim.x) {
int4 gridPoint = igrid[m];
real tuv000 = 0;
real tuv001 = 0;
real tuv010 = 0;
real tuv100 = 0;
real tuv200 = 0;
real tuv020 = 0;
real tuv002 = 0;
real tuv110 = 0;
real tuv101 = 0;
real tuv011 = 0;
real tuv300 = 0;
real tuv030 = 0;
real tuv003 = 0;
real tuv210 = 0;
real tuv201 = 0;
real tuv120 = 0;
real tuv021 = 0;
real tuv102 = 0;
real tuv012 = 0;
real tuv111 = 0;
for (int iz = 0; iz < PME_ORDER; iz++) {
int k = gridPoint.z+iz-(gridPoint.z+iz >= GRID_SIZE_Z ? GRID_SIZE_Z : 0);
real4 v = theta3[m*PME_ORDER+iz];
real tu00 = 0;
real tu10 = 0;
real tu01 = 0;
real tu20 = 0;
real tu11 = 0;
real tu02 = 0;
real tu30 = 0;
real tu21 = 0;
real tu12 = 0;
real tu03 = 0;
for (int iy = 0; iy < PME_ORDER; iy++) {
int j = gridPoint.y+iy-(gridPoint.y+iy >= GRID_SIZE_Y ? GRID_SIZE_Y : 0);
real4 u = theta2[m*PME_ORDER+iy];
real4 t = make_real4(0, 0, 0, 0);
for (int ix = 0; ix < PME_ORDER; ix++) {
int i = gridPoint.x+ix-(gridPoint.x+ix >= GRID_SIZE_X ? GRID_SIZE_X : 0);
int gridIndex = i*GRID_SIZE_Y*GRID_SIZE_Z + j*GRID_SIZE_Z + k;
real tq = pmeGrid[gridIndex].x;
real4 tadd = theta1[m*PME_ORDER+ix];
t.x += tq*tadd.x;
t.y += tq*tadd.y;
t.z += tq*tadd.z;
t.w += tq*tadd.w;
}
tu00 += t.x*u.x;
tu10 += t.y*u.x;
tu01 += t.x*u.y;
tu20 += t.z*u.x;
tu11 += t.y*u.y;
tu02 += t.x*u.z;
tu30 += t.w*u.x;
tu21 += t.z*u.y;
tu12 += t.y*u.z;
tu03 += t.x*u.w;
}
tuv000 += tu00*v.x;
tuv100 += tu10*v.x;
tuv010 += tu01*v.x;
tuv001 += tu00*v.y;
tuv200 += tu20*v.x;
tuv020 += tu02*v.x;
tuv002 += tu00*v.z;
tuv110 += tu11*v.x;
tuv101 += tu10*v.y;
tuv011 += tu01*v.y;
tuv300 += tu30*v.x;
tuv030 += tu03*v.x;
tuv003 += tu00*v.w;
tuv210 += tu21*v.x;
tuv201 += tu20*v.y;
tuv120 += tu12*v.x;
tuv021 += tu02*v.y;
tuv102 += tu10*v.z;
tuv012 += tu01*v.z;
tuv111 += tu11*v.y;
}
phi[20*m] = tuv000;
phi[20*m+1] = tuv100;
phi[20*m+2] = tuv010;
phi[20*m+3] = tuv001;
phi[20*m+4] = tuv200;
phi[20*m+5] = tuv020;
phi[20*m+6] = tuv002;
phi[20*m+7] = tuv110;
phi[20*m+8] = tuv101;
phi[20*m+9] = tuv011;
phi[20*m+10] = tuv300;
phi[20*m+11] = tuv030;
phi[20*m+12] = tuv003;
phi[20*m+13] = tuv210;
phi[20*m+14] = tuv201;
phi[20*m+15] = tuv120;
phi[20*m+16] = tuv021;
phi[20*m+17] = tuv102;
phi[20*m+18] = tuv012;
phi[20*m+19] = tuv111;
real dipoleScale = (4/(real) 3)*(EWALD_ALPHA*EWALD_ALPHA*EWALD_ALPHA)/SQRT(M_PI);
fieldBuffers[m] = (long long) ((dipoleScale*labFrameDipole[m*3]-GRID_SIZE_X*invPeriodicBoxSize.x*tuv100)*0xFFFFFFFF);
fieldBuffers[m+PADDED_NUM_ATOMS] = (long long) ((dipoleScale*labFrameDipole[m*3+1]-GRID_SIZE_Y*invPeriodicBoxSize.y*tuv010)*0xFFFFFFFF);
fieldBuffers[m+2*PADDED_NUM_ATOMS] = (long long) ((dipoleScale*labFrameDipole[m*3+2]-GRID_SIZE_Z*invPeriodicBoxSize.z*tuv001)*0xFFFFFFFF);
}
}
//extern "C" __global__ void kComputeInducedPotentialFromGrid_kernel() {
// // extract the induced dipole field at each site
//
// for (int m = blockIdx.x*blockDim.x+threadIdx.x; m < NUM_ATOMS; m += blockDim.x*gridDim.x) {
// int4 gridPoint = igrid[m];
// real tuv100_1 = 0;
// real tuv010_1 = 0;
// real tuv001_1 = 0;
// real tuv200_1 = 0;
// real tuv020_1 = 0;
// real tuv002_1 = 0;
// real tuv110_1 = 0;
// real tuv101_1 = 0;
// real tuv011_1 = 0;
// real tuv100_2 = 0;
// real tuv010_2 = 0;
// real tuv001_2 = 0;
// real tuv200_2 = 0;
// real tuv020_2 = 0;
// real tuv002_2 = 0;
// real tuv110_2 = 0;
// real tuv101_2 = 0;
// real tuv011_2 = 0;
// real tuv000 = 0;
// real tuv001 = 0;
// real tuv010 = 0;
// real tuv100 = 0;
// real tuv200 = 0;
// real tuv020 = 0;
// real tuv002 = 0;
// real tuv110 = 0;
// real tuv101 = 0;
// real tuv011 = 0;
// real tuv300 = 0;
// real tuv030 = 0;
// real tuv003 = 0;
// real tuv210 = 0;
// real tuv201 = 0;
// real tuv120 = 0;
// real tuv021 = 0;
// real tuv102 = 0;
// real tuv012 = 0;
// real tuv111 = 0;
// for (int iz = 0; iz < PME_ORDER; iz++) {
// int k = gridPoint.z+iz-(gridPoint.z+iz >= GRID_SIZE_Z ? GRID_SIZE_Z : 0);
// real4 v = theta3[m*PME_ORDER+iz];
// real tu00_1 = 0;
// real tu01_1 = 0;
// real tu10_1 = 0;
// real tu20_1 = 0;
// real tu11_1 = 0;
// real tu02_1 = 0;
// real tu00_2 = 0;
// real tu01_2 = 0;
// real tu10_2 = 0;
// real tu20_2 = 0;
// real tu11_2 = 0;
// real tu02_2 = 0;
// real tu00 = 0;
// real tu10 = 0;
// real tu01 = 0;
// real tu20 = 0;
// real tu11 = 0;
// real tu02 = 0;
// real tu30 = 0;
// real tu21 = 0;
// real tu12 = 0;
// real tu03 = 0;
// for (int iy = 0; iy < PME_ORDER; iy++) {
// int j = gridPoint.y+iy-(gridPoint.y+iy >= GRID_SIZE_Y ? GRID_SIZE_Y : 0);
// real4 u = theta2[m*PME_ORDER+iy];
// real t0_1 = 0;
// real t1_1 = 0;
// real t2_1 = 0;
// real t0_2 = 0;
// real t1_2 = 0;
// real t2_2 = 0;
// real t3 = 0;
// for (int ix = 0; ix < PME_ORDER; ix++) {
// int i = gridPoint.x+ix-(gridPoint.x+ix >= GRID_SIZE_X ? GRID_SIZE_X : 0);
// int gridIndex = i*GRID_SIZE_Y*GRID_SIZE_Z + j*GRID_SIZE_Z + k;
// real2 tq = pmeGrid[gridIndex];
// real4 tadd = theta1[m*PME_ORDER+ix];
// t0_1 += tq.x*tadd.x;
// t1_1 += tq.x*tadd.y;
// t2_1 += tq.x*tadd.z;
// t0_2 += tq.y*tadd.x;
// t1_2 += tq.y*tadd.y;
// t2_2 += tq.y*tadd.z;
// t3 += (tq.x+tq.y)*tadd.w;
// }
// tu00_1 += t0_1*u.x;
// tu10_1 += t1_1*u.x;
// tu01_1 += t0_1*u.y;
// tu20_1 += t2_1*u.x;
// tu11_1 += t1_1*u.y;
// tu02_1 += t0_1*u.z;
// tu00_2 += t0_2*u.x;
// tu10_2 += t1_2*u.x;
// tu01_2 += t0_2*u.y;
// tu20_2 += t2_2*u.x;
// tu11_2 += t1_2*u.y;
// tu02_2 += t0_2*u.z;
// real t0 = t0_1 + t0_2;
// real t1 = t1_1 + t1_2;
// real t2 = t2_1 + t2_2;
// tu00 += t0*u.x;
// tu10 += t1*u.x;
// tu01 += t0*u.y;
// tu20 += t2*u.x;
// tu11 += t1*u.y;
// tu02 += t0*u.z;
// tu30 += t3*u.x;
// tu21 += t2*u.y;
// tu12 += t1*u.z;
// tu03 += t0*u.w;
// }
// tuv100_1 += tu10_1*v.x;
// tuv010_1 += tu01_1*v.x;
// tuv001_1 += tu00_1*v.y;
// tuv200_1 += tu20_1*v.x;
// tuv020_1 += tu02_1*v.x;
// tuv002_1 += tu00_1*v.z;
// tuv110_1 += tu11_1*v.x;
// tuv101_1 += tu10_1*v.y;
// tuv011_1 += tu01_1*v.y;
// tuv100_2 += tu10_2*v.x;
// tuv010_2 += tu01_2*v.x;
// tuv001_2 += tu00_2*v.y;
// tuv200_2 += tu20_2*v.x;
// tuv020_2 += tu02_2*v.x;
// tuv002_2 += tu00_2*v.z;
// tuv110_2 += tu11_2*v.x;
// tuv101_2 += tu10_2*v.y;
// tuv011_2 += tu01_2*v.y;
// tuv000 += tu00*v.x;
// tuv100 += tu10*v.x;
// tuv010 += tu01*v.x;
// tuv001 += tu00*v.y;
// tuv200 += tu20*v.x;
// tuv020 += tu02*v.x;
// tuv002 += tu00*v.z;
// tuv110 += tu11*v.x;
// tuv101 += tu10*v.y;
// tuv011 += tu01*v.y;
// tuv300 += tu30*v.x;
// tuv030 += tu03*v.x;
// tuv003 += tu00*v.w;
// tuv210 += tu21*v.x;
// tuv201 += tu20*v.y;
// tuv120 += tu12*v.x;
// tuv021 += tu02*v.y;
// tuv102 += tu10*v.z;
// tuv012 += tu01*v.z;
// tuv111 += tu11*v.y;
// }
// phid[10*m] = 0;
// phid[10*m+1] = tuv100_1;
// phid[10*m+2] = tuv010_1;
// phid[10*m+3] = tuv001_1;
// phid[10*m+4] = tuv200_1;
// phid[10*m+5] = tuv020_1;
// phid[10*m+6] = tuv002_1;
// phid[10*m+7] = tuv110_1;
// phid[10*m+8] = tuv101_1;
// phid[10*m+9] = tuv011_1;
//
// phip[10*m] = 0;
// phip[10*m+1] = tuv100_2;
// phip[10*m+2] = tuv010_2;
// phip[10*m+3] = tuv001_2;
// phip[10*m+4] = tuv200_2;
// phip[10*m+5] = tuv020_2;
// phip[10*m+6] = tuv002_2;
// phip[10*m+7] = tuv110_2;
// phip[10*m+8] = tuv101_2;
// phip[10*m+9] = tuv011_2;
//
// phidp[20*m] = tuv000;
// phidp[20*m+1] = tuv100;
// phidp[20*m+2] = tuv010;
// phidp[20*m+3] = tuv001;
// phidp[20*m+4] = tuv200;
// phidp[20*m+5] = tuv020;
// phidp[20*m+6] = tuv002;
// phidp[20*m+7] = tuv110;
// phidp[20*m+8] = tuv101;
// phidp[20*m+9] = tuv011;
// phidp[20*m+10] = tuv300;
// phidp[20*m+11] = tuv030;
// phidp[20*m+12] = tuv003;
// phidp[20*m+13] = tuv210;
// phidp[20*m+14] = tuv201;
// phidp[20*m+15] = tuv120;
// phidp[20*m+16] = tuv021;
// phidp[20*m+17] = tuv102;
// phidp[20*m+18] = tuv012;
// phidp[20*m+19] = tuv111;
// }
//}
extern "C" __global__ void computeFixedMultipoleForceAndEnergy(real4* __restrict__ posq, unsigned long long* __restrict__ forceBuffers,
long long* __restrict__ torqueBuffers, real* __restrict__ energyBuffer, const real* __restrict__ labFrameDipole,
const real* __restrict__ labFrameQuadrupole, const real* __restrict__ phi, real4 periodicBoxSize, real4 invPeriodicBoxSize) {
real multipole[10];
const int deriv1[] = {1, 4, 7, 8, 10, 15, 17, 13, 14, 19};
const int deriv2[] = {2, 7, 5, 9, 13, 11, 18, 15, 19, 16};
const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18};
const real xscale = GRID_SIZE_X*invPeriodicBoxSize.x;
const real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y;
const real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z;
real energy = 0;
for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) {
// Compute the torque.
multipole[0] = posq[i].w;
multipole[1] = labFrameDipole[i*3];
multipole[2] = labFrameDipole[i*3+1];
multipole[3] = labFrameDipole[i*3+2];
multipole[4] = labFrameQuadrupole[i*5];
multipole[5] = labFrameQuadrupole[i*5+3];
multipole[6] = -(multipole[4]+multipole[5]);
multipole[7] = 2*labFrameQuadrupole[i*5+1];
multipole[8] = 2*labFrameQuadrupole[i*5+2];
multipole[9] = 2*labFrameQuadrupole[i*5+4];
const real* atomPhi = &phi[20*i];
torqueBuffers[i] = (long long) (EPSILON_FACTOR*(multipole[3]*yscale*atomPhi[2] - multipole[2]*zscale*atomPhi[3]
+ 2*(multipole[6]-multipole[5])*yscale*zscale*atomPhi[9]
+ multipole[8]*xscale*yscale*atomPhi[7] + multipole[9]*yscale*yscale*atomPhi[5]
- multipole[7]*xscale*zscale*atomPhi[8] - multipole[9]*zscale*zscale*atomPhi[6])*0xFFFFFFFF);
torqueBuffers[i+PADDED_NUM_ATOMS] = (long long) (EPSILON_FACTOR*(multipole[1]*zscale*atomPhi[3] - multipole[3]*xscale*atomPhi[1]
+ 2*(multipole[4]-multipole[6])*xscale*zscale*atomPhi[8]
+ multipole[7]*yscale*zscale*atomPhi[9] + multipole[8]*zscale*zscale*atomPhi[6]
- multipole[8]*xscale*xscale*atomPhi[4] - multipole[9]*xscale*yscale*atomPhi[7])*0xFFFFFFFF);
torqueBuffers[i+PADDED_NUM_ATOMS*2] = (long long) (EPSILON_FACTOR*(multipole[2]*xscale*atomPhi[1] - multipole[1]*yscale*atomPhi[2]
+ 2*(multipole[5]-multipole[4])*xscale*yscale*atomPhi[7]
+ multipole[7]*xscale*xscale*atomPhi[4] + multipole[9]*xscale*zscale*atomPhi[8]
- multipole[7]*yscale*yscale*atomPhi[5] - multipole[8]*yscale*zscale*atomPhi[9])*0xFFFFFFFF);
// Compute the force and energy.
multipole[1] *= xscale;
multipole[2] *= yscale;
multipole[3] *= zscale;
multipole[4] *= xscale*xscale;
multipole[5] *= yscale*yscale;
multipole[6] *= zscale*zscale;
multipole[7] *= xscale*yscale;
multipole[8] *= xscale*zscale;
multipole[9] *= yscale*zscale;
real4 f = make_real4(0, 0, 0, 0);
for (int k = 0; k < 10; k++) {
energy += multipole[k]*atomPhi[k];
f.x += multipole[k]*atomPhi[deriv1[k]];
f.y += multipole[k]*atomPhi[deriv2[k]];
f.z += multipole[k]*atomPhi[deriv3[k]];
}
f.x *= EPSILON_FACTOR*xscale;
f.y *= EPSILON_FACTOR*yscale;
f.z *= EPSILON_FACTOR*zscale;
forceBuffers[i] -= static_cast<unsigned long long>((long long) (f.x*0xFFFFFFFF));
forceBuffers[i+PADDED_NUM_ATOMS] -= static_cast<unsigned long long>((long long) (f.y*0xFFFFFFFF));
forceBuffers[i+PADDED_NUM_ATOMS*2] -= static_cast<unsigned long long>((long long) (f.z*0xFFFFFFFF));
}
energyBuffer[blockIdx.x*blockDim.x+threadIdx.x] += 0.5f*EPSILON_FACTOR*energy;
}
//extern "C" __global__ void kComputeInducedDipoleForceAndEnergy_kernel() {
// real multipole[10];
// real inducedDipole[3];
// real inducedDipolePolar[3];
// real scales[3];
// const int deriv1[] = {1, 4, 7, 8, 10, 15, 17, 13, 14, 19};
// const int deriv2[] = {2, 7, 5, 9, 13, 11, 18, 15, 19, 16};
// const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18};
// const real xscale = GRID_SIZE_X*invPeriodicBoxSize.x;
// const real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y;
// const real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z;
// scales[0] = xscale;
// scales[1] = yscale;
// scales[2] = zscale;
// real energy = 0;
// for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) {
// // Compute the torque.
//
// multipole[0] = posq[i].w;
// multipole[1] = labFrameDipole[i*3];
// multipole[2] = labFrameDipole[i*3+1];
// multipole[3] = labFrameDipole[i*3+2];
// multipole[4] = labFrameQuadrupole[i*5];
// multipole[5] = labFrameQuadrupole[i*5+3];
// multipole[6] = -(multipole[4]+multipole[5]);
// multipole[7] = 2*labFrameQuadrupole[i*5+1];
// multipole[8] = 2*labFrameQuadrupole[i*5+2];
// multipole[9] = 2*labFrameQuadrupole[i*5+4];
// real* phidp = &cAmoebaSim.pPhidp[20*i];
//
// cAmoebaSim.pTorque[3*i] += 0.5f*EPSILON_FACTOR*(multipole[3]*yscale*phidp[2] - multipole[2]*zscale*phidp[3]
// + 2*(multipole[6]-multipole[5])*yscale*zscale*phidp[9]
// + multipole[8]*xscale*yscale*phidp[7] + multipole[9]*yscale*yscale*phidp[5]
// - multipole[7]*xscale*zscale*phidp[8] - multipole[9]*zscale*zscale*phidp[6]);
//
// cAmoebaSim.pTorque[3*i+1] += 0.5f*EPSILON_FACTOR*(multipole[1]*zscale*phidp[3] - multipole[3]*xscale*phidp[1]
// + 2*(multipole[4]-multipole[6])*xscale*zscale*phidp[8]
// + multipole[7]*yscale*zscale*phidp[9] + multipole[8]*zscale*zscale*phidp[6]
// - multipole[8]*xscale*xscale*phidp[4] - multipole[9]*xscale*yscale*phidp[7]);
//
// cAmoebaSim.pTorque[3*i+2] += 0.5f*EPSILON_FACTOR*(multipole[2]*xscale*phidp[1] - multipole[1]*yscale*phidp[2]
// + 2*(multipole[5]-multipole[4])*xscale*yscale*phidp[7]
// + multipole[7]*xscale*xscale*phidp[4] + multipole[9]*xscale*zscale*phidp[8]
// - multipole[7]*yscale*yscale*phidp[5] - multipole[8]*yscale*zscale*phidp[9]);
//
// // Compute the force and energy.
//
// multipole[1] *= xscale;
// multipole[2] *= yscale;
// multipole[3] *= zscale;
// multipole[4] *= xscale*xscale;
// multipole[5] *= yscale*yscale;
// multipole[6] *= zscale*zscale;
// multipole[7] *= xscale*yscale;
// multipole[8] *= xscale*zscale;
// multipole[9] *= yscale*zscale;
//
// inducedDipole[0] = cAmoebaSim.pInducedDipole[i*3];
// inducedDipole[1] = cAmoebaSim.pInducedDipole[i*3+1];
// inducedDipole[2] = cAmoebaSim.pInducedDipole[i*3+2];
// inducedDipolePolar[0] = cAmoebaSim.pInducedDipolePolar[i*3];
// inducedDipolePolar[1] = cAmoebaSim.pInducedDipolePolar[i*3+1];
// inducedDipolePolar[2] = cAmoebaSim.pInducedDipolePolar[i*3+2];
// real* phi = &cAmoebaSim.pPhi[20*i];
// real* phip = &cAmoebaSim.pPhip[10*i];
// real* phid = &cAmoebaSim.pPhid[10*i];
// real4 f = make_real4(0, 0, 0, 0);
//
// energy += GRID_SIZE_X*invPeriodicBoxSize.x*inducedDipole[0]*phi[1];
// energy += GRID_SIZE_Y*invPeriodicBoxSize.y*inducedDipole[1]*phi[2];
// energy += GRID_SIZE_Z*invPeriodicBoxSize.z*inducedDipole[2]*phi[3];
//
// for (int k = 0; k < 3; k++) {
//
// int j1 = deriv1[k+1];
// int j2 = deriv2[k+1];
// int j3 = deriv3[k+1];
//
// f.x += (inducedDipole[k]+inducedDipolePolar[k])*phi[j1]*(scales[k]/xscale);
// f.y += (inducedDipole[k]+inducedDipolePolar[k])*phi[j2]*(scales[k]/yscale);
// f.z += (inducedDipole[k]+inducedDipolePolar[k])*phi[j3]*(scales[k]/zscale);
//
// if( cAmoebaSim.polarizationType == 0 )
// {
// f.x += (inducedDipole[k]*phip[j1] + inducedDipolePolar[k]*phid[j1])*(scales[k]/xscale);
// f.y += (inducedDipole[k]*phip[j2] + inducedDipolePolar[k]*phid[j2])*(scales[k]/yscale);
// f.z += (inducedDipole[k]*phip[j3] + inducedDipolePolar[k]*phid[j3])*(scales[k]/zscale);
// }
//
//
// }
//
// f.x *= GRID_SIZE_X*invPeriodicBoxSize.x;
// f.y *= GRID_SIZE_Y*invPeriodicBoxSize.y;
// f.z *= GRID_SIZE_Z*invPeriodicBoxSize.z;
// for (int k = 0; k < 10; k++) {
// f.x += multipole[k]*phidp[deriv1[k]];
// f.y += multipole[k]*phidp[deriv2[k]];
// f.z += multipole[k]*phidp[deriv3[k]];
// }
//
// f.x *= 0.5f*EPSILON_FACTOR*xscale;
// f.y *= 0.5f*EPSILON_FACTOR*yscale;
// f.z *= 0.5f*EPSILON_FACTOR*zscale;
//
// real4 force = cSim.pForce4[i];
// force.x -= f.x;
// force.y -= f.y;
// force.z -= f.z;
// cSim.pForce4[i] = force;
// }
// cSim.pEnergy[blockIdx.x*blockDim.x+threadIdx.x] += 0.5f*EPSILON_FACTOR*energy;
//}
//
//extern "C" __global__ void kRecordFixedMultipoleField_kernel(real* output) {
// const real xscale = GRID_SIZE_X*invPeriodicBoxSize.x;
// const real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y;
// const real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z;
// for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) {
// output[3*i] = -xscale*cAmoebaSim.pPhi[20*i+1];
// output[3*i+1] = -yscale*cAmoebaSim.pPhi[20*i+2];
// output[3*i+2] = -zscale*cAmoebaSim.pPhi[20*i+3];
// }
//}
//
//extern "C" __global__ void kRecordInducedDipoleField_kernel(real* output, real* outputPolar) {
// const real xscale = GRID_SIZE_X*invPeriodicBoxSize.x;
// const real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y;
// const real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z;
// for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) {
// output[3*i] -= xscale*cAmoebaSim.pPhid[10*i+1];
// output[3*i+1] -= yscale*cAmoebaSim.pPhid[10*i+2];
// output[3*i+2] -= zscale*cAmoebaSim.pPhid[10*i+3];
// outputPolar[3*i] -= xscale*cAmoebaSim.pPhip[10*i+1];
// outputPolar[3*i+1] -= yscale*cAmoebaSim.pPhip[10*i+2];
// outputPolar[3*i+2] -= zscale*cAmoebaSim.pPhip[10*i+3];
// }
//}
#define APPLY_SCALE
__device__ void computeOneInteractionF1(AtomData& atom1, volatile AtomData& atom2, real4 delta, real4 bn, real bn5, float forceFactor,
#ifdef APPLY_SCALE
float dScale, float pScale, float mScale,
#endif
real3& force, real& energy) {
real xr = delta.x;
real yr = delta.y;
real zr = delta.z;
#ifdef APPLY_SCALE
real rr1 = delta.w;
#endif
// set the permanent multipole and induced dipole values;
real ci = atom1.q;
real di1 = atom1.dipole.x;
real di2 = atom1.dipole.y;
real di3 = atom1.dipole.z;
real qi1 = atom1.quadrupoleXX;
real qi2 = atom1.quadrupoleXY;
real qi3 = atom1.quadrupoleXZ;
real qi5 = atom1.quadrupoleYY;
real qi6 = atom1.quadrupoleYZ;
real qi9 = -(atom1.quadrupoleXX + atom1.quadrupoleYY);
real ck = atom2.q;
real dk1 = atom2.dipole.x;
real dk2 = atom2.dipole.y;
real dk3 = atom2.dipole.z;
real qk1 = atom2.quadrupoleXX;
real qk2 = atom2.quadrupoleXY;
real qk3 = atom2.quadrupoleXZ;
real qk5 = atom2.quadrupoleYY;
real qk6 = atom2.quadrupoleYZ;
real qk9 = -(atom2.quadrupoleXX + atom2.quadrupoleYY);
real bn1 = bn.x;
real bn2 = bn.y;
real bn3 = bn.z;
real bn4 = bn.w;
#ifdef APPLY_SCALE
real offset = 1-mScale;
real rr3 = rr1*rr1*rr1;
real gf4 = 2*(bn2 - 3*offset*rr3*rr1*rr1);
#else
real gf4 = 2*bn2;
#endif
real qidk1 = qi1*dk1 + qi2*dk2 + qi3*dk3;
real qkdi1 = qk1*di1 + qk2*di2 + qk3*di3;
real ftm21 = gf4*(qkdi1-qidk1);
real qidk2 = qi2*dk1 + qi5*dk2 + qi6*dk3;
real qkdi2 = qk2*di1 + qk5*di2 + qk6*di3;
real ftm22 = gf4*(qkdi2-qidk2);
real qidk3 = qi3*dk1 + qi6*dk2 + qi9*dk3;
real qkdi3 = qk3*di1 + qk6*di2 + qk9*di3;
real ftm23 = gf4*(qkdi3-qidk3);
real qir1 = qi1*xr + qi2*yr + qi3*zr;
real qir2 = qi2*xr + qi5*yr + qi6*zr;
real qir3 = qi3*xr + qi6*yr + qi9*zr;
real qkr1 = qk1*xr + qk2*yr + qk3*zr;
real qkr2 = qk2*xr + qk5*yr + qk6*zr;
real qkr3 = qk3*xr + qk6*yr + qk9*zr;
#ifdef APPLY_SCALE
real gf7 = 4*(bn3 - 15*offset*rr3*rr3*rr1);
#else
real gf7 = 4*bn3;
#endif
real qiqkr1 = qi1*qkr1 + qi2*qkr2 + qi3*qkr3;
real qkqir1 = qk1*qir1 + qk2*qir2 + qk3*qir3;
ftm21 += gf7*(qiqkr1+qkqir1);
real qiqkr2 = qi2*qkr1 + qi5*qkr2 + qi6*qkr3;
real qkqir2 = qk2*qir1 + qk5*qir2 + qk6*qir3;
ftm22 += gf7*(qiqkr2+qkqir2);
real qiqkr3 = qi3*qkr1 + qi6*qkr2 + qi9*qkr3;
real qkqir3 = qk3*qir1 + qk6*qir2 + qk9*qir3;
ftm23 += gf7*(qiqkr3+qkqir3);
// calculate the scalar products for permanent components
real gl6 = di1*dk1 + di2*dk2 + di3*dk3;
real gl7 = 2*(qir1*dk1 + qir2*dk2 + qir3*dk3 - (qkr1*di1 + qkr2*di2 + qkr3*di3));
real gl5 = -4*(qir1*qkr1 + qir2*qkr2 + qir3*qkr3);
real gl8 = 2*(qi1*qk1 + qi2*qk2 + qi3*qk3 + qi2*qk2 + qi5*qk5 + qi6*qk6 + qi3*qk3 + qi6*qk6 + qi9*qk9);
real sc3 = di1*xr + di2*yr + di3*zr;
real sc5 = qir1*xr + qir2*yr + qir3*zr;
real sc4 = dk1*xr + dk2*yr + dk3*zr;
real sc6 = qkr1*xr + qkr2*yr + qkr3*zr;
real gl0 = ci*ck;
real gl1 = ck*sc3 - ci*sc4;
real gl2 = ci*sc6 + ck*sc5 - sc3*sc4;
real gl3 = sc3*sc6 - sc4*sc5;
real gl4 = sc5*sc6;
#ifdef APPLY_SCALE
energy += forceFactor*(-offset*rr1*gl0 + (bn1-offset*rr3)*(gl1+gl6) + (bn2-offset*(3*rr3*rr1*rr1))*(gl2+gl7+gl8) + (bn3-offset*(15*rr3*rr3*rr1))*(gl3+gl5) + (bn4-offset*(105*rr3*rr3*rr3))*gl4);
#else
energy += forceFactor*(bn1*(gl1+gl6) + bn2*(gl2+gl7+gl8) + bn3*(gl3+gl5) + bn4*gl4);
#endif
real gf1 = bn1*gl0 + bn2*(gl1+gl6) + bn3*(gl2+gl7+gl8) + bn4*(gl3+gl5) + bn5*gl4;
#ifdef APPLY_SCALE
gf1 -= offset*(rr3*gl0 + (3*rr3*rr1*rr1)*(gl1+gl6) + (15*rr3*rr3*rr1)*(gl2+gl7+gl8) + (105*rr3*rr3*rr3)*(gl3+gl5) + (945*rr3*rr3*rr3*rr1*rr1)*gl4);
#endif
ftm21 += gf1*xr;
ftm22 += gf1*yr;
ftm23 += gf1*zr;
#ifdef APPLY_SCALE
real gf2 = -ck*bn1 + sc4*bn2 - sc6*bn3 - offset*(-ck*rr3 + sc4*(3*rr3*rr1*rr1) - sc6*(15*rr3*rr3*rr1));
#else
real gf2 = -ck*bn1 + sc4*bn2 - sc6*bn3;
#endif
ftm21 += gf2*di1;
ftm22 += gf2*di2;
ftm23 += gf2*di3;
#ifdef APPLY_SCALE
real gf5 = 2*(-ck*bn2+sc4*bn3-sc6*bn4 - offset*(-ck*(3*rr3*rr1*rr1)+sc4*(15*rr3*rr3*rr1)-sc6*(105*rr3*rr3*rr3)));
#else
real gf5 = 2*(-ck*bn2+sc4*bn3-sc6*bn4);
#endif
ftm21 += gf5*qir1;
ftm22 += gf5*qir2;
ftm23 += gf5*qir3;
#ifdef APPLY_SCALE
real gf3 = ci*bn1 + sc3*bn2 + sc5*bn3 - offset*(ci*rr3 + sc3*(3*rr3*rr1*rr1) + sc5*(15*rr3*rr3*rr1));
#else
real gf3 = ci*bn1 + sc3*bn2 + sc5*bn3;
#endif
ftm21 += gf3*dk1;
ftm22 += gf3*dk2;
ftm23 += gf3*dk3;
#ifdef APPLY_SCALE
real gf6 = 2*(-ci*bn2-sc3*bn3-sc5*bn4 - offset*(-ci*(3*rr3*rr1*rr1)-sc3*(15*rr3*rr3*rr1)-sc5*(105*rr3*rr3*rr3)));
#else
real gf6 = 2*(-ci*bn2-sc3*bn3-sc5*bn4);
#endif
ftm21 += gf6*qkr1;
ftm22 += gf6*qkr2;
ftm23 += gf6*qkr3;
force.x = ftm21;
force.y = ftm22;
force.z = ftm23;
}
__device__ void computeOneInteractionF2(AtomData& atom1, volatile AtomData& atom2, real4 delta, real4 bn, float forceFactor,
#ifdef APPLY_SCALE
float dScale, float pScale, float mScale,
#endif
real3& force, real& energy) {
const float uScale = 1;
real xr = delta.x;
real yr = delta.y;
real zr = delta.z;
real rr1 = delta.w;
// set the permanent multipole and induced dipole values;
real ci = atom1.q;
real di1 = atom1.dipole.x;
real di2 = atom1.dipole.y;
real di3 = atom1.dipole.z;
real qi1 = atom1.quadrupoleXX;
real qi2 = atom1.quadrupoleXY;
real qi3 = atom1.quadrupoleXZ;
real qi5 = atom1.quadrupoleYY;
real qi6 = atom1.quadrupoleYZ;
real qi9 = -(atom1.quadrupoleXX + atom1.quadrupoleYY);
real bn1 = bn.x;
real bn2 = bn.y;
real bn3 = bn.z;
real bn4 = bn.w;
real damp = atom1.damp*atom2.damp;
if (damp != 0) {
real pgamma = atom1.thole < atom2.thole ? atom1.thole : atom2.thole;
real ratio = RECIP(rr1*damp);
damp = -pgamma*ratio*ratio*ratio;
damp = damp < -50 ? 0 : damp;
}
real scale5 = (damp == 0) ? 1 : (1 - (1-damp)*EXP(damp));
real rr5 = rr1*rr1;
rr5 = 3*rr1*rr5*rr5;
#ifdef APPLY_SCALE
real psc5 = rr5*(1 - scale5*pScale);
real dsc5 = rr5*(1 - scale5*dScale);
real usc5 = rr5*(1 - scale5*uScale);
#else
real psc5 = rr5*(1 - scale5);
#endif
real qiuk1 = qi1*atom2.inducedDipole.x + qi2*atom2.inducedDipole.y + qi3*atom2.inducedDipole.z;
real qiukp1 = qi1*atom2.inducedDipolePolar.x + qi2*atom2.inducedDipolePolar.y + qi3*atom2.inducedDipolePolar.z;
real ftm21 = -bn2*(qiuk1+qiukp1);
#ifdef APPLY_SCALE
ftm21 += qiuk1*psc5 + qiukp1*dsc5;
#else
ftm21 += (qiuk1 + qiukp1)*psc5;
#endif
real qiuk2 = qi2*atom2.inducedDipole.x + qi5*atom2.inducedDipole.y + qi6*atom2.inducedDipole.z;
real qiukp2 = qi2*atom2.inducedDipolePolar.x + qi5*atom2.inducedDipolePolar.y + qi6*atom2.inducedDipolePolar.z;
real ftm22 = -bn2*(qiuk2+qiukp2);
#ifdef APPLY_SCALE
ftm22 += ((qiuk2)*psc5 + (qiukp2)*dsc5);
#else
ftm22 += (qiuk2 + qiukp2)*psc5;
#endif
real qiuk3 = qi3*atom2.inducedDipole.x + qi6*atom2.inducedDipole.y + qi9*atom2.inducedDipole.z;
real qiukp3 = qi3*atom2.inducedDipolePolar.x + qi6*atom2.inducedDipolePolar.y + qi9*atom2.inducedDipolePolar.z;
real ftm23 = -bn2*(qiuk3+qiukp3);
#ifdef APPLY_SCALE
ftm23 += ((qiuk3)*psc5 + (qiukp3)*dsc5);
#else
ftm23 += (qiuk3 + qiukp3)*psc5;
#endif
real expdamp = EXP(damp);
real scale3 = (damp == 0) ? 1 : (1 - expdamp);
real rr3 = rr1*rr1*rr1;
#ifdef APPLY_SCALE
real psc3 = rr3*(1 - scale3*pScale);
real dsc3 = rr3*(1 - scale3*dScale);
real usc3 = rr3*(1 - scale3*uScale);
#else
real psc3 = rr3*(1 - scale3);
#endif
real scale7 = (damp == 0) ? 1 : (1 - (1-damp+0.6f*damp*damp)*expdamp);
#ifdef APPLY_SCALE
real psc7 = (15*rr3*rr3*rr1)*(1 - scale7*pScale);
real dsc7 = (15*rr3*rr3*rr1)*(1 - scale7*dScale);
#else
real psc7 = (15*rr3*rr3*rr1)*(1 - scale7);
#endif
real qir1 = qi1*xr + qi2*yr + qi3*zr;
real qir2 = qi2*xr + qi5*yr + qi6*zr;
real qir3 = qi3*xr + qi6*yr + qi9*zr;
real sc3 = di1*xr + di2*yr + di3*zr;
real sc5 = qir1*xr + qir2*yr + qir3*zr;
real gfi3 = ci*bn1 + sc3*bn2 + sc5*bn3;
real prefactor1;
prefactor1 = 0.5f*(ci*psc3 + sc3*psc5 + sc5*psc7 - gfi3);
ftm21 -= prefactor1*atom2.inducedDipole.x;
ftm22 -= prefactor1*atom2.inducedDipole.y;
ftm23 -= prefactor1*atom2.inducedDipole.z;
#ifdef APPLY_SCALE
prefactor1 = 0.5f*(ci*dsc3 + sc3*dsc5 + sc5*dsc7 - gfi3);
#endif
ftm21 -= prefactor1*atom2.inducedDipolePolar.x;
ftm22 -= prefactor1*atom2.inducedDipolePolar.y;
ftm23 -= prefactor1*atom2.inducedDipolePolar.z;
real sci4 = atom2.inducedDipole.x*xr + atom2.inducedDipole.y*yr + atom2.inducedDipole.z*zr;
energy += forceFactor*0.5f*sci4*((psc3-bn1)*ci + (psc5-bn2)*sc3 + (psc7-bn3)*sc5);
real scip4 = atom2.inducedDipolePolar.x*xr + atom2.inducedDipolePolar.y*yr + atom2.inducedDipolePolar.z*zr;
#ifndef DIRECT_POLARIZATION
#ifdef APPLY_SCALE
prefactor1 = 0.5f*(bn2 - usc5);
#else
prefactor1 = 0.5f*(bn2 - psc5);
#endif
ftm21 += prefactor1*((sci4*atom1.inducedDipolePolar.x + scip4*atom1.inducedDipole.x));
ftm22 += prefactor1*((sci4*atom1.inducedDipolePolar.y + scip4*atom1.inducedDipole.y));
ftm23 += prefactor1*((sci4*atom1.inducedDipolePolar.z + scip4*atom1.inducedDipole.z));
}
#endif
#ifdef APPLY_SCALE
prefactor1 = 0.5f*(bn2*(sci4+scip4) - (sci4*psc5+scip4*dsc5));
#else
sci4 += scip4;
prefactor1 = 0.5f*sci4*(bn2 - psc5);
#endif
ftm21 += prefactor1*di1;
ftm22 += prefactor1*di2;
ftm23 += prefactor1*di3;
#ifdef APPLY_SCALE
real gfi5 = bn3*(sci4+scip4) - (sci4*psc7+scip4*dsc7);
#else
real gfi5 = sci4*(bn3 - psc7);
#endif
ftm21 += gfi5*qir1;
ftm22 += gfi5*qir2;
ftm23 += gfi5*qir3;
real sci7 = qir1*atom2.inducedDipole.x + qir2*atom2.inducedDipole.y + qir3*atom2.inducedDipole.z;
energy += forceFactor*(bn2-psc5)*sci7;
real scip7 = qir1*atom2.inducedDipolePolar.x + qir2*atom2.inducedDipolePolar.y + qir3*atom2.inducedDipolePolar.z;
#ifdef APPLY_SCALE
real gli1 = -ci*sci4;
real gli2 = -sc3*sci4 + 2*sci7;
real gli3 = -sci4*sc5;
real glip1 = -ci*scip4;
real glip2 = -sc3*scip4 + 2*scip7;
real glip3 = -scip4*sc5;
#else
real gli1 = -ci*sci4;
real gli2 = -sc3*sci4 + 2*(sci7 + scip7);
real gli3 = -sci4*sc5;
#endif
#ifdef APPLY_SCALE
real gfi1 = (bn2*(gli1+glip1) + bn3*(gli2+glip2) + bn4*(gli3+glip3));
gfi1 -= (rr1*rr1)*(3*(gli1*psc3 + glip1*dsc3) + 5*(gli2*psc5 + glip2*dsc5) + 7*(gli3*psc7+glip3*dsc7));
#else
real gfi1 = bn2*gli1 + bn3*gli2 + bn4*gli3;
gfi1 -= (rr1*rr1)*(3*gli1*psc3 + 5*gli2*psc5 + 7*gli3*psc7);
#endif
gfi1 *= 0.5f;
ftm21 += gfi1*xr;
ftm22 += gfi1*yr;
ftm23 += gfi1*zr;
if (damp != 0) {
real expdamp = EXP(damp);
real temp3 = -1.5f*damp*expdamp*rr1*rr1;
real temp5 = -damp;
real temp7 = -0.2f - 0.6f*damp;
real ddsc31 = temp3*xr;
real ddsc32 = temp3*yr;
real ddsc33 = temp3*zr;
real ddsc51 = temp5*ddsc31;
real ddsc52 = temp5*ddsc32;
real ddsc53 = temp5*ddsc33;
real ddsc71 = temp7*ddsc51;
real ddsc72 = temp7*ddsc52;
real ddsc73 = temp7*ddsc53;
real rr3 = rr1*rr1*rr1;
#ifdef APPLY_SCALE
temp3 = (gli1*pScale + glip1*dScale);
temp5 = (3*rr1*rr1)*(gli2*pScale + glip2*dScale);
temp7 = (15*rr3*rr1)*(gli3*pScale + glip3*dScale);
#else
temp3 = gli1;
temp5 = (3*rr1*rr1)*gli2;
temp7 = (15*rr3*rr1)*gli3;
#endif
ftm21 -= rr3*(temp3*ddsc31 + temp5*ddsc51 + temp7*ddsc71);
ftm22 -= rr3*(temp3*ddsc32 + temp5*ddsc52 + temp7*ddsc72);
ftm23 -= rr3*(temp3*ddsc33 + temp5*ddsc53 + temp7*ddsc73);
}
//K
real qk1 = atom2.quadrupoleXX;
real qk2 = atom2.quadrupoleXY;
real qk3 = atom2.quadrupoleXZ;
real qk5 = atom2.quadrupoleYY;
real qk6 = atom2.quadrupoleYZ;
real qk9 = -(qk1 + qk5);
real qkui1 = qk1*atom1.inducedDipole.x + qk2*atom1.inducedDipole.y + qk3*atom1.inducedDipole.z;
real qkuip1 = qk1*atom1.inducedDipolePolar.x + qk2*atom1.inducedDipolePolar.y + qk3*atom1.inducedDipolePolar.z;
ftm21 += bn2*(qkui1+qkuip1);
#ifdef APPLY_SCALE
ftm21 -= (qkui1*psc5 + qkuip1*dsc5);
#else
ftm21 -= (qkui1 + qkuip1)*psc5;
#endif
real qkui2 = qk2*atom1.inducedDipole.x + qk5*atom1.inducedDipole.y + qk6*atom1.inducedDipole.z;
real qkuip2 = qk2*atom1.inducedDipolePolar.x + qk5*atom1.inducedDipolePolar.y + qk6*atom1.inducedDipolePolar.z;
ftm22 += bn2*(qkui2+qkuip2);
#ifdef APPLY_SCALE
ftm22 -= ((qkui2)*psc5 + (qkuip2)*dsc5);
#else
ftm22 -= (qkui2 + qkuip2)*psc5;
#endif
real qkui3 = qk3*atom1.inducedDipole.x + qk6*atom1.inducedDipole.y + qk9*atom1.inducedDipole.z;
real qkuip3 = qk3*atom1.inducedDipolePolar.x + qk6*atom1.inducedDipolePolar.y + qk9*atom1.inducedDipolePolar.z;
ftm23 += bn2*(qkui3+qkuip3);
#ifdef APPLY_SCALE
ftm23 -= ((qkui3)*psc5 + (qkuip3)*dsc5);
#else
ftm23 -= (qkui3 + qkuip3)*psc5;
#endif
real qkr1 = qk1*xr + qk2*yr + qk3*zr;
real qkr2 = qk2*xr + qk5*yr + qk6*zr;
real qkr3 = qk3*xr + qk6*yr + qk9*zr;
real dk1 = atom2.dipole.x;
real dk2 = atom2.dipole.y;
real dk3 = atom2.dipole.z;
real sc4 = dk1*xr + dk2*yr + dk3*zr;
real sc6 = qkr1*xr + qkr2*yr + qkr3*zr;
real ck = atom2.q;
real gfi2 = (-ck*bn1 + sc4*bn2 - sc6*bn3);
prefactor1 = 0.5f*(ck*psc3 - sc4*psc5 + sc6*psc7 + gfi2);
ftm21 += prefactor1*atom1.inducedDipole.x;
ftm22 += prefactor1*atom1.inducedDipole.y;
ftm23 += prefactor1*atom1.inducedDipole.z;
#ifdef APPLY_SCALE
prefactor1 = 0.5f*(ck*dsc3 - sc4*dsc5 + sc6*dsc7 + gfi2);
#endif
ftm21 += prefactor1*atom1.inducedDipolePolar.x;
ftm22 += prefactor1*atom1.inducedDipolePolar.y;
ftm23 += prefactor1*atom1.inducedDipolePolar.z;
real sci3 = atom1.inducedDipole.x*xr + atom1.inducedDipole.y*yr + atom1.inducedDipole.z*zr;
energy += forceFactor*0.5f*sci3*(ck*(bn1-psc3) - sc4*(bn2-psc5) + sc6*(bn3-psc7));
real scip3 = atom1.inducedDipolePolar.x*xr + atom1.inducedDipolePolar.y*yr + atom1.inducedDipolePolar.z*zr;
#ifndef DIRECT_POLARIZATION
#ifdef APPLY_SCALE
prefactor1 = 0.5f*(bn2 - usc5);
#else
prefactor1 = 0.5f*(bn2 - psc5);
#endif
ftm21 += prefactor1*(sci3*atom2.inducedDipolePolar.x + scip3*atom2.inducedDipole.x);
ftm22 += prefactor1*(sci3*atom2.inducedDipolePolar.y + scip3*atom2.inducedDipole.y);
ftm23 += prefactor1*(sci3*atom2.inducedDipolePolar.z + scip3*atom2.inducedDipole.z);
real sci34;
real sci4 = atom2.inducedDipole.x*xr + atom2.inducedDipole.y*yr + atom2.inducedDipole.z*zr;
real scip4 = atom2.inducedDipolePolar.x*xr + atom2.inducedDipolePolar.y*yr + atom2.inducedDipolePolar.z*zr;
sci34 = (sci3*scip4+scip3*sci4);
#ifdef APPLY_SCALE
gfi1 = sci34*(usc5*(5*rr1*rr1) -bn3);
#else
gfi1 = sci34*(psc5*(5*rr1*rr1) -bn3);
#endif
#else
gfi1 = 0;
#endif
#ifdef APPLY_SCALE
prefactor1 = 0.5f*(bn2*(sci3+scip3) - (sci3*psc5+scip3*dsc5));
#else
sci3 += scip3;
prefactor1 = 0.5f*sci3*(bn2 - psc5);
#endif
ftm21 += prefactor1*dk1;
ftm22 += prefactor1*dk2;
ftm23 += prefactor1*dk3;
#ifdef APPLY_SCALE
real gfi6 = -bn3*(sci3+scip3) + (sci3*psc7+scip3*dsc7);
#else
real gfi6 = sci3*(psc7 - bn3);
#endif
ftm21 += gfi6*qkr1;
ftm22 += gfi6*qkr2;
ftm23 += gfi6*qkr3;
real sci1 = atom1.inducedDipole.x*dk1 + atom1.inducedDipole.y*dk2 + atom1.inducedDipole.z*dk3 + di1*atom2.inducedDipole.x + di2*atom2.inducedDipole.y + di3*atom2.inducedDipole.z;
energy += forceFactor*0.5f*(sci1*(bn1-psc3));
real sci8 = qkr1*atom1.inducedDipole.x + qkr2*atom1.inducedDipole.y + qkr3*atom1.inducedDipole.z;
energy -= forceFactor*sci8*(bn2-psc5);
real scip1 = atom1.inducedDipolePolar.x*dk1 + atom1.inducedDipolePolar.y*dk2 + atom1.inducedDipolePolar.z*dk3 + di1*atom2.inducedDipolePolar.x + di2*atom2.inducedDipolePolar.y + di3*atom2.inducedDipolePolar.z;
#ifndef APPLY_SCALE
sci1 += scip1;
#endif
real scip2 = atom1.inducedDipole.x*atom2.inducedDipolePolar.x +
atom1.inducedDipole.y*atom2.inducedDipolePolar.y +
atom1.inducedDipole.z*atom2.inducedDipolePolar.z +
atom2.inducedDipole.x*atom1.inducedDipolePolar.x +
atom2.inducedDipole.y*atom1.inducedDipolePolar.y +
atom2.inducedDipole.z*atom1.inducedDipolePolar.z;
real scip8 = qkr1*atom1.inducedDipolePolar.x + qkr2*atom1.inducedDipolePolar.y + qkr3*atom1.inducedDipolePolar.z;
#ifndef APPLY_SCALE
sci8 += scip8;
#endif
gli1 = ck*sci3 + sci1;
gli2 = -(sci3*sc4 + 2*sci8);
gli3 = sci3*sc6;
#ifdef APPLY_SCALE
glip1 = ck*scip3 + scip1;
glip2 = -(scip3*sc4 + 2*scip8);
glip3 = scip3*sc6;
#endif
#ifdef APPLY_SCALE
gfi1 += (bn2*(gli1+glip1) + bn3*(gli2+glip2) + bn4*(gli3+glip3));
gfi1 -= (rr1*rr1)*(3*(gli1*psc3 + glip1*dsc3) + 5*(gli2*psc5 + glip2*dsc5) + 7*(gli3*psc7+glip3*dsc7));
#else
gfi1 += (bn2*gli1 + bn3*gli2 + bn4*gli3);
gfi1 -= (rr1*rr1)*(3*gli1*psc3 + 5*gli2*psc5 + 7*gli3*psc7);
#endif
#ifndef DIRECT_POLARIZATION
#ifdef APPLY_SCALE
gfi1 += scip2*(bn2 - (3*rr1*rr1)*usc3);
#else
gfi1 += scip2*(bn2 - (3*rr1*rr1)*psc3);
#endif
#endif
gfi1 *= 0.5f;
ftm21 += gfi1*xr;
ftm22 += gfi1*yr;
ftm23 += gfi1*zr;
if (damp != 0) {
real expdamp = EXP(damp);
real temp3 = -1.5f*damp*expdamp*rr1*rr1;
real temp5 = -damp;
real temp7 = -0.2f - 0.6f*damp;
real ddsc31 = temp3*xr;
real ddsc32 = temp3*yr;
real ddsc33 = temp3*zr;
real ddsc51 = temp5*ddsc31;
real ddsc52 = temp5*ddsc32;
real ddsc53 = temp5*ddsc33;
real ddsc71 = temp7*ddsc51;
real ddsc72 = temp7*ddsc52;
real ddsc73 = temp7*ddsc53;
real rr3 = rr1*rr1*rr1;
#ifdef APPLY_SCALE
temp3 = gli1*pScale + glip1*dScale;
temp5 = (3*rr1*rr1)*(gli2*pScale + glip2*dScale);
temp7 = (15*rr3*rr1)*(gli3*pScale + glip3*dScale);
#else
temp3 = gli1;
temp5 = (3*rr1*rr1)*gli2;
temp7 = (15*rr3*rr1)*(gli3);
#endif
ftm21 -= rr3*(temp3*ddsc31 + temp5*ddsc51 + temp7*ddsc71);
ftm22 -= rr3*(temp3*ddsc32 + temp5*ddsc52 + temp7*ddsc72);
ftm23 -= rr3*(temp3*ddsc33 + temp5*ddsc53 + temp7*ddsc73);
#ifndef DIRECT_POLARIZATION
#ifdef APPLY_SCALE
temp3 = uScale*scip2;
temp5 = -(3*rr1*rr1)*uScale*sci34;
#else
temp3 = scip2;
temp5 = -(3*rr1*rr1)*sci34;
#endif
ftm21 -= rr3*(temp3*ddsc31 + temp5*ddsc51);
ftm22 -= rr3*(temp3*ddsc32 + temp5*ddsc52);
ftm23 -= rr3*(temp3*ddsc33 + temp5*ddsc53);
#endif
}
force.x += ftm21;
force.y += ftm22;
force.z += ftm23;
}
__device__ void computeOneInteractionT1(AtomData& atom1, volatile AtomData& atom2, const real4 delta, const real4 bn
#ifdef APPLY_SCALE
, float dScale, float pScale, float mScale
#endif
) {
real xr = delta.x;
real yr = delta.y;
real zr = delta.z;
#ifdef APPLY_SCALE
real rr1 = delta.w;
#endif
// set the permanent multipole and induced dipole values;
real di1 = atom1.dipole.x;
real di2 = atom1.dipole.y;
real di3 = atom1.dipole.z;
real qi1 = atom1.quadrupoleXX;
real qi2 = atom1.quadrupoleXY;
real qi3 = atom1.quadrupoleXZ;
real qi5 = atom1.quadrupoleYY;
real qi6 = atom1.quadrupoleYZ;
//real qi9 = atom1.labFrameQuadrupole[5];
real qi9 = -(atom1.quadrupoleXX + atom1.quadrupoleYY);
real ck = atom2.q;
real dk1 = atom2.dipole.x;
real dk2 = atom2.dipole.y;
real dk3 = atom2.dipole.z;
real qk1 = atom2.quadrupoleXX;
real qk2 = atom2.quadrupoleXY;
real qk3 = atom2.quadrupoleXZ;
real qk5 = atom2.quadrupoleYY;
real qk6 = atom2.quadrupoleYZ;
//real qk9 = atom2.labFrameQuadrupole[5];
real qk9 = -(atom2.quadrupoleXX + atom2.quadrupoleYY);
real bn1 = bn.x;
real bn2 = bn.y;
real bn3 = bn.z;
real bn4 = bn.w;
// apply Thole polarization damping to scale factors
#ifdef APPLY_SCALE
real rr2 = rr1*rr1;
real rr3 = rr1*rr2;
real rr5 = 3*rr3*rr2;
real rr7 = 5*rr5*rr2;
real rr9 = 7*rr7*rr2;
real scale = 1-mScale;
real prefactor = scale*rr3 - bn1;
#else
real prefactor = -bn1;
#endif
real dixdk1 = di2*dk3 - di3*dk2;
real ttm21 = prefactor*dixdk1;
real dixdk2 = di3*dk1 - di1*dk3;
real ttm22 = prefactor*dixdk2;
real dixdk3 = di1*dk2 - di2*dk1;
real ttm23 = prefactor*dixdk3;
real qir1 = qi1*xr + qi2*yr + qi3*zr;
real qir2 = qi2*xr + qi5*yr + qi6*zr;
real qir3 = qi3*xr + qi6*yr + qi9*zr;
real qkr1 = qk1*xr + qk2*yr + qk3*zr;
real qkr2 = qk2*xr + qk5*yr + qk6*zr;
real qkr3 = qk3*xr + qk6*yr + qk9*zr;
real qiqkr1 = qi1*qkr1 + qi2*qkr2 + qi3*qkr3;
real qiqkr2 = qi2*qkr1 + qi5*qkr2 + qi6*qkr3;
real qiqkr3 = qi3*qkr1 + qi6*qkr2 + qi9*qkr3;
real rxqikr1 = yr*qiqkr3 - zr*qiqkr2;
real qkrxqir1 = qkr2*qir3 - qkr3*qir2;
#ifdef APPLY_SCALE
prefactor = 4*(bn3 - scale*rr7);
#else
prefactor = 4*bn3;
#endif
ttm21 -= prefactor*(rxqikr1+qkrxqir1);
real rxqikr2 = zr*qiqkr1 - xr*qiqkr3;
real qkrxqir2 = qkr3*qir1 - qkr1*qir3;
ttm22 -= prefactor*(rxqikr2+qkrxqir2);
real rxqikr3 = xr*qiqkr2 - yr*qiqkr1;
real qkrxqir3 = qkr1*qir2 - qkr2*qir1;
ttm23 -= prefactor*(rxqikr3+qkrxqir3);
real qidk1 = qi1*dk1 + qi2*dk2 + qi3*dk3;
real qidk2 = qi2*dk1 + qi5*dk2 + qi6*dk3;
real qidk3 = qi3*dk1 + qi6*dk2 + qi9*dk3;
real dixqkr1 = di2*qkr3 - di3*qkr2;
real dkxqir1 = dk2*qir3 - dk3*qir2;
real rxqidk1 = yr*qidk3 - zr*qidk2;
real qixqk1 = qi2*qk3 + qi5*qk6 + qi6*qk9 - qi3*qk2 - qi6*qk5 - qi9*qk6;
#ifdef APPLY_SCALE
prefactor = 2*(bn2 - scale*rr5);
#else
prefactor = 2*bn2;
#endif
ttm21 += prefactor*(dixqkr1+dkxqir1+rxqidk1-2*qixqk1);
real dixqkr2 = di3*qkr1 - di1*qkr3;
real dkxqir2 = dk3*qir1 - dk1*qir3;
real rxqidk2 = zr*qidk1 - xr*qidk3;
real qixqk2 = qi3*qk1 + qi6*qk2 + qi9*qk3 - qi1*qk3 - qi2*qk6 - qi3*qk9;
ttm22 += prefactor*(dixqkr2+dkxqir2+rxqidk2-2*qixqk2);
real dixqkr3 = di1*qkr2 - di2*qkr1;
real dkxqir3 = dk1*qir2 - dk2*qir1;
real rxqidk3 = xr*qidk2 - yr*qidk1;
real qixqk3 = qi1*qk2 + qi2*qk5 + qi3*qk6 - qi2*qk1 - qi5*qk2 - qi6*qk3;
ttm23 += prefactor*(dixqkr3+dkxqir3+rxqidk3-2*qixqk3);
real sc4 = dk1*xr + dk2*yr + dk3*zr;
real sc6 = qkr1*xr + qkr2*yr + qkr3*zr;
real gf2 = -ck*bn1 + sc4*bn2 - sc6*bn3;
#ifdef APPLY_SCALE
real gfr2 = -ck*rr3 + sc4*rr5 - sc6*rr7;
prefactor = (gf2 - scale*gfr2);
#else
prefactor = gf2;
#endif
ttm21 += prefactor*(di2*zr - di3*yr);
ttm22 += prefactor*(di3*xr - di1*zr);
ttm23 += prefactor*(di1*yr - di2*xr);
real gf5 = (-ck*bn2+sc4*bn3-sc6*bn4);
#ifdef APPLY_SCALE
real gfr5 = (-ck*rr5+sc4*rr7-sc6*rr9);
prefactor = 2*(gf5 - scale*gfr5);
#else
prefactor = 2*gf5;
#endif
real rxqir1 = yr*qir3 - zr*qir2;
real rxqir2 = zr*qir1 - xr*qir3;
real rxqir3 = xr*qir2 - yr*qir1;
ttm21 -= prefactor*rxqir1;
ttm22 -= prefactor*rxqir2;
ttm23 -= prefactor*rxqir3;
atom1.torque.x += ttm21;
atom1.torque.y += ttm22;
atom1.torque.z += ttm23;
}
__device__ void computeOneInteractionT2(AtomData& atom1, volatile AtomData& atom2, const real4 delta, const real4 bn
#ifdef APPLY_SCALE
, float dScale, float pScale, float mScale
#endif
) {
real xr = delta.x;
real yr = delta.y;
real zr = delta.z;
real rr1 = delta.w;
// set the permanent multipole and induced dipole values;
real di1 = atom1.dipole.x;
real di2 = atom1.dipole.y;
real di3 = atom1.dipole.z;
real qi1 = atom1.quadrupoleXX;
real qi2 = atom1.quadrupoleXY;
real qi3 = atom1.quadrupoleXZ;
real qi5 = atom1.quadrupoleYY;
real qi6 = atom1.quadrupoleYZ;
real qi9 = -(atom1.quadrupoleXX + atom1.quadrupoleYY);
real bn1 = bn.x;
real bn2 = bn.y;
real bn3 = bn.z;
// apply Thole polarization damping to scale factors
real scale3 = 1;
real scale5 = 1;
real scale7 = 1;
real damp = atom1.damp*atom2.damp;
if (damp != 0) {
real pgamma = atom1.thole < atom2.thole ? atom1.thole : atom2.thole;
real ratio = RECIP(rr1*damp);
damp = -pgamma*ratio*ratio*ratio;
if (damp > -50) {
real expdamp = EXP(damp);
scale3 = 1 - expdamp;
scale5 = 1 - (1-damp)*expdamp;
scale7 = 1 - (1-damp+0.6f*damp*damp)*expdamp;
}
}
real rr3 = rr1*rr1*rr1;
#ifdef APPLY_SCALE
real dsc3 = rr3*(1 - scale3*dScale);
real dsc5 = (3*rr3*rr1*rr1)* (1 - scale5*dScale);
real dsc7 = (15*rr3*rr3*rr1)*(1 - scale7*dScale);
real psc3 = rr3*(1 - scale3*pScale);
real psc5 = (3*rr3*rr1*rr1)*(1 - scale5*pScale);
real psc7 = (15*rr3*rr3*rr1)*(1 - scale7*pScale);
#else
real psc3 = rr3*(1 - scale3);
real psc5 = (3*rr3*rr1*rr1)*(1 - scale5);
real psc7 = (15*rr3*rr3*rr1)*(1 - scale7);
#endif
real prefactor1 = 0.5f*(psc3 - bn1);
#ifdef APPLY_SCALE
real prefactor2 = 0.5f*(dsc3 - bn1);
#endif
real dixuk1 = di2*atom2.inducedDipole.z - di3*atom2.inducedDipole.y;
real dixukp1 = di2*atom2.inducedDipolePolar.z - di3*atom2.inducedDipolePolar.y;
#ifdef APPLY_SCALE
real ttm2i1 = prefactor1*dixuk1 + prefactor2*dixukp1;
#else
real ttm2i1 = prefactor1*(dixuk1 + dixukp1);
#endif
real dixuk2 = di3*atom2.inducedDipole.x - di1*atom2.inducedDipole.z;
real dixukp2 = di3*atom2.inducedDipolePolar.x - di1*atom2.inducedDipolePolar.z;
#ifdef APPLY_SCALE
real ttm2i2 = prefactor1*dixuk2 + prefactor2*dixukp2;
#else
real ttm2i2 = prefactor1*(dixuk2 + dixukp2);
#endif
real dixuk3 = di1*atom2.inducedDipole.y - di2*atom2.inducedDipole.x;
real dixukp3 = di1*atom2.inducedDipolePolar.y - di2*atom2.inducedDipolePolar.x;
#ifdef APPLY_SCALE
real ttm2i3 = prefactor1*dixuk3 + prefactor2*dixukp3;
#else
real ttm2i3 = prefactor1*(dixuk3 + dixukp3);
#endif
real sci4 = atom2.inducedDipole.x*xr + atom2.inducedDipole.y*yr + atom2.inducedDipole.z*zr;
real scip4 = atom2.inducedDipolePolar.x*xr + atom2.inducedDipolePolar.y*yr + atom2.inducedDipolePolar.z*zr;
real gti2 = bn2*(sci4+scip4);
#ifdef APPLY_SCALE
real gtri2 = (sci4*psc5+scip4*dsc5);
#else
real gtri2 = psc5*(sci4+scip4);
#endif
prefactor1 = 0.5f*(gti2 - gtri2);
ttm2i1 += prefactor1*(di2*zr - di3*yr);
ttm2i2 += prefactor1*(di3*xr - di1*zr);
ttm2i3 += prefactor1*(di1*yr - di2*xr);
real qir1 = qi1*xr + qi2*yr + qi3*zr;
real qir2 = qi2*xr + qi5*yr + qi6*zr;
real qir3 = qi3*xr + qi6*yr + qi9*zr;
#ifdef APPLY_SCALE
prefactor1 = sci4*psc7 + scip4*dsc7 - bn3*(sci4+scip4);
#else
prefactor1 = psc7*(sci4+scip4) - bn3*(sci4+scip4);
#endif
ttm2i1 += prefactor1*(yr*qir3 - zr*qir2);
ttm2i2 += prefactor1*(zr*qir1 - xr*qir3);
ttm2i3 += prefactor1*(xr*qir2 - yr*qir1);
real qiuk1 = qi1*atom2.inducedDipole.x + qi2*atom2.inducedDipole.y + qi3*atom2.inducedDipole.z;
real qiuk2 = qi2*atom2.inducedDipole.x + qi5*atom2.inducedDipole.y + qi6*atom2.inducedDipole.z;
real qiuk3 = qi3*atom2.inducedDipole.x + qi6*atom2.inducedDipole.y + qi9*atom2.inducedDipole.z;
real qiukp1 = qi1*atom2.inducedDipolePolar.x + qi2*atom2.inducedDipolePolar.y + qi3*atom2.inducedDipolePolar.z;
real qiukp2 = qi2*atom2.inducedDipolePolar.x + qi5*atom2.inducedDipolePolar.y + qi6*atom2.inducedDipolePolar.z;
real qiukp3 = qi3*atom2.inducedDipolePolar.x + qi6*atom2.inducedDipolePolar.y + qi9*atom2.inducedDipolePolar.z;
prefactor1 = (bn2 - psc5);
#ifdef APPLY_SCALE
prefactor2 = (bn2 - dsc5);
#endif
real ukxqir1 = atom2.inducedDipole.y*qir3 - atom2.inducedDipole.z*qir2;
real ukxqirp1 = atom2.inducedDipolePolar.y*qir3 - atom2.inducedDipolePolar.z*qir2;
real rxqiuk1 = yr*qiuk3 - zr*qiuk2;
real rxqiukp1 = yr*qiukp3 - zr*qiukp2;
#ifdef APPLY_SCALE
ttm2i1 += prefactor1*(ukxqir1 + rxqiuk1) + prefactor2*(ukxqirp1 + rxqiukp1);
#else
ttm2i1 += prefactor1*(ukxqir1 + rxqiuk1 + ukxqirp1 + rxqiukp1);
#endif
real ukxqir2 = atom2.inducedDipole.z*qir1 - atom2.inducedDipole.x*qir3;
real ukxqirp2 = atom2.inducedDipolePolar.z*qir1 - atom2.inducedDipolePolar.x*qir3;
real rxqiuk2 = zr*qiuk1 - xr*qiuk3;
real rxqiukp2 = zr*qiukp1 - xr*qiukp3;
#ifdef APPLY_SCALE
ttm2i2 += prefactor1*(ukxqir2 + rxqiuk2) + prefactor2*(ukxqirp2 + rxqiukp2);
#else
ttm2i2 += prefactor1*(ukxqir2 + rxqiuk2 + ukxqirp2 + rxqiukp2);
#endif
real ukxqir3 = atom2.inducedDipole.x*qir2 - atom2.inducedDipole.y*qir1;
real ukxqirp3 = atom2.inducedDipolePolar.x*qir2 - atom2.inducedDipolePolar.y*qir1;
real rxqiuk3 = xr*qiuk2 - yr*qiuk1;
real rxqiukp3 = xr*qiukp2 - yr*qiukp1;
#ifdef APPLY_SCALE
ttm2i3 += prefactor1*(ukxqir3 + rxqiuk3) + prefactor2*(ukxqirp3 + rxqiukp3);
#else
ttm2i3 += prefactor1*(ukxqir3 + rxqiuk3 + ukxqirp3 + rxqiukp3);
#endif
atom1.torque.x += ttm2i1;
atom1.torque.y += ttm2i2;
atom1.torque.z += ttm2i3;
}
__device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, bool hasExclusions, float dScale, float pScale, float mScale, float forceFactor,
real& energy, real4 periodicBoxSize, real4 invPeriodicBoxSize) {
float4 delta;
delta.x = atom2.pos.x - atom1.pos.x;
delta.y = atom2.pos.y - atom1.pos.y;
delta.z = atom2.pos.z - atom1.pos.z;
// periodic box
delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x;
delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y;
delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;
delta.w = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z;
if (delta.w > CUTOFF_SQUARED)
return;
real r = SQRT(delta.w);
real ralpha = EWALD_ALPHA*r;
real alsq2 = 2*EWALD_ALPHA*EWALD_ALPHA;
real alsq2n = 0;
if (EWALD_ALPHA > 0)
alsq2n = RECIP(SQRT(M_PI)*EWALD_ALPHA);
real exp2a = EXP(-(ralpha*ralpha));
real rr1 = RECIP(r);
delta.w = rr1;
real bn0 = erfc(ralpha)*rr1;
energy += forceFactor*atom1.q*atom2.q*bn0;
real rr2 = rr1*rr1;
alsq2n *= alsq2;
float4 bn;
bn.x = (bn0+alsq2n*exp2a)*rr2;
alsq2n *= alsq2;
bn.y = (3*bn.x+alsq2n*exp2a)*rr2;
alsq2n *= alsq2;
bn.z = (5*bn.y+alsq2n*exp2a)*rr2;
alsq2n *= alsq2;
bn.w = (7*bn.z+alsq2n*exp2a)*rr2;
alsq2n *= alsq2;
real bn5 = (9*bn.w+alsq2n*exp2a)*rr2;
real3 force;
// if (hasExclusions) {
computeOneInteractionF1(atom1, atom2, delta, bn, bn5, forceFactor, dScale, pScale, mScale, force, energy);
computeOneInteractionF2(atom1, atom2, delta, bn, forceFactor, dScale, pScale, mScale, force, energy);
// } else {
// computeOneInteractionF1(atom1, atom2, delta, bn, bn5, forceFactor, force, energy);
// computeOneInteractionF2(atom1, atom2, delta, bn, forceFactor, force, energy);
// }
atom1.force += force;
if (forceFactor == 1)
atom2.force -= force;
computeOneInteractionT1(atom1, atom2, delta, bn, dScale, pScale, mScale);
computeOneInteractionT2(atom1, atom2, delta, bn, dScale, pScale, mScale);
if (forceFactor == 1) {
// T3 == T1 w/ particles I and J reversed
// T4 == T2 w/ particles I and J reversed
delta.x = -delta.x;
delta.y = -delta.y;
delta.z = -delta.z;
computeOneInteractionT1(atom2, atom1, delta, bn, dScale, pScale, mScale);
computeOneInteractionT2(atom2, atom1, delta, bn, dScale, pScale, mScale);
}
}
/**
* Compute the self energy and self torque.
*/
__device__ void computeSelfEnergyAndTorque(AtomData& atom1, real& energy) {
real term = 2*EWALD_ALPHA*EWALD_ALPHA;
real fterm = -EWALD_ALPHA/SQRT(M_PI);
real cii = atom1.q*atom1.q;
real dii = dot(atom1.dipole, atom1.dipole);
real qii = 2*(atom1.quadrupoleXX*atom1.quadrupoleXX +
atom1.quadrupoleYY*atom1.quadrupoleYY +
atom1.quadrupoleXX*atom1.quadrupoleYY +
atom1.quadrupoleXY*atom1.quadrupoleXY +
atom1.quadrupoleXZ*atom1.quadrupoleXZ +
atom1.quadrupoleYZ*atom1.quadrupoleYZ);
real uii = dot(atom1.dipole, atom1.inducedDipole);
real selfEnergy = (cii + term*(dii/3 + 2*term*qii/5));
selfEnergy += term*uii/3;
selfEnergy *= fterm;
energy += selfEnergy;
// self-torque for PME
real3 ui = atom1.inducedDipole+atom1.inducedDipolePolar;
atom1.torque += ((2/(real) 3)*(EWALD_ALPHA*EWALD_ALPHA*EWALD_ALPHA)/SQRT(M_PI))*cross(atom1.dipole, ui);
}
\ No newline at end of file
#define TILE_SIZE 32
#define WARPS_PER_GROUP (THREAD_BLOCK_SIZE/TILE_SIZE)
typedef struct {
real3 pos, force, torque, dipole, inducedDipole, inducedDipolePolar;
real q, quadrupoleXX, quadrupoleXY, quadrupoleXZ;
real quadrupoleYY, quadrupoleYZ;
float thole, damp, padding;
} AtomData;
__device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, bool hasExclusions, float dScale, float pScale, float mScale, float forceFactor, real& energy, real4 periodicBoxSize, real4 invPeriodicBoxSize);
__device__ void computeSelfEnergyAndTorque(AtomData& atom1, real& energy);
inline __device__ void loadAtomData(AtomData& data, int atom, const real4* __restrict__ posq, const real* __restrict__ labFrameDipole,
const real* __restrict__ labFrameQuadrupole, const real* __restrict__ inducedDipole, const real* __restrict__ inducedDipolePolar, const float2* __restrict__ dampingAndThole) {
real4 atomPosq = posq[atom];
data.pos = make_real3(atomPosq.x, atomPosq.y, atomPosq.z);
data.q = atomPosq.w;
data.dipole.x = labFrameDipole[atom*3];
data.dipole.y = labFrameDipole[atom*3+1];
data.dipole.z = labFrameDipole[atom*3+2];
data.quadrupoleXX = labFrameQuadrupole[atom*5];
data.quadrupoleXY = labFrameQuadrupole[atom*5+1];
data.quadrupoleXZ = labFrameQuadrupole[atom*5+2];
data.quadrupoleYY = labFrameQuadrupole[atom*5+3];
data.quadrupoleYZ = labFrameQuadrupole[atom*5+4];
data.inducedDipole.x = inducedDipole[atom*3];
data.inducedDipole.y = inducedDipole[atom*3+1];
data.inducedDipole.z = inducedDipole[atom*3+2];
data.inducedDipolePolar.x = inducedDipolePolar[atom*3];
data.inducedDipolePolar.y = inducedDipolePolar[atom*3+1];
data.inducedDipolePolar.z = inducedDipolePolar[atom*3+2];
float2 temp = dampingAndThole[atom];
data.damp = temp.x;
data.thole = temp.y;
}
__device__ real computeDScaleFactor(unsigned int polarizationGroup) {
return (polarizationGroup & 1 ? 0 : 1);
}
__device__ float computeMScaleFactor(uint2 covalent) {
bool x = (covalent.x & 1);
bool y = (covalent.y & 1);
return (x ? (y ? 0.0f : 0.4f) : (y ? 0.8f : 1.0f));
}
__device__ float computePScaleFactor(uint2 covalent, unsigned int polarizationGroup) {
bool x = (covalent.x & 1);
bool y = (covalent.y & 1);
bool p = (polarizationGroup & 1);
return (x && y ? 0.0f : (x && p ? 0.5f : 1.0f));
}
/**
* Compute electrostatic interactions.
*/
extern "C" __global__ void computeElectrostatics(
unsigned long long* __restrict__ forceBuffers, unsigned long long* __restrict__ torqueBuffers, real* __restrict__ energyBuffer,
const real4* __restrict__ posq, const unsigned int* __restrict__ exclusionIndices, const unsigned int* __restrict__ exclusionRowIndices,
const uint2* __restrict__ covalentFlags, const unsigned int* __restrict__ polarizationGroupFlags, unsigned int startTileIndex, unsigned int numTileIndices,
#ifdef USE_CUTOFF
const ushort2* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, unsigned int maxTiles, const unsigned int* __restrict__ interactionFlags,
#endif
const real* __restrict__ labFrameDipole, const real* __restrict__ labFrameQuadrupole, const real* __restrict__ inducedDipole,
const real* __restrict__ inducedDipolePolar, const float2* __restrict__ dampingAndThole) {
unsigned int totalWarps = (blockDim.x*gridDim.x)/TILE_SIZE;
unsigned int warp = (blockIdx.x*blockDim.x+threadIdx.x)/TILE_SIZE;
#ifdef USE_CUTOFF
const unsigned int numTiles = interactionCount[0];
unsigned int pos = (numTiles > maxTiles ? startTileIndex+warp*numTileIndices/totalWarps : warp*numTiles/totalWarps);
unsigned int end = (numTiles > maxTiles ? startTileIndex+(warp+1)*numTileIndices/totalWarps : (warp+1)*numTiles/totalWarps);
#else
const unsigned int numTiles = numTileIndices;
unsigned int pos = startTileIndex+warp*numTiles/totalWarps;
unsigned int end = startTileIndex+(warp+1)*numTiles/totalWarps;
#endif
real energy = 0;
__shared__ AtomData localData[THREAD_BLOCK_SIZE];
__shared__ unsigned int exclusionRange[2*WARPS_PER_GROUP];
__shared__ int exclusionIndex[WARPS_PER_GROUP];
#ifndef ENABLE_SHUFFLE
__shared__ real tempBuffer[3*THREAD_BLOCK_SIZE];
#endif
do {
// Extract the coordinates of this tile
const unsigned int tgx = threadIdx.x & (TILE_SIZE-1);
const unsigned int tbx = threadIdx.x - tgx;
const unsigned int localGroupIndex = threadIdx.x/TILE_SIZE;
unsigned int x, y;
AtomData data;
if (pos < end) {
#ifdef USE_CUTOFF
if (numTiles <= maxTiles) {
ushort2 tileIndices = tiles[pos];
x = tileIndices.x;
y = tileIndices.y;
}
else
#endif
{
y = (unsigned int) floor(NUM_BLOCKS+0.5f-SQRT((NUM_BLOCKS+0.5f)*(NUM_BLOCKS+0.5f)-2*pos));
x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
if (x < y || x >= NUM_BLOCKS) { // Occasionally happens due to roundoff error.
y += (x < y ? -1 : 1);
x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
}
}
unsigned int atom1 = x*TILE_SIZE + tgx;
loadAtomData(data, atom1, posq, labFrameDipole, labFrameQuadrupole, inducedDipole, inducedDipolePolar, dampingAndThole);
data.force = make_real3(0);
data.torque = make_real3(0);
// Locate the exclusion data for this tile.
if (tgx < 2)
exclusionRange[2*localGroupIndex+tgx] = exclusionRowIndices[x+tgx];
if (tgx == 0)
exclusionIndex[localGroupIndex] = -1;
for (unsigned int i = exclusionRange[2*localGroupIndex]+tgx; i < exclusionRange[2*localGroupIndex+1]; i += TILE_SIZE)
if (exclusionIndices[i] == y)
exclusionIndex[localGroupIndex] = i*TILE_SIZE;
bool hasExclusions = (exclusionIndex[localGroupIndex] > -1);
if (pos >= end)
; // This warp is done.
else if (x == y) {
// This tile is on the diagonal.
localData[threadIdx.x].pos = data.pos;
localData[threadIdx.x].q = data.q;
localData[threadIdx.x].dipole = data.dipole;
localData[threadIdx.x].quadrupoleXX = data.quadrupoleXX;
localData[threadIdx.x].quadrupoleXY = data.quadrupoleXY;
localData[threadIdx.x].quadrupoleXZ = data.quadrupoleXZ;
localData[threadIdx.x].quadrupoleYY = data.quadrupoleYY;
localData[threadIdx.x].quadrupoleYZ = data.quadrupoleYZ;
localData[threadIdx.x].inducedDipole = data.inducedDipole;
localData[threadIdx.x].inducedDipolePolar = data.inducedDipolePolar;
localData[threadIdx.x].thole = data.thole; // IS THIS CORRECT?
localData[threadIdx.x].damp = data.damp; // IS THIS CORRECT?
uint2 covalent = covalentFlags[exclusionIndex[localGroupIndex]+tgx];
unsigned int polarizationGroup = polarizationGroupFlags[exclusionIndex[localGroupIndex]+tgx];
// Compute forces.
for (unsigned int j = 0; j < TILE_SIZE; j++) {
int atom2 = y*TILE_SIZE+j;
if (atom1 != atom2 && atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) {
float d = computeDScaleFactor(polarizationGroup);
float p = computePScaleFactor(covalent, polarizationGroup);
float m = computeMScaleFactor(covalent);
computeOneInteraction(data, localData[tbx+j], hasExclusions, d, p, m, 0.5f, energy, periodicBoxSize, invPeriodicBoxSize);
}
covalent.x >>= 1;
covalent.y >>= 1;
polarizationGroup >>= 1;
}
if (atom1 < NUM_ATOMS)
computeSelfEnergyAndTorque(data, energy);
data.force *= -ENERGY_SCALE_FACTOR;
data.torque *= ENERGY_SCALE_FACTOR;
atomicAdd(&forceBuffers[atom1], static_cast<unsigned long long>((long long) (data.force.x*0xFFFFFFFF)));
atomicAdd(&forceBuffers[atom1+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.y*0xFFFFFFFF)));
atomicAdd(&forceBuffers[atom1+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.z*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[atom1], static_cast<unsigned long long>((long long) (data.torque.x*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[atom1+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.torque.y*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[atom1+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.torque.z*0xFFFFFFFF)));
}
else {
// This is an off-diagonal tile.
unsigned int j = y*TILE_SIZE + tgx;
loadAtomData(localData[threadIdx.x], j, posq, labFrameDipole, labFrameQuadrupole, inducedDipole, inducedDipolePolar, dampingAndThole);
localData[threadIdx.x].force = make_real3(0);
localData[threadIdx.x].torque = make_real3(0);
#ifdef USE_CUTOFF
// unsigned int flags = (numTiles <= maxTiles ? interactionFlags[pos] : 0xFFFFFFFF);
// if (!hasExclusions && flags != 0xFFFFFFFF) {
// if (flags == 0) {
// // No interactions in this tile.
// }
// else {
// // Compute only a subset of the interactions in this tile.
//
// for (j = 0; j < TILE_SIZE; j++) {
// if ((flags&(1<<j)) != 0) {
// int atom2 = tbx+j;
// computeOneInteraction(data, localData[tbx+j], false, 1, 1, 1, 1, energy, periodicBoxSize, invPeriodicBoxSize));
// data.force += tempForce;
// localData[atom2].force -= tempForce;
// energy += tempEnergy;
// if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) {
//#ifdef ENABLE_SHUFFLE
// for (int i = 16; i >= 1; i /= 2) {
// tempForce.x += __shfl_xor(tempForce.x, i, 32);
// tempForce.y += __shfl_xor(tempForce.y, i, 32);
// tempForce.z += __shfl_xor(tempForce.z, i, 32);
// }
// if (tgx == 0)
// localData[atom2].force -= tempForce;
//#else
// int bufferIndex = 3*threadIdx.x;
// tempBuffer[bufferIndex] = tempForce.x;
// tempBuffer[bufferIndex+1] = tempForce.y;
// tempBuffer[bufferIndex+2] = tempForce.z;
// if (tgx % 4 == 0) {
// tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9];
// tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10];
// tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11];
// }
// if (tgx == 0) {
// localData[atom2].force.x -= tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84];
// localData[atom2].force.y -= tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85];
// localData[atom2].force.z -= tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86];
// }
//#endif
// }
// }
// }
// data.force *= -ENERGY_SCALE_FACTOR;
// localData[threadIdx.x].force *= -ENERGY_SCALE_FACTOR;
// if (pos < end) {
// unsigned int offset = x*TILE_SIZE + tgx;
// atomicAdd(&forceBuffers[offset], static_cast<unsigned long long>((long long) (data.force.x*0xFFFFFFFF)));
// atomicAdd(&forceBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.y*0xFFFFFFFF)));
// atomicAdd(&forceBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.z*0xFFFFFFFF)));
// offset = y*TILE_SIZE + tgx;
// atomicAdd(&forceBuffers[offset], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.x*0xFFFFFFFF)));
// atomicAdd(&forceBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.y*0xFFFFFFFF)));
// atomicAdd(&forceBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.z*0xFFFFFFFF)));
// }
//
// // Compute torques.
//
// for (j = 0; j < TILE_SIZE; j++) {
// if ((flags&(1<<j)) != 0) {
// int atom2 = tbx+j;
// real3 delta = make_real3(localData[atom2].posq.x-data.posq.x, localData[atom2].posq.y-data.posq.y, localData[atom2].posq.z-data.posq.z);
//#ifdef USE_PERIODIC
// delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x;
// delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y;
// delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;
//#endif
// real3 tempForce;
// computeOneInteractionT1(data, localData[atom2], 1, 1, 1, tempForce);
// data.force += tempForce;
// computeOneInteractionT3(data, localData[atom2], 1, 1, 1, tempForce);
// if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) {
//#ifdef ENABLE_SHUFFLE
// for (int i = 16; i >= 1; i /= 2) {
// tempForce.x += __shfl_xor(tempForce.x, i, 32);
// tempForce.y += __shfl_xor(tempForce.y, i, 32);
// tempForce.z += __shfl_xor(tempForce.z, i, 32);
// }
// if (tgx == 0)
// localData[atom2].force -= tempForce;
//#else
// int bufferIndex = 3*threadIdx.x;
// tempBuffer[bufferIndex] = tempForce.x;
// tempBuffer[bufferIndex+1] = tempForce.y;
// tempBuffer[bufferIndex+2] = tempForce.z;
// if (tgx % 4 == 0) {
// tempBuffer[bufferIndex] += tempBuffer[bufferIndex+3]+tempBuffer[bufferIndex+6]+tempBuffer[bufferIndex+9];
// tempBuffer[bufferIndex+1] += tempBuffer[bufferIndex+4]+tempBuffer[bufferIndex+7]+tempBuffer[bufferIndex+10];
// tempBuffer[bufferIndex+2] += tempBuffer[bufferIndex+5]+tempBuffer[bufferIndex+8]+tempBuffer[bufferIndex+11];
// }
// if (tgx == 0) {
// localData[atom2].force.x += tempBuffer[bufferIndex]+tempBuffer[bufferIndex+12]+tempBuffer[bufferIndex+24]+tempBuffer[bufferIndex+36]+tempBuffer[bufferIndex+48]+tempBuffer[bufferIndex+60]+tempBuffer[bufferIndex+72]+tempBuffer[bufferIndex+84];
// localData[atom2].force.y += tempBuffer[bufferIndex+1]+tempBuffer[bufferIndex+13]+tempBuffer[bufferIndex+25]+tempBuffer[bufferIndex+37]+tempBuffer[bufferIndex+49]+tempBuffer[bufferIndex+61]+tempBuffer[bufferIndex+73]+tempBuffer[bufferIndex+85];
// localData[atom2].force.z += tempBuffer[bufferIndex+2]+tempBuffer[bufferIndex+14]+tempBuffer[bufferIndex+26]+tempBuffer[bufferIndex+38]+tempBuffer[bufferIndex+50]+tempBuffer[bufferIndex+62]+tempBuffer[bufferIndex+74]+tempBuffer[bufferIndex+86];
// }
//#endif
// }
// }
// }
// data.force *= ENERGY_SCALE_FACTOR;
// localData[threadIdx.x].force *= ENERGY_SCALE_FACTOR;
// if (pos < end) {
// unsigned int offset = x*TILE_SIZE + tgx;
// atomicAdd(&torqueBuffers[offset], static_cast<unsigned long long>((long long) (data.force.x*0xFFFFFFFF)));
// atomicAdd(&torqueBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.y*0xFFFFFFFF)));
// atomicAdd(&torqueBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.z*0xFFFFFFFF)));
// offset = y*TILE_SIZE + tgx;
// atomicAdd(&torqueBuffers[offset], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.x*0xFFFFFFFF)));
// atomicAdd(&torqueBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.y*0xFFFFFFFF)));
// atomicAdd(&torqueBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.z*0xFFFFFFFF)));
// }
// }
// }
// else
#endif
{
// Compute the full set of interactions in this tile.
uint2 covalent = (hasExclusions ? covalentFlags[exclusionIndex[localGroupIndex]+tgx] : make_uint2(0, 0));
unsigned int polarizationGroup = (hasExclusions ? polarizationGroupFlags[exclusionIndex[localGroupIndex]+tgx] : 0);
covalent.x = (covalent.x >> tgx) | (covalent.x << (TILE_SIZE - tgx));
covalent.y = (covalent.y >> tgx) | (covalent.y << (TILE_SIZE - tgx));
polarizationGroup = (polarizationGroup >> tgx) | (polarizationGroup << (TILE_SIZE - tgx));
// Compute forces.
unsigned int tj = tgx;
for (j = 0; j < TILE_SIZE; j++) {
int atom2 = y*TILE_SIZE+tj;
if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) {
float d = computeDScaleFactor(polarizationGroup);
float p = computePScaleFactor(covalent, polarizationGroup);
float m = computeMScaleFactor(covalent);
computeOneInteraction(data, localData[tbx+tj], hasExclusions, d, p, m, 1, energy, periodicBoxSize, invPeriodicBoxSize);
}
covalent.x >>= 1;
covalent.y >>= 1;
polarizationGroup >>= 1;
tj = (tj + 1) & (TILE_SIZE - 1);
}
data.force *= -ENERGY_SCALE_FACTOR;
data.torque *= ENERGY_SCALE_FACTOR;
localData[threadIdx.x].force *= -ENERGY_SCALE_FACTOR;
localData[threadIdx.x].torque *= ENERGY_SCALE_FACTOR;
if (pos < end) {
unsigned int offset = x*TILE_SIZE + tgx;
atomicAdd(&forceBuffers[offset], static_cast<unsigned long long>((long long) (data.force.x*0xFFFFFFFF)));
atomicAdd(&forceBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.y*0xFFFFFFFF)));
atomicAdd(&forceBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.force.z*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[offset], static_cast<unsigned long long>((long long) (data.torque.x*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.torque.y*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (data.torque.z*0xFFFFFFFF)));
offset = y*TILE_SIZE + tgx;
atomicAdd(&forceBuffers[offset], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.x*0xFFFFFFFF)));
atomicAdd(&forceBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.y*0xFFFFFFFF)));
atomicAdd(&forceBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].force.z*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[offset], static_cast<unsigned long long>((long long) (localData[threadIdx.x].torque.x*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[offset+PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].torque.y*0xFFFFFFFF)));
atomicAdd(&torqueBuffers[offset+2*PADDED_NUM_ATOMS], static_cast<unsigned long long>((long long) (localData[threadIdx.x].torque.z*0xFFFFFFFF)));
}
}
}
}
pos++;
} while (pos < end);
energyBuffer[blockIdx.x*blockDim.x+threadIdx.x] += energy*ENERGY_SCALE_FACTOR;
}
...@@ -1368,6 +1368,1469 @@ static void testMultipoleGridPotential( FILE* log ) { ...@@ -1368,6 +1368,1469 @@ static void testMultipoleGridPotential( FILE* log ) {
} }
// setup for box of 216 water molecules -- used to test PME
static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::AmoebaNonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::AmoebaPolarizationType polarizationType,
double cutoff, int inputPmeGridDimension, std::vector<Vec3>& forces,
double& energy, FILE* log ){
// beginning of Multipole setup
System system;
// box dimensions
double boxDimension = 1.8643;
Vec3 a( boxDimension, 0.0, 0.0 );
Vec3 b( 0.0, boxDimension, 0.0 );
Vec3 c( 0.0, 0.0, boxDimension );
system.setDefaultPeriodicBoxVectors( a, b, c );
AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();;
int numberOfParticles = 648;
amoebaMultipoleForce->setNonbondedMethod( nonbondedMethod );
amoebaMultipoleForce->setPolarizationType( polarizationType );
amoebaMultipoleForce->setCutoffDistance( cutoff );
amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 );
amoebaMultipoleForce->setMutualInducedMaxIterations( 500 );
amoebaMultipoleForce->setAEwald( 5.4459052e+00 );
amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-04 );
std::vector<int> pmeGridDimension( 3 );
pmeGridDimension[0] = pmeGridDimension[1] = pmeGridDimension[2] = inputPmeGridDimension;
amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimension );
for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){
system.addParticle( 1.5995000e+01 );
system.addParticle( 1.0080000e+00 );
system.addParticle( 1.0080000e+00 );
}
std::vector<double> oxygenMolecularDipole(3);
std::vector<double> oxygenMolecularQuadrupole(9);
oxygenMolecularDipole[0] = 0.0000000e+00;
oxygenMolecularDipole[1] = 0.0000000e+00;
oxygenMolecularDipole[2] = 7.5561214e-03;
oxygenMolecularQuadrupole[0] = 3.5403072e-04;
oxygenMolecularQuadrupole[1] = 0.0000000e+00;
oxygenMolecularQuadrupole[2] = 0.0000000e+00;
oxygenMolecularQuadrupole[3] = 0.0000000e+00;
oxygenMolecularQuadrupole[4] = -3.9025708e-04;
oxygenMolecularQuadrupole[5] = 0.0000000e+00;
oxygenMolecularQuadrupole[6] = 0.0000000e+00;
oxygenMolecularQuadrupole[7] = 0.0000000e+00;
oxygenMolecularQuadrupole[8] = 3.6226356e-05;
std::vector<double> hydrogenMolecularDipole(3);
std::vector<double> hydrogenMolecularQuadrupole(9);
hydrogenMolecularDipole[0] = -2.0420949e-03;
hydrogenMolecularDipole[1] = 0.0000000e+00;
hydrogenMolecularDipole[2] = -3.0787530e-03;
hydrogenMolecularQuadrupole[0] = -3.4284825e-05;
hydrogenMolecularQuadrupole[1] = 0.0000000e+00;
hydrogenMolecularQuadrupole[2] = -1.8948597e-06;
hydrogenMolecularQuadrupole[3] = 0.0000000e+00;
hydrogenMolecularQuadrupole[4] = -1.0024088e-04;
hydrogenMolecularQuadrupole[5] = 0.0000000e+00;
hydrogenMolecularQuadrupole[6] = -1.8948597e-06;
hydrogenMolecularQuadrupole[7] = 0.0000000e+00;
hydrogenMolecularQuadrupole[8] = 1.3452570e-04;
for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){
amoebaMultipoleForce->addParticle( -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1,
3.9000000e-01, 3.0698765e-01, 8.3700000e-04 );
amoebaMultipoleForce->addParticle( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1,
3.9000000e-01, 2.8135002e-01, 4.9600000e-04 );
amoebaMultipoleForce->addParticle( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1,
3.9000000e-01, 2.8135002e-01, 4.9600000e-04 );
}
// CovalentMaps
std::vector< int > covalentMap;
for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){
covalentMap.resize(0);
covalentMap.push_back( jj+1 );
covalentMap.push_back( jj+2 );
amoebaMultipoleForce->setCovalentMap( jj, static_cast<OpenMM::AmoebaMultipoleForce::CovalentType>(0), covalentMap );
covalentMap.resize(0);
covalentMap.push_back( jj );
covalentMap.push_back( jj+1 );
covalentMap.push_back( jj+2 );
amoebaMultipoleForce->setCovalentMap( jj, static_cast<OpenMM::AmoebaMultipoleForce::CovalentType>(4), covalentMap );
amoebaMultipoleForce->setCovalentMap( jj+1, static_cast<OpenMM::AmoebaMultipoleForce::CovalentType>(4), covalentMap );
amoebaMultipoleForce->setCovalentMap( jj+2, static_cast<OpenMM::AmoebaMultipoleForce::CovalentType>(4), covalentMap );
covalentMap.resize(0);
covalentMap.push_back( jj );
amoebaMultipoleForce->setCovalentMap( jj+1, static_cast<OpenMM::AmoebaMultipoleForce::CovalentType>(0), covalentMap );
amoebaMultipoleForce->setCovalentMap( jj+2, static_cast<OpenMM::AmoebaMultipoleForce::CovalentType>(0), covalentMap );
covalentMap.resize(0);
covalentMap.push_back( jj+2 );
amoebaMultipoleForce->setCovalentMap( jj+1, static_cast<OpenMM::AmoebaMultipoleForce::CovalentType>(1), covalentMap );
covalentMap.resize(0);
covalentMap.push_back( jj+1 );
amoebaMultipoleForce->setCovalentMap( jj+2, static_cast<OpenMM::AmoebaMultipoleForce::CovalentType>(1), covalentMap );
}
system.addForce(amoebaMultipoleForce);
// 1-2 bonds needed
AmoebaHarmonicBondForce* amoebaHarmonicBondForce = new AmoebaHarmonicBondForce();
// addBond: particle1, particle2, length, quadraticK
for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){
amoebaHarmonicBondForce->addBond( jj, jj+1, 0.0000000e+00, 0.0000000e+00 );
amoebaHarmonicBondForce->addBond( jj, jj+2, 0.0000000e+00, 0.0000000e+00 );
}
amoebaHarmonicBondForce->setAmoebaGlobalHarmonicBondCubic( -2.5500000e+01 );
amoebaHarmonicBondForce->setAmoebaGlobalHarmonicBondQuartic( 3.7931250e+02 );
system.addForce(amoebaHarmonicBondForce);
std::vector<Vec3> positions(numberOfParticles);
positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02 );
positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02 );
positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02 );
positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01 );
positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01 );
positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01 );
positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01 );
positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01 );
positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01 );
positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01 );
positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01 );
positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01 );
positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01 );
positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01 );
positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01 );
positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01 );
positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01 );
positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01 );
positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01 );
positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01 );
positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01 );
positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01 );
positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01 );
positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01 );
positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01 );
positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01 );
positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02 );
positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02 );
positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01 );
positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01 );
positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01 );
positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01 );
positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01 );
positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01 );
positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01 );
positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01 );
positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01 );
positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01 );
positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01 );
positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01 );
positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01 );
positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01 );
positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01 );
positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01 );
positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01 );
positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01 );
positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01 );
positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01 );
positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01 );
positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01 );
positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01 );
positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01 );
positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01 );
positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01 );
positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01 );
positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01 );
positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01 );
positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01 );
positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01 );
positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01 );
positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01 );
positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01 );
positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01 );
positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02 );
positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02 );
positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01 );
positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02 );
positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02 );
positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01 );
positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01 );
positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01 );
positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01 );
positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01 );
positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01 );
positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01 );
positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01 );
positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02 );
positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01 );
positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01 );
positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01 );
positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01 );
positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02 );
positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01 );
positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02 );
positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01 );
positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01 );
positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01 );
positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01 );
positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01 );
positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01 );
positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01 );
positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01 );
positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01 );
positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01 );
positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01 );
positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01 );
positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01 );
positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01 );
positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01 );
positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01 );
positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01 );
positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01 );
positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01 );
positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01 );
positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01 );
positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01 );
positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01 );
positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01 );
positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01 );
positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01 );
positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01 );
positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02 );
positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02 );
positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01 );
positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01 );
positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01 );
positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01 );
positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01 );
positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01 );
positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01 );
positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01 );
positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01 );
positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01 );
positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01 );
positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02 );
positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01 );
positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01 );
positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01 );
positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01 );
positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01 );
positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01 );
positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01 );
positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01 );
positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01 );
positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01 );
positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01 );
positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01 );
positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01 );
positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01 );
positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01 );
positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01 );
positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01 );
positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01 );
positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01 );
positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01 );
positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01 );
positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01 );
positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01 );
positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01 );
positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01 );
positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01 );
positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01 );
positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01 );
positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01 );
positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01 );
positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01 );
positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02 );
positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02 );
positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02 );
positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01 );
positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02 );
positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02 );
positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01 );
positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01 );
positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01 );
positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01 );
positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01 );
positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01 );
positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01 );
positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01 );
positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01 );
positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01 );
positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01 );
positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01 );
positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01 );
positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01 );
positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01 );
positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01 );
positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01 );
positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01 );
positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01 );
positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01 );
positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01 );
positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01 );
positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01 );
positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01 );
positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02 );
positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01 );
positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03 );
positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01 );
positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01 );
positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01 );
positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01 );
positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01 );
positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01 );
positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01 );
positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01 );
positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01 );
positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01 );
positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01 );
positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01 );
positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02 );
positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01 );
positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02 );
positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01 );
positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01 );
positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01 );
positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01 );
positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01 );
positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01 );
positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01 );
positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01 );
positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01 );
positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01 );
positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01 );
positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01 );
positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01 );
positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01 );
positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01 );
positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01 );
positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01 );
positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01 );
positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01 );
positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01 );
positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01 );
positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02 );
positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01 );
positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02 );
positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01 );
positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01 );
positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01 );
positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01 );
positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01 );
positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01 );
positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01 );
positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01 );
positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01 );
positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01 );
positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01 );
positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01 );
positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01 );
positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01 );
positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01 );
positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02 );
positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01 );
positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02 );
positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01 );
positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01 );
positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01 );
positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01 );
positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01 );
positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01 );
positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01 );
positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01 );
positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01 );
positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01 );
positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01 );
positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01 );
positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01 );
positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01 );
positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01 );
positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01 );
positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01 );
positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01 );
positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03 );
positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03 );
positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02 );
positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01 );
positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01 );
positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01 );
positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01 );
positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01 );
positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01 );
positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01 );
positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01 );
positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01 );
positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01 );
positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01 );
positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01 );
positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01 );
positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01 );
positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01 );
positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01 );
positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01 );
positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01 );
positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01 );
positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01 );
positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01 );
positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02 );
positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01 );
positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02 );
positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01 );
positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01 );
positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01 );
positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01 );
positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02 );
positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02 );
positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01 );
positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01 );
positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01 );
positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01 );
positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01 );
positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01 );
positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01 );
positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01 );
positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01 );
positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01 );
positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01 );
positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01 );
positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01 );
positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01 );
positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01 );
positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01 );
positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01 );
positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01 );
positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02 );
positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01 );
positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02 );
positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01 );
positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01 );
positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01 );
positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01 );
positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01 );
positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01 );
positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01 );
positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01 );
positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01 );
positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02 );
positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02 );
positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02 );
positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01 );
positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01 );
positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01 );
positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01 );
positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01 );
positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01 );
positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01 );
positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01 );
positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01 );
positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01 );
positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01 );
positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01 );
positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02 );
positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02 );
positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02 );
positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01 );
positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01 );
positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01 );
positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01 );
positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01 );
positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01 );
positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01 );
positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01 );
positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01 );
positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01 );
positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01 );
positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01 );
positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01 );
positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01 );
positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01 );
positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01 );
positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01 );
positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01 );
positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01 );
positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02 );
positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01 );
positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01 );
positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02 );
positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01 );
positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01 );
positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01 );
positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01 );
positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01 );
positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01 );
positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01 );
positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01 );
positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01 );
positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01 );
positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02 );
positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02 );
positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02 );
positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01 );
positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01 );
positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01 );
positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01 );
positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01 );
positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01 );
positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01 );
positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01 );
positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01 );
positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01 );
positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01 );
positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01 );
positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01 );
positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01 );
positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01 );
positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01 );
positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01 );
positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01 );
positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01 );
positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01 );
positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01 );
positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01 );
positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01 );
positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01 );
positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02 );
positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01 );
positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03 );
positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01 );
positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01 );
positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01 );
positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01 );
positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01 );
positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01 );
positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03 );
positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02 );
positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03 );
positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01 );
positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01 );
positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01 );
positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01 );
positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01 );
positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01 );
positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01 );
positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01 );
positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01 );
positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01 );
positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01 );
positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01 );
positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01 );
positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01 );
positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01 );
positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01 );
positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01 );
positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01 );
positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01 );
positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01 );
positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01 );
positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01 );
positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01 );
positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01 );
positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02 );
positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02 );
positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01 );
positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01 );
positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01 );
positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01 );
positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01 );
positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01 );
positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01 );
positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01 );
positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01 );
positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01 );
positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01 );
positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01 );
positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01 );
positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01 );
positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01 );
positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01 );
positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01 );
positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01 );
positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01 );
positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01 );
positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01 );
positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01 );
positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01 );
positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01 );
positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01 );
positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01 );
positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01 );
positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01 );
positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02 );
positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03 );
positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01 );
positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01 );
positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01 );
positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01 );
positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01 );
positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01 );
positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01 );
positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01 );
positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01 );
positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01 );
positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01 );
positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01 );
positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02 );
positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01 );
positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01 );
positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01 );
positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01 );
positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01 );
positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01 );
positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01 );
positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01 );
positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01 );
positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01 );
positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01 );
positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01 );
positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01 );
positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01 );
positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01 );
positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01 );
positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01 );
positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01 );
positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01 );
positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01 );
positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01 );
positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01 );
positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01 );
positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01 );
positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01 );
positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01 );
positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01 );
positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01 );
positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01 );
positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01 );
positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01 );
positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01 );
positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01 );
positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01 );
positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01 );
positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01 );
positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01 );
positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01 );
positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01 );
positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01 );
positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01 );
positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01 );
positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01 );
positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01 );
positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01 );
positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01 );
positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01 );
positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01 );
positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01 );
positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01 );
positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01 );
positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01 );
positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01 );
positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01 );
positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01 );
positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01 );
positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01 );
positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01 );
positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01 );
positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01 );
positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01 );
positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01 );
positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01 );
positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01 );
positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01 );
positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01 );
positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02 );
positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01 );
positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02 );
positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01 );
positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01 );
positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02 );
positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02 );
positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02 );
positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02 );
positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01 );
positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01 );
positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01 );
positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01 );
positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02 );
positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02 );
positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01 );
positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01 );
positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01 );
positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01 );
positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01 );
positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01 );
positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01 );
positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01 );
positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01 );
positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02 );
positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02 );
positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02 );
positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02 );
positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02 );
positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01 );
positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01 );
positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01 );
positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01 );
positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01 );
positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01 );
positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01 );
positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01 );
positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01 );
positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01 );
positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01 );
positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01 );
positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01 );
positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01 );
positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01 );
positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01 );
positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01 );
positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01 );
positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01 );
positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01 );
positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01 );
positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01 );
positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01 );
positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01 );
positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01 );
positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01 );
positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01 );
positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01 );
positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01 );
positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01 );
positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01 );
positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01 );
positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01 );
positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01 );
positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01 );
positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01 );
positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01 );
positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01 );
positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01 );
positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01 );
positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01 );
positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01 );
positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01 );
positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01 );
positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01 );
positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01 );
positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01 );
positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01 );
positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01 );
positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01 );
positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01 );
positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01 );
positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01 );
positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01 );
positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01 );
positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01 );
positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01 );
positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01 );
positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01 );
positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01 );
positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01 );
positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01 );
positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01 );
positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01 );
positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01 );
positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01 );
positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01 );
std::string platformName;
platformName = "CUDA";
LangevinIntegrator integrator(0.0, 0.1, 0.01);
Context context(system, integrator, Platform::getPlatformByName( platformName ) );
context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy);
forces = state.getForces();
energy = state.getPotentialEnergy();
}
// test multipole mutual polarization using PME for box of water
static void testPMEMutualPolarizationLargeWater( FILE* log ) {
std::string testName = "testPMEMutualPolarizationLargeWater";
int numberOfParticles = 648;
int inputPmeGridDimension = 24;
double cutoff = 0.70;
std::vector<Vec3> forces;
double energy;
setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual,
cutoff, inputPmeGridDimension, forces, energy, log );
std::vector<Vec3> expectedForces(numberOfParticles);
double expectedEnergy = -1.3268930e+04;
expectedForces[0] = Vec3( -5.2764003e+02, 6.5154502e+02, 7.8683284e+02 );
expectedForces[1] = Vec3( 3.3391292e+02, -1.1162521e+03, -2.9173021e+02 );
expectedForces[2] = Vec3( 9.4613310e+01, -5.8988099e+01, -6.2871010e+02 );
expectedForces[3] = Vec3( -1.6179658e+03, 1.8222798e+02, -1.0373083e+02 );
expectedForces[4] = Vec3( 1.0177962e+03, 1.7118957e+02, 4.0084976e+02 );
expectedForces[5] = Vec3( 3.0582540e+02, -5.5215191e+02, 4.8287747e+01 );
expectedForces[6] = Vec3( -5.4931641e+01, -6.7689368e+02, -1.2260977e+03 );
expectedForces[7] = Vec3( -2.9961754e+02, 1.3602079e+03, -2.2087612e+02 );
expectedForces[8] = Vec3( -3.1788045e+02, -1.3540025e+02, 1.1250958e+03 );
expectedForces[9] = Vec3( 1.0275111e+03, 1.9279625e+02, -6.0872252e+02 );
expectedForces[10] = Vec3( -5.7512410e+02, -5.6280482e+01, 7.5039261e+02 );
expectedForces[11] = Vec3( -4.7291981e+02, -3.5875411e+01, 5.2335135e+00 );
expectedForces[12] = Vec3( -1.5619899e+02, -1.3743370e+02, 1.3587339e+03 );
expectedForces[13] = Vec3( -4.7423876e+02, 1.0032873e+02, -2.0875847e+02 );
expectedForces[14] = Vec3( 7.5621178e+02, 3.7979419e+01, -4.1221012e+02 );
expectedForces[15] = Vec3( 6.7318876e+02, 4.9937148e+02, 1.1665351e+03 );
expectedForces[16] = Vec3( -7.0858091e+01, 8.4758233e+01, -1.3126942e+03 );
expectedForces[17] = Vec3( -1.0636296e+03, -1.6254851e+02, -1.0982809e+02 );
expectedForces[18] = Vec3( -1.0249489e+03, 6.7073895e+02, -2.0754278e+02 );
expectedForces[19] = Vec3( 5.6396078e+02, -1.1702137e+03, 1.5324295e+02 );
expectedForces[20] = Vec3( 6.1635144e+02, 5.6122242e+02, -7.9410893e+01 );
expectedForces[21] = Vec3( -1.5785582e+02, -1.0857764e+03, -1.1010131e+03 );
expectedForces[22] = Vec3( 2.3733181e+01, 2.0158373e+02, 3.2583783e+02 );
expectedForces[23] = Vec3( 1.8855396e+02, 1.2408889e+03, 4.5759149e+02 );
expectedForces[24] = Vec3( 9.3643408e+02, -6.1331107e+01, -3.8601431e+02 );
expectedForces[25] = Vec3( -3.1972504e+02, -1.5783340e+02, -1.3838003e+02 );
expectedForces[26] = Vec3( -5.1178039e+02, -2.5998898e+02, 6.1021975e+02 );
expectedForces[27] = Vec3( 9.1836250e+02, -4.3288112e+02, -9.5579501e+02 );
expectedForces[28] = Vec3( -9.3325184e+02, 6.2859013e+01, 5.0743198e+02 );
expectedForces[29] = Vec3( 3.1839963e+02, 5.4102155e+02, 1.1261345e+03 );
expectedForces[30] = Vec3( 7.3842640e+02, 1.0907054e+02, -2.1126612e+02 );
expectedForces[31] = Vec3( -1.8470175e+02, -4.0377182e+01, 1.2464073e+02 );
expectedForces[32] = Vec3( -5.8931386e+02, -3.5021489e+02, -7.2769901e+01 );
expectedForces[33] = Vec3( 1.4804452e+02, -1.2138869e+02, -1.2423820e+03 );
expectedForces[34] = Vec3( -2.4850935e+02, 2.3113218e+01, 1.4041979e+02 );
expectedForces[35] = Vec3( 1.3188525e+02, -6.1243481e+02, 6.4886373e+02 );
expectedForces[36] = Vec3( 5.0217683e+02, 9.2857480e+02, -7.2500648e+02 );
expectedForces[37] = Vec3( 9.9446320e+01, -3.0337270e+02, 8.0439741e+02 );
expectedForces[38] = Vec3( -1.7167491e+02, -9.3911948e+02, 5.6412500e+01 );
expectedForces[39] = Vec3( -6.6143649e+02, 1.0876882e+03, 3.3801466e+02 );
expectedForces[40] = Vec3( 5.6748150e+02, -2.2459572e+02, 3.8360728e+02 );
expectedForces[41] = Vec3( 7.7688834e+02, -6.7341171e+02, -6.4292796e+02 );
expectedForces[42] = Vec3( 1.0253263e+02, -1.3212797e+03, 9.3279892e+02 );
expectedForces[43] = Vec3( 1.5424247e+02, -1.0197346e+01, -8.0230728e+02 );
expectedForces[44] = Vec3( -6.6499384e+02, 1.2534353e+03, -1.6748341e+02 );
expectedForces[45] = Vec3( -1.9282945e+02, 5.1764789e+02, 1.5108154e+03 );
expectedForces[46] = Vec3( -4.9204245e+02, 8.8664089e+02, -8.8381078e+02 );
expectedForces[47] = Vec3( 1.3207641e+01, -5.7765859e+02, -3.5921690e+02 );
expectedForces[48] = Vec3( 4.1691955e+02, -1.1292452e+03, -6.2339128e+02 );
expectedForces[49] = Vec3( 4.8613761e+02, 6.8325845e+02, 2.3424652e+02 );
expectedForces[50] = Vec3( 3.1827501e+01, 6.8442319e+02, -5.8685438e+02 );
expectedForces[51] = Vec3( 1.1834790e+03, -1.3418299e+03, 5.6280882e+02 );
expectedForces[52] = Vec3( -5.8629616e+02, -6.9100489e+01, -9.7784543e+02 );
expectedForces[53] = Vec3( -4.0294748e+02, 5.0669032e+02, 5.3893512e+02 );
expectedForces[54] = Vec3( 6.3555947e+01, -9.0345643e+02, 7.2235587e+02 );
expectedForces[55] = Vec3( 4.9353706e+02, 4.3952680e+02, -1.5413911e+02 );
expectedForces[56] = Vec3( -3.4663273e+02, 8.4708544e+02, -8.8983178e+01 );
expectedForces[57] = Vec3( 1.5746383e+03, 5.8209931e+02, 3.6645765e+02 );
expectedForces[58] = Vec3( -4.0076588e+02, -1.2311235e+02, -1.6226002e+02 );
expectedForces[59] = Vec3( -3.3837369e+02, -5.3890252e+02, -5.5997831e+02 );
expectedForces[60] = Vec3( 8.6512912e+02, -1.0775827e+03, -3.6920406e+02 );
expectedForces[61] = Vec3( 1.0588621e+01, 4.4531974e+02, 1.1838800e+02 );
expectedForces[62] = Vec3( -7.0505255e+02, 1.5737739e+02, 3.0134165e+02 );
expectedForces[63] = Vec3( -1.2833932e+03, 5.1206074e+02, -9.3423828e+01 );
expectedForces[64] = Vec3( 2.0863538e+02, -6.7108922e+02, 3.5777952e+02 );
expectedForces[65] = Vec3( 4.9710436e+02, -6.8550896e+01, -2.7502680e+02 );
expectedForces[66] = Vec3( 4.0388289e+02, 1.0051571e+03, -2.3823633e+02 );
expectedForces[67] = Vec3( -3.3895858e+02, -6.7577709e+02, 3.1521120e+02 );
expectedForces[68] = Vec3( -4.8763670e+02, -2.9427128e+02, 2.9500438e+02 );
expectedForces[69] = Vec3( -8.4080783e+02, -1.7777886e+02, 6.5087880e+02 );
expectedForces[70] = Vec3( 2.1136356e+02, 6.6812142e+01, -5.5437438e+02 );
expectedForces[71] = Vec3( -1.3829189e+01, 7.0936421e+02, -5.0847380e+02 );
expectedForces[72] = Vec3( -1.5684247e+03, 1.6837339e+02, -4.6044105e+02 );
expectedForces[73] = Vec3( 9.9163605e+02, -4.1397181e+02, -3.9624142e+02 );
expectedForces[74] = Vec3( 6.7355000e+02, 5.7652252e+02, 1.0565003e+03 );
expectedForces[75] = Vec3( -1.3722105e+03, -1.4035644e+03, 2.7882380e+02 );
expectedForces[76] = Vec3( 5.2187588e+02, 3.9602986e+02, -2.2564009e+02 );
expectedForces[77] = Vec3( 2.6381283e+02, 4.2945748e+02, 1.8339201e+02 );
expectedForces[78] = Vec3( 5.3099327e+02, 1.7312849e+03, 3.5385638e+01 );
expectedForces[79] = Vec3( -2.1320977e+02, -1.1795453e+03, -5.1691859e+02 );
expectedForces[80] = Vec3( -7.1445218e+02, -5.8918750e+02, 7.6494816e+02 );
expectedForces[81] = Vec3( 1.0849545e+03, 6.5058603e+02, -5.6051049e+02 );
expectedForces[82] = Vec3( -4.6986151e+02, -3.3868080e+02, 7.9000645e+02 );
expectedForces[83] = Vec3( -3.8404718e+02, -4.4915037e+02, -4.2069600e+02 );
expectedForces[84] = Vec3( -3.0678477e+02, -7.2558567e+02, 2.0276275e+02 );
expectedForces[85] = Vec3( 6.2969625e+01, 3.4257826e+02, -6.8348290e+02 );
expectedForces[86] = Vec3( 3.1042613e+02, 9.6563445e+01, -1.8788848e+02 );
expectedForces[87] = Vec3( 2.4427535e+01, 5.8460648e+02, -1.3720684e+03 );
expectedForces[88] = Vec3( -4.9904469e+02, -9.1309605e+02, 1.4350031e+02 );
expectedForces[89] = Vec3( -4.0910847e+01, 5.2845046e+01, 2.7341591e+02 );
expectedForces[90] = Vec3( -4.5190765e+02, 2.2820859e+02, -1.1052181e+03 );
expectedForces[91] = Vec3( 9.1626336e+01, -1.0496400e+03, 1.0216011e+02 );
expectedForces[92] = Vec3( -1.2592678e+02, -4.4050520e+01, 1.0764584e+03 );
expectedForces[93] = Vec3( 8.4216135e+02, 1.7603150e+02, 1.3698861e+03 );
expectedForces[94] = Vec3( 1.2583734e+02, 3.4343971e+02, -7.3070182e+02 );
expectedForces[95] = Vec3( -4.5597370e+02, -6.8170738e+02, -5.2258658e+02 );
expectedForces[96] = Vec3( 1.3295639e+03, 2.5031118e+02, -3.5171095e+02 );
expectedForces[97] = Vec3( -2.0136001e+02, -2.2978012e+02, 2.1122610e+02 );
expectedForces[98] = Vec3( -1.1279722e+03, -9.9794730e+02, -1.1321006e+02 );
expectedForces[99] = Vec3( 2.9553179e+02, -2.0727600e+02, -1.8912317e+03 );
expectedForces[100] = Vec3( -9.3777487e+02, 4.3417972e+02, 5.7436670e+02 );
expectedForces[101] = Vec3( 3.1120364e+02, -4.3241206e+00, 5.6666340e+02 );
expectedForces[102] = Vec3( -6.6764840e+02, -2.3563274e+02, 9.9017992e+02 );
expectedForces[103] = Vec3( 8.2857598e+02, 1.9030059e+02, -2.4295780e+02 );
expectedForces[104] = Vec3( -2.6709334e+02, 7.3284851e+01, -3.9157038e+02 );
expectedForces[105] = Vec3( 6.6235629e+02, -8.4502811e+02, -5.3670716e+02 );
expectedForces[106] = Vec3( 3.8449086e+02, 8.0775263e+02, 5.2003911e+02 );
expectedForces[107] = Vec3( -3.4338589e+02, 1.7870086e+02, -6.1047615e+01 );
expectedForces[108] = Vec3( 4.3523975e+02, 2.8776092e+02, -1.5333067e+03 );
expectedForces[109] = Vec3( 1.9214022e+01, -9.9449061e+01, 3.9153169e+02 );
expectedForces[110] = Vec3( -7.7525496e+02, 7.7309387e+01, 7.8886699e+02 );
expectedForces[111] = Vec3( -1.1510224e+03, -2.8207337e+02, 1.4866455e+03 );
expectedForces[112] = Vec3( 1.1281316e+03, -3.0961130e+02, -1.3894255e+02 );
expectedForces[113] = Vec3( -2.4829062e+02, 5.9466066e+02, -9.0749265e+02 );
expectedForces[114] = Vec3( -1.6228531e+02, -4.1281378e+02, -1.4860946e+03 );
expectedForces[115] = Vec3( -2.9071192e+02, 7.5335271e+02, 6.5205720e+02 );
expectedForces[116] = Vec3( 3.2042337e+02, -4.0237231e+02, 1.0068554e+03 );
expectedForces[117] = Vec3( -1.4081272e+03, -5.5227579e+02, 2.8376428e+02 );
expectedForces[118] = Vec3( 9.6978276e+02, -9.6232683e+02, 2.3399918e+02 );
expectedForces[119] = Vec3( 2.0781312e+02, 9.0531947e+01, 8.3513783e+01 );
expectedForces[120] = Vec3( 2.9200105e+02, 1.0746865e+03, -6.0773727e+02 );
expectedForces[121] = Vec3( -8.7546167e+02, 3.1969683e+02, 8.1033199e+01 );
expectedForces[122] = Vec3( -5.3422658e+01, -3.8456585e+02, 1.4595003e+02 );
expectedForces[123] = Vec3( -9.5134908e+01, 8.6818098e+02, -1.3111403e+03 );
expectedForces[124] = Vec3( -7.2576830e+02, 6.3811172e+01, 7.0993488e+02 );
expectedForces[125] = Vec3( 5.6200572e+02, -1.0972338e+03, -3.5278717e+02 );
expectedForces[126] = Vec3( -1.6903718e+02, 2.6804112e+02, -8.9811032e+02 );
expectedForces[127] = Vec3( 7.0934165e+02, -3.2328700e+02, 1.0037562e+02 );
expectedForces[128] = Vec3( -2.5937738e+00, -3.3758145e+02, 3.6354335e+02 );
expectedForces[129] = Vec3( -1.1993601e+03, 1.1618922e+02, -1.1329865e+03 );
expectedForces[130] = Vec3( 8.3480845e+02, 5.2646427e+02, 9.1816763e+01 );
expectedForces[131] = Vec3( 1.9407174e+02, 7.3877492e+00, 8.8648162e+02 );
expectedForces[132] = Vec3( -1.0820540e+03, 2.7482390e+02, -1.4876848e+03 );
expectedForces[133] = Vec3( 9.5717027e+02, -4.7758356e+02, 4.0692835e+02 );
expectedForces[134] = Vec3( 2.4979896e+02, 7.1530552e+02, 6.5834243e+02 );
expectedForces[135] = Vec3( -2.7549874e+02, 1.6613806e+03, -5.0628865e+02 );
expectedForces[136] = Vec3( -1.5960544e+02, -4.5920421e+02, 9.4068762e+02 );
expectedForces[137] = Vec3( 6.9764295e+01, -4.4024430e+02, -2.3545402e+02 );
expectedForces[138] = Vec3( 2.0207569e+03, -2.6846158e+02, 3.3977998e+02 );
expectedForces[139] = Vec3( -9.9905342e+02, 9.5155462e+02, 8.3259854e+01 );
expectedForces[140] = Vec3( -8.0836255e+02, -6.3005196e+02, 1.2603525e+02 );
expectedForces[141] = Vec3( 5.2279913e+02, 1.5356061e+03, -1.4399009e+02 );
expectedForces[142] = Vec3( -1.3088783e+02, -9.0861449e+02, 9.7040422e+02 );
expectedForces[143] = Vec3( 2.8006682e+01, -1.1783245e+03, -3.7285390e+02 );
expectedForces[144] = Vec3( 6.1040927e+01, 2.1747286e+01, 9.0366011e+02 );
expectedForces[145] = Vec3( 7.0396235e+02, -2.3865001e+02, -6.8794682e+02 );
expectedForces[146] = Vec3( -5.1132933e+02, 7.7102556e+02, -4.7805042e+02 );
expectedForces[147] = Vec3( 6.2879945e+02, -6.9758821e+02, 1.0983043e+03 );
expectedForces[148] = Vec3( -9.2449123e+02, 5.0248042e+02, -2.0065211e+02 );
expectedForces[149] = Vec3( -3.9485154e+02, 3.4679511e+02, -7.3889603e+02 );
expectedForces[150] = Vec3( 4.9834751e+02, -1.0117501e+03, 1.2510946e+03 );
expectedForces[151] = Vec3( -1.4942699e+02, -7.4362790e+01, -6.8008427e+02 );
expectedForces[152] = Vec3( -1.8353666e+02, 5.1697483e+02, -8.4397292e+01 );
expectedForces[153] = Vec3( 7.0253008e+02, -1.5361338e+02, 8.6830836e+02 );
expectedForces[154] = Vec3( -4.1108898e+02, -6.8181350e+02, -5.6516951e+02 );
expectedForces[155] = Vec3( 3.9294374e+02, 3.7294948e+02, -4.9795080e+02 );
expectedForces[156] = Vec3( -7.3716758e+02, -5.5465931e+02, -9.3434525e+02 );
expectedForces[157] = Vec3( 1.8240105e+02, 1.5494359e+02, 1.3626243e+02 );
expectedForces[158] = Vec3( 9.3172059e+02, 1.4431275e+02, 6.6916065e+02 );
expectedForces[159] = Vec3( 7.3399513e+01, -3.6000187e+02, 1.9853052e+03 );
expectedForces[160] = Vec3( -2.4842520e+02, -4.0819514e+02, -8.0624794e+02 );
expectedForces[161] = Vec3( 4.3585911e+02, -2.6521764e+02, -6.7985842e+02 );
expectedForces[162] = Vec3( -8.2255783e+02, 1.1430906e+03, 1.2991183e+03 );
expectedForces[163] = Vec3( 5.6437196e+02, -1.5391213e+02, -5.0013503e+02 );
expectedForces[164] = Vec3( 3.8485296e+02, -1.1754088e+02, -1.4315511e+03 );
expectedForces[165] = Vec3( 9.8205241e+02, 1.3278205e+01, 3.0367584e+02 );
expectedForces[166] = Vec3( -3.2909916e+02, 4.5169387e+01, -3.2019488e+02 );
expectedForces[167] = Vec3( -4.2382795e+02, -8.1938351e+02, -1.5360675e+02 );
expectedForces[168] = Vec3( 9.1689997e+02, 1.4443113e+03, -1.8886795e+02 );
expectedForces[169] = Vec3( -1.2161000e+03, -2.3826187e+02, 3.4004889e+02 );
expectedForces[170] = Vec3( -2.2837927e+02, -9.8334152e+02, 3.0313790e+02 );
expectedForces[171] = Vec3( 5.2598040e+02, -1.2766936e+03, 8.1247934e+01 );
expectedForces[172] = Vec3( -6.7839687e+01, 6.9220160e+02, 3.1975320e+02 );
expectedForces[173] = Vec3( -4.8519844e+02, 4.3008979e+02, -7.6788762e+02 );
expectedForces[174] = Vec3( 3.9550092e+01, 1.0900122e+03, 5.0955281e+02 );
expectedForces[175] = Vec3( -6.3000735e+02, -7.2335263e+02, -2.2590661e+02 );
expectedForces[176] = Vec3( 1.5048762e+02, -4.0086126e+02, -1.2159849e+02 );
expectedForces[177] = Vec3( -7.1939527e+02, -1.0640815e+03, -3.1826393e+02 );
expectedForces[178] = Vec3( 7.7492135e+02, 1.0620129e+02, 3.6733165e+02 );
expectedForces[179] = Vec3( -3.5466457e+02, 7.0081887e+02, 2.2629152e+02 );
expectedForces[180] = Vec3( 3.0338275e+02, -1.1243396e+02, -1.3408996e+03 );
expectedForces[181] = Vec3( 9.0394088e+00, 4.8818819e+02, 7.3781403e+02 );
expectedForces[182] = Vec3( -5.6111982e+01, -2.5224925e+02, 3.0344460e+02 );
expectedForces[183] = Vec3( -7.4693225e+02, 1.1370727e+03, 9.3958175e+02 );
expectedForces[184] = Vec3( 3.1310327e+02, -1.2133761e+03, 2.6768166e+02 );
expectedForces[185] = Vec3( 6.0706899e+02, 9.8403362e+01, -5.0781782e+02 );
expectedForces[186] = Vec3( -6.2721609e+02, 1.7751567e+02, 2.6230643e+02 );
expectedForces[187] = Vec3( 3.5425475e+02, -3.3336896e+02, 2.9529930e+02 );
expectedForces[188] = Vec3( 4.7499029e+02, 4.5552354e+02, -2.4939310e+02 );
expectedForces[189] = Vec3( 1.1556321e+02, 2.5995186e+02, -8.4171376e+02 );
expectedForces[190] = Vec3( -4.5095184e+02, -1.6639362e+01, 4.2956175e+02 );
expectedForces[191] = Vec3( -7.5904218e+01, 3.9416063e+02, 4.2573815e+02 );
expectedForces[192] = Vec3( 2.3041013e+02, -1.2883920e+03, -5.1943189e+02 );
expectedForces[193] = Vec3( 8.6086944e+01, 1.8626094e+02, 3.7641641e+02 );
expectedForces[194] = Vec3( -5.9266805e+02, 4.4766229e+02, -4.5835497e+02 );
expectedForces[195] = Vec3( 3.9368476e+02, 1.1050329e+03, -1.3906133e+03 );
expectedForces[196] = Vec3( -1.2912212e+03, -2.9660534e+02, 3.9659215e+02 );
expectedForces[197] = Vec3( -2.4803663e+01, -2.7945607e+02, 3.5315630e+02 );
expectedForces[198] = Vec3( 1.4147479e+02, 3.2766723e+02, 1.1137899e+03 );
expectedForces[199] = Vec3( 7.8383167e+01, 2.2385715e+00, -1.0346820e+03 );
expectedForces[200] = Vec3( -2.9231551e+02, -5.4648720e+02, -6.5500265e+02 );
expectedForces[201] = Vec3( 1.3708284e+03, -1.0716376e+03, 4.5781190e+02 );
expectedForces[202] = Vec3( -7.5533654e+02, 6.5396686e+02, -4.2683276e+02 );
expectedForces[203] = Vec3( -6.5558825e+02, 3.1164131e+02, 2.6323555e+02 );
expectedForces[204] = Vec3( 1.3173432e+03, 1.3775889e+03, 1.2933072e+02 );
expectedForces[205] = Vec3( -4.0922505e+02, -7.5709333e+02, -3.4967434e+02 );
expectedForces[206] = Vec3( 4.2270572e+01, -7.4393359e+02, 5.2985443e+02 );
expectedForces[207] = Vec3( -1.5327880e+03, 7.3186706e+02, -2.3440058e+02 );
expectedForces[208] = Vec3( 1.4650210e+03, 2.8661572e+02, -2.4233049e+02 );
expectedForces[209] = Vec3( 8.4124688e+02, -3.4020518e+02, -3.1773592e+01 );
expectedForces[210] = Vec3( -1.1480436e+03, -7.4089732e+02, -4.8883682e+02 );
expectedForces[211] = Vec3( 3.5682075e+02, 2.1918110e+01, -1.2558000e+02 );
expectedForces[212] = Vec3( 1.6505256e+02, 7.9867933e+02, 9.9760760e+02 );
expectedForces[213] = Vec3( 1.2477725e+03, -8.8687803e+02, -8.2498529e+02 );
expectedForces[214] = Vec3( 1.7357042e+02, 2.0185456e+02, 8.0965301e+02 );
expectedForces[215] = Vec3( -9.0937500e+02, 5.5968713e+01, 1.7581913e+02 );
expectedForces[216] = Vec3( 1.3030711e+03, -8.2642443e+02, 1.6679926e+02 );
expectedForces[217] = Vec3( -8.4295510e+02, 2.0237547e+01, 4.0163431e+02 );
expectedForces[218] = Vec3( -3.2088719e+02, 3.0824476e+02, 9.9166532e+01 );
expectedForces[219] = Vec3( 1.4585495e+03, -4.1497503e+01, -2.2539636e+02 );
expectedForces[220] = Vec3( -2.6148433e+02, 1.7592075e+02, 2.0638296e+02 );
expectedForces[221] = Vec3( -9.2100962e+02, 2.6090225e+02, -8.4461867e+02 );
expectedForces[222] = Vec3( -9.0597287e+02, -4.8246138e+02, -1.8012972e+03 );
expectedForces[223] = Vec3( -1.1775667e+02, 1.7275816e+02, 1.1286513e+03 );
expectedForces[224] = Vec3( 1.0682239e+03, 8.0853797e+02, 2.5601774e+02 );
expectedForces[225] = Vec3( -1.6637330e+02, 7.6165466e+02, -5.9394315e+02 );
expectedForces[226] = Vec3( 2.6206832e+02, -1.5011747e+02, 5.4532792e+02 );
expectedForces[227] = Vec3( -2.6474701e+02, -1.4218144e+02, 1.1099125e+02 );
expectedForces[228] = Vec3( -9.7365994e+02, -5.5282012e+02, -6.3158992e+02 );
expectedForces[229] = Vec3( 1.1482718e+03, 1.4958662e+02, -5.6523355e+02 );
expectedForces[230] = Vec3( 4.4084982e+02, 7.9662251e+02, 4.9732039e+02 );
expectedForces[231] = Vec3( -4.8746806e+02, -1.5522005e+03, 1.0133483e+03 );
expectedForces[232] = Vec3( 1.1332903e+03, 1.2836176e+03, -2.0897082e+02 );
expectedForces[233] = Vec3( -7.9973372e+01, 6.3066961e+02, -5.8656505e+02 );
expectedForces[234] = Vec3( -8.3714021e+02, -1.5385924e+03, 1.0179672e+03 );
expectedForces[235] = Vec3( 3.5358323e+02, 9.3554369e+02, 1.6565605e+02 );
expectedForces[236] = Vec3( 1.7532341e+02, 3.0381323e+01, -1.2538424e+03 );
expectedForces[237] = Vec3( -1.0437301e+03, -4.4804918e+02, 1.5276435e+03 );
expectedForces[238] = Vec3( 8.5470872e+02, 1.0725550e+03, -9.7359443e+01 );
expectedForces[239] = Vec3( 1.8192015e+02, -7.6967211e+01, -8.6054596e+02 );
expectedForces[240] = Vec3( 1.5910180e+03, -7.9601605e+02, -8.4030326e+02 );
expectedForces[241] = Vec3( -6.4638370e+02, 4.0538540e+02, 2.3396878e+01 );
expectedForces[242] = Vec3( -5.2648918e+02, 1.3689201e+02, 9.3014716e+02 );
expectedForces[243] = Vec3( 2.2248997e+02, -6.3647370e+02, -8.3913128e+02 );
expectedForces[244] = Vec3( -7.5759832e+02, 4.7985429e+01, 5.8577833e+02 );
expectedForces[245] = Vec3( 1.2983550e+02, 4.4401985e+02, 2.3556259e+02 );
expectedForces[246] = Vec3( 7.8075637e+02, 9.9893821e+02, 7.3511307e+02 );
expectedForces[247] = Vec3( -8.6411159e+02, 2.3812628e+02, 1.9007971e+02 );
expectedForces[248] = Vec3( 2.0762263e+02, -7.0123789e+02, -4.8175733e+02 );
expectedForces[249] = Vec3( -8.2749187e+02, -7.8772346e+02, -9.8536337e+02 );
expectedForces[250] = Vec3( 8.3905893e+01, -2.8770518e+02, 6.0690561e+02 );
expectedForces[251] = Vec3( 7.2280803e+02, 4.9294103e+02, -1.2915033e+02 );
expectedForces[252] = Vec3( -1.3615809e+03, -1.8564754e+02, -4.2172817e+02 );
expectedForces[253] = Vec3( 9.2102155e+02, 5.4063967e+02, -2.7291760e+02 );
expectedForces[254] = Vec3( 7.0204283e+02, -3.0338605e+02, 6.6795953e+02 );
expectedForces[255] = Vec3( -7.2261285e+00, 3.2570478e+02, 5.9010590e+02 );
expectedForces[256] = Vec3( -8.3167819e+02, 3.0568475e+02, -9.9230441e+02 );
expectedForces[257] = Vec3( 2.1074297e+02, -4.0099946e+01, -1.2770634e+02 );
expectedForces[258] = Vec3( 1.1218559e+03, -8.8304672e+02, 1.0217945e+03 );
expectedForces[259] = Vec3( -4.4730264e+01, 5.3616918e+02, -3.2704110e+02 );
expectedForces[260] = Vec3( -1.1106141e+03, 3.3541536e+02, -1.0552986e+02 );
expectedForces[261] = Vec3( -9.3728497e+01, 4.7397796e+01, -1.1294332e+03 );
expectedForces[262] = Vec3( 5.1424956e+01, 4.0854995e+02, 5.6832607e+02 );
expectedForces[263] = Vec3( 1.4286074e+02, 2.9172921e+01, 5.1355833e+02 );
expectedForces[264] = Vec3( -4.4318133e+02, -9.5478293e+02, -1.8067439e+03 );
expectedForces[265] = Vec3( -2.8083245e+02, 8.1414586e+02, 6.6089404e+02 );
expectedForces[266] = Vec3( 1.0434876e+02, 3.0664078e+02, 1.3658532e+03 );
expectedForces[267] = Vec3( 1.2999089e+03, 5.6746563e+02, 1.2200612e+03 );
expectedForces[268] = Vec3( -5.9546942e+02, 3.6897149e+02, -8.3331437e+02 );
expectedForces[269] = Vec3( -1.1094881e+03, -5.1903335e+02, -3.5729033e+02 );
expectedForces[270] = Vec3( 4.1873464e+02, 6.9788983e+02, -1.3191929e+03 );
expectedForces[271] = Vec3( -1.0086080e+02, 3.3114447e+02, 6.3419860e+02 );
expectedForces[272] = Vec3( -2.8783906e+02, -8.8308011e+02, -5.4816768e+01 );
expectedForces[273] = Vec3( 1.0254638e+03, 2.8710026e+02, -1.9779676e+02 );
expectedForces[274] = Vec3( -3.5906548e+02, -5.5531449e+02, -6.0205492e+01 );
expectedForces[275] = Vec3( -3.9578349e+02, 5.9217272e+01, 1.0735648e+02 );
expectedForces[276] = Vec3( -8.7298871e+02, -1.5584711e+02, 9.2571354e+02 );
expectedForces[277] = Vec3( 4.1520558e+02, 5.6442126e+02, -1.8142289e+02 );
expectedForces[278] = Vec3( 6.5423421e+02, -4.1631573e+02, 1.0996479e+02 );
expectedForces[279] = Vec3( -8.0063899e+01, -1.2880940e+03, 2.9304469e+02 );
expectedForces[280] = Vec3( -9.5930841e+02, 5.8293485e+02, -1.1632205e+03 );
expectedForces[281] = Vec3( 6.3492338e+02, 2.5550931e+02, 1.7380517e+02 );
expectedForces[282] = Vec3( -1.9188175e+02, 1.0257290e+03, -8.6438702e+02 );
expectedForces[283] = Vec3( 4.0063530e+01, -5.1808902e+02, 4.9556015e+02 );
expectedForces[284] = Vec3( 5.8250018e+02, -2.5030700e+02, 1.1762860e+03 );
expectedForces[285] = Vec3( -4.3195459e+02, 7.4733530e+02, -1.3002210e+03 );
expectedForces[286] = Vec3( 2.7567334e+01, -5.1662654e+02, 3.3258050e+02 );
expectedForces[287] = Vec3( 6.1700857e+02, 3.0016354e+02, 9.5519139e+02 );
expectedForces[288] = Vec3( 7.7553094e+02, 8.6453551e+02, -1.0122996e+03 );
expectedForces[289] = Vec3( -2.6730796e+02, -7.7560875e+02, 4.3195620e+02 );
expectedForces[290] = Vec3( -8.5982146e+02, 1.6692057e+02, 4.3838169e+02 );
expectedForces[291] = Vec3( 1.2945126e+03, 6.3231748e+02, -8.3020592e+02 );
expectedForces[292] = Vec3( -6.9510729e+02, -3.1930013e+02, -1.3919425e+01 );
expectedForces[293] = Vec3( -4.1154200e+02, -3.3562358e+02, 6.3292682e+02 );
expectedForces[294] = Vec3( -4.0919783e+02, -3.8282298e+02, -4.9125465e+02 );
expectedForces[295] = Vec3( 6.3932145e+02, -1.8769713e+01, 9.9241332e+01 );
expectedForces[296] = Vec3( 8.6847663e+01, 8.7234739e+02, 2.7124112e+02 );
expectedForces[297] = Vec3( -1.0307576e+03, -6.2447562e+02, -1.5796976e+03 );
expectedForces[298] = Vec3( 6.2464595e+02, 1.0608165e+03, 3.1422521e+01 );
expectedForces[299] = Vec3( 3.7767184e+02, 4.1170186e+02, 1.0696495e+03 );
expectedForces[300] = Vec3( 1.0578030e+02, -1.9544726e+03, -4.6243957e+02 );
expectedForces[301] = Vec3( -3.1074896e+02, 8.6738333e+02, -2.0241448e+02 );
expectedForces[302] = Vec3( -2.7350519e+02, 6.9945273e+02, 7.8755130e+02 );
expectedForces[303] = Vec3( 7.8083070e+02, 6.5199614e+02, -6.6698950e+02 );
expectedForces[304] = Vec3( 1.3647451e+02, -4.2490411e+02, 1.3236061e+01 );
expectedForces[305] = Vec3( -1.1048984e+03, 3.7582184e+02, -6.4718844e+01 );
expectedForces[306] = Vec3( 1.5976050e+03, -8.9091819e+02, 9.7113419e+02 );
expectedForces[307] = Vec3( -4.5545384e+01, 8.8683300e+02, -6.5927739e+01 );
expectedForces[308] = Vec3( -1.3883497e+03, -4.6171498e+02, -2.9117829e+02 );
expectedForces[309] = Vec3( -6.6661140e+02, -8.1394964e+02, 1.2397900e+03 );
expectedForces[310] = Vec3( -2.5293546e+02, 1.8568554e+02, -6.8919479e+02 );
expectedForces[311] = Vec3( 5.2052057e+02, 1.0288555e+03, 3.1435700e+02 );
expectedForces[312] = Vec3( -2.4245555e+02, -1.1100993e+03, -1.6937710e+03 );
expectedForces[313] = Vec3( 1.6647470e+02, 9.5272347e+02, 9.2528380e+02 );
expectedForces[314] = Vec3( 8.6946518e+02, -1.6295251e+02, 5.7452409e+02 );
expectedForces[315] = Vec3( 1.4059831e+02, 5.6780959e+02, -4.6024149e+02 );
expectedForces[316] = Vec3( 2.3327811e+02, -2.2376697e+02, 1.3399582e+01 );
expectedForces[317] = Vec3( -2.6583612e+01, -4.5801841e+02, 2.9595361e+01 );
expectedForces[318] = Vec3( 1.2361796e+03, -1.9473934e+02, -2.6179421e+02 );
expectedForces[319] = Vec3( -4.2330105e+02, 5.0768290e+02, 6.8352494e+02 );
expectedForces[320] = Vec3( -2.0826312e+02, 1.4720747e+02, -9.8828425e-01 );
expectedForces[321] = Vec3( -7.3226106e+02, -1.5366771e+01, 2.7882968e+02 );
expectedForces[322] = Vec3( 4.2634684e+02, -6.2926647e+02, 3.6300784e+02 );
expectedForces[323] = Vec3( 1.7826269e+02, 1.0038378e+02, -4.2408556e+02 );
expectedForces[324] = Vec3( -1.1690005e+03, 2.1777241e+02, 9.1980300e+02 );
expectedForces[325] = Vec3( 5.6841370e+02, -2.6614377e+02, -6.4968364e+01 );
expectedForces[326] = Vec3( 3.5710749e+02, 1.3228373e+02, -3.6567433e+02 );
expectedForces[327] = Vec3( 8.1957745e+02, 7.3903486e+02, 3.9487193e+02 );
expectedForces[328] = Vec3( -8.5354740e+02, 8.9297958e+01, 9.0615539e+01 );
expectedForces[329] = Vec3( -2.3935807e+02, -2.2950021e+02, -4.6193868e+01 );
expectedForces[330] = Vec3( 8.6120406e+01, 1.4046499e+03, -1.5899345e+02 );
expectedForces[331] = Vec3( 4.6319634e+02, -4.6309406e+02, -2.2891416e+02 );
expectedForces[332] = Vec3( -4.2592255e+02, -2.6503000e+02, 6.1788141e+02 );
expectedForces[333] = Vec3( -2.4468457e+02, -7.7827760e+02, 4.2470013e+02 );
expectedForces[334] = Vec3( 2.6006448e+02, 7.6289112e+01, -4.3430411e+02 );
expectedForces[335] = Vec3( -2.5268926e+02, 7.7381529e+02, -5.0896414e+02 );
expectedForces[336] = Vec3( 1.0414844e+03, -6.1885512e+02, 1.4495539e+03 );
expectedForces[337] = Vec3( -5.9522011e+01, 1.3607073e+03, -7.3705640e+01 );
expectedForces[338] = Vec3( -5.9857094e+02, -2.7213045e+02, -9.7516268e+02 );
expectedForces[339] = Vec3( 9.2852178e+02, 3.0121600e+02, -7.4982031e+00 );
expectedForces[340] = Vec3( -1.0201472e+03, 1.6269359e+02, 1.9280960e+02 );
expectedForces[341] = Vec3( -1.8744984e+02, -4.9790658e+02, 4.2841303e+02 );
expectedForces[342] = Vec3( -1.0893114e+03, -4.6044565e+02, -2.0537532e+02 );
expectedForces[343] = Vec3( 5.1068148e+02, -3.0889884e+02, 1.7703226e+01 );
expectedForces[344] = Vec3( 2.0128423e+02, 5.0813056e+02, -5.0941772e+01 );
expectedForces[345] = Vec3( -6.0195519e+02, 1.1710803e+03, -5.8271481e+02 );
expectedForces[346] = Vec3( 1.3898239e+02, -3.2598252e+02, 1.0877023e+03 );
expectedForces[347] = Vec3( 3.1630812e+02, -8.9974673e+02, 9.6573268e+01 );
expectedForces[348] = Vec3( -5.5334313e+01, -1.1529065e+03, -2.1949997e+02 );
expectedForces[349] = Vec3( -4.4904784e+02, 2.4036076e+02, 4.1328142e+02 );
expectedForces[350] = Vec3( 1.0611611e+03, 4.1620143e+02, 9.1677657e+01 );
expectedForces[351] = Vec3( 1.3489840e+03, 9.9500659e+02, -4.5894902e+01 );
expectedForces[352] = Vec3( -9.8051252e+01, -9.0794586e+02, -8.9918421e+02 );
expectedForces[353] = Vec3( -3.5567408e+02, -7.2914902e+01, 4.7977644e+01 );
expectedForces[354] = Vec3( -1.5976501e+03, -1.2202674e+03, 7.2159213e+02 );
expectedForces[355] = Vec3( 1.7391266e+02, 1.0197773e+03, -9.1284547e+02 );
expectedForces[356] = Vec3( 7.8937287e+02, 1.1964969e+02, -3.8520683e+02 );
expectedForces[357] = Vec3( 2.8170878e+02, 1.0377979e+03, -5.0609230e+02 );
expectedForces[358] = Vec3( -4.0852118e+01, -4.3087314e+02, 4.1855459e+01 );
expectedForces[359] = Vec3( -3.2767902e+02, -7.8083477e+02, 1.1111190e+03 );
expectedForces[360] = Vec3( -1.0691030e+03, 3.1877408e+02, -7.9684323e+02 );
expectedForces[361] = Vec3( 7.7603235e+02, 3.6577850e+02, -1.9093841e+02 );
expectedForces[362] = Vec3( -4.7607360e+02, -5.1710653e+02, 7.2740737e+02 );
expectedForces[363] = Vec3( 9.3461900e+02, 7.9988609e+01, -5.8055314e+02 );
expectedForces[364] = Vec3( -9.8128918e+02, -2.6706371e+02, -3.5178135e+01 );
expectedForces[365] = Vec3( -6.5196668e+02, 8.7618054e+02, 3.3040412e+02 );
expectedForces[366] = Vec3( 5.5458970e+02, -1.1281839e+03, -8.2774754e+02 );
expectedForces[367] = Vec3( 1.8491757e+02, -5.1421593e+01, 4.7068191e+02 );
expectedForces[368] = Vec3( -4.3945944e+02, 8.2740025e+02, -2.1736033e+01 );
expectedForces[369] = Vec3( -2.5609394e+02, -6.7141305e+02, -3.2964376e+02 );
expectedForces[370] = Vec3( 1.4932730e+02, 2.2746635e+02, -3.7606156e+01 );
expectedForces[371] = Vec3( 3.0873674e+02, 5.9974800e+02, 4.2207331e+02 );
expectedForces[372] = Vec3( -3.8828932e+02, -2.1491002e+02, 1.5266506e+03 );
expectedForces[373] = Vec3( 4.4495676e+02, 6.4708482e+02, -9.2222368e+02 );
expectedForces[374] = Vec3( -4.8420767e+01, -4.3781484e+02, -5.0107314e+02 );
expectedForces[375] = Vec3( 5.7593719e+02, -1.8140066e+03, -4.0189721e+02 );
expectedForces[376] = Vec3( -5.1276233e+02, 6.6981030e+02, 3.9050744e+02 );
expectedForces[377] = Vec3( 4.0809391e+02, 1.1596412e+03, -4.1325341e+02 );
expectedForces[378] = Vec3( 1.4975560e+03, 1.7852942e+02, -7.6514466e+02 );
expectedForces[379] = Vec3( -2.2890988e+02, 2.6128742e+02, 3.8545036e+02 );
expectedForces[380] = Vec3( -3.8899762e+02, -2.5609958e+02, 2.0655882e+02 );
expectedForces[381] = Vec3( -1.9500869e+02, -1.0947633e+03, -9.1786660e+02 );
expectedForces[382] = Vec3( 8.6146884e+02, 2.5767444e+02, 3.6801549e+02 );
expectedForces[383] = Vec3( -2.0008562e+02, 2.1549793e+02, 2.5175877e+02 );
expectedForces[384] = Vec3( -5.6491749e+02, 5.4714989e+02, 3.1934114e+02 );
expectedForces[385] = Vec3( 1.7665111e+02, -4.5297277e+02, 2.2387580e+02 );
expectedForces[386] = Vec3( 6.2697664e+02, 1.1271358e+02, 2.9498078e+00 );
expectedForces[387] = Vec3( -2.1918090e+03, -7.8914005e+01, 1.0632280e+03 );
expectedForces[388] = Vec3( 7.5750278e+02, -5.0217666e+02, -1.3057335e+02 );
expectedForces[389] = Vec3( 1.0621096e+03, 1.6022661e+01, -1.1645539e+03 );
expectedForces[390] = Vec3( -4.7808938e+02, -1.2425496e+03, -1.5543074e+02 );
expectedForces[391] = Vec3( -3.4676860e+02, 8.5391303e+02, 3.5351618e+01 );
expectedForces[392] = Vec3( 5.4017203e+02, 8.6467815e+01, 1.1898140e+02 );
expectedForces[393] = Vec3( -1.8873828e+01, 2.2133074e+02, -1.3378739e+03 );
expectedForces[394] = Vec3( 7.5888012e+01, -1.6517743e+01, 1.1817186e+02 );
expectedForces[395] = Vec3( 1.1912944e+02, -1.6083226e+02, 7.8733940e+02 );
expectedForces[396] = Vec3( -1.2400005e+03, -3.9434827e+02, 1.4071802e+02 );
expectedForces[397] = Vec3( 9.6249284e+02, 1.1394516e+02, -3.4977717e+02 );
expectedForces[398] = Vec3( 2.4187486e+02, 1.3373651e+02, 6.5894105e+01 );
expectedForces[399] = Vec3( 8.8628445e+02, 7.8083892e+01, -1.0288922e+03 );
expectedForces[400] = Vec3( -9.4613057e+02, -1.9076053e+02, 6.7506442e+02 );
expectedForces[401] = Vec3( -6.2746897e+02, 2.9376858e+02, 9.2767458e+02 );
expectedForces[402] = Vec3( 5.5409175e+01, -1.2583442e+03, 7.1728490e+02 );
expectedForces[403] = Vec3( -2.9076856e+02, 7.5539656e+02, 7.0121763e+00 );
expectedForces[404] = Vec3( 2.6220897e+02, -9.5606102e+01, -7.7725998e+02 );
expectedForces[405] = Vec3( -8.6582014e+02, 9.5597761e+02, 1.5941783e+02 );
expectedForces[406] = Vec3( -1.6910265e+02, -7.2646192e+02, -3.5476587e+02 );
expectedForces[407] = Vec3( 9.7629076e+02, -8.3969437e+01, 2.5523637e+02 );
expectedForces[408] = Vec3( -4.9553396e+01, 6.3557270e+02, -7.5908312e+02 );
expectedForces[409] = Vec3( 3.3210227e+01, 1.5198340e+02, 7.0322192e+02 );
expectedForces[410] = Vec3( -2.6532687e+01, -4.1589199e+02, 4.2771258e+02 );
expectedForces[411] = Vec3( 1.1412630e+03, -2.7366656e+02, 9.8419548e+02 );
expectedForces[412] = Vec3( -3.7239786e+02, 7.2244667e+01, -9.9502150e+02 );
expectedForces[413] = Vec3( -4.6476941e+02, -6.1433607e+01, -2.5459288e+02 );
expectedForces[414] = Vec3( 9.7028883e+02, 5.5981848e+02, 8.4425262e+02 );
expectedForces[415] = Vec3( 7.2811577e+01, 2.2872709e+02, -1.3822700e+03 );
expectedForces[416] = Vec3( -1.0105821e+03, -2.8444698e+02, -7.2506392e+02 );
expectedForces[417] = Vec3( 1.0027865e+03, 6.0924816e+02, -5.7818592e+01 );
expectedForces[418] = Vec3( -3.4173955e+02, -1.1932310e+02, -2.9495449e+01 );
expectedForces[419] = Vec3( -2.7281265e+02, -1.8869212e+02, 1.9643932e+02 );
expectedForces[420] = Vec3( -7.4036328e+02, -4.8733524e+02, 1.5862094e+03 );
expectedForces[421] = Vec3( 5.6387864e+02, 3.0991659e+02, -8.6746725e+02 );
expectedForces[422] = Vec3( 6.2954421e-01, 4.9665567e+02, -1.0114913e+03 );
expectedForces[423] = Vec3( 8.9668630e+02, -1.0121499e+03, -1.1520006e+03 );
expectedForces[424] = Vec3( -2.5699741e+02, 3.3243520e+02, 7.6038873e+02 );
expectedForces[425] = Vec3( -1.2755484e+03, -2.7786159e+01, 3.0900583e+02 );
expectedForces[426] = Vec3( -1.2587339e+03, -8.6851333e+02, 1.6295957e+02 );
expectedForces[427] = Vec3( 6.4923970e+02, 4.4600015e+02, 3.3033348e+02 );
expectedForces[428] = Vec3( 5.8905637e+02, -1.1589062e+02, -1.8168184e+02 );
expectedForces[429] = Vec3( -1.1223714e+03, 3.0322406e+01, 8.7272053e+02 );
expectedForces[430] = Vec3( 3.0982625e+02, 3.1418220e+02, -3.9301742e+02 );
expectedForces[431] = Vec3( 2.4213933e+02, -7.2382572e+02, -1.0155346e+03 );
expectedForces[432] = Vec3( 1.1479692e+03, -1.6837721e+03, 1.0545407e+02 );
expectedForces[433] = Vec3( -8.2496264e+02, 6.0540594e+02, 1.3979931e+02 );
expectedForces[434] = Vec3( -6.8171514e+02, 4.0392791e+02, -3.4712316e+02 );
expectedForces[435] = Vec3( -1.5568889e+02, -1.4652975e+03, 5.1518148e+01 );
expectedForces[436] = Vec3( 5.6573856e+02, 3.5494119e+02, -3.3796345e+02 );
expectedForces[437] = Vec3( -1.3938679e+02, 4.2296152e+02, -2.0539863e+02 );
expectedForces[438] = Vec3( 8.9203493e+01, 2.8764597e+02, -7.3273496e+02 );
expectedForces[439] = Vec3( 4.3114292e+02, 9.4778082e+01, 1.8894761e+02 );
expectedForces[440] = Vec3( -2.2798193e+01, -4.5460891e+01, 9.8310963e+01 );
expectedForces[441] = Vec3( -2.1793579e+02, -1.0807542e+03, -2.3470465e+01 );
expectedForces[442] = Vec3( 1.3881360e+02, 3.9806903e+02, 4.1089741e+01 );
expectedForces[443] = Vec3( -4.5604974e+02, 4.8515999e+02, -6.6025174e+02 );
expectedForces[444] = Vec3( 3.6437700e+02, -8.1622511e+02, -9.6454258e+02 );
expectedForces[445] = Vec3( 3.1998690e+02, -3.3342314e+02, 1.2441763e+03 );
expectedForces[446] = Vec3( 3.0822409e+01, 2.0596612e+02, 2.0937122e+02 );
expectedForces[447] = Vec3( -8.4938718e+02, -1.1366483e+03, -1.3638049e+02 );
expectedForces[448] = Vec3( -5.5232451e+01, 4.7335097e+02, -5.4433565e+02 );
expectedForces[449] = Vec3( 6.5928852e+02, 1.7488804e+02, 6.7879378e+02 );
expectedForces[450] = Vec3( -9.4572079e+02, 1.9162420e+02, 4.7935043e+02 );
expectedForces[451] = Vec3( 2.5029547e+02, 3.6606767e+01, -9.3423713e+01 );
expectedForces[452] = Vec3( 1.6543841e+02, -1.1892943e+02, -5.8737050e+02 );
expectedForces[453] = Vec3( -9.8495219e+02, -1.6882428e+03, -4.0576035e+02 );
expectedForces[454] = Vec3( 7.9182557e+02, 5.3997699e+02, 3.3231603e+02 );
expectedForces[455] = Vec3( 1.8277090e+01, 1.4623150e+03, -9.4985721e+01 );
expectedForces[456] = Vec3( -1.0471948e+03, 4.6746395e+02, -1.5020000e+03 );
expectedForces[457] = Vec3( 7.2055316e+02, -5.4467216e+02, 4.0459421e+02 );
expectedForces[458] = Vec3( 7.5475531e+01, 4.9532870e+02, 1.3002474e+03 );
expectedForces[459] = Vec3( 6.3589773e+02, -2.1402397e+02, -1.4147509e+03 );
expectedForces[460] = Vec3( 2.8391861e+02, -8.0142885e+01, 5.6445225e+02 );
expectedForces[461] = Vec3( -8.2442674e+02, 5.3520687e+02, 1.1406667e+03 );
expectedForces[462] = Vec3( -5.7988771e+02, -3.3512887e+02, 4.5461752e+02 );
expectedForces[463] = Vec3( 4.5746059e+02, 3.1029926e+02, -5.0060176e+02 );
expectedForces[464] = Vec3( 7.7747136e+02, 4.2131732e+02, 5.5836239e+02 );
expectedForces[465] = Vec3( -1.2315491e+03, 9.4066088e+02, 9.6145313e+02 );
expectedForces[466] = Vec3( 7.9043841e+02, -2.2172613e+02, -2.6508587e+02 );
expectedForces[467] = Vec3( 7.8197894e+02, -3.1383822e+02, 2.5444013e+02 );
expectedForces[468] = Vec3( -7.1139498e+01, -7.1203189e+01, -4.6845544e+02 );
expectedForces[469] = Vec3( -8.9774100e+01, 1.4389287e+02, 9.8957451e+01 );
expectedForces[470] = Vec3( 3.0397922e+02, -2.8247850e+01, 4.4896034e+02 );
expectedForces[471] = Vec3( -9.7808367e+02, 1.0170553e+03, 8.1594649e+02 );
expectedForces[472] = Vec3( 1.8933676e+02, -8.8053046e+02, 6.8784042e+01 );
expectedForces[473] = Vec3( 5.1636668e+02, 1.2970985e+02, -8.9380858e+02 );
expectedForces[474] = Vec3( -5.8549608e+02, -1.8351156e+02, -5.8043066e+02 );
expectedForces[475] = Vec3( 2.7877663e+02, -3.6576715e+02, 3.5497095e+02 );
expectedForces[476] = Vec3( 3.0642370e+02, 5.3438407e+02, 1.9409584e+02 );
expectedForces[477] = Vec3( -4.8523805e+02, 1.2253320e+03, 9.6414379e+02 );
expectedForces[478] = Vec3( -1.5213013e+02, -2.0017205e+02, -6.6602643e+02 );
expectedForces[479] = Vec3( 4.6435225e+02, -4.1945066e+02, -8.6774270e+01 );
expectedForces[480] = Vec3( 2.4946889e+02, -1.0456281e+03, 4.7404434e+02 );
expectedForces[481] = Vec3( -3.0813505e+01, 2.8598938e+02, 7.7374350e+01 );
expectedForces[482] = Vec3( -2.4538851e+02, 3.8306987e+02, -5.0235520e+02 );
expectedForces[483] = Vec3( 4.0348805e+01, 1.3050360e+03, -6.8725580e+02 );
expectedForces[484] = Vec3( -1.1095514e+02, -2.7711572e+02, 2.6929959e+02 );
expectedForces[485] = Vec3( -6.8071081e+01, -3.4398150e+02, 2.5209743e+02 );
expectedForces[486] = Vec3( 2.1534786e+03, 1.3249493e+01, 7.4171165e+01 );
expectedForces[487] = Vec3( -7.2618755e+02, -3.2914219e+02, 2.5917332e+02 );
expectedForces[488] = Vec3( -1.0231949e+03, 7.2426062e+02, 1.9111862e+02 );
expectedForces[489] = Vec3( 1.1408866e+03, 6.7858353e+02, -2.1410916e+02 );
expectedForces[490] = Vec3( -4.5559047e+02, -1.3597950e+02, -3.2284091e+02 );
expectedForces[491] = Vec3( -8.5558133e+02, -7.1748324e+01, 5.3332261e+02 );
expectedForces[492] = Vec3( -7.1393886e+02, -1.1275222e+03, -6.2147584e+02 );
expectedForces[493] = Vec3( 4.4029614e+02, 1.0518224e+02, 4.6519788e+02 );
expectedForces[494] = Vec3( -3.5770378e+02, 1.0311834e+03, 2.2141802e+02 );
expectedForces[495] = Vec3( -2.6023787e+02, 1.0070248e+03, -1.1113552e+03 );
expectedForces[496] = Vec3( -3.4950242e+02, 2.8418846e+01, 1.2865161e+03 );
expectedForces[497] = Vec3( 1.5030225e+02, -7.7257505e+02, 8.7232628e+02 );
expectedForces[498] = Vec3( -1.7416695e+02, 9.9945569e+02, -1.6742483e+02 );
expectedForces[499] = Vec3( 2.0837481e+02, -1.9388709e+02, 9.7409815e+01 );
expectedForces[500] = Vec3( -1.0129845e+02, -6.8652976e+02, 8.4930186e+02 );
expectedForces[501] = Vec3( 1.2276099e+03, 1.6531986e+02, 3.6342506e+02 );
expectedForces[502] = Vec3( -1.9998077e+02, -2.6164759e+02, -1.6601933e+02 );
expectedForces[503] = Vec3( -4.0356327e+02, 4.0549152e+02, 2.9710052e+02 );
expectedForces[504] = Vec3( -7.3045150e+02, -1.6677706e+03, -9.8671765e+02 );
expectedForces[505] = Vec3( -2.1441879e+02, 1.4962605e+03, 5.6350856e+02 );
expectedForces[506] = Vec3( 7.1102593e+02, 5.9407971e+02, 9.5452239e+02 );
expectedForces[507] = Vec3( 3.2291041e+02, 1.3943261e+03, -1.8477432e+03 );
expectedForces[508] = Vec3( -1.7778104e+02, 2.8034575e+02, 1.1385089e+03 );
expectedForces[509] = Vec3( -2.4943297e+02, -9.0965773e+02, 5.2737490e+02 );
expectedForces[510] = Vec3( -3.8318508e+02, 1.3999092e+03, -5.9960180e+02 );
expectedForces[511] = Vec3( 2.6930065e+01, -3.6603454e+02, 1.0460530e+03 );
expectedForces[512] = Vec3( -1.8964668e+02, -1.1663184e+03, -2.8438291e+02 );
expectedForces[513] = Vec3( -9.4679273e+02, 8.7408257e+01, -2.5740702e+02 );
expectedForces[514] = Vec3( 1.6558849e+02, 3.3561310e+02, 3.8532718e+02 );
expectedForces[515] = Vec3( 4.0403504e+02, -8.5545173e+02, 4.0647038e+02 );
expectedForces[516] = Vec3( 8.3825526e+02, 5.0343638e+01, -3.9171626e+02 );
expectedForces[517] = Vec3( -4.0069871e+02, -6.4140295e+02, 7.5218861e+01 );
expectedForces[518] = Vec3( -6.5213072e+02, 4.1689581e+02, -8.9280241e+01 );
expectedForces[519] = Vec3( 4.0832996e+02, -3.4272605e+02, -9.2740030e+02 );
expectedForces[520] = Vec3( -2.1128040e+01, -7.3467005e+02, 6.5449252e+02 );
expectedForces[521] = Vec3( -2.8042421e+02, 3.3193211e+02, 5.1272473e+02 );
expectedForces[522] = Vec3( -1.2057322e+03, 3.3276609e+02, 6.8838073e+02 );
expectedForces[523] = Vec3( 8.9270663e+02, 1.3914748e+02, -8.7213182e+02 );
expectedForces[524] = Vec3( 8.8063936e+02, -2.4952564e+02, -8.3942753e+01 );
expectedForces[525] = Vec3( 3.6527919e+02, 3.3758036e+02, -1.3449147e+03 );
expectedForces[526] = Vec3( 7.1836993e+01, -3.9380031e+01, 4.7169292e+02 );
expectedForces[527] = Vec3( -7.2114939e+01, -1.3679457e+02, 3.9080695e+02 );
expectedForces[528] = Vec3( 1.1465645e+02, -4.4994719e+02, -3.4180224e+02 );
expectedForces[529] = Vec3( -6.0950292e+01, 4.2825716e+02, -1.4233246e+02 );
expectedForces[530] = Vec3( -1.9112828e+02, -2.8511065e+00, 2.6894050e+02 );
expectedForces[531] = Vec3( 4.4955085e+02, 2.0459389e+02, 8.9486972e+02 );
expectedForces[532] = Vec3( 6.6339624e+01, -4.2734850e+01, -4.8004048e+02 );
expectedForces[533] = Vec3( -5.0521801e+02, -1.6330265e+02, -6.2374206e+02 );
expectedForces[534] = Vec3( -1.1019306e+03, -4.5760347e+02, 4.6134602e+01 );
expectedForces[535] = Vec3( 4.9278700e+02, 8.0495847e+02, -5.7470233e+01 );
expectedForces[536] = Vec3( 9.9361557e+02, -2.4453172e+02, -3.7696369e+02 );
expectedForces[537] = Vec3( -1.1168499e+03, -2.1108925e+02, -4.1233970e+02 );
expectedForces[538] = Vec3( 5.6559058e+02, -2.8153614e+02, 3.0539700e+02 );
expectedForces[539] = Vec3( 4.0805303e+02, 2.8796083e+02, -3.0009135e+01 );
expectedForces[540] = Vec3( -8.5249075e+02, -1.0560038e+03, -6.5111795e+02 );
expectedForces[541] = Vec3( 8.4653565e+02, 2.0615416e+02, -1.5085906e+02 );
expectedForces[542] = Vec3( -2.8200251e+02, 6.6950966e+02, 5.9661450e+02 );
expectedForces[543] = Vec3( -9.3339994e+01, 8.7084190e+02, -7.8375352e+02 );
expectedForces[544] = Vec3( 1.4187243e+02, 1.2829809e+02, 8.0626841e+02 );
expectedForces[545] = Vec3( 1.5403073e+02, -4.5932125e+02, -8.3051878e+00 );
expectedForces[546] = Vec3( 1.3919197e+03, 5.4728737e+02, -1.0548033e+03 );
expectedForces[547] = Vec3( -2.7215065e+02, 1.5112718e+02, 6.7366542e+02 );
expectedForces[548] = Vec3( -7.8677637e+02, -2.6895175e+02, 4.3374996e+02 );
expectedForces[549] = Vec3( 6.6014864e+02, -1.1474704e+03, -3.7199889e+02 );
expectedForces[550] = Vec3( -5.8741315e+02, 2.6286109e+02, 1.9036264e+02 );
expectedForces[551] = Vec3( 1.4325969e+02, 7.8928381e+02, 3.6304214e+02 );
expectedForces[552] = Vec3( -9.6661866e+02, -1.0462801e+03, -6.3261994e+02 );
expectedForces[553] = Vec3( 5.5171916e+02, 2.8672800e+02, 2.7240662e+02 );
expectedForces[554] = Vec3( 1.1625052e+03, 7.7864110e+02, -5.2588322e+02 );
expectedForces[555] = Vec3( 1.7042269e+03, -5.8973225e+02, 1.4814500e+02 );
expectedForces[556] = Vec3( -7.7324022e+02, 2.9167426e+02, -1.0262563e+02 );
expectedForces[557] = Vec3( -5.4655014e+02, -8.4339654e+01, 9.7375629e+02 );
expectedForces[558] = Vec3( -6.9618127e+02, -1.6878530e+02, 7.1078501e+02 );
expectedForces[559] = Vec3( 6.9623995e+02, -3.7038954e+01, 2.2671528e+02 );
expectedForces[560] = Vec3( -7.1025694e+01, -1.8643963e+02, -8.0181026e+02 );
expectedForces[561] = Vec3( -1.4598467e+02, 1.7170707e+03, -4.3305456e+02 );
expectedForces[562] = Vec3( 7.9582463e+02, -5.9551245e+02, 8.3485625e+01 );
expectedForces[563] = Vec3( -4.6812643e+02, -3.4598874e+02, -3.6753356e+01 );
expectedForces[564] = Vec3( -1.8586268e+02, 3.1377143e+02, -1.6616022e+03 );
expectedForces[565] = Vec3( 7.4400496e+02, 5.5058789e+02, 7.5374599e+02 );
expectedForces[566] = Vec3( -6.3347529e+02, -3.1407006e+02, 8.2964691e+02 );
expectedForces[567] = Vec3( -4.2499528e+02, 9.4575975e+02, -6.6700103e+02 );
expectedForces[568] = Vec3( -9.2637696e+02, -6.6301622e+02, 3.9913705e+02 );
expectedForces[569] = Vec3( 5.0588430e+02, -8.1942697e+01, 4.2128365e+02 );
expectedForces[570] = Vec3( 2.7165158e+02, 2.7387902e+02, 1.0850277e+03 );
expectedForces[571] = Vec3( -6.8391471e+00, -1.2886307e+02, -5.3501450e+02 );
expectedForces[572] = Vec3( -2.9936240e+02, -2.2085475e+02, -6.9670281e+01 );
expectedForces[573] = Vec3( 1.6853422e+02, 4.8410887e+02, 1.0517406e+03 );
expectedForces[574] = Vec3( -4.9287521e+02, 1.6557733e+01, -3.4008916e+02 );
expectedForces[575] = Vec3( 1.1132397e+02, -9.8734894e+02, -1.1154151e+02 );
expectedForces[576] = Vec3( 3.8645582e+02, 4.3709361e+02, 1.4861132e+03 );
expectedForces[577] = Vec3( -1.0169967e+03, -3.5279110e+02, -5.4860861e+02 );
expectedForces[578] = Vec3( 2.8875246e+02, 5.3726711e+01, -5.9395936e+02 );
expectedForces[579] = Vec3( 1.5169994e+03, 8.7535209e+01, 1.0103159e+03 );
expectedForces[580] = Vec3( -1.9439968e+02, -7.9639200e+02, -1.0439069e+03 );
expectedForces[581] = Vec3( -8.7374025e+02, 2.0597360e+02, 1.0218319e+02 );
expectedForces[582] = Vec3( 6.4275846e+02, -6.2671529e+02, 8.9274592e+02 );
expectedForces[583] = Vec3( -5.4449356e+01, 7.2615928e+02, -9.1355057e+02 );
expectedForces[584] = Vec3( -2.7242606e+02, 3.9376960e+02, -4.7692581e+01 );
expectedForces[585] = Vec3( 2.6578654e+02, -6.7385441e+02, -1.5306127e+03 );
expectedForces[586] = Vec3( 5.1049761e+02, 7.3430855e+02, 6.1178168e+02 );
expectedForces[587] = Vec3( -3.3593193e+02, 3.5079666e+01, 9.7444298e+02 );
expectedForces[588] = Vec3( -7.8227654e+01, -1.1050481e+03, 1.4161574e+03 );
expectedForces[589] = Vec3( -7.6753407e+02, 9.7291633e+02, 1.9943116e+02 );
expectedForces[590] = Vec3( 2.9274184e+02, -2.5706985e+01, -5.8944290e+02 );
expectedForces[591] = Vec3( -1.2502829e+03, 2.2304820e+02, -8.8573767e+02 );
expectedForces[592] = Vec3( 1.2218682e+02, -8.2110835e+02, 3.4276058e+02 );
expectedForces[593] = Vec3( 8.9529566e+02, -1.8417573e+02, 8.4717919e+02 );
expectedForces[594] = Vec3( -4.6475772e+01, -1.5493620e+03, 4.8004365e+02 );
expectedForces[595] = Vec3( 6.7104033e+02, 4.7267915e+02, -6.2630817e+02 );
expectedForces[596] = Vec3( -2.2771561e+02, 2.7463551e+02, -2.9704610e+00 );
expectedForces[597] = Vec3( 1.7757815e+02, -1.8906761e+03, -1.6656886e+02 );
expectedForces[598] = Vec3( -7.4745588e+01, 1.0353962e+03, 4.2924498e+02 );
expectedForces[599] = Vec3( -5.5648197e+02, 7.7838572e+02, -4.1677346e+02 );
expectedForces[600] = Vec3( -5.2972489e+02, 1.1967117e+02, 1.0565388e+03 );
expectedForces[601] = Vec3( 7.8379665e+02, -4.1803420e+02, 2.0308387e+02 );
expectedForces[602] = Vec3( 1.2705528e+02, 1.1663435e+02, -7.6514830e+02 );
expectedForces[603] = Vec3( -1.5203094e+03, -8.5825144e+01, -2.3039380e+02 );
expectedForces[604] = Vec3( 5.2063739e+02, -1.7259834e+02, -2.9854160e+01 );
expectedForces[605] = Vec3( 4.7448961e+02, 2.8282389e+02, 3.4257463e+01 );
expectedForces[606] = Vec3( 1.4519531e+03, -1.2031444e+03, -6.7084095e+02 );
expectedForces[607] = Vec3( -7.5308994e+02, -3.2117501e+02, 5.7700017e+02 );
expectedForces[608] = Vec3( -1.7643179e+02, 8.5655779e+02, -2.6285482e+02 );
expectedForces[609] = Vec3( -1.3868959e+03, -1.6195505e+01, -1.3783528e+03 );
expectedForces[610] = Vec3( 2.8034476e+02, -4.2360778e+02, 4.5904202e+02 );
expectedForces[611] = Vec3( 1.0938532e+03, 6.2455629e+02, -1.0108636e+02 );
expectedForces[612] = Vec3( 9.1439974e+01, -7.2813810e+02, 1.0197075e+03 );
expectedForces[613] = Vec3( 1.4048294e+02, 2.5667744e+02, -5.1914694e+02 );
expectedForces[614] = Vec3( -2.5604629e+01, 2.9915218e+01, -5.1582702e+02 );
expectedForces[615] = Vec3( 2.0331673e+02, 1.5538650e+02, -1.1836865e+03 );
expectedForces[616] = Vec3( -2.3788957e+02, -1.1872269e+02, 9.7052698e+02 );
expectedForces[617] = Vec3( -3.2419551e+01, -1.8828745e+02, 4.3037423e+02 );
expectedForces[618] = Vec3( -4.8585762e+02, 1.4114027e+02, 1.6021114e+02 );
expectedForces[619] = Vec3( 2.8744134e+02, -5.7197623e+02, -1.8323508e+02 );
expectedForces[620] = Vec3( 2.3652930e+02, -1.5448350e+01, 2.1721186e+01 );
expectedForces[621] = Vec3( 1.1684581e+03, 2.2790484e+02, 2.7798348e+02 );
expectedForces[622] = Vec3( -4.6823976e+02, -6.1804544e+02, 2.7193441e+02 );
expectedForces[623] = Vec3( -5.8173089e+02, 4.4573870e+02, -6.0699430e+02 );
expectedForces[624] = Vec3( 7.9759250e+02, 1.8480473e+03, -5.1434277e+02 );
expectedForces[625] = Vec3( -1.0945975e+03, -6.0402685e+02, 1.5843017e+02 );
expectedForces[626] = Vec3( 1.2334392e+02, -9.5602838e+02, 7.8137824e+02 );
expectedForces[627] = Vec3( -8.5863208e+02, -5.7413454e+02, 1.7014217e+02 );
expectedForces[628] = Vec3( -1.2232569e+02, 6.0505774e+02, -1.6806693e+02 );
expectedForces[629] = Vec3( 6.1488135e+02, 4.1603705e+02, 2.1121948e+02 );
expectedForces[630] = Vec3( 2.1858899e+02, 1.2961013e+03, 4.8534041e+02 );
expectedForces[631] = Vec3( 2.1292701e+02, -4.1049165e+02, 3.9057142e+00 );
expectedForces[632] = Vec3( -6.3342469e+02, -8.7529004e+02, 6.1928550e+01 );
expectedForces[633] = Vec3( -7.3207079e+02, -1.3874807e+03, 8.6303032e+02 );
expectedForces[634] = Vec3( 6.6660351e+02, 9.5813895e+02, -1.4555416e+02 );
expectedForces[635] = Vec3( 4.1800653e+02, 2.4677420e+02, -1.1424272e+03 );
expectedForces[636] = Vec3( 8.3570430e+02, -1.5342969e+03, -1.2510269e+03 );
expectedForces[637] = Vec3( -3.0635229e+02, 1.2465088e+03, -1.9679529e+01 );
expectedForces[638] = Vec3( -6.5317178e+02, -1.6432929e+02, 9.2427724e+02 );
expectedForces[639] = Vec3( 1.5665680e+03, 9.8040004e+01, 1.0786497e+02 );
expectedForces[640] = Vec3( -4.6590380e+02, -3.7603795e+02, -9.4955273e+02 );
expectedForces[641] = Vec3( -8.7572108e+02, 5.1750570e+02, -1.2268062e+02 );
expectedForces[642] = Vec3( 1.1575067e+03, -2.2857204e+02, -2.3816900e+02 );
expectedForces[643] = Vec3( -2.6229644e+02, 3.1069110e+02, -1.2098536e+02 );
expectedForces[644] = Vec3( -1.8195659e+02, -3.8984698e+02, 6.4622752e+02 );
expectedForces[645] = Vec3( 1.0756277e+03, 2.7459106e+01, 1.0850508e+03 );
expectedForces[646] = Vec3( -6.4620310e+02, 2.5885783e+02, -2.0567224e+02 );
expectedForces[647] = Vec3( -4.7388806e+02, -5.5561844e+02, -8.5019295e+02 );
double tolerance = 1.0e-03;
compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log );
}
int main( int numberOfArguments, char* argv[] ) { int main( int numberOfArguments, char* argv[] ) {
try { try {
...@@ -1386,9 +2849,9 @@ int main( int numberOfArguments, char* argv[] ) { ...@@ -1386,9 +2849,9 @@ int main( int numberOfArguments, char* argv[] ) {
testMultipoleAmmoniaMutualPolarization( log ); testMultipoleAmmoniaMutualPolarization( log );
// // test multipole direct & mutual polarization using PME // test multipole direct & mutual polarization using PME
//
// testMultipoleWaterPMEDirectPolarization( log ); testMultipoleWaterPMEDirectPolarization( log );
// testMultipoleWaterPMEMutualPolarization( log ); // testMultipoleWaterPMEMutualPolarization( log );
// //
// // check validation of traceless/symmetric quadrupole tensor // // check validation of traceless/symmetric quadrupole tensor
...@@ -1407,6 +2870,10 @@ int main( int numberOfArguments, char* argv[] ) { ...@@ -1407,6 +2870,10 @@ int main( int numberOfArguments, char* argv[] ) {
// // test computation of grid potential // // test computation of grid potential
// //
// testMultipoleGridPotential( log ); // testMultipoleGridPotential( log );
//
// // large box of water
//
// testPMEMutualPolarizationLargeWater( log );
} catch(const std::exception& e) { } catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl; std::cout << "exception: " << e.what() << std::endl;
......
...@@ -194,8 +194,10 @@ void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, c ...@@ -194,8 +194,10 @@ void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, c
Vec3 c( 0.0, 0.0, boxDimension ); Vec3 c( 0.0, 0.0, boxDimension );
system.setDefaultPeriodicBoxVectors( a, b, c ); system.setDefaultPeriodicBoxVectors( a, b, c );
amoebaVdwForce->setPBC( 1 ); amoebaVdwForce->setPBC( 1 );
amoebaVdwForce->setUseDispersionCorrection( 1 );
} else { } else {
amoebaVdwForce->setPBC( 0 ); amoebaVdwForce->setPBC( 0 );
amoebaVdwForce->setUseDispersionCorrection( 0 );
} }
// addParticle: ivIndex, radius, epsilon, reductionFactor // addParticle: ivIndex, radius, epsilon, reductionFactor
...@@ -315,12 +317,16 @@ void compareForcesEnergy( std::string& testName, double expectedEnergy, double e ...@@ -315,12 +317,16 @@ void compareForcesEnergy( std::string& testName, double expectedEnergy, double e
std::vector<Vec3>& forces, double tolerance, FILE* log ) { std::vector<Vec3>& forces, double tolerance, FILE* log ) {
#define AMOEBA_DEBUG
#ifdef AMOEBA_DEBUG #ifdef AMOEBA_DEBUG
if( log ){ if( log ){
(void) fprintf( log, "%s: expected energy=%14.7e %14.7e\n", testName.c_str(), expectedEnergy, state.getPotentialEnergy() ); double conversion = 1.0/4.184;
(void) fprintf( log, "%s: expected energy=%14.7e %14.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy );
conversion *= -0.1;
for( unsigned int ii = 0; ii < forces.size(); ii++ ){ for( unsigned int ii = 0; ii < forces.size(); ii++ ){
(void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii,
expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2],
conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] );
} }
(void) fflush( log ); (void) fflush( log );
} }
...@@ -495,7 +501,7 @@ void testVdwPBC( FILE* log ) { ...@@ -495,7 +501,7 @@ void testVdwPBC( FILE* log ) {
setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log ); setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log );
std::vector<Vec3> expectedForces(numberOfParticles); std::vector<Vec3> expectedForces(numberOfParticles);
double expectedEnergy = 8.4385405e+00; double expectedEnergy = 1.4949141e+01;
expectedForces[0] = Vec3( 5.1453069e+02, 4.9751912e-01, -1.2759570e+01 ); expectedForces[0] = Vec3( 5.1453069e+02, 4.9751912e-01, -1.2759570e+01 );
expectedForces[1] = Vec3( -2.5622586e+02, -4.6524265e+01, 2.4281465e+01 ); expectedForces[1] = Vec3( -2.5622586e+02, -4.6524265e+01, 2.4281465e+01 );
...@@ -513,6 +519,1442 @@ void testVdwPBC( FILE* log ) { ...@@ -513,6 +519,1442 @@ void testVdwPBC( FILE* log ) {
compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log );
} }
// create box of 216 water molecules
void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff,
double boxDimension, int includeVdwDispersionCorrection,
std::vector<Vec3>& forces, double& energy, FILE* log ){
// beginning of Vdw setup
System system;
AmoebaVdwForce* amoebaVdwForce = new AmoebaVdwForce();;
int numberOfParticles = 648;
amoebaVdwForce->setSigmaCombiningRule( sigmaCombiningRule );
amoebaVdwForce->setEpsilonCombiningRule( epsilonCombiningRule );
amoebaVdwForce->setUseNeighborList( 1 );
amoebaVdwForce->setCutoff( cutoff );
if( boxDimension > 0.0 ){
Vec3 a( boxDimension, 0.0, 0.0 );
Vec3 b( 0.0, boxDimension, 0.0 );
Vec3 c( 0.0, 0.0, boxDimension );
system.setDefaultPeriodicBoxVectors( a, b, c );
amoebaVdwForce->setPBC( 1 );
amoebaVdwForce->setUseDispersionCorrection( includeVdwDispersionCorrection );
} else {
amoebaVdwForce->setPBC( 0 );
amoebaVdwForce->setUseDispersionCorrection( 0 );
}
// addParticle: ivIndex, classIndex, radius, epsilon, reductionFactor
int classIndex = 0;
for( unsigned int ii = 0; ii < numberOfParticles; ii += 3 ){
system.addParticle( 1.5995000e+01 );
amoebaVdwForce->addParticle( ii, 0, 1.7025000e-01, 4.6024000e-01, 0.0000000e+00 );
system.addParticle( 1.0080000e+00 );
amoebaVdwForce->addParticle( ii, 0, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01 );
system.addParticle( 1.0080000e+00 );
amoebaVdwForce->addParticle( ii, 0, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01 );
}
// exclusions
std::vector< int > exclusions(3);
for( unsigned int ii = 0; ii < numberOfParticles; ii += 3 ){
exclusions[0] = ii;
exclusions[1] = ii+1;
exclusions[2] = ii+2;
amoebaVdwForce->setParticleExclusions( ii, exclusions );
amoebaVdwForce->setParticleExclusions( ii+1, exclusions );
amoebaVdwForce->setParticleExclusions( ii+2, exclusions );
}
// end of Vdw setup
// set positions
std::vector<Vec3> positions(numberOfParticles);
positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02 );
positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02 );
positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02 );
positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01 );
positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01 );
positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01 );
positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01 );
positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01 );
positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01 );
positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01 );
positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01 );
positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01 );
positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01 );
positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01 );
positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01 );
positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01 );
positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01 );
positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01 );
positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01 );
positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01 );
positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01 );
positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01 );
positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01 );
positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01 );
positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01 );
positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01 );
positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02 );
positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02 );
positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01 );
positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01 );
positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01 );
positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01 );
positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01 );
positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01 );
positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01 );
positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01 );
positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01 );
positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01 );
positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01 );
positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01 );
positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01 );
positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01 );
positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01 );
positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01 );
positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01 );
positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01 );
positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01 );
positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01 );
positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01 );
positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01 );
positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01 );
positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01 );
positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01 );
positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01 );
positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01 );
positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01 );
positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01 );
positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01 );
positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01 );
positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01 );
positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01 );
positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01 );
positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01 );
positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02 );
positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02 );
positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01 );
positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02 );
positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02 );
positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01 );
positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01 );
positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01 );
positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01 );
positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01 );
positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01 );
positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01 );
positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01 );
positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02 );
positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01 );
positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01 );
positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01 );
positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01 );
positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02 );
positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01 );
positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02 );
positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01 );
positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01 );
positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01 );
positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01 );
positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01 );
positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01 );
positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01 );
positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01 );
positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01 );
positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01 );
positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01 );
positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01 );
positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01 );
positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01 );
positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01 );
positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01 );
positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01 );
positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01 );
positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01 );
positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01 );
positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01 );
positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01 );
positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01 );
positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01 );
positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01 );
positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01 );
positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01 );
positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02 );
positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02 );
positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01 );
positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01 );
positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01 );
positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01 );
positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01 );
positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01 );
positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01 );
positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01 );
positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01 );
positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01 );
positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01 );
positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02 );
positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01 );
positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01 );
positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01 );
positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01 );
positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01 );
positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01 );
positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01 );
positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01 );
positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01 );
positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01 );
positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01 );
positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01 );
positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01 );
positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01 );
positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01 );
positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01 );
positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01 );
positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01 );
positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01 );
positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01 );
positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01 );
positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01 );
positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01 );
positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01 );
positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01 );
positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01 );
positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01 );
positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01 );
positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01 );
positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01 );
positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01 );
positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02 );
positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02 );
positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02 );
positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01 );
positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02 );
positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02 );
positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01 );
positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01 );
positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01 );
positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01 );
positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01 );
positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01 );
positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01 );
positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01 );
positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01 );
positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01 );
positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01 );
positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01 );
positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01 );
positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01 );
positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01 );
positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01 );
positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01 );
positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01 );
positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01 );
positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01 );
positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01 );
positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01 );
positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01 );
positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01 );
positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02 );
positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01 );
positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03 );
positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01 );
positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01 );
positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01 );
positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01 );
positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01 );
positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01 );
positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01 );
positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01 );
positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01 );
positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01 );
positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01 );
positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01 );
positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02 );
positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01 );
positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02 );
positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01 );
positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01 );
positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01 );
positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01 );
positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01 );
positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01 );
positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01 );
positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01 );
positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01 );
positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01 );
positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01 );
positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01 );
positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01 );
positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01 );
positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01 );
positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01 );
positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01 );
positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01 );
positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01 );
positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01 );
positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01 );
positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02 );
positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01 );
positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02 );
positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01 );
positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01 );
positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01 );
positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01 );
positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01 );
positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01 );
positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01 );
positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01 );
positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01 );
positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01 );
positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01 );
positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01 );
positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01 );
positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01 );
positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01 );
positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02 );
positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01 );
positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02 );
positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01 );
positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01 );
positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01 );
positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01 );
positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01 );
positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01 );
positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01 );
positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01 );
positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01 );
positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01 );
positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01 );
positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01 );
positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01 );
positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01 );
positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01 );
positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01 );
positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01 );
positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01 );
positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03 );
positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03 );
positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02 );
positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01 );
positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01 );
positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01 );
positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01 );
positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01 );
positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01 );
positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01 );
positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01 );
positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01 );
positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01 );
positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01 );
positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01 );
positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01 );
positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01 );
positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01 );
positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01 );
positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01 );
positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01 );
positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01 );
positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01 );
positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01 );
positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02 );
positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01 );
positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02 );
positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01 );
positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01 );
positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01 );
positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01 );
positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02 );
positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02 );
positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01 );
positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01 );
positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01 );
positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01 );
positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01 );
positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01 );
positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01 );
positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01 );
positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01 );
positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01 );
positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01 );
positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01 );
positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01 );
positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01 );
positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01 );
positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01 );
positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01 );
positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01 );
positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02 );
positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01 );
positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02 );
positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01 );
positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01 );
positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01 );
positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01 );
positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01 );
positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01 );
positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01 );
positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01 );
positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01 );
positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02 );
positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02 );
positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02 );
positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01 );
positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01 );
positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01 );
positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01 );
positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01 );
positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01 );
positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01 );
positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01 );
positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01 );
positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01 );
positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01 );
positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01 );
positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02 );
positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02 );
positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02 );
positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01 );
positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01 );
positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01 );
positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01 );
positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01 );
positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01 );
positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01 );
positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01 );
positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01 );
positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01 );
positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01 );
positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01 );
positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01 );
positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01 );
positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01 );
positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01 );
positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01 );
positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01 );
positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01 );
positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02 );
positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01 );
positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01 );
positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02 );
positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01 );
positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01 );
positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01 );
positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01 );
positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01 );
positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01 );
positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01 );
positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01 );
positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01 );
positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01 );
positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02 );
positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02 );
positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02 );
positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01 );
positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01 );
positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01 );
positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01 );
positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01 );
positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01 );
positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01 );
positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01 );
positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01 );
positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01 );
positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01 );
positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01 );
positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01 );
positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01 );
positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01 );
positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01 );
positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01 );
positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01 );
positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01 );
positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01 );
positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01 );
positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01 );
positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01 );
positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01 );
positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02 );
positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01 );
positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03 );
positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01 );
positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01 );
positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01 );
positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01 );
positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01 );
positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01 );
positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03 );
positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02 );
positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03 );
positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01 );
positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01 );
positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01 );
positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01 );
positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01 );
positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01 );
positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01 );
positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01 );
positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01 );
positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01 );
positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01 );
positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01 );
positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01 );
positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01 );
positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01 );
positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01 );
positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01 );
positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01 );
positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01 );
positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01 );
positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01 );
positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01 );
positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01 );
positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01 );
positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02 );
positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02 );
positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01 );
positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01 );
positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01 );
positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01 );
positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01 );
positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01 );
positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01 );
positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01 );
positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01 );
positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01 );
positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01 );
positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01 );
positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01 );
positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01 );
positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01 );
positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01 );
positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01 );
positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01 );
positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01 );
positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01 );
positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01 );
positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01 );
positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01 );
positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01 );
positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01 );
positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01 );
positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01 );
positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01 );
positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02 );
positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03 );
positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01 );
positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01 );
positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01 );
positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01 );
positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01 );
positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01 );
positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01 );
positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01 );
positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01 );
positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01 );
positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01 );
positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01 );
positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02 );
positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01 );
positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01 );
positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01 );
positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01 );
positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01 );
positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01 );
positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01 );
positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01 );
positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01 );
positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01 );
positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01 );
positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01 );
positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01 );
positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01 );
positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01 );
positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01 );
positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01 );
positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01 );
positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01 );
positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01 );
positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01 );
positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01 );
positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01 );
positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01 );
positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01 );
positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01 );
positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01 );
positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01 );
positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01 );
positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01 );
positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01 );
positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01 );
positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01 );
positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01 );
positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01 );
positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01 );
positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01 );
positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01 );
positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01 );
positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01 );
positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01 );
positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01 );
positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01 );
positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01 );
positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01 );
positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01 );
positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01 );
positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01 );
positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01 );
positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01 );
positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01 );
positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01 );
positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01 );
positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01 );
positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01 );
positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01 );
positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01 );
positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01 );
positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01 );
positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01 );
positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01 );
positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01 );
positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01 );
positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01 );
positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01 );
positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01 );
positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02 );
positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01 );
positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02 );
positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01 );
positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01 );
positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02 );
positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02 );
positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02 );
positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02 );
positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01 );
positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01 );
positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01 );
positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01 );
positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02 );
positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02 );
positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01 );
positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01 );
positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01 );
positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01 );
positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01 );
positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01 );
positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01 );
positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01 );
positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01 );
positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02 );
positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02 );
positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02 );
positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02 );
positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02 );
positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01 );
positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01 );
positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01 );
positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01 );
positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01 );
positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01 );
positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01 );
positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01 );
positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01 );
positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01 );
positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01 );
positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01 );
positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01 );
positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01 );
positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01 );
positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01 );
positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01 );
positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01 );
positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01 );
positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01 );
positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01 );
positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01 );
positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01 );
positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01 );
positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01 );
positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01 );
positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01 );
positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01 );
positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01 );
positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01 );
positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01 );
positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01 );
positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01 );
positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01 );
positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01 );
positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01 );
positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01 );
positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01 );
positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01 );
positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01 );
positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01 );
positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01 );
positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01 );
positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01 );
positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01 );
positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01 );
positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01 );
positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01 );
positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01 );
positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01 );
positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01 );
positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01 );
positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01 );
positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01 );
positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01 );
positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01 );
positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01 );
positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01 );
positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01 );
positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01 );
positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01 );
positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01 );
positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01 );
positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01 );
positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01 );
positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01 );
positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01 );
system.addForce(amoebaVdwForce);
std::string platformName;
platformName = "CUDA";
LangevinIntegrator integrator(0.0, 0.1, 0.01);
Context context(system, integrator, Platform::getPlatformByName( platformName ) );
context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy);
forces = state.getForces();
energy = state.getPotentialEnergy();
}
// test employing box of 216 water molecules w/ and w/o dispersion correction
void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) {
std::string testName;
if( includeVdwDispersionCorrection ){
testName = "testVdwWaterWithDispersionCorrection";
} else {
testName = "testVdwWater";
}
int numberOfParticles = 648;
double boxDimension = 1.8643;
double cutoff = 0.9;
std::vector<Vec3> forces;
double energy;
setupAndGetForcesEnergyVdwWater( "CUBIC-MEAN", "HHG", cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy, log );
std::vector<Vec3> expectedForces(numberOfParticles);
// initialize expected energy and forces
double expectedEnergy;
if( includeVdwDispersionCorrection ){
expectedEnergy = 4.0108819792e+03;
} else {
expectedEnergy = 4.0349101e+03;
}
expectedForces[0] = Vec3( 2.3025909e+02, -1.0422757e+01, -2.1413965e+02 );
expectedForces[1] = Vec3( 1.1261936e+02, 5.5882575e+02, 9.6539143e+01 );
expectedForces[2] = Vec3( -8.8436857e+01, -4.4737313e+01, 2.5242022e+02 );
expectedForces[3] = Vec3( 6.3548886e+02, -1.9582636e+02, -1.2229882e+02 );
expectedForces[4] = Vec3( -3.9513809e+02, -1.3738635e+02, -1.2488717e+02 );
expectedForces[5] = Vec3( 6.8771170e+00, 9.1574345e+01, -1.3865672e+00 );
expectedForces[6] = Vec3( 3.6928792e+02, -7.1025648e+01, 5.2550320e+02 );
expectedForces[7] = Vec3( 1.5531325e+02, -7.9256260e+02, 3.8119809e+02 );
expectedForces[8] = Vec3( 1.5408049e+02, 1.4633285e+02, -5.4573735e+02 );
expectedForces[9] = Vec3( -3.2549641e+02, 2.8613802e+01, 1.8082150e+02 );
expectedForces[10] = Vec3( 1.9968249e+02, -7.7742415e+01, -4.2188467e+02 );
expectedForces[11] = Vec3( 4.6645952e+01, 2.1362909e+01, 5.7120135e+01 );
expectedForces[12] = Vec3( 4.2971265e+01, -4.2927865e+01, -7.6319121e+02 );
expectedForces[13] = Vec3( 2.1889551e+02, -5.1806784e+01, 7.6637073e+01 );
expectedForces[14] = Vec3( -3.0028991e+02, 9.0479382e+01, 1.3199449e+02 );
expectedForces[15] = Vec3( -1.8041801e+00, -1.2176813e+03, -5.9679371e+02 );
expectedForces[16] = Vec3( -1.4773339e+02, -1.2582057e+02, 8.4242040e+02 );
expectedForces[17] = Vec3( 6.8633312e+02, -2.4864325e+01, 1.0675519e+01 );
expectedForces[18] = Vec3( 4.8211733e+02, -2.2044742e+02, 1.8105309e+02 );
expectedForces[19] = Vec3( -2.1956736e+02, 5.4786741e+02, -1.4827263e+02 );
expectedForces[20] = Vec3( -1.0476100e+02, -1.6922280e+02, 8.3220473e+01 );
expectedForces[21] = Vec3( 5.5455350e+01, 1.7851224e+02, 6.0598643e+02 );
expectedForces[22] = Vec3( 7.1915871e+00, -1.6455057e+01, -6.3929797e+00 );
expectedForces[23] = Vec3( -2.4371864e+02, -7.0765288e+02, -1.7820148e+02 );
expectedForces[24] = Vec3( -4.3715367e+02, 2.8707226e+02, 2.2558361e+02 );
expectedForces[25] = Vec3( 2.3735557e+00, -4.2064130e+00, 2.5933632e+01 );
expectedForces[26] = Vec3( 1.0192415e+02, 5.3205842e+01, -2.0158900e+02 );
expectedForces[27] = Vec3( -5.1276812e+02, 2.4860179e+02, 2.5150125e+02 );
expectedForces[28] = Vec3( 3.9608987e+02, -4.0544816e+01, -2.1579831e+02 );
expectedForces[29] = Vec3( -2.5926005e+02, -1.1691294e+02, -4.7278417e+02 );
expectedForces[30] = Vec3( -1.1036158e+02, 3.3229287e+01, 8.8351491e+01 );
expectedForces[31] = Vec3( -4.1178603e+00, 1.2957632e+00, 1.2617868e+00 );
expectedForces[32] = Vec3( 1.9401524e+02, 1.0030314e+02, 3.0386141e+01 );
expectedForces[33] = Vec3( 1.0870981e+02, 2.1865882e+02, 6.7672725e+02 );
expectedForces[34] = Vec3( 3.6812338e+01, -2.9347382e-01, 1.2959790e+01 );
expectedForces[35] = Vec3( -5.5738560e+01, 2.2268442e+02, -1.4911862e+02 );
expectedForces[36] = Vec3( -1.6659719e+02, 8.1941190e+01, 7.8132996e+01 );
expectedForces[37] = Vec3( -1.1985659e+02, 7.1891763e+01, -3.2559738e+02 );
expectedForces[38] = Vec3( 1.4441653e+02, 4.1824194e+02, 3.4293255e+01 );
expectedForces[39] = Vec3( 1.1307312e+02, -3.4981802e+02, -1.0676819e+02 );
expectedForces[40] = Vec3( -1.2857487e+02, -4.0798950e+01, -1.7800009e+02 );
expectedForces[41] = Vec3( -4.1244991e+02, 2.3439565e+02, 3.8546709e+02 );
expectedForces[42] = Vec3( 2.1799653e+02, 2.9397348e+02, -3.8955146e+02 );
expectedForces[43] = Vec3( -9.4254462e+01, 5.0157547e+01, 1.3707146e+02 );
expectedForces[44] = Vec3( 8.0520929e+02, -1.0228045e+03, -4.5813594e+01 );
expectedForces[45] = Vec3( 5.3451125e+02, -7.0725115e+02, -2.3828883e+02 );
expectedForces[46] = Vec3( 3.6991801e+02, -1.0410466e+03, 8.4889413e+02 );
expectedForces[47] = Vec3( 5.8096458e+01, 2.3859368e+02, 7.3104979e+01 );
expectedForces[48] = Vec3( -1.3230378e+03, 7.1827816e+02, 9.4372946e+02 );
expectedForces[49] = Vec3( -4.2398413e+02, -3.6766481e+02, -1.6666711e+02 );
expectedForces[50] = Vec3( 8.6374766e+00, -2.7870227e+02, 3.0621233e+02 );
expectedForces[51] = Vec3( -2.4404981e+02, 1.0510491e+03, -3.5202340e+02 );
expectedForces[52] = Vec3( 1.7461155e+02, 1.3419948e+02, 5.0279733e+02 );
expectedForces[53] = Vec3( 9.7089193e+01, -1.4826120e+02, -2.3426711e+02 );
expectedForces[54] = Vec3( -1.0647432e+02, 2.3266543e+02, -3.5025025e+02 );
expectedForces[55] = Vec3( -1.9951717e+02, -1.0804258e+02, 6.2114265e+01 );
expectedForces[56] = Vec3( 2.5354284e+02, -3.5074926e+02, -2.9176946e+01 );
expectedForces[57] = Vec3( -8.8328002e+02, -1.8937053e+02, 2.0772189e+02 );
expectedForces[58] = Vec3( 4.5809698e+01, -1.8636513e+00, 1.6742910e+01 );
expectedForces[59] = Vec3( 8.6670673e+01, 1.2653519e+02, 2.0046372e+02 );
expectedForces[60] = Vec3( -9.6142275e+02, 1.1800289e+03, 1.0064471e+02 );
expectedForces[61] = Vec3( -6.9751453e+01, -1.9324691e+02, 2.2638891e+01 );
expectedForces[62] = Vec3( 1.3671815e+02, 1.0129231e+01, -6.1136892e+01 );
expectedForces[63] = Vec3( 7.6032938e+02, -1.9779542e+02, -2.5706161e+01 );
expectedForces[64] = Vec3( -9.8966607e+00, 3.6294058e+02, -2.3247376e+02 );
expectedForces[65] = Vec3( -1.3142673e+02, 9.9368000e+00, 1.4225069e+02 );
expectedForces[66] = Vec3( 5.2691625e+01, -4.0618331e+02, -1.0942115e+02 );
expectedForces[67] = Vec3( 5.8137742e+01, 2.1942441e+02, -1.7191686e+02 );
expectedForces[68] = Vec3( 1.2480778e+02, 2.4086799e+01, -1.9588545e+02 );
expectedForces[69] = Vec3( 2.4577512e+02, -2.3516051e+01, 2.3764379e+02 );
expectedForces[70] = Vec3( 4.2298797e+01, 8.6807583e+01, 2.9276129e+02 );
expectedForces[71] = Vec3( 3.0309915e+01, -3.4686002e+02, 1.0849989e+02 );
expectedForces[72] = Vec3( 5.5170999e+02, -1.5797913e+02, 9.8379834e+01 );
expectedForces[73] = Vec3( -5.3706921e+02, 2.2236470e+02, 2.7548665e+02 );
expectedForces[74] = Vec3( -2.7734936e+02, -4.2949693e+02, -8.2303469e+02 );
expectedForces[75] = Vec3( 1.1749001e+03, 9.2734627e+02, -2.6342291e+02 );
expectedForces[76] = Vec3( -1.2345216e+02, -6.6220297e+01, 1.1022778e+02 );
expectedForces[77] = Vec3( -4.4861284e+01, -7.4560959e+01, -8.0791275e+01 );
expectedForces[78] = Vec3( 1.7692476e+01, -9.9067626e+02, -3.3083363e+02 );
expectedForces[79] = Vec3( 6.4276566e+01, 5.1865608e+02, 4.1241764e+02 );
expectedForces[80] = Vec3( 6.5867999e+02, 2.0995465e+02, -5.0989840e+02 );
expectedForces[81] = Vec3( -5.2826435e+02, -1.3719887e+02, 1.9730314e+02 );
expectedForces[82] = Vec3( 2.3329314e+02, 5.1589944e+01, -3.3942818e+02 );
expectedForces[83] = Vec3( -2.5756193e+00, 1.3788257e+02, 1.3074778e+02 );
expectedForces[84] = Vec3( -2.8925811e+01, 8.8185346e+01, 1.1547804e+02 );
expectedForces[85] = Vec3( -3.3582542e+01, -1.3079843e+02, 3.4774799e+02 );
expectedForces[86] = Vec3( -5.9585326e+01, -3.7973755e+01, 1.0206767e+01 );
expectedForces[87] = Vec3( -7.1691223e+01, -1.9547311e+02, 9.3856472e+02 );
expectedForces[88] = Vec3( 1.4832977e+02, 4.2005795e+02, 2.7235044e+01 );
expectedForces[89] = Vec3( 8.6221698e+00, -1.3935906e+01, -2.5473157e+00 );
expectedForces[90] = Vec3( 3.0044348e+02, 3.4320406e+02, 2.5305998e+02 );
expectedForces[91] = Vec3( -1.6694013e+02, 7.4645776e+02, 3.3266168e+01 );
expectedForces[92] = Vec3( 1.6931562e+02, -2.3972286e+01, -3.0802865e+02 );
expectedForces[93] = Vec3( -2.5931152e+02, -9.7825375e+01, -5.5598386e+02 );
expectedForces[94] = Vec3( -7.8473519e+01, -2.6244561e+02, 2.9622027e+02 );
expectedForces[95] = Vec3( 1.5788473e+02, 2.9806605e+02, 1.8283700e+02 );
expectedForces[96] = Vec3( -4.2033208e+02, 4.8745845e+02, 9.7957219e+01 );
expectedForces[97] = Vec3( 1.3261733e+00, 3.7143158e+00, -1.8329960e+00 );
expectedForces[98] = Vec3( 7.4741051e+02, 1.0482696e+03, 1.7182445e+02 );
expectedForces[99] = Vec3( 2.0366606e+02, 1.1586652e+02, 1.5482927e+03 );
expectedForces[100] = Vec3( 5.7569884e+02, -2.2068597e+02, -1.9305186e+02 );
expectedForces[101] = Vec3( -2.4259775e+02, -6.1359858e+01, -7.5753918e+01 );
expectedForces[102] = Vec3( 2.4382837e+02, 1.3660693e+01, -2.8717824e+02 );
expectedForces[103] = Vec3( -4.1914381e+02, -1.4506334e+02, 7.7692658e+01 );
expectedForces[104] = Vec3( 9.5422158e+01, -1.4261849e+01, 1.0122453e+02 );
expectedForces[105] = Vec3( -6.1222151e+02, 6.1398147e+01, 3.2961693e+02 );
expectedForces[106] = Vec3( -2.7982116e+02, -3.7564793e+02, -2.4318658e+02 );
expectedForces[107] = Vec3( 8.2892383e+01, 1.1992522e+01, 2.4802899e+01 );
expectedForces[108] = Vec3( -3.3626753e+02, -7.8892295e+01, 8.1184535e+02 );
expectedForces[109] = Vec3( -4.6396103e+01, 3.1165111e+01, -3.5184949e+01 );
expectedForces[110] = Vec3( 4.6295297e+02, -8.0135823e+01, -3.2963637e+02 );
expectedForces[111] = Vec3( 5.5325945e+02, 3.8213691e+02, -5.9449911e+02 );
expectedForces[112] = Vec3( -6.1770559e+02, 2.2322880e+02, -2.1022934e+01 );
expectedForces[113] = Vec3( 2.3716825e+02, -3.8085281e+02, 4.9618193e+02 );
expectedForces[114] = Vec3( 2.9972570e+02, 3.3773759e+02, 3.4933501e+02 );
expectedForces[115] = Vec3( 1.9913039e+02, -3.2035626e+02, -9.7987777e+01 );
expectedForces[116] = Vec3( -2.3506456e+02, 4.0030561e+02, -6.2604809e+02 );
expectedForces[117] = Vec3( 6.0408777e+02, 5.6271523e+02, -5.8742635e+02 );
expectedForces[118] = Vec3( -5.0707285e+02, 7.8511351e+02, -1.7561830e+02 );
expectedForces[119] = Vec3( 5.6759945e+00, 6.9735233e+00, -9.8853787e+00 );
expectedForces[120] = Vec3( 1.1918531e+02, -5.6200785e+02, 3.2333502e+02 );
expectedForces[121] = Vec3( 5.1801315e+02, -3.4460898e+02, 1.1488242e+02 );
expectedForces[122] = Vec3( 7.5859703e+00, 6.9528951e+01, -6.2437444e+00 );
expectedForces[123] = Vec3( 1.1990899e+03, -1.2507886e+01, 1.1906562e+03 );
expectedForces[124] = Vec3( 2.6001536e+02, -9.5041373e+01, -4.2547252e+02 );
expectedForces[125] = Vec3( -3.5601586e+01, 9.1460220e+02, 6.2306102e+02 );
expectedForces[126] = Vec3( -3.8254176e+01, 2.4796243e+02, 3.0638741e+02 );
expectedForces[127] = Vec3( -3.8798311e+02, 1.2532794e+02, -3.1926601e+01 );
expectedForces[128] = Vec3( 5.7672682e+01, 1.7487900e+02, -1.0319581e+02 );
expectedForces[129] = Vec3( 4.4276215e+02, -1.5517993e+02, 3.8122873e+02 );
expectedForces[130] = Vec3( -2.8119980e+02, -2.6530936e+02, 4.3545814e+01 );
expectedForces[131] = Vec3( 5.9375768e+00, 1.6335780e+01, -3.6204644e+02 );
expectedForces[132] = Vec3( 5.9733834e+02, -2.9843602e+02, 1.0541092e+03 );
expectedForces[133] = Vec3( -3.4568461e+02, 2.2794808e+02, -8.4675886e+01 );
expectedForces[134] = Vec3( -6.7882706e+01, -4.5016799e+02, -1.9387646e+02 );
expectedForces[135] = Vec3( 5.6125478e+02, -1.1741092e+03, 1.4214256e+02 );
expectedForces[136] = Vec3( 1.2766648e+02, 1.2519441e+02, -4.4359129e+02 );
expectedForces[137] = Vec3( -2.7235507e+01, -1.0871423e+01, 3.2406976e+01 );
expectedForces[138] = Vec3( -1.2110689e+03, 1.3038667e+02, -7.5331947e+02 );
expectedForces[139] = Vec3( 3.2504988e+02, -7.1577942e+02, -2.4351454e+02 );
expectedForces[140] = Vec3( 2.6466925e+02, 3.6878498e+02, -6.2044711e+01 );
expectedForces[141] = Vec3( -6.2647276e+02, -4.7112562e+02, -6.1885184e+01 );
expectedForces[142] = Vec3( 3.0996699e+01, 3.1033732e+02, -5.7493337e+02 );
expectedForces[143] = Vec3( 2.4664962e+01, 7.8306665e+02, 3.7907751e+02 );
expectedForces[144] = Vec3( -1.9847551e+02, -3.0052499e+02, -6.5192951e+01 );
expectedForces[145] = Vec3( -5.0686773e+02, 1.1972933e+02, 3.6202910e+02 );
expectedForces[146] = Vec3( 4.0004521e+02, -4.3205645e+02, 2.8583074e+02 );
expectedForces[147] = Vec3( -2.9447542e+01, 6.3434099e+02, -6.5189179e+02 );
expectedForces[148] = Vec3( 4.1588516e+02, -1.5534873e+02, -1.1031323e+01 );
expectedForces[149] = Vec3( 1.2761543e+01, -5.6871456e+01, 2.8032565e+02 );
expectedForces[150] = Vec3( -4.7527199e+01, 6.2549647e+02, -8.5007589e+02 );
expectedForces[151] = Vec3( 1.6598949e+01, 1.1210199e+02, 2.0667266e+02 );
expectedForces[152] = Vec3( -2.4012423e+00, -6.1728962e+01, -1.5057977e+01 );
expectedForces[153] = Vec3( -3.6934056e+02, 2.3087063e+02, -3.3268511e+02 );
expectedForces[154] = Vec3( 1.2658460e+02, 4.1809355e+02, 1.9550635e+02 );
expectedForces[155] = Vec3( -1.9528152e+02, -1.9035919e+02, 1.4986704e+02 );
expectedForces[156] = Vec3( -5.9608803e+00, 2.7258190e+02, 5.5318395e+02 );
expectedForces[157] = Vec3( -1.0545084e+01, -1.8397001e+00, -3.3615498e+00 );
expectedForces[158] = Vec3( -4.0827462e+02, -6.4070993e+01, -2.6614992e+02 );
expectedForces[159] = Vec3( -1.5773827e+02, 4.7708702e+02, -9.9622711e+02 );
expectedForces[160] = Vec3( 8.3896122e+01, 2.5959601e+02, 1.7728081e+02 );
expectedForces[161] = Vec3( -2.4859055e+02, 8.1617294e+01, 2.7905586e+02 );
expectedForces[162] = Vec3( 1.3694593e+02, -6.2640483e+02, -2.5308878e+02 );
expectedForces[163] = Vec3( -1.5156337e+02, 1.1567379e+02, 1.8384602e+02 );
expectedForces[164] = Vec3( -1.4794785e+02, -8.0381965e+01, 9.4028021e+02 );
expectedForces[165] = Vec3( -3.5851252e+02, 2.6066489e+02, -4.1225343e+01 );
expectedForces[166] = Vec3( 1.0820389e+02, -8.3485138e+01, 9.5047812e+01 );
expectedForces[167] = Vec3( 2.0019411e+02, 5.0864719e+02, -4.8662239e+01 );
expectedForces[168] = Vec3( -3.0716707e+02, -9.8820762e+02, 1.3660536e+01 );
expectedForces[169] = Vec3( 8.5788590e+02, -1.0335921e+02, -2.2197815e+02 );
expectedForces[170] = Vec3( 9.8072705e+00, 6.6224870e+02, -1.1594055e+02 );
expectedForces[171] = Vec3( -3.6572453e+01, 2.4062731e+02, 1.7831682e+02 );
expectedForces[172] = Vec3( -2.1274187e+00, -2.5471785e+02, -2.5813525e+02 );
expectedForces[173] = Vec3( 3.4763673e+02, -2.0753062e+02, 7.5125390e+02 );
expectedForces[174] = Vec3( 2.9010685e+01, -4.1894498e+02, -6.3847846e+02 );
expectedForces[175] = Vec3( 3.0255245e+02, 2.5945698e+02, 2.3530662e+01 );
expectedForces[176] = Vec3( -2.0827676e+01, 2.2568888e+01, 1.0890440e+01 );
expectedForces[177] = Vec3( 2.2415739e+02, 3.5720682e+02, -8.7208211e+01 );
expectedForces[178] = Vec3( -2.9808276e+02, 7.0108444e+01, -1.5361211e+02 );
expectedForces[179] = Vec3( 2.3882234e+02, -2.6764176e+02, -1.7847229e+01 );
expectedForces[180] = Vec3( -4.7380966e+02, 5.2547306e+01, 7.4446526e+02 );
expectedForces[181] = Vec3( 4.2804072e+00, -2.2456284e+02, -2.0288206e+02 );
expectedForces[182] = Vec3( 2.5474630e+00, 2.5211778e+01, 1.2675317e+01 );
expectedForces[183] = Vec3( -1.4519676e+02, -1.7268277e+02, -8.4750014e+02 );
expectedForces[184] = Vec3( -1.6850633e+02, 9.5223081e+02, -2.5415253e+02 );
expectedForces[185] = Vec3( -2.1600185e+02, -1.6313340e+02, 1.8746411e+02 );
expectedForces[186] = Vec3( 4.5719348e+01, -5.8877840e+01, -1.1199622e+02 );
expectedForces[187] = Vec3( -9.0377199e+01, 2.2045926e+02, -3.2532356e+02 );
expectedForces[188] = Vec3( -1.4523032e+02, -2.2127499e+02, 1.1526636e+02 );
expectedForces[189] = Vec3( 1.9857975e+02, -1.8170037e+02, 3.2016150e+02 );
expectedForces[190] = Vec3( 1.5659789e+02, 5.2984420e+01, -1.0121553e+02 );
expectedForces[191] = Vec3( 1.3925504e+01, -1.1627739e+02, 1.7106106e+00 );
expectedForces[192] = Vec3( 1.7560737e+01, 3.1275548e+02, 1.4568181e+02 );
expectedForces[193] = Vec3( 8.5129168e-01, 3.2688468e+01, -2.0471785e+02 );
expectedForces[194] = Vec3( 2.5640904e+02, -1.8345358e+02, 3.3082812e+02 );
expectedForces[195] = Vec3( 1.5159266e+02, -7.9091822e+02, 7.6475475e+02 );
expectedForces[196] = Vec3( 7.8546101e+02, 1.7887845e+02, -7.4508377e+01 );
expectedForces[197] = Vec3( 6.9010029e+00, 2.1336674e+01, -7.8256484e+01 );
expectedForces[198] = Vec3( -3.4033432e+01, -1.6471994e+02, -2.8721884e+02 );
expectedForces[199] = Vec3( -1.2248359e+02, 5.3002993e+01, 3.5296174e+02 );
expectedForces[200] = Vec3( 1.7497881e+02, 1.1744848e+02, 1.8127502e+02 );
expectedForces[201] = Vec3( -1.1710882e+03, 8.7114752e+02, -1.3353036e+02 );
expectedForces[202] = Vec3( 2.7510368e+02, -1.9393814e+02, 2.6671453e+02 );
expectedForces[203] = Vec3( 7.3421287e+01, -3.8409917e+01, -1.0910368e+02 );
expectedForces[204] = Vec3( -8.7394869e+02, -1.2323430e+03, -1.3693068e+02 );
expectedForces[205] = Vec3( 2.5439149e+02, 2.4002077e+02, 3.0231859e+02 );
expectedForces[206] = Vec3( -9.8167431e+01, 3.1515278e+02, -2.5512038e+02 );
expectedForces[207] = Vec3( 2.7501189e+02, -4.9189774e+02, 4.5827877e+02 );
expectedForces[208] = Vec3( -8.2333908e+02, -7.0609881e+02, 2.9188070e+02 );
expectedForces[209] = Vec3( -2.9200330e+02, 1.9955124e+02, -7.9227826e+00 );
expectedForces[210] = Vec3( 8.0151971e+02, 3.8996996e+02, -1.9508756e+02 );
expectedForces[211] = Vec3( -6.2168096e+01, 2.4323951e+01, 9.8845638e+01 );
expectedForces[212] = Vec3( 2.2980428e+01, -6.2829693e+02, -7.5253154e+02 );
expectedForces[213] = Vec3( -5.7502634e+02, 8.2310635e+02, 3.7934867e+02 );
expectedForces[214] = Vec3( -8.9168889e+01, 5.0052167e+01, -8.6850564e+01 );
expectedForces[215] = Vec3( 2.7414821e+02, -5.9725191e+01, -3.7278778e+00 );
expectedForces[216] = Vec3( -5.3230933e+02, 4.7698725e+02, -2.5857751e+02 );
expectedForces[217] = Vec3( 2.1615644e+02, 6.0001233e+01, -1.1880182e+02 );
expectedForces[218] = Vec3( 2.9837823e+01, -3.9275454e+01, -4.3913571e+01 );
expectedForces[219] = Vec3( -5.6516561e+02, -1.6539113e+02, 3.3185872e+02 );
expectedForces[220] = Vec3( -1.5484833e+01, -1.0085566e+01, -2.8199778e+01 );
expectedForces[221] = Vec3( 6.4295337e+02, -2.7398997e+02, 8.2320867e+02 );
expectedForces[222] = Vec3( 3.3816540e+02, -1.8492046e+02, 8.6215770e+02 );
expectedForces[223] = Vec3( 2.4367872e+02, 8.9527142e+01, -5.9973680e+02 );
expectedForces[224] = Vec3( -6.1601439e+02, -5.3093862e+02, 4.1696221e+01 );
expectedForces[225] = Vec3( 2.2521478e+02, -2.9234267e+02, 2.9760244e+02 );
expectedForces[226] = Vec3( -1.2672295e+02, 2.5753736e+01, -1.6216252e+02 );
expectedForces[227] = Vec3( 1.1136724e+02, 4.3446676e+00, -1.4045447e+01 );
expectedForces[228] = Vec3( 3.5554849e+02, 7.7446255e+00, 5.8722356e+02 );
expectedForces[229] = Vec3( -7.8313952e+02, -5.9206053e+01, 5.1181391e+02 );
expectedForces[230] = Vec3( -9.5647729e+01, -4.6045792e+02, -3.1515210e+02 );
expectedForces[231] = Vec3( 8.7273284e+01, 8.0310279e+02, -1.2212040e+03 );
expectedForces[232] = Vec3( -9.0853819e+02, -7.6005570e+02, 1.8578569e+02 );
expectedForces[233] = Vec3( 1.2061615e+02, -3.2834560e+02, 5.1291192e+01 );
expectedForces[234] = Vec3( 6.0149262e+02, 1.6081852e+03, -1.0922015e+03 );
expectedForces[235] = Vec3( -5.8087260e+01, -2.6676779e+02, -1.5006920e+02 );
expectedForces[236] = Vec3( -1.0997771e+01, 1.3012815e+02, 5.8615633e+02 );
expectedForces[237] = Vec3( 4.9821503e+02, -9.5783644e+01, -6.5708073e+02 );
expectedForces[238] = Vec3( -4.9394992e+02, -7.0445435e+02, -1.5540228e+02 );
expectedForces[239] = Vec3( 1.5710340e+01, 1.9170336e+02, 4.6707393e+02 );
expectedForces[240] = Vec3( -1.2599557e+03, 5.6104975e+02, 6.5853210e+02 );
expectedForces[241] = Vec3( 1.3032986e+01, -2.7481865e+01, 8.0373029e+00 );
expectedForces[242] = Vec3( 1.4371505e+02, -5.2615293e+01, -3.7929456e+02 );
expectedForces[243] = Vec3( 6.0025739e+01, 1.4474905e+02, 3.6414330e+02 );
expectedForces[244] = Vec3( 4.5364033e+02, 7.0785823e+01, -2.9279112e+02 );
expectedForces[245] = Vec3( -9.7012956e+01, -8.2545229e+01, -5.4567106e+01 );
expectedForces[246] = Vec3( -3.6449281e+02, -5.6669832e+02, -3.5196038e+02 );
expectedForces[247] = Vec3( 2.6571354e+02, -2.5051716e+02, -4.7199161e+01 );
expectedForces[248] = Vec3( -4.7285701e+01, 1.7950093e+02, 8.0633971e+01 );
expectedForces[249] = Vec3( 1.8035439e+02, 4.6977540e+02, 2.2589769e+02 );
expectedForces[250] = Vec3( 5.9853399e+01, 1.5477006e+02, -1.7011806e+02 );
expectedForces[251] = Vec3( -2.6084741e+02, -2.0538756e+02, 1.0269002e+02 );
expectedForces[252] = Vec3( 4.0221722e+02, -1.0368371e+02, -1.3842460e+01 );
expectedForces[253] = Vec3( -4.4264447e+02, -3.0334810e+02, 1.6740779e+02 );
expectedForces[254] = Vec3( -1.7373662e+02, 1.5020202e+02, -3.3761418e+02 );
expectedForces[255] = Vec3( 4.7508953e+01, -5.4028784e+02, -3.6291329e+01 );
expectedForces[256] = Vec3( 5.4807168e+02, -2.0293664e+02, 5.5114363e+02 );
expectedForces[257] = Vec3( -4.9787370e+01, 4.5106329e+01, -5.7524550e+01 );
expectedForces[258] = Vec3( -5.1584935e+02, 1.5014186e+02, -6.6369834e+02 );
expectedForces[259] = Vec3( -6.0140298e+01, -9.4127280e+01, 8.7495796e+01 );
expectedForces[260] = Vec3( 8.0619588e+02, -2.1066454e+02, -5.9371508e+01 );
expectedForces[261] = Vec3( 1.2817429e+02, -2.7044116e+02, 5.3213275e+02 );
expectedForces[262] = Vec3( -4.1467442e-01, -1.3641138e+02, -8.5576287e+01 );
expectedForces[263] = Vec3( -5.6508528e+01, 2.4091504e+01, -7.9236147e+01 );
expectedForces[264] = Vec3( 1.4123799e+02, 2.1326444e+02, 1.9141445e+02 );
expectedForces[265] = Vec3( 1.6579721e+02, -3.2221503e+02, -1.5197776e+02 );
expectedForces[266] = Vec3( -2.5871222e+02, -2.6345996e+02, -1.1149413e+03 );
expectedForces[267] = Vec3( -1.2859743e+02, -3.9214753e+02, -6.5874862e+02 );
expectedForces[268] = Vec3( 1.7237157e+02, -2.8729010e+02, 3.2000889e+02 );
expectedForces[269] = Vec3( 6.6312203e+02, 3.5683926e+02, 9.7235616e+01 );
expectedForces[270] = Vec3( -1.1860349e+02, -4.3528895e+02, 1.1598672e+03 );
expectedForces[271] = Vec3( 7.7135123e+01, -2.1671305e+02, -2.3088548e+02 );
expectedForces[272] = Vec3( 7.2863708e+01, 5.2065158e+02, 1.5704752e+02 );
expectedForces[273] = Vec3( -3.6727477e+02, -6.0885463e+01, 4.1193960e+01 );
expectedForces[274] = Vec3( 5.4858881e+01, 1.6886577e+02, -1.1662392e+01 );
expectedForces[275] = Vec3( 3.2070061e+01, -1.6138709e+01, -7.6648912e+00 );
expectedForces[276] = Vec3( 2.5695892e+02, 7.7719531e+01, -8.3154765e+02 );
expectedForces[277] = Vec3( -3.3460202e+01, -1.3077348e+02, 3.6110539e+01 );
expectedForces[278] = Vec3( -4.1360402e+02, 2.7754335e+02, -1.1139467e+02 );
expectedForces[279] = Vec3( 1.0012775e+02, 1.4365237e+03, 2.6972544e+02 );
expectedForces[280] = Vec3( 7.8750024e+02, -2.3376123e+02, 9.5969232e+02 );
expectedForces[281] = Vec3( -2.2493912e+02, -1.1444344e+01, -6.3713547e+01 );
expectedForces[282] = Vec3( -9.4211966e+01, -3.9286586e+02, -7.0932607e+01 );
expectedForces[283] = Vec3( 1.6192138e+02, 2.3010404e+02, -2.1511498e+02 );
expectedForces[284] = Vec3( -4.9644702e+02, -1.1894844e+01, -4.7458477e+02 );
expectedForces[285] = Vec3( -1.0151600e+02, -4.2789293e+02, 5.2698223e+02 );
expectedForces[286] = Vec3( 1.1350409e+01, 1.5126445e+02, -5.2740587e+01 );
expectedForces[287] = Vec3( -4.7715521e+02, -3.6476152e+02, -5.4346958e+02 );
expectedForces[288] = Vec3( -9.4019721e+01, -2.4758228e+02, 4.2219712e+02 );
expectedForces[289] = Vec3( 3.1525053e+01, 3.7927245e+02, -2.4577041e+02 );
expectedForces[290] = Vec3( 4.4004025e+02, -9.4883983e+01, -6.9075632e+01 );
expectedForces[291] = Vec3( -2.6553328e+02, -2.7059185e+02, 3.1145935e+02 );
expectedForces[292] = Vec3( 1.1199463e+02, 9.0805870e+01, 8.0258804e+01 );
expectedForces[293] = Vec3( 7.8056273e+01, -3.5931761e+01, -1.9249727e+02 );
expectedForces[294] = Vec3( -1.2443366e+01, -1.4631721e+02, 7.9733561e+01 );
expectedForces[295] = Vec3( -3.2866900e+02, 1.1527926e+02, -9.3135590e+01 );
expectedForces[296] = Vec3( 7.5078643e+01, -7.2653837e+02, -1.0830908e+02 );
expectedForces[297] = Vec3( 1.0361037e+02, 1.5478274e+02, 1.1293089e+03 );
expectedForces[298] = Vec3( -2.4014663e+02, -5.6771824e+02, 1.5441974e+02 );
expectedForces[299] = Vec3( -6.8441034e+01, -1.1226846e+02, -5.4497343e+02 );
expectedForces[300] = Vec3( 2.9803689e+02, 1.0649462e+03, 2.5408768e+02 );
expectedForces[301] = Vec3( 5.6356599e+01, -2.3035579e+02, 7.6928758e+01 );
expectedForces[302] = Vec3( 1.0229494e+02, -1.9615696e+02, -3.2600199e+02 );
expectedForces[303] = Vec3( -7.0312065e+01, -3.1170055e+02, 5.6453888e+02 );
expectedForces[304] = Vec3( -7.0752582e+01, 1.2273280e+02, -1.6740503e+01 );
expectedForces[305] = Vec3( 6.8972998e+02, -2.8067032e+02, 6.6502848e+01 );
expectedForces[306] = Vec3( -8.8407472e+02, 3.7818347e+02, -1.2141945e+03 );
expectedForces[307] = Vec3( -1.0445122e+02, -4.4818836e+02, -9.5227168e+00 );
expectedForces[308] = Vec3( 8.3015802e+02, 5.0941309e+02, 3.2593793e+01 );
expectedForces[309] = Vec3( 7.6887033e+02, 4.3490548e+02, -1.0826101e+03 );
expectedForces[310] = Vec3( 1.4352949e+02, -3.9479802e+01, 1.7718790e+02 );
expectedForces[311] = Vec3( -2.5204642e+02, -3.3888239e+02, -2.7365802e+02 );
expectedForces[312] = Vec3( -4.4783121e+02, 4.4465580e+02, 9.2506336e+02 );
expectedForces[313] = Vec3( -3.3390337e+01, -5.0097602e+02, -3.6812516e+02 );
expectedForces[314] = Vec3( -4.1862341e+02, 1.9519764e+02, -2.4571211e+02 );
expectedForces[315] = Vec3( -1.4176845e+02, -3.3767798e+01, 1.7800248e+02 );
expectedForces[316] = Vec3( -4.7411046e+01, 2.3841278e+01, -1.5183689e+01 );
expectedForces[317] = Vec3( 1.6723204e+01, 1.4145797e+02, -1.6930384e+01 );
expectedForces[318] = Vec3( -8.4841167e+02, -2.1282818e+02, 8.1614626e+01 );
expectedForces[319] = Vec3( 6.5941519e+00, -1.1472179e+02, -2.3181002e+02 );
expectedForces[320] = Vec3( 2.2464095e+01, -5.7606215e+00, 5.2865780e+00 );
expectedForces[321] = Vec3( 3.8063827e+02, 2.4597014e+02, -4.1947008e+01 );
expectedForces[322] = Vec3( -3.1531672e+02, 3.5038104e+02, -3.2724191e+02 );
expectedForces[323] = Vec3( 7.4741163e+01, 7.2296536e+01, 3.1768919e+02 );
expectedForces[324] = Vec3( 7.9578966e+02, -1.5345175e+02, -7.1301288e+02 );
expectedForces[325] = Vec3( -3.1387318e+01, 1.7528515e+01, -3.4100670e+01 );
expectedForces[326] = Vec3( 9.3853572e-01, 6.8496077e+00, 1.2234894e+01 );
expectedForces[327] = Vec3( -1.3099690e+02, -4.0135958e+02, -4.3248135e+02 );
expectedForces[328] = Vec3( 4.3988113e+02, -1.5944416e+02, 5.4620163e+01 );
expectedForces[329] = Vec3( 1.3509243e+01, 3.6990268e+00, -2.6251838e-01 );
expectedForces[330] = Vec3( -8.7459998e+01, -6.4319025e+02, 2.2863360e+02 );
expectedForces[331] = Vec3( -3.5181606e+02, 3.1131978e+02, 2.8037788e+02 );
expectedForces[332] = Vec3( 1.9545884e+02, 4.3994512e+01, -2.5158598e+02 );
expectedForces[333] = Vec3( 1.8100917e+00, 1.9534738e+02, 1.7181161e+02 );
expectedForces[334] = Vec3( -1.1846876e+02, 1.5368782e+02, 2.2261016e+02 );
expectedForces[335] = Vec3( 1.4866155e+02, -4.7983795e+02, 3.0361323e+02 );
expectedForces[336] = Vec3( -7.7242468e+02, 2.0736079e+02, -8.6661236e+02 );
expectedForces[337] = Vec3( -7.9875679e+00, -9.0946585e+02, -7.1617627e+01 );
expectedForces[338] = Vec3( 2.2543457e+02, 2.0215639e+02, 4.4285374e+02 );
expectedForces[339] = Vec3( -2.6252013e+02, -1.0336519e+02, -2.6630451e+02 );
expectedForces[340] = Vec3( 5.0907589e+02, -1.2491931e+02, -4.3015857e+01 );
expectedForces[341] = Vec3( -6.0362692e+01, 1.0025664e+02, -9.3389235e+01 );
expectedForces[342] = Vec3( 5.8779874e+02, 3.7600030e+02, 2.5345454e+02 );
expectedForces[343] = Vec3( -1.3661048e+02, 1.6498482e+02, -2.6789925e+01 );
expectedForces[344] = Vec3( 4.9840419e+01, -1.2136315e+02, 2.5455320e+01 );
expectedForces[345] = Vec3( 2.3324807e+02, -3.6601512e+02, 5.6798114e+01 );
expectedForces[346] = Vec3( 5.5853546e+01, -4.9035168e+00, -5.8726331e+02 );
expectedForces[347] = Vec3( -3.8918158e+01, 3.0380495e+02, 1.0944883e+01 );
expectedForces[348] = Vec3( -2.6092065e+02, 4.3443036e+02, -1.3673862e+02 );
expectedForces[349] = Vec3( 1.5195166e+02, 1.1879426e+01, -1.1429493e+02 );
expectedForces[350] = Vec3( -8.5687107e+02, -1.7938881e+02, 4.5576455e+00 );
expectedForces[351] = Vec3( -1.0117388e+03, -3.2686610e+02, 2.9733049e+02 );
expectedForces[352] = Vec3( -2.3946369e+02, 4.9753786e+02, 7.2681440e+02 );
expectedForces[353] = Vec3( 3.9085837e+01, 7.4391931e+00, 3.4179196e+00 );
expectedForces[354] = Vec3( 1.0462977e+03, 4.3639578e+02, -5.7349371e+02 );
expectedForces[355] = Vec3( 1.2715333e+02, -5.7907885e+02, 5.7463165e+02 );
expectedForces[356] = Vec3( -1.5968981e+02, 2.2295605e+01, 6.3554487e+01 );
expectedForces[357] = Vec3( -1.9666111e+02, -2.0286725e+02, -8.3590992e+01 );
expectedForces[358] = Vec3( 5.9985006e+00, 2.9764307e+01, 3.1304672e+01 );
expectedForces[359] = Vec3( 1.0409792e+02, 4.3974987e+02, -9.1530162e+02 );
expectedForces[360] = Vec3( 2.9538724e+02, 1.4353710e+02, 2.1558768e+02 );
expectedForces[361] = Vec3( -3.7974445e+02, -9.0749144e+01, 1.4531502e+02 );
expectedForces[362] = Vec3( 3.7089093e+02, 2.2523397e+02, -2.9760698e+02 );
expectedForces[363] = Vec3( -7.6884906e+01, -2.7486958e+02, 3.5671043e+02 );
expectedForces[364] = Vec3( 4.3400097e+02, 2.2275226e+02, 5.9201087e+01 );
expectedForces[365] = Vec3( 2.1177620e+02, -6.4990517e+02, -1.8431623e+02 );
expectedForces[366] = Vec3( -8.2234148e+01, 4.9900036e+02, 3.0906858e+02 );
expectedForces[367] = Vec3( -1.4784097e+02, 1.3442463e+02, -2.6811487e+02 );
expectedForces[368] = Vec3( 2.2289541e+02, -4.1933983e+02, 1.3646246e+01 );
expectedForces[369] = Vec3( -2.1199481e+02, 6.2103281e+01, 1.6049768e+02 );
expectedForces[370] = Vec3( -2.9429845e+01, -1.3944740e+01, 1.6000003e+01 );
expectedForces[371] = Vec3( -1.5093250e+02, -1.9541345e+02, -1.5879844e+02 );
expectedForces[372] = Vec3( 2.2218133e+02, 7.5740668e+01, -7.0754853e+02 );
expectedForces[373] = Vec3( -4.7529615e+02, -3.5259490e+02, 3.8025744e+02 );
expectedForces[374] = Vec3( 4.9308495e+01, 1.2206152e+02, 4.2704595e+01 );
expectedForces[375] = Vec3( -3.6408113e+02, 9.5905960e+02, 3.3861668e+02 );
expectedForces[376] = Vec3( 1.5324093e+02, -1.4375341e+02, -9.1369900e+01 );
expectedForces[377] = Vec3( -3.5343609e+02, -4.4662438e+02, 3.1741831e+02 );
expectedForces[378] = Vec3( -8.2721281e+02, -6.4969313e+01, 4.1869320e+02 );
expectedForces[379] = Vec3( -8.7419096e+00, -4.6278343e+01, -3.0259942e+01 );
expectedForces[380] = Vec3( 1.6814871e+01, 4.5462601e+01, -3.5204538e+01 );
expectedForces[381] = Vec3( 1.9043143e+02, 5.1101135e+02, 2.9970918e+02 );
expectedForces[382] = Vec3( -4.3547560e+02, -7.7495770e+01, -8.2311440e+01 );
expectedForces[383] = Vec3( 1.3206505e+02, 4.0993476e+01, 1.5150623e+01 );
expectedForces[384] = Vec3( 4.6163268e+01, -2.7722119e+01, -2.2996255e+02 );
expectedForces[385] = Vec3( -4.7033552e+01, 1.5721545e+02, -9.2562636e+01 );
expectedForces[386] = Vec3( -2.4164903e+02, -1.4771464e+02, -5.1675638e+01 );
expectedForces[387] = Vec3( 1.3445564e+03, 3.5387081e+02, -3.7402713e+02 );
expectedForces[388] = Vec3( -2.6290280e+02, 2.5025510e+02, 3.0570707e+01 );
expectedForces[389] = Vec3( -4.4624214e+02, -2.4919412e+02, 1.1336564e+03 );
expectedForces[390] = Vec3( 3.1188483e+02, 6.4836125e+02, 4.5477683e+01 );
expectedForces[391] = Vec3( 2.5570674e+02, -2.7101115e+02, -1.2579817e+02 );
expectedForces[392] = Vec3( -3.4941759e+02, -3.2508734e+01, -5.6131515e+01 );
expectedForces[393] = Vec3( -1.2734301e+02, -2.0417657e+02, 5.7738004e+02 );
expectedForces[394] = Vec3( 5.0435795e+01, -9.5203527e+01, -4.1237509e+00 );
expectedForces[395] = Vec3( -6.8258463e+01, 1.7475914e+02, -1.6422294e+02 );
expectedForces[396] = Vec3( 2.6455575e+02, 2.6880230e+02, -1.6607620e+01 );
expectedForces[397] = Vec3( -3.5968167e+02, 6.6092937e+01, 1.5915445e+02 );
expectedForces[398] = Vec3( 8.4092494e-01, -5.9896731e+01, -2.1856007e+01 );
expectedForces[399] = Vec3( -1.9237984e+02, -1.6506355e+02, 1.3370845e+02 );
expectedForces[400] = Vec3( 4.7023043e+02, 1.2931257e+02, -1.7013618e+02 );
expectedForces[401] = Vec3( 9.4928843e+01, -3.1613892e+02, -4.6973091e+02 );
expectedForces[402] = Vec3( -2.9180818e+02, 6.5496755e+02, -2.9430870e+02 );
expectedForces[403] = Vec3( 1.6670668e+02, -2.4693913e+02, -8.8775735e+01 );
expectedForces[404] = Vec3( -1.4218604e+02, 2.3173349e+02, 3.9869740e+02 );
expectedForces[405] = Vec3( 4.3469431e+02, -2.4686568e+02, -2.6838523e+02 );
expectedForces[406] = Vec3( 1.0671130e+02, 3.9710106e+02, 2.6478100e+02 );
expectedForces[407] = Vec3( -4.4281099e+02, -3.2746126e+01, -2.0719929e+02 );
expectedForces[408] = Vec3( 1.1864952e+01, -1.5901568e+02, 1.1865945e+01 );
expectedForces[409] = Vec3( -6.0546863e+01, -1.3488005e+02, -2.9223986e+02 );
expectedForces[410] = Vec3( 2.5845942e+01, 1.7545933e+02, -1.4590654e+02 );
expectedForces[411] = Vec3( -3.0776460e+02, 2.7351986e+02, -2.0386483e+02 );
expectedForces[412] = Vec3( 1.7301558e+02, 8.3012339e+01, 7.6018513e+02 );
expectedForces[413] = Vec3( 1.2893147e+02, -3.9937475e+00, 1.4197628e+01 );
expectedForces[414] = Vec3( -3.9803615e+02, -4.4825663e+02, 2.8616211e+01 );
expectedForces[415] = Vec3( -2.3586809e+02, -8.9306136e+01, 7.5265669e+02 );
expectedForces[416] = Vec3( 8.3814512e+02, -9.5563706e+00, 2.8738759e+02 );
expectedForces[417] = Vec3( -3.8269399e+02, -2.3650170e+02, 1.7330415e+01 );
expectedForces[418] = Vec3( 7.2310675e+00, 2.4731653e+01, 1.9491126e+01 );
expectedForces[419] = Vec3( 8.4485111e+01, 9.0560261e+01, -1.4261777e+01 );
expectedForces[420] = Vec3( 2.1829925e+02, -8.3951651e+01, -7.8910117e+02 );
expectedForces[421] = Vec3( -2.4228018e+02, -5.7097512e+01, 2.6447829e+02 );
expectedForces[422] = Vec3( 6.9666665e+01, -4.7313678e+02, 4.5559673e+02 );
expectedForces[423] = Vec3( 1.0108369e+02, 4.6568610e+02, 2.5612541e+02 );
expectedForces[424] = Vec3( 7.2334238e+01, -1.5660040e+02, -2.6278686e+02 );
expectedForces[425] = Vec3( 1.0749954e+03, 2.4395658e+02, -8.7308262e+01 );
expectedForces[426] = Vec3( 5.4983082e+02, 5.6528577e+02, -3.0489991e+02 );
expectedForces[427] = Vec3( -2.1210132e+02, -1.5871954e+02, -1.6936452e+02 );
expectedForces[428] = Vec3( -9.5473983e+01, 7.4879276e+01, 5.5720204e+01 );
expectedForces[429] = Vec3( 5.6417182e+02, -1.3478250e+02, -4.8006673e+01 );
expectedForces[430] = Vec3( -1.0055266e+02, -8.3811289e+01, 6.5259748e+01 );
expectedForces[431] = Vec3( 3.0553989e+01, 4.0927300e+02, 6.2242246e+02 );
expectedForces[432] = Vec3( -6.0956353e+02, 9.0301312e+02, -1.4063582e+01 );
expectedForces[433] = Vec3( 3.2774559e+02, -1.0849473e+02, -8.8877712e+01 );
expectedForces[434] = Vec3( 2.1371643e+02, -7.2067980e+01, 2.4803863e+02 );
expectedForces[435] = Vec3( -9.0636479e+01, 1.0673514e+03, 1.3005625e+02 );
expectedForces[436] = Vec3( -3.5058624e+02, -1.4968284e+02, 1.4340635e+02 );
expectedForces[437] = Vec3( 3.4640813e+01, -4.8035225e+01, 4.4066226e+01 );
expectedForces[438] = Vec3( -2.3414523e+02, -9.1359130e+01, 2.8535427e+02 );
expectedForces[439] = Vec3( -2.7156547e+02, -6.3426763e+01, 1.6968017e+01 );
expectedForces[440] = Vec3( -2.8751166e+00, 4.3192169e+00, -2.1401359e+00 );
expectedForces[441] = Vec3( -2.0241419e+01, 4.2856138e+02, 7.3204868e+01 );
expectedForces[442] = Vec3( -4.2166169e+01, -2.2454013e+01, -5.4998450e+01 );
expectedForces[443] = Vec3( 2.6442026e+02, -1.1670567e+02, 2.8879291e+02 );
expectedForces[444] = Vec3( -4.9762729e+02, 4.7320314e+02, 3.2506251e+02 );
expectedForces[445] = Vec3( -3.0994232e+02, 3.6728867e+02, -6.8793662e+02 );
expectedForces[446] = Vec3( -5.6328374e+00, -2.3284824e+00, 1.9650486e+01 );
expectedForces[447] = Vec3( 4.0145354e+02, 7.0143762e+02, 1.3039041e+02 );
expectedForces[448] = Vec3( 1.3270713e+02, -3.3050447e+02, 2.8630784e+02 );
expectedForces[449] = Vec3( -3.8904836e+02, -4.6125118e+01, -3.8815388e+02 );
expectedForces[450] = Vec3( 4.6293066e+02, -2.4970158e+02, -5.7231818e+01 );
expectedForces[451] = Vec3( -4.7707142e+00, 1.7120822e-01, 4.5081299e+00 );
expectedForces[452] = Vec3( 3.5968818e+01, -1.1892248e+01, 1.2184792e+02 );
expectedForces[453] = Vec3( 4.4939172e+02, 4.8377647e+02, 3.0529778e+02 );
expectedForces[454] = Vec3( -2.9071570e+02, -9.0611613e+01, -2.5190431e+02 );
expectedForces[455] = Vec3( -1.4344537e+02, -1.3061997e+03, 3.8343947e+02 );
expectedForces[456] = Vec3( 4.1580940e+02, -3.6864043e+02, 6.6384066e+02 );
expectedForces[457] = Vec3( -3.4869949e+02, 3.3262427e+02, -8.3156358e+01 );
expectedForces[458] = Vec3( -5.8565457e+00, -5.1879987e+02, -7.2717213e+02 );
expectedForces[459] = Vec3( -1.0514593e+02, -2.6844396e+02, 3.0849659e+02 );
expectedForces[460] = Vec3( -1.2562153e+02, 6.5438031e+01, -2.3521687e+02 );
expectedForces[461] = Vec3( 8.3330016e+02, -6.7961048e+02, -7.2442064e+02 );
expectedForces[462] = Vec3( -1.3328298e+02, 1.6143544e+02, -3.2000493e+02 );
expectedForces[463] = Vec3( -1.1035002e+02, -8.6040775e+01, 2.0953986e+02 );
expectedForces[464] = Vec3( -2.7702219e+02, -1.2156319e+02, -3.8897654e+02 );
expectedForces[465] = Vec3( 3.6277432e+02, -7.0422679e+02, -8.2487472e+02 );
expectedForces[466] = Vec3( -2.3947587e+02, -4.3625964e+00, 4.8716989e+01 );
expectedForces[467] = Vec3( -2.6210552e+02, 9.9730213e+01, -2.4465307e+02 );
expectedForces[468] = Vec3( -4.1344138e+01, -3.8636310e+01, -1.0720610e+01 );
expectedForces[469] = Vec3( 2.3928584e+01, -1.3030908e+01, -1.7631168e+01 );
expectedForces[470] = Vec3( -1.1873594e+02, -3.3905287e+00, -8.4575994e+01 );
expectedForces[471] = Vec3( 4.3384846e+02, -4.8660929e+02, -2.4015737e+02 );
expectedForces[472] = Vec3( 3.8974922e+01, 2.4401913e+02, -1.2060132e+02 );
expectedForces[473] = Vec3( -4.2239647e+02, -8.6924630e+01, 5.7884013e+02 );
expectedForces[474] = Vec3( 1.7222431e+02, -1.9292167e+01, 4.4184770e+01 );
expectedForces[475] = Vec3( -4.8871102e+01, 1.8185057e+02, -1.3144294e+02 );
expectedForces[476] = Vec3( -1.1467881e+02, -1.8387284e+02, -2.6935761e+01 );
expectedForces[477] = Vec3( 4.4415601e+02, -8.6415426e+02, -2.2765803e+02 );
expectedForces[478] = Vec3( 2.0893474e+02, 1.3529112e+02, 2.4108004e+02 );
expectedForces[479] = Vec3( -1.2802570e+01, -4.7089261e+00, -7.0024810e+00 );
expectedForces[480] = Vec3( -1.0878354e+02, 4.5030357e+02, -3.9086153e+02 );
expectedForces[481] = Vec3( -3.7659745e+01, -4.9295745e+01, -6.0028516e+01 );
expectedForces[482] = Vec3( 1.8851809e+02, -1.6863914e+02, 1.2031505e+02 );
expectedForces[483] = Vec3( 2.2040686e+02, -1.1953187e+03, 2.9106238e+02 );
expectedForces[484] = Vec3( -1.1642847e+01, 5.6739977e+01, 3.7532413e+00 );
expectedForces[485] = Vec3( 3.5013234e+00, 2.8236323e+01, -1.1738866e+01 );
expectedForces[486] = Vec3( -2.0051506e+03, -5.3138994e+02, 4.0428126e+02 );
expectedForces[487] = Vec3( 1.6887843e+02, 1.1687735e+02, -9.6232177e+01 );
expectedForces[488] = Vec3( 2.5030722e+02, -3.6662537e+02, -5.8595505e+01 );
expectedForces[489] = Vec3( -1.5924273e+01, -2.1761920e+02, -3.4885425e+01 );
expectedForces[490] = Vec3( 1.0423157e+02, 4.0767827e+01, 1.4036192e+02 );
expectedForces[491] = Vec3( 5.0090776e+02, -5.0455702e+01, -4.2524815e+02 );
expectedForces[492] = Vec3( 3.8037844e+02, 5.7460724e+02, 2.1243310e+02 );
expectedForces[493] = Vec3( -1.1487653e+02, 3.3550952e+01, -5.7050397e+01 );
expectedForces[494] = Vec3( 1.8425697e+02, -2.7223857e+02, -2.9384020e+01 );
expectedForces[495] = Vec3( -1.1115514e+02, -4.4519957e+02, -3.3628896e+02 );
expectedForces[496] = Vec3( 3.8865823e+02, -2.1372852e+02, -7.8979988e+02 );
expectedForces[497] = Vec3( -3.1740258e+02, 4.4824683e+02, -5.0382680e+02 );
expectedForces[498] = Vec3( 1.5521684e+02, -1.5278429e+02, -1.8418006e+02 );
expectedForces[499] = Vec3( -2.2213191e+01, 7.1015095e+00, 1.0308820e+01 );
expectedForces[500] = Vec3( 3.0011560e+01, 2.4584541e+02, -5.3231694e+02 );
expectedForces[501] = Vec3( -8.4865171e+02, -2.0279022e+02, -6.8435095e+02 );
expectedForces[502] = Vec3( 7.0477549e+00, 2.7626774e+01, -1.6246047e+01 );
expectedForces[503] = Vec3( -7.1309648e+01, -1.6054218e+02, -3.1621746e+01 );
expectedForces[504] = Vec3( 3.6317856e+02, 1.9055487e+02, 3.9196046e+01 );
expectedForces[505] = Vec3( 1.4643265e+02, -1.2295335e+03, -2.2268806e+01 );
expectedForces[506] = Vec3( -3.6638240e+02, -6.5310612e+00, -6.8077013e+02 );
expectedForces[507] = Vec3( 1.9107813e+02, -6.2176534e+02, 5.1826941e+02 );
expectedForces[508] = Vec3( 1.7226933e+02, -3.8939126e+02, -7.4174355e+02 );
expectedForces[509] = Vec3( 1.3541890e+02, 4.1350561e+02, -2.6155396e+02 );
expectedForces[510] = Vec3( 1.6452609e+02, -4.1963597e+02, 1.6322800e+02 );
expectedForces[511] = Vec3( 9.1248387e+01, -1.3380408e+01, -5.1326806e+02 );
expectedForces[512] = Vec3( 1.2420564e+02, 8.9492432e+02, 2.8660661e+02 );
expectedForces[513] = Vec3( 4.5609859e+02, 3.4252036e+01, -2.3830457e+02 );
expectedForces[514] = Vec3( -8.8282131e+01, -1.4512876e+02, -4.5703642e+01 );
expectedForces[515] = Vec3( -6.9194714e+01, 5.5053415e+02, -3.9527911e+02 );
expectedForces[516] = Vec3( -1.5570798e+02, 4.1650792e-02, 3.0224667e+02 );
expectedForces[517] = Vec3( 9.2007640e+01, 3.6378499e+02, -2.2069415e+01 );
expectedForces[518] = Vec3( 2.7996922e+02, -2.0932322e+02, 6.2987796e+01 );
expectedForces[519] = Vec3( -7.4985282e+01, 1.3508916e+02, 1.1453750e+02 );
expectedForces[520] = Vec3( 1.2149786e+01, 4.2161047e+02, -2.9521571e+02 );
expectedForces[521] = Vec3( 1.9419524e+01, -8.6619683e+01, -9.4040609e+01 );
expectedForces[522] = Vec3( 3.5495800e+01, 6.4028894e+01, 1.2320699e+02 );
expectedForces[523] = Vec3( -5.6501302e+02, -1.2497462e+02, 8.1633096e+02 );
expectedForces[524] = Vec3( -3.1775230e+02, 1.6467221e+02, -4.8242287e+01 );
expectedForces[525] = Vec3( -1.8325245e+02, -1.0751941e+02, 6.2172117e+02 );
expectedForces[526] = Vec3( 1.8164299e+00, 8.0654784e-01, -1.4484741e+01 );
expectedForces[527] = Vec3( 2.6686986e+00, 1.5933475e+01, -6.8843007e+01 );
expectedForces[528] = Vec3( -1.3208642e+02, -1.2281791e+02, 7.8417959e+01 );
expectedForces[529] = Vec3( -4.8078193e+01, -1.5140963e+02, 8.3605002e+01 );
expectedForces[530] = Vec3( 8.5925332e+01, 1.9959621e+01, -5.9034655e+01 );
expectedForces[531] = Vec3( -3.1311626e+00, -3.4009931e+01, -1.5895685e+02 );
expectedForces[532] = Vec3( -9.9694666e+01, 1.0296874e+00, 1.0482739e+02 );
expectedForces[533] = Vec3( 2.8954747e+02, 1.2018666e+02, 2.2155006e+02 );
expectedForces[534] = Vec3( 3.2588176e+02, 3.6622498e+01, 3.5801460e+02 );
expectedForces[535] = Vec3( -6.5985617e+01, -3.5501709e+02, 6.8149810e+01 );
expectedForces[536] = Vec3( -4.7632753e+02, 2.7936656e+02, 1.5548558e+02 );
expectedForces[537] = Vec3( 4.7724904e+02, 2.1647106e+02, 1.2003317e+02 );
expectedForces[538] = Vec3( -1.6225405e+02, 1.4264998e+02, -1.0113321e+02 );
expectedForces[539] = Vec3( -3.2540487e+01, -7.5643223e+01, 1.6054148e+01 );
expectedForces[540] = Vec3( 4.3311991e+02, 5.8082595e+02, 1.9354276e+02 );
expectedForces[541] = Vec3( -3.4924430e+02, -7.0056069e+01, 1.0274560e+02 );
expectedForces[542] = Vec3( 1.9441645e+02, -2.0017354e+02, -2.3280717e+02 );
expectedForces[543] = Vec3( -4.1530380e+01, -5.6394351e+02, 2.4472509e+02 );
expectedForces[544] = Vec3( -1.6193396e+01, -8.0431396e+01, -2.9094018e+02 );
expectedForces[545] = Vec3( -1.9414773e+01, 4.6180982e+01, 3.3123072e+01 );
expectedForces[546] = Vec3( -3.9314039e+02, -3.9874866e+02, 4.5308571e+02 );
expectedForces[547] = Vec3( -7.1897482e+01, -1.1940445e+02, -2.7405931e+02 );
expectedForces[548] = Vec3( 3.0646396e+02, 6.1235747e+01, -1.5253270e+02 );
expectedForces[549] = Vec3( -3.2480464e+02, 4.3056561e+02, 3.2532485e+01 );
expectedForces[550] = Vec3( 1.2818655e+02, 7.4294994e-01, -5.7650521e+00 );
expectedForces[551] = Vec3( -1.7481437e+02, -2.6203225e+02, -9.6793481e+01 );
expectedForces[552] = Vec3( 1.9259110e+02, 3.0171883e+02, 5.2403235e+02 );
expectedForces[553] = Vec3( -7.8132123e+01, -7.6569340e+00, -1.1140240e+02 );
expectedForces[554] = Vec3( -5.2504673e+02, -4.3700574e+02, 4.3321261e+02 );
expectedForces[555] = Vec3( -9.9785283e+02, 2.7139143e+02, -4.1723547e+02 );
expectedForces[556] = Vec3( 2.7115933e+02, -8.7444541e+01, 1.0745103e+02 );
expectedForces[557] = Vec3( 1.4348018e+02, 1.4013343e+02, -4.0305733e+02 );
expectedForces[558] = Vec3( 4.9491010e+02, 4.3040089e+02, -3.5558583e+02 );
expectedForces[559] = Vec3( -1.8510736e+02, 6.7129731e+01, -2.1324364e+02 );
expectedForces[560] = Vec3( 8.4478090e+01, 4.0986269e+01, 4.1401094e+02 );
expectedForces[561] = Vec3( 4.4188419e+01, -8.6520108e+02, 6.8555821e+02 );
expectedForces[562] = Vec3( -4.5036974e+02, 2.2379481e+02, 6.2457971e+01 );
expectedForces[563] = Vec3( 2.4325836e+02, 6.9725116e+01, 3.6266296e+01 );
expectedForces[564] = Vec3( 1.5611925e+02, -2.4471023e+02, 4.7857332e+02 );
expectedForces[565] = Vec3( -3.5692822e+02, -2.7248961e+02, -1.8165146e+02 );
expectedForces[566] = Vec3( 4.3093388e+02, 1.6944839e+02, -4.4177741e+02 );
expectedForces[567] = Vec3( 5.2118711e+02, -1.5252783e+02, -1.6964047e+02 );
expectedForces[568] = Vec3( 1.3899083e+03, 3.8363654e+02, -6.4623177e+02 );
expectedForces[569] = Vec3( -1.4984858e+02, 4.5097170e+01, -5.0257768e+01 );
expectedForces[570] = Vec3( -8.1979709e+01, -4.1632909e+01, -5.1367825e+02 );
expectedForces[571] = Vec3( -7.8645235e+00, 1.8105470e+01, 9.2902759e+01 );
expectedForces[572] = Vec3( 1.2725548e+02, 1.3926229e+02, -4.3752260e+01 );
expectedForces[573] = Vec3( -2.7817289e+01, -8.0900345e+01, -4.3178498e+02 );
expectedForces[574] = Vec3( 2.2115263e+02, -7.8807799e+01, 8.8367391e+01 );
expectedForces[575] = Vec3( -1.2756938e+02, 4.2170937e+02, -6.8418245e+01 );
expectedForces[576] = Vec3( 8.8370341e+01, -1.4671130e+02, -5.6211071e+02 );
expectedForces[577] = Vec3( 6.7701453e+02, 2.1228010e+02, 2.3047236e+02 );
expectedForces[578] = Vec3( -1.2694819e+02, -7.2734890e+00, 1.1007893e+02 );
expectedForces[579] = Vec3( -6.8945756e+02, 1.7359485e+02, -2.5607776e+02 );
expectedForces[580] = Vec3( 6.7323923e+00, 3.1574487e+02, 5.9741152e+02 );
expectedForces[581] = Vec3( 2.1214031e+02, -4.7565197e+01, -9.6896159e+01 );
expectedForces[582] = Vec3( -3.4876562e+02, 5.8335489e+01, -1.7058451e+02 );
expectedForces[583] = Vec3( -1.6516914e+02, -3.8913162e+02, 5.8832025e+02 );
expectedForces[584] = Vec3( 4.7753612e+01, -6.6792213e+01, -4.6492749e+01 );
expectedForces[585] = Vec3( -4.7166578e+02, 7.1811831e+02, 7.0620222e+02 );
expectedForces[586] = Vec3( -3.0570577e+02, -1.7681907e+02, -2.1227370e+02 );
expectedForces[587] = Vec3( 1.8122997e+02, -6.8318737e+01, -3.4853368e+02 );
expectedForces[588] = Vec3( 7.5752093e+01, 3.9702196e+02, -9.0196404e+02 );
expectedForces[589] = Vec3( 5.1185528e+02, -7.7747186e+02, -3.3969581e+02 );
expectedForces[590] = Vec3( -3.1187606e+01, 5.9593198e+01, 7.7918649e+01 );
expectedForces[591] = Vec3( 2.2741676e+02, 2.1705631e+02, 3.9920149e+02 );
expectedForces[592] = Vec3( 7.0516894e+01, 3.3389665e+02, -6.8443760e+00 );
expectedForces[593] = Vec3( -9.9645406e+02, 2.8574127e+02, -8.0946834e+02 );
expectedForces[594] = Vec3( 1.0930460e+02, 1.5869363e+03, -4.0704089e+02 );
expectedForces[595] = Vec3( -3.0341438e+02, -5.7494385e+00, 2.9655509e+02 );
expectedForces[596] = Vec3( 8.7955203e+01, -7.6811348e+01, -6.9558652e+01 );
expectedForces[597] = Vec3( -9.4378353e+01, 3.6253070e+02, 9.0703343e-01 );
expectedForces[598] = Vec3( -4.7595525e+01, -6.9148379e+02, -4.6737971e+02 );
expectedForces[599] = Vec3( 2.2339987e+02, -2.5503335e+02, 2.8552040e+02 );
expectedForces[600] = Vec3( 1.0309072e+02, -2.1298204e+02, -4.3393283e+02 );
expectedForces[601] = Vec3( -2.4581477e+02, 2.5126386e+02, -1.8679710e+02 );
expectedForces[602] = Vec3( 7.7926618e+00, -2.4947558e+01, 1.5962011e+02 );
expectedForces[603] = Vec3( 7.0099476e+02, 5.9496129e+01, 2.0314640e+02 );
expectedForces[604] = Vec3( -5.2583810e+01, 3.1237489e+01, -4.0902937e+00 );
expectedForces[605] = Vec3( -5.4435871e+01, -7.7056693e+01, -1.5137215e+01 );
expectedForces[606] = Vec3( -7.8684074e+02, 8.1673860e+02, 5.0192222e+02 );
expectedForces[607] = Vec3( 2.9859285e+02, 1.9661708e+02, -1.9940993e+02 );
expectedForces[608] = Vec3( -9.9358476e-01, -3.4789219e+02, 1.7693106e+02 );
expectedForces[609] = Vec3( 6.7880927e+02, 7.2768533e+01, 1.1973248e+03 );
expectedForces[610] = Vec3( -1.2072838e+00, 1.1770157e+02, -8.6765918e+01 );
expectedForces[611] = Vec3( -4.3236695e+02, -2.8583002e+02, 1.3459508e+02 );
expectedForces[612] = Vec3( -6.1894609e+01, 4.4705141e+02, -2.3264215e+02 );
expectedForces[613] = Vec3( -2.6948720e+01, -2.7688230e+01, 4.6300601e+01 );
expectedForces[614] = Vec3( 4.3954815e+01, 6.1244278e+01, 1.0727211e+02 );
expectedForces[615] = Vec3( -2.2049132e+02, -9.7233594e+01, 8.3807949e+01 );
expectedForces[616] = Vec3( 2.8631226e+02, -1.3478640e+02, -5.0675977e+02 );
expectedForces[617] = Vec3( -1.1458029e+01, 6.3762007e+01, -4.9643140e+01 );
expectedForces[618] = Vec3( 7.7363305e+01, 1.1936816e+02, 3.9692323e+01 );
expectedForces[619] = Vec3( -8.4199858e+01, 2.3567494e+02, 7.2885200e+01 );
expectedForces[620] = Vec3( -7.4500104e+00, 3.5567340e+00, -2.2676267e+01 );
expectedForces[621] = Vec3( -7.9200057e+02, 3.2245192e+01, 1.1829644e+01 );
expectedForces[622] = Vec3( 3.9959336e+02, 2.2447865e+02, -3.1413233e+02 );
expectedForces[623] = Vec3( 1.5810527e+02, -2.2341997e+02, 2.3388212e+02 );
expectedForces[624] = Vec3( -2.9248657e+02, -1.0806250e+03, -6.1268035e+01 );
expectedForces[625] = Vec3( 6.5061442e+02, 1.2244756e+02, -1.1976147e+02 );
expectedForces[626] = Vec3( -1.7787710e+02, 3.7279354e+02, -3.7911745e+02 );
expectedForces[627] = Vec3( 3.7145927e+02, -2.5203732e+02, -2.2889342e+02 );
expectedForces[628] = Vec3( 1.9440281e+02, -2.3076142e+02, 7.2945279e+01 );
expectedForces[629] = Vec3( -2.3603693e+02, -1.1987203e+02, -1.2000208e+02 );
expectedForces[630] = Vec3( -8.4811726e+01, -6.4500846e+02, -5.1257210e+02 );
expectedForces[631] = Vec3( -1.6183393e+01, 1.3980655e+01, -2.3189702e+00 );
expectedForces[632] = Vec3( 1.3526098e+02, 1.3800365e+02, -9.4360476e+01 );
expectedForces[633] = Vec3( 2.0983514e+01, 5.1156494e+02, -4.3526557e+01 );
expectedForces[634] = Vec3( -2.8666500e+02, -5.8235691e+02, -8.7425194e+01 );
expectedForces[635] = Vec3( -1.7183604e+02, 1.0002944e+01, 6.5855812e+02 );
expectedForces[636] = Vec3( -2.1735465e+02, 9.4664675e+02, 8.9132890e+02 );
expectedForces[637] = Vec3( 6.3759184e+01, -5.2436201e+02, 1.2455578e+02 );
expectedForces[638] = Vec3( 3.2176621e+02, 1.8182348e+02, -4.4863340e+02 );
expectedForces[639] = Vec3( -8.4308252e+02, -1.6268681e+02, 5.8113352e+02 );
expectedForces[640] = Vec3( 6.1223389e+01, 3.6767423e+02, 5.9071999e+02 );
expectedForces[641] = Vec3( 2.2546928e+02, -2.2022805e+02, 8.3027103e+01 );
expectedForces[642] = Vec3( -4.0385190e+02, 2.0141033e+02, 2.7296512e+01 );
expectedForces[643] = Vec3( 8.4204485e+01, -7.1102294e+01, 5.7642677e+01 );
expectedForces[644] = Vec3( 6.1859901e+01, 1.4828523e+02, -2.6764016e+02 );
expectedForces[645] = Vec3( -6.7249932e+02, -8.4613525e+01, -3.9792609e+02 );
expectedForces[646] = Vec3( 9.9116485e+01, -3.7714583e+01, -5.3966332e+01 );
expectedForces[647] = Vec3( 2.0868628e+02, 2.9747206e+02, 3.3931416e+02 );
// tolerance is higher here due to interpolation used in setting tapering coefficients;
// if tapering turned off, then absolute difference < 2.0e-05
double tolerance = 5.0e-04;
compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log );
// test sigma/epsilon rules for dispersion correction
if( includeVdwDispersionCorrection ){
std::vector<std::string> sigmaRules;
std::vector<std::string> epsilonRules;
std::vector<double> expectedEnergies;
sigmaRules.push_back( "ARITHMETIC" );
epsilonRules.push_back( "ARITHMETIC" );
expectedEnergies.push_back( 6.2137988e+03 );
sigmaRules.push_back( "GEOMETRIC" );
epsilonRules.push_back( "GEOMETRIC" );
expectedEnergies.push_back( 3.6358216e+03 );
sigmaRules.push_back( "CUBIC-MEAN" );
epsilonRules.push_back( "HARMONIC" );
expectedEnergies.push_back( 3.2774624e+03 );
for( unsigned int ii = 0; ii < sigmaRules.size(); ii++ ){
setupAndGetForcesEnergyVdwWater( sigmaRules[ii], epsilonRules[ii], cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy, log );
testName = "testVdwWaterWithDispersionCorrection_" + sigmaRules[ii] + '_' + epsilonRules[ii];
ASSERT_EQUAL_TOL_MOD( expectedEnergies[ii], energy, tolerance, testName );
}
}
}
int main( int numberOfArguments, char* argv[] ) { int main( int numberOfArguments, char* argv[] ) {
try { try {
...@@ -551,6 +1993,17 @@ int main( int numberOfArguments, char* argv[] ) { ...@@ -551,6 +1993,17 @@ int main( int numberOfArguments, char* argv[] ) {
testVdwPBC( log ); testVdwPBC( log );
// tests based on box of water
int includeVdwDispersionCorrection = 0;
testVdwWater( includeVdwDispersionCorrection, log );
// includes tests for various combinations of sigma/epsilon rules
// when computing vdw dispersion correction
includeVdwDispersionCorrection = 1;
testVdwWater( includeVdwDispersionCorrection, log );
} catch(const std::exception& e) { } catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl; std::cout << "exception: " << e.what() << std::endl;
std::cout << "FAIL - ERROR. Test failed." << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl;
......
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