Commit a3d5f834 authored by Mark Friedrichs's avatar Mark Friedrichs
Browse files

Reference implementation for AmoebaGeneralizedKirkwoodForce

parent 9fd73edf
......@@ -61,9 +61,7 @@ extern "C" void initAmoebaReferenceKernels() {
platform.registerKernelFactory(CalcAmoebaTorsionTorsionForceKernel::Name(), factory);
platform.registerKernelFactory(CalcAmoebaVdwForceKernel::Name(), factory);
platform.registerKernelFactory(CalcAmoebaMultipoleForceKernel::Name(), factory);
/*
platform.registerKernelFactory(CalcAmoebaGeneralizedKirkwoodForceKernel::Name(), factory);
*/
platform.registerKernelFactory(CalcAmoebaWcaDispersionForceKernel::Name(), factory);
}
}
......@@ -101,10 +99,8 @@ KernelImpl* AmoebaReferenceKernelFactory::createKernelImpl(std::string name, con
if (name == CalcAmoebaMultipoleForceKernel::Name())
return new ReferenceCalcAmoebaMultipoleForceKernel(name, platform, context.getSystem());
/*
if (name == CalcAmoebaGeneralizedKirkwoodForceKernel::Name())
return new ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel(name, platform, context.getSystem());
*/
if (name == CalcAmoebaWcaDispersionForceKernel::Name())
return new ReferenceCalcAmoebaWcaDispersionForceKernel(name, platform, context.getSystem());
......
......@@ -35,6 +35,7 @@
#include "AmoebaReferenceMultipoleForce.h"
#include "AmoebaReferenceVdwForce.h"
#include "AmoebaReferenceWcaDispersionForce.h"
#include "AmoebaReferenceGeneralizedKirkwoodForce.h"
#include "openmm/internal/AmoebaTorsionTorsionForceImpl.h"
#include "openmm/internal/AmoebaWcaDispersionForceImpl.h"
#include "ReferencePlatform.h"
......@@ -42,6 +43,7 @@
#include "openmm/AmoebaMultipoleForce.h"
#include "openmm/internal/AmoebaMultipoleForceImpl.h"
#include "openmm/internal/AmoebaVdwForceImpl.h"
#include "openmm/internal/AmoebaGeneralizedKirkwoodForceImpl.h"
#include <cmath>
#ifdef _MSC_VER
......@@ -453,27 +455,76 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c
if( nonbondedMethod != 0 && nonbondedMethod != 1 ){
throw OpenMMException("AmoebaMultipoleForce nonbonded method not recognized.\n");
}
polarizationType = static_cast<int>(force.getPolarizationType());
if( polarizationType != 0 && polarizationType != 1 ){
throw OpenMMException("AmoebaMultipoleForce polarization type not recognized.\n");
}
polarizationType = force.getPolarizationType();
}
double ReferenceCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
vector<RealVec>& posData = extractPositions(context);
vector<RealVec>& forceData = extractForces(context);
AmoebaReferenceMultipoleForce amoebaReferenceMultipoleForce( AmoebaReferenceMultipoleForce::NoCutoff );
amoebaReferenceMultipoleForce.setMutualInducedDipoleTargetEpsilon( mutualInducedTargetEpsilon );
amoebaReferenceMultipoleForce.setMaximumMutualInducedDipoleIterations( mutualInducedMaxIterations );
ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel* gkKernel = NULL;
for (unsigned int ii = 0; ii < context.getForceImpls().size() && gkKernel == NULL; ii++) {
AmoebaGeneralizedKirkwoodForceImpl* gkImpl = dynamic_cast<AmoebaGeneralizedKirkwoodForceImpl*>(context.getForceImpls()[ii]);
if (gkImpl != NULL) {
gkKernel = dynamic_cast<ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel*>(&gkImpl->getKernel().getImpl());
}
}
AmoebaReferenceMultipoleForce* amoebaReferenceMultipoleForce = NULL;
if( gkKernel ){
// amoebaReferenceGeneralizedKirkwoodForce is deleted in AmoebaReferenceGeneralizedKirkwoodMultipoleForce
// destructor
AmoebaReferenceGeneralizedKirkwoodForce* amoebaReferenceGeneralizedKirkwoodForce = new AmoebaReferenceGeneralizedKirkwoodForce();
amoebaReferenceGeneralizedKirkwoodForce->setNumParticles( gkKernel->getNumParticles() );
amoebaReferenceGeneralizedKirkwoodForce->setSoluteDielectric( gkKernel->getSoluteDielectric() );
amoebaReferenceGeneralizedKirkwoodForce->setSolventDielectric( gkKernel->getSolventDielectric() );
amoebaReferenceGeneralizedKirkwoodForce->setDielectricOffset( gkKernel->getDielectricOffset() );
amoebaReferenceGeneralizedKirkwoodForce->setProbeRadius( gkKernel->getProbeRadius() );
amoebaReferenceGeneralizedKirkwoodForce->setSurfaceAreaFactor( gkKernel->getSurfaceAreaFactor() );
amoebaReferenceGeneralizedKirkwoodForce->setIncludeCavityTerm( gkKernel->getIncludeCavityTerm() );
amoebaReferenceGeneralizedKirkwoodForce->setDirectPolarization( gkKernel->getDirectPolarization() );
vector<RealOpenMM> parameters;
gkKernel->getAtomicRadii( parameters );
amoebaReferenceGeneralizedKirkwoodForce->setAtomicRadii( parameters );
RealOpenMM energy = amoebaReferenceMultipoleForce.calculateForceAndEnergy( posData,
charges, dipoles, quadrupoles, tholes,
gkKernel->getScaleFactors( parameters );
amoebaReferenceGeneralizedKirkwoodForce->setScaleFactors( parameters );
gkKernel->getCharges( parameters );
amoebaReferenceGeneralizedKirkwoodForce->setCharges( parameters );
// calculate Grycuk Born radii
amoebaReferenceGeneralizedKirkwoodForce->calculateGrycukBornRadii( posData );
amoebaReferenceMultipoleForce = new AmoebaReferenceGeneralizedKirkwoodMultipoleForce( amoebaReferenceGeneralizedKirkwoodForce );
} else {
amoebaReferenceMultipoleForce = new AmoebaReferenceMultipoleForce( AmoebaReferenceMultipoleForce::NoCutoff );
}
amoebaReferenceMultipoleForce->setMutualInducedDipoleTargetEpsilon( mutualInducedTargetEpsilon );
amoebaReferenceMultipoleForce->setMaximumMutualInducedDipoleIterations( mutualInducedMaxIterations );
AmoebaReferenceMultipoleForce::PolarizationType refPolarizationType;
if( polarizationType == AmoebaMultipoleForce::Mutual ){
refPolarizationType = AmoebaReferenceMultipoleForce::Mutual;
} else if( polarizationType == AmoebaMultipoleForce::Direct ){
refPolarizationType = AmoebaReferenceMultipoleForce::Direct;
} else {
throw OpenMMException("Polarization type not recognzied." );
}
RealOpenMM energy = amoebaReferenceMultipoleForce->calculateForceAndEnergy( posData, charges, dipoles, quadrupoles, tholes,
dampingFactors, polarity, axisTypes,
multipoleAtomZs, multipoleAtomXs, multipoleAtomYs,
multipoleAtomCovalentInfo, polarizationType, forceData);
multipoleAtomCovalentInfo, refPolarizationType, forceData);
delete amoebaReferenceMultipoleForce;
return static_cast<double>(energy);
}
......@@ -487,48 +538,115 @@ void ReferenceCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextI
return;
}
///* -------------------------------------------------------------------------- *
// * AmoebaGeneralizedKirkwood *
// * -------------------------------------------------------------------------- */
//
//ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel(std::string name, const Platform& platform, System& system) :
// CalcAmoebaGeneralizedKirkwoodForceKernel(name, platform), system(system) {
// data.incrementKernelCount();
//}
//
//ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::~ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel() {
// data.decrementKernelCount();
//}
//
//void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::initialize(const System& system, const AmoebaGeneralizedKirkwoodForce& force) {
//
// data.setHasAmoebaGeneralizedKirkwood( true );
//
// int numParticles = system.getNumParticles();
//
// std::vector<RealOpenMM> radius(numParticles);
// std::vector<RealOpenMM> scale(numParticles);
// std::vector<RealOpenMM> charge(numParticles);
//
// for( int ii = 0; ii < numParticles; ii++ ){
// double particleCharge, particleRadius, scalingFactor;
// force.getParticleParameters(ii, particleCharge, particleRadius, scalingFactor);
// radius[ii] = static_cast<RealOpenMM>( particleRadius );
// scale[ii] = static_cast<RealOpenMM>( scalingFactor );
// charge[ii] = static_cast<RealOpenMM>( particleCharge );
// }
// gpuSetAmoebaObcParameters( data.getAmoebaGpu(), static_cast<RealOpenMM>(force.getSoluteDielectric() ),
// static_cast<RealOpenMM>( force.getSolventDielectric() ),
// static_cast<RealOpenMM>( force.getDielectricOffset() ), radius, scale, charge,
// force.getIncludeCavityTerm(),
// static_cast<RealOpenMM>( force.getProbeRadius() ),
// static_cast<RealOpenMM>( force.getSurfaceAreaFactor() ) );
//}
//
//double ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
// // handled in computeAmoebaMultipoleForce()
// return 0.0;
//}
/* -------------------------------------------------------------------------- *
* AmoebaGeneralizedKirkwood *
* -------------------------------------------------------------------------- */
ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel(std::string name, const Platform& platform, System& system) :
CalcAmoebaGeneralizedKirkwoodForceKernel(name, platform), system(system) {
}
ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::~ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel() {
}
int ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getNumParticles( void ) const {
return numParticles;
}
int ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getIncludeCavityTerm( void ) const {
return includeCavityTerm;
}
int ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getDirectPolarization( void ) const {
return directPolarization;
}
RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getSoluteDielectric( void ) const {
return soluteDielectric;
}
RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getSolventDielectric( void ) const {
return solventDielectric;
}
RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getDielectricOffset( void ) const {
return dielectricOffset;
}
RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getProbeRadius( void ) const {
return probeRadius;
}
RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getSurfaceAreaFactor( void ) const {
return surfaceAreaFactor;
}
void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getAtomicRadii( vector<RealOpenMM>& outputAtomicRadii ) const {
outputAtomicRadii.resize( atomicRadii.size() );
copy( atomicRadii.begin(), atomicRadii.end(), outputAtomicRadii.begin() );
}
void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getScaleFactors( vector<RealOpenMM>& outputScaleFactors ) const {
outputScaleFactors.resize( scaleFactors.size() );
copy( scaleFactors.begin(), scaleFactors.end(), outputScaleFactors.begin() );
}
void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getCharges( vector<RealOpenMM>& outputCharges ) const {
outputCharges.resize( charges.size() );
copy( charges.begin(), charges.end(), outputCharges.begin() );
}
void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::initialize(const System& system, const AmoebaGeneralizedKirkwoodForce& force) {
// check that AmoebaMultipoleForce is present
const AmoebaMultipoleForce* amoebaMultipoleForce = NULL;
for (int ii = 0; ii < system.getNumForces() && amoebaMultipoleForce == NULL; ii++) {
amoebaMultipoleForce = dynamic_cast<const AmoebaMultipoleForce*>(&system.getForce(ii));
}
if (amoebaMultipoleForce == NULL) {
throw OpenMMException("AmoebaGeneralizedKirkwoodForce requires the System to also contain an AmoebaMultipoleForce.");
}
if (amoebaMultipoleForce->getNonbondedMethod() != AmoebaMultipoleForce::NoCutoff ) {
throw OpenMMException("AmoebaGeneralizedKirkwoodForce requires the AmoebaMultipoleForce use the NoCutoff nonbonded method.");
}
numParticles = system.getNumParticles();
for( int ii = 0; ii < numParticles; ii++ ){
double particleCharge, particleRadius, scalingFactor;
force.getParticleParameters(ii, particleCharge, particleRadius, scalingFactor);
atomicRadii.push_back( static_cast<RealOpenMM>( particleRadius ) );
scaleFactors.push_back( static_cast<RealOpenMM>( scalingFactor ) );
charges.push_back( static_cast<RealOpenMM>( particleCharge ) );
// Make sure the charge matches the one specified by the AmoebaMultipoleForce.
double charge2, thole, damping, polarity;
int axisType, atomX, atomY, atomZ;
vector<double> dipole, quadrupole;
amoebaMultipoleForce->getMultipoleParameters( ii, charge2, dipole, quadrupole, axisType, atomZ, atomX, atomY, thole, damping, polarity);
if ( particleCharge != charge2 ){
throw OpenMMException("AmoebaGeneralizedKirkwoodForce and AmoebaMultipoleForce must specify the same charge for every atom.");
}
}
includeCavityTerm = force.getIncludeCavityTerm();
soluteDielectric = static_cast<RealOpenMM>( force.getSoluteDielectric() );
solventDielectric = static_cast<RealOpenMM>( force.getSolventDielectric() );
dielectricOffset = static_cast<RealOpenMM>( 0.009 );
probeRadius = static_cast<RealOpenMM>( force.getProbeRadius() ),
surfaceAreaFactor = static_cast<RealOpenMM>( force.getSurfaceAreaFactor() );
directPolarization = amoebaMultipoleForce->getPolarizationType() == AmoebaMultipoleForce::Direct ? 1 : 0;
}
double ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
// handled in AmoebaReferenceGeneralizedKirkwoodMultipoleForce, a derived class of the class AmoebaReferenceMultipoleForce
return 0.0;
}
ReferenceCalcAmoebaVdwForceKernel::ReferenceCalcAmoebaVdwForceKernel(std::string name, const Platform& platform, System& system) :
CalcAmoebaVdwForceKernel(name, platform), system(system) {
......
......@@ -29,6 +29,7 @@
#include "openmm/System.h"
#include "openmm/amoebaKernels.h"
//#include "openmm/AmoebaMultipoleForce.h"
#include "SimTKReference/ReferenceNeighborList.h"
#include "SimTKUtilities/SimTKOpenMMRealType.h"
......@@ -338,7 +339,7 @@ public:
private:
int numMultipoles;
int polarizationType;
AmoebaMultipoleForce::PolarizationType polarizationType;
std::vector<RealOpenMM> charges;
std::vector<RealOpenMM> dipoles;
std::vector<RealOpenMM> quadrupoles;
......@@ -439,6 +440,132 @@ private:
System& system;
};
/**
* This kernel is invoked to calculate the Gerneralized Kirkwood forces acting on the system and the energy of the system.
*/
class ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel : public CalcAmoebaGeneralizedKirkwoodForceKernel {
public:
ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel(std::string name, const Platform& platform, System& system);
~ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaMultipoleForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaGeneralizedKirkwoodForce& force);
/**
* Execute the kernel to calculate the forces and/or energy.
*
* @param context the context in which to execute this kernel
* @param includeForces true if forces should be calculated
* @param includeEnergy true if the energy should be calculated
* @return the potential energy due to the force
*/
double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
/**
* Get include-cavity term flag
*
* @return includeCavityTerm
*/
int getIncludeCavityTerm( void ) const;
/**
* Get number of particles
*
* @return number of particles
*/
int getNumParticles( void ) const;
/**
* Get directPolarization flag
*
* @return directPolarization
*
*/
int getDirectPolarization( void ) const;
/**
* Get solute dielectric
*
* @return soluteDielectric
*
*/
RealOpenMM getSoluteDielectric( void ) const;
/**
* Get solvent dielectric
*
* @return solventDielectric
*
*/
RealOpenMM getSolventDielectric( void ) const;
/**
* Get dielectric offset
*
* @return dielectricOffset
*
*/
RealOpenMM getDielectricOffset( void ) const;
/**
* Get probeRadius
*
* @return probeRadius
*
*/
RealOpenMM getProbeRadius( void ) const;
/**
* Get surfaceAreaFactor
*
* @return surfaceAreaFactor
*
*/
RealOpenMM getSurfaceAreaFactor( void ) const;
/**
* Get atomic radii
*
* @param atomicRadii vector of atomic radii
*
*/
void getAtomicRadii( std::vector<RealOpenMM>& atomicRadii ) const;
/**
* Get scale factors
*
* @param scaleFactors vector of scale factors
*
*/
void getScaleFactors( std::vector<RealOpenMM>& scaleFactors ) const;
/**
* Get charges
*
* @param charges vector of charges
*
*/
void getCharges( std::vector<RealOpenMM>& charges ) const;
private:
int numParticles;
std::vector<RealOpenMM> atomicRadii;
std::vector<RealOpenMM> scaleFactors;
std::vector<RealOpenMM> charges;
RealOpenMM soluteDielectric;
RealOpenMM solventDielectric;
RealOpenMM dielectricOffset;
RealOpenMM probeRadius;
RealOpenMM surfaceAreaFactor;
int includeCavityTerm;
int directPolarization;
System& system;
};
} // namespace OpenMM
#endif /*AMOEBA_OPENMM_REFERENCE_KERNELS_H*/
/* Portions copyright (c) 2006 Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "AmoebaReferenceGeneralizedKirkwoodForce.h"
using std::vector;
using OpenMM::RealVec;
AmoebaReferenceGeneralizedKirkwoodForce::AmoebaReferenceGeneralizedKirkwoodForce( ) : _numParticles(0),
_includeCavityTerm(1),
_directPolarization(0),
_soluteDielectric(1.0),
_solventDielectric(78.3),
_dielectricOffset(0.009),
_probeRadius(0.14),
_surfaceAreaFactor(0.0054) {
}
void AmoebaReferenceGeneralizedKirkwoodForce::setNumParticles( int numParticles ){
_numParticles = numParticles;
}
int AmoebaReferenceGeneralizedKirkwoodForce::getNumParticles( void ) const {
return _numParticles;
}
void AmoebaReferenceGeneralizedKirkwoodForce::setIncludeCavityTerm( int includeCavityTerm ){
_includeCavityTerm = includeCavityTerm;
}
int AmoebaReferenceGeneralizedKirkwoodForce::getIncludeCavityTerm( void ) const {
return _includeCavityTerm;
}
void AmoebaReferenceGeneralizedKirkwoodForce::setDirectPolarization( int directPolarization ){
_directPolarization = directPolarization;
}
int AmoebaReferenceGeneralizedKirkwoodForce::getDirectPolarization( void ) const {
return _directPolarization;
}
void AmoebaReferenceGeneralizedKirkwoodForce::setSoluteDielectric( RealOpenMM soluteDielectric ){
_soluteDielectric = soluteDielectric;
}
RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getSoluteDielectric( void ) const {
return _soluteDielectric;
}
void AmoebaReferenceGeneralizedKirkwoodForce::setSolventDielectric( RealOpenMM solventDielectric ){
_solventDielectric = solventDielectric;
}
RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getSolventDielectric( void ) const {
return _solventDielectric;
}
void AmoebaReferenceGeneralizedKirkwoodForce::setDielectricOffset( RealOpenMM dielectricOffset ){
_dielectricOffset = dielectricOffset;
}
RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getDielectricOffset( void ) const {
return _dielectricOffset;
}
void AmoebaReferenceGeneralizedKirkwoodForce::setProbeRadius( RealOpenMM probeRadius ){
_probeRadius = probeRadius;
}
RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getProbeRadius( void ) const {
return _probeRadius;
}
void AmoebaReferenceGeneralizedKirkwoodForce::setSurfaceAreaFactor( RealOpenMM surfaceAreaFactor ){
_surfaceAreaFactor = surfaceAreaFactor;
}
RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getSurfaceAreaFactor( void ) const {
return _surfaceAreaFactor;
}
void AmoebaReferenceGeneralizedKirkwoodForce::setAtomicRadii( const vector<RealOpenMM>& atomicRadii ){
_atomicRadii.resize( atomicRadii.size() );
copy( atomicRadii.begin(), atomicRadii.end(), _atomicRadii.begin() );
}
void AmoebaReferenceGeneralizedKirkwoodForce::getAtomicRadii( vector<RealOpenMM>& atomicRadii ) const {
atomicRadii.resize( _atomicRadii.size() );
copy( _atomicRadii.begin(), _atomicRadii.end(), atomicRadii.begin() );
}
void AmoebaReferenceGeneralizedKirkwoodForce::setScaleFactors( const vector<RealOpenMM>& scaleFactors ){
_scaleFactors.resize( scaleFactors.size() );
copy( scaleFactors.begin(), scaleFactors.end(), _scaleFactors.begin() );
}
void AmoebaReferenceGeneralizedKirkwoodForce::getScaleFactors( vector<RealOpenMM>& scaleFactors ) const {
scaleFactors.resize( _scaleFactors.size() );
copy( _scaleFactors.begin(), _scaleFactors.end(), scaleFactors.begin() );
}
void AmoebaReferenceGeneralizedKirkwoodForce::setCharges( const vector<RealOpenMM>& charges ){
_charges.resize( charges.size() );
copy( charges.begin(), charges.end(), _charges.begin() );
}
void AmoebaReferenceGeneralizedKirkwoodForce::getGrycukBornRadii( vector<RealOpenMM>& bornRadii ) const {
bornRadii.resize( _bornRadii.size() );
copy( _bornRadii.begin(), _bornRadii.end(), bornRadii.begin() );
}
void AmoebaReferenceGeneralizedKirkwoodForce::calculateGrycukBornRadii( const vector<RealVec>& particlePositions ) {
const RealOpenMM zero = 0.0;
const RealOpenMM one = 1.0;
const RealOpenMM three = 3.0;
const RealOpenMM six = 6.0;
const RealOpenMM eight = 8.0;
const RealOpenMM sixteen = 16.0;
const RealOpenMM oneThird = 1.0/3.0;
const RealOpenMM bigRadius = 1000.0;
_bornRadii.resize( _numParticles );
for( unsigned int ii = 0; ii < _numParticles; ii++ ){
if( _atomicRadii[ii] <= zero ){
_bornRadii[ii] = bigRadius;
continue;
}
RealOpenMM bornSum = zero;
for( unsigned int jj = 0; jj < _numParticles; jj++ ){
if( ii == jj || _atomicRadii[jj] < zero )continue;
RealOpenMM xr = particlePositions[jj][0] - particlePositions[ii][0];
RealOpenMM yr = particlePositions[jj][1] - particlePositions[ii][1];
RealOpenMM zr = particlePositions[jj][2] - particlePositions[ii][2];
RealOpenMM r2 = xr*xr + yr*yr + zr*zr;
RealOpenMM r = SQRT( r2 );
RealOpenMM sk = _atomicRadii[jj]*_scaleFactors[jj];
RealOpenMM sk2 = sk*sk;
if( (_atomicRadii[ii] + r) < sk ){
RealOpenMM lik = _atomicRadii[ii];
RealOpenMM uik = sk - r;
RealOpenMM lik3 = lik*lik*lik;
RealOpenMM uik3 = uik*uik*uik;
bornSum -= (one/uik3 - one/lik3);
}
RealOpenMM uik = r + sk;
RealOpenMM lik;
if( (_atomicRadii[ii] + r) < sk ){
lik = sk - r;
} else if( r < (_atomicRadii[ii] + sk) ){
lik = _atomicRadii[ii];
} else {
lik = r - sk;
}
RealOpenMM l2 = lik*lik;
RealOpenMM l4 = l2*l2;
RealOpenMM lr = lik*r;
RealOpenMM l4r = l4*r;
RealOpenMM u2 = uik*uik;
RealOpenMM u4 = u2*u2;
RealOpenMM ur = uik*r;
RealOpenMM u4r = u4*r;
RealOpenMM term = (three*(r2-sk2) + six*u2 - eight*ur)/u4r - (three*(r2-sk2) + six*l2 - eight*lr)/l4r;
bornSum += term/sixteen;
}
bornSum = one/(_atomicRadii[ii]*_atomicRadii[ii]*_atomicRadii[ii]) - bornSum;
_bornRadii[ii] = (bornSum <= zero) ? bigRadius : POW( bornSum, -oneThird );
}
return;
}
/* Portions copyright (c) 2006 Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __AmoebaReferenceGeneralizedKirkwoodForce_H__
#define __AmoebaReferenceGeneralizedKirkwoodForce_H__
#include "SimTKUtilities/RealVec.h"
#include <vector>
using namespace OpenMM;
using namespace std;
// ---------------------------------------------------------------------------------------
class AmoebaReferenceGeneralizedKirkwoodForce {
public:
/**
* Constructor
*
*/
AmoebaReferenceGeneralizedKirkwoodForce( );
/**
* Destructor
*
*/
~AmoebaReferenceGeneralizedKirkwoodForce( ){};
/**
* Get number of particles
*
* @return numParticles
*
*/
int getNumParticles( void ) const;
/**
* Set numParticles
*
* @param numParticles
*
*/
void setNumParticles( int numParticles );
/**
* Get includeCavityTerm flag
*
* @return includeCavityTerm
*
*/
int getIncludeCavityTerm( void ) const;
/**
* Set includeCavityTerm flag
*
* @param includeCavityTerm flag indicating whether surface area term is to be included
*
*/
void setIncludeCavityTerm( int includeCavityTerm );
/**
* Get directPolarization flag
*
* @return directPolarization
*
*/
int getDirectPolarization( void ) const;
/**
* Set directPolarization flag
*
* @param directPolarization nonzero if direct as opposed to mutual polarization
*/
void setDirectPolarization( int directPolarization );
/**
* Get solute dielectric
*
* @return soluteDielectric
*/
RealOpenMM getSoluteDielectric( void ) const;
/**
* Set solute dielectric
*
* @param soluteDielectric solute dielectric
*
*/
void setSoluteDielectric( RealOpenMM soluteDielectric );
/**
* Get solvent dielectric
*
* @return solventDielectric
*
*/
RealOpenMM getSolventDielectric( void ) const;
/**
* Set solvent dielectric
*
* @param solventDielectric solvent dielectric
*
*/
void setSolventDielectric( RealOpenMM solventDielectric );
/**
* Get dielectric offset
*
* @return dielectricOffset
*
*/
RealOpenMM getDielectricOffset( void ) const;
/**
* Set dielectric offset
*
* @param dielectricOffset dielectric offset
*
*/
void setDielectricOffset( RealOpenMM dielectricOffset );
/**
* Get probeRadius
*
* @return probeRadius
*
*/
RealOpenMM getProbeRadius( void ) const;
/**
* Set probe radius
*
* @param probeRadius probe radiue
*
*/
void setProbeRadius( RealOpenMM probeRadius );
/**
* Get surfaceAreaFactor
*
* @return surfaceAreaFactor
*
*/
RealOpenMM getSurfaceAreaFactor( void ) const;
/**
* Set surface area factor
*
* @param surfaceAreaFactor surface area factor
*
*/
void setSurfaceAreaFactor( RealOpenMM surfaceAreaFactor );
/**
* Set atomic radii
*
* @param atomicRadii input vector of atomic radii
*
*/
void setAtomicRadii( const vector<RealOpenMM>& atomicRadii );
/**
* Get atomic radii
*
* @param atomicRadii output vector of atomic radii
*
*/
void getAtomicRadii( vector<RealOpenMM>& atomicRadii ) const;
/**
* Set scale factors
*
* @param scaleFactors input vector of scale factors
*
*/
void setScaleFactors( const vector<RealOpenMM>& scaleFactors );
/**
* Get scale factors
*
* @param scaleFactors output vector of scale factors
*
*/
void getScaleFactors( vector<RealOpenMM>& scaleFactors ) const;
/**
* Set charges
*
* @param charges input vector of charges
*
*/
void setCharges( const vector<RealOpenMM>& charges );
/**
* Calculate Grycuk Born radii
*
* @param particlePositions particle positions
*
*/
void calculateGrycukBornRadii( const vector<RealVec>& particlePositions );
/**
* Get Grycik Born radii (must have called calculateGrycukBornRadii())
*
* @param bornRadii vector of Born radii
*
*/
void getGrycukBornRadii( vector<RealOpenMM>& bornRadii ) const;
private:
int _numParticles;
int _includeCavityTerm;
int _directPolarization;
RealOpenMM _soluteDielectric;
RealOpenMM _solventDielectric;
RealOpenMM _dielectricOffset;
RealOpenMM _probeRadius;
RealOpenMM _surfaceAreaFactor;
std::vector<RealOpenMM> _atomicRadii;
std::vector<RealOpenMM> _scaleFactors;
std::vector<RealOpenMM> _charges;
std::vector<RealOpenMM> _bornRadii;
};
#endif // _AmoebaReferenceGeneralizedKirkwoodForce___
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -26,24 +26,16 @@
#define __AmoebaReferenceMultipoleForce_H__
#include "SimTKUtilities/RealVec.h"
#include "openmm/Vec3.h"
#include "openmm/AmoebaMultipoleForce.h"
#include <string>
#include <vector>
#include "AmoebaReferenceGeneralizedKirkwoodForce.h"
#include <map>
typedef std::map< unsigned int, RealOpenMM> MapIntRealOpenMM;
typedef MapIntRealOpenMM::iterator MapIntRealOpenMMI;
typedef MapIntRealOpenMM::const_iterator MapIntRealOpenMMCI;
typedef std::vector<std::vector<RealOpenMM> > VectorOfRealOpenMMVectors;
typedef VectorOfRealOpenMMVectors::iterator VectorOfRealOpenMMVectorsI;
typedef VectorOfRealOpenMMVectors::const_iterator VectorOfRealOpenMMVectorsCI;
using namespace OpenMM;
// ---------------------------------------------------------------------------------------
class AmoebaReferenceMultipoleForce {
public:
......@@ -71,138 +63,117 @@ public:
CutoffPeriodic = 2
};
/**---------------------------------------------------------------------------------------
enum PolarizationType {
Constructor
/**
* Mutual polarization
*/
Mutual = 0,
--------------------------------------------------------------------------------------- */
/**
* Direct polarization
*/
Direct = 1
};
/**
* Constructor
*
*/
AmoebaReferenceMultipoleForce( );
/**---------------------------------------------------------------------------------------
Constructor
--------------------------------------------------------------------------------------- */
/**
* Constructor
*
* @param nonbondedMethod nonbonded method
*/
AmoebaReferenceMultipoleForce( NonbondedMethod nonbondedMethod );
/**---------------------------------------------------------------------------------------
Destructor
--------------------------------------------------------------------------------------- */
~AmoebaReferenceMultipoleForce( ){};
/**---------------------------------------------------------------------------------------
Get nonbonded method
@return nonbonded method
--------------------------------------------------------------------------------------- */
/**
* Destructor
*
*/
virtual ~AmoebaReferenceMultipoleForce( ){};
/**
* Get nonbonded method
*
* @return nonbonded method
*/
NonbondedMethod getNonbondedMethod( void ) const;
/**---------------------------------------------------------------------------------------
Set nonbonded method
@param nonbonded method
--------------------------------------------------------------------------------------- */
/**
* Set nonbonded method
*
* @param nonbondedMethod nonbonded method
*/
void setNonbondedMethod( NonbondedMethod nonbondedMethod );
/**---------------------------------------------------------------------------------------
Get flag indicating if mutual induced dipoles are converged
@return nonzero if converged
--------------------------------------------------------------------------------------- */
/**
* Get flag indicating if mutual induced dipoles are converged
*
* @return nonzero if converged
*
*/
int getMutualInducedDipoleConverged( void ) const;
/**---------------------------------------------------------------------------------------
Get number of iterations used in computing mutual induced dipoles
@return number of iterations
--------------------------------------------------------------------------------------- */
/**
* Get number of iterations used in computing mutual induced dipoles
*
* @return number of iterations
*
*/
int getMutualInducedDipoleIterations( void ) const;
/**---------------------------------------------------------------------------------------
Get the final epsilon for mutual induced dipoles
@return epsilon
--------------------------------------------------------------------------------------- */
/**
* Get the final epsilon for mutual induced dipoles
*
* @return epsilon
*
*/
RealOpenMM getMutualInducedDipoleEpsilon( void ) const;
/**---------------------------------------------------------------------------------------
Set the target epsilon for converging mutual induced dipoles
@param target epsilon for converging mutual induced dipoles
--------------------------------------------------------------------------------------- */
/**
* Set the target epsilon for converging mutual induced dipoles
*
* @param targetEpsilon target epsilon for converging mutual induced dipoles
*
*/
void setMutualInducedDipoleTargetEpsilon( RealOpenMM targetEpsilon );
/**---------------------------------------------------------------------------------------
Get the target epsilon for converging mutual induced dipoles
@return target epsilon for converging mutual induced dipoles
--------------------------------------------------------------------------------------- */
/**
* Get the target epsilon for converging mutual induced dipoles
*
* @return target epsilon for converging mutual induced dipoles
*
*/
RealOpenMM getMutualInducedDipoleTargetEpsilon( void ) const;
/**---------------------------------------------------------------------------------------
Set the maximum number of iterations to be executed in converging mutual induced dipoles
@param maximum number of iterations to be executed in converging mutual induced dipoles
--------------------------------------------------------------------------------------- */
/**
* Set the maximum number of iterations to be executed in converging mutual induced dipoles
*
* @param maximumMutualInducedDipoleIterations maximum number of iterations to be executed in converging mutual induced dipoles
*
*/
void setMaximumMutualInducedDipoleIterations( int maximumMutualInducedDipoleIterations );
/**---------------------------------------------------------------------------------------
Get the maximum number of iterations to be executed in converging mutual induced dipoles
@return maximum number of iterations to be executed in converging mutual induced dipoles
--------------------------------------------------------------------------------------- */
/**
* Get the maximum number of iterations to be executed in converging mutual induced dipoles
*
* @return maximum number of iterations to be executed in converging mutual induced dipoles
*
*/
int getMaximumMutualInducedDipoleIterations( void ) const;
/**---------------------------------------------------------------------------------------
Calculate Amoeba Hal vdw ixns
@param numParticles number of particles
@param particlePositions Cartesian coordinates of particles
@param indexIVs position index for associated reducing particle
@param indexClasses class index for combining sigmas/epsilons (not currently used)
@param sigmas particle sigmas
@param epsilons particle epsilons
@param reductions particle reduction factors
@param vdwExclusions particle exclusions
@param forces add forces to this vector
@return energy
--------------------------------------------------------------------------------------- */
/**
* Calculate force and energy
*
* @param numParticles number of particles
* @param particlePositions Cartesian coordinates of particles
* @param forces add forces to this vector
*
* @return energy
*/
RealOpenMM calculateForceAndEnergy( const std::vector<OpenMM::RealVec>& particlePositions,
const std::vector<RealOpenMM>& charges,
const std::vector<RealOpenMM>& dipoles,
......@@ -215,30 +186,44 @@ public:
const std::vector<int>& multipoleAtomXs,
const std::vector<int>& multipoleAtomYs,
const std::vector< std::vector< std::vector<int> > >& multipoleAtomCovalentInfo,
int polarizationType,
AmoebaReferenceMultipoleForce::PolarizationType polarizationType,
std::vector<OpenMM::RealVec>& forces );
protected:
enum MultipoleParticleDataEnum { PARTICLE_POSITION, PARTICLE_CHARGE, PARTICLE_DIPOLE, PARTICLE_QUADRUPOLE,
PARTICLE_THOLE, PARTICLE_DAMPING_FACTOR, PARTICLE_POLARITY, PARTICLE_FIELD,
PARTICLE_FIELD_POLAR, GK_FIELD, PARTICLE_INDUCED_DIPOLE, PARTICLE_INDUCED_DIPOLE_POLAR };
private:
enum QuadrupoleIndices { QXX, QXY, QXZ, QYY, QYZ, QZZ };
struct MultipoleParticleData {
/*
* Particle parameters and coordinates
*/
class MultipoleParticleData {
public:
unsigned int particleIndex;
RealOpenMM position[3];
RealVec position;
RealOpenMM charge;
RealOpenMM dipole[3];
RealVec dipole;
RealOpenMM quadrupole[6];
RealOpenMM thole;
RealOpenMM dampingFactor;
RealOpenMM polarity;
RealOpenMM field[3];
RealOpenMM fieldPolar[3];
RealOpenMM inducedDipole[3];
RealOpenMM inducedDipolePolar[3];
};
enum MultipoleParticleDataEnum { PARTICLE_POSITION, PARTICLE_CHARGE, PARTICLE_DIPOLE, PARTICLE_QUADRUPOLE,
PARTICLE_THOLE, PARTICLE_DAMPING_FACTOR, PARTICLE_POLARITY, PARTICLE_FIELD,
PARTICLE_FIELD_POLAR, PARTICLE_INDUCED_DIPOLE, PARTICLE_INDUCED_DIPOLE_POLAR };
/*
* Helper class used in calculating induced dipoles
*/
class UpdateInducedDipoleField {
public:
UpdateInducedDipoleField( std::vector<OpenMM::RealVec>* inputFixed_E_Field, std::vector<OpenMM::RealVec>* inputInducedDipoles );
std::vector<OpenMM::RealVec>* fixed_E_Field;
std::vector<OpenMM::RealVec>* inducedDipoles;
std::vector<OpenMM::RealVec> inducedDipoleField;
};
unsigned int _numParticles;
NonbondedMethod _nonbondedMethod;
......@@ -253,6 +238,11 @@ private:
RealOpenMM _mScale[5];
RealOpenMM _uScale[5];
std::vector<RealVec> _fixed_E_Field;
std::vector<RealVec> _fixed_E_FieldPolar;
std::vector<RealVec> _inducedDipole;
std::vector<RealVec> _inducedDipolePolar;
int _mutualInducedDipoleConverged;
int _mutualInducedDipoleIterations;
int _maximumMutualInducedDipoleIterations;
......@@ -261,16 +251,25 @@ private:
RealOpenMM _polarSOR;
RealOpenMM _debye;
enum QuadrupoleIndices { QXX, QXY, QXZ, QYY, QYZ, QZZ };
/**---------------------------------------------------------------------------------------
Helper constructor method to centralize initialization of objects
--------------------------------------------------------------------------------------- */
/**
* Helper constructor method to centralize initialization of objects
*
*/
void initialize( void );
/**
* Load particle data
*
* @param particlePositions particle coordinates
* @param charges charges
* @param dipoles dipoles
* @param quadrupoles quadrupoles
* @param tholes Thole parameters
* @param dampingFactors dampming factors
* @param polarity polarity
* @param particleData output data struct
*
*/
void loadParticleData( const std::vector<OpenMM::RealVec>& particlePositions,
const std::vector<RealOpenMM>& charges,
const std::vector<RealOpenMM>& dipoles,
......@@ -280,259 +279,543 @@ private:
const std::vector<RealOpenMM>& polarity,
std::vector<MultipoleParticleData>& particleData ) const;
/**---------------------------------------------------------------------------------------
Set flag indicating if mutual induced dipoles are converged
@param nonzero if converged
--------------------------------------------------------------------------------------- */
void setMutualInducedDipoleConverged( int iterations );
/**---------------------------------------------------------------------------------------
Set number of iterations used in computing mutual induced dipoles
@param number of iterations
/**
* Calculate fixed electric fields
*
* @param particleData vector particle data
*
*/
virtual void calculateFixedEField( vector<MultipoleParticleData>& particleData );
--------------------------------------------------------------------------------------- */
/**
* Set flag indicating if mutual induced dipoles are converged
*
* @param converged nonzero if converged
*
*/
void setMutualInducedDipoleConverged( int converged );
/**
* Set number of iterations used in computing mutual induced dipoles
*
* @param number of iterations
*
*/
void setMutualInducedDipoleIterations( int iterations );
/**---------------------------------------------------------------------------------------
Set the final epsilon for mutual induced dipoles
@param epsilon
--------------------------------------------------------------------------------------- */
/**
* Set the final epsilon for mutual induced dipoles
*
* @param epsilon
*
*/
void setMutualInducedDipoleEpsilon( RealOpenMM epsilon );
/**---------------------------------------------------------------------------------------
Get delta between positions of two particles
@param particleI index of particleI
@param particleJ index of particleJ
@param delta output: delta[0] = pos[particleJ][0] - pos[particleI][0], ...
--------------------------------------------------------------------------------------- */
void getDelta( unsigned int particleI, unsigned int particleJ, std::vector<OpenMM::RealVec>& particlePositions, RealOpenMM* delta ) const;
/**---------------------------------------------------------------------------------------
Get delta between positions of two particles
@param particleI index of particleI
@param particleJ index of particleJ
@param delta output: delta[0] = pos[particleJ][0] - pos[particleI][0], ...
--------------------------------------------------------------------------------------- */
void getDelta( const MultipoleParticleData& particleI, const MultipoleParticleData& particleJ, RealOpenMM* delta ) const;
/**---------------------------------------------------------------------------------------
Load values from vector (dipole, quadrupoles vectors for example) into an array
@param particleI index of particleI whose values are to be loaded
@param offset offset to use (3 for dipole, 9 for quadrupole)
@param vectorToCopy vector of values to be loaded
@param loadArray on return contains loaded values
--------------------------------------------------------------------------------------- */
/**
* Setup scale factors given covalent info
*
* @param multipoleAtomCovalentInfo vector of vectors containing the covalent info
*
*/
void setupScaleMaps( const std::vector< std::vector< std::vector<int> > >& multipoleAtomCovalentInfo );
void loadArrayFromVector( unsigned int particleI, unsigned int offset, const std::vector<RealOpenMM>& vectorToCopy, RealOpenMM* loadArray ) const;
/**
* Get multipole scale factor for particleI & particleJ
*
* @param particleI index of particleI whose scale factor is to be retrieved
* @param particleJ index of particleJ whose scale factor is to be retrieved
* @param scaleType scale type (D_SCALE, P_SCALE, M_SCAL)
*
* @return scaleFactor
*/
RealOpenMM getMultipoleScaleFactor( unsigned int particleI, unsigned int particleJ, ScaleType scaleType ) const;
/**---------------------------------------------------------------------------------------
/**
* Get scale factor for particleI & particleJ
*
* @param particleI index of particleI whose scale factor is to be retrieved
* @param particleJ index of particleJ whose scale factor is to be retrieved
* @param scaleType scale type (D_SCALE, P_SCALE, M_SCAL)
*
* @return array of scaleFactors
*/
void getMultipoleScaleFactors( unsigned int particleI, unsigned int particleJ, std::vector<RealOpenMM>& scaleFactors ) const;
Add fields valus to vector
/**
* Get p- and d-scale factors for particleI & particleJ ixn
*
* @param particleI index of particleI
* @param particleJ index of particleJ
* @param dScale output d-scale factor
* @param pScale output p-scale factor
*/
void getDScaleAndPScale( unsigned int particleI, unsigned int particleJ, RealOpenMM& dScale, RealOpenMM& pScale ) const;
@param particleIOffset index of particleI times offset (3,9 for dipole. quadrupole) whose values are to be updated
@param sign if > 0, then add the field values; otherwise subtract the values
@param field field values
@param vectorToAddTo vector whose of values are to be incremented by the values in field
/**
* Calculate damped powers of 1/r
*
* @param particleI index of particleI
* @param particleJ index of particleJ
* @param dScale output d-scale factor
* @param pScale output p-scale factor
*/
void getAndScaleInverseRs( RealOpenMM dampI, RealOpenMM dampJ, RealOpenMM tholeI, RealOpenMM tholeJ,
RealOpenMM r, std::vector<RealOpenMM>& rrI ) const;
--------------------------------------------------------------------------------------- */
/**
* Check if multipoles at chiral site should be inverted
*
* @param particleI particleI data
* @param axisType axis type
* @param particleZ z-axis particle to particleI
* @param particleX x-axis particle to particleI
* @param particleY y-axis particle to particleI
*
*/
void checkChiralCenterAtParticle( MultipoleParticleData& particleI, int axisType, MultipoleParticleData& particleZ,
MultipoleParticleData& particleX, MultipoleParticleData& particleY ) const;
void addField( unsigned int particleIOffset, int sign, RealOpenMM field[3], std::vector<RealOpenMM>& vectorToAddTo ) const;
/**
* Invert multipole moments (dipole[Y], quadrupole[XY] and quadrupole[YZ]) if chiral center inverted
*
* @param particleData vector of parameters (charge, labFrame dipoles, quadrupoles, ...) for particles
* @param multipoleAtomXs vector of z-particle indices used to map molecular frame to lab frame
* @param multipoleAtomYs vector of x-particle indices used to map molecular frame to lab frame
* @param multipoleAtomZs vector of y-particle indices used to map molecular frame to lab frame
* @param axisType axis type
*/
void checkChiral( std::vector<MultipoleParticleData>& particleData,
const std::vector<int>& multipoleAtomXs,
const std::vector<int>& multipoleAtomYs,
const std::vector<int>& multipoleAtomZs,
const std::vector<int>& axisTypes ) const;
/**
* Apply rotation matrix to molecular dipole/quadrupoles to get corresponding lab frame values
* for particle I
*
* @param particleI particleI data
* @param particleJ particleI data
* @param axisType axis type
*/
void applyRotationMatrixToParticle( MultipoleParticleData& particleI,
const MultipoleParticleData& particleZ,
const MultipoleParticleData& particleX,
MultipoleParticleData* particleY, int axisType ) const;
void logRealOpenMMVectors( const std::string& header, const VectorOfRealOpenMMVectors& printVector,
FILE* log = NULL, unsigned int itemsPerVector = 1, int maxPrint = -1 ) const;
/**
* Apply rotation matrix to molecular dipole/quadrupoles to get corresponding lab frame values
*
* @param particleData vector of parameters (charge, labFrame dipoles, quadrupoles, ...) for particles
* dipole and quadrupole entries are modified
* @param multipoleAtomXs vector of z-particle indices used to map molecular frame to lab frame
* @param multipoleAtomYs vector of x-particle indices used to map molecular frame to lab frame
* @param multipoleAtomZs vector of y-particle indices used to map molecular frame to lab frame
* @param axisType axis type
*/
void applyRotationMatrix( std::vector<MultipoleParticleData>& particleData,
const std::vector<int>& multipoleAtomXs,
const std::vector<int>& multipoleAtomYs,
const std::vector<int>& multipoleAtomZs,
const std::vector<int>& axisTypes ) const;
/**
* Zero fixed E-fields
*/
virtual void zeroFixed_E_Fields( void );
void logParticleData( const std::string& header, const std::vector<MultipoleParticleData>& particleData,
unsigned int printFlag, FILE* log, unsigned int maxPrint ) const;
/**
* Calculate electric field at particle I due fixed multipoles at particle J and vice versa
* (field at particle J due fixed multipoles at particle I)
*
* @param particleI positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle I
* @param particleJ positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle J
* @param dScale d-scale value for i-j interaction
* @param pScale p-scale value for i-j interaction
*/
virtual void calculateFixedEFieldPairIxn( MultipoleParticleData& particleI, MultipoleParticleData& particleJ,
RealOpenMM dScale, RealOpenMM pScale );
void showScaleMapForParticle( unsigned int particleI, FILE* log ) const;
/**
* Calculate field at particle I due induced dipole at particle J and vice versa
* (field at particle J due induced dipole at particle I)
*
* @param particleI index of particle I
* @param particleJ index of particle J
* @param rr3 damped 1/r^3 factor
* @param rr5 damped 1/r^5 factor
* @param delta delta of particle positions: particleJ.x - particleI.x, ...
* @param inducedDipole vector of induced dipoles
* @param field vector of induced dipole fields
*/
void calculateInducedDipolePairIxn( unsigned int particleI, unsigned int particleJ,
RealOpenMM rr3, RealOpenMM rr5, const RealVec& delta,
const std::vector<RealVec>& inducedDipole,
std::vector<RealVec>& field ) const;
/**---------------------------------------------------------------------------------------
/**
* Calculate fields due induced dipoles at each site
*
* @param particleI positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle I
* @param particleJ positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle J
* @param updateInducedDipoleFields vector of UpdateInducedDipoleField containing input induced dipoles and output fields
*/
virtual void calculateInducedDipolePairIxns( const MultipoleParticleData& particleI, const MultipoleParticleData& particleJ,
std::vector<UpdateInducedDipoleField>& updateInducedDipoleFields );
Setup scale factors given covalent info
/**
* Converge induced dipoles
*
* @param particleData vector of particle positions and parameters (charge, labFrame dipoles, quadrupoles, ...)
* @param updateInducedDipoleFields vector of UpdateInducedDipoleField containing input induced dipoles and output fields
*/
void convergeInduceDipoles( const std::vector<MultipoleParticleData>& particleData,
std::vector<UpdateInducedDipoleField>& calculateInducedDipoleField );
@param multipoleAtomCovalentInfo vector of vectors containing the covalent info
/**
* Update fields due to induced dipoles for each particle
*
* @param particleData vector of particle positions and parameters (charge, labFrame dipoles, quadrupoles, ...)
* @param updateInducedDipoleFields vector of UpdateInducedDipoleField containing input induced dipoles and output fields
*/
RealOpenMM updateInducedDipoleFields( const std::vector<MultipoleParticleData>& particleData,
std::vector<UpdateInducedDipoleField>& calculateInducedDipoleField);
--------------------------------------------------------------------------------------- */
/**
* Update induced dipole for a particle given updated induced dipole field at the site
*
* @param particleI positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle I
* @param fixed_E_Field fields due fixed multipoles at each site
* @param inducedDipoleField fields due induced dipoles at each site
* @param inducedDipoles output vector of updated induced dipoles
*/
RealOpenMM updateInducedDipole( const std::vector<MultipoleParticleData>& particleI,
const std::vector<RealVec>& fixed_E_Field,
const std::vector<RealVec>& inducedDipoleField,
std::vector<RealVec>& inducedDipoles);
void setupScaleMaps( const std::vector< std::vector< std::vector<int> > >& multipoleAtomCovalentInfo );
/**
* Calculate induced dipoles
*
* @param polarizationType if 'Direct' polariztion, only initial induced dipoles calculated
* if 'Mutual' polariztion, induced dipoles converged to specified tolerance
* @param particleData vector of particle positions and parameters (charge, labFrame dipoles, quadrupoles, ...)
*/
virtual void calculateInducedDipoles( AmoebaReferenceMultipoleForce::PolarizationType polarizationType, const std::vector<MultipoleParticleData>& particleData );
/**---------------------------------------------------------------------------------------
/**
* Calculate electrostatic interaction between particles I and K
*
* @param polarizationType if 'Direct' polariztion, only initial induced dipoles calculated
* if 'Mutual' polariztion, induced dipoles converged to specified tolerance
* @param particleI positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle I
* @param particleK positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle K
* @param scalingFactors scaling factors for interaction
* @param forces vector of particle forces to be updated
* @param torques vector of particle torques to be updated
*/
RealOpenMM calculateElectrostaticPairIxn( AmoebaReferenceMultipoleForce::PolarizationType polarizationType,
const MultipoleParticleData& particleI, const MultipoleParticleData& particleK,
const std::vector<RealOpenMM>& scalingFactors, std::vector<OpenMM::RealVec>& forces, std::vector<RealVec>& torque ) const;
Get scale factor for particleI & particleJ
/**
* Map torque to forces
*
* @param particleI particle whose torque is to be mapped
* @param particleU particle1 of lab frame for particleI
* @param particleV particle2 of lab frame for particleI
* @param particleW particle3 of lab frame for particleI
* @param axisType axis type (Bisector/Z-then-X, ...)
* @param torque torque on particle I
*/
void mapTorqueToForceForParticle( const MultipoleParticleData& particleI,
const MultipoleParticleData& particleU,
const MultipoleParticleData& particleV,
MultipoleParticleData* particleW,
int axisType, const Vec3& torque, std::vector<OpenMM::RealVec>& forces ) const;
@param particleI index of particleI whose scale factor is to be retreived
@param particleJ index of particleJ whose scale factor is to be retreived
@param scaleType scale type (D_SCALE, P_SCALE, M_SCAL)
/**
* Map torques to forces
*
* @param particleData vector of parameters (charge, labFrame dipoles, quadrupoles, ...) for particles
* @param multipoleAtomZs vector of z-particle indices used to map molecular frame to lab frame
* @param multipoleAtomXs vector of x-particle indices used to map molecular frame to lab frame
* @param multipoleAtomYs vector of y-particle indices used to map molecular frame to lab frame
* @param axisType vector of axis types (Bisector/Z-then-X, ...) for particles
* @param torques output torques
* @param forces output forces
*
* @return energy
*/
void mapTorqueToForce( std::vector<MultipoleParticleData>& particleData,
const std::vector<int>& multipoleAtomXs,
const std::vector<int>& multipoleAtomYs,
const std::vector<int>& multipoleAtomZs,
const std::vector<int>& axisTypes,
std::vector<OpenMM::RealVec>& torques,
std::vector<OpenMM::RealVec>& forces ) const;
@return scaleFactor
/**
* Calculate electrostatic forces
*
* @param particleData vector of parameters (charge, labFrame dipoles, quadrupoles, ...) for particles
* @param axisType vector of axis types (Bisector/Z-then-X, ...) for particles
* @param multipoleAtomZs vector of z-particle indices used to map molecular frame to lab frame
* @param multipoleAtomXs vector of x-particle indices used to map molecular frame to lab frame
* @param multipoleAtomYs vector of y-particle indices used to map molecular frame to lab frame
* @param polarizationType polarization type (direct or mutual)
* @param torques output torques
* @param forces output forces
*
* @return energy
*/
virtual RealOpenMM calculateElectrostatic( std::vector<MultipoleParticleData>& particleData,
const std::vector<int>& axisTypes,
const std::vector<int>& multipoleAtomZs,
const std::vector<int>& multipoleAtomXs,
const std::vector<int>& multipoleAtomYs,
AmoebaReferenceMultipoleForce::PolarizationType polarizationType,
std::vector<OpenMM::RealVec>& torques,
std::vector<OpenMM::RealVec>& forces ) const;
--------------------------------------------------------------------------------------- */
/**
* Normalize a RealVec
*
* @param vectorToNormalize vector to normalize
*
* @return norm of vector on input
*
*/
RealOpenMM normalizeRealVec( RealVec& vectorToNormalize ) const;
RealOpenMM getScaleFactor( unsigned int particleI, unsigned int particleJ, ScaleType scaleType ) const;
void getScaleFactors( unsigned int particleI, unsigned int particleJ, RealOpenMM* scaleFactors ) const;
/**
* Initialize vector of RealOpenMM (size=numParticles)
*
* @param vectorToInitialize vector to initialize
*
*/
void initializeRealOpenMMVector( vector<RealOpenMM>& vectorToInitialize ) const;
/**---------------------------------------------------------------------------------------
/**
* Initialize vector of RealVec (size=numParticles)
*
* @param vectorToInitialize vector to initialize
*
*/
void initializeRealVecVector( vector<RealVec>& vectorToInitialize ) const;
Scale field for particleI & particleJ ixn
/**
* Copy vector of RealVec
*
* @param inputVector vector to copy
* @param outputVector output vector
*
*/
void copyRealVecVector( const std::vector<OpenMM::RealVec>& inputVector, std::vector<OpenMM::RealVec>& outputVector ) const;
@param particleI index of particleI
@param particleJ index of particleJ
@param field field to scale
void showScaleMapForParticle( unsigned int particleI, FILE* log ) const;
};
--------------------------------------------------------------------------------------- */
class AmoebaReferenceGeneralizedKirkwoodMultipoleForce : public AmoebaReferenceMultipoleForce {
void getDScaleAndPScale( unsigned int particleI, unsigned int particleJ, RealOpenMM& dScale, RealOpenMM& pScale ) const;
public:
void getAndScaleInverseRs( RealOpenMM dampI, RealOpenMM dampJ, RealOpenMM tholeI, RealOpenMM tholeJ,
RealOpenMM r, std::vector<RealOpenMM>& rrI ) const;
/**
* Constructor
*
*/
AmoebaReferenceGeneralizedKirkwoodMultipoleForce( AmoebaReferenceGeneralizedKirkwoodForce* amoebaReferenceGeneralizedKirkwoodForce );
/**---------------------------------------------------------------------------------------
/**
* Destructor
*
*/
~AmoebaReferenceGeneralizedKirkwoodMultipoleForce( );
Check multipoles at chiral sites
/**
* Get flag signalling whether cavity term is to be included
*
* @return flag
*
*/
int getIncludeCavityTerm( void ) const;
inverts atomic multipole moments as necessary
at sites with chiral local reference frame definitions
/**
* Get probe radius
*
* @return probe radius
*
*/
RealOpenMM getProbeRadius( void ) const;
@param particleI particleI data
@param axisType axis type
@param particleZ z-axis particle to particleI
@param particleX x-axis particle to particleI
@param particleY y-axis particle to particleI
/**
* Get surface area factor
*
* @return surface area factor
*
*/
RealOpenMM getSurfaceAreaFactor( void ) const;
--------------------------------------------------------------------------------------- */
/**
* Get dielectric offset
*
* @return dielectric offset
*
*/
RealOpenMM getDielectricOffset( void ) const;
void checkChiral( MultipoleParticleData& particleI, int axisType, MultipoleParticleData& particleZ,
MultipoleParticleData& particleX, MultipoleParticleData& particleY ) const;
private:
/**---------------------------------------------------------------------------------------
AmoebaReferenceGeneralizedKirkwoodForce* _amoebaReferenceGeneralizedKirkwoodForce;
Apply roatation matrix to molecular dipole/quadrupoles to get corresponding lab frame values
for particle I
RealOpenMM _gkc;
RealOpenMM _fc;
RealOpenMM _fd;
RealOpenMM _fq;
@param particleI particleI data
@param particleJ particleI data
@param axisType axis type
std::vector<RealOpenMM> _atomicRadii;
std::vector<RealOpenMM> _scaledRadii;
std::vector<RealOpenMM> _bornRadii;
std::vector<RealOpenMM> _bornForce;
--------------------------------------------------------------------------------------- */
std::vector<RealVec> _gkField;
std::vector<RealVec> _inducedDipoleS;
std::vector<RealVec> _inducedDipolePolarS;
void applyRotationMatrix( MultipoleParticleData& particleI,
const MultipoleParticleData& particleZ,
const MultipoleParticleData& particleX,
MultipoleParticleData* particleY, int axisType ) const;
int _includeCavityTerm;
RealOpenMM _probeRadius;
RealOpenMM _surfaceAreaFactor;
RealOpenMM _dielectricOffset;
void applyRotationMatrixOld( MultipoleParticleData& particleI,
const MultipoleParticleData& particleZ,
const MultipoleParticleData& particleX, int axisType ) const;
/**
* Zero fixed E-fields
*
*/
void zeroFixed_E_Fields( void );
/**
* Calculate electric field at particle I due fixed multipoles at particle J and vice versa
* (field at particle J due fixed multipoles at particle I)
*
* @param particleI positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle I
* @param particleJ positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle J
* @param dScale d-scale value for i-j interaction
* @param pScale p-scale value for i-j interaction
*/
void calculateFixedEFieldPairIxn( MultipoleParticleData& particleI, MultipoleParticleData& particleJ,
RealOpenMM dScale, RealOpenMM pScale ) const;
RealOpenMM dScale, RealOpenMM pScale );
void calculateInducedDipolePairIxn( MultipoleParticleData& particleI, MultipoleParticleData& particleJ,
std::vector<RealOpenMM>& field, std::vector<RealOpenMM>& fieldPolar ) const;
void updateInducedDipole( MultipoleParticleData& particleI,
const std::vector<RealOpenMM>& field,
const std::vector<RealOpenMM>& fieldPolar,
RealOpenMM& epsilonD, RealOpenMM& epsilonP ) const;
void calculateNoCutoffInducedDipoles( int polarizationType, std::vector<MultipoleParticleData>& particleData );
void calculateInducedDipoleField( std::vector<MultipoleParticleData>& particleData,
std::vector<RealOpenMM>& field,
std::vector<RealOpenMM>& fieldPolar ) const;
RealOpenMM calculateNoCutoffElectrostaticPairIxn( int polarizationType, const MultipoleParticleData& particleI,
const MultipoleParticleData& particleK,
RealOpenMM* scalingFactors, std::vector<OpenMM::RealVec>& forces, std::vector<Vec3>& torque ) const;
/**---------------------------------------------------------------------------------------
Map torque to forces
@param particleI particle whose torque is to be mapped
@param particleU particle1 of lab frame for particleI
@param particleV particle2 of lab frame for particleI
@param particleW particle3 of lab frame for particleI
@param axisType axis type (Bisector/Z-then-X, ...)
@param torque torque on particle I
--------------------------------------------------------------------------------------- */
void mapTorqueToForce( const MultipoleParticleData& particleI,
const MultipoleParticleData& particleU,
const MultipoleParticleData& particleV,
MultipoleParticleData* particleW,
int axisType, const Vec3& torque, std::vector<OpenMM::RealVec>& forces ) const;
/**
* Calculate induced dipoles
*
* @param polarizationType if 'Direct' polariztion, only initial induced dipoles calculated
* if 'Mutual' polariztion, induced dipoles converged to specified tolerance
* @param particleData vector of particle positions and parameters (charge, labFrame dipoles, quadrupoles, ...)
*/
void calculateInducedDipoles( AmoebaReferenceMultipoleForce::PolarizationType polarizationType, const std::vector<MultipoleParticleData>& particleData );
void mapTorqueToForceOld( const MultipoleParticleData& particleI,
const MultipoleParticleData& particleU,
const MultipoleParticleData& particleV,
int axisType, const Vec3& torque, std::vector<OpenMM::RealVec>& forces ) const;
/**
* Calculate fields due induced dipoles at each site
*
* @param particleI positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle I
* @param particleJ positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle J
* @param updateInducedDipoleFields vector of UpdateInducedDipoleField containing input induced dipoles and output fields
*/
void calculateInducedDipolePairIxns( const MultipoleParticleData& particleI, const MultipoleParticleData& particleJ,
std::vector<UpdateInducedDipoleField>& updateInducedDipoleFields );
RealOpenMM calculateNoCutoffElectrostatic( std::vector<MultipoleParticleData>& particleData,
/**
* Calculate electrostatic forces
*
* @param particleData vector of parameters (charge, labFrame dipoles, quadrupoles, ...) for particles
* @param axisType vector of axis types (Bisector/Z-then-X, ...) for particles
* @param multipoleAtomZs vector of z-particle indices used to map molecular frame to lab frame
* @param multipoleAtomXs vector of x-particle indices used to map molecular frame to lab frame
* @param multipoleAtomYs vector of y-particle indices used to map molecular frame to lab frame
* @param polarizationType polarization type (direct or mutual)
* @param torques output torques
* @param forces output forces
*
* @return energy
*/
RealOpenMM calculateElectrostatic( std::vector<MultipoleParticleData>& particleData,
const std::vector<int>& axisTypes,
const std::vector<int>& multipoleAtomZs,
const std::vector<int>& multipoleAtomXs,
const std::vector<int>& multipoleAtomYs,
int polarizationType,
AmoebaReferenceMultipoleForce::PolarizationType polarizationType,
std::vector<OpenMM::RealVec>& torques,
std::vector<OpenMM::RealVec>& forces ) const;
/**---------------------------------------------------------------------------------------
Calculate Multipole ixns w/ no cutoff
/**
* Calculate GK field at particle I due induced dipole at particle J and vice versa
* (field at particle J due induced dipole at particle I)
*
* @param particleI index of particle I
* @param particleJ index of particle J
* @param field vector of induced dipole fields
* @param fieldPolar vector of induced dipole polar fields
*/
void calculateInducedDipolePairGkIxn( const MultipoleParticleData& particleI, const MultipoleParticleData& particleJ,
const std::vector<RealVec>& field, std::vector<RealVec>& fieldPolar ) const;
@param numParticles number of particles
@param particlePositions Cartesian coordinates of particles
@param indexIVs position index for associated reducing particle
@param indexClasses class index for combining sigmas/epsilons (not currently used)
@param sigmas particle sigmas
@param epsilons particle epsilons
@param reductions particle reduction factors
@param vdwExclusions particle exclusions
@param forces add forces to this vector
/**
* Calculate Kirkwood interaction
*
* @param polarizationType polarization type ( direct or mutual )
* @param particleI particle parameters (charge, labFrame dipoles, quadrupoles, ...) for particle I
* @param particleJ particle parameters (charge, labFrame dipoles, quadrupoles, ...) for particle J
* @param forces add Kirkwood force to forces
* @param torques add Kirkwood torque to torques
* @param dBorn chain-rule factor
*
* @return energy
*/
RealOpenMM calculateKirkwoodPairIxn( AmoebaReferenceMultipoleForce::PolarizationType polarizationType,
const MultipoleParticleData& particleI, const MultipoleParticleData& particleJ,
std::vector<RealVec>& forces,
std::vector<RealVec>& torques,
std::vector<RealOpenMM>& dBorn ) const;
@return energy
/**
* Calculate Grycuk 'chain-rule' force
*
* @param particleI particle parameters (charge, labFrame dipoles, quadrupoles, ...) for particle I
* @param particleJ particle parameters (charge, labFrame dipoles, quadrupoles, ...) for particle J
* @param dBorn chain-rule Born force factor
* @param forces add Kirkwood force to forces
*
*/
void calculateGrycukChainRulePairIxn( const MultipoleParticleData& particleI, const MultipoleParticleData& particleJ,
const std::vector<RealOpenMM>& dBorn, std::vector<RealVec>& forces ) const;
--------------------------------------------------------------------------------------- */
/**
* Calculate TINKER's ACE approximation to non-polar cavity term
*
* @param forces add Kirkwood force to forces
*
* @return energy
*
*/
RealOpenMM calculateCavityTermEnergyAndForces( std::vector<RealOpenMM>& dBorn ) const;
RealOpenMM calculateNoCutoffForceAndEnergy( const std::vector<OpenMM::RealVec>& particlePositions,
const std::vector<RealOpenMM>& charges,
const std::vector<RealOpenMM>& dipoles,
const std::vector<RealOpenMM>& quadrupoles,
const std::vector<RealOpenMM>& tholes,
const std::vector<RealOpenMM>& dampingFactors,
const std::vector<RealOpenMM>& polarity,
const std::vector<int>& axisTypes,
const std::vector<int>& multipoleAtomZs,
const std::vector<int>& multipoleAtomXs,
const std::vector<int>& multipoleAtomYs,
int polarizationType,
std::vector<OpenMM::RealVec>& forces );
/**
* Correct vacuum to SCRF derivatives
*
* @param polarizationType polarization type ( direct or mutual )
* @param particleI particle parameters (charge, labFrame dipoles, quadrupoles, ...) for particle I
* @param particleJ particle parameters (charge, labFrame dipoles, quadrupoles, ...) for particle J
* @param pscale p-scale factor
* @param dscale d-scale factor
* @param forces force accumulator
* @param torques torque accumulator
*
* @return energy
*/
RealOpenMM calculateKirkwoodEDiffPairIxn( AmoebaReferenceMultipoleForce::PolarizationType polarizationType,
const MultipoleParticleData& particleI, const MultipoleParticleData& particleJ,
RealOpenMM pscale, RealOpenMM dscale,
std::vector<RealVec>& forces, std::vector<RealVec>& torques ) const;
};
// ---------------------------------------------------------------------------------------
#endif // _AmoebaReferenceMultipoleForce___
This source diff could not be displayed because it is too large. You can view the blob instead.
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