Simpatico  v1.10
NvtNhIntegrator.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 "NvtNhIntegrator.h"
9 #include <mcMd/mdSimulation/MdSystem.h>
10 #include <mcMd/simulation/Simulation.h>
11 #include <mcMd/potentials/pair/MdPairPotential.h>
12 #include <mcMd/chemistry/Molecule.h>
13 #include <mcMd/chemistry/Atom.h>
14 #include <simp/ensembles/EnergyEnsemble.h>
15 #include <simp/boundary/Boundary.h>
16 #include <util/space/Vector.h>
17 #include <util/archives/Serializable_includes.h>
18 
19 namespace McMd
20 {
21 
22  using namespace Util;
23  using namespace Simp;
24 
25  /*
26  * Constructor.
27  */
29  : MdIntegrator(system),
30  T_target_(1.0),
31  T_kinetic_(1.0),
32  xi_(0.0),
33  xiDot_(0.0),
34  tauT_(1.0),
35  nuT_(1.0),
36  energyEnsemblePtr_(0)
37  {
38  // Note: Within the constructor, the method parameter "system" hides
39  // the system() method name.
40 
41  // Precondition
42  if (!system.energyEnsemble().isIsothermal() ) {
43  UTIL_THROW("System energy ensemble is not isothermal");
44  }
45 
46  energyEnsemblePtr_ = &(system.energyEnsemble());
47  T_target_ = energyEnsemblePtr_->temperature();
48  T_kinetic_ = T_target_;
49 
50  setClassName("NvtNhIntegrator");
51  }
52 
53  /*
54  * Destructor.
55  */
57  {}
58 
59  /*
60  * Read parameter and configuration files, initialize system.
61  */
62  void NvtNhIntegrator::readParameters(std::istream &in)
63  {
64  read<double>(in, "dt", dt_);
65  read<double>(in, "tauT", tauT_);
66  nuT_ = 1.0/tauT_;
67  T_target_ = energyEnsemblePtr_->temperature();
68  T_kinetic_ = T_target_;
69  xiDot_ = 0.0;
70  xi_ = 0.0;
71 
72  int nAtomType = simulation().nAtomType();
73  if (!prefactors_.isAllocated()) {
74  prefactors_.allocate(nAtomType);
75  }
76 
77  }
78 
79  /*
80  * Load the internal state to an archive.
81  */
83  {
84  loadParameter<double>(ar, "dt", dt_);
85  loadParameter<double>(ar, "tauT", tauT_);
86  ar & nuT_;
87  ar & T_target_;
88  ar & T_kinetic_;
89  ar & xiDot_;
90  ar & xi_;
91  ar & prefactors_;
92  }
93 
94  /*
95  * Save the internal state to an archive.
96  */
98  {
99  ar & dt_;
100  ar & tauT_;
101  ar & nuT_;
102  ar & T_target_;
103  ar & T_kinetic_;
104  ar & xiDot_;
105  ar & xi_;
106  ar & prefactors_;
107  }
108 
110  {
111  double mass, dtHalf;
112  int nAtomType = simulation().nAtomType();
113  int nAtom = system().nAtom();
114 
115  T_kinetic_ = system().kineticEnergy()*2.0/double(3*nAtom);
116  T_target_ = energyEnsemblePtr_->temperature();
117  xiDot_ = (T_kinetic_/T_target_ -1.0)*nuT_*nuT_;
118  xi_ = 0.0;
119 
120  dtHalf = 0.5*dt_;
121  for (int i = 0; i < nAtomType; ++i) {
122  mass = simulation().atomType(i).mass();
123  prefactors_[i] = dtHalf/mass;
124  }
127  }
128 
129  /*
130  * Nose-Hoover integrator step.
131  *
132  * This implements a reversible Velocity-Verlet MD NVT integrator step.
133  *
134  * Reference: Winkler, Kraus, and Reineker, J. Chem. Phys. 102, 9018 (1995).
135  */
137  {
138  Vector dv;
139  Vector dr;
140  System::MoleculeIterator molIter;
141  double dtHalf = 0.5*dt_;
142  double prefactor;
143  double factor;
144  Molecule::AtomIterator atomIter;
145  int iSpecies, nSpecies;
146  int nAtom;
147 
148  T_target_ = energyEnsemblePtr_->temperature();
149  nSpecies = simulation().nSpecies();
150  nAtom = system().nAtom();
151 
152  factor = exp(-dtHalf*(xi_ + xiDot_*dtHalf));
153 
154  // 1st half velocity Verlet, loop over atoms
155  for (iSpecies = 0; iSpecies < nSpecies; ++iSpecies) {
156  system().begin(iSpecies, molIter);
157  for ( ; molIter.notEnd(); ++molIter) {
158 
159  molIter->begin(atomIter);
160  for ( ; atomIter.notEnd(); ++atomIter) {
161 
162  atomIter->velocity() *= factor;
163 
164  prefactor = prefactors_[atomIter->typeId()];
165  dv.multiply(atomIter->force(), prefactor);
166  //dv.multiply(atomIter->force(), dtHalf);
167 
168  atomIter->velocity() += dv;
169  dr.multiply(atomIter->velocity(), dt_);
170 
171  atomIter->position() += dr;
172 
173  }
174 
175  }
176  }
179 
180  // First half of update of xi_
181  xi_ += xiDot_*dtHalf;
182 
183  #ifndef SIMP_NOPAIR
184  // Rebuild the pair list if necessary
185  if (!system().pairPotential().isPairListCurrent()) {
187  }
188  #endif
189 
191 
192  // 2nd half velocity Verlet, loop over atoms
193  for (iSpecies=0; iSpecies < nSpecies; ++iSpecies) {
194  system().begin(iSpecies, molIter);
195  for ( ; molIter.notEnd(); ++molIter) {
196  for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {
197  prefactor = prefactors_[atomIter->typeId()];
198  dv.multiply(atomIter->force(), prefactor);
199  atomIter->velocity() += dv;
200  atomIter->velocity() *=factor;
201  }
202  }
203  }
205 
206  // Update xiDot and complete update of xi_
207  T_kinetic_ = system().kineticEnergy()*2.0/double(3*nAtom);
208  xiDot_ = (T_kinetic_/T_target_ -1.0)*nuT_*nuT_;
209  xi_ += xiDot_*dtHalf;
210 
211  }
212 
213 }
A Vector is a Cartesian vector.
Definition: Vector.h:75
virtual ~NvtNhIntegrator()
Destructor.
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
int nAtom() const
Return the total number of atoms in this System.
Definition: System.cpp:1216
NvtNhIntegrator(MdSystem &system)
Constructor.
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 & multiply(const Vector &v, double s)
Multiply a vector v by a scalar s.
Definition: Vector.h:686
virtual void save(Serializable::OArchive &ar)
Save the internal state to an archive.
EnergyEnsemble & energyEnsemble() const
Get the EnergyEnsemble by reference.
Definition: System.h:1095
Classes used by all simpatico molecular simulations.
Simulation & simulation()
Get parent Simulation by reference.
Definition: MdIntegrator.h:111
Abstract base for molecular dynamics integrators.
Definition: MdIntegrator.h:30
Saving / output archive for binary ostream.
MdPairPotential & pairPotential() const
Return MdPairPotential by reference.
Definition: MdSystem.h:520
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
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
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
Forward iterator for an Array or a C array.
Definition: ArrayIterator.h:39
double kineticEnergy() const
Compute and return total kinetic energy.
Definition: MdSystem.cpp:1003
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
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191
virtual void setup()
Setup auxiliary parameters of integrator, just before main loop.
double temperature() const
Return the temperature.
int nAtomType() const
Get the number of atom types.
virtual void readParameters(std::istream &in)
Read parameters from file and initialize.
virtual void step()
Take a complete NVT MD integration step.
virtual void loadParameters(Serializable::IArchive &ar)
Load the internal state to an archive.