Simpatico  v1.10
RingRouseAutoCorr.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 "RingRouseAutoCorr.h"
9 #include <mcMd/simulation/Simulation.h>
10 #include <mcMd/chemistry/Molecule.h>
11 #include <mcMd/chemistry/Atom.h>
12 #include <simp/species/Species.h>
13 #include <simp/boundary/Boundary.h>
14 #include <util/misc/FileMaster.h>
15 #include <util/archives/Serializable_includes.h>
16 
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  data_(),
33  projector_(),
34  speciesId_(-1),
35  nMolecule_(-1),
36  nAtom_(-1),
37  p_(-1),
38  capacity_(-1),
39  isInitialized_(false)
40  { setClassName("RingRouseAutoCorr"); }
41 
42  /*
43  * Destructor.
44  */
46  {}
47 
48  /*
49  * Read parameters from file, and allocate data array.
50  */
51  void RingRouseAutoCorr::readParameters(std::istream& in)
52  {
53  readInterval(in);
55  read<int>(in, "speciesId", speciesId_);
56  read<int>(in, "p", p_);
57  read<int>(in, "capacity", capacity_);
58 
59  if (speciesId_ < 0) UTIL_THROW("Negative speciesId");
60  if (p_ < 0) UTIL_THROW("Negative mode index");
61  if (capacity_ <= 0) UTIL_THROW("Negative capacity");
62  if (speciesId_ >= system().simulation().nSpecies())
63  UTIL_THROW("speciesId > nSpecies");
64 
65  speciesPtr_ = &system().simulation().species(speciesId_);
66  int speciesCapacity = speciesPtr_->capacity();
67  nAtom_ = speciesPtr_->nAtom();
68 
69  // Allocate arrays
70  data_.allocate(speciesCapacity);
71  projector_.allocate(nAtom_);
72 
73  isInitialized_ = true;
74  }
75 
76  /*
77  * Load internal state from an archive.
78  */
80  {
82  loadParameter<int>(ar, "speciesId", speciesId_);
83  loadParameter<int>(ar, "p", p_);
84  loadParameter<int>(ar, "capacity", capacity_);
85  ar & nAtom_;
86  ar & nMolecule_;
87  ar & accumulator_;
88  ar & projector_;
89 
90  speciesPtr_ = &system().simulation().species(speciesId_);
91  int speciesCapacity = speciesPtr_->capacity();
92  data_.allocate(speciesCapacity);
93 
94  // Validate input
95  if (speciesId_ < 0) {
96  UTIL_THROW("Negative speciesId");
97  }
98  if (p_ < 0) {
99  UTIL_THROW("Negative mode index");
100  }
101  if (capacity_ <= 0) {
102  UTIL_THROW("Negative capacity");
103  }
104  if (speciesId_ < 0) {
105  UTIL_THROW("speciesId < 0");
106  }
107  if (speciesId_ >= system().simulation().nSpecies()) {
108  UTIL_THROW("speciesId >= nSpecies");
109  }
110  if (nAtom_ != speciesPtr_->nAtom()) {
111  UTIL_THROW("Inconsistent values of nAtom");
112  }
113  if (projector_.capacity() != nAtom_) {
114  UTIL_THROW("Inconsistent projector capacity");
115  }
116  if (accumulator_.bufferCapacity() != capacity_) {
117  UTIL_THROW("Inconsistent accumulator buffer capacity");
118  }
119 
120  isInitialized_ = true;
121  }
122 
123  /*
124  * Save internal state to an archive.
125  */
127  { ar << *this; }
128 
129  /*
130  * Allocate memory, initialize accumulator, and initialize eigenvector.
131  */
133  {
134 
135  // Get nMolecule for this species and nAtom per molecule
136  nMolecule_ = system().nMolecule(speciesId_);
137  nAtom_ = speciesPtr_->nAtom();
138  if (nAtom_ <= 0) UTIL_THROW("Number of atoms per molecule < 1.");
139 
140  // data_.allocate(nMolecule_);
141  // projector_.allocate(nAtom_);
142 
143  // Initialize mode projection eigenvector
144  double qMode;
145  if (p_ == 0) {
146  for (int j = 0; j < nAtom_; ++j)
147  projector_[j] = 1.0 / double(nAtom_);
148  } else {
149  if (p_%2 == 0) {
150  qMode = 2.0*acos(-1.0)*double(p_/2)/double(nAtom_);
151  for (int j = 0; j < nAtom_; ++j)
152  projector_[j] = 1.0 / double(nAtom_) * cos(qMode*double(j));
153  } else {
154  qMode = 2.0*acos(-1.0)*double((p_+1)/2)/double(nAtom_);
155  for (int j = 0; j < nAtom_; ++j)
156  projector_[j] = 1.0 / double(nAtom_) * sin(qMode*double(j));
157  }
158  }
159 
160  // Initialize the AutoCorrArray object.
161  accumulator_.setParam(nMolecule_, capacity_);
162 
163  }
164 
165  /*
166  * Evaluate end-to-end vectors of all chains, add to ensemble.
167  */
168  void RingRouseAutoCorr::sample(long iStep)
169  {
170  if (isAtInterval(iStep)) {
171 
172  Molecule* moleculePtr;
173  Vector r1, r2, dR, atomPos;
174  int i, j;
175 
176  // Confirm that nMolecule has remained constant
177  if (nMolecule_ != system().nMolecule(speciesId_)) {
178  UTIL_THROW("Number of molecules has changed.");
179  }
180 
181  // Loop over molecules
182  for (i=0; i < nMolecule_; i++) {
183  moleculePtr = &(system().molecule(speciesId_, i));
184 
185  // Retrace non-periodic shape and calculate coefficients
186  atomPos = moleculePtr->atom(0).position();
187  dR.multiply(atomPos, projector_[0]);
188  data_[i] = dR;
189  for (j = 1; j < nAtom_; j++) {
190  r1 = moleculePtr->atom(j-1).position();
191  r2 = moleculePtr->atom(j).position();
192  system().boundary().distanceSq(r2, r1, dR);
193  atomPos += dR;
194  dR.multiply(atomPos, projector_[j]);
195  data_[i] += dR;
196  }
197  }
198 
199  accumulator_.sample(data_);
200 
201  } // if isAtInterval
202 
203  }
204 
205  /*
206  * Output results after simulation is completed.
207  */
209  {
210 
211  // Echo parameters to analyzer log file
212  fileMaster().openOutputFile(outputFileName(), outputFile_);
213  writeParam(outputFile_);
214  outputFile_.close();
215 
216  // Output statistical analysis to separate data file
217  fileMaster().openOutputFile(outputFileName(".dat"), outputFile_);
218  accumulator_.output(outputFile_);
219  outputFile_.close();
220 
221  }
222 
223 }
A Vector is a Cartesian vector.
Definition: Vector.h:75
virtual void sample(long iStep)
Evaluate end-to-end vectors of all chains, add to ensemble.
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 save(Serializable::OArchive &ar)
Save internal state to an archive.
Vector & multiply(const Vector &v, double s)
Multiply a vector v by a scalar s.
Definition: Vector.h:686
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.
virtual void output()
Output results to file after simulation is completed.
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.
RingRouseAutoCorr(System &system)
Constructor.
virtual ~RingRouseAutoCorr()
Destructor.
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
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
virtual void setup()
Allocate memory and initialize Rouse mode eigenvector p.
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.
void readInterval(std::istream &in)
Read interval from file, with error checking.
Utility classes for scientific computation.
Definition: accumulators.mod:1
virtual void readParameters(std::istream &in)
Read parameters from file, and allocate data array.
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).
void setClassName(const char *className)
Set class name string.
const Atom & atom(int localId) const
Get a specific Atom in this Molecule.
int capacity() const
Maximum allowed number of molecules for this Species.
FileMaster & fileMaster()
Get the FileMaster by reference.
bool isAtInterval(long counter) const
Return true iff counter is a multiple of the interval.
const std::string & outputFileName() const
Return outputFileName string.
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191
A physical molecule (a set of covalently bonded Atoms).
const Vector & position() const
Get the position Vector by const reference.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Species & species(int i)
Get a specific Species by reference.