NAMD
Controller.C
Go to the documentation of this file.
1 
7 /*****************************************************************************
8  * $Source: /home/cvs/namd/cvsroot/namd2/src/Controller.C,v $
9  * $Author: jim $
10  * $Date: 2017/03/29 21:29:03 $
11  * $Revision: 1.1326 $
12  *****************************************************************************/
13 
14 #include "InfoStream.h"
15 #include "common.h"
16 #include "converse.h"
17 #include "memusage.h"
18 #include "Node.h"
19 #include "Molecule.h"
20 #include "SimParameters.h"
21 #include "Controller.h"
22 #include "ReductionMgr.h"
23 #include "CollectionMaster.h"
24 #include "Output.h"
25 #include "strlib.h"
26 #include "BroadcastObject.h"
27 #include "NamdState.h"
28 #include "ScriptTcl.h"
29 #include "Broadcasts.h"
30 #include "LdbCoordinator.h"
31 #include "Thread.h"
32 #include <math.h>
33 #include <signal.h>
34 #include "NamdOneTools.h"
35 #include "PatchMap.h"
36 #include "PatchMap.inl"
37 #include "Random.h"
38 #include "imd.h"
39 #include "IMDOutput.h"
40 #include "BackEnd.h"
41 #include <fstream>
42 #include <iomanip>
43 #include <errno.h>
44 #include "qd.h"
45 #include "PatchData.h"
46 
47 #if defined(USE_GETTIMEOFDAY)
48 #include <sys/time.h>
49 // Replace CmiWallTimer with our own based on gettimeofday
50 static double namdWallTimer() {
51  struct timeval t;
52  gettimeofday(&t, NULL);
53  double sec = double(t.tv_sec); // get absolute seconds
54  double usec = double (t.tv_usec); // plus microseconds
55  double totalSec = sec + 1e-6 * usec;
56  return totalSec;
57 }
58 #else
59 static double namdWallTimer() {
60  return CmiWallTimer();
61 }
62 #endif
63 
64 #if(CMK_CCS_AVAILABLE && CMK_WEB_MODE)
65 extern "C" void CApplicationDepositNode0Data(char *);
66 #endif
67 
68 //#define DEBUG_PRESSURE
69 #define MIN_DEBUG_LEVEL 3
70 //#define DEBUGM
71 #include "Debug.h"
72 
73 #define XXXBIGREAL 1.0e32
74 
75 //Modifications for alchemical fep
76 static char *FEPTITLE(int X)
77 {
78  static char tmp_string[21];
79  sprintf(tmp_string, "FepEnergy: %6d ",X);
80  return tmp_string;
81 }
82 
83 static char *FEPTITLE_BACK(int X)
84 {
85  static char tmp_string[21];
86  sprintf(tmp_string, "FepE_back: %6d ",X);
87  return tmp_string;
88 }
89 
90 static char *FEPTITLE2(int X)
91 {
92  static char tmp_string[21];
93  sprintf(tmp_string, "FEP: %7d",X);
94  return tmp_string;
95 }
96 
97 static char *TITITLE(int X)
98 {
99  static char tmp_string[21];
100  sprintf(tmp_string, "TI: %7d",X);
101  return tmp_string;
102 }
103 //fepe
104 
106 private:
107  RequireReduction *reduction;
108  const int nslabs;
109  const int freq;
110  int nelements;
111  int count;
112  char *name;
113 
114  BigReal *average;
115 
116 public:
117  PressureProfileReduction(int rtag, int numslabs, int numpartitions,
118  const char *myname, int outputfreq)
119  : nslabs(numslabs), freq(outputfreq) {
120  name = strdup(myname);
121  nelements = 3*nslabs * numpartitions;
122  reduction = ReductionMgr::Object()->willRequire(rtag,nelements);
123 
124  average = new BigReal[nelements];
125  count = 0;
126  }
128  delete [] average;
129  delete reduction;
130  free(name);
131  }
132  //
133  void getData(int firsttimestep, int step, const Lattice &lattice,
134  BigReal *total) {
135  reduction->require();
136 
137  int i;
138  double inv_volume = 1.0 / lattice.volume();
139  // accumulate the pressure profile computed for this step into the average.
140  int arraysize = 3*nslabs;
141  for (i=0; i<nelements; i++) {
142  BigReal val = reduction->item(i) * inv_volume;
143  average[i] += val;
144  total[i % arraysize] += val;
145  }
146  count++;
147  if (!(step % freq)) {
148  // convert NAMD internal virial to pressure in units of bar
149  BigReal scalefac = PRESSUREFACTOR * nslabs;
150 
151  iout << "PPROFILE" << name << ": " << step << " ";
152  if (step == firsttimestep) {
153  // output pressure profile for this step
154  for (i=0; i<nelements; i++)
155  iout << reduction->item(i)*scalefac*inv_volume << " ";
156  } else {
157  // output pressure profile averaged over the last Freq steps.
158  scalefac /= count;
159  for (i=0; i<nelements; i++)
160  iout << average[i]*scalefac << " ";
161  }
162  iout << "\n" << endi;
163  // Clear the average for the next block
164  memset(average, 0, nelements*sizeof(BigReal));
165  count = 0;
166  }
167  }
168 };
169 
171  CthThread thread;
172 };
173 
175  computeChecksum(0), marginViolations(0), pairlistWarnings(0),
176  simParams(Node::Object()->simParameters),
177  state(s),
178  collection(CollectionMaster::Object()),
179  startCTime(0),
180  firstCTime(CmiTimer()),
181  startWTime(0),
182  firstWTime(namdWallTimer()),
183  startBenchTime(0),
184  stepInFullRun(0),
185  ldbSteps(0),
186  fflush_count(3)
187 {
188 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
190  CProxy_PatchData cpdata(CkpvAccess(BOCclass_group).patchData);
191  PatchData* patchData = cpdata.ckLocalBranch();
192  broadcast = new ControllerBroadcasts(0 /* ldObjPtr */, patchData->nodeBroadcast);
193  } else
194 #endif // defined(NAMD_CUDA) || defined(NAMD_HIP)
195  {
197  }
199  // for accelMD
200  if (simParams->accelMDOn) {
201  // REDUCTIONS_BASIC wil contain all potential energies and arrive first
203  // contents of amd_reduction be submitted to REDUCTIONS_AMD
205  // REDUCTIONS_AMD will contain Sequencer contributions and arrive second
207  } else {
208  amd_reduction = NULL;
209  submit_reduction = NULL;
210 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
213  }
214 #endif // defined(NAMD_CUDA) || defined(NAMD_HIP)
216  }
217  // pressure profile reductions
220  ppbonded = ppnonbonded = ppint = NULL;
222  int ntypes = simParams->pressureProfileAtomTypes;
224  // number of partitions for pairwise interactions
225  int npairs = (ntypes * (ntypes+1))/2;
226  pressureProfileAverage = new BigReal[3*nslabs];
227  memset(pressureProfileAverage, 0, 3*nslabs*sizeof(BigReal));
228  int freq = simParams->pressureProfileFreq;
231  nslabs, npairs, "BONDED", freq);
233  nslabs, npairs, "NONBONDED", freq);
234  // internal partitions by atom type, but not in a pairwise fashion
236  nslabs, ntypes, "INTERNAL", freq);
237  } else {
238  // just doing Ewald, so only need nonbonded
240  nslabs, npairs, "NONBONDED", freq);
241  }
242  }
244  random->split(0,PatchMap::Object()->numPatches()+1);
245 
246  heat = totalEnergy0 = 0.0;
249  stochRescale_count = 0;
250  if (simParams->stochRescaleOn) {
253  }
255  // strainRate tensor is symmetric to avoid rotation
258  if ( ! simParams->useFlexibleCell ) {
259  BigReal avg = trace(langevinPiston_strainRate) / 3.;
261  } else if ( simParams->useConstantRatio ) {
262 #define AVGXY(T) T.xy = T.yx = 0; T.xx = T.yy = 0.5 * ( T.xx + T.yy );\
263  T.xz = T.zx = T.yz = T.zy = 0.5 * ( T.xz + T.yz );
265 #undef AVGXY
266  }
268 
269  // Monte Carlo pressure control
275  for(int ax = 0; ax < MC_AXIS_TOTAL; ++ax) {
276  mc_trial[ax] = 0;
277  mc_accept[ax] = 0;
278  }
279  }
280 
281  if (simParams->multigratorOn) {
282  multigratorXi = 0.0;
285  Node *node = Node::Object();
286  Molecule *molecule = node->molecule;
287  BigReal Nf = molecule->num_deg_freedom();
289  multigratorNu.resize(n);
290  multigratorNuT.resize(n);
291  multigratorZeta.resize(n);
292  multigratorOmega.resize(n);
293  for (int i=0;i < n;i++) {
294  multigratorNu[i] = 0.0;
295  multigratorZeta[i] = 0.0;
296  if (i == 0) {
297  multigratorOmega[i] = Nf*kT0*tau*tau;
298  } else {
299  multigratorOmega[i] = kT0*tau*tau;
300  }
301  }
303  } else {
304  multigratorReduction = NULL;
305  }
306  origLattice = state->lattice;
308  temp_avg = 0;
309  pressure_avg = 0;
310  groupPressure_avg = 0;
311  avg_count = 0;
312  pressure_tavg = 0;
313  groupPressure_tavg = 0;
314  tavg_count = 0;
315  checkpoint_stored = 0;
316  drudeBondTemp = 0;
317  drudeBondTempAvg = 0;
318  cumAlchWork = 0;
319 
320  bondedEnergy_ti_1 = 0;
321  bondedEnergy_ti_2 = 0;
322  ljEnergy_ti_1 = 0;
323  ljEnergy_ti_2 = 0;
324  electEnergy_ti_1 = 0;
325  electEnergy_ti_2 = 0;
328  TIderivative = 0;
329 }
330 
332 {
333  delete broadcast;
334  if (reductionBasic) {
335  delete reductionBasic;
336  }
337 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
338  if (reductionGpuResident) {
339  delete reductionGpuResident;
340  }
341 #endif
342  delete min_reduction;
343  delete amd_reduction;
344  delete submit_reduction;
345  delete ppbonded;
346  delete ppnonbonded;
347  delete ppint;
348  delete [] pressureProfileAverage;
349  delete random;
351 }
352 
353 void Controller::threadRun(Controller* arg)
354 {
355  arg->algorithm();
356 }
357 
358 void Controller::run(void)
359 {
360  // create a Thread and invoke it
361  DebugM(4, "Starting thread in controller on this=" << this << "\n");
362  threadWrapper = new CthThreadWrapper;
363  threadWrapper->thread = CthCreate((CthVoidFn)&(threadRun),(void*)(this),CTRL_STK_SZ);
364  CthSetStrategyDefault(threadWrapper->thread);
365 #if CMK_BLUEGENE_CHARM
366  BgAttach(thread);
367 #endif
368  awaken();
369 }
370 
371 void Controller::awaken(void) {
372  CthAwaken(threadWrapper->thread);
373 }
374 
376  CthSuspend();
377 }
378 
380 {
381  int scriptTask;
382  int scriptSeq = 0;
383  BackEnd::awaken();
384  while ( (scriptTask = broadcast->scriptBarrier.get(scriptSeq++)) != SCRIPT_END) {
385 #ifdef NODEGROUP_FORCE_REGISTER
386  CProxy_PatchData cpdata(CkpvAccess(BOCclass_group).patchData);
387  PatchData *patchData = cpdata.ckLocalBranch();
388 #endif
389  switch ( scriptTask ) {
390  case SCRIPT_OUTPUT:
393  break;
394  case SCRIPT_FORCEOUTPUT:
396  break;
397  case SCRIPT_MEASURE:
399  break;
400  case SCRIPT_REINITVELS:
401  iout << "REINITIALIZING VELOCITIES AT STEP " << simParams->firstTimestep
402  << " TO " << simParams->initialTemp << " KELVIN.\n" << endi;
403  break;
404  case SCRIPT_RESCALEVELS:
405  iout << "RESCALING VELOCITIES AT STEP " << simParams->firstTimestep
406  << " BY " << simParams->scriptArg1 << "\n" << endi;
407  break;
409  // Parameter setting already reported in ScriptTcl
410  // Nothing to do!
411  break;
412  case SCRIPT_CHECKPOINT:
413  iout << "CHECKPOINTING AT STEP " << simParams->firstTimestep
414  << "\n" << endi;
415  checkpoint_stored = 1;
416  checkpoint_lattice = state->lattice;
418  break;
419  case SCRIPT_REVERT:
420  iout << "REVERTING AT STEP " << simParams->firstTimestep
421  << "\n" << endi;
422  if ( ! checkpoint_stored )
423  NAMD_die("Unable to revert, checkpoint was never called!");
424  state->lattice = checkpoint_lattice;
426  break;
428  iout << "STORING CHECKPOINT AT STEP " << simParams->firstTimestep
429  << " TO KEY " << simParams->scriptStringArg1;
430  if ( CmiNumPartitions() > 1 ) iout << " ON REPLICA " << simParams->scriptIntArg1;
431  iout << "\n" << endi;
432  if ( simParams->scriptIntArg1 == CmiMyPartition() ) {
433  if ( ! checkpoints.count(simParams->scriptStringArg1) ) {
435  }
437  cp.lattice = state->lattice;
438  cp.state = *(ControllerState*)this;
439  } else {
441  scriptTask, state->lattice, *(ControllerState*)this);
442  }
443  break;
445  iout << "LOADING CHECKPOINT AT STEP " << simParams->firstTimestep
446  << " FROM KEY " << simParams->scriptStringArg1;
447  if ( CmiNumPartitions() > 1 ) iout << " ON REPLICA " << simParams->scriptIntArg1;
448  iout << "\n" << endi;
449  if ( simParams->scriptIntArg1 == CmiMyPartition() ) {
450  if ( ! checkpoints.count(simParams->scriptStringArg1) ) {
451  NAMD_die("Unable to load checkpoint, requested key was never stored.");
452  }
454  state->lattice = cp.lattice;
455  *(ControllerState*)this = cp.state;
456  } else {
458  scriptTask, state->lattice, *(ControllerState*)this);
459  }
460  break;
462  iout << "SWAPPING CHECKPOINT AT STEP " << simParams->firstTimestep
463  << " FROM KEY " << simParams->scriptStringArg1;
464  if ( CmiNumPartitions() > 1 ) iout << " ON REPLICA " << simParams->scriptIntArg1;
465  iout << "\n" << endi;
466  if ( simParams->scriptIntArg1 == CmiMyPartition() ) {
467  if ( ! checkpoints.count(simParams->scriptStringArg1) ) {
468  NAMD_die("Unable to swap checkpoint, requested key was never stored.");
469  }
471  std::swap(state->lattice,cp.lattice);
472  std::swap(*(ControllerState*)this,cp.state);
473  } else {
475  scriptTask, state->lattice, *(ControllerState*)this);
476  }
477  break;
479  iout << "FREEING CHECKPOINT AT STEP " << simParams->firstTimestep
480  << " FROM KEY " << simParams->scriptStringArg1;
481  if ( CmiNumPartitions() > 1 ) iout << " ON REPLICA " << simParams->scriptIntArg1;
482  iout << "\n" << endi;
483  if ( simParams->scriptIntArg1 == CmiMyPartition() ) {
484  if ( ! checkpoints.count(simParams->scriptStringArg1) ) {
485  NAMD_die("Unable to free checkpoint, requested key was never stored.");
486  }
489  } else {
491  scriptTask, state->lattice, *(ControllerState*)this);
492  }
493  break;
494  case SCRIPT_ATOMSENDRECV:
495  case SCRIPT_ATOMSEND:
496  case SCRIPT_ATOMRECV:
497  break;
498  case SCRIPT_MINIMIZE:
499  minimize();
500  break;
501  case SCRIPT_RUN:
502  case SCRIPT_CONTINUE:
503  integrate(scriptTask);
504  break;
505  default:
506  NAMD_bug("Unknown task in Controller::algorithm");
507  }
508  BackEnd::awaken();
509  }
512  terminate();
513 }
514 
515 
516 //
517 // XXX static and global variables are unsafe for shared memory builds.
518 // The use of global and static vars should be eliminated.
519 //
520 extern int eventEndOfTimeStep;
521 
522 // Handle SIGINT so that restart files get written completely.
523 static int gotsigint = 0;
524 static void my_sigint_handler(int sig) {
525  if (sig == SIGINT) gotsigint = 1;
526 }
527 extern "C" {
528  typedef void (*namd_sighandler_t)(int);
529 }
530 
531 void Controller::integrate(int scriptTask) {
532  char traceNote[24];
533 
534  int step = simParams->firstTimestep;
535 
536  const int numberOfSteps = simParams->N;
537  const int stepsPerCycle = simParams->stepsPerCycle;
538 
539  const int zeroMomentum = simParams->zeroMomentum;
540 
542  const int dofull = ( simParams->fullElectFrequency ? 1 : 0 );
543  if (dofull)
545  else
547  if ( step >= numberOfSteps ) slowFreq = nbondFreq = 1;
548 
550 
551  if ( scriptTask == SCRIPT_RUN ) {
552 
553  reassignVelocities(step); // only for full-step velecities
554  rescaleaccelMD(step);
555  adaptTempUpdate(step); // Init adaptive tempering;
556 
557  receivePressure(step);
558  if ( zeroMomentum && dofull && ! (step % slowFreq) )
559  correctMomentum(step);
560  printFepMessage(step);
561  printTiMessage(step);
562  printDynamicsEnergies(step);
563  outputFepEnergy(step);
564  outputTiEnergy(step);
565  if(traceIsOn()){
566  traceUserEvent(eventEndOfTimeStep);
567  sprintf(traceNote, "s:%d", step);
568  traceUserSuppliedNote(traceNote);
569  }
570  outputExtendedSystem(step);
571  rebalanceLoad(step);
572 
573  }
574 
575  // Handling SIGINT doesn't seem to be working on Lemieux, and it
576  // sometimes causes the net-xxx versions of NAMD to segfault on exit,
577  // so disable it for now.
578  // namd_sighandler_t oldhandler = signal(SIGINT,
579  // (namd_sighandler_t)my_sigint_handler);
580  for ( ++step ; step <= numberOfSteps; ++step )
581  {
582  adaptTempUpdate(step);
583  rescaleVelocities(step);
584  tcoupleVelocities(step);
586  berendsenPressure(step);
587  langevinPiston1(step);
588  rescaleaccelMD(step);
589  enqueueCollections(step); // after lattice scaling!
590  receivePressure(step);
591  if ( zeroMomentum && dofull && ! (step % slowFreq) )
592  correctMomentum(step);
593  langevinPiston2(step);
594  reassignVelocities(step);
595 
596  multigratorTemperature(step, 1);
597  multigratorPressure(step, 1);
598  multigratorPressure(step, 2);
599  multigratorTemperature(step, 2);
600 
601  printDynamicsEnergies(step);
602  outputFepEnergy(step);
603  outputTiEnergy(step);
604  if(traceIsOn()){
605  traceUserEvent(eventEndOfTimeStep);
606  sprintf(traceNote, "s:%d", step);
607  traceUserSuppliedNote(traceNote);
608  }
609  // if (gotsigint) {
610  // iout << iINFO << "Received SIGINT; shutting down.\n" << endi;
611  // NAMD_quit();
612  // }
613  outputExtendedSystem(step);
614 #if CYCLE_BARRIER
615  cycleBarrier(!((step+1) % stepsPerCycle),step);
616 #elif PME_BARRIER
617  cycleBarrier(dofull && !(step%slowFreq),step);
618 #elif STEP_BARRIER
619  cycleBarrier(1, step);
620 #endif
621 
622  if(Node::Object()->specialTracing || simParams->statsOn){
623  int bstep = simParams->traceStartStep;
624  int estep = bstep + simParams->numTraceSteps;
625  if(step == bstep){
626  traceBarrier(1, step);
627  }
628  if(step == estep){
629  traceBarrier(0, step);
630  }
631  }
632 
633 #ifdef MEASURE_NAMD_WITH_PAPI
634  if(simParams->papiMeasure) {
635  int bstep = simParams->papiMeasureStartStep;
636  int estep = bstep + simParams->numPapiMeasureSteps;
637  if(step == bstep) {
638  papiMeasureBarrier(1, step);
639  }
640  if(step == estep) {
641  papiMeasureBarrier(0, step);
642  }
643  }
644 #endif
645 
646  rebalanceLoad(step);
647 
648 #if PME_BARRIER
649  cycleBarrier(dofull && !((step+1)%slowFreq),step); // step before PME
650 #endif
651  }
652  }else CthSuspend();
653  // signal(SIGINT, oldhandler);
654 }
655 
657  const int size = simParams->movingAverageWindowSize;
660  pressureAverage.reset(size);
662 }
663 
664 #ifdef NODEGROUP_FORCE_REGISTER
665 
666 void Controller::printStep(int step){
667  char traceNote[24];
668  const int numberOfSteps = simParams->N;
669  const int stepsPerCycle = simParams->stepsPerCycle;
670  const int zeroMomentum = simParams->zeroMomentum;
672  const int dofull = ( simParams->fullElectFrequency ? 1 : 0 );
673  if (dofull)
675  else
677  if ( step >= numberOfSteps ) slowFreq = nbondFreq = 1;
678 
679 if(step == simParams->firstTimestep /* && scriptTask == SCRIPT_RUN */){
680  reassignVelocities(step); // only for full-step velecities
681  rescaleaccelMD(step);
682  adaptTempUpdate(step); // Init adaptive tempering;
683 
684  receivePressure(step);
685  if ( zeroMomentum && dofull && ! (step % slowFreq) )
686  correctMomentum(step);
687  printFepMessage(step);
688  printTiMessage(step);
689  printDynamicsEnergies(step);
690  outputFepEnergy(step);
691  outputTiEnergy(step);
692  if(traceIsOn()){
693  traceUserEvent(eventEndOfTimeStep);
694  sprintf(traceNote, "s:%d", step);
695  traceUserSuppliedNote(traceNote);
696  }
697  outputExtendedSystem(step);
698  }else{
699  adaptTempUpdate(step);
700  rescaleVelocities(step);
701  tcoupleVelocities(step);
702  // XXX for single GPU version, call directly from Sequencer
703  // stochRescaleVelocities(step);
704  // XXX for single GPU version, call directly from Sequencer
705  // berendsenPressure(step);
706  // XXX for single GPU version, call directly from Sequencer
707  // langevinPiston1(step);
708  // XXX for single GPU version, call directly from Sequencer
709  // monteCarloPressure_prepare(step);
710  // monteCarloPressure_accept(step);
711  rescaleaccelMD(step);
712  enqueueCollections(step); // after lattice scaling!
713  receivePressure(step);
714  if ( zeroMomentum && dofull && ! (step % slowFreq) )
715  correctMomentum(step);
716  langevinPiston2(step);
717  reassignVelocities(step);
718 
719  multigratorTemperature(step, 1);
720  multigratorPressure(step, 1);
721  multigratorPressure(step, 2);
722  multigratorTemperature(step, 2);
723 
724  printDynamicsEnergies(step);
725  outputFepEnergy(step);
726  outputTiEnergy(step);
727  if(traceIsOn()){
728  traceUserEvent(eventEndOfTimeStep);
729  sprintf(traceNote, "s:%d", step);
730  traceUserSuppliedNote(traceNote);
731  }
732  outputExtendedSystem(step);
733  }
734 }
735 
736 #endif
737 
738 
739 #define CALCULATE \
740  printMinimizeEnergies(step); \
741  outputExtendedSystem(step); \
742  rebalanceLoad(step); \
743  if ( step == numberOfSteps ) return; \
744  else ++step;
745 
746 #define MOVETO(X) \
747  if ( step == numberOfSteps ) { \
748  if ( minVerbose ) { iout << "LINE MINIMIZER: RETURNING TO " << mid.x << " FROM " << last.x << "\n" << endi; } \
749  if ( newDir || (mid.x-last.x) ) { \
750  broadcast->minimizeCoefficient.publish(minSeq++,mid.x-last.x); \
751  } else { \
752  broadcast->minimizeCoefficient.publish(minSeq++,0.); \
753  broadcast->minimizeCoefficient.publish(minSeq++,0.); \
754  min_reduction->require(); \
755  broadcast->minimizeCoefficient.publish(minSeq++,0.); \
756  } \
757  enqueueCollections(step); \
758  CALCULATE \
759  } else if ( (X)-last.x ) { \
760  broadcast->minimizeCoefficient.publish(minSeq++,(X)-last.x); \
761  newDir = 0; \
762  last.x = (X); \
763  enqueueCollections(step); \
764  CALCULATE \
765  last.u = min_energy; \
766  last.dudx = -1. * min_f_dot_v; \
767  last.noGradient = min_huge_count; \
768  if ( minVerbose ) { \
769  iout << "LINE MINIMIZER: POSITION " << last.x << " ENERGY " << last.u << " GRADIENT " << last.dudx; \
770  if ( last.noGradient ) iout << " HUGECOUNT " << last.noGradient; \
771  iout << "\n" << endi; \
772  } \
773  }
774 
775 struct minpoint {
777  minpoint() : x(0), u(0), dudx(0), noGradient(1) { ; }
778 };
779 
781  // iout << "Controller::minimize() called.\n" << endi;
782 
783  const int minVerbose = simParams->minVerbose;
784  const int numberOfSteps = simParams->N;
785  int step = simParams->firstTimestep;
786  slowFreq = nbondFreq = 1;
787  BigReal linegoal = simParams->minLineGoal; // 1.0e-3
788  const BigReal goldenRatio = 0.5 * ( sqrt(5.0) - 1.0 );
789 
790  CALCULATE
791 
792  int minSeq = 0;
793 
794  // just move downhill until initial bad contacts go away or 100 steps
795  int old_min_huge_count = 2000000000;
796  int steps_at_same_min_huge_count = 0;
797  for ( int i_slow = 0; min_huge_count && i_slow < 100; ++i_slow ) {
798  if ( min_huge_count >= old_min_huge_count ) {
799  if ( ++steps_at_same_min_huge_count > 10 ) break;
800  } else {
801  old_min_huge_count = min_huge_count;
802  steps_at_same_min_huge_count = 0;
803  }
804  iout << "MINIMIZER SLOWLY MOVING " << min_huge_count << " ATOMS WITH BAD CONTACTS DOWNHILL\n" << endi;
805  broadcast->minimizeCoefficient.publish(minSeq++,1.);
806  enqueueCollections(step);
807  CALCULATE
808  }
809  if ( min_huge_count ) {
810  iout << "MINIMIZER GIVING UP ON " << min_huge_count << " ATOMS WITH BAD CONTACTS\n" << endi;
811  }
812  iout << "MINIMIZER STARTING CONJUGATE GRADIENT ALGORITHM\n" << endi;
813 
814  int atStart = 2;
815  int errorFactor = 10;
816  BigReal old_f_dot_f = min_f_dot_f;
817  broadcast->minimizeCoefficient.publish(minSeq++,0.);
818  broadcast->minimizeCoefficient.publish(minSeq++,0.); // v = f
819  int newDir = 1;
822  while ( 1 ) {
823  // line minimization
824  // bracket minimum on line
825  minpoint lo,hi,mid,last;
826  BigReal x = 0;
827  lo.x = x;
828  lo.u = min_energy;
829  lo.dudx = -1. * min_f_dot_v;
831  mid = lo;
832  last = mid;
833  if ( minVerbose ) {
834  iout << "LINE MINIMIZER: POSITION " << last.x << " ENERGY " << last.u << " GRADIENT " << last.dudx;
835  if ( last.noGradient ) iout << " HUGECOUNT " << last.noGradient;
836  iout << "\n" << endi;
837  }
838  BigReal tol = fabs( linegoal * min_f_dot_v );
839  iout << "LINE MINIMIZER REDUCING GRADIENT FROM " <<
840  fabs(min_f_dot_v) << " TO " << tol << "\n" << endi;
841  int start_with_huge = last.noGradient;
843  BigReal maxstep = 0.1 / sqrt(min_reduction->item(0));
844  x = maxstep; MOVETO(x);
845  // bracket minimum on line
846  while ( last.u < mid.u ) {
847  if ( last.dudx < mid.dudx * (5.5 - x/maxstep)/5. ) {
848  x = 6 * maxstep; break;
849  }
850  lo = mid; mid = last;
851  x += maxstep;
852  if ( x > 5.5 * maxstep ) break;
853  MOVETO(x)
854  }
855  if ( x > 5.5 * maxstep ) {
856  iout << "MINIMIZER RESTARTING CONJUGATE GRADIENT ALGORITHM DUE TO POOR PROGRESS\n" << endi;
857  broadcast->minimizeCoefficient.publish(minSeq++,0.);
858  broadcast->minimizeCoefficient.publish(minSeq++,0.); // v = f
859  newDir = 1;
860  old_f_dot_f = min_f_dot_f;
863  continue;
864  }
865  hi = last;
866 #define PRINT_BRACKET \
867  iout << "LINE MINIMIZER BRACKET: DX " \
868  << (mid.x-lo.x) << " " << (hi.x-mid.x) << \
869  " DU " << (mid.u-lo.u) << " " << (hi.u-mid.u) << " DUDX " << \
870  lo.dudx << " " << mid.dudx << " " << hi.dudx << " \n" << endi;
872  // converge on minimum on line
873  int itcnt;
874  for ( itcnt = 10; itcnt > 0; --itcnt ) {
875  int progress = 1;
876  // select new position
877  if ( mid.noGradient ) {
878  if ( ( mid.x - lo.x ) > ( hi.x - mid.x ) ) { // subdivide left side
879  x = (1.0 - goldenRatio) * lo.x + goldenRatio * mid.x;
880  MOVETO(x)
881  if ( last.u <= mid.u ) {
882  hi = mid; mid = last;
883  } else {
884  lo = last;
885  }
886  } else { // subdivide right side
887  x = (1.0 - goldenRatio) * hi.x + goldenRatio * mid.x;
888  MOVETO(x)
889  if ( last.u <= mid.u ) {
890  lo = mid; mid = last;
891  } else {
892  hi = last;
893  }
894  }
895  } else {
896  if ( mid.dudx > 0. ) { // subdivide left side
897  BigReal altxhi = 0.1 * lo.x + 0.9 * mid.x;
898  BigReal altxlo = 0.9 * lo.x + 0.1 * mid.x;
899  x = mid.dudx*(mid.x*mid.x-lo.x*lo.x) + 2*mid.x*(lo.u-mid.u);
900  BigReal xdiv = 2*(mid.dudx*(mid.x-lo.x)+(lo.u-mid.u));
901  if ( xdiv ) x /= xdiv; else x = last.x;
902  if ( x > altxhi ) x = altxhi;
903  if ( x < altxlo ) x = altxlo;
904  if ( x-last.x == 0 ) break;
905  MOVETO(x)
906  if ( last.u <= mid.u ) {
907  hi = mid; mid = last;
908  } else {
909  if ( lo.dudx < 0. && last.dudx > 0. ) progress = 0;
910  lo = last;
911  }
912  } else { // subdivide right side
913  BigReal altxlo = 0.1 * hi.x + 0.9 * mid.x;
914  BigReal altxhi = 0.9 * hi.x + 0.1 * mid.x;
915  x = mid.dudx*(mid.x*mid.x-hi.x*hi.x) + 2*mid.x*(hi.u-mid.u);
916  BigReal xdiv = 2*(mid.dudx*(mid.x-hi.x)+(hi.u-mid.u));
917  if ( xdiv ) x /= xdiv; else x = last.x;
918  if ( x < altxlo ) x = altxlo;
919  if ( x > altxhi ) x = altxhi;
920  if ( x-last.x == 0 ) break;
921  MOVETO(x)
922  if ( last.u <= mid.u ) {
923  lo = mid; mid = last;
924  } else {
925  if ( hi.dudx > 0. && last.dudx < 0. ) progress = 0;
926  hi = last;
927  }
928  }
929  }
931  if ( ! progress ) {
932  MOVETO(mid.x);
933  break;
934  }
935  if ( fabs(last.dudx) < tol ) break;
936  if ( lo.x != mid.x && (lo.u-mid.u) < tol * (mid.x-lo.x) ) break;
937  if ( mid.x != hi.x && (hi.u-mid.u) < tol * (hi.x-mid.x) ) break;
938  }
939  // new direction
940  broadcast->minimizeCoefficient.publish(minSeq++,0.);
941  BigReal c = min_f_dot_f / old_f_dot_f;
942  c = ( c > 1.5 ? 1.5 : c );
943  if ( atStart ) { c = 0; --atStart; }
944  if ( c*c*min_v_dot_v > errorFactor*min_f_dot_f ) {
945  c = 0;
946  if ( errorFactor < 100 ) errorFactor += 10;
947  }
948  if ( c == 0 ) {
949  iout << "MINIMIZER RESTARTING CONJUGATE GRADIENT ALGORITHM\n" << endi;
950  }
951  broadcast->minimizeCoefficient.publish(minSeq++,c); // v = c*v+f
952  newDir = 1;
953  old_f_dot_f = min_f_dot_f;
956  }
957 
958 }
959 
960 #undef MOVETO
961 #undef CALCULATE
962 
963 // NOTE: Only isotropic case implemented here!
964 void Controller::multigratorPressure(int step, int callNumber) {
969  BigReal NGfac = 1.0/sqrt(3.0*NG + 1.0);
972  {
973  // Compute new scaling factors and send them to Sequencer
974  BigReal V = state->lattice.volume();
975  BigReal Pinst = trace(controlPressure)/3.0;
976  BigReal PGsum = trace(momentumSqrSum);
977  //
978  multigratorXiT = multigratorXi + 0.5*s*NGfac/kT0*( 3.0*V*(Pinst - P0) + PGsum/NG );
979  BigReal scale = exp(s*NGfac*multigratorXiT);
980  BigReal velScale = exp(-s*NGfac*(1.0 + 1.0/NG)*multigratorXiT);
981  // fprintf(stderr, "%d | T %lf P %lf V %1.3lf\n", step, temperature, Pinst*PRESSUREFACTOR, V);
982  Tensor scaleTensor = Tensor::identity(scale);
983  Tensor volScaleTensor = Tensor::identity(scale);
984  Tensor velScaleTensor = Tensor::identity(velScale);
985  state->lattice.rescale(volScaleTensor);
986  if (callNumber == 1) {
987  broadcast->positionRescaleFactor.publish(step,scaleTensor);
988  broadcast->velocityRescaleTensor.publish(step,velScaleTensor);
989  } else {
990  broadcast->positionRescaleFactor2.publish(step,scaleTensor);
991  broadcast->velocityRescaleTensor2.publish(step,velScaleTensor);
992  }
993  }
994 
995  {
996  // Wait here for Sequencer to finish scaling and force computation
997  RequireReduction* reduction = getCurrentReduction();
998  reduction->require();
999  Tensor virial_normal;
1000  Tensor virial_nbond;
1001  Tensor virial_slow;
1002  Tensor intVirial_normal;
1003  Tensor intVirial_nbond;
1004  Tensor intVirial_slow;
1005  Vector extForce_normal;
1006  Vector extForce_nbond;
1007  Vector extForce_slow;
1008  GET_TENSOR(momentumSqrSum, reduction, REDUCTION_MOMENTUM_SQUARED);
1009  GET_TENSOR(virial_normal, reduction, REDUCTION_VIRIAL_NORMAL);
1010  GET_TENSOR(virial_nbond, reduction, REDUCTION_VIRIAL_NBOND);
1011  GET_TENSOR(virial_slow, reduction, REDUCTION_VIRIAL_SLOW);
1012  GET_TENSOR(intVirial_normal, reduction, REDUCTION_INT_VIRIAL_NORMAL);
1013  GET_TENSOR(intVirial_nbond, reduction, REDUCTION_INT_VIRIAL_NBOND);
1014  GET_TENSOR(intVirial_slow, reduction, REDUCTION_INT_VIRIAL_SLOW);
1015  GET_VECTOR(extForce_normal, reduction, REDUCTION_EXT_FORCE_NORMAL);
1016  GET_VECTOR(extForce_nbond, reduction, REDUCTION_EXT_FORCE_NBOND);
1017  GET_VECTOR(extForce_slow, reduction, REDUCTION_EXT_FORCE_SLOW);
1018  calcPressure(step, 0, virial_normal, virial_nbond, virial_slow,
1019  intVirial_normal, intVirial_nbond, intVirial_slow,
1020  extForce_normal, extForce_nbond, extForce_slow);
1021  if (callNumber == 2) {
1022  // Update temperature for the Temperature Cycle that is coming next
1025  }
1026  }
1027 
1028  {
1029  // Update pressure integrator
1030  BigReal V = state->lattice.volume();
1031  BigReal Pinst = trace(controlPressure)/3.0;
1032  BigReal PGsum = trace(momentumSqrSum);
1033  //
1034  multigratorXi = multigratorXiT + 0.5*s*NGfac/kT0*( 3.0*V*(Pinst - P0) + PGsum/NG );
1035  }
1036 
1037  }
1038 }
1039 
1040 void Controller::multigratorTemperature(int step, int callNumber) {
1045  BigReal Nf = numDegFreedom;
1047  BigReal T1, T2, v;
1048  {
1049  T1 = temperature;
1050  BigReal kTinst = BOLTZMANN * temperature;
1051  for (int i=n-1;i >= 0;i--) {
1052  if (i == 0) {
1053  BigReal NuOmega = (n > 1) ? multigratorNuT[1]/multigratorOmega[1] : 0.0;
1054  multigratorNuT[0] = exp(-0.5*t*NuOmega)*multigratorNu[0] + 0.5*Nf*t*exp(-0.25*t*NuOmega)*(kTinst - kT0);
1055  } else if (i == n-1) {
1056  multigratorNuT[n-1] = multigratorNu[n-1] + 0.5*t*(pow(multigratorNu[n-2],2.0)/multigratorOmega[n-2] - kT0);
1057  } else {
1058  BigReal NuOmega = multigratorNuT[i+1]/multigratorOmega[i+1];
1059  multigratorNuT[i] = exp(-0.5*t*NuOmega)*multigratorNu[i] +
1060  0.5*t*exp(-0.25*t*NuOmega)*(pow(multigratorNu[i-1],2.0)/multigratorOmega[i-1] - kT0);
1061  }
1062  }
1063  BigReal velScale = exp(-t*multigratorNuT[0]/multigratorOmega[0]);
1064  v = velScale;
1065  if (callNumber == 1)
1066  broadcast->velocityRescaleFactor.publish(step,velScale);
1067  else
1068  broadcast->velocityRescaleFactor2.publish(step,velScale);
1069  }
1070 
1071  {
1072  // Wait here for Sequencer to finish scaling and re-calculating kinetic energy
1076  T2 = temperature;
1077  if (callNumber == 1 && !(step % simParams->multigratorPressureFreq)) {
1078  // If this is pressure cycle, receive new momentum product
1079  GET_TENSOR(momentumSqrSum, multigratorReduction, MULTIGRATOR_REDUCTION_MOMENTUM_SQUARED);
1080  }
1081  }
1082 
1083  // fprintf(stderr, "%d | T %lf scale %lf T' %lf\n", step, T1, v, T2);
1084 
1085  {
1086  BigReal kTinst = BOLTZMANN * temperature;
1087  for (int i=0;i < n;i++) {
1088  if (i == 0) {
1089  BigReal NuOmega = (n > 1) ? multigratorNuT[1]/multigratorOmega[1] : 0.0;
1090  multigratorNu[0] = exp(-0.5*t*NuOmega)*multigratorNuT[0] + 0.5*Nf*t*exp(-0.25*t*NuOmega)*(kTinst - kT0);
1091  } else if (i == n-1) {
1092  multigratorNu[n-1] = multigratorNuT[n-1] + 0.5*t*(pow(multigratorNu[n-2],2.0)/multigratorOmega[n-2] - kT0);
1093  } else {
1094  BigReal NuOmega = multigratorNuT[i+1]/multigratorOmega[i+1];
1095  multigratorNu[i] = exp(-0.5*t*NuOmega)*multigratorNuT[i] +
1096  0.5*t*exp(-0.25*t*NuOmega)*(pow(multigratorNu[i-1],2.0)/multigratorOmega[i-1] - kT0);
1097  }
1099  }
1100  }
1101 
1102  }
1103 }
1104 
1105 // Calculates Enthalpy for multigrator
1106 BigReal Controller::multigatorCalcEnthalpy(BigReal potentialEnergy, int step, int minimize) {
1107  Node *node = Node::Object();
1108  Molecule *molecule = node->molecule;
1109  SimParameters *simParameters = node->simParameters;
1110 
1111  BigReal V = state->lattice.volume();
1115  BigReal Nf = numDegFreedom;
1117  BigReal sumZeta = 0.0;
1118  for (int i=1;i < simParams->multigratorNoseHooverChainLength;i++) {
1119  sumZeta += multigratorZeta[i];
1120  }
1121  BigReal nuOmegaSum = 0.0;
1122  for (int i=0;i < simParams->multigratorNoseHooverChainLength;i++) {
1123  nuOmegaSum += multigratorNu[i]*multigratorNu[i]/(2.0*multigratorOmega[i]);
1124  }
1125  BigReal W = (3.0*NG + 1.0)*kT0*tauV*tauV;
1126  BigReal eta = sqrt(kT0*W)*multigratorXi;
1127 
1128  BigReal enthalpy = kineticEnergy + potentialEnergy + eta*eta/(2.0*W) + P0*V + nuOmegaSum + kT0*(Nf*multigratorZeta[0] + sumZeta);
1129 
1130 // if (!(step % 100))
1131  // fprintf(stderr, "enthalpy %lf %lf %lf %lf %lf %lf %lf\n", enthalpy,
1132  // kineticEnergy, potentialEnergy, eta*eta/(2.0*W), P0*V, nuOmegaSum, kT0*(Nf*multigratorZeta[0] + sumZeta));
1133 
1134  return enthalpy;
1135 }
1136 
1138 {
1140  if ( !(step % simParams->monteCarloPressureFreq) ) {
1141  Node *node = Node::Object();
1142  Molecule *molecule = node->molecule;
1143  // need to consider the fix atom case!
1144  int numAtom = molecule->numMolecules;
1145  BigReal volumeOld = mc_oldLattice.volume();
1146  BigReal volumeNew = state->lattice.volume();
1147  BigReal areaNew = (volumeNew / state->lattice.c().z);
1148  BigReal areaOld = (volumeOld / mc_oldLattice.c().z);
1150  BigReal pressureTarget = simParams->monteCarloPressureTarget;
1151  BigReal surfTensionTarget = simParams->surfaceTensionTarget;
1152 
1153  // When using the GPU resident code path in single process mode, the reduction
1154  // data needs to persist so it can be consumed by the printStep function
1155  const bool clear_reduction_data = !simParams->GPUresidentSingleProcessMode;
1156  RequireReduction* reduction = getCurrentReduction();
1157  reduction->require(clear_reduction_data);
1158 
1159  BigReal totalEnergyOld = mc_totalEnergyOld;
1160  BigReal totalEnergyNew = getTotalPotentialEnergy(step);
1161  BigReal weight = (totalEnergyNew - totalEnergyOld);
1162  weight += (pressureTarget * (volumeNew - volumeOld));
1163  weight -= (numAtom * kbT * log(volumeNew / volumeOld));
1164  weight -= (surfTensionTarget * (areaNew - areaOld));
1165  BigReal totalWeight = exp(-weight / kbT);
1166  int accepted = (random->uniform() < totalWeight);
1167  //accepted = 0;
1168  #if 0
1169  printf("MC-data (accept): step: %d, Pe: %d, numAtom: %d\n", step, CkMyPe(), numAtom);
1170  printf(" oldE: %f, newE: %f, deltaE: %f\n", totalEnergyOld, totalEnergyNew, totalEnergyNew - totalEnergyOld);
1171  printf(" oldV: %f, newV: %f, deltaV: %f\n", volumeOld, volumeNew, volumeNew - volumeOld);
1172  printf(" surfTen: %f, deltaA: %f \n", surfTensionTarget, areaNew - areaOld);
1173  printf(" weight: %f, accepted: %d\n\n", totalWeight, accepted);
1174  #endif
1175  if(accepted) {
1176  // what should I do if its accepted?
1177  ++mc_totalAccept;
1179  } else {
1180  // what should I do if its rejected?
1181  state->lattice = mc_oldLattice;
1182  }
1183  // update the maximum scale no matter if it's accepted or not
1184  {
1186  BigReal factor = 1.0;
1188  // safe check to make sure there is any accepted move
1189  if (accRate > 0.0) {
1190  factor = accRate / simParams->monteCarloAcceptanceRate;
1191  } else {
1192  factor = 0.5; // if no move was accepted, we scale by half
1193  }
1194  // reset the trial for picked axis
1196  BigReal maxVolume = state->lattice.volume() * 0.3;
1197  switch (mc_picked_axis) {
1198  case MC_X:
1199  monteCarloMaxVolume.x *= factor;
1200  if (monteCarloMaxVolume.x < 0.001) {
1201  iout << iWARN << "Small volume change in MC barostat!\n" << endi;
1202  iout << iWARN << "Maximum volume change is set to 0.001 A^3.\n" << endi;
1203  monteCarloMaxVolume.x = 0.001;
1204  } else if (monteCarloMaxVolume.x > maxVolume ) {
1205  iout << iWARN << "Large volume change in MC barostat!\n" << endi;
1206  iout << iWARN << "Maximum volume change is set to " << maxVolume << " A^3.\n" << endi;
1207  monteCarloMaxVolume.x = maxVolume;
1208  }
1209  break;
1210 
1211  case MC_Y:
1212  monteCarloMaxVolume.y *= factor;
1213  if (monteCarloMaxVolume.y < 0.001) {
1214  iout << iWARN << "Small volume change in MC barostat!\n" << endi;
1215  iout << iWARN << "Maximum volume change is set to 0.001 A^3.\n" << endi;
1216  monteCarloMaxVolume.y = 0.001;
1217  } else if (monteCarloMaxVolume.y > maxVolume ) {
1218  iout << iWARN << "Large volume change in MC barostat!\n" << endi;
1219  iout << iWARN << "Maximum volume change is set to " << maxVolume << " A^3.\n" << endi;
1220  monteCarloMaxVolume.y = maxVolume;
1221  }
1222  break;
1223 
1224  case MC_Z:
1225  monteCarloMaxVolume.z *= factor;
1226  if (monteCarloMaxVolume.z < 0.001) {
1227  iout << iWARN << "Small volume change in MC barostat!\n" << endi;
1228  iout << iWARN << "Maximum volume change is set to 0.001 A^3.\n" << endi;
1229  monteCarloMaxVolume.z = 0.001;
1230  } else if (monteCarloMaxVolume.z > maxVolume ) {
1231  iout << iWARN << "Large volume change in MC barostat!\n" << endi;
1232  iout << iWARN << "Maximum volume change is set to " << maxVolume << " A^3.\n" << endi;
1233  monteCarloMaxVolume.z = maxVolume;
1234  }
1235  break;
1236  }
1237  }
1238  }
1239 
1240  if ( !(step % simParams->outputEnergies) ) {
1241  BigReal acceptPerc = 100.0 * ((BigReal) mc_totalAccept /
1242  (BigReal) mc_totalTry);
1243  iout << "MC_BAROSTAT STEP: " << step << " TRIALS: " << mc_totalTry <<
1244  " ACCEPTED: " << mc_totalAccept << " %ACCEPTANCE: " << acceptPerc;
1245  if (simParams->useFlexibleCell) {
1246  if (simParams->useConstantArea) {
1247  iout << " MAX_VOLUME_Z: " << monteCarloMaxVolume.z << "\n\n";
1248  } else if (simParams->useConstantRatio) {
1249  iout << " MAX_VOLUME_XY: " << monteCarloMaxVolume.x <<
1250  " MAX_VOLUME_Z: " << monteCarloMaxVolume.z << "\n\n";
1251  } else {
1252  iout << " MAX_VOLUME_X: " << monteCarloMaxVolume.x
1253  << " MAX_VOLUME_Y: " << monteCarloMaxVolume.y
1254  << " MAX_VOLUME_Z: " << monteCarloMaxVolume.z
1255  << "\n\n";
1256  }
1257  } else {
1258  iout << " MAX_VOLUME_XYZ: " << monteCarloMaxVolume.x << "\n\n";
1259  }
1260  }
1261 
1263  }
1264  }
1265 }
1266 
1268 {
1270  if ( !(step % simParams->monteCarloPressureFreq) ) {
1271  // Wait here for Sequencer to finish energy/force computation
1272  // When using the GPU resident code path in single process mode, the reduction
1273  // data needs to persist so it can be consumed by the MCPressure accept function
1274  const bool clear_reduction_data = !simParams->GPUresidentSingleProcessMode;
1275  RequireReduction* reduction = getCurrentReduction();
1276  reduction->require(clear_reduction_data);
1277  mc_oldLattice = state->lattice;
1279  Tensor factor = Tensor::identity(1.0);
1280  // pick a random deltaV and calc scaling factor
1281  {
1282  BigReal oldVolume = mc_oldLattice.volume();
1283  bool flexible = simParams->useFlexibleCell;
1284  bool constArea = simParams->useConstantArea;
1285  bool constRatio = simParams->useConstantRatio;
1286  bool constZ, constY, constX;
1287  if (simParams->fixCellDims) {
1288  constX = simParams->fixCellDimX;
1289  constY = simParams->fixCellDimY;
1290  constZ = simParams->fixCellDimZ;
1291  } else {
1292  constZ = constY = constX = false;
1293  }
1294 
1295  if(flexible) {
1296  //Anisotropic fluctuation
1297  if(constArea) {
1298  // always pick z
1299  mc_picked_axis = MC_Z;
1300  BigReal dV = monteCarloMaxVolume.z * (2.0 * random->uniform() - 1.0);
1301  factor.zz = (oldVolume + dV) / oldVolume;
1302  } else if (constRatio) {
1303  while(true) {
1304  // decide to scale x-y or scale z
1305  BigReal probAxis = 2.0 * random->uniform();
1306  if (probAxis < 1.0) {
1307  //picking x or y. We use MC_X for constant ratio
1308  mc_picked_axis = MC_X;
1309  BigReal dV = monteCarloMaxVolume.x * (2.0 * random->uniform() - 1.0);
1310  BigReal scale = sqrt((oldVolume + dV)/oldVolume);
1311  factor.xx = factor.yy = scale;
1312  break;
1313  } else if (probAxis < 2.0 && !constZ) {
1314  //picking z
1315  mc_picked_axis = MC_Z;
1316  BigReal dV = monteCarloMaxVolume.z * (2.0 * random->uniform() - 1.0);
1317  BigReal scale = (oldVolume + dV)/oldVolume;
1318  factor.zz = scale;
1319  break;
1320  }
1321  }
1322  } else {
1323  while(true) {
1324  // decide to scale x, y or z
1325  BigReal probAxis = 3.0 * random->uniform();
1326  if (probAxis < 1.0 && !constX) {
1327  // picking x
1328  mc_picked_axis = MC_X;
1329  BigReal dV = monteCarloMaxVolume.x * (2.0 * random->uniform() - 1.0);
1330  factor.xx = (oldVolume + dV) / oldVolume;
1331  break;
1332  } else if (probAxis < 2.0 && !constY) {
1333  // picking y
1334  mc_picked_axis = MC_Y;
1335  BigReal dV = monteCarloMaxVolume.y * (2.0 * random->uniform() - 1.0);
1336  factor.yy = (oldVolume + dV) / oldVolume;
1337  break;
1338  } else if (probAxis < 3.0 && !constZ) {
1339  // picking z
1340  mc_picked_axis = MC_Z;
1341  BigReal dV = monteCarloMaxVolume.z * (2.0 * random->uniform() - 1.0);
1342  factor.zz = (oldVolume + dV) / oldVolume;
1343  break;
1344  }
1345  }
1346  }
1347  } else {
1348  //Isotropic fluctuation. We use MC_X for isotropic fluctuation
1349  mc_picked_axis = MC_X;
1350  BigReal dV = monteCarloMaxVolume.x * (2.0 * random->uniform() - 1.0);
1351  BigReal scale = pow((oldVolume + dV)/oldVolume, 1.0/3.0);
1352  factor.xx = factor.yy = factor.zz = scale;
1353  }
1354  // increament the MC trial
1355  ++mc_totalTry;
1357  }
1358 
1359  broadcast->positionRescaleFactor.publish(step,factor);
1360  state->lattice.rescale(factor);
1361  }
1362  }
1363 }
1364 
1365 
1366 #define LIMIT_SCALING(VAR,MIN,MAX,FLAG) {\
1367  if ( VAR < (MIN) ) { VAR = (MIN); FLAG = 1; } \
1368  if ( VAR > (MAX) ) { VAR = (MAX); FLAG = 1; } }
1369 
1371 {
1372  if ( simParams->berendsenPressureOn ) {
1375  const int freq = simParams->berendsenPressureFreq;
1376  if ( ! (berendsenPressure_count % freq) ) {
1380  // We only use on-diagonal terms (for now)
1381  factor = Tensor::diagonal(diagonal(factor));
1383  factor *= ( ( simParams->berendsenPressureCompressibility / 3.0 ) *
1385  factor += Tensor::identity(1.0);
1386  int limited = 0;
1387  LIMIT_SCALING(factor.xx,1./1.03,1.03,limited)
1388  LIMIT_SCALING(factor.yy,1./1.03,1.03,limited)
1389  LIMIT_SCALING(factor.zz,1./1.03,1.03,limited)
1390  if ( limited ) {
1391  iout << iERROR << "Step " << step <<
1392  " cell rescaling factor limited.\n" << endi;
1393  }
1394  broadcast->positionRescaleFactor.publish(step,factor);
1395  state->lattice.rescale(factor);
1396  }
1397  } else {
1400  }
1401 }
1402 
1403 #undef LIMIT_SCALING
1404 
1406 {
1407  if ( simParams->langevinPistonOn )
1408  {
1409  Tensor &strainRate = langevinPiston_strainRate;
1410  int cellDims = simParams->useFlexibleCell ? 1 : 3;
1411  BigReal dt = simParams->dt;
1412  BigReal dt_long = slowFreq * dt;
1415  BigReal mass = controlNumDegFreedom * kT * tau * tau * cellDims;
1416 
1417 #ifdef DEBUG_PRESSURE
1418  iout << iINFO << "entering langevinPiston1, strain rate: " << strainRate << "\n";
1419 #endif
1420 
1421  if ( ! ( (step-1) % slowFreq ) )
1422  {
1423  BigReal gamma = 1 / simParams->langevinPistonDecay;
1424  BigReal f1 = exp( -0.5 * dt_long * gamma );
1425  BigReal f2 = sqrt( ( 1. - f1*f1 ) * kT / mass );
1426  strainRate *= f1;
1427  if ( simParams->useFlexibleCell ) {
1428  // We only use on-diagonal terms (for now)
1429  if ( simParams->useConstantRatio ) {
1430  BigReal r = f2 * random->gaussian();
1431  strainRate.xx += r;
1432  strainRate.yy += r;
1433  strainRate.zz += f2 * random->gaussian();
1434  } else {
1435  strainRate += f2 * Tensor::diagonal(random->gaussian_vector());
1436  }
1437  } else {
1438  strainRate += f2 * Tensor::identity(random->gaussian());
1439  }
1440 
1441 #ifdef DEBUG_PRESSURE
1442  iout << iINFO << "applying langevin, strain rate: " << strainRate << "\n";
1443 #endif
1444  }
1445 
1446  // Apply surface tension. If surfaceTensionTarget is zero, we get
1447  // the default (isotropic pressure) case.
1448 
1449  Tensor ptarget;
1450  ptarget.xx = ptarget.yy = ptarget.zz = simParams->langevinPistonTarget;
1451  if ( simParams->surfaceTensionTarget != 0. ) {
1452  ptarget.xx = ptarget.yy = simParams->langevinPistonTarget -
1453  simParams->surfaceTensionTarget / state->lattice.c().z;
1454  }
1455 
1456  strainRate += ( 0.5 * dt * cellDims * state->lattice.volume() / mass ) *
1457  ( controlPressure - ptarget );
1458 
1459  if (simParams->fixCellDims) {
1460  if (simParams->fixCellDimX) strainRate.xx = 0;
1461  if (simParams->fixCellDimY) strainRate.yy = 0;
1462  if (simParams->fixCellDimZ) strainRate.zz = 0;
1463  }
1464 
1465 
1466 #ifdef DEBUG_PRESSURE
1467  iout << iINFO << "integrating half step, strain rate: " << strainRate << "\n";
1468 #endif
1469 
1471  if ( ! ( (step-1-slowFreq/2) % slowFreq ) )
1472  {
1473  // We only use on-diagonal terms (for now)
1474  Tensor factor;
1475  if ( !simParams->useConstantArea ) {
1476  factor.xx = exp( dt_long * strainRate.xx );
1477  factor.yy = exp( dt_long * strainRate.yy );
1478  } else {
1479  factor.xx = factor.yy = 1;
1480  }
1481  factor.zz = exp( dt_long * strainRate.zz );
1482  broadcast->positionRescaleFactor.publish(step,factor);
1483  state->lattice.rescale(factor);
1484 #ifdef DEBUG_PRESSURE
1485  iout << iINFO << "rescaling by: " << factor << "\n";
1486 #endif
1487  }
1488  } else { // langevinPistonBarrier
1489  if ( ! ( (step-1-slowFreq/2) % slowFreq ) )
1490  {
1491  if ( ! positionRescaleFactor.xx ) { // first pass without MTS
1492  // We only use on-diagonal terms (for now)
1493  Tensor factor;
1494  if ( !simParams->useConstantArea ) {
1495  factor.xx = exp( dt_long * strainRate.xx );
1496  factor.yy = exp( dt_long * strainRate.yy );
1497  } else {
1498  factor.xx = factor.yy = 1;
1499  }
1500  factor.zz = exp( dt_long * strainRate.zz );
1501  broadcast->positionRescaleFactor.publish(step,factor);
1502  positionRescaleFactor = factor;
1503  strainRate_old = strainRate;
1504  }
1506 #ifdef DEBUG_PRESSURE
1507  iout << iINFO << "rescaling by: " << positionRescaleFactor << "\n";
1508 #endif
1509  }
1510  if ( ! ( (step-slowFreq/2) % slowFreq ) )
1511  {
1512  // We only use on-diagonal terms (for now)
1513  Tensor factor;
1514  if ( !simParams->useConstantArea ) {
1515  factor.xx = exp( (dt+dt_long) * strainRate.xx - dt * strainRate_old.xx );
1516  factor.yy = exp( (dt+dt_long) * strainRate.yy - dt * strainRate_old.yy );
1517  } else {
1518  factor.xx = factor.yy = 1;
1519  }
1520  factor.zz = exp( (dt+dt_long) * strainRate.zz - dt * strainRate_old.zz );
1521  broadcast->positionRescaleFactor.publish(step+1,factor);
1522  positionRescaleFactor = factor;
1523  strainRate_old = strainRate;
1524  }
1525  }
1526 
1527  // corrections to integrator
1528  if ( ! ( step % nbondFreq ) )
1529  {
1530 #ifdef DEBUG_PRESSURE
1531  iout << iINFO << "correcting strain rate for nbond, ";
1532 #endif
1533  strainRate -= ( 0.5 * dt * cellDims * state->lattice.volume() / mass ) *
1534  ( (nbondFreq - 1) * controlPressure_nbond );
1535 #ifdef DEBUG_PRESSURE
1536  iout << "strain rate: " << strainRate << "\n";
1537 #endif
1538  }
1539  if ( ! ( step % slowFreq ) )
1540  {
1541 #ifdef DEBUG_PRESSURE
1542  iout << iINFO << "correcting strain rate for slow, ";
1543 #endif
1544  strainRate -= ( 0.5 * dt * cellDims * state->lattice.volume() / mass ) *
1545  ( (slowFreq - 1) * controlPressure_slow );
1546 #ifdef DEBUG_PRESSURE
1547  iout << "strain rate: " << strainRate << "\n";
1548 #endif
1549  }
1550  if (simParams->fixCellDims) {
1551  if (simParams->fixCellDimX) strainRate.xx = 0;
1552  if (simParams->fixCellDimY) strainRate.yy = 0;
1553  if (simParams->fixCellDimZ) strainRate.zz = 0;
1554  }
1555 
1556  }
1557 
1558 }
1559 
1561 {
1562  if ( simParams->langevinPistonOn )
1563  {
1564  Tensor &strainRate = langevinPiston_strainRate;
1565  int cellDims = simParams->useFlexibleCell ? 1 : 3;
1566  BigReal dt = simParams->dt;
1567  BigReal dt_long = slowFreq * dt;
1570  BigReal mass = controlNumDegFreedom * kT * tau * tau * cellDims;
1571 
1572  // corrections to integrator
1573  if ( ! ( step % nbondFreq ) )
1574  {
1575 #ifdef DEBUG_PRESSURE
1576  iout << iINFO << "correcting strain rate for nbond, ";
1577 #endif
1578  strainRate += ( 0.5 * dt * cellDims * state->lattice.volume() / mass ) *
1579  ( (nbondFreq - 1) * controlPressure_nbond );
1580 #ifdef DEBUG_PRESSURE
1581  iout << "strain rate: " << strainRate << "\n";
1582 #endif
1583  }
1584  if ( ! ( step % slowFreq ) )
1585  {
1586 #ifdef DEBUG_PRESSURE
1587  iout << iINFO << "correcting strain rate for slow, ";
1588 #endif
1589  strainRate += ( 0.5 * dt * cellDims * state->lattice.volume() / mass ) *
1590  ( (slowFreq - 1) * controlPressure_slow );
1591 #ifdef DEBUG_PRESSURE
1592  iout << "strain rate: " << strainRate << "\n";
1593 #endif
1594  }
1595 
1596  // Apply surface tension. If surfaceTensionTarget is zero, we get
1597  // the default (isotropic pressure) case.
1598 
1599  Tensor ptarget;
1600  ptarget.xx = ptarget.yy = ptarget.zz = simParams->langevinPistonTarget;
1601  if ( simParams->surfaceTensionTarget != 0. ) {
1602  ptarget.xx = ptarget.yy = simParams->langevinPistonTarget -
1603  simParams->surfaceTensionTarget / state->lattice.c().z;
1604  }
1605 
1606  strainRate += ( 0.5 * dt * cellDims * state->lattice.volume() / mass ) *
1607  ( controlPressure - ptarget );
1608 
1609 
1610 #ifdef DEBUG_PRESSURE
1611  iout << iINFO << "integrating half step, strain rate: " << strainRate << "\n";
1612 #endif
1613 
1614  if ( ! ( step % slowFreq ) )
1615  {
1616  BigReal gamma = 1 / simParams->langevinPistonDecay;
1617  BigReal f1 = exp( -0.5 * dt_long * gamma );
1618  BigReal f2 = sqrt( ( 1. - f1*f1 ) * kT / mass );
1619  strainRate *= f1;
1620  if ( simParams->useFlexibleCell ) {
1621  // We only use on-diagonal terms (for now)
1622  if ( simParams->useConstantRatio ) {
1623  BigReal r = f2 * random->gaussian();
1624  strainRate.xx += r;
1625  strainRate.yy += r;
1626  strainRate.zz += f2 * random->gaussian();
1627  } else {
1628  strainRate += f2 * Tensor::diagonal(random->gaussian_vector());
1629  }
1630  } else {
1631  strainRate += f2 * Tensor::identity(random->gaussian());
1632  }
1633 #ifdef DEBUG_PRESSURE
1634  iout << iINFO << "applying langevin, strain rate: " << strainRate << "\n";
1635 #endif
1636  }
1637 
1638 #ifdef DEBUG_PRESSURE
1639  iout << iINFO << "exiting langevinPiston2, strain rate: " << strainRate << "\n";
1640 #endif
1641  if (simParams->fixCellDims) {
1642  if (simParams->fixCellDimX) strainRate.xx = 0;
1643  if (simParams->fixCellDimY) strainRate.yy = 0;
1644  if (simParams->fixCellDimZ) strainRate.zz = 0;
1645  }
1646  }
1647 
1648 
1649 }
1650 
1652 {
1653  const int rescaleFreq = simParams->rescaleFreq;
1654  if ( rescaleFreq > 0 ) {
1656  if ( rescaleVelocities_numTemps == rescaleFreq ) {
1658  BigReal rescaleTemp = simParams->rescaleTemp;
1660  (!(simParams->adaptTempLastStep > 0) || step < simParams->adaptTempLastStep )) {
1661  rescaleTemp = adaptTempT;
1662  }
1663  BigReal factor = sqrt(rescaleTemp/avgTemp);
1664  broadcast->velocityRescaleFactor.publish(step,factor);
1665  //iout << "RESCALING VELOCITIES AT STEP " << step
1666  // << " FROM AVERAGE TEMPERATURE OF " << avgTemp
1667  // << " TO " << rescaleTemp << " KELVIN.\n" << endi;
1669  }
1670  }
1671 }
1672 
1674  RequireReduction* reduction = getCurrentReduction();
1675 
1676  Vector momentum;
1677  BigReal mass;
1678  momentum.x = reduction->item(REDUCTION_HALFSTEP_MOMENTUM_X);
1679  momentum.y = reduction->item(REDUCTION_HALFSTEP_MOMENTUM_Y);
1680  momentum.z = reduction->item(REDUCTION_HALFSTEP_MOMENTUM_Z);
1681  mass = reduction->item(REDUCTION_MOMENTUM_MASS);
1682 
1683  if ( momentum.length2() == 0. )
1684  iout << iERROR << "Momentum is exactly zero; probably a bug.\n" << endi;
1685  if ( mass == 0. )
1686  NAMD_die("Total mass is zero in Controller::correctMomentum");
1687 
1688  momentum *= (-1./mass);
1689  // What does this mean???
1690  broadcast->momentumCorrection.publish(step+slowFreq,momentum);
1691 }
1692 
1693 //Modifications for alchemical fep
1695 {
1697  && !simParams->alchLambdaFreq) {
1698  const BigReal alchLambda = simParams->alchLambda;
1699  const BigReal alchLambda2 = simParams->alchLambda2;
1700  const BigReal alchLambdaIDWS = simParams->alchLambdaIDWS;
1701  const BigReal alchTemp = simParams->alchTemp;
1702  const int alchEquilSteps = simParams->alchEquilSteps;
1703  iout << "FEP: RESETTING FOR NEW FEP WINDOW "
1704  << "LAMBDA SET TO " << alchLambda << " LAMBDA2 " << alchLambda2;
1705  if ( alchLambdaIDWS >= 0. ) {
1706  iout << " LAMBDA_IDWS " << alchLambdaIDWS;
1707  }
1708  iout << "\nFEP: WINDOW TO HAVE " << alchEquilSteps
1709  << " STEPS OF EQUILIBRATION PRIOR TO FEP DATA COLLECTION.\n"
1710  << "FEP: USING CONSTANT TEMPERATURE OF " << alchTemp
1711  << " K FOR FEP CALCULATION\n" << endi;
1712  }
1713 }
1715 {
1717  && !simParams->alchLambdaFreq) {
1718  const BigReal alchLambda = simParams->alchLambda;
1719  const int alchEquilSteps = simParams->alchEquilSteps;
1720  iout << "TI: RESETTING FOR NEW WINDOW "
1721  << "LAMBDA SET TO " << alchLambda
1722  << "\nTI: WINDOW TO HAVE " << alchEquilSteps
1723  << " STEPS OF EQUILIBRATION PRIOR TO TI DATA COLLECTION.\n" << endi;
1724  }
1725 }
1726 //fepe
1727 
1729 {
1730  const int reassignFreq = simParams->reassignFreq;
1731  if ( ( reassignFreq > 0 ) && ! ( step % reassignFreq ) ) {
1732  BigReal newTemp = simParams->reassignTemp;
1733  newTemp += ( step / reassignFreq ) * simParams->reassignIncr;
1734  if ( simParams->reassignIncr > 0.0 ) {
1735  if ( newTemp > simParams->reassignHold && simParams->reassignHold > 0.0 )
1736  newTemp = simParams->reassignHold;
1737  } else {
1738  if ( newTemp < simParams->reassignHold )
1739  newTemp = simParams->reassignHold;
1740  }
1741  iout << "REASSIGNING VELOCITIES AT STEP " << step
1742  << " TO " << newTemp << " KELVIN.\n" << endi;
1743  }
1744 }
1745 
1747 {
1748  if ( simParams->tCoupleOn )
1749  {
1750  const BigReal tCoupleTemp = simParams->tCoupleTemp;
1751  BigReal coefficient = 1.;
1752  if ( temperature > 0. ) coefficient = tCoupleTemp/temperature - 1.;
1753  broadcast->tcoupleCoefficient.publish(step,coefficient);
1754  }
1755 }
1756 
1769 {
1770  if ( simParams->stochRescaleOn ) {
1773  double coefficient = stochRescaleCoefficient();
1774  broadcast->stochRescaleCoefficient.publish(step,coefficient);
1775  stochRescale_count = 0;
1776  }
1777  }
1778 }
1779 
1785  const double stochRescaleTemp = simParams->stochRescaleTemp;
1786  double coefficient = 1;
1787  if ( temperature > 0 ) {
1788  double R1 = random->gaussian();
1789  // double gammaShape = 0.5*(numDegFreedom - 1);
1790  // R2sum is the sum of (numDegFreedom - 1) squared normal variables,
1791  // which is chi-squared distributed.
1792  // This is in turn a special case of the Gamma distribution,
1793  // which converges to a normal distribution in the limit of a
1794  // large shape parameter.
1795  // double R2sum = 2*(gammaShape+sqrt(gammaShape)*random->gaussian())+R1*R1;
1796  double R2sum = random->sum_of_squared_gaussians(numDegFreedom-1);
1797  double tempfactor = stochRescaleTemp/(temperature*numDegFreedom);
1798 
1799  coefficient = sqrt(stochRescaleTimefactor +
1800  (1 - stochRescaleTimefactor)*tempfactor*R2sum +
1801  2*R1*sqrt(tempfactor*(1 - stochRescaleTimefactor)*
1803  }
1804  heat += 0.5*numDegFreedom*BOLTZMANN*temperature*(coefficient*coefficient-1);
1805  return coefficient;
1806 }
1807 
1808 static char *FORMAT(BigReal X, int decimal = 4)
1809 {
1810  static char tmp_string[50];
1811  static char format_string[50];
1812  const double maxnum = 99999999999.9999;
1813  if ( X > maxnum ) X = maxnum;
1814  if ( X < -maxnum ) X = -maxnum;
1815 
1816  int whole = (decimal <= 4 ? 14 : 10 + decimal);
1817  sprintf(format_string, " %%%d.%df", whole, decimal);
1818  sprintf(tmp_string, format_string, X);
1819  return tmp_string;
1820 }
1821 
1822 static char *FORMAT(const char *X, int decimal = 4)
1823 {
1824  static char tmp_string[50];
1825  static char format_string[50];
1826 
1827  int width = (decimal <= 4 ? 14 : 10 + decimal);
1828  sprintf(format_string, " %%%ds", width);
1829  sprintf(tmp_string, format_string, X);
1830  return tmp_string;
1831 }
1832 
1833 static char *ETITLE(int X)
1834 {
1835  static char tmp_string[21];
1836  sprintf(tmp_string,"ENERGY: %7d",X);
1837  return tmp_string;
1838 }
1839 
1840 void Controller::receivePressure(int step, int minimize)
1841 {
1842  Node *node = Node::Object();
1843  Molecule *molecule = node->molecule;
1844  Lattice &lattice = state->lattice;
1845  bool cudaIntegrator = simParams->CUDASOAintegrate;
1846 
1847  RequireReduction* reduction = getCurrentReduction();
1848  reduction->require();
1849 
1850  Tensor virial_normal;
1851  Tensor virial_nbond;
1852  Tensor virial_slow;
1853 #ifdef ALTVIRIAL
1854  Tensor altVirial_normal;
1855  Tensor altVirial_nbond;
1856  Tensor altVirial_slow;
1857 #endif
1858  Tensor intVirial_normal;
1859  Tensor intVirial_nbond;
1860  Tensor intVirial_slow;
1861  Vector extForce_normal;
1862  Vector extForce_nbond;
1863  Vector extForce_slow;
1864 
1865 #if 1
1866  numDegFreedom = molecule->num_deg_freedom();
1867  int64_t numGroupDegFreedom = molecule->num_group_deg_freedom();
1868  int numFixedGroups = molecule->num_fixed_groups();
1869  int numFixedAtoms = molecule->num_fixed_atoms();
1870 #endif
1871 #if 0
1872  int numAtoms = molecule->numAtoms;
1873  numDegFreedom = 3 * numAtoms;
1874  int numGroupDegFreedom = 3 * molecule->numHydrogenGroups;
1875  int numFixedAtoms =
1876  ( simParams->fixedAtomsOn ? molecule->numFixedAtoms : 0 );
1877  int numLonepairs = molecule->numLonepairs;
1878  int numFixedGroups = ( numFixedAtoms ? molecule->numFixedGroups : 0 );
1879  if ( numFixedAtoms ) numDegFreedom -= 3 * numFixedAtoms;
1880  if (numLonepairs) numDegFreedom -= 3 * numLonepairs;
1881  if ( numFixedGroups ) numGroupDegFreedom -= 3 * numFixedGroups;
1882  if ( ! ( numFixedAtoms || molecule->numConstraints
1883  || simParams->comMove || simParams->langevinOn ) ) {
1884  numDegFreedom -= 3;
1885  numGroupDegFreedom -= 3;
1886  }
1888  // this doesn't attempt to deal with fixed atoms or constraints
1889  numDegFreedom = 3 * molecule->numFepInitial;
1890  }
1891  int numRigidBonds = molecule->numRigidBonds;
1892  int numFixedRigidBonds =
1893  ( simParams->fixedAtomsOn ? molecule->numFixedRigidBonds : 0 );
1894 
1895  // numLonepairs is subtracted here because all lonepairs have a rigid bond
1896  // to oxygen, but all of the LP degrees of freedom are dealt with above
1897  numDegFreedom -= ( numRigidBonds - numFixedRigidBonds - numLonepairs);
1898 #endif
1899  BigReal groupKineticEnergyHalfstep, groupKineticEnergyCentered;
1902  groupKineticEnergyHalfstep = kineticEnergyHalfstep -
1904  groupKineticEnergyCentered = kineticEnergyCentered -
1906 
1907  BigReal atomTempHalfstep = 2.0 * kineticEnergyHalfstep
1908  / ( numDegFreedom * BOLTZMANN );
1909  BigReal atomTempCentered = 2.0 * kineticEnergyCentered
1910  / ( numDegFreedom * BOLTZMANN );
1911  BigReal groupTempHalfstep = 2.0 * groupKineticEnergyHalfstep
1912  / ( numGroupDegFreedom * BOLTZMANN );
1913  BigReal groupTempCentered = 2.0 * groupKineticEnergyCentered
1914  / ( numGroupDegFreedom * BOLTZMANN );
1915 
1916  /* test code for comparing different temperatures
1917  iout << "TEMPTEST: " << step << " " <<
1918  atomTempHalfstep << " " <<
1919  atomTempCentered << " " <<
1920  groupTempHalfstep << " " <<
1921  groupTempCentered << "\n" << endi;
1922  iout << "Number of degrees of freedom: " << numDegFreedom << " " <<
1923  numGroupDegFreedom << "\n" << endi;
1924  */
1925  GET_TENSOR(momentumSqrSum, reduction,REDUCTION_MOMENTUM_SQUARED);
1926 
1927  GET_TENSOR(virial_normal, reduction,REDUCTION_VIRIAL_NORMAL);
1928  GET_TENSOR(virial_nbond, reduction,REDUCTION_VIRIAL_NBOND);
1929  GET_TENSOR(virial_slow, reduction,REDUCTION_VIRIAL_SLOW);
1930 
1931 #ifdef ALTVIRIAL
1932  GET_TENSOR(altVirial_normal, reduction,REDUCTION_ALT_VIRIAL_NORMAL);
1933  GET_TENSOR(altVirial_nbond, reduction,REDUCTION_ALT_VIRIAL_NBOND);
1934  GET_TENSOR(altVirial_slow, reduction,REDUCTION_ALT_VIRIAL_SLOW);
1935 #endif
1936 
1937  GET_TENSOR(intVirial_normal, reduction,REDUCTION_INT_VIRIAL_NORMAL);
1938  GET_TENSOR(intVirial_nbond, reduction,REDUCTION_INT_VIRIAL_NBOND);
1939  GET_TENSOR(intVirial_slow, reduction,REDUCTION_INT_VIRIAL_SLOW);
1940 
1941  GET_VECTOR(extForce_normal, reduction,REDUCTION_EXT_FORCE_NORMAL);
1942  GET_VECTOR(extForce_nbond, reduction,REDUCTION_EXT_FORCE_NBOND);
1943  GET_VECTOR(extForce_slow, reduction,REDUCTION_EXT_FORCE_SLOW);
1944 
1945  // APH NOTE: These four lines are now done in calcPressure()
1946  // Vector extPosition = lattice.origin();
1947  // virial_normal -= outer(extForce_normal,extPosition);
1948  // virial_nbond -= outer(extForce_nbond,extPosition);
1949  // virial_slow -= outer(extForce_slow,extPosition);
1950 
1953 
1954  if (simParams->drudeOn) {
1955  BigReal drudeComKE, drudeBondKE;
1956  drudeComKE = reduction->item(REDUCTION_DRUDECOM_CENTERED_KINETIC_ENERGY);
1957  drudeBondKE = reduction->item(REDUCTION_DRUDEBOND_CENTERED_KINETIC_ENERGY);
1958  int g_bond = 3 * molecule->numDrudeAtoms;
1959  int g_com = numDegFreedom - g_bond;
1960  temperature = 2.0 * drudeComKE / (g_com * BOLTZMANN);
1961  drudeBondTemp = (g_bond!=0 ? (2.*drudeBondKE/(g_bond*BOLTZMANN)) : 0.);
1962  }
1963 
1964  // Calculate number of degrees of freedom (controlNumDegFreedom)
1965  if ( simParams->useGroupPressure )
1966  {
1967  controlNumDegFreedom = molecule->numHydrogenGroups - numFixedGroups;
1968  if ( ! ( numFixedAtoms || molecule->numConstraints
1969  || simParams->comMove || simParams->langevinOn ) ) {
1970  controlNumDegFreedom -= 1;
1971  }
1972  }
1973  else
1974  {
1976  }
1977  if (simParams->fixCellDims) {
1981  }
1982 
1983  // Calculate pressure tensors using virials
1984  calcPressure(step, minimize,
1985  virial_normal, virial_nbond, virial_slow,
1986  intVirial_normal, intVirial_nbond, intVirial_slow,
1987  extForce_normal, extForce_nbond, extForce_slow);
1988 
1989 #ifdef DEBUG_PRESSURE
1990  iout << iINFO << "Control pressure = " << controlPressure <<
1991  " = " << controlPressure_normal << " + " <<
1992  controlPressure_nbond << " + " << controlPressure_slow << "\n" << endi;
1993 #endif
1995  iout << " PRESS " << trace(pressure)*PRESSUREFACTOR/3. << "\n"
1996  << " PNORMAL " << trace(pressure_normal)*PRESSUREFACTOR/3. << "\n"
1997  << " PNBOND " << trace(pressure_nbond)*PRESSUREFACTOR/3. << "\n"
1998  << " PSLOW " << trace(pressure_slow)*PRESSUREFACTOR/3. << "\n"
1999  << " PAMD " << trace(pressure_amd)*PRESSUREFACTOR/3. << "\n"
2000  << " GPRESS " << trace(groupPressure)*PRESSUREFACTOR/3. << "\n"
2001  << " GPNORMAL " << trace(groupPressure_normal)*PRESSUREFACTOR/3. << "\n"
2002  << " GPNBOND " << trace(groupPressure_nbond)*PRESSUREFACTOR/3. << "\n"
2003  << " GPSLOW " << trace(groupPressure_slow)*PRESSUREFACTOR/3. << "\n"
2004  << endi;
2005  }
2006 }
2007 
2008 //
2009 // Calculates all pressure tensors using virials
2010 //
2011 // Sets variables:
2012 // pressure, pressure_normal, pressure_nbond, pressure_slow
2013 // groupPressure, groupPressure_normal, groupPressure_nbond, groupPressure_slow
2014 // controlPressure, controlPressure_normal, controlPressure_nbond, controlPressure_slow
2015 // pressure_amd
2016 //
2017 void Controller::calcPressure(int step, int minimize,
2018  const Tensor& virial_normal_in, const Tensor& virial_nbond_in, const Tensor& virial_slow_in,
2019  const Tensor& intVirial_normal, const Tensor& intVirial_nbond, const Tensor& intVirial_slow,
2020  const Vector& extForce_normal, const Vector& extForce_nbond, const Vector& extForce_slow) {
2021 
2022  Tensor virial_normal = virial_normal_in;
2023  Tensor virial_nbond = virial_nbond_in;
2024  Tensor virial_slow = virial_slow_in;
2025 
2026 #if 0
2027  Tensor tmp = virial_normal;
2028  fprintf(stderr, "VIRIAL_NORMAL %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf\n",
2029  tmp.xx, tmp.xy, tmp.xz, tmp.yx, tmp.yy, tmp.yz, tmp.zx, tmp.zy, tmp.zz);
2030 
2031  tmp = virial_nbond;
2032  fprintf(stderr, "VIRIAL_NBOND %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf\n",
2033  tmp.xx, tmp.xy, tmp.xz, tmp.yx, tmp.yy, tmp.yz, tmp.zx, tmp.zy, tmp.zz);
2034 
2035  tmp = virial_slow;
2036  fprintf(stderr, "VIRIAL_SLOW %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf\n",
2037  tmp.xx, tmp.xy, tmp.xz, tmp.yx, tmp.yy, tmp.yz, tmp.zx, tmp.zy, tmp.zz);
2038 
2039  tmp = intVirial_normal;
2040  fprintf(stderr, "INT_VIRIAL_NORMAL %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf\n",
2041  tmp.xx, tmp.xy, tmp.xz, tmp.yx, tmp.yy, tmp.yz, tmp.zx, tmp.zy, tmp.zz);
2042 
2043  tmp = intVirial_nbond;
2044  fprintf(stderr, "INT_VIRIAL_NBOND %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf\n",
2045  tmp.xx, tmp.xy, tmp.xz, tmp.yx, tmp.yy, tmp.yz, tmp.zx, tmp.zy, tmp.zz);
2046 
2047  tmp = intVirial_slow;
2048  fprintf(stderr, "INT_VIRIAL_SLOW %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf %1.2lf\n",
2049  tmp.xx, tmp.xy, tmp.xz, tmp.yx, tmp.yy, tmp.yz, tmp.zx, tmp.zy, tmp.zz);
2050 
2051  Vector ext = extForce_normal;
2052  fprintf(stderr, "EXT_FORCE_NORMAL %1.2lf %1.2lf %1.2lf\n",
2053  ext.x, ext.y, ext.z);
2054 
2055  ext = extForce_nbond;
2056  fprintf(stderr, "EXT_FORCE_NBOND %1.2lf %1.2lf %1.2lf\n",
2057  ext.x, ext.y, ext.z);
2058 
2059  ext = extForce_slow;
2060  fprintf(stderr, "EXT_FORCE_SLOW %1.2lf %1.2lf %1.2lf\n",
2061  ext.x, ext.y, ext.z);
2062 
2063  //fprintf(stderr, "State Lattice for timestep %d\n", step);
2064  fprintf(stderr, "LATTICE %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
2065  state->lattice.a().x, state->lattice.a().y, state->lattice.a().z,
2066  state->lattice.b().x, state->lattice.b().y, state->lattice.b().z,
2067  state->lattice.c().x, state->lattice.c().y, state->lattice.c().z);
2068 
2069  fprintf(stderr, "VOLUME %3.10lf\n", state->lattice.volume());
2070 
2071 #endif
2072 
2073 
2074  Node *node = Node::Object();
2075  Molecule *molecule = node->molecule;
2076  Lattice &lattice = state->lattice;
2077  BigReal volume;
2078 
2079  Vector extPosition = lattice.origin();
2080  virial_normal -= outer(extForce_normal,extPosition);
2081  virial_nbond -= outer(extForce_nbond,extPosition);
2082  virial_slow -= outer(extForce_slow,extPosition);
2083 
2084  if ( (volume=lattice.volume()) != 0. )
2085  {
2086 
2087  if ((simParams->LJcorrection || simParams->LJcorrectionAlt) && volume) {
2088 #ifdef MEM_OPT_VERSION
2089  NAMD_bug("LJcorrection not supported in memory optimized build.");
2090 #else
2091  // Apply tail correction to pressure
2092  BigReal alchLambda = simParams->getCurrentLambda(step);
2093  virial_normal += Tensor::identity(molecule->getVirialTailCorr(alchLambda) / volume);
2094 #endif
2095  }
2096 
2097 
2098  // kinetic energy component included in virials
2099  if(simParams->CUDASOAintegrate && step != 0 && !simParams->isMultiTimeStepping()){
2100  pressure_normal = virial_normal / volume;
2101  // groupPressure_normal = ( virial_normal - intVirial_normal ) / volume;
2102  if (simParams->accelMDOn) {
2103  pressure_amd = virial_amd / volume;
2106  }
2107 
2108  if ( minimize || ! ( step % nbondFreq ) )
2109  {
2110  pressure_nbond = virial_nbond / volume;
2111  // groupPressure_nbond = ( virial_nbond - intVirial_nbond ) / volume;
2112  }
2113 
2114  if ( minimize || ! ( step % slowFreq ) )
2115  {
2116  pressure_slow = virial_slow / volume;
2117  // groupPressure_slow = ( virial_slow - intVirial_slow ) / volume;
2118  }
2119 
2121  groupPressure = pressure - intVirial_normal / volume;
2122  // groupPressure = groupPressure_normal + groupPressure_nbond +
2123  // groupPressure_slow;
2124  }else{
2125  pressure_normal = virial_normal / volume;
2126 
2127  groupPressure_normal = ( virial_normal - intVirial_normal ) / volume;
2128  if (simParams->accelMDOn) {
2129  pressure_amd = virial_amd / volume;
2132  }
2133 
2134  if ( minimize || ! ( step % nbondFreq ) )
2135  {
2136  pressure_nbond = virial_nbond / volume;
2137  groupPressure_nbond = ( virial_nbond - intVirial_nbond ) / volume;
2138  }
2139 
2140  if ( minimize || ! ( step % slowFreq ) )
2141  {
2142  pressure_slow = virial_slow / volume;
2143  groupPressure_slow = ( virial_slow - intVirial_slow ) / volume;
2144  }
2145 
2149  }
2150  }
2151  else
2152  {
2153  pressure = Tensor();
2154  groupPressure = Tensor();
2155  }
2156 
2157  if ( simParams->useGroupPressure )
2158  {
2163  }
2164  else
2165  {
2170  }
2171 
2172  if ( simParams->useFlexibleCell ) {
2173  // use symmetric pressure to control rotation
2174  // controlPressure_normal = symmetric(controlPressure_normal);
2175  // controlPressure_nbond = symmetric(controlPressure_nbond);
2176  // controlPressure_slow = symmetric(controlPressure_slow);
2177  // controlPressure = symmetric(controlPressure);
2178  // only use on-diagonal components for now
2183  if ( simParams->useConstantRatio ) {
2184 #define AVGXY(T) T.xy = T.yx = 0; T.xx = T.yy = 0.5 * ( T.xx + T.yy );\
2185  T.xz = T.zx = T.yz = T.zy = 0.5 * ( T.xz + T.yz );
2190 #undef AVGXY
2191  }
2192  } else {
2199  controlPressure =
2200  Tensor::identity(trace(controlPressure)/3.);
2201  }
2202 }
2203 
2205 (BigReal testV, int n,
2206  BigReal *Vmax, BigReal *Vmin, BigReal *Vavg, BigReal *M2, BigReal *sigmaV){
2207  BigReal delta;
2208 
2209  if(testV > *Vmax){
2210  *Vmax = testV;
2211  }
2212  else if(testV < *Vmin){
2213  *Vmin = testV;
2214  }
2215 
2216  //mean and std calculated by Online Algorithm
2217  delta = testV - *Vavg;
2218  *Vavg += delta / (BigReal)n;
2219  *M2 += delta * (testV - (*Vavg));
2220 
2221  *sigmaV = sqrt(*M2/n);
2222 }
2223 
2225 (int iE, int step, BigReal sigma0, BigReal Vmax, BigReal Vmin, BigReal Vavg, BigReal sigmaV,
2226  BigReal* k0, BigReal* k, BigReal* E, int *iEused, char *warn){
2227  switch(iE){
2228  case 2:
2229  *k0 = (1-sigma0/sigmaV) * (Vmax-Vmin) / (Vavg-Vmin);
2230  // if k0 <=0 OR k0 > 1, switch to iE=1 mode
2231  if(*k0 > 1.)
2232  *warn |= 1;
2233  else if(*k0 <= 0.)
2234  *warn |= 2;
2235  //else stay in iE=2 mode
2236  else{
2237  *E = Vmin + (Vmax-Vmin)/(*k0);
2238  *iEused = 2;
2239  break;
2240  }
2241  case 1:
2242  *E = Vmax;
2243  *k0 = (sigma0 / sigmaV) * (Vmax-Vmin) / (Vmax-Vavg);
2244  if(*k0 > 1.)
2245  *k0 = 1.;
2246  *iEused = 1;
2247  break;
2248  }
2249 
2250  *k = *k0 / (Vmax - Vmin);
2251 }
2252 
2254 (BigReal k, BigReal E, BigReal testV, Tensor vir_orig,
2255  BigReal *dV, BigReal *factor, Tensor *vir){
2256  BigReal VE = testV - E;
2257  //if V < E, apply boost
2258  if(VE < 0){
2259  *factor = k * VE;
2260  *vir += vir_orig * (*factor);
2261  *dV += (*factor) * VE/2.;
2262  *factor += 1.;
2263  }
2264  else{
2265  *factor = 1.;
2266  }
2267 }
2268 
2270 (int step_n, char type, int V_n, BigReal Vmax, BigReal Vmin, BigReal Vavg, BigReal sigmaV, BigReal M2, BigReal E, BigReal k, bool write_topic, bool lasttime){
2271  FILE *rest;
2272  char timestepstr[20];
2273  char *filename;
2274  int baselen;
2275  char *restart_name;
2276  const char *bsuffix;
2277 
2278  if(lasttime || simParams->restartFrequency == 0){
2279  filename = simParams->outputFilename;
2280  bsuffix = ".BAK";
2281  }
2282  else{
2283  filename = simParams->restartFilename;
2284  bsuffix = ".old";
2285  }
2286 
2287  baselen = strlen(filename);
2288  restart_name = new char[baselen+26];
2289 
2290  strcpy(restart_name, filename);
2291  if ( simParams->restartSave && !lasttime) {
2292  sprintf(timestepstr,".%d",step_n);
2293  strcat(restart_name, timestepstr);
2294  bsuffix = ".BAK";
2295  }
2296  strcat(restart_name, ".gamd");
2297 
2298  if(write_topic){
2299  NAMD_backup_file(restart_name,bsuffix);
2300 
2301  rest = fopen(restart_name, "w");
2302  if(rest){
2303  fprintf(rest, "# NAMD accelMDG restart file\n"
2304  "# D/T Vn Vmax Vmin Vavg sigmaV M2 E k\n"
2305  "%c %d %.17lg %.17lg %.17lg %.17lg %.17le %.17lg %.17lg\n",
2306  type, V_n-1, Vmax, Vmin, Vavg, sigmaV, M2, E, k);
2307  fclose(rest);
2308  iout << "GAUSSIAN ACCELERATED MD RESTART DATA WRITTEN TO " << restart_name << "\n" << endi;
2309  }
2310  else
2311  iout << iWARN << "Cannot write accelMDG restart file\n" << endi;
2312  }
2313  else{
2314  rest = fopen(restart_name, "a");
2315  if(rest){
2316  fprintf(rest, "%c %d %.17lg %.17lg %.17lg %.17lg %.17le %.17lg %.17lg\n",
2317  type, V_n-1, Vmax, Vmin, Vavg, sigmaV, M2, E, k);
2318  fclose(rest);
2319  }
2320  else
2321  iout << iWARN << "Cannot write accelMDG restart file\n" << endi;
2322  }
2323 
2324  delete[] restart_name;
2325 }
2326 
2327 
2328 void Controller::rescaleaccelMD(int step, int minimize)
2329 {
2330  if ( !simParams->accelMDOn ) return;
2331 
2333 
2334  // copy all to submit_reduction
2335  for ( int i=0; i<REDUCTION_MAX_RESERVED; ++i ) {
2337  }
2339 
2340  if (step == simParams->firstTimestep) {
2341  accelMDdVAverage = 0;
2342  accelMDdV = 0;
2343  }
2344 // if ( minimize || ((step < simParams->accelMDFirstStep ) || (step > simParams->accelMDLastStep ))) return;
2345  if ( minimize || (step < simParams->accelMDFirstStep ) || ( simParams->accelMDLastStep > 0 && step > simParams->accelMDLastStep )) return;
2346 
2347  Node *node = Node::Object();
2348  Molecule *molecule = node->molecule;
2349  Lattice &lattice = state->lattice;
2350 
2351  const BigReal accelMDE = simParams->accelMDE;
2352  const BigReal accelMDalpha = simParams->accelMDalpha;
2353  const BigReal accelMDTE = simParams->accelMDTE;
2354  const BigReal accelMDTalpha = simParams->accelMDTalpha;
2355  const int accelMDOutFreq = simParams->accelMDOutFreq;
2356 
2357  //GaMD
2358  static BigReal VmaxP, VminP, VavgP, M2P=0, sigmaVP;
2359  static BigReal VmaxD, VminD, VavgD, M2D=0, sigmaVD;
2360  static BigReal k0P, kP, EP;
2361  static BigReal k0D, kD, ED;
2362  static int V_n = 1, iEusedD, iEusedP;
2363  static char warnD, warnP;
2364  static int restfreq;
2365 
2368  const int ntcmd = simParams->accelMDFirstStep + simParams->accelMDGcMDSteps;
2369  const int ntebprep = ntcmd + simParams->accelMDGEquiPrepSteps;
2370  const int nteb = ntcmd + simParams->accelMDGEquiSteps;
2371  const int ntave = simParams->accelMDGStatWindow;
2372 
2373  BigReal volume;
2374  BigReal bondEnergy;
2375  BigReal angleEnergy;
2376  BigReal dihedralEnergy;
2377  BigReal improperEnergy;
2378  BigReal crosstermEnergy;
2379  BigReal boundaryEnergy;
2380  BigReal miscEnergy;
2381  BigReal amd_electEnergy;
2382  BigReal amd_ljEnergy;
2383  BigReal amd_ljEnergy_Corr = 0.;
2384  BigReal amd_electEnergySlow;
2385  BigReal amd_groLJEnergy;
2386  BigReal amd_groGaussEnergy;
2387  BigReal amd_goTotalEnergy;
2388  BigReal potentialEnergy;
2389  BigReal factor_dihe = 1;
2390  BigReal factor_tot = 1;
2391  BigReal testV;
2392  BigReal dV = 0.;
2393  Vector accelMDfactor;
2394  Tensor vir; //auto initialized to 0
2395  Tensor vir_dihe;
2396  Tensor vir_normal;
2397  Tensor vir_nbond;
2398  Tensor vir_slow;
2399 
2400  volume = lattice.volume();
2401 
2402  bondEnergy = amd_reduction->item(REDUCTION_BOND_ENERGY);
2403  angleEnergy = amd_reduction->item(REDUCTION_ANGLE_ENERGY);
2404  dihedralEnergy = amd_reduction->item(REDUCTION_DIHEDRAL_ENERGY);
2405  improperEnergy = amd_reduction->item(REDUCTION_IMPROPER_ENERGY);
2406  crosstermEnergy = amd_reduction->item(REDUCTION_CROSSTERM_ENERGY);
2407  boundaryEnergy = amd_reduction->item(REDUCTION_BC_ENERGY);
2408  miscEnergy = amd_reduction->item(REDUCTION_MISC_ENERGY);
2409 
2410  GET_TENSOR(vir_dihe,amd_reduction,REDUCTION_VIRIAL_AMD_DIHE);
2411  GET_TENSOR(vir_normal,amd_reduction,REDUCTION_VIRIAL_NORMAL);
2412  GET_TENSOR(vir_nbond,amd_reduction,REDUCTION_VIRIAL_NBOND);
2413  GET_TENSOR(vir_slow,amd_reduction,REDUCTION_VIRIAL_SLOW);
2414 
2415  if ( !( step % nbondFreq ) ) {
2416  amd_electEnergy = amd_reduction->item(REDUCTION_ELECT_ENERGY);
2417  amd_ljEnergy = amd_reduction->item(REDUCTION_LJ_ENERGY);
2418  amd_groLJEnergy = amd_reduction->item(REDUCTION_GRO_LJ_ENERGY);
2419  amd_groGaussEnergy = amd_reduction->item(REDUCTION_GRO_GAUSS_ENERGY);
2422  amd_goTotalEnergy = goNativeEnergy + goNonnativeEnergy;
2423  } else {
2424  amd_electEnergy = electEnergy;
2425  amd_ljEnergy = ljEnergy;
2426  amd_groLJEnergy = groLJEnergy;
2427  amd_groGaussEnergy = groGaussEnergy;
2428  amd_goTotalEnergy = goTotalEnergy;
2429  }
2430 
2431  if( (simParams->LJcorrection || simParams->LJcorrectionAlt) && volume ) {
2432  // Obtain tail correction (copied from printEnergies())
2433  // This value is only printed for sanity check
2434  // accelMD currently does not 'boost' tail correction
2435  amd_ljEnergy_Corr = molecule->tail_corr_ener / volume;
2436  }
2437 
2438  if ( !( step % slowFreq ) ) {
2439  amd_electEnergySlow = amd_reduction->item(REDUCTION_ELECT_ENERGY_SLOW);
2440  } else {
2441  amd_electEnergySlow = electEnergySlow;
2442  }
2443 
2444  potentialEnergy = bondEnergy + angleEnergy + dihedralEnergy +
2445  improperEnergy + amd_electEnergy + amd_electEnergySlow + amd_ljEnergy +
2446  crosstermEnergy + boundaryEnergy + miscEnergy +
2447  amd_goTotalEnergy + amd_groLJEnergy + amd_groGaussEnergy;
2448 
2449  //GaMD
2450  if(simParams->accelMDG){
2451  // if first time running accelMDG module
2452  if(step == firststep) {
2453  iEusedD = iEusedP = simParams->accelMDGiE;
2454  warnD = warnP = '\0';
2455 
2456  //restart file reading
2458  FILE *rest = fopen(simParams->accelMDGRestartFile, "r");
2459  char line[256];
2460  int dihe_n=0, tot_n=0;
2461  if(!rest){
2462  sprintf(line, "Cannot open accelMDG restart file: %s", simParams->accelMDGRestartFile);
2463  NAMD_die(line);
2464  }
2465 
2466  while(fgets(line, 256, rest)){
2467  if(line[0] == 'D'){
2468  dihe_n = sscanf(line+1, " %d %la %la %la %la %la %la %la",
2469  &V_n, &VmaxD, &VminD, &VavgD, &sigmaVD, &M2D, &ED, &kD);
2470  }
2471  else if(line[0] == 'T'){
2472  tot_n = sscanf(line+1, " %d %la %la %la %la %la %la %la",
2473  &V_n, &VmaxP, &VminP, &VavgP, &sigmaVP, &M2P, &EP, &kP);
2474  }
2475  }
2476 
2477  fclose(rest);
2478 
2479  V_n++;
2480 
2481  //check dihe settings
2483  if(dihe_n !=8)
2484  NAMD_die("Invalid dihedral potential energy format in accelMDG restart file");
2485  k0D = kD * (VmaxD - VminD);
2486  iout << "GAUSSIAN ACCELERATED MD READ FROM RESTART FILE: DIHED"
2487  << " Vmax " << VmaxD << " Vmin " << VminD
2488  << " Vavg " << VavgD << " sigmaV " << sigmaVD
2489  << " E " << ED << " k " << kD
2490  << "\n" << endi;
2491  }
2492 
2493  //check tot settings
2495  if(tot_n !=8)
2496  NAMD_die("Invalid total potential energy format in accelMDG restart file");
2497  k0P = kP * (VmaxP - VminP);
2498  iout << "GAUSSIAN ACCELERATED MD READ FROM RESTART FILE: TOTAL"
2499  << " Vmax " << VmaxP << " Vmin " << VminP
2500  << " Vavg " << VavgP << " sigmaV " << sigmaVP
2501  << " E " << EP << " k " << kP
2502  << "\n" << endi;
2503  }
2504 
2505  iEusedD = (ED == VmaxD) ? 1 : 2;
2506  iEusedP = (EP == VmaxP) ? 1 : 2;
2507  }
2508  //local restfreq follows NAMD restartfreq (default: 500)
2510  }
2511 
2512  //for dihedral potential
2514  testV = dihedralEnergy + crosstermEnergy;
2515 
2516  //write restart file every restartfreq steps
2517  if(step > firststep && step % restfreq == 0)
2518  write_accelMDG_rest_file(step, 'D', V_n, VmaxD, VminD, VavgD, sigmaVD, M2D, ED, kD,
2519  true, false);
2520  //write restart file at the end of the simulation
2521  if( simParams->accelMDLastStep > 0 ){
2522  if( step == simParams->accelMDLastStep )
2523  write_accelMDG_rest_file(step, 'D', V_n, VmaxD, VminD, VavgD, sigmaVD, M2D, ED, kD,
2524  true, true);
2525  }
2526  else if(step == simParams->N)
2527  write_accelMDG_rest_file(step, 'D', V_n, VmaxD, VminD, VavgD, sigmaVD, M2D, ED, kD,
2528  true, true);
2529 
2530  //conventional MD
2531  if(step < ntcmd){
2532  //very first step
2533  if(step == firststep && !simParams->accelMDGRestart){
2534  //initialize stat
2535  VmaxD = VminD = VavgD = testV;
2536  M2D = sigmaVD = 0.;
2537  }
2538  //first step after cmdprep
2539  else if(step == ntcmdprep && ntcmdprep != 0){
2540  //reset stat
2541  VmaxD = VminD = VavgD = testV;
2542  M2D = sigmaVD = 0.;
2543  iout << "GAUSSIAN ACCELERATED MD: RESET DIHEDRAL POTENTIAL STATISTICS\n" << endi;
2544  }
2545  //every ntave steps
2546  else if(ntave > 0 && step % ntave == 0){
2547  //update Vmax Vmin
2548  if(testV > VmaxD) VmaxD = testV;
2549  if(testV < VminD) VminD = testV;
2550  //reset avg and std
2551  VavgD = testV;
2552  M2D = sigmaVD = 0.;
2553  iout << "GAUSSIAN ACCELERATED MD: RESET DIHEDRAL POTENTIAL AVG AND STD\n" << endi;
2554  }
2555  //normal steps
2556  else
2557  calc_accelMDG_mean_std(testV, V_n,
2558  &VmaxD, &VminD, &VavgD, &M2D, &sigmaVD) ;
2559 
2560  //last cmd step
2561  if(step == ntcmd - 1){
2563  VmaxD, VminD, VavgD, sigmaVD, &k0D, &kD, &ED, &iEusedD, &warnD);
2564  }
2565  }
2566  //equilibration
2567  else if(step < nteb){
2568  calc_accelMDG_force_factor(kD, ED, testV, vir_dihe,
2569  &dV, &factor_dihe, &vir);
2570 
2571  //first step after cmd
2572  if(step == ntcmd && simParams->accelMDGresetVaftercmd){
2573  //reset stat
2574  VmaxD = VminD = VavgD = testV;
2575  M2D = sigmaVD = 0.;
2576  iout << "GAUSSIAN ACCELERATED MD: RESET DIHEDRAL POTENTIAL STATISTICS\n" << endi;
2577  }
2578  //every ntave steps
2579  else if(ntave > 0 && step % ntave == 0){
2580  //update Vmax Vmin
2581  if(testV > VmaxD) VmaxD = testV;
2582  if(testV < VminD) VminD = testV;
2583  //reset avg and std
2584  VavgD = testV;
2585  M2D = sigmaVD = 0.;
2586  iout << "GAUSSIAN ACCELERATED MD: RESET DIHEDRAL POTENTIAL AVG AND STD\n" << endi;
2587  }
2588  else
2589  calc_accelMDG_mean_std(testV, V_n,
2590  &VmaxD, &VminD, &VavgD, &M2D, &sigmaVD) ;
2591 
2592  //steps after ebprep
2593  if(step >= ntebprep)
2594  if((ntave > 0 && step % ntave == 0) || ntave <= 0)
2596  VmaxD, VminD, VavgD, sigmaVD, &k0D, &kD, &ED, &iEusedD, &warnD);
2597  }
2598  //production
2599  else{
2600  calc_accelMDG_force_factor(kD, ED, testV, vir_dihe,
2601  &dV, &factor_dihe, &vir);
2602  }
2603 
2604  }
2605  //for total potential
2607  Tensor vir_tot = vir_normal + vir_nbond + vir_slow;
2608  testV = potentialEnergy;
2609  if(simParams->accelMDdual){
2610  testV -= dihedralEnergy + crosstermEnergy;
2611  vir_tot -= vir_dihe;
2612  }
2613 
2614  //write restart file every restartfreq steps
2615  if(step > firststep && step % restfreq == 0)
2616  write_accelMDG_rest_file(step, 'T', V_n, VmaxP, VminP, VavgP, sigmaVP, M2P, EP, kP,
2617  !simParams->accelMDdual, false);
2618  //write restart file at the end of simulation
2619  if( simParams->accelMDLastStep > 0 ){
2620  if( step == simParams->accelMDLastStep )
2621  write_accelMDG_rest_file(step, 'T', V_n, VmaxP, VminP, VavgP, sigmaVP, M2P, EP, kP,
2622  !simParams->accelMDdual, true);
2623  }
2624  else if(step == simParams->N)
2625  write_accelMDG_rest_file(step, 'T', V_n, VmaxP, VminP, VavgP, sigmaVP, M2P, EP, kP,
2626  !simParams->accelMDdual, true);
2627 
2628  //conventional MD
2629  if(step < ntcmd){
2630  //very first step
2631  if(step == firststep && !simParams->accelMDGRestart){
2632  //initialize stat
2633  VmaxP = VminP = VavgP = testV;
2634  M2P = sigmaVP = 0.;
2635  }
2636  //first step after cmdprep
2637  else if(step == ntcmdprep && ntcmdprep != 0){
2638  //reset stat
2639  VmaxP = VminP = VavgP = testV;
2640  M2P = sigmaVP = 0.;
2641  iout << "GAUSSIAN ACCELERATED MD: RESET TOTAL POTENTIAL STATISTICS\n" << endi;
2642  }
2643  //every ntave steps
2644  else if(ntave > 0 && step % ntave == 0){
2645  //update Vmax Vmin
2646  if(testV > VmaxP) VmaxP = testV;
2647  if(testV < VminP) VminP = testV;
2648  //reset avg and std
2649  VavgP = testV;
2650  M2P = sigmaVP = 0.;
2651  iout << "GAUSSIAN ACCELERATED MD: RESET TOTAL POTENTIAL AVG AND STD\n" << endi;
2652  }
2653  //normal steps
2654  else
2655  calc_accelMDG_mean_std(testV, V_n,
2656  &VmaxP, &VminP, &VavgP, &M2P, &sigmaVP);
2657  //last cmd step
2658  if(step == ntcmd - 1){
2660  VmaxP, VminP, VavgP, sigmaVP, &k0P, &kP, &EP, &iEusedP, &warnP);
2661  }
2662  }
2663  //equilibration
2664  else if(step < nteb){
2665  calc_accelMDG_force_factor(kP, EP, testV, vir_tot,
2666  &dV, &factor_tot, &vir);
2667 
2668  //first step after cmd
2669  if(step == ntcmd && simParams->accelMDGresetVaftercmd){
2670  //reset stat
2671  VmaxP = VminP = VavgP = testV;
2672  M2P = sigmaVP = 0.;
2673  iout << "GAUSSIAN ACCELERATED MD: RESET TOTAL POTENTIAL STATISTICS\n" << endi;
2674  }
2675  //every ntave steps
2676  else if(ntave > 0 && step % ntave == 0){
2677  //update Vmax Vmin
2678  if(testV > VmaxP) VmaxP = testV;
2679  if(testV < VminP) VminP = testV;
2680  //reset avg and std
2681  VavgP = testV;
2682  M2P = sigmaVP = 0.;
2683  iout << "GAUSSIAN ACCELERATED MD: RESET TOTAL POTENTIAL AVG AND STD\n" << endi;
2684  }
2685  else
2686  calc_accelMDG_mean_std(testV, V_n,
2687  &VmaxP, &VminP, &VavgP, &M2P, &sigmaVP);
2688 
2689  //steps after ebprep
2690  if(step >= ntebprep)
2691  if((ntave > 0 && step % ntave == 0) || ntave <= 0)
2693  VmaxP, VminP, VavgP, sigmaVP, &k0P, &kP, &EP, &iEusedP, &warnP);
2694  }
2695  //production
2696  else{
2697  calc_accelMDG_force_factor(kP, EP, testV, vir_tot,
2698  &dV, &factor_tot, &vir);
2699  }
2700 
2701  }
2702  accelMDdVAverage += dV;
2703 
2704  //first step after ntcmdprep
2705  if((ntcmdprep > 0 && step == ntcmdprep) ||
2706  (step < nteb && ntave > 0 && step % ntave == 0) ||
2707  (simParams->accelMDGresetVaftercmd && step == ntcmd)){
2708  V_n = 1;
2709  }
2710 
2711  if(step < nteb)
2712  V_n++;
2713 
2714  }
2715  //aMD
2716  else{
2717  if (simParams->accelMDdihe) {
2718 
2719  testV = dihedralEnergy + crosstermEnergy;
2720  if ( testV < accelMDE ) {
2721  factor_dihe = accelMDalpha/(accelMDalpha + accelMDE - testV);
2722  factor_dihe *= factor_dihe;
2723  vir = vir_dihe * (factor_dihe - 1.0);
2724  dV = (accelMDE - testV)*(accelMDE - testV)/(accelMDalpha + accelMDE - testV);
2725  accelMDdVAverage += dV;
2726  }
2727 
2728  } else if (simParams->accelMDdual) {
2729 
2730  testV = dihedralEnergy + crosstermEnergy;
2731  if ( testV < accelMDE ) {
2732  factor_dihe = accelMDalpha/(accelMDalpha + accelMDE - testV);
2733  factor_dihe *= factor_dihe;
2734  vir = vir_dihe * (factor_dihe - 1.0) ;
2735  dV = (accelMDE - testV)*(accelMDE - testV)/(accelMDalpha + accelMDE - testV);
2736  }
2737 
2738  testV = potentialEnergy - dihedralEnergy - crosstermEnergy;
2739  if ( testV < accelMDTE ) {
2740  factor_tot = accelMDTalpha/(accelMDTalpha + accelMDTE - testV);
2741  factor_tot *= factor_tot;
2742  vir += (vir_normal - vir_dihe + vir_nbond + vir_slow) * (factor_tot - 1.0);
2743  dV += (accelMDTE - testV)*(accelMDTE - testV)/(accelMDTalpha + accelMDTE - testV);
2744  }
2745  accelMDdVAverage += dV;
2746 
2747  } else {
2748 
2749  testV = potentialEnergy;
2750  if ( testV < accelMDE ) {
2751  factor_tot = accelMDalpha/(accelMDalpha + accelMDE - testV);
2752  factor_tot *= factor_tot;
2753  vir = (vir_normal + vir_nbond + vir_slow) * (factor_tot - 1.0);
2754  dV = (accelMDE - testV)*(accelMDE - testV)/(accelMDalpha + accelMDE - testV);
2755  accelMDdVAverage += dV;
2756  }
2757  }
2758  }
2759 
2760  accelMDfactor[0]=factor_dihe;
2761  accelMDfactor[1]=factor_tot;
2762  accelMDfactor[2]=1;
2763  broadcast->accelMDRescaleFactor.publish(step,accelMDfactor);
2764  virial_amd = vir;
2765  accelMDdV = dV;
2766 
2767  if ( factor_tot < 0.001 ) {
2768  iout << iWARN << "accelMD is using a very high boost potential, simulation may become unstable!"
2769  << "\n" << endi;
2770  }
2771 
2772  if ( ! (step % accelMDOutFreq) ) {
2773  if ( !(step == simParams->firstTimestep) ) {
2774  accelMDdVAverage = accelMDdVAverage/accelMDOutFreq;
2775  }
2776  iout << "ACCELERATED MD: STEP " << step
2777  << " dV " << dV
2778  << " dVAVG " << accelMDdVAverage
2779  << " BOND " << bondEnergy
2780  << " ANGLE " << angleEnergy
2781  << " DIHED " << dihedralEnergy+crosstermEnergy
2782  << " IMPRP " << improperEnergy
2783  << " ELECT " << amd_electEnergy+amd_electEnergySlow
2784  << " VDW " << amd_ljEnergy
2785  << " POTENTIAL " << potentialEnergy;
2786  if(amd_ljEnergy_Corr)
2787  iout << " LJcorr " << amd_ljEnergy_Corr;
2788  iout << "\n" << endi;
2789  if(simParams->accelMDG){
2791  iout << "GAUSSIAN ACCELERATED MD: DIHED iE " << iEusedD
2792  << " Vmax " << VmaxD << " Vmin " << VminD
2793  << " Vavg " << VavgD << " sigmaV " << sigmaVD
2794  << " E " << ED << " k0 " << k0D << " k " << kD
2795  << "\n" << endi;
2796  if(warnD & 1)
2797  iout << "GAUSSIAN ACCELERATED MD: DIHED !!! WARNING: k0 > 1, "
2798  << "SWITCHED TO iE = 1 MODE !!!\n" << endi;
2799  if(warnD & 2)
2800  iout << "GAUSSIAN ACCELERATED MD: DIHED !!! WARNING: k0 <= 0, "
2801  << "SWITCHED TO iE = 1 MODE !!!\n" << endi;
2803  iout << "GAUSSIAN ACCELERATED MD: TOTAL iE " << iEusedP
2804  << " Vmax " << VmaxP << " Vmin " << VminP
2805  << " Vavg " << VavgP << " sigmaV " << sigmaVP
2806  << " E " << EP << " k0 " << k0P << " k " << kP
2807  << "\n" << endi;
2808  if(warnP & 1)
2809  iout << "GAUSSIAN ACCELERATED MD: TOTAL !!! WARNING: k0 > 1, "
2810  << "SWITCHED TO iE = 1 MODE !!!\n" << endi;
2811  if(warnP & 2)
2812  iout << "GAUSSIAN ACCELERATED MD: TOTAL !!! WARNING: k0 <= 0, "
2813  << "SWITCHED TO iE = 1 MODE !!!\n" << endi;
2814  warnD = warnP = '\0';
2815  }
2816 
2817  accelMDdVAverage = 0;
2818 
2819  if (simParams->accelMDDebugOn) {
2820  Tensor p_normal;
2821  Tensor p_nbond;
2822  Tensor p_slow;
2823  Tensor p;
2824  if ( volume != 0. ) {
2825  p_normal = vir_normal/volume;
2826  p_nbond = vir_nbond/volume;
2827  p_slow = vir_slow/volume;
2828  p = vir/volume;
2829  }
2830  iout << " accelMD Scaling Factor: " << accelMDfactor << "\n"
2831  << " accelMD PNORMAL " << trace(p_normal)*PRESSUREFACTOR/3. << "\n"
2832  << " accelMD PNBOND " << trace(p_nbond)*PRESSUREFACTOR/3. << "\n"
2833  << " accelMD PSLOW " << trace(p_slow)*PRESSUREFACTOR/3. << "\n"
2834  << " accelMD PAMD " << trace(p)*PRESSUREFACTOR/3. << "\n"
2835  << endi;
2836  }
2837  }
2838 }
2839 
2841  if (!simParams->adaptTempOn) return;
2842  iout << iINFO << "INITIALISING ADAPTIVE TEMPERING\n" << endi;
2843  adaptTempDtMin = 0;
2844  adaptTempDtMax = 0;
2845  adaptTempAutoDt = false;
2846  if (simParams->adaptTempBins == 0) {
2847  iout << iINFO << "READING ADAPTIVE TEMPERING RESTART FILE\n" << endi;
2848  std::ifstream adaptTempRead(simParams->adaptTempInFile);
2849  if (adaptTempRead) {
2850  int readInt;
2851  BigReal readReal;
2852  bool readBool;
2853  // step
2854  adaptTempRead >> readInt;
2855  // Start with min and max temperatures
2856  adaptTempRead >> adaptTempT; // KELVIN
2857  adaptTempRead >> adaptTempBetaMin; // KELVIN
2858  adaptTempRead >> adaptTempBetaMax; // KELVIN
2859  adaptTempBetaMin = 1./adaptTempBetaMin; // KELVIN^-1
2860  adaptTempBetaMax = 1./adaptTempBetaMax; // KELVIN^-1
2861  // In case file is manually edited
2863  readReal = adaptTempBetaMax;
2866  }
2867  adaptTempRead >> adaptTempBins;
2868  adaptTempRead >> adaptTempCg;
2869  adaptTempRead >> adaptTempDt;
2878  for(int j = 0; j < adaptTempBins; ++j) {
2879  adaptTempRead >> adaptTempPotEnergyAve[j];
2880  adaptTempRead >> adaptTempPotEnergyVar[j];
2881  adaptTempRead >> adaptTempPotEnergySamples[j];
2882  adaptTempRead >> adaptTempPotEnergyAveNum[j];
2883  adaptTempRead >> adaptTempPotEnergyVarNum[j];
2884  adaptTempRead >> adaptTempPotEnergyAveDen[j];
2886  }
2887  adaptTempRead.close();
2888  }
2889  else NAMD_die("Could not open ADAPTIVE TEMPERING restart file.\n");
2890  }
2891  else {
2906  if (simParams->langevinOn)
2908  else if (simParams->rescaleFreq > 0)
2910  for(int j = 0; j < adaptTempBins; ++j){
2911  adaptTempPotEnergyAveNum[j] = 0.;
2912  adaptTempPotEnergyAveDen[j] = 0.;
2914  adaptTempPotEnergyVarNum[j] = 0.;
2915  adaptTempPotEnergyVar[j] = 0.;
2916  adaptTempPotEnergyAve[j] = 0.;
2918  }
2919  }
2920  if (simParams->adaptTempAutoDt > 0.0) {
2921  adaptTempAutoDt = true;
2924  }
2925  adaptTempDTave = 0;
2926  adaptTempDTavenum = 0;
2927  iout << iINFO << "ADAPTIVE TEMPERING: TEMPERATURE RANGE: [" << 1./adaptTempBetaMax << "," << 1./adaptTempBetaMin << "] KELVIN\n";
2928  iout << iINFO << "ADAPTIVE TEMPERING: NUMBER OF BINS TO STORE POT. ENERGY: " << adaptTempBins << "\n";
2929  iout << iINFO << "ADAPTIVE TEMPERING: ADAPTIVE BIN AVERAGING PARAMETER: " << adaptTempCg << "\n";
2930  iout << iINFO << "ADAPTIVE TEMPERING: SCALING CONSTANT FOR LANGEVIN TEMPERATURE UPDATES: " << adaptTempDt << "\n";
2931  iout << iINFO << "ADAPTIVE TEMPERING: INITIAL TEMPERATURE: " << adaptTempT<< "\n";
2932  if (simParams->adaptTempRestartFreq > 0) {
2936  NAMD_die("Error opening restart file");
2937  }
2938 }
2939 
2942  adaptTempRestartFile.seekp(std::ios::beg);
2943  iout << "ADAPTEMP: WRITING RESTART FILE AT STEP " << step << "\n" << endi;
2944  adaptTempRestartFile << step << " ";
2945  // Start with min and max temperatures
2946  adaptTempRestartFile << adaptTempT<< " "; // KELVIN
2947  adaptTempRestartFile << 1./adaptTempBetaMin << " "; // KELVIN
2948  adaptTempRestartFile << 1./adaptTempBetaMax << " "; // KELVIN
2952  adaptTempRestartFile << "\n" ;
2953  for(int j = 0; j < adaptTempBins; ++j) {
2960  adaptTempRestartFile << "\n";
2961  }
2963  }
2964 }
2965 
2966 void Controller::adaptTempUpdate(int step, int minimize)
2967 {
2968  //Beta = 1./T
2969  if ( !simParams->adaptTempOn ) return;
2970  int j = 0;
2971  if (step == simParams->firstTimestep) {
2972  adaptTempInit(step);
2973  return;
2974  }
2975  if ( minimize || (step < simParams->adaptTempFirstStep ) ||
2976  ( simParams->adaptTempLastStep > 0 && step > simParams->adaptTempLastStep )) return;
2977  const int adaptTempOutFreq = simParams->adaptTempOutFreq;
2978  const bool adaptTempDebug = simParams->adaptTempDebug;
2979  //Calculate Current inverse temperature and bin
2980  BigReal adaptTempBeta = 1./adaptTempT;
2981  adaptTempBin = (int)floor((adaptTempBeta - adaptTempBetaMin)/adaptTempDBeta);
2982 
2983  if (adaptTempBin < 0 || adaptTempBin > adaptTempBins)
2984  iout << iWARN << " adaptTempBin out of range: adaptTempBin: " << adaptTempBin
2985  << " adaptTempBeta: " << adaptTempBeta
2986  << " adaptTempDBeta: " << adaptTempDBeta
2987  << " betaMin:" << adaptTempBetaMin
2988  << " betaMax: " << adaptTempBetaMax << "\n";
2991 
2992  BigReal potentialEnergy;
2993  BigReal potEnergyAverage;
2994  BigReal potEnergyVariance;
2995  potentialEnergy = totalEnergy-kineticEnergy;
2996 
2997  //calculate new bin average and variance using adaptive averaging
3000  adaptTempPotEnergyVarNum[adaptTempBin] = adaptTempPotEnergyVarNum[adaptTempBin]*gammaAve + potentialEnergy*potentialEnergy;
3001 
3004  potEnergyVariance -= potEnergyAverage*potEnergyAverage;
3005 
3006  adaptTempPotEnergyAve[adaptTempBin] = potEnergyAverage;
3007  adaptTempPotEnergyVar[adaptTempBin] = potEnergyVariance;
3008 
3009  // Weighted integral of <Delta E^2>_beta dbeta <= Eq 4 of JCP 132 244101
3010  // Integrals of Eqs 5 and 6 is done as piecewise assuming <Delta E^2>_beta
3011  // is constant for each bin. This is to estimate <E(beta)> where beta \in
3012  // (beta_i,beta_{i+1}) using Eq 2 of JCP 132 244101
3013  if ( ! ( step % simParams->adaptTempFreq ) ) {
3014  // If adaptTempBin not at the edge, calculate improved average:
3015  if (adaptTempBin > 0 && adaptTempBin < adaptTempBins-1) {
3016  // Get Averaging Limits:
3017  BigReal deltaBeta = 0.04*adaptTempBeta; //0.08 used in paper - make variable
3018  BigReal betaPlus;
3019  BigReal betaMinus;
3020  int nMinus =0;
3021  int nPlus = 0;
3022  if ( adaptTempBeta-adaptTempBetaMin < deltaBeta ) deltaBeta = adaptTempBeta-adaptTempBetaMin;
3023  if ( adaptTempBetaMax-adaptTempBeta < deltaBeta ) deltaBeta = adaptTempBetaMax-adaptTempBeta;
3024  betaMinus = adaptTempBeta - deltaBeta;
3025  betaPlus = adaptTempBeta + deltaBeta;
3026  BigReal betaMinus2 = betaMinus*betaMinus;
3027  BigReal betaPlus2 = betaPlus*betaPlus;
3028  nMinus = (int)floor((betaMinus-adaptTempBetaMin)/adaptTempDBeta);
3029  nPlus = (int)floor((betaPlus-adaptTempBetaMin)/adaptTempDBeta);
3030  // Variables for <E(beta)> estimate:
3031  BigReal potEnergyAve0 = 0.0;
3032  BigReal potEnergyAve1 = 0.0;
3033  // Integral terms
3034  BigReal A0 = 0;
3035  BigReal A1 = 0;
3036  BigReal A2 = 0;
3037  //A0 phi_s integral for beta_minus < beta < beta_{i+1}
3038  BigReal betaNp1 = adaptTempBetaN[adaptTempBin+1];
3039  BigReal DeltaE2Ave;
3040  BigReal DeltaE2AveSum = 0;
3041  BigReal betaj;
3042  for (j = nMinus+1; j <= adaptTempBin; ++j) {
3043  potEnergyAve0 += adaptTempPotEnergyAve[j];
3044  DeltaE2Ave = adaptTempPotEnergyVar[j];
3045  DeltaE2AveSum += DeltaE2Ave;
3046  A0 += j*DeltaE2Ave;
3047  }
3048  A0 *= adaptTempDBeta;
3049  A0 += (adaptTempBetaMin+0.5*adaptTempDBeta-betaMinus)*DeltaE2AveSum;
3050  A0 *= adaptTempDBeta;
3051  betaj = adaptTempBetaN[nMinus+1]-betaMinus;
3052  betaj *= betaj;
3053  A0 += 0.5*betaj*adaptTempPotEnergyVar[nMinus];
3054  A0 /= (betaNp1-betaMinus);
3055 
3056  //A1 phi_s integral for beta_{i+1} < beta < beta_plus
3057  DeltaE2AveSum = 0;
3058  for (j = adaptTempBin+1; j < nPlus; j++) {
3059  potEnergyAve1 += adaptTempPotEnergyAve[j];
3060  DeltaE2Ave = adaptTempPotEnergyVar[j];
3061  DeltaE2AveSum += DeltaE2Ave;
3062  A1 += j*DeltaE2Ave;
3063  }
3064  A1 *= adaptTempDBeta;
3065  A1 += (adaptTempBetaMin+0.5*adaptTempDBeta-betaPlus)*DeltaE2AveSum;
3066  A1 *= adaptTempDBeta;
3067  if ( nPlus < adaptTempBins ) {
3068  betaj = betaPlus-adaptTempBetaN[nPlus];
3069  betaj *= betaj;
3070  A1 -= 0.5*betaj*adaptTempPotEnergyVar[nPlus];
3071  }
3072  A1 /= (betaPlus-betaNp1);
3073 
3074  //A2 phi_t integral for beta_i
3075  A2 = 0.5*adaptTempDBeta*potEnergyVariance;
3076 
3077  // Now calculate a+ and a-
3078  DeltaE2Ave = A0-A1;
3079  BigReal aplus = 0;
3080  BigReal aminus = 0;
3081  if (DeltaE2Ave != 0) {
3082  aplus = (A0-A2)/(A0-A1);
3083  if (aplus < 0) {
3084  aplus = 0;
3085  }
3086  if (aplus > 1) {
3087  aplus = 1;
3088  }
3089  aminus = 1-aplus;
3090  potEnergyAve0 *= adaptTempDBeta;
3091  potEnergyAve0 += adaptTempPotEnergyAve[nMinus]*(adaptTempBetaN[nMinus+1]-betaMinus);
3092  potEnergyAve0 /= (betaNp1-betaMinus);
3093  potEnergyAve1 *= adaptTempDBeta;
3094  if ( nPlus < adaptTempBins ) {
3095  potEnergyAve1 += adaptTempPotEnergyAve[nPlus]*(betaPlus-adaptTempBetaN[nPlus]);
3096  }
3097  potEnergyAve1 /= (betaPlus-betaNp1);
3098  potEnergyAverage = aminus*potEnergyAve0;
3099  potEnergyAverage += aplus*potEnergyAve1;
3100  }
3101  if (simParams->adaptTempDebug) {
3102  iout << "ADAPTEMP DEBUG:" << "\n"
3103  << " adaptTempBin: " << adaptTempBin << "\n"
3104  << " Samples: " << adaptTempPotEnergySamples[adaptTempBin] << "\n"
3105  << " adaptTempBeta: " << adaptTempBeta << "\n"
3106  << " adaptTemp: " << adaptTempT<< "\n"
3107  << " betaMin: " << adaptTempBetaMin << "\n"
3108  << " betaMax: " << adaptTempBetaMax << "\n"
3109  << " gammaAve: " << gammaAve << "\n"
3110  << " deltaBeta: " << deltaBeta << "\n"
3111  << " betaMinus: " << betaMinus << "\n"
3112  << " betaPlus: " << betaPlus << "\n"
3113  << " nMinus: " << nMinus << "\n"
3114  << " nPlus: " << nPlus << "\n"
3115  << " A0: " << A0 << "\n"
3116  << " A1: " << A1 << "\n"
3117  << " A2: " << A2 << "\n"
3118  << " a+: " << aplus << "\n"
3119  << " a-: " << aminus << "\n"
3120  << endi;
3121  }
3122  }
3123  else {
3124  if (simParams->adaptTempDebug) {
3125  iout << "ADAPTEMP DEBUG:" << "\n"
3126  << " adaptTempBin: " << adaptTempBin << "\n"
3127  << " Samples: " << adaptTempPotEnergySamples[adaptTempBin] << "\n"
3128  << " adaptTempBeta: " << adaptTempBeta << "\n"
3129  << " adaptTemp: " << adaptTempT<< "\n"
3130  << " betaMin: " << adaptTempBetaMin << "\n"
3131  << " betaMax: " << adaptTempBetaMax << "\n"
3132  << " gammaAve: " << gammaAve << "\n"
3133  << " deltaBeta: N/A\n"
3134  << " betaMinus: N/A\n"
3135  << " betaPlus: N/A\n"
3136  << " nMinus: N/A\n"
3137  << " nPlus: N/A\n"
3138  << " A0: N/A\n"
3139  << " A1: N/A\n"
3140  << " A2: N/A\n"
3141  << " a+: N/A\n"
3142  << " a-: N/A\n"
3143  << endi;
3144  }
3145  }
3146 
3147  //dT is new temperature
3148  BigReal dT = ((potentialEnergy-potEnergyAverage)/BOLTZMANN+adaptTempT)*adaptTempDt;
3149  dT += random->gaussian()*sqrt(2.*adaptTempDt)*adaptTempT;
3150  dT += adaptTempT;
3151 
3152  // Check if dT in [adaptTempTmin,adaptTempTmax]. If not try simpler estimate of mean
3153  // This helps sampling with poor statistics in the bins surrounding adaptTempBin.
3154  if ( dT > 1./adaptTempBetaMin || dT < 1./adaptTempBetaMax ) {
3156  dT += random->gaussian()*sqrt(2.*adaptTempDt)*adaptTempT;
3157  dT += adaptTempT;
3158  // Check again, if not then keep original adaptTempTor assign random.
3159  if ( dT > 1./adaptTempBetaMin ) {
3160  if (!simParams->adaptTempRandom) {
3161  //iout << iWARN << "ADAPTEMP: " << step << " T= " << dT
3162  // << " K higher than adaptTempTmax."
3163  // << " Keeping temperature at "
3164  // << adaptTempT<< "\n"<< endi;
3165  dT = adaptTempT;
3166  }
3167  else {
3168  //iout << iWARN << "ADAPTEMP: " << step << " T= " << dT
3169  // << " K higher than adaptTempTmax."
3170  // << " Assigning random temperature in range\n" << endi;
3172  dT = 1./dT;
3173  }
3174  }
3175  else if ( dT < 1./adaptTempBetaMax ) {
3176  if (!simParams->adaptTempRandom) {
3177  //iout << iWARN << "ADAPTEMP: " << step << " T= "<< dT
3178  // << " K lower than adaptTempTmin."
3179  // << " Keeping temperature at " << adaptTempT<< "\n" << endi;
3180  dT = adaptTempT;
3181  }
3182  else {
3183  //iout << iWARN << "ADAPTEMP: " << step << " T= "<< dT
3184  // << " K lower than adaptTempTmin."
3185  // << " Assigning random temperature in range\n" << endi;
3187  dT = 1./dT;
3188  }
3189  }
3190  else if (adaptTempAutoDt) {
3191  //update temperature step size counter
3192  //FOR "TRUE" ADAPTIVE TEMPERING
3193  BigReal adaptTempTdiff = fabs(dT-adaptTempT);
3194  if (adaptTempTdiff > 0) {
3195  adaptTempDTave += adaptTempTdiff;
3197 // iout << "ADAPTEMP: adapTempTdiff = " << adaptTempTdiff << "\n";
3198  }
3199  if(adaptTempDTavenum == 100){
3200  BigReal Frac;
3202  Frac = 1./adaptTempBetaMin-1./adaptTempBetaMax;
3203  Frac = adaptTempDTave/Frac;
3204  //if average temperature jump is > 3% of temperature range,
3205  //modify jump size to match 3%
3206  iout << "ADAPTEMP: " << step << " FRAC " << Frac << "\n";
3207  if (Frac > adaptTempDtMax || Frac < adaptTempDtMin) {
3208  Frac = adaptTempDtMax/Frac;
3209  iout << "ADAPTEMP: Updating adaptTempDt to ";
3210  adaptTempDt *= Frac;
3211  iout << adaptTempDt << "\n" << endi;
3212  }
3213  adaptTempDTave = 0;
3214  adaptTempDTavenum = 0;
3215  }
3216  }
3217  }
3218  else if (adaptTempAutoDt) {
3219  //update temperature step size counter
3220  // FOR "TRUE" ADAPTIVE TEMPERING
3221  BigReal adaptTempTdiff = fabs(dT-adaptTempT);
3222  if (adaptTempTdiff > 0) {
3223  adaptTempDTave += adaptTempTdiff;
3225 // iout << "ADAPTEMP: adapTempTdiff = " << adaptTempTdiff << "\n";
3226  }
3227  if(adaptTempDTavenum == 100){
3228  BigReal Frac;
3230  Frac = 1./adaptTempBetaMin-1./adaptTempBetaMax;
3231  Frac = adaptTempDTave/Frac;
3232  //if average temperature jump is > 3% of temperature range,
3233  //modify jump size to match 3%
3234  iout << "ADAPTEMP: " << step << " FRAC " << Frac << "\n";
3235  if (Frac > adaptTempDtMax || Frac < adaptTempDtMin) {
3236  Frac = adaptTempDtMax/Frac;
3237  iout << "ADAPTEMP: Updating adaptTempDt to ";
3238  adaptTempDt *= Frac;
3239  iout << adaptTempDt << "\n" << endi;
3240  }
3241  adaptTempDTave = 0;
3242  adaptTempDTavenum = 0;
3243 
3244  }
3245 
3246  }
3247 
3248  adaptTempT = dT;
3250  }
3251  adaptTempWriteRestart(step);
3252  if ( ! (step % adaptTempOutFreq) ) {
3253  iout << "ADAPTEMP: STEP " << step
3254  << " TEMP " << adaptTempT
3255  << " ENERGY " << std::setprecision(10) << potentialEnergy
3256  << " ENERGYAVG " << std::setprecision(10) << potEnergyAverage
3257  << " ENERGYVAR " << std::setprecision(10) << potEnergyVariance;
3258  iout << "\n" << endi;
3259  }
3260 
3261 }
3262 
3263 
3264 void Controller::compareChecksums(int step, int forgiving) {
3265  Node *node = Node::Object();
3266  Molecule *molecule = node->molecule;
3267  bool cudaIntegrator = simParams->CUDASOAintegrate;
3268  RequireReduction* reduction = getCurrentReduction();
3269 
3270  // Some basic correctness checking
3271  BigReal checksum, checksum_b;
3272  char errmsg[256];
3273 
3274  checksum = reduction->item(REDUCTION_ATOM_CHECKSUM);
3275  if ( ((int)checksum) != molecule->numAtoms && step != 0) {
3276  sprintf(errmsg, "Bad global atom count! (%d vs %d)\n",
3277  (int)checksum, molecule->numAtoms);
3278  NAMD_bug(errmsg);
3279  }
3280  // do we ever need this if we're on a GPU-based code?
3281  checksum = reduction->item(REDUCTION_COMPUTE_CHECKSUM);
3282 
3283  if ( ((int)checksum) && ((int)checksum) != computeChecksum ) {
3284  if ( ! computeChecksum ) {
3285  computesPartitioned = 0;
3286  } else if ( (int)checksum > computeChecksum && ! computesPartitioned ) {
3287  computesPartitioned = 1;
3288  } else {
3289  NAMD_bug("Bad global compute count!\n");
3290  }
3291  computeChecksum = ((int)checksum);
3292  }
3293  checksum_b = checksum = reduction->item(REDUCTION_BOND_CHECKSUM);
3294  if ( checksum_b && (((int)checksum) != molecule->numCalcBonds) ) {
3295  sprintf(errmsg, "Bad global bond count! (%d vs %d)\n",
3296  (int)checksum, molecule->numCalcBonds);
3297  if ( forgiving && (((int)checksum) < molecule->numCalcBonds) )
3298  iout << iWARN << errmsg << endi;
3299  else NAMD_bug(errmsg);
3300  }
3301 
3302  checksum = reduction->item(REDUCTION_ANGLE_CHECKSUM);
3303 
3304  if ( checksum_b && (((int)checksum) != molecule->numCalcAngles) ) {
3305  sprintf(errmsg, "Bad global angle count! (%d vs %d)\n",
3306  (int)checksum, molecule->numCalcAngles);
3307  if ( forgiving && (((int)checksum) < molecule->numCalcAngles) )
3308  iout << iWARN << errmsg << endi;
3309  else NAMD_bug(errmsg);
3310  }
3311  checksum = reduction->item(REDUCTION_DIHEDRAL_CHECKSUM);
3312  if ( checksum_b && (((int)checksum) != molecule->numCalcDihedrals) ) {
3313  sprintf(errmsg, "Bad global dihedral count! (%d vs %d)\n",
3314  (int)checksum, molecule->numCalcDihedrals);
3315  if ( forgiving && (((int)checksum) < molecule->numCalcDihedrals) )
3316  iout << iWARN << errmsg << endi;
3317  else NAMD_bug(errmsg);
3318  }
3319 
3320  checksum = reduction->item(REDUCTION_IMPROPER_CHECKSUM);
3321  if ( checksum_b && (((int)checksum) != molecule->numCalcImpropers) ) {
3322  sprintf(errmsg, "Bad global improper count! (%d vs %d)\n",
3323  (int)checksum, molecule->numCalcImpropers);
3324  if ( forgiving && (((int)checksum) < molecule->numCalcImpropers) )
3325  iout << iWARN << errmsg << endi;
3326  else NAMD_bug(errmsg);
3327  }
3328 
3329  checksum = reduction->item(REDUCTION_THOLE_CHECKSUM);
3330  if ( checksum_b && (((int)checksum) != molecule->numCalcTholes) ) {
3331  sprintf(errmsg, "Bad global Thole count! (%d vs %d)\n",
3332  (int)checksum, molecule->numCalcTholes);
3333  if ( forgiving && (((int)checksum) < molecule->numCalcTholes) )
3334  iout << iWARN << errmsg << endi;
3335  else NAMD_bug(errmsg);
3336  }
3337 
3338  checksum = reduction->item(REDUCTION_ANISO_CHECKSUM);
3339  if ( checksum_b && (((int)checksum) != molecule->numCalcAnisos) ) {
3340  sprintf(errmsg, "Bad global Aniso count! (%d vs %d)\n",
3341  (int)checksum, molecule->numCalcAnisos);
3342  if ( forgiving && (((int)checksum) < molecule->numCalcAnisos) )
3343  iout << iWARN << errmsg << endi;
3344  else NAMD_bug(errmsg);
3345  }
3346 
3347  checksum = reduction->item(REDUCTION_CROSSTERM_CHECKSUM);
3348  if ( checksum_b && (((int)checksum) != molecule->numCalcCrossterms) ) {
3349  sprintf(errmsg, "Bad global crossterm count! (%d vs %d)\n",
3350  (int)checksum, molecule->numCalcCrossterms);
3351  if ( forgiving && (((int)checksum) < molecule->numCalcCrossterms) )
3352  iout << iWARN << errmsg << endi;
3353  else NAMD_bug(errmsg);
3354  }
3355 
3356  checksum = reduction->item(REDUCTION_ONEFOURNBTHOLE_CHECKSUM);
3357  if ( checksum_b && (((int)checksum) != molecule->numCalcOneFourNbTholes) ) {
3358  sprintf(errmsg, "Bad global 1-4 NbThole count! (%d vs %d)\n",
3359  (int)checksum, molecule->numCalcOneFourNbTholes);
3360  if ( forgiving && (((int)checksum) < molecule->numCalcOneFourNbTholes) )
3361  iout << iWARN << errmsg << endi;
3362  else NAMD_bug(errmsg);
3363  }
3364 
3365  checksum = reduction->item(REDUCTION_EXCLUSION_CHECKSUM);
3366  if ( ((int64)checksum) > molecule->numCalcExclusions &&
3367  ( ! simParams->mollyOn || step % slowFreq ) ) {
3368  if ( forgiving )
3369  iout << iWARN << "High global exclusion count ("
3370  << ((int64)checksum) << " vs "
3371  << molecule->numCalcExclusions << "), possible error!\n"
3372  << iWARN << "This warning is not unusual during minimization.\n"
3373  << iWARN << "Decreasing pairlistdist or cutoff that is too close to periodic cell size may avoid this.\n" << endi;
3374  else {
3375  char errmsg[256];
3376  sprintf(errmsg, "High global exclusion count! (%lld vs %lld) System unstable or pairlistdist or cutoff too close to periodic cell size.\n",
3377  (long long)checksum, (long long)molecule->numCalcExclusions);
3378  NAMD_bug(errmsg);
3379  }
3380  }
3381 
3382  if ( ((int64)checksum) && ((int64)checksum) < molecule->numCalcExclusions &&
3384  if ( forgiving || ! simParams->fullElectFrequency ) {
3385  iout << iWARN << "Low global exclusion count! ("
3386  << ((int64)checksum) << " vs " << molecule->numCalcExclusions << ")";
3387  if ( forgiving ) {
3388  iout << "\n"
3389  << iWARN << "This warning is not unusual during minimization.\n"
3390  << iWARN << "Increasing pairlistdist or cutoff may avoid this.\n";
3391  } else {
3392  iout << " System unstable or pairlistdist or cutoff too small.\n";
3393  }
3394  iout << endi;
3395  } else {
3396  char errmsg[256];
3397  sprintf(errmsg, "Low global exclusion count! (%lld vs %lld) System unstable or pairlistdist or cutoff too small.\n",
3398  (long long)checksum, (long long)molecule->numCalcExclusions);
3399  NAMD_bug(errmsg);
3400  }
3401  }
3402 
3403 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
3404  checksum = reduction->item(REDUCTION_EXCLUSION_CHECKSUM_CUDA);
3405  if ( ((int64)checksum) > molecule->numCalcFullExclusions &&
3406  ( ! simParams->mollyOn || step % slowFreq ) ) {
3407  if ( forgiving )
3408  iout << iWARN << "High global CUDA exclusion count ("
3409  << ((int64)checksum) << " vs "
3410  << molecule->numCalcFullExclusions << "), possible error!\n"
3411  << iWARN << "This warning is not unusual during minimization.\n"
3412  << iWARN << "Decreasing pairlistdist or cutoff that is too close to periodic cell size may avoid this.\n" << endi;
3413  else {
3414  char errmsg[256];
3415  sprintf(errmsg, "High global CUDA exclusion count! (%lld vs %lld) System unstable or pairlistdist or cutoff too close to periodic cell size.\n",
3416  (long long)checksum, (long long)molecule->numCalcFullExclusions);
3417  NAMD_bug(errmsg);
3418  }
3419  }
3420 
3421  if ( ((int64)checksum) && ((int64)checksum) < molecule->numCalcFullExclusions &&
3423  if ( forgiving || ! simParams->fullElectFrequency ) {
3424  iout << iWARN << "Low global CUDA exclusion count! ("
3425  << ((int64)checksum) << " vs " << molecule->numCalcFullExclusions << ") on step " << step;
3426  if ( forgiving ) {
3427  iout << "\n"
3428  << iWARN << "This warning is not unusual during minimization.\n"
3429  << iWARN << "Increasing pairlistdist or cutoff may avoid this.\n";
3430  } else {
3431  iout << " System unstable or pairlistdist or cutoff too small.\n";
3432  }
3433  iout << endi;
3434  } else {
3435  char errmsg[256];
3436  sprintf(errmsg, "Low global CUDA exclusion count! (%lld vs %lld) System unstable or pairlistdist or cutoff too small.\n",
3437  (long long)checksum, (long long)molecule->numCalcFullExclusions);
3438  NAMD_bug(errmsg);
3439  }
3440  }
3441 #endif
3442 
3443  checksum = reduction->item(REDUCTION_MARGIN_VIOLATIONS);
3444  if ( ((int)checksum) && ! marginViolations ) {
3445  iout << iERROR << "Margin is too small for " << ((int)checksum) <<
3446  " atoms during timestep " << step << ".\n" << iERROR <<
3447  "Incorrect nonbonded forces and energies may be calculated!\n" << endi;
3448  }
3449  marginViolations += (int)checksum;
3450 
3451  checksum = reduction->item(REDUCTION_PAIRLIST_WARNINGS);
3452  if ( simParams->outputPairlists && ((int)checksum) && ! pairlistWarnings ) {
3453  iout << iINFO <<
3454  "Pairlistdist is too small for " << ((int)checksum) <<
3455  " computes during timestep " << step << ".\n" << endi;
3456  }
3457  if ( simParams->outputPairlists ) pairlistWarnings += (int)checksum;
3458 
3459  checksum = reduction->item(REDUCTION_STRAY_CHARGE_ERRORS);
3460  if ( checksum ) {
3461  if ( forgiving )
3462  iout << iWARN << "Stray PME grid charges ignored!\n" << endi;
3463  else NAMD_bug("Stray PME grid charges detected!\n");
3464  }
3465 }
3466 
3467 void Controller::printTiming(int step) {
3468 
3469  if ( simParams->outputTiming && ! ( step % simParams->outputTiming ) )
3470  {
3471  const double endWTime = namdWallTimer() - firstWTime;
3472  const double endCTime = CmiTimer() - firstCTime;
3473 
3474  // fflush about once per minute
3475  if ( (((int)endWTime)>>6) != (((int)startWTime)>>6 ) ) fflush_count = 2;
3476 
3477  const double elapsedW =
3478  (endWTime - startWTime) / simParams->outputTiming;
3479  const double elapsedC =
3480  (endCTime - startCTime) / simParams->outputTiming;
3481 
3482  const double remainingW = elapsedW * (simParams->N - step);
3483  const double remainingW_hours = remainingW / 3600;
3484 
3485  startWTime = endWTime;
3486  startCTime = endCTime;
3487 
3488 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
3489  if ( simParams->computeEnergies < 60 &&
3490  step < (simParams->firstTimestep + 10 * simParams->outputTiming) ) {
3491  iout << iWARN << "Energy evaluation is expensive, increase computeEnergies to improve performance.\n" << endi;
3492  iout << iWARN << "If computeEnergies is not defined, its value defaults to the same as outputEnergies, and increasing outputEnergies would be helpful to improve the performance.\n" << endi;
3493  }
3494 #endif
3495  if ( step >= (simParams->firstTimestep + simParams->outputTiming) ) {
3496  if (simParams->nsPerDayOn) {
3497  BigReal ns = simParams->dt / 1000000.0;
3498  BigReal days = 1.0 / (24.0 * 60.0 * 60.0);
3499  BigReal nsPerDay = ns / (elapsedW * days);
3500  CmiPrintf("TIMING: %d CPU: %g, %g/step Wall: %g, %g/step"
3501  ", %g ns/days"
3502  ", %g hours remaining, %f MB of memory in use.\n",
3503  step, endCTime, elapsedC, endWTime, elapsedW,
3504  nsPerDay,
3505  remainingW_hours, memusage_MB());
3506  }
3507  else {
3508  CmiPrintf("TIMING: %d CPU: %g, %g/step Wall: %g, %g/step"
3509  ", %g hours remaining, %f MB of memory in use.\n",
3510  step, endCTime, elapsedC, endWTime, elapsedW,
3511  remainingW_hours, memusage_MB());
3512  }
3514  // calculate running average and sample variance of
3515  // the measured time per step (elapsedW)
3516  perfstats.add_sample(elapsedW);
3517  double t_avg = perfstats.average();
3518  double t_std = perfstats.standard_deviation();
3519  // convert t_avg to average number of nanoseconds simulated per day
3520  double ns_per_day = (simParams->dt / t_avg) * (60 * 60 * 24 * 1e-6);
3521  CmiPrintf("PERFORMANCE: %d averaging %g ns/day, %g sec/step with"
3522  " standard deviation %g\n", step, ns_per_day, t_avg, t_std);
3523  }
3524  if ( fflush_count ) { --fflush_count; fflush(stdout); }
3525  double benchmarkTime = (double) simParams->benchmarkTime;
3526  if (benchmarkTime > 0 && benchmarkTime <= endWTime) {
3527  // terminate NAMD benchmark
3528  char s[100];
3529  sprintf(s, "Exceeded benchmark time limit %g seconds",
3530  benchmarkTime);
3531  NAMD_quit(s);
3532  }
3533  }
3534  }
3535 }
3536 
3538 
3539  rescaleaccelMD(step,1);
3540  receivePressure(step,1);
3541  RequireReduction* reduction = getCurrentReduction();
3542 
3543  Node *node = Node::Object();
3544  Molecule *molecule = node->molecule;
3545  compareChecksums(step,1);
3546 
3547  printEnergies(step,1);
3548 
3550  min_f_dot_f = reduction->item(REDUCTION_MIN_F_DOT_F);
3551  min_f_dot_v = reduction->item(REDUCTION_MIN_F_DOT_V);
3552  min_v_dot_v = reduction->item(REDUCTION_MIN_V_DOT_V);
3553  min_huge_count = (int) (reduction->item(REDUCTION_MIN_HUGE_COUNT));
3554 
3555 #ifdef DEBUG_MINIMIZE
3556  printf("%s, line %d\n", __FILE__, __LINE__);
3557  printf("Step %d:\n", step);
3558  printf(" min_energy = %f\n", min_energy);
3559  printf(" min_f_dot_f = %f\n", min_f_dot_f);
3560  printf(" min_f_dot_v = %f\n", min_f_dot_v);
3561  printf(" min_v_dot_v = %f\n", min_v_dot_v);
3562  printf(" min_huge_count = %d\n", min_huge_count);
3563  printf("\n");
3564 #endif
3565 }
3566 
3568  compareChecksums(step);
3569  printEnergies(step,0);
3570 }
3571 
3573 {
3574  compareChecksums(step, 0);
3575 
3576  Node *node = Node::Object();
3577  Molecule *molecule = node->molecule;
3578  Lattice &lattice = state->lattice;
3579  BigReal volume = lattice.volume();
3580  // store total energy
3581  BigReal totalPotentialEnergy = 0.0;
3582  BigReal bondEnergy, angleEnergy, dihedralEnergy;
3583  BigReal improperEnergy, crosstermEnergy;
3585  BigReal miscEnergy, bcEnergy;
3586  bool cudaIntegrator = simParams->CUDASOAintegrate;
3587  RequireReduction* reduction = getCurrentReduction();
3588 
3589  bondEnergy = reduction->item(REDUCTION_BOND_ENERGY);
3590  angleEnergy = reduction->item(REDUCTION_ANGLE_ENERGY);
3591  dihedralEnergy = reduction->item(REDUCTION_DIHEDRAL_ENERGY);
3592  improperEnergy = reduction->item(REDUCTION_IMPROPER_ENERGY);
3593  crosstermEnergy = reduction->item(REDUCTION_CROSSTERM_ENERGY);
3594  bcEnergy = reduction->item(REDUCTION_BC_ENERGY);
3595  miscEnergy = reduction->item(REDUCTION_MISC_ENERGY);
3596 
3597  totalPotentialEnergy += bondEnergy + angleEnergy + dihedralEnergy +
3598  improperEnergy + crosstermEnergy + miscEnergy
3599  + bcEnergy;
3600 
3601  if (! ( step % nbondFreq ))
3602  {
3603  electEnergy = reduction->item(REDUCTION_ELECT_ENERGY);
3604  ljEnergy = reduction->item(REDUCTION_LJ_ENERGY);
3605  totalPotentialEnergy += electEnergy + ljEnergy;
3606  }
3607 
3608  if (! ( step % slowFreq ))
3609  {
3612  totalPotentialEnergy += electEnergySlow;
3613  totalPotentialEnergy += ljEnergySlow;
3614  }
3615 
3616  if (simParams->LJcorrection && volume) {
3617 #ifdef MEM_OPT_VERSION
3618  NAMD_bug("LJcorrection not supported in memory optimized build.");
3619 #else
3620  // Apply tail correction to energy.
3621  BigReal alchLambda = simParams->getCurrentLambda(step);
3622  totalPotentialEnergy += molecule->getEnergyTailCorr(alchLambda, 0) / volume;
3623 #endif
3624  }
3625 
3626  #if 0
3627  printf("MC-data (TotalPotentialEnergy): step: %d, Pe: %d, Bond: %f, Angle: %f, Dih: %f, IMP: %f, Cross: %f\n",
3628  step, CkMyPe(), bondEnergy, angleEnergy, dihedralEnergy, improperEnergy, crosstermEnergy);
3629  printf("MC-data (TotalPotentialEnergy): step: %d, Pe: %d, LJ: %f, Real: %f, Recip: %f\n", step, CkMyPe(),
3631  printf("MC-data (TotalPotentialEnergy): step: %d, Pe: %d, MISC: %f, BC: %f, TOTAL: %f\n", step, CkMyPe(),
3632  miscEnergy, bcEnergy, totalPotentialEnergy);
3633  #endif
3634 
3635  return totalPotentialEnergy;
3636 }
3637 
3638 
3639 void Controller::printEnergies(int step, int minimize)
3640 {
3641  Node *node = Node::Object();
3642  Molecule *molecule = node->molecule;
3643  Lattice &lattice = state->lattice;
3644  bool cudaIntegrator = simParams->CUDASOAintegrate;
3645  RequireReduction* reduction = getCurrentReduction();
3646 
3647  // Drude model ANISO energy is added into BOND energy
3648  // and THOLE energy is added into ELECT energy
3649 
3650  BigReal bondEnergy;
3651  BigReal angleEnergy;
3652  BigReal dihedralEnergy;
3653  BigReal improperEnergy;
3654  BigReal crosstermEnergy;
3655  BigReal boundaryEnergy;
3656  BigReal miscEnergy;
3657  BigReal potentialEnergy;
3658  BigReal flatEnergy;
3659  BigReal smoothEnergy;
3660  BigReal work;
3661 
3662  Vector momentum;
3663  Vector angularMomentum;
3664  BigReal volume = lattice.volume();
3665  bondEnergy = reduction->item(REDUCTION_BOND_ENERGY);
3666  angleEnergy = reduction->item(REDUCTION_ANGLE_ENERGY);
3667  dihedralEnergy = reduction->item(REDUCTION_DIHEDRAL_ENERGY);
3668  improperEnergy = reduction->item(REDUCTION_IMPROPER_ENERGY);
3669  crosstermEnergy = reduction->item(REDUCTION_CROSSTERM_ENERGY);
3670  boundaryEnergy = reduction->item(REDUCTION_BC_ENERGY);
3671  miscEnergy = reduction->item(REDUCTION_MISC_ENERGY);
3672 
3673  if ( minimize || ! ( step % nbondFreq ) )
3674  {
3675  electEnergy = reduction->item(REDUCTION_ELECT_ENERGY);
3676  ljEnergy = reduction->item(REDUCTION_LJ_ENERGY);
3677 
3678  // JLai
3681 
3685 
3686  //fepb
3689  ljEnergy_f = reduction->item(REDUCTION_LJ_ENERGY_F);
3690 
3697 //fepe
3698  }
3699 
3700  if ( minimize || ! ( step % slowFreq ) )
3701  {
3704 //fepb
3706 
3711 //fepe
3712  }
3713 
3714  if ((simParams->LJcorrection || simParams->LJcorrectionAlt) && volume) {
3715 #ifdef MEM_OPT_VERSION
3716  NAMD_bug("LJcorrection not supported in memory optimized build.");
3717 #else
3718  // Apply tail correction to energy.
3719  BigReal alchLambda = simParams->getCurrentLambda(step);
3720  ljEnergy += molecule->getEnergyTailCorr(alchLambda, 0) / volume;
3721 
3722  if (simParams->alchOn) {
3723  if (simParams->alchFepOn) {
3724  BigReal alchLambda2 = simParams->getCurrentLambda2(step);
3725  ljEnergy_f += molecule->getEnergyTailCorr(alchLambda2, 0) / volume;
3726  } else if (simParams->alchThermIntOn) {
3727  ljEnergy_ti_1 += molecule->getEnergyTailCorr(1.0, 1) / volume;
3728  ljEnergy_ti_2 += molecule->getEnergyTailCorr(0.0, 1) / volume;
3729  }
3730  }
3731 #endif
3732  }
3733 
3734 //fepb BKR - Compute alchemical work if using dynamic lambda. This is here so
3735 // that the cumulative work can be given during a callback.
3736  if (simParams->alchLambdaFreq > 0) {
3737  if (step <=
3739  cumAlchWork = 0.0;
3740  }
3741  alchWork = computeAlchWork(step);
3742  cumAlchWork += alchWork;
3743  }
3744 //fepe
3745  momentum.x = reduction->item(REDUCTION_MOMENTUM_X);
3746  momentum.y = reduction->item(REDUCTION_MOMENTUM_Y);
3747  momentum.z = reduction->item(REDUCTION_MOMENTUM_Z);
3748  angularMomentum.x = reduction->item(REDUCTION_ANGULAR_MOMENTUM_X);
3749  angularMomentum.y = reduction->item(REDUCTION_ANGULAR_MOMENTUM_Y);
3750  angularMomentum.z = reduction->item(REDUCTION_ANGULAR_MOMENTUM_Z);
3751 
3752  // Ported by JLai
3753  potentialEnergy = (bondEnergy + angleEnergy + dihedralEnergy
3754  + improperEnergy + electEnergy + electEnergySlow
3756  + crosstermEnergy + boundaryEnergy + miscEnergy + goTotalEnergy
3758  // End of port
3759  totalEnergy = potentialEnergy + kineticEnergy;
3760  if ( ! cudaIntegrator) {
3761  flatEnergy = (totalEnergy
3763  if ( !(step%slowFreq) ) {
3764  // only adjust based on most accurate energies
3766  if ( smooth2_avg == XXXBIGREAL ) smooth2_avg = s;
3767  if ( step != simParams->firstTimestep ) {
3768  smooth2_avg *= 0.9375;
3769  smooth2_avg += 0.0625 * s;
3770  }
3771  }
3772  smoothEnergy = (flatEnergy + smooth2_avg
3774  }
3775 
3776  // Reset values for accumulated heat and work.
3777  if (step <= simParams->firstTimestep &&
3779  heat = 0.0;
3781  }
3782  if ( simParams->outputMomenta && ! minimize &&
3783  ! ( step % simParams->outputMomenta ) )
3784  {
3785  iout << "MOMENTUM: " << step
3786  << " P: " << momentum
3787  << " L: " << angularMomentum
3788  << "\n" << endi;
3789  }
3790 
3791  if ( simParams->outputPressure ) {
3792  if ( ! cudaIntegrator ) {
3795  }
3796  tavg_count += 1;
3797  if ( minimize || ! ( step % simParams->outputPressure ) ) {
3798  if (cudaIntegrator) {
3799  // tensors are valid for outputPressure step
3800  // update averages, then copy into tensor for output
3834  iout << "PRESSURE: " << step << " "
3835  << PRESSUREFACTOR * pressure << "\n"
3836  << "GPRESSURE: " << step << " "
3837  << PRESSUREFACTOR * groupPressure << "\n";
3838  // tavg_count makes output behaves the same as for standard case
3839  // but is no longer part of the average
3840  if ( tavg_count > 1 ) iout << "PRESSAVG: " << step << " "
3841  << (PRESSUREFACTOR) * pressure_tavg << "\n"
3842  << "GPRESSAVG: " << step << " "
3843  << (PRESSUREFACTOR) * groupPressure_tavg << "\n";
3844  iout << endi;
3845  tavg_count = 0;
3846  }
3847  else {
3848  iout << "PRESSURE: " << step << " "
3849  << PRESSUREFACTOR * pressure << "\n"
3850  << "GPRESSURE: " << step << " "
3851  << PRESSUREFACTOR * groupPressure << "\n";
3852  if ( tavg_count > 1 ) iout << "PRESSAVG: " << step << " "
3853  << (PRESSUREFACTOR/tavg_count) * pressure_tavg << "\n"
3854  << "GPRESSAVG: " << step << " "
3856  iout << endi;
3857  pressure_tavg = 0;
3858  groupPressure_tavg = 0;
3859  tavg_count = 0;
3860  }
3861  }
3862  }
3863 
3864  // pressure profile reductions
3865  if (pressureProfileSlabs) {
3866  const int freq = simParams->pressureProfileFreq;
3867  const int arraysize = 3*pressureProfileSlabs;
3868 
3869  BigReal *total = new BigReal[arraysize];
3870  memset(total, 0, arraysize*sizeof(BigReal));
3871  const int first = simParams->firstTimestep;
3872 
3873  if (ppbonded) ppbonded->getData(first, step, lattice, total);
3874  if (ppnonbonded) ppnonbonded->getData(first, step, lattice, total);
3875  if (ppint) ppint->getData(first, step, lattice, total);
3876  for (int i=0; i<arraysize; i++) pressureProfileAverage[i] += total[i];
3878 
3879  if (!(step % freq)) {
3880  // convert NAMD internal virial to pressure in units of bar
3882 
3883  iout << "PRESSUREPROFILE: " << step << " ";
3884  if (step == first) {
3885  // output pressure profile for this step
3886  for (int i=0; i<arraysize; i++) {
3887  iout << total[i] * scalefac << " ";
3888  }
3889  } else {
3890  // output pressure profile averaged over the last count steps.
3891  scalefac /= pressureProfileCount;
3892  for (int i=0; i<arraysize; i++)
3893  iout << pressureProfileAverage[i]*scalefac << " ";
3894  }
3895  iout << "\n" << endi;
3896 
3897  // Clear the average for the next block
3898  memset(pressureProfileAverage, 0, arraysize*sizeof(BigReal));
3900  }
3901  delete [] total;
3902  }
3903 
3904  if ( step != simParams->firstTimestep || stepInFullRun == 0 ) { // skip repeated first step
3905  if ( stepInFullRun % simParams->firstLdbStep == 0 ) {
3906  int benchPhase = stepInFullRun / simParams->firstLdbStep;
3907  if ( benchPhase > 0 && benchPhase < 10 ) {
3908 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
3909  if ( simParams->computeEnergies < 60 ) {
3910  iout << iWARN << "Energy evaluation is expensive, increase computeEnergies to improve performance.\n";
3911  iout << iWARN << "If computeEnergies is not defined, its value defaults to the same as outputEnergies, and increasing outputEnergies would be helpful to improve the performance.\n";
3912  }
3913 #endif
3914  iout << iINFO;
3915  if ( benchPhase < 4 ) iout << "Initial time: ";
3916  else iout << "Benchmark time: ";
3917  iout << CkNumPes() << " CPUs ";
3918 
3919  {
3920  BigReal wallPerStep =
3921  (namdWallTimer() - startBenchTime) / simParams->firstLdbStep;
3922  BigReal ns = simParams->dt / 1000000.0;
3923  BigReal days = 1.0 / (24.0 * 60.0 * 60.0);
3924 
3925  if (simParams->nsPerDayOn) {
3926  BigReal nsPerDay = ns / (wallPerStep * days);
3927  iout << wallPerStep << " s/step " << nsPerDay << " ns/day ";
3928  }
3929  else {
3930  BigReal daysPerNano = wallPerStep * days / ns;
3931  iout << wallPerStep << " s/step " << daysPerNano << " days/ns ";
3932  }
3933  iout << memusage_MB() << " MB memory\n" << endi;
3934  }
3935 
3936  }
3937  startBenchTime = namdWallTimer();
3938  }
3939  ++stepInFullRun;
3940  }
3941 
3942  printTiming(step);
3943 
3944  Vector pairVDWForce, pairElectForce;
3945  if ( simParams->pairInteractionOn ){
3946  GET_VECTOR(pairVDWForce,reduction,REDUCTION_PAIR_VDW_FORCE);
3947  GET_VECTOR(pairElectForce,reduction,REDUCTION_PAIR_ELECT_FORCE);
3948  }
3949 
3950  // Compute cumulative nonequilibrium work (including shadow work).
3952  work = totalEnergy - totalEnergy0 - heat;
3953  }
3954 
3955  // callback to Tcl with whatever we can
3956 #ifdef NAMD_TCL
3957 #define CALLBACKDATA(LABEL,VALUE) \
3958  labels << (LABEL) << " "; values << (VALUE) << " ";
3959 #define CALLBACKLIST(LABEL,VALUE) \
3960  labels << (LABEL) << " "; values << "{" << (VALUE) << "} ";
3961  if (step == simParams->N && node->getScript() && node->getScript()->doCallback()) {
3962 
3963  std::ostringstream labels, values;
3964 #if CMK_BLUEGENEL
3965  // the normal version below gives a compiler error
3966  values.precision(16);
3967 #else
3968  values << std::setprecision(16);
3969 #endif
3970  CALLBACKDATA("TS",step);
3971  CALLBACKDATA("BOND",bondEnergy);
3972  CALLBACKDATA("ANGLE",angleEnergy);
3973  CALLBACKDATA("DIHED",dihedralEnergy);
3974  CALLBACKDATA("CROSS",crosstermEnergy);
3975  CALLBACKDATA("IMPRP",improperEnergy);
3978  CALLBACKDATA("BOUNDARY",boundaryEnergy);
3979  CALLBACKDATA("MISC",miscEnergy);
3980  CALLBACKDATA("POTENTIAL",potentialEnergy);
3981  CALLBACKDATA("KINETIC",kineticEnergy);
3982  CALLBACKDATA("TOTAL",totalEnergy);
3983  CALLBACKDATA("TEMP",temperature);
3984  CALLBACKLIST("PRESSURE",pressure*PRESSUREFACTOR);
3986  CALLBACKDATA("VOLUME",lattice.volume());
3987  CALLBACKLIST("CELL_A",lattice.a());
3988  CALLBACKLIST("CELL_B",lattice.b());
3989  CALLBACKLIST("CELL_C",lattice.c());
3990  CALLBACKLIST("CELL_O",lattice.origin());
3991  labels << "PERIODIC "; values << "{" << lattice.a_p() << " "
3992  << lattice.b_p() << " " << lattice.c_p() << "} ";
3993  if (simParams->drudeOn) {
3994  CALLBACKDATA("DRUDEBOND",drudeBondTemp);
3995  }
3996  if ( simParams->pairInteractionOn ) {
3997  CALLBACKLIST("VDW_FORCE",pairVDWForce);
3998  CALLBACKLIST("ELECT_FORCE",pairElectForce);
3999  }
4001  CALLBACKLIST("HEAT",heat);
4002  CALLBACKLIST("WORK",work);
4003  }
4004  if (simParams->alchOn) {
4005  if (simParams->alchThermIntOn) {
4006  CALLBACKLIST("BOND1", bondedEnergy_ti_1);
4009  CALLBACKLIST("VDW1", ljEnergy_ti_1);
4010  CALLBACKLIST("BOND2", bondedEnergy_ti_2);
4013  CALLBACKLIST("VDW2", ljEnergy_ti_2);
4014  if (simParams->alchLambdaFreq > 0) {
4015  CALLBACKLIST("CUMALCHWORK", cumAlchWork);
4016  }
4017  } else if (simParams->alchFepOn) {
4018  CALLBACKLIST("BOND2", bondEnergy + angleEnergy + dihedralEnergy +
4019  improperEnergy + bondedEnergyDiff_f);
4021  CALLBACKLIST("VDW2", ljEnergy_f);
4022  }
4023  }
4024 
4025  labels << '\0'; values << '\0'; // insane but makes Linux work
4026  state->callback_labelstring = labels.str();
4027  state->callback_valuestring = values.str();
4028  // node->getScript()->doCallback(labelstring.c_str(),valuestring.c_str());
4029  }
4030 #undef CALLBACKDATA
4031 #endif
4032 
4033  if ( ! cudaIntegrator) {
4035  temp_avg += temperature;
4036  pressure_avg += trace(pressure)/3.;
4037  groupPressure_avg += trace(groupPressure)/3.;
4038  avg_count += 1;
4039  }
4040 
4042  ! (step % simParams->outputPairlists) ) {
4043  iout << iINFO << pairlistWarnings <<
4044  " pairlist warnings in past " << simParams->outputPairlists <<
4045  " steps.\n" << endi;
4046  pairlistWarnings = 0;
4047  }
4048 
4049  BigReal enthalpy;
4050  if (simParams->multigratorOn && ((step % simParams->computeEnergies) == 0)) {
4051  enthalpy = multigatorCalcEnthalpy(potentialEnergy, step, minimize);
4052  }
4053 
4054  if (simParams->IMDon) {
4055  IMDOutput *imd = NULL;
4056 #ifdef NODEGROUP_FORCE_REGISTER
4057  if (simParams->CUDASOAintegrate) {
4058  CProxy_PatchData cpdata(CkpvAccess(BOCclass_group).patchData);
4059  imd = cpdata.ckLocalBranch()->imd;
4060  } else
4061 #endif
4062  {
4063  imd = Node::Object()->imd;
4064  }
4065  if ( !(step % simParams->IMDfreq) &&
4068  && (step != simParams->firstTimestep)) ) {
4069 
4070  IMDTime time = {simParams->dt * 0.001, simParams->dt * 0.001 * step, step}; // convert to ps
4071 
4072  if (imd != NULL) imd->gather_time(&time);
4073  }
4074 
4075  if (!(step % simParams->IMDfreq) && ((simParams->IMDversion == IMDversion_t::IMDv2) ||
4077  IMDEnergies energies;
4078  energies.tstep = step;
4079  energies.T = temp_avg/avg_count;
4080  energies.Etot = totalEnergy;
4081  energies.Epot = potentialEnergy;
4082  energies.Evdw = ljEnergy + ljEnergySlow;
4083  energies.Eelec = electEnergy + electEnergySlow;
4084  energies.Ebond = bondEnergy;
4085  energies.Eangle = angleEnergy;
4086  energies.Edihe = dihedralEnergy + crosstermEnergy;
4087  energies.Eimpr = improperEnergy;
4088  if (imd != NULL) imd->gather_energies(&energies);
4089  }
4090 
4091  if (!simParams->CUDASOAintegrate &&
4093  !(step % simParams->IMDfreq) &&
4095  (step != simParams->firstTimestep)) {
4097  }
4098  }
4099  // XXX
4100  // Important note: in CPU-only/GPU-offload modes
4101  // printEnergies is called EVERY STEP.
4102  // Reduction averages are summed above and then later are output
4103  // divided by count. Sums and counter are reset after printing.
4104  // XXX
4105  // NO CALCULATIONS OR REDUCTIONS BEYOND THIS POINT!!!
4106  if ( ! minimize && step % simParams->outputEnergies ) return;
4107 
4108  if (cudaIntegrator) {
4111  pressureAverage.addSample((1./3)*trace(pressure));
4113  }
4114 
4115  // ONLY OUTPUT SHOULD OCCUR BELOW THIS LINE!!!
4116 
4117  if ( marginViolations ) {
4118  iout << iERROR << marginViolations <<
4119  " margin violations detected since previous energy output.\n" << endi;
4120  }
4121  marginViolations = 0;
4122 
4123  int precision = simParams->outputEnergiesPrecision;
4124  if ( (step % (10 * (minimize?1:simParams->outputEnergies) ) ) == 0 )
4125  {
4126  iout << "ETITLE: TS";
4127  iout << FORMAT("BOND", precision);
4128  iout << FORMAT("ANGLE", precision);
4129  iout << FORMAT("DIHED", precision);
4130  if ( ! simParams->mergeCrossterms ) iout << FORMAT("CROSS", precision);
4131  iout << FORMAT("IMPRP", precision);
4132  iout << " ";
4133  iout << FORMAT("ELECT", precision);
4134  iout << FORMAT("VDW", precision);
4135  iout << FORMAT("BOUNDARY", precision);
4136  iout << FORMAT("MISC", precision);
4137  iout << FORMAT("KINETIC", precision);
4138  iout << " ";
4139  iout << FORMAT("TOTAL", precision);
4140  iout << FORMAT("TEMP", precision);
4141  iout << FORMAT("POTENTIAL", precision);
4142  if (cudaIntegrator) {
4143  iout << FORMAT("TOTALAVG", precision);
4144  }
4145  else {
4146  // iout << FORMAT("TOTAL2", precision);
4147  iout << FORMAT("TOTAL3", precision);
4148  }
4149  iout << FORMAT("TEMPAVG", precision);
4150  if ( volume != 0. ) {
4151  iout << " ";
4152  iout << FORMAT("PRESSURE", precision);
4153  iout << FORMAT("GPRESSURE", precision);
4154  iout << FORMAT("VOLUME", precision);
4155  iout << FORMAT("PRESSAVG", precision);
4156  iout << FORMAT("GPRESSAVG", precision);
4157  }
4159  iout << " ";
4160  iout << FORMAT("HEAT", precision);
4161  iout << FORMAT("WORK", precision);
4162  }
4163  if (simParams->drudeOn) {
4164  iout << " ";
4165  iout << FORMAT("DRUDEBOND", precision);
4166  iout << FORMAT("DRBONDAVG", precision);
4167  }
4168  // Ported by JLai
4169  if (simParams->goGroPair) {
4170  iout << " ";
4171  iout << FORMAT("GRO_PAIR_LJ", precision);
4172  iout << FORMAT("GRO_PAIR_GAUSS", precision);
4173  }
4174 
4175  if (simParams->goForcesOn) {
4176  iout << " ";
4177  iout << FORMAT("NATIVE", precision);
4178  iout << FORMAT("NONNATIVE", precision);
4179  //iout << FORMAT("REL_NATIVE", precision);
4180  //iout << FORMAT("REL_NONNATIVE", precision);
4181  iout << FORMAT("GOTOTAL", precision);
4182  //iout << FORMAT("GOAVG", precision);
4183  }
4184  // End of port -- JLai
4185 
4186  if (simParams->alchOn) {
4187  if (simParams->alchThermIntOn) {
4188  iout << "\nTITITLE: TS";
4189  iout << FORMAT("BOND1", precision);
4190  iout << FORMAT("ELECT1", precision);
4191  iout << FORMAT("VDW1", precision);
4192  iout << FORMAT("BOND2", precision);
4193  iout << " ";
4194  iout << FORMAT("ELECT2", precision);
4195  iout << FORMAT("VDW2", precision);
4196  if (simParams->alchLambdaFreq > 0) {
4197  iout << FORMAT("LAMBDA", precision);
4198  iout << FORMAT("ALCHWORK", precision);
4199  iout << FORMAT("CUMALCHWORK", precision);
4200  }
4201  } else if (simParams->alchFepOn) {
4202  iout << "\nFEPTITLE: TS";
4203  iout << FORMAT("BOND2", precision);
4204  iout << FORMAT("ELECT2", precision);
4205  iout << FORMAT("VDW2", precision);
4206  if (simParams->alchLambdaFreq > 0) {
4207  iout << FORMAT("LAMBDA", precision);
4208  }
4209  }
4210  }
4211 
4212  iout << "\n\n" << endi;
4213 
4214  if (simParams->qmForcesOn) {
4215  iout << "QMETITLE: TS";
4216  iout << FORMAT("QMID", precision);
4217  iout << FORMAT("ENERGY", precision);
4218  if (simParams->PMEOn) iout << FORMAT("PMECORRENERGY", precision);
4219  iout << "\n\n" << endi;
4220  }
4221 
4222  }
4223 
4224  // N.B. HP's aCC compiler merges FORMAT calls in the same expression.
4225  // Need separate statements because data returned in static array.
4226  iout << ETITLE(step);
4227  iout << FORMAT(bondEnergy, precision);
4228  iout << FORMAT(angleEnergy, precision);
4229  if ( simParams->mergeCrossterms ) {
4230  iout << FORMAT(dihedralEnergy+crosstermEnergy, precision);
4231  } else {
4232  iout << FORMAT(dihedralEnergy, precision);
4233  iout << FORMAT(crosstermEnergy, precision);
4234  }
4235  iout << FORMAT(improperEnergy, precision);
4236  iout << " ";
4237  iout << FORMAT(electEnergy+electEnergySlow, precision);
4238  iout << FORMAT(ljEnergy+ljEnergySlow, precision);
4239  iout << FORMAT(boundaryEnergy, precision);
4240  iout << FORMAT(miscEnergy, precision);
4241  iout << FORMAT(kineticEnergy, precision);
4242  iout << " ";
4243  iout << FORMAT(totalEnergy, precision);
4244  iout << FORMAT(temperature, precision);
4245  iout << FORMAT(potentialEnergy, precision);
4246  if (cudaIntegrator) {
4247  iout << FORMAT(totalEnergyAverage.average(), precision);
4248  iout << FORMAT(temperatureAverage.average(), precision);
4249  }
4250  else {
4251  // iout << FORMAT(flatEnergy, precision);
4252  iout << FORMAT(smoothEnergy, precision);
4253  iout << FORMAT(temp_avg/avg_count, precision);
4254  }
4255  if ( volume != 0. )
4256  {
4257  iout << " ";
4258  iout << FORMAT(trace(pressure)*PRESSUREFACTOR/3., precision);
4259  iout << FORMAT(trace(groupPressure)*PRESSUREFACTOR/3., precision);
4260  iout << FORMAT(volume, precision);
4261  if (cudaIntegrator) {
4264  }
4265  else {
4268  }
4269  }
4271  iout << " ";
4272  iout << FORMAT(heat, precision);
4273  iout << FORMAT(work, precision);
4274  }
4275  if (simParams->drudeOn) {
4276  iout << " ";
4277  iout << FORMAT(drudeBondTemp, precision);
4278  iout << FORMAT(drudeBondTempAvg/avg_count, precision);
4279  }
4280  // Ported by JLai
4281  if (simParams->goGroPair) {
4282  iout << " ";
4283  iout << FORMAT(groLJEnergy, precision);
4284  iout << FORMAT(groGaussEnergy, precision);
4285  }
4286 
4287  if (simParams->goForcesOn) {
4288  iout << " ";
4289  iout << FORMAT(goNativeEnergy, precision);
4290  iout << FORMAT(goNonnativeEnergy, precision);
4291  //iout << FORMAT(relgoNativeEnergy, precision);
4292  //iout << FORMAT(relgoNonnativeEnergy, precision);
4293  iout << FORMAT(goTotalEnergy, precision);
4294  //iout << FORMAT("not implemented", precision);
4295  } // End of port -- JLai
4296 
4297  if (simParams->alchOn) {
4298  if (simParams->alchThermIntOn) {
4299  iout << "\n";
4300  iout << TITITLE(step);
4301  iout << FORMAT(bondedEnergy_ti_1, precision);
4303  electEnergyPME_ti_1, precision);
4304  iout << FORMAT(ljEnergy_ti_1, precision);
4305  iout << FORMAT(bondedEnergy_ti_2, precision);
4306  iout << " ";
4308  electEnergyPME_ti_2, precision);
4309  iout << FORMAT(ljEnergy_ti_2, precision);
4310  if (simParams->alchLambdaFreq > 0) {
4311  iout << FORMAT(simParams->getCurrentLambda(step), precision);
4312  iout << FORMAT(alchWork, precision);
4313  iout << FORMAT(cumAlchWork, precision);
4314  }
4315  } else if (simParams->alchFepOn) {
4316  iout << "\n";
4317  iout << FEPTITLE2(step);
4318  iout << FORMAT(bondEnergy + angleEnergy + dihedralEnergy
4319  + improperEnergy + bondedEnergyDiff_f, precision);
4320  iout << FORMAT(electEnergy_f + electEnergySlow_f, precision);
4321  iout << FORMAT(ljEnergy_f, precision);
4322  if (simParams->alchLambdaFreq > 0) {
4323  iout << FORMAT(simParams->getCurrentLambda(step), precision);
4324  }
4325  }
4326  }
4327 
4328  iout << "\n\n" << endi;
4329 
4330 #if(CMK_CCS_AVAILABLE && CMK_WEB_MODE)
4331  char webout[80];
4332  sprintf(webout,"%d %d %d %d",(int)totalEnergy,
4333  (int)(potentialEnergy),
4334  (int)kineticEnergy,(int)temperature);
4335  CApplicationDepositNode0Data(webout);
4336 #endif
4337 
4339  iout << "PAIR INTERACTION:";
4340  iout << " STEP: " << step;
4341  iout << " VDW_FORCE: ";
4342  iout << FORMAT(pairVDWForce.x, precision);
4343  iout << FORMAT(pairVDWForce.y, precision);
4344  iout << FORMAT(pairVDWForce.z, precision);
4345  iout << " ELECT_FORCE: ";
4346  iout << FORMAT(pairElectForce.x, precision);
4347  iout << FORMAT(pairElectForce.y, precision);
4348  iout << FORMAT(pairElectForce.z, precision);
4349  iout << "\n" << endi;
4350  }
4351  drudeBondTempAvg = 0;
4352  temp_avg = 0;
4353  pressure_avg = 0;
4354  groupPressure_avg = 0;
4355  avg_count = 0;
4356 
4357  if ( fflush_count ) {
4358  --fflush_count;
4359  fflush(stdout);
4360  }
4361 }
4362 
4364  Lattice &lattice = state->lattice;
4365  file << "#$LABELS step";
4366  if ( lattice.a_p() ) file << " a_x a_y a_z";
4367  if ( lattice.b_p() ) file << " b_x b_y b_z";
4368  if ( lattice.c_p() ) file << " c_x c_y c_z";
4369  file << " o_x o_y o_z";
4370  if ( simParams->langevinPistonOn ) {
4371  file << " s_x s_y s_z s_u s_v s_w";
4372  }
4374  file << " v_x v_y v_z";
4375  }
4376  file << std::endl;
4377 }
4378 
4380  Lattice &lattice = state->lattice;
4381  file.precision(12);
4382  file << step;
4383  if ( lattice.a_p() ) file << " " << lattice.a().x << " " << lattice.a().y << " " << lattice.a().z;
4384  if ( lattice.b_p() ) file << " " << lattice.b().x << " " << lattice.b().y << " " << lattice.b().z;
4385  if ( lattice.c_p() ) file << " " << lattice.c().x << " " << lattice.c().y << " " << lattice.c().z;
4386  file << " " << lattice.origin().x << " " << lattice.origin().y << " " << lattice.origin().z;
4387  if ( simParams->langevinPistonOn ) {
4388  Vector strainRate = diagonal(langevinPiston_strainRate);
4389  Vector strainRate2 = off_diagonal(langevinPiston_strainRate);
4390  file << " " << strainRate.x;
4391  file << " " << strainRate.y;
4392  file << " " << strainRate.z;
4393  file << " " << strainRate2.x;
4394  file << " " << strainRate2.y;
4395  file << " " << strainRate2.z;
4396  }
4398  // We could print the elements as they are, but it would be meaningless,
4399  // because for constant ratio and isotropic fluctuations, we only operate
4400  // on x element.
4401  if (!simParams->useFlexibleCell) {
4402  // isotropic fluctuations: use x element for v_x, v_y, and v_z
4403  file << " " << monteCarloMaxVolume.x;
4404  file << " " << monteCarloMaxVolume.x;
4405  file << " " << monteCarloMaxVolume.x;
4406  } else {
4407  // we have flexible cell
4408  if (simParams->useConstantRatio) {
4409  // use x element for v_x and v_y
4410  file << " " << monteCarloMaxVolume.x;
4411  file << " " << monteCarloMaxVolume.x;
4412  file << " " << monteCarloMaxVolume.z;
4413  } else {
4414  // constant area or just flexible in each axis dimension
4415  file << " " << monteCarloMaxVolume.x;
4416  file << " " << monteCarloMaxVolume.y;
4417  file << " " << monteCarloMaxVolume.z;
4418  }
4419  }
4420  }
4421  file << std::endl;
4422 }
4423 
4425 {
4426  int prec;
4427  int dcdIndex;
4428 
4429  std::tie(prec, dcdIndex) = Output::coordinateNeeded(timestep);
4430 #ifndef MEM_OPT_VERSION
4431  if ( prec == 4 ){
4432  collection->enqueuePositionsDcdSelection(timestep,state->lattice);
4433  }
4434  else
4435 #endif
4436  if ( prec ){
4437  collection->enqueuePositions(timestep,state->lattice);
4438  }
4439  if ( Output::velocityNeeded(timestep) )
4440  collection->enqueueVelocities(timestep);
4441  if ( Output::forceNeeded(timestep) )
4442  collection->enqueueForces(timestep);
4443 }
4444 
4445 //Modifications for alchemical fep
4447  if (simParams->alchOn && simParams->alchFepOn) {
4448  const int stepInRun = step - simParams->firstTimestep;
4449  const int alchEquilSteps = simParams->alchEquilSteps;
4450  const BigReal alchLambda = simParams->alchLambda;
4451  const bool alchEnsembleAvg = simParams->alchEnsembleAvg;
4452 
4453  if (alchEnsembleAvg && (stepInRun == 0 || stepInRun == alchEquilSteps)) {
4454  FepNo = 0;
4455  exp_dE_ByRT = 0.0;
4456  net_dE = 0.0;
4457  }
4461 
4462  if (alchEnsembleAvg && (simParams->alchLambdaIDWS < 0. ||
4463  (step / simParams->alchIDWSFreq) % 2 == 1 )
4464 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
4465  &&
4466  // some people rely on the ensemble averages (dE_avg and dG) in fep output for calculating the free energy changes.
4467  // in the GPU version, dE is only available every outputEnergies steps.
4468  // so I check if the step is multiples of outputEnergies here.
4469  // I am still not sure whether we should check the stepInRun or step.
4470  // JH: dE is also calculated at alchOutFreq
4471  (step % simParams->computeEnergies == 0 || step % simParams->alchOutFreq == 0)
4472 #endif
4473  ) {
4474  // with IDWS, only accumulate stats on those timesteps where target lambda is "forward"
4475  FepNo++;
4476  exp_dE_ByRT += exp(-dE/RT);
4477  net_dE += dE;
4478  }
4479 
4480  if (simParams->alchOutFreq) {
4481  if (stepInRun == 0) {
4482  if (!fepFile.is_open()) {
4485  iout << "OPENING FEP ENERGY OUTPUT FILE\n" << endi;
4486  if(alchEnsembleAvg){
4487  fepSum = 0.0;
4488  fepFile << "# STEP Elec "
4489  << "vdW dE dE_avg Temp dG\n"
4490  << "# l l+dl "
4491  << " l l+dl E(l+dl)-E(l)" << std::endl;
4492  }
4493  else{
4494  fepFile << "# STEP Elec "
4495  << "vdW dE Temp\n"
4496  << "# l l+dl "
4497  << " l l+dl E(l+dl)-E(l)" << std::endl;
4498  }
4499  }
4500  if(!step){
4501  fepFile << "#NEW FEP WINDOW: "
4502  << "LAMBDA SET TO " << alchLambda << " LAMBDA2 "
4503  << simParams->alchLambda2;
4504  if ( simParams->alchLambdaIDWS >= 0. ) {
4505  fepFile << " LAMBDA_IDWS " << simParams->alchLambdaIDWS;
4506  }
4507  fepFile << std::endl;
4508  }
4509  }
4510  if ((alchEquilSteps) && (stepInRun == alchEquilSteps)) {
4511  fepFile << "#" << alchEquilSteps << " STEPS OF EQUILIBRATION AT "
4512  << "LAMBDA " << simParams->alchLambda << " COMPLETED\n"
4513  << "#STARTING COLLECTION OF ENSEMBLE AVERAGE" << std::endl;
4514  }
4515  if ((simParams->N) && ((step%simParams->alchOutFreq) == 0)) {
4516  writeFepEnergyData(step, fepFile);
4517  fepFile.flush();
4518  }
4519  if (alchEnsembleAvg && (step == simParams->N)) {
4520  fepSum = fepSum + dG;
4521  fepFile << "#Free energy change for lambda window [ " << alchLambda
4522  << " " << simParams->alchLambda2 << " ] is " << dG
4523  << " ; net change until now is " << fepSum << std::endl;
4524  fepFile.flush();
4525  }
4526  }
4527  }
4528 }
4529 
4532  const int stepInRun = step - simParams->firstTimestep;
4533  const int alchEquilSteps = simParams->alchEquilSteps;
4534  const int alchLambdaFreq = simParams->alchLambdaFreq;
4535 
4536  if (stepInRun == 0 || stepInRun == alchEquilSteps) {
4537  TiNo = 0;
4538  net_dEdl_bond_1 = 0;
4539  net_dEdl_bond_2 = 0;
4540  net_dEdl_elec_1 = 0;
4541  net_dEdl_elec_2 = 0;
4542  net_dEdl_lj_1 = 0;
4543  net_dEdl_lj_2 = 0;
4544  }
4545  // The energies are only computed if they are required to output in CUDA build.
4546  // In the case when step % simParams->computeEnergies != 0 the energies are 0.
4547  // All output terms in writeTiEnergyData use TiNo and recent_TiNo as denominators,
4548  // so the TiNo and recent_TiNo should NOT be increased.
4549 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
4550  if (step % simParams->computeEnergies == 0) {
4551 #endif
4552  TiNo++;
4561  // Compute global dE / dLambda for lambda-dynamics
4562  computeTIderivative(step);
4563 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
4564  }
4565 #endif
4566 
4567  // Don't accumulate block averages (you'll get a divide by zero!) or even
4568  // open the TI output if alchOutFreq is zero.
4569  if (simParams->alchOutFreq) {
4570  if (stepInRun == 0 || stepInRun == alchEquilSteps
4571  || (! ((step - 1) % simParams->alchOutFreq))) {
4572  // output of instantaneous dU/dl now replaced with running average
4573  // over last alchOutFreq steps (except for step 0)
4574  recent_TiNo = 0;
4575  recent_dEdl_bond_1 = 0;
4576  recent_dEdl_bond_2 = 0;
4577  recent_dEdl_elec_1 = 0;
4578  recent_dEdl_elec_2 = 0;
4579  recent_dEdl_lj_1 = 0;
4580  recent_dEdl_lj_2 = 0;
4581  recent_alchWork = 0;
4582  }
4583 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
4584  if (step % simParams->computeEnergies == 0) {
4585 #endif
4586  recent_TiNo++;
4590  + electEnergyPME_ti_1);
4592  + electEnergyPME_ti_2);
4596 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
4597  }
4598 #endif
4599 
4600  if (stepInRun == 0) {
4601  if (!tiFile.is_open()) {
4604  /* BKR - This has been rather drastically updated to better match
4605  stdout. This was necessary for several reasons:
4606  1) PME global scaling is obsolete (now removed)
4607  2) scaling of bonded terms was added
4608  3) alchemical work is now accumulated when switching is active
4609  */
4610  iout << "OPENING TI ENERGY OUTPUT FILE\n" << endi;
4611  tiFile << "#TITITLE: TS";
4612  tiFile << FORMAT("BOND1");
4613  tiFile << FORMAT("AVGBOND1");
4614  tiFile << FORMAT("ELECT1");
4615  tiFile << FORMAT("AVGELECT1");
4616  tiFile << " ";
4617  tiFile << FORMAT("VDW1");
4618  tiFile << FORMAT("AVGVDW1");
4619  tiFile << FORMAT("BOND2");
4620  tiFile << FORMAT("AVGBOND2");
4621  tiFile << FORMAT("ELECT2");
4622  tiFile << " ";
4623  tiFile << FORMAT("AVGELECT2");
4624  tiFile << FORMAT("VDW2");
4625  tiFile << FORMAT("AVGVDW2");
4626  if (alchLambdaFreq > 0) {
4627  tiFile << FORMAT("ALCHWORK");
4628  tiFile << FORMAT("CUMALCHWORK");
4629  }
4630  tiFile << std::endl;
4631  }
4632 
4633  if (alchLambdaFreq > 0) {
4634  tiFile << "#ALCHEMICAL SWITCHING ACTIVE "
4635  << simParams->alchLambda << " --> " << simParams->getCurrentLambda2(step)
4636  << "\n#LAMBDA SCHEDULE: "
4637  << "dL: " << simParams->getLambdaDelta()
4638  << " Freq: " << alchLambdaFreq;
4639  }
4640  else {
4641  const BigReal alchLambda = simParams->alchLambda;
4642  const BigReal bond_lambda_1 = simParams->getBondLambda(alchLambda);
4643  const BigReal bond_lambda_2 = simParams->getBondLambda(1-alchLambda);
4644  const BigReal elec_lambda_1 = simParams->getElecLambda(alchLambda);
4645  const BigReal elec_lambda_2 = simParams->getElecLambda(1-alchLambda);
4646  const BigReal vdw_lambda_1 = simParams->getVdwLambda(alchLambda);
4647  const BigReal vdw_lambda_2 = simParams->getVdwLambda(1-alchLambda);
4648  tiFile << "#NEW TI WINDOW: "
4649  << "LAMBDA " << alchLambda
4650  << "\n#PARTITION 1 SCALING: BOND " << bond_lambda_1
4651  << " VDW " << vdw_lambda_1 << " ELEC " << elec_lambda_1
4652  << "\n#PARTITION 2 SCALING: BOND " << bond_lambda_2
4653  << " VDW " << vdw_lambda_2 << " ELEC " << elec_lambda_2;
4654  }
4655  tiFile << "\n#CONSTANT TEMPERATURE: " << simParams->alchTemp << " K"
4656  << std::endl;
4657  }
4658 
4659  if ((alchEquilSteps) && (stepInRun == alchEquilSteps)) {
4660  tiFile << "#" << alchEquilSteps << " STEPS OF EQUILIBRATION AT "
4661  << "LAMBDA " << simParams->alchLambda << " COMPLETED\n"
4662  << "#STARTING COLLECTION OF ENSEMBLE AVERAGE" << std::endl;
4663  }
4664  if ((step%simParams->alchOutFreq) == 0) {
4665  writeTiEnergyData(step, tiFile);
4666  tiFile.flush();
4667  }
4668  }
4669  }
4670 }
4671 
4672 /*
4673  Work is accumulated whenever alchLambda changes. In the current scheme we
4674  always increment lambda _first_, then integrate in time. Therefore the work
4675  is wrt the "old" lambda before the increment.
4676 */
4678  // alchemical scaling factors for groups 1/2 at the previous lambda
4679  const BigReal oldLambda = simParams->getCurrentLambda(step-1);
4680  const BigReal bond_lambda_1 = simParams->getBondLambda(oldLambda);
4681  const BigReal bond_lambda_2 = simParams->getBondLambda(1-oldLambda);
4682  const BigReal elec_lambda_1 = simParams->getElecLambda(oldLambda);
4683  const BigReal elec_lambda_2 = simParams->getElecLambda(1-oldLambda);
4684  const BigReal vdw_lambda_1 = simParams->getVdwLambda(oldLambda);
4685  const BigReal vdw_lambda_2 = simParams->getVdwLambda(1-oldLambda);
4686  // alchemical scaling factors for groups 1/2 at the new lambda
4687  const BigReal alchLambda = simParams->getCurrentLambda(step);
4688  const BigReal bond_lambda_12 = simParams->getBondLambda(alchLambda);
4689  const BigReal bond_lambda_22 = simParams->getBondLambda(1-alchLambda);
4690  const BigReal elec_lambda_12 = simParams->getElecLambda(alchLambda);
4691  const BigReal elec_lambda_22 = simParams->getElecLambda(1-alchLambda);
4692  const BigReal vdw_lambda_12 = simParams->getVdwLambda(alchLambda);
4693  const BigReal vdw_lambda_22 = simParams->getVdwLambda(1-alchLambda);
4694 
4695  return ((bond_lambda_12 - bond_lambda_1)*bondedEnergy_ti_1 +
4696  (elec_lambda_12 - elec_lambda_1)*
4698  (vdw_lambda_12 - vdw_lambda_1)*ljEnergy_ti_1 +
4699  (bond_lambda_22 - bond_lambda_2)*bondedEnergy_ti_2 +
4700  (elec_lambda_22 - elec_lambda_2)*
4702  (vdw_lambda_22 - vdw_lambda_2)*ljEnergy_ti_2
4703  );
4704 }
4705 
4706 void Controller::computeTIderivative(const int step) {
4707  // Note: WCA is incompatible with TI
4708  BigReal l1 = simParams->getCurrentLambda(step);
4709  BigReal l2 = 1. - l1;
4710 
4711  BigReal dl_bond_dl1 = (l1 >= simParams->alchBondLambdaEnd ?
4712  0. : 1. / simParams->alchBondLambdaEnd);
4713  BigReal dl_bond_dl2 = (l2 >= simParams->alchBondLambdaEnd ?
4714  0. : -1. / simParams->alchBondLambdaEnd);
4715 
4716  BigReal dl_lj_dl1 = (l1 >= simParams->alchVdwLambdaEnd ?
4717  0. : 1. / simParams->alchVdwLambdaEnd);
4718  BigReal dl_lj_dl2 = (l2 >= simParams->alchVdwLambdaEnd ?
4719  0. : -1. / simParams->alchVdwLambdaEnd);
4720 
4721  BigReal dl_elec_dl1 = (l1 <= simParams->alchElecLambdaStart ?
4722  0. : 1. / (1. - simParams->alchElecLambdaStart));
4723  BigReal dl_elec_dl2 = (l2 <= simParams->alchElecLambdaStart ?
4724  0. : -1. / (1. - simParams->alchElecLambdaStart));
4725 
4726  TIderivative =
4727  dl_bond_dl1 * bondedEnergy_ti_1
4728  + dl_bond_dl2 * bondedEnergy_ti_2
4729  + dl_lj_dl1 * ljEnergy_ti_1
4730  + dl_lj_dl2 * ljEnergy_ti_2
4733 }
4734 
4739 
4740  const bool alchEnsembleAvg = simParams->alchEnsembleAvg;
4741  const int stepInRun = step - simParams->firstTimestep;
4742  const BigReal alchLambda = simParams->alchLambda;
4743 
4744  if(stepInRun){
4745  if ( simParams->alchLambdaIDWS >= 0. &&
4746  (step / simParams->alchIDWSFreq) % 2 == 0 ) {
4747  // IDWS is active and we are on a "backward" timestep
4748  fepFile << FEPTITLE_BACK(step);
4749  } else {
4750  // "forward" timestep
4751  fepFile << FEPTITLE(step);
4752  }
4753  fepFile << FORMAT(eeng);
4754  fepFile << FORMAT(eeng_f);
4755  fepFile << FORMAT(ljEnergy);
4757  fepFile << FORMAT(dE);
4758  if(alchEnsembleAvg){
4759  BigReal dE_avg = net_dE / FepNo;
4760  fepFile << FORMAT(dE_avg);
4761  }
4763  if(alchEnsembleAvg){
4764  dG = -(RT * log(exp_dE_ByRT / FepNo));
4765  fepFile << FORMAT(dG);
4766  }
4767  fepFile << std::endl;
4768  }
4769 }
4770 
4772  tiFile << TITITLE(step);
4777  tiFile << " ";
4783  tiFile << " ";
4787  if (simParams->alchLambdaFreq > 0) {
4790  }
4791  tiFile << std::endl;
4792 }
4793 //fepe
4794 
4796 {
4797 
4798  if ( step >= 0 ) {
4799 
4800  // Write out eXtended System Trajectory (XST) file
4801  if ( simParams->xstFrequency &&
4802  ((step % simParams->xstFrequency) == 0) )
4803  {
4804  if ( ! xstFile.is_open() )
4805  {
4806  iout << "OPENING EXTENDED SYSTEM TRAJECTORY FILE\n" << endi;
4809  while (!xstFile) {
4810  if ( errno == EINTR ) {
4811  CkPrintf("Warning: Interrupted system call opening XST trajectory file, retrying.\n");
4812  xstFile.clear();
4814  continue;
4815  }
4816  char err_msg[257];
4817  sprintf(err_msg, "Error opening XST trajectory file %s",simParams->xstFilename);
4818  NAMD_err(err_msg);
4819  }
4820  xstFile << "# NAMD extended system trajectory file" << std::endl;
4822  }
4824  xstFile.flush();
4825  }
4826 
4827  // Write out eXtended System Configuration (XSC) files
4828  // Output a restart file
4829  if ( simParams->restartFrequency &&
4830  ((step % simParams->restartFrequency) == 0) &&
4831  (step != simParams->firstTimestep) )
4832  {
4833  iout << "WRITING EXTENDED SYSTEM TO RESTART FILE AT STEP "
4834  << step << "\n" << endi;
4835  char fname[NAMD_FILENAME_BUFFER_SIZE];
4836  const char *bsuffix = ".old";
4837  strcpy(fname, simParams->restartFilename);
4838  if ( simParams->restartSave ) {
4839  char timestepstr[20];
4840  sprintf(timestepstr,".%d",step);
4841  strcat(fname, timestepstr);
4842  bsuffix = ".BAK";
4843  }
4844  strcat(fname, ".xsc");
4845  NAMD_backup_file(fname,bsuffix);
4846  ofstream_namd xscFile(fname);
4847  while (!xscFile) {
4848  if ( errno == EINTR ) {
4849  CkPrintf("Warning: Interrupted system call opening XSC restart file, retrying.\n");
4850  xscFile.clear();
4851  xscFile.open(fname);
4852  continue;
4853  }
4854  char err_msg[257];
4855  sprintf(err_msg, "Error opening XSC restart file %s",fname);
4856  NAMD_err(err_msg);
4857  }
4858  xscFile << "# NAMD extended system configuration restart file" << std::endl;
4859  writeExtendedSystemLabels(xscFile);
4860  writeExtendedSystemData(step,xscFile);
4861  if (!xscFile) {
4862  char err_msg[257];
4863  sprintf(err_msg, "Error writing XSC restart file %s",fname);
4864  NAMD_err(err_msg);
4865  }
4866  }
4867 
4868  }
4869 
4870  // Output final coordinates
4871  if (step == FILE_OUTPUT || step == END_OF_RUN)
4872  {
4873  int realstep = ( step == FILE_OUTPUT ?
4875  iout << "WRITING EXTENDED SYSTEM TO OUTPUT FILE AT STEP "
4876  << realstep << "\n" << endi;
4877  static char fname[NAMD_FILENAME_BUFFER_SIZE];
4878  strcpy(fname, simParams->outputFilename);
4879  strcat(fname, ".xsc");
4880  NAMD_backup_file(fname);
4881  ofstream_namd xscFile(fname);
4882  while (!xscFile) {
4883  if ( errno == EINTR ) {
4884  CkPrintf("Warning: Interrupted system call opening XSC output file, retrying.\n");
4885  xscFile.clear();
4886  xscFile.open(fname);
4887  continue;
4888  }
4889  char err_msg[257];
4890  sprintf(err_msg, "Error opening XSC output file %s",fname);
4891  NAMD_err(err_msg);
4892  }
4893  xscFile << "# NAMD extended system configuration output file" << std::endl;
4894  writeExtendedSystemLabels(xscFile);
4895  writeExtendedSystemData(realstep,xscFile);
4896  if (!xscFile) {
4897  char err_msg[257];
4898  sprintf(err_msg, "Error writing XSC output file %s",fname);
4899  NAMD_err(err_msg);
4900  }
4901  }
4902 
4903  // Close trajectory file
4904  if (step == END_OF_RUN) {
4905  if ( xstFile.is_open() ) {
4906  xstFile.close();
4907  iout << "CLOSING EXTENDED SYSTEM TRAJECTORY FILE\n" << endi;
4908  }
4909  }
4910 
4911 }
4912 
4913 
4914 void Controller::recvCheckpointReq(const char *key, int task, checkpoint &cp) { // responding replica
4915  switch ( task ) {
4917  if ( ! checkpoints.count(key) ) {
4918  checkpoints[key] = new checkpoint;
4919  }
4920  *checkpoints[key] = cp;
4921  break;
4923  if ( ! checkpoints.count(key) ) {
4924  NAMD_die("Unable to load checkpoint, requested key was never stored.");
4925  }
4926  cp = *checkpoints[key];
4927  break;
4929  if ( ! checkpoints.count(key) ) {
4930  NAMD_die("Unable to swap checkpoint, requested key was never stored.");
4931  }
4932  std::swap(cp,*checkpoints[key]);
4933  break;
4935  if ( ! checkpoints.count(key) ) {
4936  NAMD_die("Unable to free checkpoint, requested key was never stored.");
4937  }
4938  delete checkpoints[key];
4939  checkpoints.erase(key);
4940  break;
4941  }
4942 }
4943 
4944 void Controller::recvCheckpointAck(checkpoint &cp) { // initiating replica
4946  state->lattice = cp.lattice;
4947  *(ControllerState*)this = cp.state;
4948  }
4949  CkpvAccess(_qd)->process();
4950 }
4951 
4952 
4954 {
4955  if ( ! ldbSteps ) {
4957  }
4958  if ( ! --ldbSteps ) {
4959  startBenchTime -= namdWallTimer();
4960  Node::Object()->outputPatchComputeMaps("before_ldb", step);
4962  startBenchTime += namdWallTimer();
4963  fflush_count = 3;
4964  }
4965 }
4966 
4967 void Controller::cycleBarrier(int doBarrier, int step) {
4968 #if USE_BARRIER
4969  if (doBarrier) {
4970  broadcast->cycleBarrier.publish(step,1);
4971  CkPrintf("Cycle time at sync Wall: %f CPU %f\n",
4972  namdWallTimer()-firstWTime,CmiTimer()-firstCTime);
4973  }
4974 #endif
4975 }
4976 
4977 void Controller::traceBarrier(int turnOnTrace, int step) {
4978  CkPrintf("Cycle time at trace sync (begin) Wall at step %d: %f CPU %f\n", step, namdWallTimer()-firstWTime,CmiTimer()-firstCTime);
4979  CProxy_Node nd(CkpvAccess(BOCclass_group).node);
4980  nd.traceBarrier(turnOnTrace, step);
4981  CthSuspend();
4982 }
4983 
4985  broadcast->traceBarrier.publish(step,1);
4986  CkPrintf("Cycle time at trace sync (end) Wall at step %d: %f CPU %f\n", step, namdWallTimer()-firstWTime,CmiTimer()-firstCTime);
4987  awaken();
4988 }
4989 
4990 #ifdef MEASURE_NAMD_WITH_PAPI
4991 void Controller::papiMeasureBarrier(int turnOnMeasure, int step){
4992  CkPrintf("Cycle time at PAPI measurement sync (begin) Wall at step %d: %f CPU %f\n", step, namdWallTimer()-firstWTime,CmiTimer()-firstCTime);
4993  CProxy_Node nd(CkpvAccess(BOCclass_group).node);
4994  nd.papiMeasureBarrier(turnOnMeasure, step);
4995  CthSuspend();
4996 }
4997 
4998 void Controller::resumeAfterPapiMeasureBarrier(int step){
4999  broadcast->papiMeasureBarrier.publish(step,1);
5000  CkPrintf("Cycle time at PAPI measurement sync (end) Wall at step %d: %f CPU %f\n", step, namdWallTimer()-firstWTime,CmiTimer()-firstCTime);
5001  awaken();
5002 }
5003 #endif
5004 
5006  BackEnd::awaken();
5007  CthFree(threadWrapper->thread);
5008  delete threadWrapper;
5009  CthSuspend();
5010 }
5011 
5012 RequireReduction* Controller::getCurrentReduction() {
5013 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
5016 #else
5017  return reductionBasic;
5018 #endif
5019 }
5020 
ofstream_namd tiFile
Definition: Controller.h:376
static Node * Object()
Definition: Node.h:86
Vector gaussian_vector(void)
Definition: Random.h:219
BigReal adaptTempBetaMin
Definition: Controller.h:431
BigReal adaptTempTmax
static NAMD_HOST_DEVICE Tensor symmetric(const Vector &v1, const Vector &v2)
Definition: Tensor.h:45
int checkpoint_stored
Definition: Controller.h:382
int adaptTempRestartFreq
int numFixedGroups
Definition: Molecule.h:639
Bool accelMDGresetVaftercmd
BigReal berendsenPressureCompressibility
NAMD_HOST_DEVICE void rescale(Tensor factor)
Definition: Lattice.h:60
MovingAverage groupPressureAverage_xx
Definition: Controller.h:459
BigReal net_dE
Definition: Controller.h:203
void enqueueCollections(int)
Definition: Controller.C:4424
#define AVGXY(T)
BigReal zy
Definition: Tensor.h:19
Bool berendsenPressureOn
Tensor controlPressure_slow
Definition: Controller.h:158
BigReal * adaptTempBetaN
Definition: Controller.h:427
char scriptStringArg1[128]
BigReal berendsenPressureRelaxationTime
void reset(int mws=20)
Definition: Controller.h:56
int adaptTempBins
Definition: Controller.h:434
std::ostream & iINFO(std::ostream &s)
Definition: InfoStream.C:81
#define XXXBIGREAL
Definition: Controller.C:73
int pressureProfileSlabs
Definition: Controller.h:361
BigReal electEnergy_ti_1
Definition: Controller.h:211
#define CALLBACKDATA(LABEL, VALUE)
void recvCheckpointReq(const char *key, int task, checkpoint &cp)
Definition: Controller.C:4914
void cycleBarrier(int, int)
Definition: Controller.C:4967
BigReal net_dEdl_lj_2
Definition: Controller.h:222
void rescaleVelocities(int)
Definition: Controller.C:1651
BigReal smooth2_avg
Definition: Controller.h:102
void rescaleaccelMD(int step, int minimize=0)
Definition: Controller.C:2328
BigReal dG
Definition: Controller.h:204
int nbondFreq
Definition: Controller.h:159
BigReal accelMDE
BigReal min_v_dot_v
Definition: Controller.h:179
MovingAverage groupPressureAverage_yx
Definition: Controller.h:462
static void awaken(void)
Definition: BackEnd.C:323
BigReal monteCarloAcceptanceRate
void write_accelMDG_rest_file(int step_n, char type, int V_n, BigReal Vmax, BigReal Vmin, BigReal Vavg, BigReal sigmaV, BigReal M2, BigReal E, BigReal k, bool write_topic, bool lasttime)
Definition: Controller.C:2270
int numCalcBonds
Definition: Molecule.h:657
ControllerState state
Definition: Controller.h:388
BigReal adaptTempCgamma
int numCalcAnisos
Definition: Molecule.h:667
NAMD_HOST_DEVICE Vector c() const
Definition: Lattice.h:270
BigReal xz
Definition: Tensor.h:17
BigReal getBondLambda(const BigReal) const
void compareChecksums(int, int=0)
Definition: Controller.C:3264
BigReal noGradient
Definition: Controller.C:776
BigReal uniform(void)
Definition: Random.h:109
Tensor groupPressure_nbond
Definition: Controller.h:154
void NAMD_err(const char *err_msg)
Definition: common.C:170
BigReal goNativeEnergy
Definition: Controller.h:192
std::map< std::string, checkpoint * > checkpoints
Definition: Controller.h:390
BigReal langevinPistonTemp
SimpleBroadcastObject< int > traceBarrier
Definition: Broadcasts.h:89
BigReal accelMDLastStep
void calcPressure(int step, int minimize, const Tensor &virial_normal_in, const Tensor &virial_nbond_in, const Tensor &virial_slow_in, const Tensor &intVirial_normal, const Tensor &intVirial_nbond, const Tensor &intVirial_slow, const Vector &extForce_normal, const Vector &extForce_nbond, const Vector &extForce_slow)
Definition: Controller.C:2017
int eventEndOfTimeStep
Definition: Node.C:296
BigReal fepSum
Definition: Controller.h:207
BigReal adaptTempTmin
Bool monteCarloPressureOn
BigReal net_dEdl_lj_1
Definition: Controller.h:221
Definition: common.h:275
NAMD_HOST_DEVICE int c_p() const
Definition: Lattice.h:291
#define BOLTZMANN
Definition: common.h:54
void NAMD_quit(const char *err_msg)
Definition: common.C:125
Definition: Node.h:78
void printTiMessage(int)
Definition: Controller.C:1714
BigReal temp_avg
Definition: Controller.h:161
int movingAverageWindowSize
MovingAverage pressureAverage_xx
Definition: Controller.h:453
#define FILE_OUTPUT
Definition: Output.h:25
IMDOutput * imd
Definition: Node.h:186
int fflush_count
Definition: Controller.h:329
BigReal gaussian(void)
Definition: Random.h:116
MovingAverage groupPressureAverage_yy
Definition: Controller.h:463
BigReal adaptTempT
Definition: Controller.h:428
int mc_accept[MC_AXIS_TOTAL]
Definition: Controller.h:309
void adaptTempWriteRestart(int step)
Definition: Controller.C:2940
int numHydrogenGroups
Definition: Molecule.h:635
SimpleBroadcastObject< Vector > momentumCorrection
Definition: Broadcasts.h:82
virtual void require(const bool clearData=true)=0
virtual void algorithm(void)
Definition: Controller.C:379
BigReal adaptTempDt
Definition: Controller.h:437
static PatchMap * Object()
Definition: PatchMap.h:27
BigReal ljEnergy
Definition: Controller.h:188
void calc_accelMDG_mean_std(BigReal testV, int step_n, BigReal *Vmax, BigReal *Vmin, BigReal *Vavg, BigReal *M2, BigReal *sigmaV)
Definition: Controller.C:2205
Tensor controlPressure
Definition: Controller.h:253
void adaptTempInit(int step)
Definition: Controller.C:2840
MovingAverage groupPressureAverage_zx
Definition: Controller.h:465
NAMD_HOST_DEVICE Tensor outer(const Vector &v1, const Vector &v2)
Definition: Tensor.h:241
void minimize()
Definition: Controller.C:780
BigReal totalEnergy0
Definition: Controller.h:247
#define EVAL_MEASURE
Definition: Output.h:27
BigReal alchElecLambdaStart
char adaptTempInFile[NAMD_FILENAME_BUFFER_SIZE]
PressureProfileReduction(int rtag, int numslabs, int numpartitions, const char *myname, int outputfreq)
Definition: Controller.C:117
Definition: Vector.h:72
zVector monteCarloMaxVolume
virtual void submit(void)=0
SimParameters * simParameters
Definition: Node.h:181
void printMinimizeEnergies(int)
Definition: Controller.C:3537
void integrate(int)
Definition: Controller.C:531
BigReal multigratorPressureTarget
void(* namd_sighandler_t)(int)
Definition: Controller.C:528
#define PRESSUREFACTOR
Definition: common.h:56
int min_huge_count
Definition: Controller.h:180
int accelMDGEquiPrepSteps
double stochRescaleCoefficient()
Definition: Controller.C:1784
Bool CUDASOAintegrateMode
BigReal net_dEdl_bond_2
Definition: Controller.h:218
BigReal surfaceTensionTarget
void writeExtendedSystemLabels(ofstream_namd &file)
Definition: Controller.C:4363
BigReal reassignTemp
BigReal pressure_avg
Definition: Controller.h:162
void monteCarloPressure_accept(int)
Definition: Controller.C:1137
BigReal & item(int i)
Definition: ReductionMgr.h:336
#define DebugM(x, y)
Definition: Debug.h:75
MovingAverage pressureAverage_zx
Definition: Controller.h:456
void enqueueVelocities(int seq)
std::vector< BigReal > multigratorOmega
Definition: Controller.h:322
std::ostream & endi(std::ostream &s)
Definition: InfoStream.C:54
BigReal z
Definition: Vector.h:74
BigReal alchLambda2
BigReal alchBondLambdaEnd
BigReal accelMDTE
BigReal sum_of_squared_gaussians(int64_t num_gaussians)
Return the sum of i.i.d. squared Gaussians.
Definition: Random.h:189
float Eelec
Definition: imd.h:42
BigReal electEnergySlow_f
Definition: Controller.h:198
BigReal yz
Definition: Tensor.h:18
#define X
Definition: msm_defn.h:29
MovingAverage totalEnergyAverage
Definition: Controller.h:447
BigReal minLineGoal
std::vector< BigReal > multigratorNuT
Definition: Controller.h:321
int berendsenPressureFreq
static char * FEPTITLE2(int X)
Definition: Controller.C:90
MovingAverage temperatureAverage
Definition: Controller.h:448
MovingAverage groupPressureAverage_yz
Definition: Controller.h:464
std::ostream & iWARN(std::ostream &s)
Definition: InfoStream.C:82
SubmitReduction * willSubmit(int setID, int size=-1)
Definition: ReductionMgr.C:368
bool is_open() const
Definition: fstream_namd.h:30
ofstream_namd & flush()
Definition: fstream_namd.C:17
BigReal recent_alchWork
Definition: Controller.h:233
BigReal u
Definition: Controller.C:776
int monteCarloAdjustmentFreq
SimpleBroadcastObject< BigReal > adaptTemperature
Definition: Broadcasts.h:92
Tensor groupPressure_tavg
Definition: Controller.h:166
Bool langevinPistonBarrier
BigReal * adaptTempPotEnergyAveNum
Definition: Controller.h:421
static int gotsigint
Definition: Controller.C:523
static ReductionMgr * Object(void)
Definition: ReductionMgr.h:290
#define iout
Definition: InfoStream.h:51
Tensor pressure_amd
Definition: Controller.h:151
BigReal accelMDalpha
#define NAMD_FILENAME_BUFFER_SIZE
Definition: common.h:45
int pressureProfileSlabs
BigReal getElecLambda(const BigReal) const
int stochRescale_count
Definition: Controller.h:276
#define GET_TENSOR(O, R, A)
Definition: ReductionMgr.h:60
BigReal tail_corr_ener
Definition: Molecule.h:499
RunningAverage perfstats
Definition: Controller.h:444
static char * FEPTITLE(int X)
Definition: Controller.C:76
#define CTRL_STK_SZ
Definition: Thread.h:12
BigReal adaptTempDBeta
Definition: Controller.h:435
BigReal recent_dEdl_bond_2
Definition: Controller.h:228
void enqueuePositions(int seq, Lattice &lattice)
BigReal electEnergySlow
Definition: Controller.h:187
SimpleBroadcastObject< BigReal > tcoupleCoefficient
Definition: Broadcasts.h:79
void outputPatchComputeMaps(const char *filename, int tag)
Definition: Node.C:1617
BigReal alchLambda
int mc_trial[MC_AXIS_TOTAL]
Definition: Controller.h:309
Bool pairInteractionOn
void swap(Array< T > &s, Array< T > &t)
Definition: MsmMap.h:319
Molecule stores the structural information for the system.
Definition: Molecule.h:174
NAMD_HOST_DEVICE int b_p() const
Definition: Lattice.h:290
MovingAverage groupPressureAverage_xy
Definition: Controller.h:460
MovingAverage pressureAverage_yy
Definition: Controller.h:455
void split(int iStream, int numStreams)
Definition: Random.h:77
RequireReduction * amd_reduction
Definition: Controller.h:354
static NAMD_HOST_DEVICE Tensor identity(BigReal v1=1.0)
Definition: Tensor.h:31
char outputFilename[NAMD_FILENAME_BUFFER_SIZE]
void multigratorTemperature(int step, int callNumber)
Definition: Controller.C:1040
static double namdWallTimer()
Definition: Controller.C:59
void gather_energies(IMDEnergies *energies)
Definition: IMDOutput.C:24
float Eimpr
Definition: imd.h:46
BigReal mc_totalEnergyOld
Definition: Controller.h:312
BigReal min_energy
Definition: Controller.h:176
BigReal heat
Definition: Controller.h:245
MovingAverage pressureAverage_zz
Definition: Controller.h:458
void enqueuePositionsDcdSelection(int seq, Lattice &lattice)
#define MOVETO(X)
Definition: Controller.C:746
float Etot
Definition: imd.h:39
Tensor pressure_slow
Definition: Controller.h:150
BigReal accelMDTalpha
SimpleBroadcastObject< BigReal > stochRescaleCoefficient
Definition: Broadcasts.h:80
void langevinPiston1(int)
Definition: Controller.C:1405
SimpleBroadcastObject< int > monteCarloBarostatAcceptance
Definition: Broadcasts.h:84
BigReal alchWork
Definition: Controller.h:234
void outputTiEnergy(int step)
Definition: Controller.C:4530
BigReal electEnergy_f
Definition: Controller.h:197
int numCalcCrossterms
Definition: Molecule.h:661
ofstream_namd xstFile
Definition: Controller.h:366
Tensor langevinPiston_strainRate
Definition: Controller.h:95
BigReal langevinPistonDecay
double memusage_MB()
Definition: memusage.h:13
BigReal temperature
Definition: Controller.h:244
int pressureProfileCount
Definition: Controller.h:362
BigReal alchLambdaIDWS
std::vector< BigReal > multigratorNu
Definition: Controller.h:320
NamdState *const state
Definition: Controller.h:343
BigReal adaptTempDTavenum
Definition: Controller.h:430
BigReal adaptTempDTave
Definition: Controller.h:429
Lattice checkpoint_lattice
Definition: Controller.h:383
PressureProfileReduction * ppint
Definition: Controller.h:360
ofstream_namd adaptTempRestartFile
Definition: Controller.h:441
int adaptTempBin
Definition: Controller.h:433
BigReal berendsenPressureTarget
BigReal ljEnergy_ti_1
Definition: Controller.h:213
BigReal adaptTempDtMin
Definition: Controller.h:439
ControllerState checkpoint_state
Definition: Controller.h:384
Tensor pressure
Definition: Controller.h:250
Controller(NamdState *s)
Definition: Controller.C:174
BigReal stochRescalePeriod
Definition: Random.h:37
void writeExtendedSystemData(int step, ofstream_namd &file)
Definition: Controller.C:4379
ControllerBroadcasts * broadcast
Definition: Controller.h:365
BigReal computeAlchWork(const int step)
Definition: Controller.C:4677
float Edihe
Definition: imd.h:45
int mc_picked_axis
Definition: Controller.h:311
static std::pair< int, int > coordinateNeeded(int timestep)
Check if the step requires to output the coordinates.
Definition: Output.C:185
Tensor groupPressure_slow
Definition: Controller.h:155
BigReal * adaptTempPotEnergyVar
Definition: Controller.h:425
BigReal getEnergyTailCorr(const BigReal, const int)
BigReal groupPressure_avg
Definition: Controller.h:163
int numLonepairs
Number of lone pairs.
Definition: Molecule.h:610
double standard_deviation() const
Definition: Controller.h:39
BigReal drudeBondTempAvg
Definition: Controller.h:239
int64_t numDegFreedom
Definition: Controller.h:183
std::vector< BigReal > multigratorZeta
Definition: Controller.h:323
void stochRescaleVelocities(int)
Definition: Controller.C:1768
int64 numCalcFullExclusions
Definition: Molecule.h:663
void gather_time(IMDTime *time)
Definition: IMDOutput.C:61
int accelMDGcMDPrepSteps
BigReal rescaleTemp
void NAMD_bug(const char *err_msg)
Definition: common.C:195
BigReal recent_dEdl_elec_2
Definition: Controller.h:230
BigReal drudeBondTemp
Definition: Controller.h:238
BigReal bondedEnergyDiff_f
Definition: Controller.h:196
void correctMomentum(int step)
Definition: Controller.C:1673
BigReal recent_dEdl_elec_1
Definition: Controller.h:229
bool isMultiTimeStepping()
BigReal accelMDFirstStep
float Eangle
Definition: imd.h:44
BigReal yx
Definition: Tensor.h:18
Lattice mc_oldLattice
Definition: Controller.h:313
void berendsenPressure(int)
Definition: Controller.C:1370
BigReal adaptTempDtMax
Definition: Controller.h:440
zVector strainRate2
int numFixedRigidBonds
Definition: Molecule.h:641
int recent_TiNo
Definition: Controller.h:235
static NAMD_HOST_DEVICE Tensor diagonal(const Vector &v1)
Definition: Tensor.h:37
MovingAverage groupPressureAverage_xz
Definition: Controller.h:461
static char * ETITLE(int X)
Definition: Controller.C:1833
void awaken(void)
Definition: Controller.C:371
void rebalance(Sequencer *seq, PatchID id)
SimpleBroadcastObject< Tensor > velocityRescaleTensor2
Definition: Broadcasts.h:75
int numFepInitial
Definition: Molecule.h:643
void langevinPiston2(int)
Definition: Controller.C:1560
int numMolecules
Number of 1-4 atom pairs with NBThole defined.
Definition: Molecule.h:619
BigReal kineticEnergyCentered
Definition: Controller.h:243
MovingAverage groupPressureAverage_zy
Definition: Controller.h:466
void printTiming(int)
Definition: Controller.C:3467
int computeChecksum
Definition: Controller.h:169
BigReal ljEnergySlow
Definition: Controller.h:189
BigReal accelMDdV
Definition: Controller.h:116
MovingAverage pressureAverage_zy
Definition: Controller.h:457
BigReal electEnergySlow_ti_1
Definition: Controller.h:212
char adaptTempRestartFile[NAMD_FILENAME_BUFFER_SIZE]
SimpleBroadcastObject< int > IMDTimeEnergyBarrier
Definition: Broadcasts.h:90
int marginViolations
Definition: Controller.h:170
BigReal langevinTemp
SubmitReduction * submit_reduction
Definition: Controller.h:355
int time_switch
Definition: imd.h:62
void add_sample(double x)
Definition: Controller.h:29
int numCalcDihedrals
Definition: Molecule.h:659
BigReal groLJEnergy
Definition: Controller.h:190
NAMD_HOST_DEVICE BigReal length2(void) const
Definition: Vector.h:206
void recvCheckpointAck(checkpoint &cp)
Definition: Controller.C:4944
static char * FORMAT(BigReal X, int decimal=4)
Definition: Controller.C:1808
BigReal rescaleVelocities_sumTemps
Definition: Controller.h:257
SimpleBroadcastObject< int > scriptBarrier
Definition: Broadcasts.h:88
BigReal scriptArg1
BigReal x
Definition: Vector.h:74
RequireReduction * reductionGpuResident
Definition: Controller.h:352
int numFixedAtoms
Definition: Molecule.h:632
BigReal goTotalEnergy
Definition: Controller.h:194
float T
Definition: imd.h:38
BigReal x
Definition: Controller.C:776
int berendsenPressure_count
Definition: Controller.h:101
int monteCarloPressureFreq
NAMD_HOST_DEVICE BigReal volume(void) const
Definition: Lattice.h:293
NAMD_HOST_DEVICE int a_p() const
Definition: Lattice.h:289
static char * FEPTITLE_BACK(int X)
Definition: Controller.C:83
int num_fixed_atoms() const
Definition: Molecule.h:527
int numCalcImpropers
Definition: Molecule.h:660
SimpleBroadcastObject< BigReal > velocityRescaleFactor2
Definition: Broadcasts.h:76
RequireReduction * multigratorReduction
Definition: Controller.h:324
BigReal electEnergyPME_ti_1
Definition: Controller.h:224
Bool adaptTempAutoDt
Definition: Controller.h:438
int numAtoms
Definition: Molecule.h:586
void receivePressure(int step, int minimize=0)
Definition: Controller.C:1840
BigReal dE
Definition: Controller.h:202
char alchOutFile[NAMD_FILENAME_BUFFER_SIZE]
#define END_OF_RUN
Definition: Output.h:26
int multigratorNoseHooverChainLength
BigReal multigratorTemperatureTarget
#define GET_VECTOR(O, R, A)
Definition: ReductionMgr.h:55
BigReal multigratorPressureRelaxationTime
BigReal groGaussEnergy
Definition: Controller.h:191
void NAMD_die(const char *err_msg)
Definition: common.C:147
Tensor groupPressure_normal
Definition: Controller.h:153
BigReal exp_dE_ByRT
Definition: Controller.h:201
void run(void)
Definition: Controller.C:358
static LdbCoordinator * Object()
BigReal reassignIncr
BigReal getVirialTailCorr(const BigReal)
Tensor virial_amd
Definition: Controller.h:152
int32 tstep
Definition: imd.h:37
static int forceNeeded(int timestep)
Check if the step requires to output the forces.
Definition: Output.C:612
BigReal min_f_dot_f
Definition: Controller.h:177
void terminate(void)
Definition: Controller.C:5005
Definition: imd.h:49
int ldbSteps
Definition: Controller.h:327
SimpleBroadcastObject< BigReal > velocityRescaleFactor
Definition: Broadcasts.h:71
zVector strainRate
void publish(int tag, const T &t)
SimpleBroadcastObject< BigReal > minimizeCoefficient
Definition: Broadcasts.h:81
Bool pressureProfileEwaldOn
float Epot
Definition: imd.h:40
NAMD_HOST_DEVICE Vector b() const
Definition: Lattice.h:269
BigReal alchVdwLambdaEnd
void reassignVelocities(int)
Definition: Controller.C:1728
SimpleBroadcastObject< Vector > accelMDRescaleFactor
Definition: Broadcasts.h:91
int checkpoint_task
Definition: Controller.h:391
Random * random
Definition: Controller.h:341
void getData(int firsttimestep, int step, const Lattice &lattice, BigReal *total)
Definition: Controller.C:133
void printEnergies(int step, int minimize)
Definition: Controller.C:3639
BigReal multigratorTemperatureRelaxationTime
BigReal accelMDdVAverage
Definition: Controller.h:415
void addSample(double x)
Definition: Controller.h:63
BigReal xx
Definition: Tensor.h:17
BigReal adaptTempDt
SimpleBroadcastObject< Tensor > positionRescaleFactor
Definition: Broadcasts.h:72
MovingAverage groupPressureAverage_zz
Definition: Controller.h:467
float Evdw
Definition: imd.h:41
float Ebond
Definition: imd.h:43
void NAMD_backup_file(const char *filename, const char *extension)
Definition: common.C:235
BigReal accelMDGSigma0P
IMDSessionInfo IMDsendsettings
int numCalcOneFourNbTholes
Definition: Molecule.h:668
char restartFilename[NAMD_FILENAME_BUFFER_SIZE]
int numConstraints
Definition: Molecule.h:624
virtual ~Controller(void)
Definition: Controller.C:331
BigReal dudx
Definition: Controller.C:776
BigReal multigatorCalcEnthalpy(BigReal potentialEnergy, int step, int minimize)
Definition: Controller.C:1106
BigReal langevinPistonPeriod
NodeBroadcast * nodeBroadcast
Definition: PatchData.h:141
int num_fixed_groups() const
Definition: Molecule.h:533
BigReal electEnergy_ti_2
Definition: Controller.h:214
BigReal zz
Definition: Tensor.h:19
int64 numCalcExclusions
Definition: Molecule.h:662
void monteCarloPressure_prepare(int)
Definition: Controller.C:1267
BigReal net_dEdl_elec_1
Definition: Controller.h:219
MovingAverage pressureAverage_yx
Definition: Controller.h:454
void outputFepEnergy(int step)
Definition: Controller.C:4446
BigReal monteCarloTemp
int pairlistWarnings
Definition: Controller.h:171
void suspend(void)
Definition: Controller.C:375
unsigned int randomSeed
BigReal alchTemp
int mc_totalTry
Definition: Controller.h:310
BigReal initialTemp
CollectionMaster *const collection
Definition: Controller.h:364
BigReal * adaptTempPotEnergyAveDen
Definition: Controller.h:422
int pressureProfileAtomTypes
#define simParams
Definition: Output.C:131
BigReal * pressureProfileAverage
Definition: Controller.h:363
RequireReduction * min_reduction
Definition: Controller.h:140
BigReal recent_dEdl_lj_1
Definition: Controller.h:231
MovingAverage pressureAverage
Definition: Controller.h:449
#define CALCULATE
Definition: Controller.C:739
char accelMDGRestartFile[NAMD_FILENAME_BUFFER_SIZE]
void printFepMessage(int)
Definition: Controller.C:1694
BigReal stochRescaleTimefactor
Definition: Controller.h:279
BigReal * adaptTempPotEnergyVarNum
Definition: Controller.h:423
void calc_accelMDG_force_factor(BigReal k, BigReal E, BigReal testV, Tensor vir_orig, BigReal *dV, BigReal *factor, Tensor *vir)
Definition: Controller.C:2254
BigReal electEnergyPME_ti_2
Definition: Controller.h:225
#define PRINT_BRACKET
BigReal getCurrentLambda2(const int) const
Bool GPUresidentSingleProcessMode
BigReal cumAlchWork
Definition: Controller.h:223
BigReal getCurrentLambda(const int) const
Definition: Tensor.h:15
BigReal getLambdaDelta(void) const
BigReal adaptTempCg
Definition: Controller.h:436
BigReal xy
Definition: Tensor.h:17
Tensor pressure_normal
Definition: Controller.h:148
Tensor strainRate_old
Definition: Controller.h:290
BigReal item(int i) const
Definition: ReductionMgr.h:404
Tensor pressure_tavg
Definition: Controller.h:165
int rescaleVelocities_numTemps
Definition: Controller.h:258
BigReal y
Definition: Vector.h:74
BigReal electEnergy
Definition: Controller.h:186
void calc_accelMDG_E_k(int iE, int V_n, BigReal sigma0, BigReal Vmax, BigReal Vmin, BigReal Vavg, BigReal sigmaV, BigReal *k0, BigReal *k, BigReal *E, int *iEused, char *warn)
Definition: Controller.C:2225
int getNumStepsToRun(void)
double average() const
Definition: Controller.h:80
void resetMovingAverage()
Definition: Controller.C:656
Tensor groupPressure
Definition: Controller.h:251
ScriptTcl * getScript()
Definition: Node.C:1656
Vector monteCarloMaxVolume
Definition: Controller.h:100
BigReal ljEnergy_f
Definition: Controller.h:199
int slowFreq
Definition: Controller.h:160
void traceBarrier(int, int)
Definition: Controller.C:4977
Bool pressureProfileOn
int * adaptTempPotEnergySamples
Definition: Controller.h:426
BigReal yy
Definition: Tensor.h:18
PressureProfileReduction * ppnonbonded
Definition: Controller.h:359
MovingAverage groupPressureAverage
Definition: Controller.h:450
void printDynamicsEnergies(int)
Definition: Controller.C:3567
int64_t num_deg_freedom(int isInitialReport=0) const
Definition: Molecule.h:553
void multigratorPressure(int step, int callNumber)
Definition: Controller.C:964
BigReal tCoupleTemp
#define LIMIT_SCALING(VAR, MIN, MAX, FLAG)
Definition: Controller.C:1366
int multigratorPressureFreq
static int velocityNeeded(int timestep)
Check if the step requires to output the velocities.
Definition: Output.C:502
BigReal totalEnergy
Definition: Controller.h:185
BigReal kineticEnergyHalfstep
Definition: Controller.h:242
BigReal getVdwLambda(const BigReal) const
RequireReduction * willRequire(int setID, int size=-1)
Definition: ReductionMgr.C:539
BigReal electEnergySlow_ti_2
Definition: Controller.h:215
void tcoupleVelocities(int)
Definition: Controller.C:1746
BigReal adaptTempBetaMax
Definition: Controller.h:432
void enqueueForces(int seq)
static char * TITITLE(int X)
Definition: Controller.C:97
SimParameters *const simParams
Definition: Controller.h:342
Tensor controlPressure_normal
Definition: Controller.h:156
BigReal net_dEdl_elec_2
Definition: Controller.h:220
int64_t num_group_deg_freedom() const
Definition: Molecule.h:540
int numDrudeAtoms
Number of Drude particles.
Definition: Molecule.h:611
BigReal adaptTempAutoDt
std::ostream & iERROR(std::ostream &s)
Definition: InfoStream.C:83
void resumeAfterTraceBarrier(int)
Definition: Controller.C:4984
Definition: common.h:275
BigReal recent_dEdl_lj_2
Definition: Controller.h:232
char xstFilename[NAMD_FILENAME_BUFFER_SIZE]
#define CALLBACKLIST(LABEL, VALUE)
void sendCheckpointReq(int remote, const char *key, int task, Lattice &lat, ControllerState &cs)
Definition: Node.C:1376
BigReal accelMDGSigma0D
BigReal bondedEnergy_ti_2
Definition: Controller.h:210
int tavg_count
Definition: Controller.h:167
BigReal reassignHold
PressureProfileReduction * ppbonded
Definition: Controller.h:358
BigReal * adaptTempPotEnergyAve
Definition: Controller.h:424
void writeTiEnergyData(int step, ofstream_namd &file)
Definition: Controller.C:4771
Lattice origLattice
Definition: Controller.h:395
BigReal monteCarloPressureTarget
int numCalcTholes
Definition: Molecule.h:666
NAMD_HOST_DEVICE Vector a() const
Definition: Lattice.h:268
ofstream_namd fepFile
Definition: Controller.h:372
void rebalanceLoad(int)
Definition: Controller.C:4953
SimpleBroadcastObject< Tensor > positionRescaleFactor2
Definition: Broadcasts.h:77
void writeFepEnergyData(int step, ofstream_namd &file)
Definition: Controller.C:4735
void open(const char *_fname, std::ios_base::openmode _mode=std::ios_base::out)
Definition: fstream_namd.C:11
int numRigidBonds
Definition: Molecule.h:640
int64_t int64
Definition: common.h:39
BigReal net_dEdl_bond_1
Definition: Controller.h:217
void outputExtendedSystem(int step)
Definition: Controller.C:4795
SimpleBroadcastObject< Tensor > velocityRescaleTensor
Definition: Broadcasts.h:74
BigReal zx
Definition: Tensor.h:19
BigReal bondedEnergy_ti_1
Definition: Controller.h:209
int energies_switch
Definition: imd.h:63
Tensor positionRescaleFactor
Definition: Controller.h:291
Tensor langevinPiston_origStrainRate
Definition: Controller.h:289
BigReal goNonnativeEnergy
Definition: Controller.h:193
BigReal langevinPistonTarget
Molecule * molecule
Definition: Node.h:179
int controlNumDegFreedom
Definition: Controller.h:252
double average() const
Definition: Controller.h:35
NAMD_HOST_DEVICE Vector origin() const
Definition: Lattice.h:278
RequireReduction * reductionBasic
Definition: Controller.h:344
int numCalcAngles
Definition: Molecule.h:658
Tensor berendsenPressure_avg
Definition: Controller.h:96
BigReal getTotalPotentialEnergy(int step)
Definition: Controller.C:3572
int stepInFullRun
Definition: Controller.h:184
int outputEnergiesPrecision
int avg_count
Definition: Controller.h:164
BigReal multigratorXiT
Definition: Controller.h:317
Tensor pressure_nbond
Definition: Controller.h:149
BigReal multigratorXi
Definition: Controller.h:316
int multigratorTemperatureFreq
Tensor controlPressure_nbond
Definition: Controller.h:157
BigReal stochRescaleTemp
#define FORCE_OUTPUT
Definition: Output.h:28
BigReal kineticEnergy
Definition: Controller.h:241
void adaptTempUpdate(int step, int minimize=0)
Definition: Controller.C:2966
Tensor momentumSqrSum
Definition: Controller.h:318
double BigReal
Definition: common.h:123
int average(CompAtom *qtilde, const HGArrayVector &q, BigReal *lambda, const int n, const int m, const HGArrayBigReal &imass, const HGArrayBigReal &length2, const HGArrayInt &ial, const HGArrayInt &ibl, const HGArrayVector &refab, const BigReal tolf, const int ntrial)
Definition: HomePatch.C:6470
BigReal min_f_dot_v
Definition: Controller.h:178
static void my_sigint_handler(int sig)
Definition: Controller.C:524
BigReal ljEnergy_ti_2
Definition: Controller.h:216
int mc_totalAccept
Definition: Controller.h:310
BigReal recent_dEdl_bond_1
Definition: Controller.h:227
T get(int tag, const int expected=-1)