Simpatico  v1.10
mcMd/mdIntegrators/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 <mcMd/mdSimulation/MdSystem.h>
10 #include <mcMd/simulation/Simulation.h>
11 #include <mcMd/potentials/pair/MdPairPotential.h>
12 #include <simp/boundary/Boundary.h>
13 #include <simp/ensembles/EnergyEnsemble.h>
14 #include <mcMd/chemistry/Molecule.h>
15 #include <mcMd/chemistry/Atom.h>
16 #include <util/space/Vector.h>
17 #include <util/archives/Serializable_includes.h>
18 
19 //#define USE_ITERATOR 1
20 namespace McMd
21 {
22 
23  using namespace Util;
24  using namespace Simp;
25 
26  /*
27  * Constructor.
28  */
30  : MdIntegrator(system),
31  prefactors_(),
32  cv_(),
33  cr_(),
34  gamma_()
35  { setClassName("NvtLangevinIntegrator"); }
36 
37  /*
38  * Destructor.
39  */
41  {}
42 
43  /*
44  * Read parameter and configuration files, initialize system.
45  */
47  {
48  read<double>(in, "dt", dt_);
49  read<double>(in, "gamma", gamma_);
50  int nAtomType = simulation().nAtomType();
51  prefactors_.allocate(nAtomType);
52  cv_.allocate(nAtomType);
53  cr_.allocate(nAtomType);
54  }
55 
56  /*
57  * Load the internal state to an archive.
58  */
60  {
61  loadParameter<double>(ar, "dt", dt_);
62  int nAtomType = simulation().nAtomType();
63  prefactors_.allocate(nAtomType);
64  ar & prefactors_;
65  ar & cv_;
66  ar & cr_;
67  }
68 
69  /*
70  * Save the internal state to an archive.
71  */
73  {
74  ar & dt_;
75  ar & gamma_;
76  ar & prefactors_;
77  ar & cv_;
78  ar & cr_;
79  }
80 
81  /*
82  * Initialize constants.
83  */
85  {
86  const EnergyEnsemble& energyEnsemble = system().energyEnsemble();
87  if (!energyEnsemble.isIsothermal()) {
88  UTIL_THROW("Energy ensemble is not isothermal");
89  }
90  double cv = (exp(-dt_*gamma_) - 1.0)/dt_;
91  double temp = energyEnsemble.temperature();
92  double d = 2.0/(1.0 + exp(-dt_*gamma_));
93  double cr = 12.0*temp*d*(1.0 - exp(-2.0*dt_*gamma_))/(dt_*dt_);
94 
95  // Loop over atom types
96  double mass;
97  int nAtomType = prefactors_.capacity();
98  for (int i = 0; i < nAtomType; ++i) {
99  mass = simulation().atomType(i).mass();
100  prefactors_[i] = 0.5*dt_/mass;
101  cv_[i] = mass*cv;
102  cr_[i] = sqrt(mass*cr);
103  }
106 
107  }
108 
109  /*
110  * Verlet MD NVE integrator step
111  *
112  * This method implements the algorithm:
113  *
114  * vm(n) = v(n) + 0.5*a(n)*dt
115  * x(n+1) = x(n) + vm(n)*dt
116  *
117  * calculate determinstic force f(n+1)
118  * add Langevin force, calculated using vm(n)
119  *
120  * v(n+1) = vm(n) + 0.5*f(n+1)*dt/m
121  *
122  * where x is position, v is velocity, and f is force.
123  */
125  {
126  Vector dr;
127  Vector dv;
128  Vector df;
129  double cr;
130  System::MoleculeIterator molIter;
131  int iSpecies, nSpecies, typeId;
132 
133  nSpecies = simulation().nSpecies();
134 
135  // 1st half velocity Verlet, loop over atoms
136  #if USE_ITERATOR
137  Molecule::AtomIterator atomIter;
138  for (iSpecies=0; iSpecies < nSpecies; ++iSpecies) {
139  system().begin(iSpecies, molIter);
140  for ( ; molIter.notEnd(); ++molIter) {
141  molIter->begin(atomIter);
142  for ( ; atomIter.notEnd(); ++atomIter) {
143  typeId = atomIter->typeId();
144 
145  // Update velocity one half step, prefactor = dt/(2m)
146  dv.multiply(atomIter->force(), prefactors_[typeId]);
147  atomIter->velocity() += dv;
148 
149  // Update position (full step)
150  dr.multiply(atomIter->velocity(), dt_);
151  atomIter->position() += dr;
152  }
153  }
154  }
155  #else
156  Atom* atomPtr;
157  int ia;
158  for (iSpecies=0; iSpecies < nSpecies; ++iSpecies) {
159  system().begin(iSpecies, molIter);
160  for ( ; molIter.notEnd(); ++molIter) {
161  for (ia=0; ia < molIter->nAtom(); ++ia) {
162  atomPtr = &molIter->atom(ia);
163  typeId = atomPtr->typeId();
164 
165  // Update velocity one half step, prefactor = dt/(2m)
166  dv.multiply(atomPtr->force(), prefactors_[typeId]);
167  atomPtr->velocity() += dv;
168 
169  // Position update (full step)
170  dr.multiply(atomPtr->velocity(), dt_);
171  atomPtr->position() += dr;
172  }
173  }
174  }
175  #endif
178 
179  #ifndef SIMP_NOPAIR
180  if (!system().pairPotential().isPairListCurrent()) {
182  }
183  #endif
184 
185  // Calculate conservative force
187 
188  // 2nd half velocity Verlet, loop over atoms
189  Random& random = simulation().random();
190  int j;
191  #if USE_ITERATOR
192  for (iSpecies=0; iSpecies < nSpecies; ++iSpecies) {
193  system().begin(iSpecies, molIter);
194  for ( ; molIter.notEnd(); ++molIter) {
195  molIter->begin(atomIter);
196  for ( ; atomIter.notEnd(); ++atomIter) {
197  typeId = atomIter->typeId();
198 
199  // Add Langevin drag and random force to atomic force
200  df.multiply(atomIter->velocity(), cv_[typeId]);
201  cr = cr_[typeId];
202  for (j=0; j < Dimension; ++j) {
203  df[j] += (random.uniform() - 0.5)*cr;
204  }
205  atomIter->force() += df;
206 
207  // Velocity update by half step
208  dv.multiply(atomIter->force(), prefactors_[typeId]);
209  atomIter->velocity() += dv;
210  }
211  }
212  }
213  #else
214  for (iSpecies=0; iSpecies < nSpecies; ++iSpecies) {
215  system().begin(iSpecies, molIter);
216  for ( ; molIter.notEnd(); ++molIter) {
217  for (ia=0; ia < molIter->nAtom(); ++ia) {
218  atomPtr = &molIter->atom(ia);
219  typeId = atomPtr->typeId();
220 
221  // Add Langevin drag and random force to atomic force
222  df.multiply(atomPtr->velocity(), cv_[typeId]);
223  cr = cr_[typeId];
224  for (j=0; j < Dimension; ++j) {
225  df[j] += (random.uniform() - 0.5)*cr;
226  }
227  atomPtr->force() += df;
228 
229  // Velocity update by half step
230  dv.multiply(atomPtr->force(), prefactors_[typeId]);
231  atomPtr->velocity() += dv;
232  }
233  }
234  }
235  #endif
237 
238  }
239 
240 }
241 #undef USE_ITERATOR
virtual void save(Serializable::OArchive &ar)
Save the internal state to an archive.
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
virtual void setup()
Setup private variables before main loop.
A Vector is a Cartesian vector.
Definition: Vector.h:75
void calculateForces()
Compute all forces in this System.
Definition: MdSystem.cpp:857
void begin(int speciesId, MoleculeIterator &iterator)
Initialize an iterator for molecules of one species in this System.
Definition: System.h:1147
Vector & velocity()
Get atomic velocity Vector by reference.
bool notEnd() const
Is the current pointer not at the end of the array?
Definition: ArrayIterator.h:83
Signal & positionSignal()
Signal to indicate change in atomic positions.
Definition: MdSystem.h:669
Vector & force()
Get atomic force Vector by reference.
Vector & multiply(const Vector &v, double s)
Multiply a vector v by a scalar s.
Definition: Vector.h:686
EnergyEnsemble & energyEnsemble() const
Get the EnergyEnsemble by reference.
Definition: System.h:1095
virtual void loadParameters(Serializable::IArchive &ar)
Load the internal state to an archive.
Classes used by all simpatico molecular simulations.
Simulation & simulation()
Get parent Simulation by reference.
Definition: MdIntegrator.h:111
double uniform()
Return a random floating point number x, uniformly distributed in the range 0 <= x < 1...
Definition: Random.h:203
Abstract base for molecular dynamics integrators.
Definition: MdIntegrator.h:30
virtual void step()
Take a complete NVE MD integration step.
Saving / output archive for binary ostream.
MdPairPotential & pairPotential() const
Return MdPairPotential by reference.
Definition: MdSystem.h:520
A statistical ensemble for energy.
const AtomType & atomType(int i) const
Get a single AtomType object by const reference.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
int typeId() const
Get type index for this Atom.
bool isIsothermal() const
Is this an Isothermal ensemble?
MdSystem & system()
Get parent MdSystem by reference.
Definition: MdIntegrator.h:105
void notify(const T &t)
Notify all observers.
Definition: Signal.cpp:22
A point particle within a Molecule.
bool notEnd() const
Is the current pointer not at the end of the PArray?
Utility classes for scientific computation.
Definition: accumulators.mod:1
Forward iterator for an Array or a C array.
Definition: ArrayIterator.h:39
Forward iterator for a PArray.
Definition: ArraySet.h:19
double dt_
Integrator time step.
Definition: MdIntegrator.h:79
Signal & velocitySignal()
Signal to indicate change in atomic velocities.
Definition: MdSystem.h:675
Saving archive for binary istream.
double mass() const
Get the mass.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
int nSpecies() const
Get the number of Species in this Simulation.
void buildPairList()
Build the internal PairList.
void setClassName(const char *className)
Set class name string.
A System for Molecular Dynamics simulation.
Definition: MdSystem.h:68
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.
const Vector & position() const
Get the position Vector by const reference.
int nAtomType() const
Get the number of atom types.
Random & random()
Get the random number generator by reference.
virtual void readParameters(std::istream &in)
Read parameters from file and initialize this MdSystem.