Simpatico  v1.10
ddMd/integrators/NvtLangevinIntegrator.cpp
1 /*
2 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
3 *
4 * Copyright 2010 - 2017, The Regents of the University of Minnesota
5 * Distributed under the terms of the GNU General Public License.
6 */
7 
8 #include "NvtLangevinIntegrator.h"
9 #include <ddMd/simulation/Simulation.h>
10 #include <ddMd/storage/AtomStorage.h>
11 #include <ddMd/storage/AtomIterator.h>
12 #include <ddMd/communicate/Exchanger.h>
13 #include <ddMd/potentials/pair/PairPotential.h>
14 #include <simp/ensembles/EnergyEnsemble.h>
15 #include <util/space/Vector.h>
16 #include <util/global.h>
17 
18 #include <iostream>
19 
20 namespace DdMd
21 {
22 
23  using namespace Util;
24  using namespace Simp;
25 
26  /*
27  * Constructor.
28  */
30  : TwoStepIntegrator(simulation),
31  dt_(0.0),
32  gamma_(0.0),
33  prefactors_(),
34  cv_(),
35  cr_()
36  { setClassName("NvtLangevinIntegrator"); }
37 
38  /*
39  * Destructor.
40  */
42  {}
43 
44  /*
45  * Read time step dt.
46  */
48  {
49  read<double>(in, "dt", dt_);
50  read<double>(in, "gamma", gamma_);
52 
53  int nAtomType = simulation().nAtomType();
54  if (!prefactors_.isAllocated()) {
55  prefactors_.allocate(nAtomType);
56  cv_.allocate(nAtomType);
57  cr_.allocate(nAtomType);
58  }
59  }
60 
65  {
66  loadParameter<double>(ar, "dt", dt_);
68 
69  int nAtomType = simulation().nAtomType();
70  if (!prefactors_.isAllocated()) {
71  prefactors_.allocate(nAtomType);
72  cv_.allocate(nAtomType);
73  cr_.allocate(nAtomType);
74  }
75  // Note: Values of prefactors_, cv_, cr_ calculated in setup()
76  }
77 
78  /*
79  * Save internal state to an archive.
80  */
82  {
83  ar << dt_;
84  ar << gamma_;
85  Integrator::save(ar);
86  }
87 
88  /*
89  * Setup at beginning of run, before entering main loop.
90  */
92  {
93  // Precondition
95  if (!energyEnsemble.isIsothermal()) {
96  UTIL_THROW("Energy ensemble is not isothermal");
97  }
98 
99  // Initialize state and clear statistics on first usage.
100  if (!isSetup()) {
101  clear();
102  setIsSetup();
103  }
104 
105  // Exchange atoms, build pair list, compute forces.
106  setupAtoms();
107 
108  // Set constants that are independent of atom type
109  double cv = (exp(-dt_*gamma_) - 1.0)/dt_;
110  double temp = energyEnsemble.temperature();
111  double d = 2.0/(1.0 + exp(-dt_*gamma_));
112  double cr = 12.0*temp*d*(1.0 - exp(-2.0*dt_*gamma_))/(dt_*dt_);
113 
114  // Loop over atom types
115  double dtHalf = 0.5*dt_;
116  double mass;
117  int nAtomType = prefactors_.capacity();
118  for (int i = 0; i < nAtomType; ++i) {
119  mass = simulation().atomType(i).mass();
120  prefactors_[i] = dtHalf/mass;
121  cv_[i] = mass*cv;
122  cr_[i] = sqrt(mass*cr);
123  }
124 
125  }
126 
127  /*
128  * First half of velocity-Verlet update.
129  */
131  {
132  Vector dv;
133  Vector dr;
134  double prefactor; // = 0.5*dt/mass
135  AtomIterator atomIter;
136 
137  // 1st half of velocity Verlet.
138  atomStorage().begin(atomIter);
139  for ( ; atomIter.notEnd(); ++atomIter) {
140  prefactor = prefactors_[atomIter->typeId()];
141 
142  dv.multiply(atomIter->force(), prefactor);
143  atomIter->velocity() += dv;
144 
145  dr.multiply(atomIter->velocity(), dt_);
146  atomIter->position() += dr;
147  }
148  }
149 
150  /*
151  * Second half of velocity-Verlet update.
152  */
154  {
156  Vector dv;
157  Vector df;
158  double cr;
159  AtomIterator atomIter;
160  int typeId, j;
161 
162  // 2nd half of velocity Verlet
163  atomStorage().begin(atomIter);
164  for ( ; atomIter.notEnd(); ++atomIter) {
165  typeId = atomIter->typeId();
166 
167  // Add Langevin drag and random force to atomic force
168  df.multiply(atomIter->velocity(), cv_[typeId]);
169  cr = cr_[typeId];
170  for (j=0; j < Dimension; ++j) {
171  df[j] += (random.uniform() - 0.5)*cr;
172  }
173  atomIter->force() += df;
174 
175  // Update velocity (half step)
176  dv.multiply(atomIter->force(), prefactors_[typeId]);
177  atomIter->velocity() += dv;
178  }
179 
180  // Notify observers of change in velocity
182  }
183 
184 }
void loadParameters(Serializable::IArchive &ar)
Load saveInterval and saveFileName from restart archive.
Definition: Integrator.cpp:83
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Signal & velocitySignal()
Signal to indicate change in atomic velocities.
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
A Vector is a Cartesian vector.
Definition: Vector.h:75
virtual void integrateStep2()
Execute second step of two-step integrator.
Vector & multiply(const Vector &v, double s)
Multiply a vector v by a scalar s.
Definition: Vector.h:686
void readParameters(std::istream &in)
Read saveInterval and saveFileName.
Definition: Integrator.cpp:65
NvtLangevinIntegrator(Simulation &simulation)
Constructor.
void setIsSetup()
Mark the integrator as having been setup at least once.
Definition: Integrator.h:240
double mass() const
Get the mass.
EnergyEnsemble & energyEnsemble()
Get the EnergyEnsemble.
File containing preprocessor macros for error handling.
Parallel domain decomposition (DD) MD simulation.
Classes used by all simpatico molecular simulations.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Main object for a domain-decomposition MD simulation.
double uniform()
Return a random floating point number x, uniformly distributed in the range 0 <= x < 1...
Definition: Random.h:203
void readParameters(std::istream &in)
Read required parameters.
AtomType & atomType(int i)
Get an AtomType descriptor by reference.
Saving / output archive for binary ostream.
void setup()
Setup state just before main loop.
A statistical ensemble for energy.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
void setupAtoms()
Setup state of atoms just before integration.
Definition: Integrator.cpp:118
virtual void integrateStep1()
Execute first step of two-step integrator.
bool isIsothermal() const
Is this an Isothermal ensemble?
void notify(const T &t)
Notify all observers.
Definition: Signal.cpp:22
Random & random()
Get the Random number generator.
bool notEnd() const
Is the current pointer not at the end of the PArray?
Utility classes for scientific computation.
Definition: accumulators.mod:1
bool isAllocated() const
Return true if the DArray has been allocated, false otherwise.
Definition: DArray.h:222
bool isSetup() const
Has the setup() method been called at least once previously?
Definition: Integrator.h:234
AtomStorage & atomStorage()
Get the AtomStorage.
void save(Serializable::OArchive &ar)
Save saveInterval and saveFileName from restart archive.
Definition: Integrator.cpp:105
Simulation & simulation()
Get the parent simulation.
int nAtomType()
Get maximum number of atom types.
Saving archive for binary istream.
A two-step velocity-Verlet style integrator.
void setClassName(const char *className)
Set class name string.
int nAtomType()
Get maximum number of atom types.
Random & random()
Get the Random number generator by reference.
Random number generator.
Definition: Random.h:46
int capacity() const
Return allocated size.
Definition: Array.h:153
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191
double temperature() const
Return the temperature.
Iterator for all atoms owned by an AtomStorage.
Definition: AtomIterator.h:24
virtual void clear()
Set integrator to initial state and clears all statistics.
Definition: Integrator.cpp:539
void begin(AtomIterator &iterator)
Set iterator to beginning of the set of atoms.
EnergyEnsemble & energyEnsemble()
Get the EnergyEnsemble by reference.