"platforms/opencl/tests/TestOpenCLRandom.cpp" did not exist on "bc00090dd0a4a6cd76673ab7361baf73ede87228"
Commit f11bafd9 authored by peastman's avatar peastman
Browse files

Merge pull request #828 from peastman/cleanup

Cleanup to AMOEBA code
parents 162d69a2 d95b90b9
...@@ -44,7 +44,7 @@ int AmoebaPiTorsionForce::addPiTorsion(int particle1, int particle2, int particl ...@@ -44,7 +44,7 @@ int AmoebaPiTorsionForce::addPiTorsion(int particle1, int particle2, int particl
return piTorsions.size()-1; return piTorsions.size()-1;
} }
void AmoebaPiTorsionForce::getPiTorsionParameters(int index, int& particle1, int& particle2, int& particle3, int& particle4, int& particle5, int& particle6, double& k ) const { void AmoebaPiTorsionForce::getPiTorsionParameters(int index, int& particle1, int& particle2, int& particle3, int& particle4, int& particle5, int& particle6, double& k) const {
particle1 = piTorsions[index].particle1; particle1 = piTorsions[index].particle1;
particle2 = piTorsions[index].particle2; particle2 = piTorsions[index].particle2;
particle3 = piTorsions[index].particle3; particle3 = piTorsions[index].particle3;
...@@ -54,7 +54,7 @@ void AmoebaPiTorsionForce::getPiTorsionParameters(int index, int& particle1, int ...@@ -54,7 +54,7 @@ void AmoebaPiTorsionForce::getPiTorsionParameters(int index, int& particle1, int
k = piTorsions[index].k; k = piTorsions[index].k;
} }
void AmoebaPiTorsionForce::setPiTorsionParameters(int index, int particle1, int particle2, int particle3, int particle4, int particle5, int particle6, double k ) { void AmoebaPiTorsionForce::setPiTorsionParameters(int index, int particle1, int particle2, int particle3, int particle4, int particle5, int particle6, double k) {
piTorsions[index].particle1 = particle1; piTorsions[index].particle1 = particle1;
piTorsions[index].particle2 = particle2; piTorsions[index].particle2 = particle2;
piTorsions[index].particle3 = particle3; piTorsions[index].particle3 = particle3;
......
...@@ -46,7 +46,7 @@ int AmoebaStretchBendForce::addStretchBend(int particle1, int particle2, int par ...@@ -46,7 +46,7 @@ int AmoebaStretchBendForce::addStretchBend(int particle1, int particle2, int par
} }
void AmoebaStretchBendForce::getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, void AmoebaStretchBendForce::getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3,
double& lengthAB, double& lengthCB, double& angle, double& k1, double& k2 ) const { double& lengthAB, double& lengthCB, double& angle, double& k1, double& k2) const {
particle1 = stretchBends[index].particle1; particle1 = stretchBends[index].particle1;
particle2 = stretchBends[index].particle2; particle2 = stretchBends[index].particle2;
particle3 = stretchBends[index].particle3; particle3 = stretchBends[index].particle3;
......
...@@ -70,13 +70,13 @@ void AmoebaTorsionTorsionForce::setTorsionTorsionParameters(int index, int parti ...@@ -70,13 +70,13 @@ void AmoebaTorsionTorsionForce::setTorsionTorsionParameters(int index, int parti
torsionTorsions[index].gridIndex = gridIndex; torsionTorsions[index].gridIndex = gridIndex;
} }
const TorsionTorsionGrid& AmoebaTorsionTorsionForce::getTorsionTorsionGrid(int index ) const { const TorsionTorsionGrid& AmoebaTorsionTorsionForce::getTorsionTorsionGrid(int index) const {
return torsionTorsionGrids[index].getTorsionTorsionGrid(); return torsionTorsionGrids[index].getTorsionTorsionGrid();
} }
void AmoebaTorsionTorsionForce::setTorsionTorsionGrid(int index, const TorsionTorsionGrid& grid ) { void AmoebaTorsionTorsionForce::setTorsionTorsionGrid(int index, const TorsionTorsionGrid& grid) {
if( index >= static_cast<int>(torsionTorsionGrids.size()) ){ if (index >= static_cast<int>(torsionTorsionGrids.size())) {
torsionTorsionGrids.resize( index + 1); torsionTorsionGrids.resize(index + 1);
} }
torsionTorsionGrids[index] = grid; torsionTorsionGrids[index] = grid;
} }
......
...@@ -70,12 +70,11 @@ typedef std::map< double, Map_Double_IntPair > Map_Double_MapDoubleIntPair; ...@@ -70,12 +70,11 @@ typedef std::map< double, Map_Double_IntPair > Map_Double_MapDoubleIntPair;
typedef Map_Double_MapDoubleIntPair::iterator Map_Double_MapDoubleIntPairI; typedef Map_Double_MapDoubleIntPair::iterator Map_Double_MapDoubleIntPairI;
typedef Map_Double_MapDoubleIntPair::const_iterator Map_Double_MapDoubleIntPairCI; typedef Map_Double_MapDoubleIntPair::const_iterator Map_Double_MapDoubleIntPairCI;
void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid, TorsionTorsionGrid& reorderedGrid ){ void AmoebaTorsionTorsionForceImpl::reorderGrid(const TorsionTorsionGrid& grid, TorsionTorsionGrid& reorderedGrid) {
reorderedGrid.resize( grid.size() ); reorderedGrid.resize(grid.size());
std::vector<Map_Double_IntPair> map_Double_IntPair_Vector( grid.size() ); std::vector<Map_Double_IntPair> map_Double_IntPair_Vector(grid.size());
Map_Double_MapDoubleIntPair mapAngles; Map_Double_MapDoubleIntPair mapAngles;
//(void) fprintf( stderr, "AmoebaTorsionTorsionForceImpl::reorder grid\n" );
// (1) set dimensions for reorderd grid // (1) set dimensions for reorderd grid
// (2) build map: // (2) build map:
...@@ -84,27 +83,27 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid, ...@@ -84,27 +83,27 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid,
for (unsigned int ii = 0; ii < grid.size(); ii++) { for (unsigned int ii = 0; ii < grid.size(); ii++) {
reorderedGrid[ii].resize( grid[ii].size() ); reorderedGrid[ii].resize(grid[ii].size());
for (unsigned int jj = 0; jj < grid[ii].size(); jj++) { for (unsigned int jj = 0; jj < grid[ii].size(); jj++) {
reorderedGrid[ii][jj].resize( grid[ii][jj].size() ); reorderedGrid[ii][jj].resize(grid[ii][jj].size());
double angleX = grid[ii][jj][0]; double angleX = grid[ii][jj][0];
double angleY = grid[ii][jj][1]; double angleY = grid[ii][jj][1];
if( mapAngles.find( angleX ) == mapAngles.end() ){ if (mapAngles.find(angleX) == mapAngles.end()) {
if( map_Double_IntPair_Vector[ii].size() > 0 ){ if (map_Double_IntPair_Vector[ii].size() > 0) {
char buffer[1024]; char buffer[1024];
(void) sprintf( buffer, "TorsionTorsion grid reorder: x-angle not set correctly: x=%15.7e y=%15.7e size=%u should be zero; ii/jj indies=%u %u.\n", (void) sprintf(buffer, "TorsionTorsion grid reorder: x-angle not set correctly: x=%15.7e y=%15.7e size=%u should be zero; ii/jj indies=%u %u.\n",
angleX, angleY, static_cast<unsigned int>(map_Double_IntPair_Vector[ii].size()), ii, jj ); angleX, angleY, static_cast<unsigned int>(map_Double_IntPair_Vector[ii].size()), ii, jj);
throw OpenMMException(buffer); throw OpenMMException(buffer);
} }
mapAngles[angleX] = map_Double_IntPair_Vector[ii]; mapAngles[angleX] = map_Double_IntPair_Vector[ii];
} }
Map_Double_IntPair& map_Double_IntPair = mapAngles[angleX]; Map_Double_IntPair& map_Double_IntPair = mapAngles[angleX];
if( map_Double_IntPair.find( angleY ) != map_Double_IntPair.end() ){ if (map_Double_IntPair.find(angleY) != map_Double_IntPair.end()) {
char buffer[1024]; char buffer[1024];
(void) sprintf( buffer, "TorsionTorsion grid reorder: angle pair found twice: %15.7e %15.7e %u\n", angleX, angleY, static_cast<unsigned int>(map_Double_IntPair.size()) ); (void) sprintf(buffer, "TorsionTorsion grid reorder: angle pair found twice: %15.7e %15.7e %u\n", angleX, angleY, static_cast<unsigned int>(map_Double_IntPair.size()));
throw OpenMMException(buffer); throw OpenMMException(buffer);
} }
struct IntPair pair; struct IntPair pair;
...@@ -114,24 +113,6 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid, ...@@ -114,24 +113,6 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid,
} }
} }
#if 0
(void) fprintf( stderr, "TorsionTorsion grid reorder map\n" );
for( Map_Double_MapDoubleIntPairCI ii = mapAngles.begin(); ii != mapAngles.end(); ii++ ){
double angleX = ii->first;
Map_Double_IntPair map_Double_IntPair = ii->second;
(void) fprintf( stderr, " %15.7e %u \n", angleX, static_cast<unsigned int>(map_Double_IntPair.size()) );
}
for( Map_Double_MapDoubleIntPairCI ii = mapAngles.begin(); ii != mapAngles.end(); ii++ ){
double angleX = ii->first;
Map_Double_IntPair map_Double_IntPair = ii->second;
for( Map_Double_IntPairCI jj = map_Double_IntPair.begin(); jj != map_Double_IntPair.end(); jj++ ){
double angle = jj->first;
struct IntPair pair = jj->second;
(void) fprintf( stderr, " %15.7e %15.7e %d %d\n", angleX, angle, pair.index1, pair.index2 );
}
}
#endif
// load reordered entries // load reordered entries
Map_Double_MapDoubleIntPairCI mapII = mapAngles.begin(); Map_Double_MapDoubleIntPairCI mapII = mapAngles.begin();
...@@ -144,7 +125,6 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid, ...@@ -144,7 +125,6 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid,
struct IntPair pair = mapJJ->second; struct IntPair pair = mapJJ->second;
int index1 = pair.index1; int index1 = pair.index1;
int index2 = pair.index2; int index2 = pair.index2;
//(void) fprintf( stderr, " %3d %3d %15.7e %15.7e %3d %3d zzz\n", ii, jj, mapII->first, mapJJ->first, index1, index2 );
for (unsigned int kk = 0; kk < grid[ii][jj].size(); kk++) { for (unsigned int kk = 0; kk < grid[ii][jj].size(); kk++) {
reorderedGrid[ii][jj][kk] = static_cast<float>(grid[index1][index2][kk]); reorderedGrid[ii][jj][kk] = static_cast<float>(grid[index1][index2][kk]);
...@@ -153,12 +133,12 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid, ...@@ -153,12 +133,12 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid,
// increment map iterators // increment map iterators
mapJJ++; mapJJ++;
if( mapJJ == map_Double_IntPair.end() ){ if (mapJJ == map_Double_IntPair.end()) {
mapII++; mapII++;
if( mapII == mapAngles.end() ){ if (mapII == mapAngles.end()) {
if( (jj != (grid[ii].size()-1)) && (ii != (grid.size()-1)) ){ if ((jj != (grid[ii].size()-1)) && (ii != (grid.size()-1))) {
char buffer[1024]; char buffer[1024];
(void) sprintf( buffer, "AmoebaTorsionTorsionForceImpl::reorderGrid: error detected with map iterators.\n" ); (void) sprintf(buffer, "AmoebaTorsionTorsionForceImpl::reorderGrid: error detected with map iterators.\n");
throw OpenMMException(buffer); throw OpenMMException(buffer);
} }
} else { } else {
......
...@@ -41,13 +41,13 @@ using std::vector; ...@@ -41,13 +41,13 @@ using std::vector;
AmoebaVdwForce::AmoebaVdwForce() : nonbondedMethod(NoCutoff), sigmaCombiningRule("CUBIC-MEAN"), epsilonCombiningRule("HHG"), cutoff(1.0e+10), useDispersionCorrection(true) { AmoebaVdwForce::AmoebaVdwForce() : nonbondedMethod(NoCutoff), sigmaCombiningRule("CUBIC-MEAN"), epsilonCombiningRule("HHG"), cutoff(1.0e+10), useDispersionCorrection(true) {
} }
int AmoebaVdwForce::addParticle(int parentIndex, double sigma, double epsilon, double reductionFactor ) { int AmoebaVdwForce::addParticle(int parentIndex, double sigma, double epsilon, double reductionFactor) {
parameters.push_back(VdwInfo(parentIndex, sigma, epsilon, reductionFactor)); parameters.push_back(VdwInfo(parentIndex, sigma, epsilon, reductionFactor));
return parameters.size()-1; return parameters.size()-1;
} }
void AmoebaVdwForce::getParticleParameters(int particleIndex, int& parentIndex, void AmoebaVdwForce::getParticleParameters(int particleIndex, int& parentIndex,
double& sigma, double& epsilon, double& reductionFactor ) const { double& sigma, double& epsilon, double& reductionFactor) const {
parentIndex = parameters[particleIndex].parentIndex; parentIndex = parameters[particleIndex].parentIndex;
sigma = parameters[particleIndex].sigma; sigma = parameters[particleIndex].sigma;
epsilon = parameters[particleIndex].epsilon; epsilon = parameters[particleIndex].epsilon;
...@@ -55,14 +55,14 @@ void AmoebaVdwForce::getParticleParameters(int particleIndex, int& parentIndex, ...@@ -55,14 +55,14 @@ void AmoebaVdwForce::getParticleParameters(int particleIndex, int& parentIndex,
} }
void AmoebaVdwForce::setParticleParameters(int particleIndex, int parentIndex, void AmoebaVdwForce::setParticleParameters(int particleIndex, int parentIndex,
double sigma, double epsilon, double reductionFactor ) { double sigma, double epsilon, double reductionFactor) {
parameters[particleIndex].parentIndex = parentIndex; parameters[particleIndex].parentIndex = parentIndex;
parameters[particleIndex].sigma = sigma; parameters[particleIndex].sigma = sigma;
parameters[particleIndex].epsilon = epsilon; parameters[particleIndex].epsilon = epsilon;
parameters[particleIndex].reductionFactor = reductionFactor; parameters[particleIndex].reductionFactor = reductionFactor;
} }
void AmoebaVdwForce::setSigmaCombiningRule( const std::string& inputSigmaCombiningRule ) { void AmoebaVdwForce::setSigmaCombiningRule(const std::string& inputSigmaCombiningRule) {
sigmaCombiningRule = inputSigmaCombiningRule; sigmaCombiningRule = inputSigmaCombiningRule;
} }
...@@ -70,7 +70,7 @@ const std::string& AmoebaVdwForce::getSigmaCombiningRule() const { ...@@ -70,7 +70,7 @@ const std::string& AmoebaVdwForce::getSigmaCombiningRule() const {
return sigmaCombiningRule; return sigmaCombiningRule;
} }
void AmoebaVdwForce::setEpsilonCombiningRule( const std::string& inputEpsilonCombiningRule ) { void AmoebaVdwForce::setEpsilonCombiningRule(const std::string& inputEpsilonCombiningRule) {
epsilonCombiningRule = inputEpsilonCombiningRule; epsilonCombiningRule = inputEpsilonCombiningRule;
} }
...@@ -78,31 +78,31 @@ const std::string& AmoebaVdwForce::getEpsilonCombiningRule() const { ...@@ -78,31 +78,31 @@ const std::string& AmoebaVdwForce::getEpsilonCombiningRule() const {
return epsilonCombiningRule; return epsilonCombiningRule;
} }
void AmoebaVdwForce::setParticleExclusions( int particleIndex, const std::vector< int >& inputExclusions ) { void AmoebaVdwForce::setParticleExclusions(int particleIndex, const std::vector< int >& inputExclusions) {
if( exclusions.size() < parameters.size() ){ if (exclusions.size() < parameters.size()) {
exclusions.resize( parameters.size() ); exclusions.resize(parameters.size());
} }
if( static_cast<int>(exclusions.size()) < particleIndex ){ if (static_cast<int>(exclusions.size()) < particleIndex) {
exclusions.resize( particleIndex + 10 ); exclusions.resize(particleIndex + 10);
} }
for( unsigned int ii = 0; ii < inputExclusions.size(); ii++ ){ for (unsigned int ii = 0; ii < inputExclusions.size(); ii++) {
exclusions[particleIndex].push_back( inputExclusions[ii] ); exclusions[particleIndex].push_back(inputExclusions[ii]);
} }
} }
void AmoebaVdwForce::getParticleExclusions( int particleIndex, std::vector< int >& outputExclusions ) const { void AmoebaVdwForce::getParticleExclusions(int particleIndex, std::vector< int >& outputExclusions) const {
if( particleIndex < static_cast<int>(exclusions.size()) ){ if (particleIndex < static_cast<int>(exclusions.size())) {
outputExclusions.resize( exclusions[particleIndex].size() ); outputExclusions.resize(exclusions[particleIndex].size());
for( unsigned int ii = 0; ii < exclusions[particleIndex].size(); ii++ ){ for (unsigned int ii = 0; ii < exclusions[particleIndex].size(); ii++) {
outputExclusions[ii] = exclusions[particleIndex][ii]; outputExclusions[ii] = exclusions[particleIndex][ii];
} }
} }
} }
void AmoebaVdwForce::setCutoff( double inputCutoff ){ void AmoebaVdwForce::setCutoff(double inputCutoff) {
cutoff = inputCutoff; cutoff = inputCutoff;
} }
......
...@@ -48,17 +48,17 @@ AmoebaWcaDispersionForce::AmoebaWcaDispersionForce() { ...@@ -48,17 +48,17 @@ AmoebaWcaDispersionForce::AmoebaWcaDispersionForce() {
dispoff = 0.26; dispoff = 0.26;
} }
int AmoebaWcaDispersionForce::addParticle( double radius, double epsilon ) { int AmoebaWcaDispersionForce::addParticle(double radius, double epsilon) {
parameters.push_back(WcaDispersionInfo( radius, epsilon)); parameters.push_back(WcaDispersionInfo(radius, epsilon));
return parameters.size()-1; return parameters.size()-1;
} }
void AmoebaWcaDispersionForce::getParticleParameters(int particleIndex, double& radius, double& epsilon ) const { void AmoebaWcaDispersionForce::getParticleParameters(int particleIndex, double& radius, double& epsilon) const {
radius = parameters[particleIndex].radius; radius = parameters[particleIndex].radius;
epsilon = parameters[particleIndex].epsilon; epsilon = parameters[particleIndex].epsilon;
} }
void AmoebaWcaDispersionForce::setParticleParameters(int particleIndex, double radius, double epsilon ) { void AmoebaWcaDispersionForce::setParticleParameters(int particleIndex, double radius, double epsilon) {
parameters[particleIndex].radius = radius; parameters[particleIndex].radius = radius;
parameters[particleIndex].epsilon = epsilon; parameters[particleIndex].epsilon = epsilon;
} }
...@@ -95,35 +95,35 @@ double AmoebaWcaDispersionForce::getSlevy() const { ...@@ -95,35 +95,35 @@ double AmoebaWcaDispersionForce::getSlevy() const {
return slevy; return slevy;
} }
void AmoebaWcaDispersionForce::setEpso( double inputEpso ){ void AmoebaWcaDispersionForce::setEpso(double inputEpso) {
epso = inputEpso; epso = inputEpso;
} }
void AmoebaWcaDispersionForce::setEpsh( double inputEpsh ){ void AmoebaWcaDispersionForce::setEpsh(double inputEpsh) {
epsh = inputEpsh; epsh = inputEpsh;
} }
void AmoebaWcaDispersionForce::setRmino( double inputRmino ){ void AmoebaWcaDispersionForce::setRmino(double inputRmino) {
rmino = inputRmino; rmino = inputRmino;
} }
void AmoebaWcaDispersionForce::setRminh( double inputRminh ){ void AmoebaWcaDispersionForce::setRminh(double inputRminh) {
rminh = inputRminh; rminh = inputRminh;
} }
void AmoebaWcaDispersionForce::setAwater( double inputAwater ){ void AmoebaWcaDispersionForce::setAwater(double inputAwater) {
awater = inputAwater; awater = inputAwater;
} }
void AmoebaWcaDispersionForce::setShctd( double inputShctd ){ void AmoebaWcaDispersionForce::setShctd(double inputShctd) {
shctd = inputShctd; shctd = inputShctd;
} }
void AmoebaWcaDispersionForce::setDispoff( double inputDispoff ){ void AmoebaWcaDispersionForce::setDispoff(double inputDispoff) {
dispoff = inputDispoff; dispoff = inputDispoff;
} }
void AmoebaWcaDispersionForce::setSlevy( double inputSlevy ){ void AmoebaWcaDispersionForce::setSlevy(double inputSlevy) {
slevy = inputSlevy; slevy = inputSlevy;
} }
......
...@@ -61,15 +61,15 @@ double AmoebaWcaDispersionForceImpl::calcForcesAndEnergy(ContextImpl& context, b ...@@ -61,15 +61,15 @@ double AmoebaWcaDispersionForceImpl::calcForcesAndEnergy(ContextImpl& context, b
return kernel.getAs<CalcAmoebaWcaDispersionForceKernel>().execute(context, includeForces, includeEnergy); return kernel.getAs<CalcAmoebaWcaDispersionForceKernel>().execute(context, includeForces, includeEnergy);
return 0.0; return 0.0;
} }
void AmoebaWcaDispersionForceImpl::getMaximumDispersionEnergy( const AmoebaWcaDispersionForce& force, int particleIndex, double& maxDispersionEnergy ) { void AmoebaWcaDispersionForceImpl::getMaximumDispersionEnergy(const AmoebaWcaDispersionForce& force, int particleIndex, double& maxDispersionEnergy) {
const double pi = 3.1415926535897; const double pi = 3.1415926535897;
// from last loop in subroutine knp in ksolv.f // from last loop in subroutine knp in ksolv.f
double rdisp, epsi; double rdisp, epsi;
force.getParticleParameters( particleIndex, rdisp, epsi ); force.getParticleParameters(particleIndex, rdisp, epsi);
if( epsi <= 0.0 || rdisp <= 0.0 ){ if (epsi <= 0.0 || rdisp <= 0.0) {
maxDispersionEnergy = 0.0; maxDispersionEnergy = 0.0;
return; return;
} }
...@@ -104,32 +104,27 @@ void AmoebaWcaDispersionForceImpl::getMaximumDispersionEnergy( const AmoebaWcaDi ...@@ -104,32 +104,27 @@ void AmoebaWcaDispersionForceImpl::getMaximumDispersionEnergy( const AmoebaWcaDi
double rdisp11 = rdisp7*rdisp3*rdisp; double rdisp11 = rdisp7*rdisp3*rdisp;
double cdisp; double cdisp;
if( rdisp < rmixh) { if (rdisp < rmixh) {
cdisp = -4.0*pi*emixh*(rmixh3-rdisp3)/3.0 - emixh*18.0/11.0*rmixh3*pi; cdisp = -4.0*pi*emixh*(rmixh3-rdisp3)/3.0 - emixh*18.0/11.0*rmixh3*pi;
} else { } else {
cdisp = 2.0*pi*(2.0*rmixh7-11.0*rdisp7)*ah/ (11.0*rdisp11); cdisp = 2.0*pi*(2.0*rmixh7-11.0*rdisp7)*ah/ (11.0*rdisp11);
} }
cdisp *= 2.0; cdisp *= 2.0;
if (rdisp < rmixo ) { if (rdisp < rmixo) {
cdisp -= 4.0*pi*emixo*(rmixo3-rdisp3)/3.0; cdisp -= 4.0*pi*emixo*(rmixo3-rdisp3)/3.0;
cdisp -= emixo*18.0/11.0*rmixo3*pi; cdisp -= emixo*18.0/11.0*rmixo3*pi;
} else { } else {
cdisp += 2.0*pi*(2.0*rmixo7-11.0*rdisp7) * ao/(11.0*rdisp11); cdisp += 2.0*pi*(2.0*rmixo7-11.0*rdisp7) * ao/(11.0*rdisp11);
} }
maxDispersionEnergy = force.getSlevy()*force.getAwater()*cdisp; maxDispersionEnergy = force.getSlevy()*force.getAwater()*cdisp;
// (void) fprintf( stderr,"Wca %5d %14.7e %14.7e %14.7e %14.7e %14.7e %14.7e %14.7e %14.7e\n",
// particleIndex, rdisp,rmini,epsi, emixh,rmixh,emixo,rmixo,cdisp );
return;
} }
double AmoebaWcaDispersionForceImpl::getTotalMaximumDispersionEnergy( const AmoebaWcaDispersionForce& force ){ double AmoebaWcaDispersionForceImpl::getTotalMaximumDispersionEnergy(const AmoebaWcaDispersionForce& force) {
double totalMaximumDispersionEnergy = 0.0; double totalMaximumDispersionEnergy = 0.0;
for( int ii = 0; ii < force.getNumParticles(); ii++ ){ for (int ii = 0; ii < force.getNumParticles(); ii++) {
double maximumDispersionEnergy; double maximumDispersionEnergy;
getMaximumDispersionEnergy( force, ii, maximumDispersionEnergy ); getMaximumDispersionEnergy(force, ii, maximumDispersionEnergy);
totalMaximumDispersionEnergy += maximumDispersionEnergy; totalMaximumDispersionEnergy += maximumDispersionEnergy;
} }
return totalMaximumDispersionEnergy; return totalMaximumDispersionEnergy;
......
...@@ -774,16 +774,16 @@ public: ...@@ -774,16 +774,16 @@ public:
vector<double> dipole1, dipole2, quadrupole1, quadrupole2; vector<double> dipole1, dipole2, quadrupole1, quadrupole2;
force.getMultipoleParameters(particle1, charge1, dipole1, quadrupole1, axis1, multipole11, multipole21, multipole31, thole1, damping1, polarity1); force.getMultipoleParameters(particle1, charge1, dipole1, quadrupole1, axis1, multipole11, multipole21, multipole31, thole1, damping1, polarity1);
force.getMultipoleParameters(particle2, charge2, dipole2, quadrupole2, axis2, multipole12, multipole22, multipole32, thole2, damping2, polarity2); force.getMultipoleParameters(particle2, charge2, dipole2, quadrupole2, axis2, multipole12, multipole22, multipole32, thole2, damping2, polarity2);
if (charge1 != charge2 || thole1 != thole2 || damping1 != damping2 || polarity1 != polarity2 || axis1 != axis2){ if (charge1 != charge2 || thole1 != thole2 || damping1 != damping2 || polarity1 != polarity2 || axis1 != axis2) {
return false; return false;
} }
for (int i = 0; i < (int) dipole1.size(); ++i){ for (int i = 0; i < (int) dipole1.size(); ++i) {
if (dipole1[i] != dipole2[i]){ if (dipole1[i] != dipole2[i]) {
return false; return false;
} }
} }
for (int i = 0; i < (int) quadrupole1.size(); ++i){ for (int i = 0; i < (int) quadrupole1.size(); ++i) {
if (quadrupole1[i] != quadrupole2[i]){ if (quadrupole1[i] != quadrupole2[i]) {
return false; return false;
} }
} }
......
...@@ -343,7 +343,7 @@ public: ...@@ -343,7 +343,7 @@ public:
* @param outputElectrostaticPotential output potential * @param outputElectrostaticPotential output potential
*/ */
void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid,
std::vector< double >& outputElectrostaticPotential ); std::vector< double >& outputElectrostaticPotential);
/** /**
* Get the system multipole moments * Get the system multipole moments
...@@ -353,7 +353,7 @@ public: ...@@ -353,7 +353,7 @@ public:
* dipole_x, dipole_y, dipole_z, * dipole_x, dipole_y, dipole_z,
* quadrupole_xx, quadrupole_xy, quadrupole_xz, * quadrupole_xx, quadrupole_xy, quadrupole_xz,
* quadrupole_yx, quadrupole_yy, quadrupole_yz, * quadrupole_yx, quadrupole_yy, quadrupole_yz,
* quadrupole_zx, quadrupole_zy, quadrupole_zz ) * quadrupole_zx, quadrupole_zy, quadrupole_zz)
*/ */
void getSystemMultipoleMoments(ContextImpl& context, std::vector<double>& outputMultipoleMoments); void getSystemMultipoleMoments(ContextImpl& context, std::vector<double>& outputMultipoleMoments);
/** /**
......
...@@ -26,13 +26,13 @@ __device__ void bicubic(real4 y, real4 y1i, real4 y2i, real4 y12i, real x1, real ...@@ -26,13 +26,13 @@ __device__ void bicubic(real4 y, real4 y1i, real4 y2i, real4 y12i, real x1, real
-2.0f*y12.x - y12.y - y12.z - 2.0f*y12.w; -2.0f*y12.x - y12.y - y12.z - 2.0f*y12.w;
c[3][0] = 2.0f*(y.x - y.y) + y1.x + y1.y; c[3][0] = 2.0f*(y.x - y.y) + y1.x + y1.y;
c[3][1] = 2.0f*(y2.x - y2.y) + y12.x + y12.y; c[3][1] = 2.0f*(y2.x - y2.y) + y12.x + y12.y;
c[3][2] = 6.0f*( y.y - y.x + y.w - y.z) + c[3][2] = 6.0f*(y.y - y.x + y.w - y.z) +
3.0f*(y1.z + y1.w - y1.x - y1.y) + 3.0f*(y1.z + y1.w - y1.x - y1.y) +
2.0f*( 2.0f*(y2.y - y2.x) + y2.z - y2.w) + 2.0f*(2.0f*(y2.y - y2.x) + y2.z - y2.w) +
-2.0f*(y12.x + y12.y) - y12.z - y12.w; -2.0f*(y12.x + y12.y) - y12.z - y12.w;
c[3][3] = 4.0f*( y.x - y.y + y.z - y.w) + c[3][3] = 4.0f*( y.x - y.y + y.z - y.w) +
2.0f*( y1.x + y1.y - y1.z - y1.w) + 2.0f*(y1.x + y1.y - y1.z - y1.w) +
2.0f*( y2.x - y2.y - y2.z + y2.w) + 2.0f*(y2.x - y2.y - y2.z + y2.w) +
y12.x + y12.y + y12.z + y12.w; y12.x + y12.y + y12.z + y12.w;
real t = (x1-x1l) / (x1u-x1l); real t = (x1-x1l) / (x1u-x1l);
......
...@@ -66,7 +66,7 @@ const double TOL = 1e-5; ...@@ -66,7 +66,7 @@ const double TOL = 1e-5;
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) {
vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1];
vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2];
...@@ -75,26 +75,19 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto ...@@ -75,26 +75,19 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto
return; return;
} }
static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, double quadraticK, double cubicK, static void getPrefactorsGivenAngleCosine(double cosine, double idealAngle, double quadraticK, double cubicK,
double quarticK, double penticK, double sexticK, double quarticK, double penticK, double sexticK,
double* dEdR, double* energyTerm, FILE* log ) { double* dEdR, double* energyTerm) {
double angle; double angle;
if( cosine >= 1.0 ){ if (cosine >= 1.0) {
angle = 0.0f; angle = 0.0f;
} else if( cosine <= -1.0 ){ } else if (cosine <= -1.0) {
angle = RADIAN*PI_M; angle = RADIAN*PI_M;
} else { } else {
angle = RADIAN*acos(cosine); angle = RADIAN*acos(cosine);
} }
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "getPrefactorsGivenAngleCosine: cosine=%10.3e angle=%10.3e ideal=%10.3e\n", cosine, angle, idealAngle );
(void) fflush( log );
}
#endif
double deltaIdeal = angle - idealAngle; double deltaIdeal = angle - idealAngle;
double deltaIdeal2 = deltaIdeal*deltaIdeal; double deltaIdeal2 = deltaIdeal*deltaIdeal;
double deltaIdeal3 = deltaIdeal*deltaIdeal2; double deltaIdeal3 = deltaIdeal*deltaIdeal2;
...@@ -102,11 +95,11 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou ...@@ -102,11 +95,11 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou
// deltaIdeal = r - r_0 // deltaIdeal = r - r_0
*dEdR = ( 2.0 + *dEdR = (2.0 +
3.0*cubicK* deltaIdeal + 3.0*cubicK* deltaIdeal +
4.0*quarticK*deltaIdeal2 + 4.0*quarticK*deltaIdeal2 +
5.0*penticK* deltaIdeal3 + 5.0*penticK* deltaIdeal3 +
6.0*sexticK* deltaIdeal4 ); 6.0*sexticK* deltaIdeal4 );
*dEdR *= RADIAN*quadraticK*deltaIdeal; *dEdR *= RADIAN*quadraticK*deltaIdeal;
...@@ -121,30 +114,22 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou ...@@ -121,30 +114,22 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou
} }
static void computeAmoebaAngleForce(int bondIndex, std::vector<Vec3>& positions, AmoebaAngleForce& amoebaAngleForce, static void computeAmoebaAngleForce(int bondIndex, std::vector<Vec3>& positions, AmoebaAngleForce& amoebaAngleForce,
std::vector<Vec3>& forces, double* energy, FILE* log ) { std::vector<Vec3>& forces, double* energy) {
int particle1, particle2, particle3; int particle1, particle2, particle3;
double idealAngle; double idealAngle;
double quadraticK; double quadraticK;
amoebaAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, idealAngle, quadraticK ); amoebaAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, idealAngle, quadraticK);
double cubicK = amoebaAngleForce.getAmoebaGlobalAngleCubic(); double cubicK = amoebaAngleForce.getAmoebaGlobalAngleCubic();
double quarticK = amoebaAngleForce.getAmoebaGlobalAngleQuartic(); double quarticK = amoebaAngleForce.getAmoebaGlobalAngleQuartic();
double penticK = amoebaAngleForce.getAmoebaGlobalAnglePentic(); double penticK = amoebaAngleForce.getAmoebaGlobalAnglePentic();
double sexticK = amoebaAngleForce.getAmoebaGlobalAngleSextic(); double sexticK = amoebaAngleForce.getAmoebaGlobalAngleSextic();
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaAngleForce: bond %d [%d %d %d] ang=%10.3f k=%10.3f [%10.3e %10.3e %10.3e %10.3e]\n",
bondIndex, particle1, particle2, particle3, idealAngle, quadraticK, cubicK, quarticK, penticK, sexticK );
(void) fflush( log );
}
#endif
double deltaR[2][3]; double deltaR[2][3];
double r2_0 = 0.0; double r2_0 = 0.0;
double r2_1 = 0.0; double r2_1 = 0.0;
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaR[0][ii] = positions[particle1][ii] - positions[particle2][ii]; deltaR[0][ii] = positions[particle1][ii] - positions[particle2][ii];
r2_0 += deltaR[0][ii]*deltaR[0][ii]; r2_0 += deltaR[0][ii]*deltaR[0][ii];
...@@ -155,33 +140,26 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector<Vec3>& positions ...@@ -155,33 +140,26 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector<Vec3>& positions
} }
double pVector[3]; double pVector[3];
crossProductVector3( deltaR[0], deltaR[1], pVector ); crossProductVector3(deltaR[0], deltaR[1], pVector);
double rp = sqrt( pVector[0]*pVector[0] + pVector[1]*pVector[1] + pVector[2]*pVector[2] ); double rp = sqrt(pVector[0]*pVector[0] + pVector[1]*pVector[1] + pVector[2]*pVector[2]);
if( rp < 1.0e-06 ){ if (rp < 1.0e-06) {
rp = 1.0e-06; rp = 1.0e-06;
} }
double dot = deltaR[0][0]*deltaR[1][0] + deltaR[0][1]*deltaR[1][1] + deltaR[0][2]*deltaR[1][2]; double dot = deltaR[0][0]*deltaR[1][0] + deltaR[0][1]*deltaR[1][1] + deltaR[0][2]*deltaR[1][2];
double cosine = dot/sqrt(r2_0*r2_1); double cosine = dot/sqrt(r2_0*r2_1);
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "dot=%10.3e r2_0=%10.3e r2_1=%10.3e\n", dot, r2_0, r2_1 );
(void) fflush( log );
}
#endif
double dEdR; double dEdR;
double energyTerm; double energyTerm;
getPrefactorsGivenAngleCosine( cosine, idealAngle, quadraticK, cubicK, getPrefactorsGivenAngleCosine(cosine, idealAngle, quadraticK, cubicK,
quarticK, penticK, sexticK, &dEdR, &energyTerm, log ); quarticK, penticK, sexticK, &dEdR, &energyTerm);
double termA = -dEdR/(r2_0*rp); double termA = -dEdR/(r2_0*rp);
double termC = dEdR/(r2_1*rp); double termC = dEdR/(r2_1*rp);
double deltaCrossP[3][3]; double deltaCrossP[3][3];
crossProductVector3( deltaR[0], pVector, deltaCrossP[0] ); crossProductVector3(deltaR[0], pVector, deltaCrossP[0]);
crossProductVector3( deltaR[1], pVector, deltaCrossP[2] ); crossProductVector3(deltaR[1], pVector, deltaCrossP[2]);
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaCrossP[0][ii] *= termA; deltaCrossP[0][ii] *= termA;
deltaCrossP[2][ii] *= termC; deltaCrossP[2][ii] *= termC;
deltaCrossP[1][ii] = -1.0*(deltaCrossP[0][ii] + deltaCrossP[2][ii]); deltaCrossP[1][ii] = -1.0*(deltaCrossP[0][ii] + deltaCrossP[2][ii]);
...@@ -202,72 +180,51 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector<Vec3>& positions ...@@ -202,72 +180,51 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector<Vec3>& positions
*energy += energyTerm; *energy += energyTerm;
} }
static void computeAmoebaAngleForces( Context& context, AmoebaAngleForce& amoebaAngleForce, static void computeAmoebaAngleForces(Context& context, AmoebaAngleForce& amoebaAngleForce,
std::vector<Vec3>& expectedForces, double* expectedEnergy, FILE* log ) { std::vector<Vec3>& expectedForces, double* expectedEnergy) {
// get positions and zero forces // get positions and zero forces
State state = context.getState(State::Positions); State state = context.getState(State::Positions);
std::vector<Vec3> positions = state.getPositions(); std::vector<Vec3> positions = state.getPositions();
expectedForces.resize( positions.size() ); expectedForces.resize(positions.size());
for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ for (unsigned int ii = 0; ii < expectedForces.size(); ii++) {
expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0;
} }
// calculates forces/energy // calculates forces/energy
*expectedEnergy = 0.0; *expectedEnergy = 0.0;
for( int ii = 0; ii < amoebaAngleForce.getNumAngles(); ii++ ){ for (int ii = 0; ii < amoebaAngleForce.getNumAngles(); ii++) {
computeAmoebaAngleForce(ii, positions, amoebaAngleForce, expectedForces, expectedEnergy, log ); computeAmoebaAngleForce(ii, positions, amoebaAngleForce, expectedForces, expectedEnergy);
}
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaAngleForces: expected energy=%14.7e\n", *expectedEnergy );
for( unsigned int ii = 0; ii < positions.size(); ii++ ){
(void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] );
}
(void) fflush( log );
} }
#endif
return; return;
} }
void compareWithExpectedForceAndEnergy( Context& context, AmoebaAngleForce& amoebaAngleForce, void compareWithExpectedForceAndEnergy(Context& context, AmoebaAngleForce& amoebaAngleForce,
double tolerance, const std::string& idString, FILE* log) { double tolerance, const std::string& idString) {
std::vector<Vec3> expectedForces; std::vector<Vec3> expectedForces;
double expectedEnergy; double expectedEnergy;
computeAmoebaAngleForces( context, amoebaAngleForce, expectedForces, &expectedEnergy, log ); computeAmoebaAngleForces(context, amoebaAngleForce, expectedForces, &expectedEnergy);
State state = context.getState(State::Forces | State::Energy); State state = context.getState(State::Forces | State::Energy);
const std::vector<Vec3> forces = state.getForces(); const std::vector<Vec3> forces = state.getForces();
#ifdef AMOEBA_DEBUG for (unsigned int ii = 0; ii < forces.size(); ii++) {
if( log ){ ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance);
(void) fprintf( log, "computeAmoebaAngleForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() );
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,
expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] );
}
(void) fflush( log );
}
#endif
for( unsigned int ii = 0; ii < forces.size(); ii++ ){
ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance );
} }
ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance);
} }
void testOneAngle( FILE* log ) { void testOneAngle() {
System system; System system;
int numberOfParticles = 3; int numberOfParticles = 3;
for( int ii = 0; ii < numberOfParticles; ii++ ){ for (int ii = 0; ii < numberOfParticles; ii++) {
system.addParticle(1.0); system.addParticle(1.0);
} }
...@@ -289,7 +246,7 @@ void testOneAngle( FILE* log ) { ...@@ -289,7 +246,7 @@ void testOneAngle( FILE* log ) {
amoebaAngleForce->setAmoebaGlobalAngleSextic(sexticK); amoebaAngleForce->setAmoebaGlobalAngleSextic(sexticK);
system.addForce(amoebaAngleForce); system.addForce(amoebaAngleForce);
Context context(system, integrator, Platform::getPlatformByName( "CUDA")); Context context(system, integrator, Platform::getPlatformByName("CUDA"));
std::vector<Vec3> positions(numberOfParticles); std::vector<Vec3> positions(numberOfParticles);
...@@ -298,7 +255,7 @@ void testOneAngle( FILE* log ) { ...@@ -298,7 +255,7 @@ void testOneAngle( FILE* log ) {
positions[2] = Vec3(0, 0, 1); positions[2] = Vec3(0, 0, 1);
context.setPositions(positions); context.setPositions(positions);
compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle", log ); compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle");
// Try changing the angle parameters and make sure it's still correct. // Try changing the angle parameters and make sure it's still correct.
...@@ -306,14 +263,14 @@ void testOneAngle( FILE* log ) { ...@@ -306,14 +263,14 @@ void testOneAngle( FILE* log ) {
bool exceptionThrown = false; bool exceptionThrown = false;
try { try {
// This should throw an exception. // This should throw an exception.
compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle", log ); compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle");
} }
catch (std::exception ex) { catch (std::exception ex) {
exceptionThrown = true; exceptionThrown = true;
} }
ASSERT(exceptionThrown); ASSERT(exceptionThrown);
amoebaAngleForce->updateParametersInContext(context); amoebaAngleForce->updateParametersInContext(context);
compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle", log ); compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle");
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
...@@ -322,8 +279,7 @@ int main(int argc, char* argv[]) { ...@@ -322,8 +279,7 @@ int main(int argc, char* argv[]) {
registerAmoebaCudaKernelFactories(); registerAmoebaCudaKernelFactories();
if (argc > 1) if (argc > 1)
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1]));
FILE* log = NULL; testOneAngle();
testOneAngle( 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;
......
...@@ -48,22 +48,22 @@ extern "C" void registerAmoebaCudaKernelFactories(); ...@@ -48,22 +48,22 @@ extern "C" void registerAmoebaCudaKernelFactories();
const double TOL = 1e-5; const double TOL = 1e-5;
static void computeAmoebaBondForce(int bondIndex, std::vector<Vec3>& positions, AmoebaBondForce& amoebaBondForce, static void computeAmoebaBondForce(int bondIndex, std::vector<Vec3>& positions, AmoebaBondForce& amoebaBondForce,
std::vector<Vec3>& forces, double* energy ) { std::vector<Vec3>& forces, double* energy) {
int particle1, particle2; int particle1, particle2;
double bondLength; double bondLength;
double quadraticK; double quadraticK;
double cubicK = amoebaBondForce.getAmoebaGlobalBondCubic(); double cubicK = amoebaBondForce.getAmoebaGlobalBondCubic();
double quarticK = amoebaBondForce.getAmoebaGlobalBondQuartic(); double quarticK = amoebaBondForce.getAmoebaGlobalBondQuartic();
amoebaBondForce.getBondParameters(bondIndex, particle1, particle2, bondLength, quadraticK ); amoebaBondForce.getBondParameters(bondIndex, particle1, particle2, bondLength, quadraticK);
double deltaR[3]; double deltaR[3];
double r2 = 0.0; double r2 = 0.0;
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaR[ii] = positions[particle2][ii] - positions[particle1][ii]; deltaR[ii] = positions[particle2][ii] - positions[particle1][ii];
r2 += deltaR[ii]*deltaR[ii]; r2 += deltaR[ii]*deltaR[ii];
} }
double r = sqrt( r2 ); double r = sqrt(r2);
double bondDelta = (r - bondLength); double bondDelta = (r - bondLength);
double bondDelta2 = bondDelta*bondDelta; double bondDelta2 = bondDelta*bondDelta;
...@@ -83,66 +83,43 @@ static void computeAmoebaBondForce(int bondIndex, std::vector<Vec3>& positions, ...@@ -83,66 +83,43 @@ static void computeAmoebaBondForce(int bondIndex, std::vector<Vec3>& positions,
} }
static void computeAmoebaBondForces( Context& context, AmoebaBondForce& amoebaBondForce, static void computeAmoebaBondForces(Context& context, AmoebaBondForce& amoebaBondForce,
std::vector<Vec3>& expectedForces, double* expectedEnergy, FILE* log ) { std::vector<Vec3>& expectedForces, double* expectedEnergy) {
// get positions and zero forces // get positions and zero forces
State state = context.getState(State::Positions); State state = context.getState(State::Positions);
std::vector<Vec3> positions = state.getPositions(); std::vector<Vec3> positions = state.getPositions();
expectedForces.resize( positions.size() ); expectedForces.resize(positions.size());
for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ for (unsigned int ii = 0; ii < expectedForces.size(); ii++) {
expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0;
} }
// calculates forces/energy // calculates forces/energy
*expectedEnergy = 0.0; *expectedEnergy = 0.0;
for( int ii = 0; ii < amoebaBondForce.getNumBonds(); ii++ ){ for (int ii = 0; ii < amoebaBondForce.getNumBonds(); ii++) {
computeAmoebaBondForce(ii, positions, amoebaBondForce, expectedForces, expectedEnergy ); computeAmoebaBondForce(ii, positions, amoebaBondForce, expectedForces, expectedEnergy);
} }
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaBondForces: expected energy=%15.7e\n", *expectedEnergy );
for( unsigned int ii = 0; ii < positions.size(); ii++ ){
(void) fprintf( log, "%6u [%15.7e %15.7e %15.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] );
}
(void) fflush( log );
}
#endif
return;
} }
void compareWithExpectedForceAndEnergy( Context& context, AmoebaBondForce& amoebaBondForce, double tolerance, const std::string& idString, FILE* log) { void compareWithExpectedForceAndEnergy(Context& context, AmoebaBondForce& amoebaBondForce, double tolerance, const std::string& idString) {
std::vector<Vec3> expectedForces; std::vector<Vec3> expectedForces;
double expectedEnergy; double expectedEnergy;
computeAmoebaBondForces( context, amoebaBondForce, expectedForces, &expectedEnergy, NULL ); computeAmoebaBondForces(context, amoebaBondForce, expectedForces, &expectedEnergy);
State state = context.getState(State::Forces | State::Energy); State state = context.getState(State::Forces | State::Energy);
const std::vector<Vec3> forces = state.getForces(); const std::vector<Vec3> forces = state.getForces();
#ifdef AMOEBA_DEBUG for (unsigned int ii = 0; ii < forces.size(); ii++) {
if( log ){ ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance);
(void) fprintf( log, "computeAmoebaBondForces: expected energy=%15.7e %15.7e\n", expectedEnergy, state.getPotentialEnergy() );
for( unsigned int ii = 0; ii < forces.size(); ii++ ){
(void) fprintf( log, "%6u [%15.7e %15.7e %15.7e] [%15.7e %15.7e %15.7e]\n", ii,
expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] );
}
(void) fflush( log );
}
#endif
for( unsigned int ii = 0; ii < forces.size(); ii++ ){
ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance );
} }
ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance);
} }
void testOneBond( FILE* log ) { void testOneBond() {
System system; System system;
...@@ -157,22 +134,22 @@ void testOneBond( FILE* log ) { ...@@ -157,22 +134,22 @@ void testOneBond( FILE* log ) {
double quadraticK = 1.0; double quadraticK = 1.0;
double cubicK = 2.0; double cubicK = 2.0;
double quarticicK = 3.0; double quarticicK = 3.0;
amoebaBondForce->setAmoebaGlobalBondCubic( cubicK ); amoebaBondForce->setAmoebaGlobalBondCubic(cubicK);
amoebaBondForce->setAmoebaGlobalBondQuartic( quarticicK ); amoebaBondForce->setAmoebaGlobalBondQuartic(quarticicK);
amoebaBondForce->addBond(0, 1, bondLength, quadraticK); amoebaBondForce->addBond(0, 1, bondLength, quadraticK);
system.addForce(amoebaBondForce); system.addForce(amoebaBondForce);
Context context(system, integrator, Platform::getPlatformByName( "CUDA")); Context context(system, integrator, Platform::getPlatformByName("CUDA"));
std::vector<Vec3> positions(2); std::vector<Vec3> positions(2);
positions[0] = Vec3(0, 1, 0); positions[0] = Vec3(0, 1, 0);
positions[1] = Vec3(0, 0, 0); positions[1] = Vec3(0, 0, 0);
context.setPositions(positions); context.setPositions(positions);
compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testOneBond", log ); compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testOneBond");
} }
void testTwoBond( FILE* log ) { void testTwoBond() {
System system; System system;
...@@ -188,14 +165,14 @@ void testTwoBond( FILE* log ) { ...@@ -188,14 +165,14 @@ void testTwoBond( FILE* log ) {
double quadraticK = 1.0; double quadraticK = 1.0;
double cubicK = 2.0; double cubicK = 2.0;
double quarticicK = 3.0; double quarticicK = 3.0;
amoebaBondForce->setAmoebaGlobalBondCubic( cubicK ); amoebaBondForce->setAmoebaGlobalBondCubic(cubicK);
amoebaBondForce->setAmoebaGlobalBondQuartic( quarticicK ); amoebaBondForce->setAmoebaGlobalBondQuartic(quarticicK);
amoebaBondForce->addBond(0, 1, bondLength, quadraticK); amoebaBondForce->addBond(0, 1, bondLength, quadraticK);
amoebaBondForce->addBond(1, 2, bondLength, quadraticK); amoebaBondForce->addBond(1, 2, bondLength, quadraticK);
system.addForce(amoebaBondForce); system.addForce(amoebaBondForce);
Context context(system, integrator, Platform::getPlatformByName( "CUDA")); Context context(system, integrator, Platform::getPlatformByName("CUDA"));
//Context context(system, integrator, platform ); //Context context(system, integrator, platform);
std::vector<Vec3> positions(3); std::vector<Vec3> positions(3);
positions[0] = Vec3(0, 1, 0); positions[0] = Vec3(0, 1, 0);
...@@ -203,7 +180,7 @@ void testTwoBond( FILE* log ) { ...@@ -203,7 +180,7 @@ void testTwoBond( FILE* log ) {
positions[2] = Vec3(1, 0, 1); positions[2] = Vec3(1, 0, 1);
context.setPositions(positions); context.setPositions(positions);
compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond", log ); compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond");
// Try changing the bond parameters and make sure it's still correct. // Try changing the bond parameters and make sure it's still correct.
...@@ -212,14 +189,14 @@ void testTwoBond( FILE* log ) { ...@@ -212,14 +189,14 @@ void testTwoBond( FILE* log ) {
bool exceptionThrown = false; bool exceptionThrown = false;
try { try {
// This should throw an exception. // This should throw an exception.
compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond", log ); compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond");
} }
catch (std::exception ex) { catch (std::exception ex) {
exceptionThrown = true; exceptionThrown = true;
} }
ASSERT(exceptionThrown); ASSERT(exceptionThrown);
amoebaBondForce->updateParametersInContext(context); amoebaBondForce->updateParametersInContext(context);
compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond", log ); compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond");
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
...@@ -228,8 +205,7 @@ int main(int argc, char* argv[]) { ...@@ -228,8 +205,7 @@ int main(int argc, char* argv[]) {
registerAmoebaCudaKernelFactories(); registerAmoebaCudaKernelFactories();
if (argc > 1) if (argc > 1)
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1]));
FILE* log = NULL; testTwoBond();
testTwoBond( 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;
......
...@@ -63,7 +63,7 @@ const double TOL = 1e-5; ...@@ -63,7 +63,7 @@ const double TOL = 1e-5;
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) {
vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1];
vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2];
...@@ -72,30 +72,23 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto ...@@ -72,30 +72,23 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto
return; return;
} }
static double dotVector3( double* vectorX, double* vectorY ){ static double dotVector3(double* vectorX, double* vectorY) {
return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2];
} }
static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInPlaneAngle, double quadraticK, double cubicK, static void getPrefactorsGivenInPlaneAngleCosine(double cosine, double idealInPlaneAngle, double quadraticK, double cubicK,
double quarticK, double penticK, double sexticK, double quarticK, double penticK, double sexticK,
double* dEdR, double* energyTerm, FILE* log ) { double* dEdR, double* energyTerm) {
double angle; double angle;
if( cosine >= 1.0 ){ if (cosine >= 1.0) {
angle = 0.0f; angle = 0.0f;
} else if( cosine <= -1.0 ){ } else if (cosine <= -1.0) {
angle = RADIAN*PI_M; angle = RADIAN*PI_M;
} else { } else {
angle = RADIAN*acos(cosine); angle = RADIAN*acos(cosine);
} }
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "getPrefactorsGivenInPlaneAngleCosine: cosine=%10.3e angle=%10.3e ideal=%10.3e\n", cosine, angle, idealInPlaneAngle );
(void) fflush( log );
}
#endif
double deltaIdeal = angle - idealInPlaneAngle; double deltaIdeal = angle - idealInPlaneAngle;
double deltaIdeal2 = deltaIdeal*deltaIdeal; double deltaIdeal2 = deltaIdeal*deltaIdeal;
double deltaIdeal3 = deltaIdeal*deltaIdeal2; double deltaIdeal3 = deltaIdeal*deltaIdeal2;
...@@ -103,11 +96,11 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP ...@@ -103,11 +96,11 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP
// deltaIdeal = r - r_0 // deltaIdeal = r - r_0
*dEdR = ( 2.0 + *dEdR = (2.0 +
3.0*cubicK* deltaIdeal + 3.0*cubicK* deltaIdeal +
4.0*quarticK*deltaIdeal2 + 4.0*quarticK*deltaIdeal2 +
5.0*penticK* deltaIdeal3 + 5.0*penticK* deltaIdeal3 +
6.0*sexticK* deltaIdeal4 ); 6.0*sexticK* deltaIdeal4 );
*dEdR *= RADIAN*quadraticK*deltaIdeal; *dEdR *= RADIAN*quadraticK*deltaIdeal;
...@@ -122,26 +115,18 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP ...@@ -122,26 +115,18 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP
} }
static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector<Vec3>& positions, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector<Vec3>& positions, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce,
std::vector<Vec3>& forces, double* energy, FILE* log ) { std::vector<Vec3>& forces, double* energy) {
int particle1, particle2, particle3, particle4; int particle1, particle2, particle3, particle4;
double idealInPlaneAngle; double idealInPlaneAngle;
double quadraticK; double quadraticK;
amoebaInPlaneAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK ); amoebaInPlaneAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK);
double cubicK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleCubic(); double cubicK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleCubic();
double quarticK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleQuartic(); double quarticK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleQuartic();
double penticK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAnglePentic(); double penticK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAnglePentic();
double sexticK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleSextic(); double sexticK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleSextic();
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaInPlaneAngleForce: bond %d [%d %d %d %d] ang=%10.3f k=%10.3f [%10.3e %10.3e %10.3e %10.3e]\n",
bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK, cubicK, quarticK, penticK, sexticK );
(void) fflush( log );
}
#endif
// T = AD x CD // T = AD x CD
// P = B + T*delta // P = B + T*delta
// AP = A - P // AP = A - P
...@@ -161,83 +146,75 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector<Vec3>& po ...@@ -161,83 +146,75 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector<Vec3>& po
// APxM, CPxM, ADxBD, BDxCD, TxCD, ADxT, dBxAD, CDxdB, LastDeltaAtomIndex // APxM, CPxM, ADxBD, BDxCD, TxCD, ADxT, dBxAD, CDxdB, LastDeltaAtomIndex
double deltaR[LastDeltaAtomIndex][3]; double deltaR[LastDeltaAtomIndex][3];
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaR[AD][ii] = positions[particle1][ii] - positions[particle4][ii]; deltaR[AD][ii] = positions[particle1][ii] - positions[particle4][ii];
deltaR[BD][ii] = positions[particle2][ii] - positions[particle4][ii]; deltaR[BD][ii] = positions[particle2][ii] - positions[particle4][ii];
deltaR[CD][ii] = positions[particle3][ii] - positions[particle4][ii]; deltaR[CD][ii] = positions[particle3][ii] - positions[particle4][ii];
} }
crossProductVector3( deltaR[AD], deltaR[CD], deltaR[T] ); crossProductVector3(deltaR[AD], deltaR[CD], deltaR[T]);
double rT2 = dotVector3( deltaR[T], deltaR[T] ); double rT2 = dotVector3(deltaR[T], deltaR[T]);
double delta = dotVector3( deltaR[T], deltaR[BD] ); double delta = dotVector3(deltaR[T], deltaR[BD]);
delta *= -1.0/rT2; delta *= -1.0/rT2;
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaR[P][ii] = positions[particle2][ii] + deltaR[T][ii]*delta; deltaR[P][ii] = positions[particle2][ii] + deltaR[T][ii]*delta;
deltaR[AP][ii] = positions[particle1][ii] - deltaR[P][ii]; deltaR[AP][ii] = positions[particle1][ii] - deltaR[P][ii];
deltaR[CP][ii] = positions[particle3][ii] - deltaR[P][ii]; deltaR[CP][ii] = positions[particle3][ii] - deltaR[P][ii];
} }
double rAp2 = dotVector3( deltaR[AP], deltaR[AP] ); double rAp2 = dotVector3(deltaR[AP], deltaR[AP]);
double rCp2 = dotVector3( deltaR[CP], deltaR[CP] ); double rCp2 = dotVector3(deltaR[CP], deltaR[CP]);
if( rAp2 <= 0.0 && rCp2 <= 0.0 ){ if (rAp2 <= 0.0 && rCp2 <= 0.0) {
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaInPlaneAngleForce: rAp2 or rCp2 <= 0.0\n" );
(void) fflush( log );
}
#endif
return;
} }
crossProductVector3( deltaR[CP], deltaR[AP], deltaR[M] ); crossProductVector3(deltaR[CP], deltaR[AP], deltaR[M]);
double rm = dotVector3( deltaR[M], deltaR[M] ); double rm = dotVector3(deltaR[M], deltaR[M]);
rm = sqrt( rm ); rm = sqrt(rm);
if( rm < 0.000001 ){ if (rm < 0.000001) {
rm = 0.000001; rm = 0.000001;
} }
double dot = dotVector3( deltaR[AP], deltaR[CP] ); double dot = dotVector3(deltaR[AP], deltaR[CP]);
double cosine = dot/sqrt( rAp2*rCp2 ); double cosine = dot/sqrt(rAp2*rCp2);
double dEdR; double dEdR;
double energyTerm; double energyTerm;
getPrefactorsGivenInPlaneAngleCosine( cosine, idealInPlaneAngle, quadraticK, cubicK, getPrefactorsGivenInPlaneAngleCosine(cosine, idealInPlaneAngle, quadraticK, cubicK,
quarticK, penticK, sexticK, &dEdR, &energyTerm, log ); quarticK, penticK, sexticK, &dEdR, &energyTerm);
double termA = -dEdR/(rAp2*rm); double termA = -dEdR/(rAp2*rm);
double termC = dEdR/(rCp2*rm); double termC = dEdR/(rCp2*rm);
crossProductVector3( deltaR[AP], deltaR[M], deltaR[APxM] ); crossProductVector3(deltaR[AP], deltaR[M], deltaR[APxM]);
crossProductVector3( deltaR[CP], deltaR[M], deltaR[CPxM] ); crossProductVector3(deltaR[CP], deltaR[M], deltaR[CPxM]);
// forces will be gathered here // forces will be gathered here
enum { dA, dB, dC, dD, LastDIndex }; enum { dA, dB, dC, dD, LastDIndex };
double forceTerm[LastDIndex][3]; double forceTerm[LastDIndex][3];
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
forceTerm[dA][ii] = deltaR[APxM][ii]*termA; forceTerm[dA][ii] = deltaR[APxM][ii]*termA;
forceTerm[dC][ii] = deltaR[CPxM][ii]*termC; forceTerm[dC][ii] = deltaR[CPxM][ii]*termC;
forceTerm[dB][ii] = -1.0*( forceTerm[dA][ii] + forceTerm[dC][ii] ); forceTerm[dB][ii] = -1.0*(forceTerm[dA][ii] + forceTerm[dC][ii]);
} }
double pTrT2 = dotVector3( forceTerm[dB], deltaR[T] ); double pTrT2 = dotVector3(forceTerm[dB], deltaR[T]);
pTrT2 /= rT2; pTrT2 /= rT2;
crossProductVector3( deltaR[CD], forceTerm[dB], deltaR[CDxdB] ); crossProductVector3(deltaR[CD], forceTerm[dB], deltaR[CDxdB]);
crossProductVector3( forceTerm[dB], deltaR[AD], deltaR[dBxAD] ); crossProductVector3(forceTerm[dB], deltaR[AD], deltaR[dBxAD]);
if( fabs( pTrT2 ) > 1.0e-08 ){ if (fabs(pTrT2) > 1.0e-08) {
double delta2 = delta*2.0; double delta2 = delta*2.0;
crossProductVector3( deltaR[BD], deltaR[CD], deltaR[BDxCD] ); crossProductVector3(deltaR[BD], deltaR[CD], deltaR[BDxCD]);
crossProductVector3( deltaR[T], deltaR[CD], deltaR[TxCD] ); crossProductVector3(deltaR[T], deltaR[CD], deltaR[TxCD] );
crossProductVector3( deltaR[AD], deltaR[BD], deltaR[ADxBD] ); crossProductVector3(deltaR[AD], deltaR[BD], deltaR[ADxBD]);
crossProductVector3( deltaR[AD], deltaR[T], deltaR[ADxT] ); crossProductVector3(deltaR[AD], deltaR[T], deltaR[ADxT] );
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
double term = deltaR[BDxCD][ii] + delta2*deltaR[TxCD][ii]; double term = deltaR[BDxCD][ii] + delta2*deltaR[TxCD][ii];
forceTerm[dA][ii] += delta*deltaR[CDxdB][ii] + term*pTrT2; forceTerm[dA][ii] += delta*deltaR[CDxdB][ii] + term*pTrT2;
...@@ -245,15 +222,15 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector<Vec3>& po ...@@ -245,15 +222,15 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector<Vec3>& po
term = deltaR[ADxBD][ii] + delta2*deltaR[ADxT][ii]; term = deltaR[ADxBD][ii] + delta2*deltaR[ADxT][ii];
forceTerm[dC][ii] += delta*deltaR[dBxAD][ii] + term*pTrT2; forceTerm[dC][ii] += delta*deltaR[dBxAD][ii] + term*pTrT2;
forceTerm[dD][ii] = -( forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii] ); forceTerm[dD][ii] = -(forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii]);
} }
} else { } else {
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
forceTerm[dA][ii] += delta*deltaR[CDxdB][ii]; forceTerm[dA][ii] += delta*deltaR[CDxdB][ii];
forceTerm[dC][ii] += delta*deltaR[dBxAD][ii]; forceTerm[dC][ii] += delta*deltaR[dBxAD][ii];
forceTerm[dD][ii] = -( forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii] ); forceTerm[dD][ii] = -(forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii]);
} }
} }
...@@ -279,71 +256,47 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector<Vec3>& po ...@@ -279,71 +256,47 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector<Vec3>& po
} }
static void computeAmoebaInPlaneAngleForces( Context& context, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, static void computeAmoebaInPlaneAngleForces(Context& context, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce,
std::vector<Vec3>& expectedForces, double* expectedEnergy, FILE* log ) { std::vector<Vec3>& expectedForces, double* expectedEnergy) {
// get positions and zero forces // get positions and zero forces
State state = context.getState(State::Positions); State state = context.getState(State::Positions);
std::vector<Vec3> positions = state.getPositions(); std::vector<Vec3> positions = state.getPositions();
expectedForces.resize( positions.size() ); expectedForces.resize(positions.size());
for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ for (unsigned int ii = 0; ii < expectedForces.size(); ii++) {
expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0;
} }
// calculates forces/energy // calculates forces/energy
*expectedEnergy = 0.0; *expectedEnergy = 0.0;
for( int ii = 0; ii < amoebaInPlaneAngleForce.getNumAngles(); ii++ ){ for (int ii = 0; ii < amoebaInPlaneAngleForce.getNumAngles(); ii++) {
computeAmoebaInPlaneAngleForce(ii, positions, amoebaInPlaneAngleForce, expectedForces, expectedEnergy, log ); computeAmoebaInPlaneAngleForce(ii, positions, amoebaInPlaneAngleForce, expectedForces, expectedEnergy);
}
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaInPlaneAngleForces: expected energy=%14.7e\n", *expectedEnergy );
for( unsigned int ii = 0; ii < positions.size(); ii++ ){
(void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] );
}
(void) fflush( log );
} }
#endif
return;
} }
void compareWithExpectedForceAndEnergy( Context& context, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, void compareWithExpectedForceAndEnergy(Context& context, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce,
double tolerance, const std::string& idString, FILE* log) { double tolerance, const std::string& idString) {
std::vector<Vec3> expectedForces; std::vector<Vec3> expectedForces;
double expectedEnergy; double expectedEnergy;
computeAmoebaInPlaneAngleForces( context, amoebaInPlaneAngleForce, expectedForces, &expectedEnergy, log ); computeAmoebaInPlaneAngleForces(context, amoebaInPlaneAngleForce, expectedForces, &expectedEnergy);
State state = context.getState(State::Forces | State::Energy); State state = context.getState(State::Forces | State::Energy);
const std::vector<Vec3> forces = state.getForces(); const std::vector<Vec3> forces = state.getForces();
for (unsigned int ii = 0; ii < forces.size(); ii++) {
#ifdef AMOEBA_DEBUG ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance);
if( log ){
(void) fprintf( log, "computeAmoebaInPlaneAngleForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() );
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,
expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] );
}
(void) fflush( log );
}
#endif
for( unsigned int ii = 0; ii < forces.size(); ii++ ){
ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance );
} }
ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance);
} }
void testOneAngle( FILE* log ) { void testOneAngle() {
System system; System system;
int numberOfParticles = 4; int numberOfParticles = 4;
for( int ii = 0; ii < numberOfParticles; ii++ ){ for (int ii = 0; ii < numberOfParticles; ii++) {
system.addParticle(1.0); system.addParticle(1.0);
} }
...@@ -365,7 +318,7 @@ void testOneAngle( FILE* log ) { ...@@ -365,7 +318,7 @@ void testOneAngle( FILE* log ) {
amoebaInPlaneAngleForce->setAmoebaGlobalInPlaneAngleSextic(sexticK); amoebaInPlaneAngleForce->setAmoebaGlobalInPlaneAngleSextic(sexticK);
system.addForce(amoebaInPlaneAngleForce); system.addForce(amoebaInPlaneAngleForce);
Context context(system, integrator, Platform::getPlatformByName( "CUDA")); Context context(system, integrator, Platform::getPlatformByName("CUDA"));
std::vector<Vec3> positions(numberOfParticles); std::vector<Vec3> positions(numberOfParticles);
...@@ -375,7 +328,7 @@ void testOneAngle( FILE* log ) { ...@@ -375,7 +328,7 @@ void testOneAngle( FILE* log ) {
positions[3] = Vec3(1, 1, 1); positions[3] = Vec3(1, 1, 1);
context.setPositions(positions); context.setPositions(positions);
compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log ); compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle");
// Try changing the angle parameters and make sure it's still correct. // Try changing the angle parameters and make sure it's still correct.
...@@ -383,14 +336,14 @@ void testOneAngle( FILE* log ) { ...@@ -383,14 +336,14 @@ void testOneAngle( FILE* log ) {
bool exceptionThrown = false; bool exceptionThrown = false;
try { try {
// This should throw an exception. // This should throw an exception.
compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log ); compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle");
} }
catch (std::exception ex) { catch (std::exception ex) {
exceptionThrown = true; exceptionThrown = true;
} }
ASSERT(exceptionThrown); ASSERT(exceptionThrown);
amoebaInPlaneAngleForce->updateParametersInContext(context); amoebaInPlaneAngleForce->updateParametersInContext(context);
compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log ); compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle");
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
...@@ -399,8 +352,7 @@ int main(int argc, char* argv[]) { ...@@ -399,8 +352,7 @@ int main(int argc, char* argv[]) {
registerAmoebaCudaKernelFactories(); registerAmoebaCudaKernelFactories();
if (argc > 1) if (argc > 1)
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1]));
FILE* log = NULL; testOneAngle();
testOneAngle( NULL );
} 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;
......
...@@ -63,7 +63,7 @@ const double TOL = 1e-5; ...@@ -63,7 +63,7 @@ const double TOL = 1e-5;
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) {
vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1];
vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2];
...@@ -72,43 +72,35 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto ...@@ -72,43 +72,35 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto
return; return;
} }
static double dotVector3( double* vectorX, double* vectorY ){ static double dotVector3(double* vectorX, double* vectorY) {
return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2];
} }
static void computeAmoebaPiTorsionForce(int bondIndex, std::vector<Vec3>& positions, AmoebaPiTorsionForce& amoebaPiTorsionForce, static void computeAmoebaPiTorsionForce(int bondIndex, std::vector<Vec3>& positions, AmoebaPiTorsionForce& amoebaPiTorsionForce,
std::vector<Vec3>& forces, double* energy, FILE* log ) { std::vector<Vec3>& forces, double* energy) {
int particle1, particle2, particle3, particle4, particle5, particle6; int particle1, particle2, particle3, particle4, particle5, particle6;
double kTorsion; double kTorsion;
amoebaPiTorsionForce.getPiTorsionParameters(bondIndex, particle1, particle2, particle3, particle4, particle5, particle6, kTorsion); amoebaPiTorsionForce.getPiTorsionParameters(bondIndex, particle1, particle2, particle3, particle4, particle5, particle6, kTorsion);
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaPiTorsionForce: bond %d [%d %d %d %d %d %d] k=%10.3e\n",
bondIndex, particle1, particle2, particle3, particle4, particle5, particle6, kTorsion );
(void) fflush( log );
}
#endif
enum { AD, BD, EC, FC, P, Q, CP, DC, QD, T, U, TU, DP, QC, dT, dU, dP, dQ, dC1, dC2, dD1, dD2, LastDeltaIndex }; enum { AD, BD, EC, FC, P, Q, CP, DC, QD, T, U, TU, DP, QC, dT, dU, dP, dQ, dC1, dC2, dD1, dD2, LastDeltaIndex };
double deltaR[LastDeltaIndex][3]; double deltaR[LastDeltaIndex][3];
enum { A, B, C, D, E, F, LastAtomIndex }; enum { A, B, C, D, E, F, LastAtomIndex };
double d[LastAtomIndex][3]; double d[LastAtomIndex][3];
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaR[AD][ii] = positions[particle1][ii] - positions[particle4][ii]; deltaR[AD][ii] = positions[particle1][ii] - positions[particle4][ii];
deltaR[BD][ii] = positions[particle2][ii] - positions[particle4][ii]; deltaR[BD][ii] = positions[particle2][ii] - positions[particle4][ii];
deltaR[EC][ii] = positions[particle5][ii] - positions[particle3][ii]; deltaR[EC][ii] = positions[particle5][ii] - positions[particle3][ii];
deltaR[FC][ii] = positions[particle6][ii] - positions[particle3][ii]; deltaR[FC][ii] = positions[particle6][ii] - positions[particle3][ii];
} }
crossProductVector3( deltaR[AD], deltaR[BD], deltaR[P] ); crossProductVector3(deltaR[AD], deltaR[BD], deltaR[P]);
crossProductVector3( deltaR[EC], deltaR[FC], deltaR[Q] ); crossProductVector3(deltaR[EC], deltaR[FC], deltaR[Q]);
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaR[CP][ii] = -deltaR[P][ii]; deltaR[CP][ii] = -deltaR[P][ii];
deltaR[DC][ii] = positions[particle4][ii] - positions[particle3][ii]; deltaR[DC][ii] = positions[particle4][ii] - positions[particle3][ii];
deltaR[QD][ii] = deltaR[Q][ii]; deltaR[QD][ii] = deltaR[Q][ii];
...@@ -116,25 +108,25 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector<Vec3>& posit ...@@ -116,25 +108,25 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector<Vec3>& posit
deltaR[P][ii] += positions[particle3][ii]; deltaR[P][ii] += positions[particle3][ii];
deltaR[Q][ii] += positions[particle4][ii]; deltaR[Q][ii] += positions[particle4][ii];
} }
crossProductVector3( deltaR[CP], deltaR[DC], deltaR[T] ); crossProductVector3(deltaR[CP], deltaR[DC], deltaR[T] );
crossProductVector3( deltaR[DC], deltaR[QD], deltaR[U] ); crossProductVector3(deltaR[DC], deltaR[QD], deltaR[U] );
crossProductVector3( deltaR[T], deltaR[U], deltaR[TU] ); crossProductVector3(deltaR[T], deltaR[U], deltaR[TU]);
double rT2 = dotVector3( deltaR[T], deltaR[T] ); double rT2 = dotVector3(deltaR[T], deltaR[T]);
double rU2 = dotVector3( deltaR[U], deltaR[U] ); double rU2 = dotVector3(deltaR[U], deltaR[U]);
double rTrU = sqrt( rT2*rU2 ); double rTrU = sqrt(rT2*rU2);
if( rTrU <= 0.0 ){ if (rTrU <= 0.0) {
return; return;
} }
double rDC = dotVector3( deltaR[DC], deltaR[DC] ); double rDC = dotVector3(deltaR[DC], deltaR[DC]);
rDC = sqrt( rDC ); rDC = sqrt(rDC);
double cosine = dotVector3( deltaR[T], deltaR[U] ); double cosine = dotVector3(deltaR[T], deltaR[U]);
cosine /= rTrU; cosine /= rTrU;
double sine = dotVector3( deltaR[DC], deltaR[TU] ); double sine = dotVector3(deltaR[DC], deltaR[TU]);
sine /= ( rDC*rTrU ); sine /= (rDC*rTrU);
double cosine2 = cosine*cosine - sine*sine; double cosine2 = cosine*cosine - sine*sine;
double sine2 = 2.0*cosine*sine; double sine2 = 2.0*cosine*sine;
...@@ -144,37 +136,37 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector<Vec3>& posit ...@@ -144,37 +136,37 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector<Vec3>& posit
double dedphi = kTorsion*dphi2; double dedphi = kTorsion*dphi2;
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaR[DP][ii] = positions[particle4][ii] - deltaR[P][ii]; deltaR[DP][ii] = positions[particle4][ii] - deltaR[P][ii];
deltaR[QC][ii] = deltaR[Q][ii] - positions[particle3][ii]; deltaR[QC][ii] = deltaR[Q][ii] - positions[particle3][ii];
} }
double factorT = dedphi/( rDC*rT2 ); double factorT = dedphi/(rDC*rT2);
double factorU = -dedphi/( rDC*rU2 ); double factorU = -dedphi/(rDC*rU2);
crossProductVector3( deltaR[T], deltaR[DC], deltaR[dT] ); crossProductVector3(deltaR[T], deltaR[DC], deltaR[dT] );
crossProductVector3( deltaR[U], deltaR[DC], deltaR[dU] ); crossProductVector3(deltaR[U], deltaR[DC], deltaR[dU] );
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaR[dT][ii] *= factorT; deltaR[dT][ii] *= factorT;
deltaR[dU][ii] *= factorU; deltaR[dU][ii] *= factorU;
} }
crossProductVector3( deltaR[dT], deltaR[DC], deltaR[dP] ); crossProductVector3(deltaR[dT], deltaR[DC], deltaR[dP] );
crossProductVector3( deltaR[dU], deltaR[DC], deltaR[dQ] ); crossProductVector3(deltaR[dU], deltaR[DC], deltaR[dQ] );
crossProductVector3( deltaR[DP], deltaR[dT], deltaR[dC1] ); crossProductVector3(deltaR[DP], deltaR[dT], deltaR[dC1] );
crossProductVector3( deltaR[dU], deltaR[QD], deltaR[dC2] ); crossProductVector3(deltaR[dU], deltaR[QD], deltaR[dC2] );
crossProductVector3( deltaR[dT], deltaR[CP], deltaR[dD1] ); crossProductVector3(deltaR[dT], deltaR[CP], deltaR[dD1] );
crossProductVector3( deltaR[QC], deltaR[dU], deltaR[dD2] ); crossProductVector3(deltaR[QC], deltaR[dU], deltaR[dD2] );
crossProductVector3( deltaR[BD], deltaR[dP], d[A] ); crossProductVector3(deltaR[BD], deltaR[dP], d[A] );
crossProductVector3( deltaR[dP], deltaR[AD], d[B] ); crossProductVector3(deltaR[dP], deltaR[AD], d[B] );
crossProductVector3( deltaR[FC], deltaR[dQ], d[E] ); crossProductVector3(deltaR[FC], deltaR[dQ], d[E] );
crossProductVector3( deltaR[dQ], deltaR[EC], d[F] ); crossProductVector3(deltaR[dQ], deltaR[EC], d[F] );
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
d[C][ii] = deltaR[dC1][ii] + deltaR[dC2][ii] + deltaR[dP][ii] - d[E][ii] - d[F][ii]; d[C][ii] = deltaR[dC1][ii] + deltaR[dC2][ii] + deltaR[dP][ii] - d[E][ii] - d[F][ii];
d[D][ii] = deltaR[dD1][ii] + deltaR[dD2][ii] + deltaR[dQ][ii] - d[A][ii] - d[B][ii]; d[D][ii] = deltaR[dD1][ii] + deltaR[dD2][ii] + deltaR[dQ][ii] - d[A][ii] - d[B][ii];
} }
...@@ -212,71 +204,48 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector<Vec3>& posit ...@@ -212,71 +204,48 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector<Vec3>& posit
return; return;
} }
static void computeAmoebaPiTorsionForces( Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, static void computeAmoebaPiTorsionForces(Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce,
std::vector<Vec3>& expectedForces, double* expectedEnergy, FILE* log ) { std::vector<Vec3>& expectedForces, double* expectedEnergy) {
// get positions and zero forces // get positions and zero forces
State state = context.getState(State::Positions); State state = context.getState(State::Positions);
std::vector<Vec3> positions = state.getPositions(); std::vector<Vec3> positions = state.getPositions();
expectedForces.resize( positions.size() ); expectedForces.resize(positions.size());
for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ for (unsigned int ii = 0; ii < expectedForces.size(); ii++) {
expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0;
} }
// calculates forces/energy // calculates forces/energy
*expectedEnergy = 0.0; *expectedEnergy = 0.0;
for( int ii = 0; ii < amoebaPiTorsionForce.getNumPiTorsions(); ii++ ){ for (int ii = 0; ii < amoebaPiTorsionForce.getNumPiTorsions(); ii++) {
computeAmoebaPiTorsionForce(ii, positions, amoebaPiTorsionForce, expectedForces, expectedEnergy, log ); computeAmoebaPiTorsionForce(ii, positions, amoebaPiTorsionForce, expectedForces, expectedEnergy);
}
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaPiTorsionForces: expected energy=%14.7e\n", *expectedEnergy );
for( unsigned int ii = 0; ii < positions.size(); ii++ ){
(void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] );
}
(void) fflush( log );
} }
#endif
return;
} }
void compareWithExpectedForceAndEnergy( Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, void compareWithExpectedForceAndEnergy(Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce,
double tolerance, const std::string& idString, FILE* log) { double tolerance, const std::string& idString) {
std::vector<Vec3> expectedForces; std::vector<Vec3> expectedForces;
double expectedEnergy; double expectedEnergy;
computeAmoebaPiTorsionForces( context, amoebaPiTorsionForce, expectedForces, &expectedEnergy, log ); computeAmoebaPiTorsionForces(context, amoebaPiTorsionForce, expectedForces, &expectedEnergy);
State state = context.getState(State::Forces | State::Energy); State state = context.getState(State::Forces | State::Energy);
const std::vector<Vec3> forces = state.getForces(); const std::vector<Vec3> forces = state.getForces();
#ifdef AMOEBA_DEBUG for (unsigned int ii = 0; ii < forces.size(); ii++) {
if( log ){ ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance);
(void) fprintf( log, "computeAmoebaPiTorsionForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() );
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,
expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] );
}
(void) fflush( log );
}
#endif
for( unsigned int ii = 0; ii < forces.size(); ii++ ){
ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance );
} }
ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance);
} }
void testOnePiTorsion( FILE* log ) { void testOnePiTorsion() {
System system; System system;
int numberOfParticles = 6; int numberOfParticles = 6;
for( int ii = 0; ii < numberOfParticles; ii++ ){ for (int ii = 0; ii < numberOfParticles; ii++) {
system.addParticle(1.0); system.addParticle(1.0);
} }
...@@ -285,23 +254,23 @@ void testOnePiTorsion( FILE* log ) { ...@@ -285,23 +254,23 @@ void testOnePiTorsion( FILE* log ) {
AmoebaPiTorsionForce* amoebaPiTorsionForce = new AmoebaPiTorsionForce(); AmoebaPiTorsionForce* amoebaPiTorsionForce = new AmoebaPiTorsionForce();
double kTorsion = 6.85; double kTorsion = 6.85;
amoebaPiTorsionForce->addPiTorsion(0, 1, 2, 3, 4, 5, kTorsion ); amoebaPiTorsionForce->addPiTorsion(0, 1, 2, 3, 4, 5, kTorsion);
system.addForce(amoebaPiTorsionForce); system.addForce(amoebaPiTorsionForce);
Context context(system, integrator, Platform::getPlatformByName( "CUDA")); Context context(system, integrator, Platform::getPlatformByName("CUDA"));
std::vector<Vec3> positions(numberOfParticles); std::vector<Vec3> positions(numberOfParticles);
positions[0] = Vec3( 0.262660000E+02, 0.254130000E+02, 0.284200000E+01 ); positions[0] = Vec3(0.262660000E+02, 0.254130000E+02, 0.284200000E+01);
positions[1] = Vec3( 0.278860000E+02, 0.264630000E+02, 0.426300000E+01 ); positions[1] = Vec3(0.278860000E+02, 0.264630000E+02, 0.426300000E+01);
positions[2] = Vec3( 0.269130000E+02, 0.266390000E+02, 0.353100000E+01 ); positions[2] = Vec3(0.269130000E+02, 0.266390000E+02, 0.353100000E+01);
positions[3] = Vec3( 0.245568230E+02, 0.250215290E+02, 0.796852800E+01 ); positions[3] = Vec3(0.245568230E+02, 0.250215290E+02, 0.796852800E+01);
positions[4] = Vec3( 0.261000000E+02, 0.292530000E+02, 0.520200000E+01 ); positions[4] = Vec3(0.261000000E+02, 0.292530000E+02, 0.520200000E+01);
positions[5] = Vec3( 0.254124630E+02, 0.234691880E+02, 0.773335400E+01 ); positions[5] = Vec3(0.254124630E+02, 0.234691880E+02, 0.773335400E+01);
context.setPositions(positions); context.setPositions(positions);
compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log ); compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion");
// Try changing the torsion parameters and make sure it's still correct. // Try changing the torsion parameters and make sure it's still correct.
...@@ -309,14 +278,14 @@ void testOnePiTorsion( FILE* log ) { ...@@ -309,14 +278,14 @@ void testOnePiTorsion( FILE* log ) {
bool exceptionThrown = false; bool exceptionThrown = false;
try { try {
// This should throw an exception. // This should throw an exception.
compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log ); compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion");
} }
catch (std::exception ex) { catch (std::exception ex) {
exceptionThrown = true; exceptionThrown = true;
} }
ASSERT(exceptionThrown); ASSERT(exceptionThrown);
amoebaPiTorsionForce->updateParametersInContext(context); amoebaPiTorsionForce->updateParametersInContext(context);
compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log ); compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion");
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
...@@ -325,8 +294,7 @@ int main(int argc, char* argv[]) { ...@@ -325,8 +294,7 @@ int main(int argc, char* argv[]) {
registerAmoebaCudaKernelFactories(); registerAmoebaCudaKernelFactories();
if (argc > 1) if (argc > 1)
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1]));
FILE* log = NULL; testOnePiTorsion();
testOnePiTorsion( 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;
......
...@@ -64,7 +64,7 @@ const double DegreesToRadians = PI_M/180.0; ...@@ -64,7 +64,7 @@ const double DegreesToRadians = PI_M/180.0;
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) {
vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1];
vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2];
...@@ -73,27 +73,19 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto ...@@ -73,27 +73,19 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto
return; return;
} }
static double dotVector3( double* vectorX, double* vectorY ){ static double dotVector3(double* vectorX, double* vectorY) {
return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2];
} }
static void computeAmoebaStretchBendForce(int bondIndex, std::vector<Vec3>& positions, AmoebaStretchBendForce& amoebaStretchBendForce, static void computeAmoebaStretchBendForce(int bondIndex, std::vector<Vec3>& positions, AmoebaStretchBendForce& amoebaStretchBendForce,
std::vector<Vec3>& forces, double* energy, FILE* log ) { std::vector<Vec3>& forces, double* energy) {
int particle1, particle2, particle3; int particle1, particle2, particle3;
double abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend; double abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend;
amoebaStretchBendForce.getStretchBendParameters(bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend); amoebaStretchBendForce.getStretchBendParameters(bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend);
angleStretchBend *= RADIAN; angleStretchBend *= RADIAN;
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaStretchBendForce: bond %d [%d %d %d] ab=%10.3e cb=%10.3e angle=%10.3e k1=%10.3e k2=%10.3e\n",
bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend );
(void) fflush( log );
}
#endif
enum { A, B, C, LastAtomIndex }; enum { A, B, C, LastAtomIndex };
enum { AB, CB, CBxAB, ABxP, CBxP, LastDeltaIndex }; enum { AB, CB, CBxAB, ABxP, CBxP, LastDeltaIndex };
...@@ -105,31 +97,31 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector<Vec3>& pos ...@@ -105,31 +97,31 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector<Vec3>& pos
double deltaR[LastDeltaIndex][3]; double deltaR[LastDeltaIndex][3];
double rAB2 = 0.0; double rAB2 = 0.0;
double rCB2 = 0.0; double rCB2 = 0.0;
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaR[AB][ii] = positions[particle1][ii] - positions[particle2][ii]; deltaR[AB][ii] = positions[particle1][ii] - positions[particle2][ii];
rAB2 += deltaR[AB][ii]*deltaR[AB][ii]; rAB2 += deltaR[AB][ii]*deltaR[AB][ii];
deltaR[CB][ii] = positions[particle3][ii] - positions[particle2][ii]; deltaR[CB][ii] = positions[particle3][ii] - positions[particle2][ii];
rCB2 += deltaR[CB][ii]*deltaR[CB][ii]; rCB2 += deltaR[CB][ii]*deltaR[CB][ii];
} }
double rAB = sqrt( rAB2 ); double rAB = sqrt(rAB2);
double rCB = sqrt( rCB2 ); double rCB = sqrt(rCB2);
crossProductVector3( deltaR[CB], deltaR[AB], deltaR[CBxAB] ); crossProductVector3(deltaR[CB], deltaR[AB], deltaR[CBxAB]);
double rP = dotVector3( deltaR[CBxAB], deltaR[CBxAB] ); double rP = dotVector3(deltaR[CBxAB], deltaR[CBxAB]);
rP = sqrt( rP ); rP = sqrt(rP);
if( rP <= 0.0 ){ if (rP <= 0.0) {
return; return;
} }
double dot = dotVector3( deltaR[CB], deltaR[AB] ); double dot = dotVector3(deltaR[CB], deltaR[AB]);
double cosine = dot/(rAB*rCB); double cosine = dot/(rAB*rCB);
double angle; double angle;
if( cosine >= 1.0 ){ if (cosine >= 1.0) {
angle = 0.0; angle = 0.0;
} }
else if( cosine <= -1.0 ){ else if (cosine <= -1.0) {
angle = PI_M; angle = PI_M;
} }
else { else {
...@@ -141,9 +133,9 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector<Vec3>& pos ...@@ -141,9 +133,9 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector<Vec3>& pos
// P = CBxAB // P = CBxAB
crossProductVector3( deltaR[AB], deltaR[CBxAB], deltaR[ABxP] ); crossProductVector3(deltaR[AB], deltaR[CBxAB], deltaR[ABxP]);
crossProductVector3( deltaR[CB], deltaR[CBxAB], deltaR[CBxP] ); crossProductVector3(deltaR[CB], deltaR[CBxAB], deltaR[CBxP]);
for( int ii = 0; ii < 3; ii++ ){ for (int ii = 0; ii < 3; ii++) {
deltaR[ABxP][ii] *= termA; deltaR[ABxP][ii] *= termA;
deltaR[CBxP][ii] *= termC; deltaR[CBxP][ii] *= termC;
} }
...@@ -161,14 +153,14 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector<Vec3>& pos ...@@ -161,14 +153,14 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector<Vec3>& pos
// forces // forces
// calculate forces for atoms a, b, c // calculate forces for atoms a, b, c
// the force for b is then -( a + c) // the force for b is then -(a + c)
double subForce[LastAtomIndex][3]; double subForce[LastAtomIndex][3];
double dt = angle - angleStretchBend; double dt = angle - angleStretchBend;
for( int jj = 0; jj < 3; jj++ ){ for (int jj = 0; jj < 3; jj++) {
subForce[A][jj] = kStretchBend*dt*termA*deltaR[AB][jj] + drkk*deltaR[ABxP][jj]; subForce[A][jj] = kStretchBend*dt*termA*deltaR[AB][jj] + drkk*deltaR[ABxP][jj];
subForce[C][jj] = k2StretchBend*dt*termC*deltaR[CB][jj] + drkk*deltaR[CBxP][jj]; subForce[C][jj] = k2StretchBend*dt*termC*deltaR[CB][jj] + drkk*deltaR[CBxP][jj];
subForce[B][jj] = -( subForce[A][jj] + subForce[C][jj] ); subForce[B][jj] = -(subForce[A][jj] + subForce[C][jj]);
} }
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
...@@ -188,81 +180,49 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector<Vec3>& pos ...@@ -188,81 +180,49 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector<Vec3>& pos
forces[particle3][2] -= subForce[2][2]; forces[particle3][2] -= subForce[2][2];
*energy += dt*drkk; *energy += dt*drkk;
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaStretchBendForce: angle=%10.3e dt=%10.3e dr=%10.3e\n", angle, dt, dr );
(void) fflush( log );
}
#endif
return;
} }
static void computeAmoebaStretchBendForces( Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, static void computeAmoebaStretchBendForces(Context& context, AmoebaStretchBendForce& amoebaStretchBendForce,
std::vector<Vec3>& expectedForces, double* expectedEnergy, FILE* log ) { std::vector<Vec3>& expectedForces, double* expectedEnergy) {
// get positions and zero forces // get positions and zero forces
State state = context.getState(State::Positions); State state = context.getState(State::Positions);
std::vector<Vec3> positions = state.getPositions(); std::vector<Vec3> positions = state.getPositions();
expectedForces.resize( positions.size() ); expectedForces.resize(positions.size());
for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ for (unsigned int ii = 0; ii < expectedForces.size(); ii++) {
expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0;
} }
// calculates forces/energy // calculates forces/energy
*expectedEnergy = 0.0; *expectedEnergy = 0.0;
for( int ii = 0; ii < amoebaStretchBendForce.getNumStretchBends(); ii++ ){ for (int ii = 0; ii < amoebaStretchBendForce.getNumStretchBends(); ii++) {
computeAmoebaStretchBendForce(ii, positions, amoebaStretchBendForce, expectedForces, expectedEnergy, log ); computeAmoebaStretchBendForce(ii, positions, amoebaStretchBendForce, expectedForces, expectedEnergy);
}
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaStretchBendForces: expected energy=%14.7e\n", *expectedEnergy );
for( unsigned int ii = 0; ii < positions.size(); ii++ ){
(void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] );
}
(void) fflush( log );
} }
#endif
return;
} }
void compareWithExpectedForceAndEnergy( Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, void compareWithExpectedForceAndEnergy(Context& context, AmoebaStretchBendForce& amoebaStretchBendForce,
double tolerance, const std::string& idString, FILE* log) { double tolerance, const std::string& idString) {
std::vector<Vec3> expectedForces; std::vector<Vec3> expectedForces;
double expectedEnergy; double expectedEnergy;
computeAmoebaStretchBendForces( context, amoebaStretchBendForce, expectedForces, &expectedEnergy, log ); computeAmoebaStretchBendForces(context, amoebaStretchBendForce, expectedForces, &expectedEnergy);
State state = context.getState(State::Forces | State::Energy); State state = context.getState(State::Forces | State::Energy);
const std::vector<Vec3> forces = state.getForces(); const std::vector<Vec3> forces = state.getForces();
for (unsigned int ii = 0; ii < forces.size(); ii++) {
#ifdef AMOEBA_DEBUG ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance);
if( log ){
(void) fprintf( log, "computeAmoebaStretchBendForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() );
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,
expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] );
}
(void) fflush( log );
}
#endif
for( unsigned int ii = 0; ii < forces.size(); ii++ ){
ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance );
} }
ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance);
} }
void testOneStretchBend( FILE* log ) { void testOneStretchBend() {
System system; System system;
int numberOfParticles = 3; int numberOfParticles = 3;
for( int ii = 0; ii < numberOfParticles; ii++ ){ for (int ii = 0; ii < numberOfParticles; ii++) {
system.addParticle(1.0); system.addParticle(1.0);
} }
...@@ -276,19 +236,19 @@ void testOneStretchBend( FILE* log ) { ...@@ -276,19 +236,19 @@ void testOneStretchBend( FILE* log ) {
//double kStretchBend = 0.750491578E-01; //double kStretchBend = 0.750491578E-01;
double kStretchBend = 1.0; double kStretchBend = 1.0;
amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend, kStretchBend ); amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend, kStretchBend);
system.addForce(amoebaStretchBendForce); system.addForce(amoebaStretchBendForce);
Context context(system, integrator, Platform::getPlatformByName( "CUDA")); Context context(system, integrator, Platform::getPlatformByName("CUDA"));
std::vector<Vec3> positions(numberOfParticles); std::vector<Vec3> positions(numberOfParticles);
positions[0] = Vec3( 0.262660000E+02, 0.254130000E+02, 0.284200000E+01 ); positions[0] = Vec3(0.262660000E+02, 0.254130000E+02, 0.284200000E+01);
positions[1] = Vec3( 0.273400000E+02, 0.244300000E+02, 0.261400000E+01 ); positions[1] = Vec3(0.273400000E+02, 0.244300000E+02, 0.261400000E+01);
positions[2] = Vec3( 0.269573220E+02, 0.236108860E+02, 0.216376800E+01 ); positions[2] = Vec3(0.269573220E+02, 0.236108860E+02, 0.216376800E+01);
context.setPositions(positions); context.setPositions(positions);
compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log ); compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend");
// Try changing the stretch-bend parameters and make sure it's still correct. // Try changing the stretch-bend parameters and make sure it's still correct.
...@@ -296,14 +256,14 @@ void testOneStretchBend( FILE* log ) { ...@@ -296,14 +256,14 @@ void testOneStretchBend( FILE* log ) {
bool exceptionThrown = false; bool exceptionThrown = false;
try { try {
// This should throw an exception. // This should throw an exception.
compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log ); compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend");
} }
catch (std::exception ex) { catch (std::exception ex) {
exceptionThrown = true; exceptionThrown = true;
} }
ASSERT(exceptionThrown); ASSERT(exceptionThrown);
amoebaStretchBendForce->updateParametersInContext(context); amoebaStretchBendForce->updateParametersInContext(context);
compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log ); compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend");
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
...@@ -312,8 +272,7 @@ int main(int argc, char* argv[]) { ...@@ -312,8 +272,7 @@ int main(int argc, char* argv[]) {
registerAmoebaCudaKernelFactories(); registerAmoebaCudaKernelFactories();
if (argc > 1) if (argc > 1)
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1]));
FILE* log = NULL; testOneStretchBend();
testOneStretchBend( 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;
......
...@@ -48,7 +48,7 @@ extern "C" void registerAmoebaCudaKernelFactories(); ...@@ -48,7 +48,7 @@ extern "C" void registerAmoebaCudaKernelFactories();
const double TOL = 1e-4; const double TOL = 1e-4;
TorsionTorsionGrid& getTorsionGrid( int gridIndex ) { TorsionTorsionGrid& getTorsionGrid(int gridIndex) {
static double grid[4][625][6] = { static double grid[4][625][6] = {
{ {
...@@ -2558,22 +2558,22 @@ TorsionTorsionGrid& getTorsionGrid( int gridIndex ) { ...@@ -2558,22 +2558,22 @@ TorsionTorsionGrid& getTorsionGrid( int gridIndex ) {
// static std::vector< std::vector< std::vector<double> > > TorsionTorsionGrid // static std::vector< std::vector< std::vector<double> > > TorsionTorsionGrid
static std::vector<TorsionTorsionGrid> grids; static std::vector<TorsionTorsionGrid> grids;
if( grids.size() == 0 ){ if (grids.size() == 0) {
grids.resize(4); grids.resize(4);
for( int ii = 0; ii < 4; ii++ ){ for (int ii = 0; ii < 4; ii++) {
grids[ii].resize( 25 ); grids[ii].resize(25);
for( int jj = 0; jj < 25; jj++ ){ for (int jj = 0; jj < 25; jj++) {
grids[ii][jj].resize(25); grids[ii][jj].resize(25);
for( int kk = 0; kk < 25; kk++ ){ for (int kk = 0; kk < 25; kk++) {
grids[ii][jj][kk].resize(6); grids[ii][jj][kk].resize(6);
} }
} }
int index = 0; int index = 0;
for( int jj = 0; jj < 25; jj++ ){ for (int jj = 0; jj < 25; jj++) {
for( int kk = 0; kk < 25; kk++ ){ for (int kk = 0; kk < 25; kk++) {
int jjIndex = static_cast<int>(((grid[ii][index][0] + 180.0)/15.0)+1.0e-05); int jjIndex = static_cast<int>(((grid[ii][index][0] + 180.0)/15.0)+1.0e-05);
int kkIndex = static_cast<int>(((grid[ii][index][1] + 180.0)/15.0)+1.0e-05); int kkIndex = static_cast<int>(((grid[ii][index][1] + 180.0)/15.0)+1.0e-05);
for( int ll = 0; ll < 6; ll++ ){ for (int ll = 0; ll < 6; ll++) {
grids[ii][kk][jj][ll] = grid[ii][index][ll]; grids[ii][kk][jj][ll] = grid[ii][index][ll];
} }
index++; index++;
...@@ -2584,11 +2584,11 @@ TorsionTorsionGrid& getTorsionGrid( int gridIndex ) { ...@@ -2584,11 +2584,11 @@ TorsionTorsionGrid& getTorsionGrid( int gridIndex ) {
return grids[gridIndex]; return grids[gridIndex];
} }
void testTorsionTorsion( FILE* log, int systemId ) { void testTorsionTorsion(int systemId) {
System system; System system;
int numberOfParticles = 6; int numberOfParticles = 6;
for( int ii = 0; ii < numberOfParticles; ii++ ){ for (int ii = 0; ii < numberOfParticles; ii++) {
system.addParticle(1.0); system.addParticle(1.0);
} }
LangevinIntegrator integrator(0.0, 0.1, 0.01); LangevinIntegrator integrator(0.0, 0.1, 0.01);
...@@ -2600,84 +2600,71 @@ void testTorsionTorsion( FILE* log, int systemId ) { ...@@ -2600,84 +2600,71 @@ void testTorsionTorsion( FILE* log, int systemId ) {
std::vector<Vec3> positions(numberOfParticles); std::vector<Vec3> positions(numberOfParticles);
std::vector<Vec3> expectedForces(numberOfParticles); std::vector<Vec3> expectedForces(numberOfParticles);
double expectedEnergy; double expectedEnergy;
if( systemId == 0 ){ if (systemId == 0) {
// villin: 2 19 20 21 38 25 grid=2 // villin: 2 19 20 21 38 25 grid=2
chiralCheckAtomIndex = 5; chiralCheckAtomIndex = 5;
gridIndex = 2; gridIndex = 2;
positions[0] = Vec3( -0.422792800E+01, -0.110605910E+02, -0.508156700E+01 ); positions[0] = Vec3(-0.422792800E+01, -0.110605910E+02, -0.508156700E+01);
positions[1] = Vec3( -0.447153100E+01, -0.978627900E+01, -0.466405800E+01 ); positions[1] = Vec3(-0.447153100E+01, -0.978627900E+01, -0.466405800E+01);
positions[2] = Vec3( -0.531878400E+01, -0.940508600E+01, -0.352283100E+01 ); positions[2] = Vec3(-0.531878400E+01, -0.940508600E+01, -0.352283100E+01);
positions[3] = Vec3( -0.679606000E+01, -0.974353100E+01, -0.382975700E+01 ); positions[3] = Vec3(-0.679606000E+01, -0.974353100E+01, -0.382975700E+01);
positions[4] = Vec3( -0.760612300E+01, -0.992590200E+01, -0.275088400E+01 ); positions[4] = Vec3(-0.760612300E+01, -0.992590200E+01, -0.275088400E+01);
positions[5] = Vec3( -0.516893900E+01, -0.788347000E+01, -0.316943000E+01 ); positions[5] = Vec3(-0.516893900E+01, -0.788347000E+01, -0.316943000E+01);
expectedForces[0] = Vec3( 0.906091624E+00, -0.529814945E-01, 0.690384140E+00 ); expectedForces[0] = Vec3( 0.906091624E+00, -0.529814945E-01, 0.690384140E+00);
expectedForces[1] = Vec3( -0.124550232E+01, -0.999341692E+00, -0.590867130E+00 ); expectedForces[1] = Vec3(-0.124550232E+01, -0.999341692E+00, -0.590867130E+00);
expectedForces[2] = Vec3( 0.534419689E+00, 0.612404926E-01, 0.547380310E-01 ); expectedForces[2] = Vec3( 0.534419689E+00, 0.612404926E-01, 0.547380310E-01);
expectedForces[3] = Vec3( -5.732010432E-01, 2.645718463E+00, -1.585204274E-01 ); expectedForces[3] = Vec3(-5.732010432E-01, 2.645718463E+00, -1.585204274E-01);
expectedForces[4] = Vec3( 3.781920539E-01, -1.654635768E+00, 4.265386268E-03 ); expectedForces[4] = Vec3( 3.781920539E-01, -1.654635768E+00, 4.265386268E-03);
expectedForces[5] = Vec3( 0.0, 0.0, 0.0 ); expectedForces[5] = Vec3( 0.0, 0.0, 0.0);
expectedEnergy = -2.699654759E+00; expectedEnergy = -2.699654759E+00;
} else if( systemId == 1 ){ } else if (systemId == 1) {
// villin: 158 176 177 178 183 -1 0 // villin: 158 176 177 178 183 -1 0
chiralCheckAtomIndex = -1; chiralCheckAtomIndex = -1;
gridIndex = 0; gridIndex = 0;
positions[0] = Vec3( -0.105946640E+02, -0.917797000E+00, 0.105486310E+02 ); positions[0] = Vec3(-0.105946640E+02, -0.917797000E+00, 0.105486310E+02);
positions[1] = Vec3( -0.115059090E+02, -0.141876700E+01, 0.966933200E+01 ); positions[1] = Vec3(-0.115059090E+02, -0.141876700E+01, 0.966933200E+01);
positions[2] = Vec3( -0.128314660E+02, -0.876338000E+00, 0.942959800E+01 ); positions[2] = Vec3(-0.128314660E+02, -0.876338000E+00, 0.942959800E+01);
positions[3] = Vec3( -0.130879850E+02, -0.760280000E-01, 0.814732200E+01 ); positions[3] = Vec3(-0.130879850E+02, -0.760280000E-01, 0.814732200E+01);
positions[4] = Vec3( -0.120888080E+02, 0.112050000E-01, 0.722704500E+01 ); positions[4] = Vec3(-0.120888080E+02, 0.112050000E-01, 0.722704500E+01);
positions[5] = Vec3( 0.0, 0.0, 0.0 ); positions[5] = Vec3( 0.0, 0.0, 0.0);
expectedForces[0] = Vec3( 4.165851130E-01, 6.608242922E-01, -8.082168261E-01 ); expectedForces[0] = Vec3( 4.165851130E-01, 6.608242922E-01, -8.082168261E-01);
expectedForces[1] = Vec3( -6.024659721E-01, -8.878744406E-01, 1.322274444E+00 ); expectedForces[1] = Vec3(-6.024659721E-01, -8.878744406E-01, 1.322274444E+00);
expectedForces[2] = Vec3( 3.196925118E-02, -3.137497848E-01, -8.207984001E-01 ); expectedForces[2] = Vec3( 3.196925118E-02, -3.137497848E-01, -8.207984001E-01);
expectedForces[3] = Vec3( 3.842205941E-02, 2.602732089E-01, 1.547586195E-01 ); expectedForces[3] = Vec3( 3.842205941E-02, 2.602732089E-01, 1.547586195E-01);
expectedForces[4] = Vec3( 1.154895485E-01, 2.805267242E-01, 1.519821623E-01 ); expectedForces[4] = Vec3( 1.154895485E-01, 2.805267242E-01, 1.519821623E-01);
expectedForces[5] = Vec3( 0.0, 0.0, 0.0 ); expectedForces[5] = Vec3( 0.0, 0.0, 0.0);
expectedEnergy = -3.372536909E+00; expectedEnergy = -3.372536909E+00;
} }
amoebaTorsionTorsionForce->addTorsionTorsion( 0, 1, 2, 3, 4, chiralCheckAtomIndex, 0 ); amoebaTorsionTorsionForce->addTorsionTorsion(0, 1, 2, 3, 4, chiralCheckAtomIndex, 0);
amoebaTorsionTorsionForce->setTorsionTorsionGrid( 0, getTorsionGrid( gridIndex ) ); amoebaTorsionTorsionForce->setTorsionTorsionGrid(0, getTorsionGrid(gridIndex));
system.addForce(amoebaTorsionTorsionForce); system.addForce(amoebaTorsionTorsionForce);
Context context(system, integrator, Platform::getPlatformByName( "CUDA")); Context context(system, integrator, Platform::getPlatformByName("CUDA"));
context.setPositions(positions); context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy); State state = context.getState(State::Forces | State::Energy);
std::vector<Vec3> forces = state.getForces(); std::vector<Vec3> forces = state.getForces();
const double conversion = -1.0; const double conversion = -1.0;
for( unsigned int ii = 0; ii < forces.size(); ii++ ){ for (unsigned int ii = 0; ii < forces.size(); ii++) {
forces[ii][0] *= conversion; forces[ii][0] *= conversion;
forces[ii][1] *= conversion; forces[ii][1] *= conversion;
forces[ii][2] *= conversion; forces[ii][2] *= conversion;
} }
#ifdef AMOEBA_DEBUG
if( log ){
(void) fprintf( log, "computeAmoebaTorsionTorsionForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() );
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,
expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2],
forces[ii][0], forces[ii][1], forces[ii][2] );
}
(void) fflush( log );
}
#endif
double tolerance = 1.0e-03; double tolerance = 1.0e-03;
for( unsigned int ii = 0; ii < forces.size(); ii++ ){ for (unsigned int ii = 0; ii < forces.size(); ii++) {
ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance);
} }
ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance);
} }
...@@ -2687,8 +2674,7 @@ int main(int argc, char* argv[]) { ...@@ -2687,8 +2674,7 @@ int main(int argc, char* argv[]) {
registerAmoebaCudaKernelFactories(); registerAmoebaCudaKernelFactories();
if (argc > 1) if (argc > 1)
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1]));
FILE* log = NULL; testTorsionTorsion(1);
testTorsionTorsion( log, 1 );
} 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