/* -------------------------------------------------------------------------- *
* 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) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* 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 "BrookLangevinDynamics.h"
#include "BrookPlatform.h"
#include "openmm/OpenMMException.h"
#include "BrookStreamImpl.h"
#include "kernels/kshakeh.h"
#include "kernels/kupdatesd.h"
#include "kernels/kcommon.h"
#include
// use random number generator
#include "../../reference/src/SimTKUtilities/SimTKOpenMMUtilities.h"
using namespace OpenMM;
using namespace std;
/**
*
* Constructor
*
*/
BrookLangevinDynamics::BrookLangevinDynamics( ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookLangevinDynamics::BrookLangevinDynamics";
BrookOpenMMFloat zero = (BrookOpenMMFloat) 0.0;
BrookOpenMMFloat one = (BrookOpenMMFloat) 1.0;
BrookOpenMMFloat oneMinus = (BrookOpenMMFloat) -1.0;
// ---------------------------------------------------------------------------------------
_numberOfParticles = -1;
_internalStepCount = 0;
// mark stream dimension variables as unset
_sdParticleStreamWidth = -1;
_sdParticleStreamHeight = -1;
_sdParticleStreamSize = -1;
for( int ii = 0; ii < LastStreamIndex; ii++ ){
_sdStreams[ii] = NULL;
}
for( int ii = 0; ii < MaxDerivedParameters; ii++ ){
_derivedParameters[ii] = oneMinus;
}
_temperature = oneMinus;
_stepSize = oneMinus;
_tau = oneMinus;
// setup inverse sqrt masses
_inverseSqrtMasses = NULL;
// set randomNumber seed
_randomNumberSeed = 1393;
//_randomNumberSeed = randomNumberSeed ? randomNumberSeed : 1393;
//SimTKOpenMMUtilities::setRandomNumberSeed( randomNumberSeed );
}
/**
* Destructor
*
*/
BrookLangevinDynamics::~BrookLangevinDynamics( ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookLangevinDynamics::~BrookLangevinDynamics";
// ---------------------------------------------------------------------------------------
for( int ii = 0; ii < LastStreamIndex; ii++ ){
delete _sdStreams[ii];
}
delete[] _inverseSqrtMasses;
}
/**
* Get tau
*
* @return tau
*
*/
BrookOpenMMFloat BrookLangevinDynamics::getTau( void ) const {
return _tau;
}
/**
* Get friction
*
* @return friction
*
*/
BrookOpenMMFloat BrookLangevinDynamics::getFriction( void ) const {
static const BrookOpenMMFloat zero = static_cast( 0.0 );
static const BrookOpenMMFloat one = static_cast( 1.0 );
return ( (_tau == zero) ? zero : (one/_tau) );
}
/**
* Get temperature
*
* @return temperature
*
*/
BrookOpenMMFloat BrookLangevinDynamics::getTemperature( void ) const {
return _temperature;
}
/**
* Get stepSize
*
* @return stepSize
*
*/
BrookOpenMMFloat BrookLangevinDynamics::getStepSize( void ) const {
return _stepSize;
}
/**
* Set tau
*
* @param tau new tau value
*
* @return DefaultReturnValue
*
*/
int BrookLangevinDynamics::_setTau( BrookOpenMMFloat tau ){
_tau = tau;
return DefaultReturnValue;
}
/**
* Set friction = 1/tau
*
* @param friction new friction value
*
* @return DefaultReturnValue
*
*/
int BrookLangevinDynamics::_setFriction( BrookOpenMMFloat friction ){
_tau = static_cast( (friction != 0.0) ? 1.0/friction : 0.0);
return DefaultReturnValue;
}
/**
* Set temperature
*
* @parameter temperature
*
* @return DefaultReturnValue
*
*/
int BrookLangevinDynamics::_setTemperature( BrookOpenMMFloat temperature ){
_temperature = temperature;
return DefaultReturnValue;
}
/**
* Set stepSize
*
* @param stepSize
*
* @return DefaultReturnValue
*
*/
int BrookLangevinDynamics::_setStepSize( BrookOpenMMFloat stepSize ){
_stepSize = stepSize;
return DefaultReturnValue;
}
/**
* Update derived parameters
*
* @return DefaultReturnValue
*
* @throw OpenMMException if tau too small
*
*/
int BrookLangevinDynamics::_updateDerivedParameters( void ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "\nBrookLangevinDynamics::_updateDerivedParameters";
static const BrookOpenMMFloat zero = 0.0;
static const BrookOpenMMFloat one = 1.0;
static const BrookOpenMMFloat two = 2.0;
static const BrookOpenMMFloat three = 3.0;
static const BrookOpenMMFloat four = 4.0;
static const BrookOpenMMFloat half = 0.5;
float epsilon = 1.0e-08f;
// ---------------------------------------------------------------------------------------
BrookOpenMMFloat tau = getTau();
BrookOpenMMFloat temperature = getTemperature();
BrookOpenMMFloat stepSize = getStepSize();
if( fabsf( (float) tau ) < epsilon ){
std::stringstream message;
message << methodName << " tau=" << tau << " too small.";
throw OpenMMException( message.str() );
}
_derivedParameters[GDT] = stepSize/tau;
_derivedParameters[EPH] = EXP( half*_derivedParameters[GDT] );
_derivedParameters[EMH] = EXP( -half*_derivedParameters[GDT] );
_derivedParameters[EM] = EXP( -_derivedParameters[GDT] );
_derivedParameters[EP] = EXP( _derivedParameters[GDT] );
if( _derivedParameters[GDT] >= static_cast( 0.1 ) ){
BrookOpenMMFloat term1 = _derivedParameters[EPH] - one;
term1 *= term1;
_derivedParameters[B] = _derivedParameters[GDT]*(_derivedParameters[EP] - one) - four*term1;
_derivedParameters[C] = _derivedParameters[GDT] - three + four*_derivedParameters[EMH] - _derivedParameters[EM];
_derivedParameters[D] = two - _derivedParameters[EPH] - _derivedParameters[EMH];
} else {
BrookOpenMMFloat term1 = half*_derivedParameters[GDT];
BrookOpenMMFloat term2 = term1*term1;
BrookOpenMMFloat term4 = term2*term2;
BrookOpenMMFloat third = static_cast( ( 1.0/3.0 ) );
BrookOpenMMFloat o7_9 = static_cast( ( 7.0/9.0 ) );
BrookOpenMMFloat o1_12 = static_cast( ( 1.0/12.0 ) );
BrookOpenMMFloat o17_90 = static_cast( ( 17.0/90.0 ) );
BrookOpenMMFloat o7_30 = static_cast( ( 7.0/30.0 ) );
BrookOpenMMFloat o31_1260 = static_cast( ( 31.0/1260.0 ) );
BrookOpenMMFloat o_360 = static_cast( ( 1.0/360.0 ) );
_derivedParameters[B] = term4*( third + term1*( third + term1*( o17_90 + term1*o7_9 )));
_derivedParameters[C] = term2*term1*( two*third + term1*( -half + term1*( o7_30 + term1*(-o1_12 + term1*o31_1260 ))));
_derivedParameters[D] = term2*( -one + term2*(-o1_12 - term2*o_360));
}
BrookOpenMMFloat kT = static_cast( BOLTZ )*temperature;
_derivedParameters[V] = SQRT( kT*( one - _derivedParameters[EM]) );
_derivedParameters[X] = tau*SQRT( kT*_derivedParameters[C] );
_derivedParameters[Yv] = SQRT( kT*_derivedParameters[B]/_derivedParameters[C] );
_derivedParameters[Yx] = tau*SQRT( kT*_derivedParameters[B]/(one - _derivedParameters[EM]) );
_derivedParameters[Sd1pc1] = tau*( one - _derivedParameters[EM] );
_derivedParameters[Sd1pc2] = tau*( _derivedParameters[EPH] - _derivedParameters[EMH] );
if( fabsf( _derivedParameters[Sd1pc2] ) < 1.0e-06 ){
_derivedParameters[Sd1pc2] = tau*_derivedParameters[GDT];
}
_derivedParameters[Sd1pc3] = _derivedParameters[D]/(tau*_derivedParameters[C] );
// if tau was greater than 20000, then _derivedParameters[Sd1pc2] was zero
// using tau*_derivedParameters[GDT] as approximation to tau*( _derivedParameters[EPH] - _derivedParameters[EMH] ) for values in this
// range
if( fabsf( _derivedParameters[Sd1pc2] ) > 1.0e-10 ){
_derivedParameters[Sd2pc1] = one/_derivedParameters[Sd1pc2];
} else {
std::stringstream message;
message << methodName << " Sd1pc2=" << _derivedParameters[Sd1pc2] << " is too small (Sd2pc1 is 1/Sd1pc2)";
throw OpenMMException( message.str() );
}
_derivedParameters[Sd2pc2] = tau*_derivedParameters[D]/( _derivedParameters[EM] - one );
return DefaultReturnValue;
}
/**
* Update parameters -- only way parameters can be set
*
* @param temperature temperature
* @param friction friction
* @param step size step size
*
* @return solute dielectric
*
*/
int BrookLangevinDynamics::updateParameters( double temperature, double friction, double stepSize ){
// ---------------------------------------------------------------------------------------
static int showUpdate = 1;
static int maxShowUpdate = 3;
static const std::string methodName = "\nBrookLangevinDynamics::updateParameters";
// ---------------------------------------------------------------------------------------
_setStepSize( (BrookOpenMMFloat) stepSize );
_setFriction( (BrookOpenMMFloat) friction );
//_setTau( (BrookOpenMMFloat) friction );
_setTemperature( (BrookOpenMMFloat) temperature );
_updateDerivedParameters( );
_updateSdStreams( );
// show update
if( showUpdate && getLog() && (showUpdate++ < maxShowUpdate) ){
std::string contents = getContentsString( );
(void) fprintf( getLog(), "%s contents\n%s", methodName.c_str(), contents.c_str() );
(void) fflush( getLog() );
}
return DefaultReturnValue;
}
/**
*
* Get array of derived parameters indexed by 'DerivedParameters' enums
*
* @return array
*
*/
const BrookOpenMMFloat* BrookLangevinDynamics::getDerivedParameters( void ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "\nBrookLangevinDynamics::getDerivedParameters";
// ---------------------------------------------------------------------------------------
return _derivedParameters;
}
/**
* Get Particle stream size
*
* @return Particle stream size
*
*/
int BrookLangevinDynamics::getLangevinDynamicsParticleStreamSize( void ) const {
return _sdParticleStreamSize;
}
/**
* Get particle stream width
*
* @return particle stream width
*
*/
int BrookLangevinDynamics::getLangevinDynamicsParticleStreamWidth( void ) const {
return _sdParticleStreamWidth;
}
/**
* Get particle stream height
*
* @return particle stream height
*/
int BrookLangevinDynamics::getLangevinDynamicsParticleStreamHeight( void ) const {
return _sdParticleStreamHeight;
}
/**
* Get SDPC1 stream
*
* @return SDPC1 stream
*
*/
BrookFloatStreamInternal* BrookLangevinDynamics::getSDPC1Stream( void ) const {
return _sdStreams[SDPC1Stream];
}
/**
* Get SDPC2 stream
*
* @return SDPC2 stream
*
*/
BrookFloatStreamInternal* BrookLangevinDynamics::getSDPC2Stream( void ) const {
return _sdStreams[SDPC2Stream];
}
/**
* Get SD2X stream
*
* @return SD2X stream
*
*/
BrookFloatStreamInternal* BrookLangevinDynamics::getSD2XStream( void ) const {
return _sdStreams[SD2XStream];
}
/**
* Get SD1V stream
*
* @return SD1V stream
*
*/
BrookFloatStreamInternal* BrookLangevinDynamics::getSD1VStream( void ) const {
return _sdStreams[SD1VStream];
}
/**
* Get VPrime stream
*
* @return Vprime stream
*
*/
BrookFloatStreamInternal* BrookLangevinDynamics::getVPrimeStream( void ) const {
return _sdStreams[VPrimeStream];
}
/**
* Get XPrime stream
*
* @return Xprime stream
*
*/
BrookFloatStreamInternal* BrookLangevinDynamics::getXPrimeStream( void ) const {
return _sdStreams[XPrimeStream];
}
/**
* Get InverseMass stream
*
* @return inverse mass stream
*
*/
BrookFloatStreamInternal* BrookLangevinDynamics::getInverseMassStream( void ) const {
return _sdStreams[InverseMassStream];
}
/**
* Initialize stream dimensions
*
* @param numberOfParticles number of particles
* @param platform platform
*
* @return ErrorReturnValue if error, else DefaultReturnValue
*
*/
int BrookLangevinDynamics::_initializeStreamSizes( int numberOfParticles, const Platform& platform ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookLangevinDynamics::_initializeStreamSizes";
// ---------------------------------------------------------------------------------------
_sdParticleStreamSize = getParticleStreamSize( platform );
_sdParticleStreamWidth = getParticleStreamWidth( platform );
_sdParticleStreamHeight = getParticleStreamHeight( platform );
return DefaultReturnValue;
}
/**
* Initialize stream dimensions
*
* @param numberOfParticles number of particles
* @param platform platform
*
* @return ErrorReturnValue if error, else DefaultReturnValue
*
*/
//std::string BrookLangevinDynamics::_getDerivedParametersString( BrookLangevinDynamics::DerivedParameters derivedParametersIndex ) const {
std::string BrookLangevinDynamics::_getDerivedParametersString( int derivedParametersIndex ) const {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookLangevinDynamics::_getDerivedParametersString";
// ---------------------------------------------------------------------------------------
std::string returnString;
switch( derivedParametersIndex ){
case GDT:
returnString = "GDT";
break;
case EPH:
returnString = "EPH";
break;
case EMH:
returnString = "EMH";
break;
case EP:
returnString = "EP";
break;
case EM:
returnString = "EM";
break;
case B:
returnString = "B";
break;
case C:
returnString = "C";
break;
case D:
returnString = "D";
break;
case V:
returnString = "V";
break;
case X:
returnString = "X";
break;
case Yv:
returnString = "Yv";
break;
case Yx:
returnString = "Yx";
break;
case Sd1pc1:
returnString = "Sd1pc1";
break;
case Sd1pc2:
returnString = "Sd1pc2";
break;
case Sd1pc3:
returnString = "Sd1pc3";
break;
case Sd2pc1:
returnString = "Sd2pc1";
break;
case Sd2pc2:
returnString = "Sd2pc2";
break;
default:
returnString = "Unknown";
break;
}
return returnString;
}
/**
* Initialize streams
*
* @param platform platform
*
* @return ErrorReturnValue if error, else DefaultReturnValue
*
*/
int BrookLangevinDynamics::_initializeStreams( const Platform& platform ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookLangevinDynamics::_initializeStreams";
BrookOpenMMFloat dangleValue = (BrookOpenMMFloat) 0.0;
// ---------------------------------------------------------------------------------------
int sdParticleStreamSize = getLangevinDynamicsParticleStreamSize();
int sdParticleStreamWidth = getLangevinDynamicsParticleStreamWidth();
_sdStreams[SDPC1Stream] = new BrookFloatStreamInternal( BrookCommon::SDPC1Stream,
sdParticleStreamSize, sdParticleStreamWidth,
BrookStreamInternal::Float2, dangleValue );
_sdStreams[SDPC2Stream] = new BrookFloatStreamInternal( BrookCommon::SDPC2Stream,
sdParticleStreamSize, sdParticleStreamWidth,
BrookStreamInternal::Float2, dangleValue );
_sdStreams[SD2XStream] = new BrookFloatStreamInternal( BrookCommon::SD2XStream,
sdParticleStreamSize, sdParticleStreamWidth,
BrookStreamInternal::Float3, dangleValue );
_sdStreams[SD1VStream] = new BrookFloatStreamInternal( BrookCommon::SD1VStream,
sdParticleStreamSize, sdParticleStreamWidth,
BrookStreamInternal::Float3, dangleValue );
_sdStreams[VPrimeStream] = new BrookFloatStreamInternal( BrookCommon::VPrimeStream,
sdParticleStreamSize, sdParticleStreamWidth,
BrookStreamInternal::Float3, dangleValue );
_sdStreams[XPrimeStream] = new BrookFloatStreamInternal( BrookCommon::XPrimeStream,
sdParticleStreamSize, sdParticleStreamWidth,
BrookStreamInternal::Float3, dangleValue );
_sdStreams[InverseMassStream] = new BrookFloatStreamInternal( BrookCommon::InverseMassStream,
sdParticleStreamSize, sdParticleStreamWidth,
BrookStreamInternal::Float, dangleValue );
return DefaultReturnValue;
}
/**
* Update sd streams -- called after parameters change
*
* @return ErrorReturnValue if error, else DefaultReturnValue
*
*/
int BrookLangevinDynamics::_updateSdStreams( void ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookLangevinDynamics::_updateSdStreams";
// ---------------------------------------------------------------------------------------
int sdParticleStreamSize = getLangevinDynamicsParticleStreamSize();
// create and initialize sdpc streams
BrookOpenMMFloat* sdpc[2];
for( int ii = 0; ii < 2; ii++ ){
sdpc[ii] = new BrookOpenMMFloat[2*sdParticleStreamSize];
memset( sdpc[ii], 0, 2*sdParticleStreamSize*sizeof( BrookOpenMMFloat ) );
}
BrookOpenMMFloat* inverseMass = new BrookOpenMMFloat[sdParticleStreamSize];
memset( inverseMass, 0, sdParticleStreamSize*sizeof( BrookOpenMMFloat ) );
const BrookOpenMMFloat* derivedParameters = getDerivedParameters( );
int numberOfParticles = getNumberOfParticles();
int index = 0;
for( int ii = 0; ii < numberOfParticles; ii++, index += 2 ){
sdpc[0][index] = _inverseSqrtMasses[ii]*( static_cast (derivedParameters[Yv]) );
sdpc[0][index+1] = _inverseSqrtMasses[ii]*( static_cast (derivedParameters[V]) );
sdpc[1][index] = _inverseSqrtMasses[ii]*( static_cast (derivedParameters[Yx]) );
sdpc[1][index+1] = _inverseSqrtMasses[ii]*( static_cast (derivedParameters[X]) );
inverseMass[ii] = _inverseSqrtMasses[ii]*_inverseSqrtMasses[ii];
}
_sdStreams[SDPC1Stream]->loadFromArray( sdpc[0] );
_sdStreams[SDPC2Stream]->loadFromArray( sdpc[1] );
_sdStreams[InverseMassStream]->loadFromArray( inverseMass );
for( int ii = 0; ii < 2; ii++ ){
delete[] sdpc[ii];
}
delete[] inverseMass;
// initialize SD2X
BrookOpenMMFloat* sd2x = new BrookOpenMMFloat[3*sdParticleStreamSize];
//SimTKOpenMMUtilities::setRandomNumberSeed( (uint32_t) getRandomNumberSeed() );
memset( sd2x, 0, 3*sdParticleStreamSize*sizeof( BrookOpenMMFloat ) );
index = 0;
int useFixedRandomValue = 0;
if( useFixedRandomValue ){
// diagnostics only!
BrookOpenMMFloat fixedRandomValue = static_cast( 0.1 );
for( int ii = 0; ii < numberOfParticles; ii++, index += 3 ){
BrookOpenMMFloat value = _inverseSqrtMasses[ii]*derivedParameters[X]*fixedRandomValue;
sd2x[index] = value;
sd2x[index+1] = value;
sd2x[index+2] = value;
}
// print message letting user know non-random value being used
FILE* log = getLog() ? getLog() : stderr;
(void) fprintf( log, "%s using fixed 'random value'=%.3f to initialize sd2x\n", methodName.c_str(), fixedRandomValue );
} else {
for( int ii = 0; ii < numberOfParticles; ii++, index += 3 ){
sd2x[index] = _inverseSqrtMasses[ii]*derivedParameters[X]*( static_cast (SimTKOpenMMUtilities::getNormallyDistributedRandomNumber()) );
sd2x[index+1] = _inverseSqrtMasses[ii]*derivedParameters[X]*( static_cast (SimTKOpenMMUtilities::getNormallyDistributedRandomNumber()) );
sd2x[index+2] = _inverseSqrtMasses[ii]*derivedParameters[X]*( static_cast (SimTKOpenMMUtilities::getNormallyDistributedRandomNumber()) );
}
}
_sdStreams[SD2XStream]->loadFromArray( sd2x );
delete[] sd2x;
return DefaultReturnValue;
}
/**
* Set masses
*
* @param masses particle masses
*
*/
int BrookLangevinDynamics::_setInverseSqrtMasses( const std::vector& masses ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookLangevinDynamics::_setInverseSqrtMasses";
BrookOpenMMFloat zero = static_cast( 0.0 );
BrookOpenMMFloat one = static_cast( 1.0 );
// ---------------------------------------------------------------------------------------
// setup inverse sqrt masses
_inverseSqrtMasses = new BrookOpenMMFloat[masses.size()];
int index = 0;
for( std::vector::const_iterator ii = masses.begin(); ii != masses.end(); ii++, index++ ){
if( *ii != 0.0 ){
BrookOpenMMFloat value = static_cast(*ii);
_inverseSqrtMasses[index] = ( SQRT( one/value ) );
} else {
_inverseSqrtMasses[index] = zero;
}
}
return DefaultReturnValue;
}
/*
* Setup of LangevinDynamics parameters
*
* @param masses masses
* @param platform Brook platform
*
* @return nonzero value if error
*
* */
int BrookLangevinDynamics::setup( const std::vector& masses, const Platform& platform ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookLangevinDynamics::setup";
// ---------------------------------------------------------------------------------------
const BrookPlatform& brookPlatform = dynamic_cast (platform);
setLog( brookPlatform.getLog() );
int numberOfParticles = (int) masses.size();
setNumberOfParticles( numberOfParticles );
// set stream sizes and then create streams
_initializeStreamSizes( numberOfParticles, platform );
_initializeStreams( platform );
_setInverseSqrtMasses( masses );
return DefaultReturnValue;
}
/**
* Get T
*
* @param velocities velocities
* @param inverseMassStream inverse masses
* @param numberOfConstraints number of constraints
*
* @return temperature
*/
float BrookLangevinDynamics::getTemperature( BrookStreamInternal* velocities, BrookFloatStreamInternal* inverseMassStream,
int numberOfConstraints ) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookLangevinDynamics::getTemperature";
// ---------------------------------------------------------------------------------------
void* dataArrayV = velocities->getData( 1 );
float* velocitiesI = (float*) dataArrayV;
void* inverseMassStreamV = inverseMassStream->getData( 1 );
float* inverseMassStreamI = (float*) inverseMassStreamV;
float ke = 0.0f;
int index = 0;
int numberOfParticles = getNumberOfParticles();
for( int ii = 0; ii < numberOfParticles; ii++, index += 3 ){
ke += (velocitiesI[index]*velocitiesI[index] + velocitiesI[index+1]*velocitiesI[index+1] + velocitiesI[index+2]*velocitiesI[index+2] )/inverseMassStreamI[ii];
}
int degreesOfFreedom = 3*getNumberOfParticles() - numberOfConstraints;
float denominator = 1.0f/( ((float) BOLTZ)*((float) ( degreesOfFreedom )) );
//(void) fprintf( stderr, "%s ke=%.5e T=%.3f dof=%d\n", methodName.c_str(), ke, (ke*denominator), degreesOfFreedom );
ke *= denominator;
return ke;
}
/**
* Remove velocity com (diagnostics)
*
* @param velocities velocities
* @param inverseMassStream inverse masses
*
* @return DefaultReturnValue
*/
int BrookLangevinDynamics::removeCom( BrookStreamInternal* velocities, BrookFloatStreamInternal* inverseMassStream ) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookLangevinDynamics::removeCom";
// ---------------------------------------------------------------------------------------
void* dataArrayV = velocities->getData( 1 );
float* velocitiesI = (float*) dataArrayV;
void* inverseMassStreamV = inverseMassStream->getData( 1 );
float* inverseMassStreamI = (float*) inverseMassStreamV;
float totalMass = 0.0f;
float com[3] = { 0.0f, 0.0f, 0.0f };
int index = 0;
for( int ii = 0; ii < getNumberOfParticles(); ii++ ){
float mass = 1.0f/inverseMassStreamI[ii];
totalMass += mass;
com[0] += mass*velocitiesI[index];
com[1] += mass*velocitiesI[index+1];
com[2] += mass*velocitiesI[index+2];
index += 3;
}
totalMass = 1.0f/totalMass;
com[0] *= totalMass;
com[1] *= totalMass;
com[2] *= totalMass;
index = 0;
double* newVelocities = new double[velocities->getStreamSize()*velocities->getWidth()];
memset( newVelocities, 0, sizeof( double )*velocities->getStreamSize()*velocities->getWidth() );
for( int ii = 0; ii < getNumberOfParticles(); ii++ ){
newVelocities[index] = (double) velocitiesI[index] - com[0];
newVelocities[index+1] = (double) velocitiesI[index+1] - com[1];
newVelocities[index+2] = (double) velocitiesI[index+2] - com[2];
index += 3;
}
velocities->loadFromArray( newVelocities );
dataArrayV = velocities->getData( 1 );
velocitiesI = (float*) dataArrayV;
/*
(void) fprintf( stderr, "%s readback\n", methodName.c_str() );
for( int ii = 0; ii < velocities->getStreamSize()*3; ii += 3 ){
(void) fprintf( stderr, "%s %d velocitiesI[%14.5e %14.5e %14.5e]\n", methodName.c_str(), ii/3, velocitiesI[ii], velocitiesI[ii+1], velocitiesI[ii+2] );
}
*/
velocities->loadFromArray( newVelocities );
delete[] newVelocities;
return DefaultReturnValue;
}
/**
* Reset velocities (diagnostics)
*
* @param velocities velocities
*
* @return DefaultReturnValue
*/
int BrookLangevinDynamics::resetVelocities( BrookStreamInternal* velocities ) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookLangevinDynamics::resetVelocities";
// ---------------------------------------------------------------------------------------
// reset velocities to determinisitic values
// note use of double instead of float for the load array
double* newVelocities = new double[velocities->getStreamSize()*velocities->getWidth()];
memset( newVelocities, 0, sizeof( double )*velocities->getStreamSize()*velocities->getWidth() );
for( int ii = 1; ii <= 3*getNumberOfParticles(); ii++ ){
int jj = ii % 10;
double sign = jj % 2 ? 0.1 : -0.1;
newVelocities[ii-1] = sign*( (double) jj);
}
velocities->loadFromArray( newVelocities );
delete[] newVelocities;
return DefaultReturnValue;
}
/*
* Get contents of object
*
* @param level level of dump
*
* @return string containing contents
*
* */
std::string BrookLangevinDynamics::getContentsString( int level ) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookLangevinDynamics::getContentsString";
static const unsigned int MAX_LINE_CHARS = 256;
char value[MAX_LINE_CHARS];
static const char* Set = "Set";
static const char* NotSet = "Not set";
// ---------------------------------------------------------------------------------------
std::stringstream message;
std::string tab = " ";
#ifdef _MSC_VER
#define LOCAL_SPRINTF(a,b,c) sprintf_s( (a), MAX_LINE_CHARS, (b), (c) );
#else
#define LOCAL_SPRINTF(a,b,c) sprintf( (a), (b), (c) );
#endif
(void) LOCAL_SPRINTF( value, "%d", getNumberOfParticles() );
message << _getLine( tab, "Number of particles:", value );
(void) LOCAL_SPRINTF( value, "%d", getParticleStreamWidth() );
message << _getLine( tab, "Particle stream width:", value );
(void) LOCAL_SPRINTF( value, "%d", getParticleStreamHeight() );
message << _getLine( tab, "Particle stream height:", value );
(void) LOCAL_SPRINTF( value, "%d", getParticleStreamSize() );
message << _getLine( tab, "Particle stream size:", value );
(void) LOCAL_SPRINTF( value, "%.5f", getTau() );
message << _getLine( tab, "Tau:", value );
(void) LOCAL_SPRINTF( value, "%.5f", getTemperature() );
message << _getLine( tab, "Temperature:", value );
(void) LOCAL_SPRINTF( value, "%.5f", getStepSize() );
message << _getLine( tab, "Step size:", value );
const BrookOpenMMFloat* derivedParameters = getDerivedParameters();
for( int ii = 0; ii < MaxDerivedParameters; ii++ ){
(void) LOCAL_SPRINTF( value, "%.5e", derivedParameters[ii] );
message << _getLine( tab, _getDerivedParametersString( ii ), value );
}
(void) LOCAL_SPRINTF( value, "%.5f", getTemperature() );
message << _getLine( tab, "Temperature:", value );
message << _getLine( tab, "Log:", (getLog() ? Set : NotSet) );
message << _getLine( tab, "SDPC1:", (getSDPC1Stream() ? Set : NotSet) );
message << _getLine( tab, "SDPC2:", (getSDPC2Stream() ? Set : NotSet) );
message << _getLine( tab, "SD2X:", (getSD2XStream() ? Set : NotSet) );
message << _getLine( tab, "SD1V:", (getSD1VStream() ? Set : NotSet) );
for( int ii = 0; ii < LastStreamIndex; ii++ ){
message << std::endl;
if( _sdStreams[ii] ){
message << _sdStreams[ii]->getContentsString( );
}
}
#undef LOCAL_SPRINTF
return message.str();
}
/**
* Update
*
* @param positions particle positions
* @param velocities particle velocities
* @param forces particle forces
* @param brookShakeAlgorithm BrookShakeAlgorithm reference
* @param brookRandomNumberGenerator BrookRandomNumberGenerator reference
*
* @return DefaultReturnValue
*
*/
int BrookLangevinDynamics::update( BrookStreamImpl& positionStream, BrookStreamImpl& velocityStream,
BrookStreamImpl& forceStream,
BrookShakeAlgorithm& brookShakeAlgorithm,
BrookRandomNumberGenerator& brookRandomNumberGenerator ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "\nBrookLangevinDynamics::update";
int printOn = 0;
FILE* log;
// ---------------------------------------------------------------------------------------
_internalStepCount++;
//setLog( stderr );
if( printOn && getLog() ){
log = getLog();
} else {
printOn = 0;
}
const BrookOpenMMFloat* derivedParameters = getDerivedParameters();
if( printOn ){
static int showAux = 1;
if( printOn && showAux ){
(void) fprintf( log, "%s step=%d shake=%d\n", methodName.c_str(), _internalStepCount, brookShakeAlgorithm.getNumberOfConstraints() );
(void) fflush( log );
}
// show update
if( showAux ){
showAux = 0;
std::string contents = getContentsString( );
(void) fprintf( log, "%s step=%d contents\n%s", methodName.c_str(), _internalStepCount, contents.c_str() );
contents = brookRandomNumberGenerator.getContentsString( );
(void) fprintf( log, "%s step=%d RNG contents\n%s", methodName.c_str(), _internalStepCount, contents.c_str() );
// brookRandomNumberGenerator.getRandomNumberStream( brookRandomNumberGenerator.getRvStreamIndex() )->printToFile( log );
contents = brookShakeAlgorithm.getContentsString( );
(void) fprintf( log, "%s step=%d Shake contents\n%s", methodName.c_str(), _internalStepCount, contents.c_str() );
(void) fflush( log );
}
}
// diagnostics
if( 0 && _internalStepCount == 1 ){
//resetVelocities( velocityStream.getBrookStreamInternal() );
std::string velocityFileName = "kupdate_sd1_strV.in";
std::string rvName0 = "kupdate_sd1_0.fgauss.in";
std::string rvName1 = "kupdate_sd1_1.fgauss.in";
std::string sd2xName = "kupdate_sd1_strSD2X.in";
velocityStream.getBrookStreamInternal()->loadStreamGivenFileName( velocityFileName );
brookRandomNumberGenerator.getRandomNumberStream( 0 )->loadStreamGivenFileName( rvName0 );
brookRandomNumberGenerator.getRandomNumberStream( 1 )->loadStreamGivenFileName( rvName1 );
getSD2XStream()->loadStreamGivenFileName( sd2xName );
}
// more diagnostics
if( 0 && (_internalStepCount % 10) == 0 ){
FILE* log1 = stderr;
(void) fprintf( log1, "\nVelocityStream %d XX\n", _internalStepCount ); fflush( log1 );
BrookStreamInternal* brookStreamInternalPos = velocityStream.getBrookStreamInternal();
float temperature = getTemperature( brookStreamInternalPos, getInverseMassStream(), brookShakeAlgorithm.getNumberOfConstraints() );
// removeCom( brookStreamInternalPos, getInverseMassStream() );
float temperaturePost = getTemperature( brookStreamInternalPos, getInverseMassStream(), brookShakeAlgorithm.getNumberOfConstraints() );
(void) fprintf( log1, "\nVelocityStream %d Tp=%.3f %.3f\n", _internalStepCount, temperature, temperaturePost );
(void) fprintf( log1, "\n%s step=%d Post kupdate_sd1_fix1: particleStrW=%3d rngStrW=%3d rngOff=%5d "
"EM=%12.5e Sd1pc[]=[%12.5e %12.5e %12.5e]", methodName.c_str(), _internalStepCount,
getLangevinDynamicsParticleStreamWidth(),
brookRandomNumberGenerator.getRandomNumberStreamWidth(),
brookRandomNumberGenerator.getRvStreamOffset(),
derivedParameters[EM], derivedParameters[Sd1pc1], derivedParameters[Sd1pc2], derivedParameters[Sd1pc3] );
(void) fprintf( log1, "\nRvStreamIndex=%d step=%d\n", brookRandomNumberGenerator.getRvStreamIndex(), _internalStepCount );
fflush( log1 );
}
// first integration step
kupdate_sd1_fix1(
(float) getLangevinDynamicsParticleStreamWidth(),
(float) brookRandomNumberGenerator.getRandomNumberStreamWidth(),
(float) brookRandomNumberGenerator.getRvStreamOffset(),
derivedParameters[EM],
derivedParameters[Sd1pc1],
derivedParameters[Sd1pc2],
derivedParameters[Sd1pc3],
getSDPC1Stream()->getBrookStream(),
brookRandomNumberGenerator.getRandomNumberStream( brookRandomNumberGenerator.getRvStreamIndex() )->getBrookStream(),
getSD2XStream()->getBrookStream(),
positionStream.getBrookStream(),
forceStream.getBrookStream(),
velocityStream.getBrookStream(),
getInverseMassStream()->getBrookStream(),
getSD1VStream()->getBrookStream(),
getVPrimeStream()->getBrookStream(),
getXPrimeStream()->getBrookStream() );
// diagnostics
if( 0 && printOn ){
(void) fprintf( log, "\n%s step=%d Post kupdate_sd1_fix1: particleStrW=%3d rngStrW=%3d rngOff=%5d "
"EM=%12.5e Sd1pc[]=[%12.5e %12.5e %12.5e]", methodName.c_str(), _internalStepCount,
getLangevinDynamicsParticleStreamWidth(),
brookRandomNumberGenerator.getRandomNumberStreamWidth(),
brookRandomNumberGenerator.getRvStreamOffset(),
derivedParameters[EM], derivedParameters[Sd1pc1], derivedParameters[Sd1pc2], derivedParameters[Sd1pc3] );
if( _internalStepCount == 1 ){
(void) fprintf( log, "\nSDPC1Stream fixed input sd1 step=%d\n", _internalStepCount );
getSDPC1Stream()->printToFile( log );
(void) fprintf( log, "\nSD2XStream fixed input sd1 step=%d\n", _internalStepCount );
getSD2XStream()->printToFile( log );
(void) fprintf( log, "\nInverseMassStream fixed input sd1 step=%d\n", _internalStepCount );
getInverseMassStream()->printToFile( log );
}
BrookStreamInternal* brookStreamInternalPos = positionStream.getBrookStreamInternal();
(void) fprintf( log, "\nPositionStream input sd1 step=%d\n", _internalStepCount );
brookStreamInternalPos->printToFile( log );
(void) fprintf( log, "\nForceStream input sd1 step=%d\n", _internalStepCount );
BrookStreamInternal* brookStreamInternalF = forceStream.getBrookStreamInternal();
brookStreamInternalF->printToFile( log );
BrookStreamInternal* brookStreamInternalV = velocityStream.getBrookStreamInternal();
(void) fprintf( log, "\nVelocityStream input sd1 step=%d\n", _internalStepCount );
brookStreamInternalV->printToFile( log );
(void) fprintf( log, "\nSD1VStream output sd1 step=%d\n", _internalStepCount );
getSD1VStream()->printToFile( log );
(void) fprintf( log, "\nVPrimeStream output sd1 step=%d\n", _internalStepCount );
getVPrimeStream()->printToFile( log );
(void) fprintf( log, "\nXPrimeStream output sd1 step=%d\n", _internalStepCount );
getXPrimeStream()->printToFile( log );
if( _internalStepCount == 1 ){
std::vector streams;
streams.push_back( brookStreamInternalPos );
streams.push_back( getXPrimeStream() );
std::stringstream fileNameBaseS;
fileNameBaseS << "Brook_Sd1PreShk_" << _internalStepCount << ".txt";
BrookStreamInternal::printStreamsToFile( fileNameBaseS.str(), streams );
}
(void) fprintf( log, "\nRvStreamIndex=%d step=%d\n", brookRandomNumberGenerator.getRvStreamIndex(), _internalStepCount );
// brookRandomNumberGenerator.getRandomNumberStream( brookRandomNumberGenerator.getRvStreamIndex() )->printToFile( log );
}
// advance random number cursor
brookRandomNumberGenerator.advanceGVCursor( 2*getNumberOfParticles() );
// first Shake step
if( brookShakeAlgorithm.getNumberOfConstraints() > 0 ){
kshakeh_fix1(
(float) brookShakeAlgorithm.getMaxIterations(),
(float) getLangevinDynamicsParticleStreamWidth(),
brookShakeAlgorithm.getShakeTolerance(),
brookShakeAlgorithm.getShakeParticleIndicesStream()->getBrookStream(),
positionStream.getBrookStream(),
getXPrimeStream()->getBrookStream(),
brookShakeAlgorithm.getShakeParticleParameterStream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons0Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons1Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons2Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons3Stream()->getBrookStream() );
// first Shake gather
kshakeh_update1_fix1(
(float) brookShakeAlgorithm.getShakeConstraintStreamWidth(),
brookShakeAlgorithm.getShakeInverseMapStream()->getBrookStream(),
getXPrimeStream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons0Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons1Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons2Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons3Stream()->getBrookStream(),
getXPrimeStream()->getBrookStream() );
if( 0 && printOn ){
(void) fprintf( log, "\n%s Post kshakeh_update1: sw=%d ShkCnstStrW=%3d tol=%.3f maxIt=%d",
methodName.c_str(), getLangevinDynamicsParticleStreamWidth(),
brookShakeAlgorithm.getShakeConstraintStreamWidth(),
brookShakeAlgorithm.getShakeTolerance(), brookShakeAlgorithm.getMaxIterations() );
if( _internalStepCount == 1 ){
(void) fprintf( log, "\nShakeInverseMapStream fixed input sd shake1 at step=%d\n" );
brookShakeAlgorithm.getShakeInverseMapStream()->printToFile( log );
}
BrookStreamInternal* brookStreamInternalPos = positionStream.getBrookStreamInternal();
(void) fprintf( log, "\nPositionStream input sd shake1 at step=%d\n", _internalStepCount );
brookStreamInternalPos->printToFile( log );
(void) fprintf( log, "\nXPrimeStream output sd shake1 at step=%d\n", _internalStepCount );
getXPrimeStream()->printToFile( log );
(void) fprintf( log, "\nShakeXCons0 output sd shake1 at step=%d\n", _internalStepCount );
brookShakeAlgorithm.getShakeXCons0Stream()->printToFile( log );
(void) fprintf( log, "\nShakeXCons1 output sd shake1 at step=%d\n", _internalStepCount );
brookShakeAlgorithm.getShakeXCons1Stream()->printToFile( log );
(void) fprintf( log, "\nShakeXCons2 output sd shake1 at step=%d\n", _internalStepCount );
brookShakeAlgorithm.getShakeXCons2Stream()->printToFile( log );
(void) fprintf( log, "\nShakeXCons3 output sd shake1 at step=%d\n", _internalStepCount );
brookShakeAlgorithm.getShakeXCons3Stream()->printToFile( log );
if( _internalStepCount < 2 ){
std::vector streams;
streams.push_back( brookStreamInternalPos );
streams.push_back( getXPrimeStream() );
std::stringstream fileNameBaseS;
fileNameBaseS << "Brook_Sd1PostShk_" << _internalStepCount << ".txt";
BrookStreamInternal::printStreamsToFile( fileNameBaseS.str(), streams );
}
}
}
// second integration step
kupdate_sd2_fix1(
(float) getLangevinDynamicsParticleStreamWidth(),
(float) brookRandomNumberGenerator.getRandomNumberStreamWidth(),
(float) brookRandomNumberGenerator.getRvStreamOffset(),
derivedParameters[Sd2pc1],
derivedParameters[Sd2pc2],
getSDPC2Stream()->getBrookStream(),
brookRandomNumberGenerator.getRandomNumberStream( brookRandomNumberGenerator.getRvStreamIndex() )->getBrookStream(),
getSD1VStream()->getBrookStream(),
positionStream.getBrookStream(),
getXPrimeStream()->getBrookStream(),
getVPrimeStream()->getBrookStream(),
getSD2XStream()->getBrookStream(),
velocityStream.getBrookStream(),
getXPrimeStream()->getBrookStream()
);
// diagnostics
if( 0 && printOn ){
(void) fprintf( log, "\n%s step=%d Post kupdate_sd2_fix1: particleStrW=%3d rngStrW=%3d rngOff=%5d "
"Sd2pc[]=[%12.5e %12.5e]", methodName.c_str(), _internalStepCount,
getLangevinDynamicsParticleStreamWidth(),
brookRandomNumberGenerator.getRandomNumberStreamWidth(),
brookRandomNumberGenerator.getRvStreamOffset(),
derivedParameters[Sd2pc1], derivedParameters[Sd2pc2] );
(void) fprintf( log, "\nSDPC2Stream input sd2 step=%d\n", _internalStepCount );
getSDPC2Stream()->printToFile( log );
(void) fprintf( log, "\ngetSD1VStream input sd2 step=%d\n", _internalStepCount );
getSD1VStream()->printToFile( log );
BrookStreamInternal* brookStreamInternalPos = positionStream.getBrookStreamInternal();
(void) fprintf( log, "\nPositionStream input sd2 step=%d \n", _internalStepCount );
brookStreamInternalPos->printToFile( log );
(void) fprintf( log, "\nVPrimeStream input sd2 step=%d\n", _internalStepCount );
getVPrimeStream()->printToFile( log );
(void) fprintf( log, "\nXPrimeStream output sd2 step=%d\n", _internalStepCount );
getXPrimeStream()->printToFile( log );
(void) fprintf( log, "\nSD2XStream output sd2 step=%d\n", _internalStepCount );
getSD2XStream()->printToFile( log );
BrookStreamInternal* brookStreamInternalVel = velocityStream.getBrookStreamInternal();
(void) fprintf( log, "\nVelocityStream output sd2 step=%d\n", _internalStepCount );
brookStreamInternalVel->printToFile( log );
(void) fprintf( log, "\nRvStreamIndex=%d step=%d\n", brookRandomNumberGenerator.getRvStreamIndex(), _internalStepCount );
// brookRandomNumberGenerator.getRandomNumberStream( brookRandomNumberGenerator.getRvStreamIndex() )->printToFile( log );
if( _internalStepCount < 3 ){
std::vector streams;
streams.push_back( brookStreamInternalVel );
streams.push_back( getXPrimeStream() );
std::stringstream fileNameBaseS;
fileNameBaseS << "Brook_Sd2Out_" << _internalStepCount << ".txt";
BrookStreamInternal::printStreamsToFile( fileNameBaseS.str(), streams );
}
}
// advance random number cursor
brookRandomNumberGenerator.advanceGVCursor( 2*getNumberOfParticles() );
// second Shake step
if( brookShakeAlgorithm.getNumberOfConstraints() > 0 ){
kshakeh_fix1(
(float) brookShakeAlgorithm.getMaxIterations(),
(float) getLangevinDynamicsParticleStreamWidth(),
brookShakeAlgorithm.getShakeTolerance(),
brookShakeAlgorithm.getShakeParticleIndicesStream()->getBrookStream(),
positionStream.getBrookStream(),
getXPrimeStream()->getBrookStream(),
brookShakeAlgorithm.getShakeParticleParameterStream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons0Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons1Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons2Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons3Stream()->getBrookStream() );
// second Shake gather
kshakeh_update2_fix1(
(float) brookShakeAlgorithm.getShakeConstraintStreamWidth(),
brookShakeAlgorithm.getShakeInverseMapStream()->getBrookStream(),
positionStream.getBrookStream(),
getXPrimeStream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons0Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons1Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons2Stream()->getBrookStream(),
brookShakeAlgorithm.getShakeXCons3Stream()->getBrookStream(),
positionStream.getBrookStream() );
// diagnostics
if( 0 && printOn ){
(void) fprintf( log, "\n%s step=%d Post kshakeh_update2_fix1: ShakeConstraintStreamWidth=%3d rngStrW=%3d rngOff=%5d "
"Sd2pc[]=[%12.5e %12.5e]\n", methodName.c_str(), _internalStepCount,
brookShakeAlgorithm.getShakeConstraintStreamWidth(),
brookRandomNumberGenerator.getRandomNumberStreamWidth(),
brookRandomNumberGenerator.getRvStreamOffset(),
derivedParameters[Sd2pc1], derivedParameters[Sd2pc2] );
BrookStreamInternal* brookStreamInternalPos = positionStream.getBrookStreamInternal();
std::string violationString;
brookShakeAlgorithm.checkConstraints( brookStreamInternalPos, violationString, 0.0001f );
(void) fprintf( log, "\nPositionStream output sd shake2 step=%d %s\n", _internalStepCount, violationString.c_str() );
brookStreamInternalPos->printToFile( log );
BrookStreamInternal* brookStreamInternalF = forceStream.getBrookStreamInternal();
std::vector > forceStatistics;
brookStreamInternalF->getStatistics( forceStatistics, getNumberOfParticles() );
std::stringstream tag;
tag << _internalStepCount << " Fxx ";
std::string stats = brookStreamInternalF->printStatistics( tag.str(), forceStatistics );
(void) fprintf( log, "\nStep %d Force stats:\n%s", _internalStepCount, stats.c_str() );
brookStreamInternalF->printToFile( log );
brookStreamInternalPos = velocityStream.getBrookStreamInternal();
std::vector > velocityStatistics;
brookStreamInternalPos->getStatistics( velocityStatistics, getNumberOfParticles() );
std::stringstream tagV;
tagV << _internalStepCount << " Vxx ";
stats = brookStreamInternalPos->printStatistics( tagV.str(), velocityStatistics );
(void) fprintf( log, "\nStep %d Velocity stats:\n%s", _internalStepCount, stats.c_str() );
float temperature = getTemperature( brookStreamInternalPos, getInverseMassStream(), brookShakeAlgorithm.getNumberOfConstraints() );
(void) fprintf( log, "\nVelocityStream %d T=%.3f\n", _internalStepCount, temperature );
brookStreamInternalPos->printToFile( log );
(void) fprintf( log, "\nXPrimeStream input sd shake2 step=%d\n", _internalStepCount );
getXPrimeStream()->printToFile( log );
// brookRandomNumberGenerator.getRandomNumberStream( brookRandomNumberGenerator.getRvStreamIndex() )->printToFile( log );
}
} else {
// no constraints
if( 0 && printOn ){
(void) fprintf( log, "\n%s Pre ksetStr3 (no constraints)", methodName.c_str() );
BrookStreamInternal* brookStreamInternalPos = positionStream.getBrookStreamInternal();
(void) fprintf( log, "\nPositionStream\n" );
brookStreamInternalPos->printToFile( log );
}
kadd3( getXPrimeStream()->getBrookStream(), positionStream.getBrookStream(), positionStream.getBrookStream() );
// diagnostics
if( printOn ){
(void) fprintf( log, "\n%s Post ksetStr3 (no constraints)", methodName.c_str() );
(void) fprintf( log, "\nXPrimeStream\n" );
getXPrimeStream()->printToFile( log );
BrookStreamInternal* brookStreamInternalPos = positionStream.getBrookStreamInternal();
(void) fprintf( log, "\nPositionStream\n" );
brookStreamInternalPos->printToFile( log );
// brookRandomNumberGenerator.getRandomNumberStream( brookRandomNumberGenerator.getRvStreamIndex() )->printToFile( log );
}
}
// diagnostics
if( 0 && (_internalStepCount % 1000) == 0 ){
FILE* log1 = stderr;
float epsilon = 1.0e-01f;
BrookStreamInternal* brookStreamInternalPos = positionStream.getBrookStreamInternal();
BrookStreamInternal* brookStreamInternalVel = velocityStream.getBrookStreamInternal();
BrookStreamInternal* brookStreamInternalFrc = forceStream.getBrookStreamInternal();
// check for nan and infinities
int coordinateNans = brookStreamInternalPos->checkForNans( );
int velocityNans = brookStreamInternalVel->checkForNans( );
int forceNans = brookStreamInternalFrc->checkForNans( );
int abort = abs( coordinateNans ) + abs( velocityNans ) + abs( forceNans );
// Shake violations
std::string violationString;
int constraintViolations = brookShakeAlgorithm.checkConstraints( brookStreamInternalPos, violationString, 0.0001f );
abort += abs( constraintViolations );
// check T consistent w/ specified value
float temperature = getTemperature( brookStreamInternalVel, getInverseMassStream(), brookShakeAlgorithm.getNumberOfConstraints() );
if( fabsf( temperature - getTemperature() ) > 2.0f*temperature ){
abort++;
}
// force sums ~ 0?
std::vector sums;
brookStreamInternalFrc->sumColumns( sums );
// check if should abort
(void) fprintf( log1, "%d T=%.3f Nans: x=%d v=%d f=%d ", _internalStepCount, temperature, coordinateNans, velocityNans, forceNans );
(void) fprintf( log1, " Fsum[" );
for( int ii = 0; ii < 3; ii++ ){
if( fabsf( sums[ii] ) > epsilon ){
abort++;
}
(void) fprintf( log1, "%12.4e ", sums[ii] );
}
(void) fprintf( log1, "] %s abort=%d\n", violationString.c_str(), abort );
(void) fflush( log1 );
if( abort ){
int nans[2];
nans[0] = brookRandomNumberGenerator.getRandomNumberStream( 0 )->checkForNans();
nans[1] = brookRandomNumberGenerator.getRandomNumberStream( 1 )->checkForNans();
(void) fprintf( log1, "Aborting: Nans rng: active index=%d %d %d\n", brookRandomNumberGenerator.getRvStreamIndex(), nans[0], nans[1] );
brookStreamInternalPos->printToFile( log1 );
brookStreamInternalVel->printToFile( log1 );
brookStreamInternalFrc->printToFile( log1 );
brookRandomNumberGenerator.getRandomNumberStream( brookRandomNumberGenerator.getRvStreamIndex() )->printToFile( log1 );
exit(1);
}
/*
std::vector > velocityStatistics;
brookStreamInternalPos->getStatistics( velocityStatistics, getNumberOfParticles() );
std::stringstream tagV;
tagV << _internalStepCount << " Vxx ";
std::string stats = brookStreamInternalPos->printStatistics( tagV.str(), velocityStatistics );
(void) fprintf( log1, "\nStep %d Velocity stats:\n%s", _internalStepCount, stats.c_str() );
*/
//removeCom( brookStreamInternalPos, getInverseMassStream() );
}
return DefaultReturnValue;
}