Simpatico  v1.10
NvtIntegrator.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 "NvtIntegrator.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/mpi/MpiLoader.h>
17 #include <util/misc/Timer.h>
18 #include <util/global.h>
19 
20 #include <iostream>
21 
22 namespace DdMd
23 {
24 
25  using namespace Util;
26  using namespace Simp;
27 
28  /*
29  * Constructor.
30  */
32  : TwoStepIntegrator(simulation),
33  prefactors_(),
34  T_target_(1.0),
35  T_kinetic_(1.0),
36  xi_(0.0),
37  xiDot_(0.0),
38  tauT_(1.0),
39  nuT_(1.0)
40  {
41  setClassName("NvtIntegrator");
42 
43  // Note: Within this constructor, the method parameter "simulation"
44  // hides the simulation() method name.
45 
46  // Precondition
47  if (!simulation.energyEnsemble().isIsothermal() ) {
48  UTIL_THROW("Simulation energy ensemble is not isothermal");
49  }
50  }
51 
52  /*
53  * Destructor.
54  */
56  {}
57 
58  /*
59  * Read parameter and configuration files, initialize simulation.
60  */
61  void NvtIntegrator::readParameters(std::istream &in)
62  {
63  read<double>(in, "dt", dt_);
64  read<double>(in, "tauT", tauT_);
66 
67  nuT_ = 1.0/tauT_;
68  int nAtomType = simulation().nAtomType();
69  if (!prefactors_.isAllocated()) {
70  prefactors_.allocate(nAtomType);
71  }
72  }
73 
78  {
79  loadParameter<double>(ar, "dt", dt_);
80  loadParameter<double>(ar, "tauT", tauT_);
82 
83  MpiLoader<Serializable::IArchive> loader(*this, ar);
84  loader.load(nuT_);
85  loader.load(xi_);
86 
87  int nAtomType = simulation().nAtomType();
88  if (!prefactors_.isAllocated()) {
89  prefactors_.allocate(nAtomType);
90  }
91  }
92 
93  /*
94  * Read time step dt.
95  */
97  {
98  ar << dt_;
99  ar << tauT_;
100  Integrator::save(ar);
101  ar << nuT_;
102  ar << xi_;
103  }
104 
105  /*
106  * Initialize xi_ and xiDot_ to zero.
107  */
109  { xi_ = 0.0; }
110 
111 
112  /*
113  * Setup parameters before beginning of run.
114  */
116  {
117 
118  // Initialize state and clear statistics on first usage.
119  if (!isSetup()) {
120  clear();
121  setIsSetup();
122  }
123 
124  // Exchange atoms, build pair list, compute forces.
125  setupAtoms();
126 
127  // Calculate prefactors for acceleration
128  double dtHalf = 0.5*dt_;
129  double mass;
130  int nAtomType = prefactors_.capacity();
131  for (int i = 0; i < nAtomType; ++i) {
132  mass = simulation().atomType(i).mass();
133  prefactors_[i] = dtHalf/mass;
134  }
135 
136  // Initialize nAtom_, xiDot_
138  #ifdef UTIL_MPI
139  atomStorage().computeNAtomTotal(domain().communicator());
140  #endif
141  if (domain().isMaster()) {
142  T_target_ = simulation().energyEnsemble().temperature();
143  nAtom_ = atomStorage().nAtomTotal();
144  T_kinetic_ = simulation().kineticEnergy()*2.0/double(3*nAtom_);
145  xiDot_ = (T_kinetic_/T_target_ -1.0)*nuT_*nuT_;
146  }
147  #ifdef UTIL_MPI
148  bcast(domain().communicator(), xiDot_, 0);
149  #endif
150 
151  }
152 
154  {
155  Vector dv;
156  Vector dr;
157  double prefactor; // = 0.5*dt/mass
158  double dtHalf = 0.5*dt_;
159  double factor;
160  AtomIterator atomIter;
161 
162 
163  T_target_ = simulation().energyEnsemble().temperature();
164  factor = exp(-dtHalf*(xi_ + xiDot_*dtHalf));
165 
166  // 1st half of velocity Verlet.
167  atomStorage().begin(atomIter);
168  for ( ; atomIter.notEnd(); ++atomIter) {
169  atomIter->velocity() *= factor;
170  prefactor = prefactors_[atomIter->typeId()];
171  dv.multiply(atomIter->force(), prefactor);
172  atomIter->velocity() += dv;
173  dr.multiply(atomIter->velocity(), dt_);
174  atomIter->position() += dr;
175  }
176  }
177 
179  {
180  Vector dv;
181  double prefactor; // = 0.5*dt/mass
182  double dtHalf = 0.5*dt_;
183  double factor;
184  AtomIterator atomIter;
185 
186  T_target_ = simulation().energyEnsemble().temperature();
187  factor = exp(-dtHalf*(xi_ + xiDot_*dtHalf));
188 
189  // 2nd half of velocity Verlet
190  atomStorage().begin(atomIter);
191  for ( ; atomIter.notEnd(); ++atomIter) {
192  prefactor = prefactors_[atomIter->typeId()];
193  dv.multiply(atomIter->force(), prefactor);
194  atomIter->velocity() += dv;
195  atomIter->velocity() *=factor;
196  }
197 
198  // Notify observers of change in velocity
200 
201  // Update xiDot_ and xi_
203  if (domain().isMaster()) {
204  xi_ += xiDot_*dtHalf;
205  T_kinetic_ = simulation().kineticEnergy()*2.0/double(3*nAtom_);
206  xiDot_ = (T_kinetic_/T_target_ - 1.0)*nuT_*nuT_;
207  xi_ += xiDot_*dtHalf;
208  }
209  #ifdef UTIL_MPI
210  bcast(domain().communicator(), xiDot_, 0);
211  bcast(domain().communicator(), xi_, 0);
212  #endif
213 
214  }
215 
216 }
void loadParameters(Serializable::IArchive &ar)
Load saveInterval and saveFileName from restart archive.
Definition: Integrator.cpp:83
~NvtIntegrator()
Destructor.
Signal & velocitySignal()
Signal to indicate change in atomic velocities.
A Vector is a Cartesian vector.
Definition: Vector.h:75
void readParameters(std::istream &in)
Read required parameters.
int nAtomTotal() const
Get total number of atoms on all processors.
double kineticEnergy()
Return precomputed total kinetic energy.
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
void setIsSetup()
Mark the integrator as having been setup at least once.
Definition: Integrator.h:240
double mass() const
Get the mass.
File containing preprocessor macros for error handling.
Parallel domain decomposition (DD) MD simulation.
Classes used by all simpatico molecular simulations.
Main object for a domain-decomposition MD simulation.
AtomType & atomType(int i)
Get an AtomType descriptor by reference.
Saving / output archive for binary ostream.
virtual void integrateStep2()
Execute secodn step of two-step integrator.
#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
void bcast(MPI::Intracomm &comm, T &data, int root)
Broadcast a single T value.
Definition: MpiSendRecv.h:134
void setup()
Setup state just before integration.
bool isIsothermal() const
Is this an Isothermal ensemble?
virtual void initDynamicalState()
Initialize internal dynamical state variables to default value.
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
void load(Data &value)
Load and broadcast a single Data value.
Definition: MpiLoader.h:137
Domain & domain()
Get the Domain.
bool isAllocated() const
Return true if the DArray has been allocated, false otherwise.
Definition: DArray.h:222
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
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
void computeNAtomTotal(MPI::Intracomm &communicator)
Compute the total number of local atoms on all processors.
Simulation & simulation()
Get the parent simulation.
int nAtomType()
Get maximum number of atom types.
Saving archive for binary istream.
NvtIntegrator(Simulation &simulation)
Constructor.
Provides methods for MPI-aware loading of data from input archive.
Definition: MpiLoader.h:43
A two-step velocity-Verlet style integrator.
void setClassName(const char *className)
Set class name string.
int nAtomType()
Get maximum number of atom types.
virtual void integrateStep1()
Execute first step of two-step integrator.
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.
void computeKineticEnergy()
Compute total kinetic energy.
Iterator for all atoms owned by an AtomStorage.
Definition: AtomIterator.h:24
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
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.