/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see . *
* -------------------------------------------------------------------------- */
#include "ValidateOpenMM.h"
using namespace OpenMM;
// fixed force names
const std::string ValidateOpenMM::HARMONIC_BOND_FORCE = "HarmonicBond";
const std::string ValidateOpenMM::HARMONIC_ANGLE_FORCE = "HarmonicAngle";
const std::string ValidateOpenMM::PERIODIC_TORSION_FORCE = "PeriodicTorsion";
const std::string ValidateOpenMM::RB_TORSION_FORCE = "RbTorsion";
const std::string ValidateOpenMM::NB_FORCE = "Nb";
const std::string ValidateOpenMM::NB_SOFTCORE_FORCE = "NbSoftcore";
const std::string ValidateOpenMM::NB_EXCEPTION_FORCE = "NbException";
const std::string ValidateOpenMM::NB_EXCEPTION_SOFTCORE_FORCE = "NbSoftcoreException";
const std::string ValidateOpenMM::GBSA_OBC_FORCE = "Obc";
const std::string ValidateOpenMM::GBSA_OBC_SOFTCORE_FORCE = "ObcSoftcore";
const std::string ValidateOpenMM::GBVI_FORCE = "GBVI";
const std::string ValidateOpenMM::GBVI_SOFTCORE_FORCE = "GBVISoftcore";
const std::string ValidateOpenMM::CM_MOTION_REMOVER = "CMMotionRemover";
const std::string ValidateOpenMM::ANDERSEN_THERMOSTAT = "AndersenThermostat";
const std::string ValidateOpenMM::CUSTOM_BOND_FORCE = "CustomBond";
const std::string ValidateOpenMM::CUSTOM_EXTERNAL_FORCE = "CustomExternal";
const std::string ValidateOpenMM::CUSTOM_NONBONDED_FORCE = "CustomNonBonded";
ValidateOpenMM::ValidateOpenMM( void ) {
_log = NULL;
// force dependencies
// these may need to specialized depending on platform since
// currently apply to Cuda platform, but may not apply to OpenCL platform
std::vector< std::string > nbVector;
nbVector.push_back( NB_FORCE );
_forceDependencies[GBSA_OBC_FORCE] = nbVector;
_forceDependencies[GBVI_FORCE] = nbVector;
std::vector< std::string > nbSoftcoreVector;
nbSoftcoreVector.push_back( NB_SOFTCORE_FORCE );
_forceDependencies[GBSA_OBC_SOFTCORE_FORCE] = nbSoftcoreVector;
_forceDependencies[GBVI_SOFTCORE_FORCE] = nbSoftcoreVector;
}
ValidateOpenMM::~ValidateOpenMM() {
}
int ValidateOpenMM::isNan( double number ){
return isinf( number ) || isnan( number ) ? 1 : 0;
}
FILE* ValidateOpenMM::getLog( void ) const {
return _log;
}
void ValidateOpenMM::setLog( FILE* log ){
_log = log;
}
std::string ValidateOpenMM::getForceName(const Force& force) const {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "ValidateForce::getForceName";
// ---------------------------------------------------------------------------------------
std::string forceName = "NA";
// bond force
try {
const HarmonicBondForce& harmonicBondForce = dynamic_cast(force);
return HARMONIC_BOND_FORCE;
} catch( std::bad_cast ){
}
// angle force
try {
const HarmonicAngleForce& harmonicAngleForce = dynamic_cast(force);
return HARMONIC_ANGLE_FORCE;
} catch( std::bad_cast ){
}
// periodic torsion force
try {
const PeriodicTorsionForce & periodicTorsionForce = dynamic_cast(force);
return PERIODIC_TORSION_FORCE;
} catch( std::bad_cast ){
}
// RB torsion force
try {
const RBTorsionForce& rBTorsionForce = dynamic_cast(force);
return RB_TORSION_FORCE;
} catch( std::bad_cast ){
}
// nonbonded force
try {
const NonbondedForce& nbForce = dynamic_cast(force);
return NB_FORCE;
} catch( std::bad_cast ){
}
// GBSA OBC
try {
const GBSAOBCForce& obcForce = dynamic_cast(force);
return GBSA_OBC_FORCE;
} catch( std::bad_cast ){
}
// GB/VI
try {
const GBVIForce& obcForce = dynamic_cast(force);
return GBVI_FORCE;
} catch( std::bad_cast ){
}
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
// free energy plugin forces
// nonbonded softcore
try {
const NonbondedSoftcoreForce& nbForce = dynamic_cast(force);
return NB_SOFTCORE_FORCE;
} catch( std::bad_cast ){
}
// GBSA OBC softcore
try {
const GBSAOBCSoftcoreForce& obcForce = dynamic_cast(force);
return GBSA_OBC_SOFTCORE_FORCE;
} catch( std::bad_cast ){
}
// GB/VI softcore
try {
const GBVISoftcoreForce& gbviForce = dynamic_cast(force);
return GBVI_SOFTCORE_FORCE;
} catch( std::bad_cast ){
}
#endif
// CMMotionRemover
try {
const CMMotionRemover& cMMotionRemover = dynamic_cast(force);
return CM_MOTION_REMOVER;
} catch( std::bad_cast ){
}
// AndersenThermostat
try {
const AndersenThermostat & andersenThermostat = dynamic_cast(force);
return ANDERSEN_THERMOSTAT;
} catch( std::bad_cast ){
}
// CustomBondForce
try {
const CustomBondForce & customBondForce = dynamic_cast(force);
return CUSTOM_BOND_FORCE;
} catch( std::bad_cast ){
}
// CustomExternalForce
try {
const CustomExternalForce& customExternalForce = dynamic_cast(force);
return CUSTOM_EXTERNAL_FORCE;
} catch( std::bad_cast ){
}
// CustomNonbondedForce
try {
const CustomNonbondedForce& customNonbondedForce = dynamic_cast(force);
return CUSTOM_NONBONDED_FORCE;
} catch( std::bad_cast ){
}
return forceName;
}
Force* ValidateOpenMM::copyForce(const Force& force) const {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "ValidateForce::copyForce";
// ---------------------------------------------------------------------------------------
// bond force
try {
const HarmonicBondForce& harmonicBondForce = dynamic_cast(force);
return copyHarmonicBondForce( harmonicBondForce );
} catch( std::bad_cast ){
}
// angle force
try {
const HarmonicAngleForce& harmonicAngleForce = dynamic_cast(force);
return copyHarmonicAngleForce( harmonicAngleForce );
} catch( std::bad_cast ){
}
// periodic torsion force
try {
const PeriodicTorsionForce & periodicTorsionForce = dynamic_cast(force);
return copyPeriodicTorsionForce( periodicTorsionForce );
} catch( std::bad_cast ){
}
// RB torsion force
try {
const RBTorsionForce& rBTorsionForce = dynamic_cast(force);
return copyRBTorsionForce( rBTorsionForce );
} catch( std::bad_cast ){
}
// nonbonded force
try {
const NonbondedForce& nbForce = dynamic_cast(force);
return copyNonbondedForce( nbForce );
} catch( std::bad_cast ){
}
// GBSA OBC
try {
const GBSAOBCForce& obcForce = dynamic_cast(force);
return copyGBSAOBCForce( obcForce );
} catch( std::bad_cast ){
}
// GB/VI
try {
const GBVIForce& gbviForce = dynamic_cast(force);
return copyGBVIForce( gbviForce );
} catch( std::bad_cast ){
}
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
// free energy plugin forces
// nonbonded softcore
try {
const NonbondedSoftcoreForce& nbForce = dynamic_cast(force);
return copyNonbondedSoftcoreForce( nbForce );
} catch( std::bad_cast ){
}
// GBSA OBC softcore
try {
const GBSAOBCSoftcoreForce& obcForce = dynamic_cast(force);
return copyGBSAOBCSoftcoreForce( obcForce );
} catch( std::bad_cast ){
}
// GB/VI softcore
try {
const GBVISoftcoreForce& gbviForce = dynamic_cast(force);
return copyGBVISoftcoreForce( gbviForce );
} catch( std::bad_cast ){
}
#endif
// CMMotionRemover
try {
const CMMotionRemover& cMMotionRemover = dynamic_cast(force);
return NULL;
} catch( std::bad_cast ){
}
// AndersenThermostat
try {
const AndersenThermostat & andersenThermostat = dynamic_cast(force);
return NULL;
} catch( std::bad_cast ){
}
// CustomBondForce
try {
const CustomBondForce & customBondForce = dynamic_cast(force);
return NULL;
} catch( std::bad_cast ){
}
// CustomExternalForce
try {
const CustomExternalForce& customExternalForce = dynamic_cast(force);
return NULL;
} catch( std::bad_cast ){
}
// CustomNonbondedForce
try {
const CustomNonbondedForce& customNonbondedForce = dynamic_cast(force);
return NULL;
} catch( std::bad_cast ){
}
return NULL;
}
/**
* Get copy of input system, but leave out forces
*
* @param systemToCopy system to copy
* @return system w/o forces
*/
System* ValidateOpenMM::copySystemExcludingForces( const System& systemToCopy ) const {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "ValidateOpenMM::copySystemExcludingForces";
// ---------------------------------------------------------------------------------------
// create new system and add masses and box dimensions
System* system = new System();
for(int ii = 0; ii < systemToCopy.getNumParticles(); ii++ ){
double mass = systemToCopy.getParticleMass( ii );
system->addParticle( mass );
}
Vec3 a, b, c;
systemToCopy.getPeriodicBoxVectors( a, b, c );
system->setPeriodicBoxVectors( a, b, c );
copyConstraints( systemToCopy, system );
return system;
}
/**---------------------------------------------------------------------------------------
Set the velocities/positions of context2 to those of context1
@param context1 context1
@param context2 context2
@return 0
--------------------------------------------------------------------------------------- */
void ValidateOpenMM::synchContexts( const Context& context1, Context& context2 ) const {
// ---------------------------------------------------------------------------------------
//static const char* methodName = "ValidateOpenMM::synchContexts: ";
// ---------------------------------------------------------------------------------------
const State state = context1.getState(State::Positions | State::Velocities);
const std::vector& positions = state.getPositions();
const std::vector& velocities = state.getVelocities();
context2.setPositions( positions );
context2.setVelocities( velocities );
return;
}
/**---------------------------------------------------------------------------------------
Copy harmonic bond force
@param forceToCopy force to copy
@param log log file pointer -- may be NULL
@return copy of force
--------------------------------------------------------------------------------------- */
Force* ValidateOpenMM::copyHarmonicBondForce( const HarmonicBondForce& forceToCopy, FILE* log ) const {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "copyHarmonicBondForce";
// ---------------------------------------------------------------------------------------
HarmonicBondForce* bondForce = new HarmonicBondForce();
for( int ii = 0; ii < forceToCopy.getNumBonds(); ii++ ){
int particle1, particle2;
double length, k;
forceToCopy.getBondParameters( ii, particle1, particle2, length, k );
bondForce->addBond( particle1, particle2, length, k );
}
return bondForce;
}
/**---------------------------------------------------------------------------------------
Copy harmonic angle
@param forceToCopy force to copy
@param log log file pointer -- may be NULL
@return copy of force
--------------------------------------------------------------------------------------- */
Force* ValidateOpenMM::copyHarmonicAngleForce( const HarmonicAngleForce& forceToCopy, FILE* log ) const {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "copyHarmonicAngleForce";
// ---------------------------------------------------------------------------------------
HarmonicAngleForce* bondForce = new HarmonicAngleForce();
for( int ii = 0; ii < forceToCopy.getNumAngles(); ii++ ){
int particle1, particle2, particle3;
double angle, k;
forceToCopy.getAngleParameters( ii, particle1, particle2, particle3, angle, k );
bondForce->addAngle( particle1, particle2, particle3, angle, k );
}
return bondForce;
}
/**---------------------------------------------------------------------------------------
Copy PeriodicTorsionForce
@param forceToCopy force to copy
@param log log file pointer -- may be NULL
@return copy of force
--------------------------------------------------------------------------------------- */
Force* ValidateOpenMM::copyPeriodicTorsionForce( const PeriodicTorsionForce& forceToCopy, FILE* log ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "copyPeriodicTorsionForce";
// ---------------------------------------------------------------------------------------
PeriodicTorsionForce* bondForce = new PeriodicTorsionForce();
for( int ii = 0; ii < forceToCopy.getNumTorsions(); ii++ ){
int particle1, particle2, particle3, particle4, periodicity;
double phase, k;
forceToCopy.getTorsionParameters( ii, particle1, particle2, particle3, particle4, periodicity, phase, k );
bondForce->addTorsion( particle1, particle2, particle3, particle4, periodicity, phase, k );
}
return bondForce;
}
/**---------------------------------------------------------------------------------------
Copy RBTorsionForce
@param forceToCopy force to copy
@param log log file pointer -- may be NULL
@return copy of force
--------------------------------------------------------------------------------------- */
Force* ValidateOpenMM::copyRBTorsionForce( const RBTorsionForce& forceToCopy, FILE* log ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "copyRBTorsionForce";
// ---------------------------------------------------------------------------------------
RBTorsionForce* bondForce = new RBTorsionForce();
for( int ii = 0; ii < forceToCopy.getNumTorsions(); ii++ ){
int particle1, particle2, particle3, particle4;
double c0, c1, c2, c3, c4, c5;
forceToCopy.getTorsionParameters( ii, particle1, particle2, particle3, particle4, c0, c1, c2, c3, c4, c5 );
bondForce->addTorsion( particle1, particle2, particle3, particle4, c0, c1, c2, c3, c4, c5 );
}
return bondForce;
}
/**---------------------------------------------------------------------------------------
Copy NonbondedException force
@param forceToCopy force to copy
@param nonbondedForce force to copy execeptions to
@param log log file pointer -- may be NULL
--------------------------------------------------------------------------------------- */
void ValidateOpenMM::copyNonbondedExceptions( const NonbondedForce& forceToCopy, NonbondedForce* nonbondedForce, FILE* log ) const {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "copyNonbondedExceptions";
// ---------------------------------------------------------------------------------------
for( int ii = 0; ii < forceToCopy.getNumExceptions(); ii++ ){
int particle1, particle2;
double chargeProd, sigma, epsilon;
forceToCopy.getExceptionParameters( ii, particle1, particle2, chargeProd, sigma, epsilon );
nonbondedForce->addException( particle1, particle2, chargeProd, sigma, epsilon );
}
}
/**---------------------------------------------------------------------------------------
Copy NonbondedSoftcoreExceptions force
@param forceToCopy force to copy
@param nonbondedForce force to copy execeptions to
@param log log file pointer -- may be NULL
--------------------------------------------------------------------------------------- */
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
void ValidateOpenMM::copyNonbondedSoftcoreExceptions( const NonbondedSoftcoreForce& forceToCopy,
NonbondedSoftcoreForce* nonbondedForce, FILE* log ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "copyNonbondedSoftcoreExceptions";
// ---------------------------------------------------------------------------------------
for( int ii = 0; ii < forceToCopy.getNumExceptions(); ii++ ){
int particle1, particle2;
double chargeProd, sigma, epsilon, softcoreLJLambda;
forceToCopy.getExceptionParameters( ii, particle1, particle2, chargeProd, sigma, epsilon, softcoreLJLambda );
nonbondedForce->addException( particle1, particle2, chargeProd, sigma, epsilon, softcoreLJLambda );
}
return;
}
#endif
/**---------------------------------------------------------------------------------------
Copy NonbondedForce
@param forceToCopy force to copy
@param log log file pointer -- may be NULL
@return copy of force
--------------------------------------------------------------------------------------- */
Force* ValidateOpenMM::copyNonbondedForce( const NonbondedForce& forceToCopy, FILE* log ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "copyNonbondedForce";
// ---------------------------------------------------------------------------------------
NonbondedForce* nonbondedForce = new NonbondedForce();
for( int ii = 0; ii < forceToCopy.getNumParticles(); ii++ ){
double charge, sigma, epsilon;
forceToCopy.getParticleParameters( ii, charge, sigma, epsilon );
nonbondedForce->addParticle( charge, sigma, epsilon );
}
nonbondedForce->setNonbondedMethod( forceToCopy.getNonbondedMethod() );
nonbondedForce->setCutoffDistance( forceToCopy.getCutoffDistance() );
nonbondedForce->setReactionFieldDielectric( forceToCopy.getReactionFieldDielectric() );
nonbondedForce->setEwaldErrorTolerance( forceToCopy.getEwaldErrorTolerance() );
copyNonbondedExceptions( forceToCopy, nonbondedForce, log );
return nonbondedForce;
}
/**---------------------------------------------------------------------------------------
Copy NonbondedSoftcoreForce
@param forceToCopy force to copy
@param log log file pointer -- may be NULL
@return copy of force
--------------------------------------------------------------------------------------- */
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
Force* ValidateOpenMM::copyNonbondedSoftcoreForce( const NonbondedSoftcoreForce& forceToCopy, FILE* log ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "copyNonbondedSoftcoreForce";
// ---------------------------------------------------------------------------------------
NonbondedSoftcoreForce* nonbondedSoftcore = new NonbondedSoftcoreForce();
for( int ii = 0; ii < forceToCopy.getNumParticles(); ii++ ){
double charge, sigma, epsilon, softcoreLJLambda;
forceToCopy.getParticleParameters( ii, charge, sigma, epsilon, softcoreLJLambda );
nonbondedSoftcore->addParticle( charge, sigma, epsilon, softcoreLJLambda );
}
nonbondedSoftcore->setNonbondedMethod( forceToCopy.getNonbondedMethod() );
nonbondedSoftcore->setCutoffDistance( forceToCopy.getCutoffDistance() );
nonbondedSoftcore->setReactionFieldDielectric( forceToCopy.getReactionFieldDielectric() );
nonbondedSoftcore->setEwaldErrorTolerance( forceToCopy.getEwaldErrorTolerance() );
copyNonbondedSoftcoreExceptions( forceToCopy, nonbondedSoftcore, log );
return nonbondedSoftcore;
}
#endif
/**---------------------------------------------------------------------------------------
Copy GBSAOBCForce
@param forceToCopy force to copy
@param log log file pointer -- may be NULL
@return copy of force
--------------------------------------------------------------------------------------- */
Force* ValidateOpenMM::copyGBSAOBCForce( const GBSAOBCForce& forceToCopy, FILE* log ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "copyGBSAOBCForce";
// ---------------------------------------------------------------------------------------
GBSAOBCForce* gbsaObcForce = new GBSAOBCForce();
gbsaObcForce->setSoluteDielectric( forceToCopy.getSoluteDielectric() );
gbsaObcForce->setSolventDielectric( forceToCopy.getSolventDielectric() );
for( int ii = 0; ii < forceToCopy.getNumParticles(); ii++ ){
double charge, radius, scalingFactor;
forceToCopy.getParticleParameters( ii, charge, radius, scalingFactor );
gbsaObcForce->addParticle( charge, radius, scalingFactor );
}
return gbsaObcForce;
}
/**---------------------------------------------------------------------------------------
Copy GBSAOBCSoftcoreForce
@param forceToCopy force to copy
@param log log file pointer -- may be NULL
@return copy of force
--------------------------------------------------------------------------------------- */
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
Force* ValidateOpenMM::copyGBSAOBCSoftcoreForce( const GBSAOBCSoftcoreForce& forceToCopy, FILE* log ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "copyGBSAOBCSoftcoreForce";
// ---------------------------------------------------------------------------------------
GBSAOBCSoftcoreForce* gbsaObcSoftcoreForce = new GBSAOBCSoftcoreForce();
gbsaObcSoftcoreForce->setSoluteDielectric( forceToCopy.getSoluteDielectric() );
gbsaObcSoftcoreForce->setSolventDielectric( forceToCopy.getSolventDielectric() );
for( int ii = 0; ii < forceToCopy.getNumParticles(); ii++ ){
double charge, radius, scalingFactor, nonpolarScaleFactor;
forceToCopy.getParticleParameters( ii, charge, radius, scalingFactor, nonpolarScaleFactor );
gbsaObcSoftcoreForce->addParticle( charge, radius, scalingFactor, nonpolarScaleFactor );
}
return gbsaObcSoftcoreForce;
}
#endif
/**---------------------------------------------------------------------------------------
Copy GBVIForce
@param forceToCopy force to copy
@param log log file pointer -- may be NULL
@return copy of force
--------------------------------------------------------------------------------------- */
Force* ValidateOpenMM::copyGBVIForce( const GBVIForce& forceToCopy, FILE* log ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "copyGBVIForce";
// ---------------------------------------------------------------------------------------
GBVIForce* gbviForce = new GBVIForce();
gbviForce->setSoluteDielectric( forceToCopy.getSoluteDielectric() );
gbviForce->setSolventDielectric( forceToCopy.getSolventDielectric() );
for( int ii = 0; ii < forceToCopy.getNumParticles(); ii++ ){
double charge, radius, gamma;
forceToCopy.getParticleParameters( ii, charge, radius, gamma );
gbviForce->addParticle( charge, radius, gamma );
}
for( int ii = 0; ii < forceToCopy.getNumBonds(); ii++ ){
int atomI, atomJ;
double bondLength;
forceToCopy.getBondParameters( ii, atomI, atomJ, bondLength );
gbviForce->addBond( atomI, atomJ, bondLength );
}
return gbviForce;
}
/**---------------------------------------------------------------------------------------
Copy GBVISoftcoreForce
@param forceToCopy force to copy
@param log log file pointer -- may be NULL
@return copy of force
--------------------------------------------------------------------------------------- */
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
Force* ValidateOpenMM::copyGBVISoftcoreForce( const GBVISoftcoreForce& forceToCopy, FILE* log ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "copyGBVISoftcoreForce";
// ---------------------------------------------------------------------------------------
GBVISoftcoreForce* gbviForce = new GBVISoftcoreForce();
gbviForce->setSoluteDielectric( forceToCopy.getSoluteDielectric() );
gbviForce->setSolventDielectric( forceToCopy.getSolventDielectric() );
gbviForce->setBornRadiusScalingMethod( forceToCopy.getBornRadiusScalingMethod() );
gbviForce->setQuinticLowerLimitFactor( forceToCopy.getQuinticLowerLimitFactor() );
gbviForce->setQuinticUpperBornRadiusLimit( forceToCopy.getQuinticUpperBornRadiusLimit() );
for( int ii = 0; ii < forceToCopy.getNumParticles(); ii++ ){
double charge, radius, gamma, bornRadiusScaleFactor;
forceToCopy.getParticleParameters( ii, charge, radius, gamma, bornRadiusScaleFactor );
gbviForce->addParticle( charge, radius, gamma, bornRadiusScaleFactor );
}
for( int ii = 0; ii < forceToCopy.getNumBonds(); ii++ ){
int atomI, atomJ;
double bondLength;
forceToCopy.getBondParameters( ii, atomI, atomJ, bondLength );
gbviForce->addBond( atomI, atomJ, bondLength );
}
return gbviForce;
}
#endif
/**---------------------------------------------------------------------------------------
Copy constraints
@param systemToCopy system whose constraints are to be copied
@param system system to add constraints to
@param log log file pointer -- may be NULL
--------------------------------------------------------------------------------------- */
void ValidateOpenMM::copyConstraints( const System& systemToCopy, System* system, FILE* log ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "copyConstraints";
// ---------------------------------------------------------------------------------------
for( int ii = 0; ii < systemToCopy.getNumConstraints(); ii++ ){
int particle1, particle2;
double distance;
systemToCopy.getConstraintParameters( ii, particle1, particle2, distance );
system->addConstraint( particle1, particle2, distance );
}
}
/**---------------------------------------------------------------------------------------
Get force dependencies
@param forceName force to check if there exist any dependencies
@param returnVector vector of forces the input force is dependent on (example: GBSAOBC force requires Nonbonded force)
--------------------------------------------------------------------------------------- */
void ValidateOpenMM::getForceDependencies( std::string forceName, StringVector& returnVector ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "getForceDependencies";
// ---------------------------------------------------------------------------------------
StringStringVectorMapCI dependencyVector = _forceDependencies.find( forceName );
if( dependencyVector != _forceDependencies.end() ){
StringVector dependices = (*dependencyVector).second;
for( unsigned int ii = 0; ii < dependices.size(); ii++ ){
returnVector.push_back( dependices[ii] );
}
}
}
/**
* Write masses and box dimensions to parameter file
*/
void ValidateOpenMM::writeMasses( FILE* filePtr, const System& system ) const {
(void) fprintf( filePtr, "Masses %d\n", system.getNumParticles() );
for(int ii = 0; ii < system.getNumParticles(); ii++ ){
double mass = system.getParticleMass( ii );
(void) fprintf( filePtr, "%8d %14.7e\n", ii, mass );
}
Vec3 a, b, c;
system.getPeriodicBoxVectors( a, b, c);
(void) fprintf( filePtr, "Box %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f\n",
a[0], a[1], a[2], b[0], b[1], b[2], c[0], c[1], c[2] );
}
/**
* Write constraints to parameter file
*/
void ValidateOpenMM::writeConstraints( FILE* filePtr, const System& system ) const {
(void) fprintf( filePtr, "Constraints %d\n", system.getNumConstraints() );
for(int ii = 0; ii < system.getNumConstraints(); ii++ ){
int particle1, particle2;
double distance;
system.getConstraintParameters( ii, particle1, particle2, distance );
(void) fprintf( filePtr, "%8d %8d %8d %14.7e\n", ii, particle1, particle2, distance );
}
}
/**
* Write harmonicBondForce parameters to file
*/
void ValidateOpenMM::writeHarmonicBondForce( FILE* filePtr, const HarmonicBondForce& harmonicBondForce ) const {
(void) fprintf( filePtr, "HarmonicBondForce %d\n", harmonicBondForce.getNumBonds() );
for(int ii = 0; ii < harmonicBondForce.getNumBonds(); ii++ ){
int particle1, particle2;
double length, k;
harmonicBondForce.getBondParameters( ii, particle1, particle2, length, k );
(void) fprintf( filePtr, "%8d %8d %8d %14.7e %14.7e\n", ii, particle1, particle2, length, k);
}
}
/**
* Write harmonicAngleForce parameters to file
*/
void ValidateOpenMM::writeHarmonicAngleForce( FILE* filePtr, const HarmonicAngleForce& harmonicAngleForce ) const {
(void) fprintf( filePtr, "HarmonicAngleForce %d\n", harmonicAngleForce.getNumAngles() );
for(int ii = 0; ii < harmonicAngleForce.getNumAngles(); ii++ ){
int particle1, particle2, particle3;
double angle, k;
harmonicAngleForce.getAngleParameters( ii, particle1, particle2, particle3, angle, k );
(void) fprintf( filePtr, "%8d %8d %8d %8d %14.7e %14.7e\n", ii, particle1, particle2, particle3, angle, k);
}
}
/**
* Write rbTorsionForce parameters to file
*/
void ValidateOpenMM::writeRbTorsionForce( FILE* filePtr, const RBTorsionForce& rbTorsionForce ) const {
(void) fprintf( filePtr, "RBTorsionForce %d\n", rbTorsionForce.getNumTorsions() );
for(int ii = 0; ii < rbTorsionForce.getNumTorsions(); ii++ ){
int particle1, particle2, particle3, particle4;
double c0, c1, c2, c3, c4, c5;
rbTorsionForce.getTorsionParameters( ii, particle1, particle2, particle3, particle4, c0, c1, c2, c3, c4, c5 );
(void) fprintf( filePtr, "%8d %8d %8d %8d %8d %14.7e %14.7e %14.7e %14.7e %14.7e %14.7e\n", ii, particle1, particle2, particle3, particle4, c0, c1, c2, c3, c4, c5 );
}
}
/**
* Write periodicTorsionForce parameters to file
*/
void ValidateOpenMM::writePeriodicTorsionForce( FILE* filePtr, const PeriodicTorsionForce& periodicTorsionForce ) const {
(void) fprintf( filePtr, "PeriodicTorsionForce %d\n", periodicTorsionForce.getNumTorsions() );
for(int ii = 0; ii < periodicTorsionForce.getNumTorsions(); ii++ ){
int particle1, particle2, particle3, particle4, periodicity;
double phase, k;
periodicTorsionForce.getTorsionParameters( ii, particle1, particle2, particle3, particle4, periodicity, phase, k );
(void) fprintf( filePtr, "%8d %8d %8d %8d %8d %8d %14.7e %14.7e\n", ii, particle1, particle2, particle3, particle4, periodicity, phase, k );
}
}
/**
* Write GBSAOBCForce parameters to file
*/
void ValidateOpenMM::writeGbsaObcForce( FILE* filePtr, const GBSAOBCForce& gbsaObcForce ) const {
(void) fprintf( filePtr, "GBSAOBCForce %d\n", gbsaObcForce.getNumParticles() );
for(int ii = 0; ii < gbsaObcForce.getNumParticles(); ii++ ){
double charge, radius, scalingFactor;
gbsaObcForce.getParticleParameters( ii, charge, radius, scalingFactor );
(void) fprintf( filePtr, "%8d %14.7e %14.7e %14.7e\n", ii, charge, radius, scalingFactor );
}
(void) fprintf( filePtr, "SoluteDielectric %14.7e\n", gbsaObcForce.getSoluteDielectric() );
(void) fprintf( filePtr, "SolventDielectric %14.7e\n", gbsaObcForce.getSolventDielectric() );
}
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
/**
* Write GBSAOBCSoftcoreForce parameters to file
*/
void ValidateOpenMM::writeGbsaObcSoftcoreForce( FILE* filePtr, const GBSAOBCSoftcoreForce& gbsaObcForce ) const {
(void) fprintf( filePtr, "GBSAOBCSoftcoreForce %d\n", gbsaObcForce.getNumParticles() );
for(int ii = 0; ii < gbsaObcForce.getNumParticles(); ii++ ){
double charge, radius, scalingFactor;
double nonPolarScalingFactor;
gbsaObcForce.getParticleParameters( ii, charge, radius, scalingFactor, nonPolarScalingFactor );
(void) fprintf( filePtr, "%8d %14.7e %14.7e %14.7e %14.7e\n", ii, charge, radius, scalingFactor, nonPolarScalingFactor );
}
(void) fprintf( filePtr, "SoluteDielectric %14.7e\n", gbsaObcForce.getSoluteDielectric() );
(void) fprintf( filePtr, "SolventDielectric %14.7e\n", gbsaObcForce.getSolventDielectric() );
}
#endif
/**
* Write GBSA GB/VI Force parameters to file
*/
void ValidateOpenMM::writeGBVIForce( FILE* filePtr, const GBVIForce& gbviForce ) const {
(void) fprintf( filePtr, "GBVIForce %d\n", gbviForce.getNumParticles() );
for(int ii = 0; ii < gbviForce.getNumParticles(); ii++ ){
double charge, radius, gamma;
gbviForce.getParticleParameters( ii, charge, radius, gamma );
(void) fprintf( filePtr, "%8d %14.7e %14.7e %14.7e\n", ii, charge, radius, gamma );
}
(void) fprintf( filePtr, "GBVIBonds %d\n", gbviForce.getNumBonds() );
for(int ii = 0; ii < gbviForce.getNumBonds(); ii++ ){
int atomI, atomJ;
double bondLength;
gbviForce.getBondParameters( ii, atomI, atomJ, bondLength );
(void) fprintf( filePtr, "%8d %8d %8d %14.7e\n", ii, atomI, atomJ, bondLength );
}
(void) fprintf( filePtr, "SoluteDielectric %14.7e\n", gbviForce.getSoluteDielectric() );
(void) fprintf( filePtr, "SolventDielectric %14.7e\n", gbviForce.getSolventDielectric() );
}
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
/**
* Write GBSA GB/VI softcore force parameters to file
*/
void ValidateOpenMM::writeGBVISoftcoreForce( FILE* filePtr, const GBVISoftcoreForce& gbviSoftcoreForce ) const {
(void) fprintf( filePtr, "GBVISoftcoreForce %d\n", gbviSoftcoreForce.getNumParticles() );
for(int ii = 0; ii < gbviSoftcoreForce.getNumParticles(); ii++ ){
double charge, radius, gamma;
double nonPolarScalingFactor;
gbviSoftcoreForce.getParticleParameters( ii, charge, radius, gamma, nonPolarScalingFactor );
(void) fprintf( filePtr, "%8d %14.7e %14.7e %14.7e %14.7e\n", ii, charge, radius, gamma, nonPolarScalingFactor );
}
(void) fprintf( filePtr, "GBVISoftcoreBonds %d\n", gbviSoftcoreForce.getNumBonds() );
for(int ii = 0; ii < gbviSoftcoreForce.getNumBonds(); ii++ ){
int atomI, atomJ;
double bondLength;
gbviSoftcoreForce.getBondParameters( ii, atomI, atomJ, bondLength );
(void) fprintf( filePtr, "%8d %8d %8d %14.7e\n", ii, atomI, atomJ, bondLength );
}
(void) fprintf( filePtr, "SoluteDielectric %14.7e\n", gbviSoftcoreForce.getSoluteDielectric() );
(void) fprintf( filePtr, "SolventDielectric %14.7e\n", gbviSoftcoreForce.getSolventDielectric() );
(void) fprintf( filePtr, "BornRadiusScalingMethod %d\n", gbviSoftcoreForce.getBornRadiusScalingMethod() );
(void) fprintf( filePtr, "QuinticLowerLimitFactor %14.7e\n", gbviSoftcoreForce.getQuinticLowerLimitFactor() );
(void) fprintf( filePtr, "QuinticUpperBornRadiusLimit %14.7e\n", gbviSoftcoreForce.getQuinticUpperBornRadiusLimit() );
}
#endif
/**
* Write coordinates to file
*/
void ValidateOpenMM::writeVec3( FILE* filePtr, const std::vector& vect3Array ) const {
for( unsigned int ii = 0; ii < vect3Array.size(); ii++ ){
(void) fprintf( filePtr, "%8d %14.7e %14.7e %14.7e\n", ii,
vect3Array[ii][0], vect3Array[ii][1], vect3Array[ii][2] );
}
}
/**
* Write context info to file
*/
void ValidateOpenMM::writeContext( FILE* filePtr, const Context& context ) const {
State state = context.getState( State::Positions | State::Velocities | State::Forces | State::Energy );
std::vector positions = state.getPositions();
std::vector velocities = state.getVelocities();
std::vector forces = state.getForces();
(void) fprintf( filePtr, "Positions %u\n", positions.size() );
writeVec3( filePtr, positions );
(void) fprintf( filePtr, "Velocities %u\n", velocities.size() );
writeVec3( filePtr, velocities );
(void) fprintf( filePtr, "Forces %u\n", forces.size() );
writeVec3( filePtr, forces );
(void) fprintf( filePtr, "KineticEnergy %14.7e\n", state.getKineticEnergy() );
(void) fprintf( filePtr, "PotentialEnergy %14.7e\n", state.getPotentialEnergy() );
}
/**
* Write nonbonded parameters to file
*/
void ValidateOpenMM::writeNonbondedForce( FILE* filePtr, const NonbondedForce & nonbondedForce ) const {
// charge and vdw parameters
(void) fprintf( filePtr, "NonbondedForce %d\n", nonbondedForce.getNumParticles() );
for(int ii = 0; ii < nonbondedForce.getNumParticles(); ii++ ){
double charge, sigma, epsilon;
nonbondedForce.getParticleParameters( ii, charge, sigma, epsilon );
(void) fprintf( filePtr, "%8d %14.7e %14.7e %14.7e\n", ii, charge, sigma, epsilon );
}
// cutoff, dielectric, Ewald tolerance
(void) fprintf( filePtr, "CutoffDistance %14.7e\n", nonbondedForce.getCutoffDistance() );
(void) fprintf( filePtr, "RFDielectric %14.7e\n", nonbondedForce.getReactionFieldDielectric() );
(void) fprintf( filePtr, "EwaldRTolerance %14.7e\n", nonbondedForce.getEwaldErrorTolerance() );
// cutoff mode
std::string nonbondedForceMethod;
switch( nonbondedForce.getNonbondedMethod() ){
case NonbondedForce::NoCutoff:
nonbondedForceMethod = "NoCutoff";
break;
case NonbondedForce::CutoffNonPeriodic:
nonbondedForceMethod = "CutoffNonPeriodic";
break;
case NonbondedForce::CutoffPeriodic:
nonbondedForceMethod = "CutoffPeriodic";
break;
case NonbondedForce::Ewald:
nonbondedForceMethod = "Ewald";
break;
case NonbondedForce::PME:
nonbondedForceMethod = "PME";
break;
default:
nonbondedForceMethod = "Unknown";
}
(void) fprintf( filePtr, "NonbondedForceMethod %s\n", nonbondedForceMethod.c_str() );
(void) fprintf( filePtr, "NonbondedForceExceptions %d\n", nonbondedForce.getNumExceptions() );
for(int ii = 0; ii < nonbondedForce.getNumExceptions(); ii++ ){
int particle1, particle2;
double chargeProd, sigma, epsilon;
nonbondedForce.getExceptionParameters( ii, particle1, particle2, chargeProd, sigma, epsilon );
(void) fprintf( filePtr, "%8d %8d %8d %14.7e %14.7e %14.7e\n", ii, particle1, particle2, chargeProd, sigma, epsilon );
}
}
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
/**
* Write nonbonded softcore parameters to file
*/
void ValidateOpenMM::writeNonbondedSoftcoreForce( FILE* filePtr, const NonbondedSoftcoreForce & nonbondedSoftcoreForce ) const {
(void) fprintf( filePtr, "NonbondedSoftcoreForce %d\n", nonbondedSoftcoreForce.getNumParticles() );
for(int ii = 0; ii < nonbondedSoftcoreForce.getNumParticles(); ii++ ){
double charge, sigma, epsilon, softCoreLJ;
nonbondedSoftcoreForce.getParticleParameters( ii, charge, sigma, epsilon, softCoreLJ );
(void) fprintf( filePtr, "%8d %14.7e %14.7e %14.7e %14.7e\n", ii, charge, sigma, epsilon, softCoreLJ );
}
(void) fprintf( filePtr, "CutoffDistance %14.7e\n", nonbondedSoftcoreForce.getCutoffDistance() );
(void) fprintf( filePtr, "RFDielectric %14.7e\n", nonbondedSoftcoreForce.getReactionFieldDielectric() );
(void) fprintf( filePtr, "EwaldRTolerance %14.7e\n", nonbondedSoftcoreForce.getEwaldErrorTolerance() );
std::string nonbondedSoftcoreForceMethod;
switch( nonbondedSoftcoreForce.getNonbondedMethod() ){
case NonbondedSoftcoreForce::NoCutoff:
nonbondedSoftcoreForceMethod = "NoCutoff";
break;
/*
case NonbondedSoftcoreForce::CutoffNonPeriodic:
nonbondedSoftcoreForceMethod = "CutoffNonPeriodic";
break;
case NonbondedSoftcoreForce::CutoffPeriodic:
nonbondedSoftcoreForceMethod = "CutoffPeriodic";
break;
case NonbondedSoftcoreForce::Ewald:
nonbondedSoftcoreForceMethod = "Ewald";
break;
case NonbondedSoftcoreForce::PME:
nonbondedSoftcoreForceMethod = "PME";
break;
*/
default:
nonbondedSoftcoreForceMethod = "Unknown";
}
(void) fprintf( filePtr, "NonbondedSoftcoreForceMethod %s\n", nonbondedSoftcoreForceMethod.c_str() );
(void) fprintf( filePtr, "NonbondedSoftcoreForceExceptions %d\n", nonbondedSoftcoreForce.getNumExceptions() );
for(int ii = 0; ii < nonbondedSoftcoreForce.getNumExceptions(); ii++ ){
int particle1, particle2;
double chargeProd, sigma, epsilon, softCoreLJ;
nonbondedSoftcoreForce.getExceptionParameters( ii, particle1, particle2, chargeProd, sigma, epsilon, softCoreLJ );
(void) fprintf( filePtr, "%8d %8d %8d %14.7e %14.7e %14.7e %14.7e\n", ii, particle1, particle2, chargeProd, sigma, epsilon, softCoreLJ );
}
return;
}
#endif
void ValidateOpenMM::writeIntegrator( FILE* filePtr, const Integrator& integrator ) const {
// LangevinIntegrator
try {
const LangevinIntegrator langevinIntegrator = dynamic_cast(integrator);
(void) fprintf( filePtr, "Integrator LangevinIntegrator\n" );
(void) fprintf( filePtr, "StepSize %14.7e\n", langevinIntegrator.getStepSize() );
(void) fprintf( filePtr, "ConstraintTolerance %14.7e\n", langevinIntegrator.getConstraintTolerance() );
(void) fprintf( filePtr, "Temperature %14.7e\n", langevinIntegrator.getTemperature() );
(void) fprintf( filePtr, "Friction %14.7e\n", langevinIntegrator.getFriction() );
(void) fprintf( filePtr, "RandomNumberSeed %d\n", langevinIntegrator.getRandomNumberSeed() );
return;
} catch( std::bad_cast ){
}
// VariableLangevinIntegrator
try {
const VariableLangevinIntegrator& langevinIntegrator = dynamic_cast(integrator);
(void) fprintf( filePtr, "Integrator VariableLangevinIntegrator\n" );
(void) fprintf( filePtr, "StepSize %14.7e\n", langevinIntegrator.getStepSize() );
(void) fprintf( filePtr, "ConstraintTolerance %14.7e\n", langevinIntegrator.getConstraintTolerance() );
(void) fprintf( filePtr, "Temperature %14.7e\n", langevinIntegrator.getTemperature() );
(void) fprintf( filePtr, "Friction %14.7e\n", langevinIntegrator.getFriction() );
(void) fprintf( filePtr, "RandomNumberSeed %d\n", langevinIntegrator.getRandomNumberSeed() );
(void) fprintf( filePtr, "ErrorTolerance %14.7e\n", langevinIntegrator.getErrorTolerance() );
return;
} catch( std::bad_cast ){
}
// VerletIntegrator
try {
const VerletIntegrator& verletIntegrator = dynamic_cast(integrator);
(void) fprintf( filePtr, "Integrator VerletIntegrator\n" );
(void) fprintf( filePtr, "StepSize %14.7e\n", verletIntegrator.getStepSize() );
(void) fprintf( filePtr, "ConstraintTolerance %14.7e\n", verletIntegrator.getConstraintTolerance() );
return;
} catch( std::bad_cast ){
}
// VariableVerletIntegrator
try {
const VariableVerletIntegrator & variableVerletIntegrator = dynamic_cast(integrator);
(void) fprintf( filePtr, "Integrator VariableVerletIntegrator\n" );
(void) fprintf( filePtr, "StepSize %14.7e\n", variableVerletIntegrator.getStepSize() );
(void) fprintf( filePtr, "ConstraintTolerance %14.7e\n", variableVerletIntegrator.getConstraintTolerance() );
(void) fprintf( filePtr, "ErrorTolerance %14.7e\n", variableVerletIntegrator.getErrorTolerance() );
return;
} catch( std::bad_cast ){
}
// BrownianIntegrator
try {
const BrownianIntegrator& brownianIntegrator = dynamic_cast(integrator);
(void) fprintf( filePtr, "Integrator BrownianIntegrator\n" );
(void) fprintf( filePtr, "StepSize %14.7e\n", brownianIntegrator.getStepSize() );
(void) fprintf( filePtr, "ConstraintTolerance %14.7e\n", brownianIntegrator.getConstraintTolerance() );
(void) fprintf( filePtr, "Temperature %14.7e\n", brownianIntegrator.getTemperature() );
(void) fprintf( filePtr, "Friction %14.7e\n", brownianIntegrator.getFriction() );
(void) fprintf( filePtr, "RandomNumberSeed %d\n", brownianIntegrator.getRandomNumberSeed() );
return;
} catch( std::bad_cast ){
}
if( getLog() ){
(void) fprintf( getLog(), "Integrator not recognized." );
(void) fflush( getLog() );
}
return;
}
/**
* Write parameter file
*/
void ValidateOpenMM::writeParameterFile( const Context& context, const std::string& parameterFileName ) const {
// open file
FILE* filePtr = fopen( parameterFileName.c_str(), "w" );
const System& system = context.getSystem();
const Integrator& integrator = context.getIntegrator();
// (void) fprintf( filePtr, "Version %s\n", versionString.c_str() );
(void) fprintf( filePtr, "Particles %8d\n", system.getNumParticles() );
writeMasses( filePtr, system );
(void) fprintf( filePtr, "NumberOfForces %8d\n", system.getNumForces() );
// print active forces and relevant parameters
for(int i = 0; i < system.getNumForces(); ++i) {
int hit = 0;
const Force& force = system.getForce(i);
// bond
if( !hit ){
try {
const HarmonicBondForce& harmonicBondForce = dynamic_cast(force);
writeHarmonicBondForce( filePtr, harmonicBondForce );
hit++;
} catch( std::bad_cast ){
}
}
// angle
if( !hit ){
try {
const HarmonicAngleForce& harmonicAngleForce = dynamic_cast(force);
writeHarmonicAngleForce( filePtr, harmonicAngleForce );
hit++;
} catch( std::bad_cast ){
}
}
// PeriodicTorsionForce
if( !hit ){
try {
const PeriodicTorsionForce & periodicTorsionForce = dynamic_cast(force);
writePeriodicTorsionForce( filePtr, periodicTorsionForce );
hit++;
} catch( std::bad_cast ){
}
}
// RBTorsionForce
if( !hit ){
try {
const RBTorsionForce& rBTorsionForce = dynamic_cast(force);
writeRbTorsionForce( filePtr, rBTorsionForce );
hit++;
} catch( std::bad_cast ){
}
}
// nonbonded
if( !hit ){
try {
const NonbondedForce& nbForce = dynamic_cast(force);
writeNonbondedForce( filePtr, nbForce );
hit++;
} catch( std::bad_cast ){
}
}
// nonbonded softcore
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
if( !hit ){
try {
const NonbondedSoftcoreForce& nbForce = dynamic_cast(force);
writeNonbondedSoftcoreForce( filePtr, nbForce );
hit++;
} catch( std::bad_cast ){
}
}
#endif
// GBSA OBC
if( !hit ){
try {
const GBSAOBCForce& obcForce = dynamic_cast(force);
writeGbsaObcForce( filePtr, obcForce );
hit++;
} catch( std::bad_cast ){
}
}
// GBSA OBC softcore
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
if( !hit ){
try {
const GBSAOBCSoftcoreForce& obcForce = dynamic_cast(force);
writeGbsaObcSoftcoreForce( filePtr, obcForce );
hit++;
} catch( std::bad_cast ){
}
}
#endif
// GB/VI
if( !hit ){
try {
const GBVIForce& obcForce = dynamic_cast(force);
writeGBVIForce( filePtr, obcForce );
hit++;
} catch( std::bad_cast ){
}
}
// GB/VI softcore
#ifdef INCLUDE_FREE_ENERGY_PLUGIN
if( !hit ){
try {
const GBVISoftcoreForce& obcForce = dynamic_cast(force);
writeGBVISoftcoreForce( filePtr, obcForce );
hit++;
} catch( std::bad_cast ){
}
}
#endif
// COM
if( !hit ){
try {
const CMMotionRemover& cMMotionRemover = dynamic_cast(force);
(void) fprintf( filePtr, "CMMotionRemover %d\n", cMMotionRemover.getFrequency() );
hit++;
} catch( std::bad_cast ){
}
}
if( !hit ){
(void) fprintf( stderr, " %2d force not recognized.\n", i );
exit(-1);
}
}
// constraints
writeConstraints( filePtr, system );
// context
writeContext( filePtr, context );
// integrator
writeIntegrator( filePtr, integrator );
// close file
(void) fclose( filePtr );
}