diff --git a/patches/gromacs-4.6.5.diff/src/kernel/md.c b/patches/gromacs-4.6.5.diff/src/kernel/md.c index c896ffadd94a9bfac98caa32822d7f8482161473..a96f3bcd40e5f62081515b9a7980411be94a632c 100644 --- a/patches/gromacs-4.6.5.diff/src/kernel/md.c +++ b/patches/gromacs-4.6.5.diff/src/kernel/md.c @@ -726,6 +726,13 @@ double do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[], /* PLUMED */ if(plumedswitch){ +/* detect plumed API version */ + int pversion=0; + plumed_cmd(plumedmain,"getApiVersion",&pversion); +/* setting kbT is only implemented with api>1) */ + real kbT=ir->opts.ref_t[0]*BOLTZ; + if(pversion>1) plumed_cmd(plumedmain,"setKbT",&kbT); + if(cr->ms && cr->ms->nsim>1) { if(MASTER(cr)) plumed_cmd(plumedmain,"GREX setMPIIntercomm",&cr->ms->mpi_comm_masters); if(PAR(cr)){ diff --git a/src/analysis/Analysis.cpp b/src/analysis/Analysis.cpp index 9e3a6cc9f2b31d59ea77b33e78eb4c865f629334..425f51a8553e28e420190e890ec5fa1e1d013c20 100644 --- a/src/analysis/Analysis.cpp +++ b/src/analysis/Analysis.cpp @@ -150,14 +150,19 @@ argument_names(getNumberOfArguments()) } } - simtemp=0.; parse("TEMP",simtemp); - if( simtemp==0 && !biases.empty() ) error("to reweight you must specify a temperature use TEMP"); - rtemp=0; + rtemp=0; if( keywords.exists("REWEIGHT_TEMP") ) parse("REWEIGHT_TEMP",rtemp); if( rtemp!=0 ){ - if( simtemp==0 ) error("to reweight you must specify a temperature use TEMP"); - needeng=true; - log.printf(" reweighting simulation at %f to probabilities at temperature %f\n",simtemp,rtemp); + needeng=true; + log.printf(" reweighting simulation to probabilities at temperature %f\n",rtemp); + rtemp*=plumed.getAtoms().getKBoltzmann(); + } + simtemp=0.; parse("TEMP",simtemp); + if( rtemp>0 || !biases.empty() ){ + if(simtemp>0) simtemp*=plumed.getAtoms().getKBoltzmann(); + else simtemp*=plumed.getAtoms().getKbT(); + + if(simtemp==0) error("The MD engine does not pass the temperature to plumed so you have to specify it using TEMP"); } parseFlag("USE_ALL_DATA",single_run); @@ -260,10 +265,10 @@ void Analysis::calculate(){ if(needeng){ double energy=plumed.getAtoms().getEnergy()+bias; // Reweighting because of temperature difference - ww=-( (1.0/rtemp) - (1.0/simtemp) )*(energy+bias) / plumed.getAtoms().getKBoltzmann(); + ww=-( (1.0/rtemp) - (1.0/simtemp) )*(energy+bias); } // Reweighting because of biases - if( !biases.empty() ) ww += bias/( plumed.getAtoms().getKBoltzmann()*simtemp ); + if( !biases.empty() ) ww += bias/ simtemp; // Get the arguments ready to transfer to reference configuration for(unsigned i=0;i<getNumberOfArguments();++i) current_args[i]=getArgument(i); diff --git a/src/analysis/Analysis.h b/src/analysis/Analysis.h index 22c30f8e433912308e5a43b462c561a0bb851d34..5b4343a6785f0dee31d5fd235b0eac7d119ec29d 100644 --- a/src/analysis/Analysis.h +++ b/src/analysis/Analysis.h @@ -121,7 +121,7 @@ protected: bool getPeriodicityInformation(const unsigned& i, std::string& dmin, std::string& dmax); /// Return the normalization constant double getNormalization() const; -/// Return the set temperature +/// Return the set temperature (N.B. k_B T is what is returned by this function) double getTemp () const; /// Are we analyzing each data block separately (if we are not this also returns the old normalization ) bool usingMemory() const; diff --git a/src/analysis/Histogram.cpp b/src/analysis/Histogram.cpp index 3fa0c092f993977428f402cc8a4f54bca8af8890..b4f984169f33fed41e4401406538e903e9bbe29f 100644 --- a/src/analysis/Histogram.cpp +++ b/src/analysis/Histogram.cpp @@ -258,7 +258,7 @@ void Histogram::performAnalysis(){ // Normalize the histogram gg->scaleAllValuesAndDerivatives( 1.0 / getNormalization() ); if(fenergy) { - gg->logAllValuesAndDerivatives( -getTemp() * plumed.getAtoms().getKBoltzmann() ); + gg->logAllValuesAndDerivatives( -getTemp() ); gg->setMinToZero(); } diff --git a/src/bias/MetaD.cpp b/src/bias/MetaD.cpp index 3266464283f9b8be796400fd9d903ed9b0b0e3fe..f9f2619d0d3c1d3bb41a46de1d73c0fcd79f9c5f 100644 --- a/src/bias/MetaD.cpp +++ b/src/bias/MetaD.cpp @@ -245,7 +245,7 @@ private: bool grid_,hasextgrid_; double height0_; double biasf_; - double temp_; + double kbt_; int stride_; bool welltemp_; double* dp_; @@ -342,7 +342,7 @@ PLUMED_BIAS_INIT(ao), // Grid stuff initialization BiasGrid_(NULL),ExtGrid_(NULL), wgridstride_(0), grid_(false), hasextgrid_(false), // Metadynamics basic parameters -height0_(std::numeric_limits<double>::max()), biasf_(1.0), temp_(0.0), +height0_(std::numeric_limits<double>::max()), biasf_(1.0), kbt_(0.0), stride_(0), welltemp_(false), // Other stuff dp_(NULL), adaptive_(FlexibleBin::none), @@ -417,9 +417,12 @@ isFirstStep(true) parse("FILE",hillsfname); parse("BIASFACTOR",biasf_); if( biasf_<1.0 ) error("well tempered bias factor is nonsensical"); - parse("TEMP",temp_); + double temp; + parse("TEMP",temp); + if(temp>0.0) kbt_=plumed.getAtoms().getKBoltzmann()*temp; + else kbt_=plumed.getAtoms().getKbT(); if(biasf_>1.0){ - if(temp_==0.0) error("if you are doing well tempered metadynamics you must specify the temperature using TEMP"); + if(kbt_==0.0) error("Unless the MD engine passes the temperature to plumed, with well-tempered metad you must specify it using TEMP"); welltemp_=true; } double tau=0.0; @@ -427,11 +430,11 @@ isFirstStep(true) if(tau==0.0){ if(height0_==std::numeric_limits<double>::max()) error("At least one between HEIGHT and TAU should be specified"); // if tau is not set, we compute it here from the other input parameters - if(welltemp_) tau=(plumed.getAtoms().getKBoltzmann()*temp_*(biasf_-1.0))/height0_*getTimeStep()*stride_; + if(welltemp_) tau=(kbt_*(biasf_-1.0))/height0_*getTimeStep()*stride_; } else { if(!welltemp_)error("TAU only makes sense in well-tempered metadynamics"); if(height0_!=std::numeric_limits<double>::max()) error("At most one between HEIGHT and TAU should be specified"); - height0_=(plumed.getAtoms().getKBoltzmann()*temp_*(biasf_-1.0))/tau*getTimeStep()*stride_; + height0_=(kbt_*(biasf_-1.0))/tau*getTimeStep()*stride_; } // Grid Stuff @@ -537,6 +540,7 @@ isFirstStep(true) if(welltemp_){ log.printf(" Well-Tempered Bias Factor %f\n",biasf_); log.printf(" Hills relaxation time (tau) %f\n",tau); + log.printf(" KbT %f\n",kbt_); } if(doInt_) log.printf(" Upper and Lower limits boundaries for the bias are activated at %f - %f\n", lowI_, uppI_); if(grid_){ @@ -971,7 +975,7 @@ double MetaD::getHeight(const vector<double>& cv) double height=height0_; if(welltemp_){ double vbias=getBiasAndDerivatives(cv); - height=height0_*exp(-vbias/(plumed.getAtoms().getKBoltzmann()*temp_*(biasf_-1.0))); + height=height0_*exp(-vbias/(kbt_*(biasf_-1.0))); } return height; } @@ -993,7 +997,7 @@ void MetaD::calculate() getPntrToComponent("bias")->set(ene); // calculate the acceleration factor if(acceleration&&!isFirstStep) { - acc += exp(ene/(plumed.getAtoms().getKBoltzmann()*temp_)); + acc += exp(ene/(kbt_)); double mean_acc = acc/((double) getStep()); getPntrToComponent("acc")->set(mean_acc); } diff --git a/src/core/Atoms.cpp b/src/core/Atoms.cpp index 2ce582a1e1b119f887eb14b57a9a7d278671aaaa..1fa1b04da19456ac633b89a68c49bdc38aa9823d 100644 --- a/src/core/Atoms.cpp +++ b/src/core/Atoms.cpp @@ -55,7 +55,8 @@ Atoms::Atoms(PlumedMain&plumed): plumed(plumed), naturalUnits(false), timestep(0.0), - forceOnEnergy(0.0) + forceOnEnergy(0.0), + kbT(0.0) { mdatoms=MDAtomsBase::create(sizeof(double)); } @@ -356,6 +357,15 @@ double Atoms::getTimeStep()const{ return timestep/units.getTime()*MDUnits.getTime(); } +void Atoms::setKbT(void*p){ + MD2double(p,kbT); +} + +double Atoms::getKbT()const{ + return kbT/units.getEnergy()*MDUnits.getEnergy(); +} + + void Atoms::createFullList(int*n){ vector<AtomNumber> fullListTmp; for(unsigned i=0;i<actions.size();i++) if(actions[i]->isActive()) diff --git a/src/core/Atoms.h b/src/core/Atoms.h index ee3daeae2ec2d3a28bc7638fb18686c51847c05c..3d5ca4030c8d3203e4d53a13839307d24510e7d6 100644 --- a/src/core/Atoms.h +++ b/src/core/Atoms.h @@ -90,6 +90,8 @@ class Atoms double timestep; double forceOnEnergy; + double kbT; + std::vector<const ActionAtomistic*> actions; std::vector<int> gatindex; @@ -137,6 +139,9 @@ public: void setTimeStep(void*); double getTimeStep()const; + void setKbT(void*); + double getKbT()const; + void setNatoms(int); const int & getNatoms()const; diff --git a/src/core/PlumedMain.cpp b/src/core/PlumedMain.cpp index 5319d29fd5ce670ee2114f18081c854bbd93a2d5..e3a6c43d86f791a805b1cb0ac42fe300090eff65 100644 --- a/src/core/PlumedMain.cpp +++ b/src/core/PlumedMain.cpp @@ -46,7 +46,7 @@ using namespace std; -enum { SETBOX, SETPOSITIONS, SETMASSES, SETCHARGES, SETPOSITIONSX, SETPOSITIONSY, SETPOSITIONSZ, SETVIRIAL, SETENERGY, SETFORCES, SETFORCESX, SETFORCESY, SETFORCESZ, CALC, PREPAREDEPENDENCIES, SHAREDATA, PREPARECALC, PERFORMCALC, SETSTEP, SETSTEPLONG, SETATOMSNLOCAL, SETATOMSGATINDEX, SETATOMSCONTIGUOUS, CREATEFULLLIST, GETFULLLIST, CLEARFULLLIST, READ, CLEAR, GETAPIVERSION, INIT, SETREALPRECISION, SETMDLENGTHUNITS, SETMDENERGYUNITS, SETMDTIMEUNITS, SETNATURALUNITS, SETNOVIRIAL, SETPLUMEDDAT, SETMPICOMM, SETMPIFCOMM, SETMPIMULTISIMCOMM, SETNATOMS, SETTIMESTEP, SETMDENGINE, SETLOG, SETLOGFILE, SETSTOPFLAG, GETEXCHANGESFLAG, SETEXCHANGESSEED, SETNUMBEROFREPLICAS, GETEXCHANGESLIST, RUNFINALJOBS, ISENERGYNEEDED, GETBIAS }; +enum { SETBOX, SETPOSITIONS, SETMASSES, SETCHARGES, SETPOSITIONSX, SETPOSITIONSY, SETPOSITIONSZ, SETVIRIAL, SETENERGY, SETFORCES, SETFORCESX, SETFORCESY, SETFORCESZ, CALC, PREPAREDEPENDENCIES, SHAREDATA, PREPARECALC, PERFORMCALC, SETSTEP, SETSTEPLONG, SETATOMSNLOCAL, SETATOMSGATINDEX, SETATOMSCONTIGUOUS, CREATEFULLLIST, GETFULLLIST, CLEARFULLLIST, READ, CLEAR, GETAPIVERSION, INIT, SETREALPRECISION, SETMDLENGTHUNITS, SETMDENERGYUNITS, SETMDTIMEUNITS, SETNATURALUNITS, SETNOVIRIAL, SETPLUMEDDAT, SETMPICOMM, SETMPIFCOMM, SETMPIMULTISIMCOMM, SETNATOMS, SETTIMESTEP, SETMDENGINE, SETLOG, SETLOGFILE, SETSTOPFLAG, GETEXCHANGESFLAG, SETEXCHANGESSEED, SETNUMBEROFREPLICAS, GETEXCHANGESLIST, RUNFINALJOBS, ISENERGYNEEDED, GETBIAS, SETKBT }; namespace PLMD{ @@ -130,6 +130,7 @@ PlumedMain::PlumedMain(): word_map["runFinalJobs"]=RUNFINALJOBS; word_map["isEnergyNeeded"]=ISENERGYNEEDED; word_map["getBias"]=GETBIAS; + word_map["setKbT"]=SETKBT; } PlumedMain::~PlumedMain(){ @@ -292,7 +293,7 @@ void PlumedMain::cmd(const std::string & word,void*val){ break; case GETAPIVERSION: CHECK_NULL(val,word); - *(static_cast<int*>(val))=1; + *(static_cast<int*>(val))=2; break; // commands which can be used only before initialization: case INIT: @@ -362,6 +363,11 @@ void PlumedMain::cmd(const std::string & word,void*val){ CHECK_NULL(val,word); atoms.setTimeStep(val); break; + case SETKBT: /* ADDED WITH API==2 */ + CHECK_NOTINIT(initialized,word); + CHECK_NULL(val,word); + atoms.setKbT(val); + break; case SETMDENGINE: CHECK_NOTINIT(initialized,word); CHECK_NULL(val,word); @@ -469,6 +475,12 @@ void PlumedMain::init(){ } atoms.updateUnits(); log.printf("Timestep: %f\n",atoms.getTimeStep()); + if(atoms.getKbT()>0.0) + log.printf("KbT: %f\n",atoms.getKbT()); + else { + log.printf("KbT has not been set by the MD engine\n"); + log.printf("It should be set by hand where needed\n"); + } log<<"Relevant bibliography:\n"; log<<citations; log<<"Please read and cite where appropriate!\n";