/* -------------------------------------------------------------------------- * * 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::isNanOrInfinity( double number ){ return (number != number || number == std::numeric_limits::infinity() || number == -std::numeric_limits::infinity()) ? 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 ); }