Simpatico  v1.10
ComMSD.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 "ComMSD.h"
9 #include <mcMd/simulation/System.h> // base class template parameter
10 #include <mcMd/simulation/Simulation.h>
11 #include <mcMd/chemistry/Molecule.h>
12 #include <mcMd/chemistry/Atom.h>
13 #include <simp/boundary/Boundary.h>
14 #include <simp/species/Species.h> // forward declaration in header
15 #include <util/space/Dimension.h>
16 #include <util/archives/Serializable_includes.h>
17 #include <util/global.h>
18 
19 namespace McMd
20 {
21 
22  using namespace Util;
23  using namespace Simp;
24 
25  /*
26  * Constructor.
27  */
29  : SystemAnalyzer<System>(system),
30  outputFile_(),
31  accumulator_(),
32  truePositions_(),
33  oldPositions_(),
34  shifts_(),
35  speciesId_(-1),
36  nMolecule_(-1),
37  nAtom_(-1),
38  capacity_(-1),
39  isInitialized_(false)
40  { setClassName("ComMSD"); }
41 
42  /*
43  * Read parameters from file, and allocate data array.
44  */
45  void ComMSD::readParameters(std::istream& in)
46  {
47  // Read interval and parameters for AutoCorrArray
48  readInterval(in);
50  read<int>(in, "speciesId", speciesId_);
51  read<int>(in, "capacity", capacity_);
52 
53  // Validate parameters
54  if (speciesId_ < 0) UTIL_THROW("Negative speciesId");
55  if (speciesId_ >= system().simulation().nSpecies())
56  UTIL_THROW("speciesId > nSpecies");
57  if (capacity_ <= 0) UTIL_THROW("Negative capacity");
58 
59  // Maximum possible number of molecules of this species
60  int speciesCapacity;
61  speciesCapacity = system().simulation().species(speciesId_).capacity();
62 
63  // Allocate local arrays
64  truePositions_.allocate(speciesCapacity);
65  oldPositions_.allocate(speciesCapacity);
66  shifts_.allocate(speciesCapacity);
67 
68  // Allocate memory for the AutoCorrArray accumulator
69  accumulator_.setParam(speciesCapacity, capacity_);
70 
71  // Get number of atoms per molecule.
72  nAtom_ = system().simulation().species(speciesId_).nAtom();
73 
74  isInitialized_ = true;
75  }
76 
77  /*
78  * Load state from an archive.
79  */
81  {
83  loadParameter<int>(ar, "speciesId", speciesId_);
84  loadParameter<int>(ar, "capacity", capacity_);
85  ar & nAtom_;
86 
87  // Validate parameters
88  if (speciesId_ < 0) {
89  UTIL_THROW("Negative speciesId");
90  }
91  if (speciesId_ >= system().simulation().nSpecies()) {
92  UTIL_THROW("speciesId > nSpecies");
93  }
94  if (capacity_ <= 0) {
95  UTIL_THROW("Negative capacity");
96  }
97  if (nAtom_ != system().simulation().species(speciesId_).nAtom()) {
98  UTIL_THROW("Inconsistent values for nAtom");
99  }
100 
101  // Maximum possible number of molecules of this species
102  int speciesCapacity;
103  speciesCapacity = system().simulation().species(speciesId_).capacity();
104 
105  // Allocate memory
106  truePositions_.allocate(speciesCapacity);
107  oldPositions_.allocate(speciesCapacity);
108  shifts_.allocate(speciesCapacity);
109  accumulator_.setParam(speciesCapacity, capacity_);
110 
111  // Finish reading internal state
112  ar & accumulator_;
113  ar & truePositions_;
114  ar & oldPositions_;
115  ar & shifts_;
116  ar & nMolecule_;
117  }
118 
119  /*
120  * Save state to archive.
121  */
123  { ar & *this; }
124 
125  /*
126  * Set number of molecules and initialize state.
127  */
129  {
130  // Precondition: Confirm that readParam was called
131  if (!isInitialized_)
132  UTIL_THROW("Analyzer not initialized");
133 
134  // Get number of molecules of this species in this System.
135  nMolecule_ = system().nMolecule(speciesId_);
136  if (nMolecule_ <= 0)
137  UTIL_THROW("nMolecule_ <= 0");
138  accumulator_.setNEnsemble(nMolecule_);
139 
140  accumulator_.clear();
141 
142  // Store initial positions, and set initial shift vectors.
143  Vector r;
144  for (int i = 0; i < nMolecule_; ++i) {
145  r = system().molecule(speciesId_, i).atom(0).position();
146  system().boundary().shift(r);
147  oldPositions_[i] = r;
148  shifts_[i] = IntVector(0);
149  }
150 
151  }
152 
153  /*
154  * Evaluate end-to-end vectors of all chains, add to ensemble.
155  */
156  void ComMSD::sample(long iStep)
157  {
158  if (!isAtInterval(iStep)) return;
159 
160  // Confirm that nMolecule has remained constant, and nMolecule > 0.
161  if (nMolecule_ <= 0) {
162  UTIL_THROW("nMolecule <= 0");
163  }
164  if (nMolecule_ != system().nMolecule(speciesId_)) {
165  UTIL_THROW("Number of molecules has changed.");
166  }
167 
168  Vector r;
169  IntVector shift;
170  Vector lengths = system().boundary().lengths();
171  int i, j;
172  for (i = 0; i < nMolecule_; ++i) {
173 
174  r = system().molecule(speciesId_, i).atom(0).position();
175  system().boundary().shift(r);
176 
177  // Compare current r to previous position, oldPositions_[i]
178  system().boundary().distanceSq(r, oldPositions_[i], shift);
179 
180  // If atom 0 crossed a boundary, increment its shift vector
181  shifts_[i] += shift;
182 
183  // Store current position in box for comparison to next one
184  oldPositions_[i] = r;
185 
186  // Add the other particle's positions to C.O.M.
187  moleculeCom(i, r);
188 
189  // Reconstruct true position
190  for (j = 0; j < Dimension; ++j) {
191  truePositions_[i][j] = r[j] + double(shifts_[i][j])*lengths[j];
192  }
193 
194  }
195  accumulator_.sample(truePositions_);
196 
197  }
198 
199  /*
200  * Output results to file after simulation is completed.
201  */
203  {
204 
205  // Echo parameter to analyzer log file
206  fileMaster().openOutputFile(outputFileName(".prm"), outputFile_);
207  writeParam(outputFile_);
208  outputFile_ << std::endl;
209  outputFile_ << std::endl;
210  outputFile_ << "nMolecule " << accumulator_.nEnsemble() << std::endl;
211  outputFile_ << "bufferCapacity " << accumulator_.bufferCapacity()
212  << std::endl;
213  outputFile_ << "nSample " << accumulator_.nSample() << std::endl;
214  outputFile_ << std::endl;
215  outputFile_ << "Format of *.dat file:" << std::endl;
216  outputFile_ << "[i] [MSD]"
217  << std::endl;
218  outputFile_.close();
219 
220  // Output statistical analysis to separate data file
221  fileMaster().openOutputFile(outputFileName(".dat"), outputFile_);
222  accumulator_.output(outputFile_);
223  outputFile_.close();
224  }
225 
226  /*
227  * Evaluate center of mass of a single molecule, given a starting vector R0.
228  */
229  void ComMSD::moleculeCom(int iMol, Vector &R0)
230  {
231  Vector R = R0, r1, r2, dr;
232 
233  // Assuming a linear chain (including Ring molecules).
234  for (int i = 1; i < nAtom_-1; ++i) {
235  r1 = system().molecule(speciesId_, iMol).atom(i-1).position();
236  r2 = system().molecule(speciesId_, iMol).atom(i).position();
237  system().boundary().distanceSq(r2, r1, dr);
238  R += dr;
239  R0 += R;
240  }
241 
242  // Do the average.
243  R0 /= double(nAtom_);
244  }
245 
246 }
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
A Vector is a Cartesian vector.
Definition: Vector.h:75
int nAtom() const
Get number of atoms per molecule for this Species.
double distanceSq(const Vector &r1, const Vector &r2) const
Return square distance between positions r1 and r2.
virtual void sample(long iStep)
Evaluate center of mass displacement of all chains and add to ensemble.
Definition: ComMSD.cpp:156
const Vector & lengths() const
Get Vector of unit cell lengths by const reference.
void openOutputFile(const std::string &filename, std::ofstream &out, std::ios_base::openmode mode=std::ios_base::out) const
Open an output file.
Definition: FileMaster.cpp:290
virtual void loadParameters(Serializable::IArchive &ar)
Load parameters from archive.
A set of interacting Molecules enclosed by a Boundary.
Definition: System.h:115
System & system()
Return reference to parent system.
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
void readOutputFileName(std::istream &in)
Read outputFileName from file.
Saving / output archive for binary ostream.
Molecule & molecule(int speciesId, int moleculeId)
Get a specific Molecule in this System, by integer index.
Definition: System.h:1137
ComMSD(System &system)
Constructor.
Definition: ComMSD.cpp:28
int nMolecule(int speciesId) const
Get the number of molecules of one Species in this System.
Definition: System.h:1128
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
Simulation & simulation() const
Get the parent Simulation by reference.
Definition: System.h:1055
virtual void writeParam(std::ostream &out)
Write all parameters to an output stream.
virtual void readParameters(std::istream &in)
Read parameters from file.
Definition: ComMSD.cpp:45
void readInterval(std::istream &in)
Read interval from file, with error checking.
Utility classes for scientific computation.
Definition: accumulators.mod:1
void shift(Vector &r) const
Shift Cartesian Vector r to its primary image.
Template for Analyzer associated with one System.
Boundary & boundary() const
Get the Boundary by reference.
Definition: System.h:1064
Saving archive for binary istream.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
virtual void output()
Output results to file after simulation is completed.
Definition: ComMSD.cpp:202
void setClassName(const char *className)
Set class name string.
An IntVector is an integer Cartesian vector.
Definition: IntVector.h:73
const Atom & atom(int localId) const
Get a specific Atom in this Molecule.
int capacity() const
Maximum allowed number of molecules for this Species.
virtual void save(Serializable::OArchive &ar)
Save state to archive.
Definition: ComMSD.cpp:122
FileMaster & fileMaster()
Get the FileMaster by reference.
virtual void setup()
Determine number of molecules and allocate memory.
Definition: ComMSD.cpp:128
bool isAtInterval(long counter) const
Return true iff counter is a multiple of the interval.
const std::string & outputFileName() const
Return outputFileName string.
const Vector & position() const
Get the position Vector by const reference.
virtual void loadParameters(Serializable::IArchive &ar)
Load state from an archive.
Definition: ComMSD.cpp:80
Species & species(int i)
Get a specific Species by reference.