Simpatico  v1.10
mcMd/analyzers/system/VanHove.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 "VanHove.h"
9 #include <mcMd/simulation/Simulation.h>
10 #include <mcMd/simulation/McMd_mpi.h>
11 #include <mcMd/chemistry/Molecule.h>
12 #include <mcMd/chemistry/Atom.h>
13 #include <simp/boundary/Boundary.h>
14 #include <util/math/Constants.h>
15 #include <util/space/Dimension.h>
16 #include <util/misc/FileMaster.h>
17 #include <util/archives/Serializable_includes.h>
18 #include <util/misc/ioUtil.h>
19 #include <util/format/Int.h>
20 #include <util/format/Dbl.h>
21 
22 namespace McMd
23 {
24 
25  using namespace Util;
26  using namespace Simp;
27 
28  /*
29  * Constructor.
30  */
32  : SystemAnalyzer<System>(system),
33  isInitialized_(false)
34  { setClassName("VanHove"); }
35 
36  /*
37  * Destructor
38  */
40  {}
41 
42  /*
43  * Read parameters from file, and allocate memory.
44  */
45  void VanHove::readParameters(std::istream& in)
46  {
47  readInterval(in);
49 
50  nAtomType_ = system().simulation().nAtomType();
51  atomTypeCoeffs_.allocate(nAtomType_);
52  readDArray<double>(in, "atomTypeCoeffs", atomTypeCoeffs_, nAtomType_);
53 
54  read<int>(in, "nBuffer", nBuffer_);
55  read<int>(in, "nWave", nWave_);
56  waveIntVectors_.allocate(nWave_);
57  waveVectors_.allocate(nWave_);
58  fourierModes_.allocate(nWave_);
59  accumulators_.allocate(nWave_);
60  for (int i = 0; i < nWave_; ++i) {
61  accumulators_[i].setParam(nBuffer_);
62  }
63 
64  readDArray<IntVector>(in, "waveIntVectors", waveIntVectors_, nWave_);
65  isInitialized_ = true;
66  }
67 
68  /*
69  * Load state from an archive.
70  */
72  {
74  ar & nAtomType_;
75  atomTypeCoeffs_.allocate(nAtomType_);
76  loadDArray<double>(ar, "atomTypeCoeffs", atomTypeCoeffs_, nAtomType_);
77  loadParameter<int>(ar, "nBuffer", nBuffer_);
78  loadParameter<int>(ar, "nWave", nWave_);
79  waveIntVectors_.allocate(nWave_);
80  loadDArray<IntVector>(ar, "waveIntVectors", waveIntVectors_, nWave_);
81  accumulators_.allocate(nWave_);
82  ar & accumulators_;
83  ar & nSample_;
84 
85  // Validate
86  if (nAtomType_ != system().simulation().nAtomType()) {
87  UTIL_THROW("Inconsistent values of nAtomType");
88  }
89  if (nAtomType_ != atomTypeCoeffs_.capacity()) {
90  UTIL_THROW("Inconsistent capacity for atomTypeCoeffs");
91  }
92  if (nWave_ != waveIntVectors_.capacity()) {
93  UTIL_THROW("Inconsistent capacity for waveIntVectors");
94  }
95 
96  // Allocate work arrays.
97  waveVectors_.allocate(nWave_);
98  fourierModes_.allocate(nWave_);
99 
100  isInitialized_ = true;
101  }
102 
103  /*
104  * Save state to an archive.
105  */
107  { ar & *this; }
108 
109  /*
110  * Clear accumulators.
111  */
113  {
114  if (!isInitialized_) {
115  UTIL_THROW("Error: Object not initialized");
116  }
117  assert (nBuffer_ > 0);
118  assert (nWave_ > 0);
119  for (int i = 0; i < nWave_; ++i) {
120  accumulators_[i].clear();
121  }
122  }
123 
125  void VanHove::sample(long iStep)
126  {
127  if (isAtInterval(iStep)) {
128 
129  Vector position;
130  std::complex<double> expFactor;
131  double product, coeff;
134  int nSpecies, iSpecies, i;
135 
136  makeWaveVectors();
137 
138  // Set all Fourier modes to zero
139  for (i = 0; i < nWave_; ++i) {
140  fourierModes_[i] = std::complex<double>(0.0, 0.0);
141  }
142 
143  // Loop over all atoms to calculate Fourier modes
144  nSpecies = system().simulation().nSpecies();
145  for (iSpecies = 0; iSpecies < nSpecies; ++iSpecies) {
146  system().begin(iSpecies, molIter);
147  for ( ; molIter.notEnd(); ++molIter) {
148  molIter->begin(atomIter);
149  for ( ; atomIter.notEnd(); ++atomIter) {
150  position = atomIter->position();
151  coeff = atomTypeCoeffs_[atomIter->typeId()];
152 
153  // Loop over wavevectors
154  for (i = 0; i < nWave_; ++i) {
155 
156  product = position.dot(waveVectors_[i]);
157  expFactor = exp( product*Constants::Im );
158  fourierModes_[i] += (coeff*expFactor);
159 
160  }
161 
162  }
163  }
164 
165  }
166 
167  // Add Fourier modes to autocorrelation accumulators
168  double sqrtV = sqrt(system().boundary().volume());
169  for (i = 0; i < nWave_; ++i) {
170  accumulators_[i].sample(fourierModes_[i]/sqrtV);
171  }
172 
173  }
174 
175  }
176 
180  void VanHove::makeWaveVectors()
181  {
182  Vector dWave;
183  Boundary* boundaryPtr = &system().boundary();
184  int i, j;
185 
186  // Calculate wavevectors
187  for (i = 0; i < nWave_; ++i) {
188  waveVectors_[i] = Vector::Zero;
189  for (j = 0; j < Dimension; ++j) {
190  dWave = boundaryPtr->reciprocalBasisVector(j);
191  dWave *= waveIntVectors_[i][j];
192  waveVectors_[i] += dWave;
193  }
194  }
195  }
196 
198  {
199  std::string suffix;
200  int i, j;
201 
202  // Echo parameters to a log file
203  fileMaster().openOutputFile(outputFileName(".prm"), outputFile_);
204  writeParam(outputFile_);
205  outputFile_.close();
206 
207  // Output autocorrelation functions to file
208  fileMaster().openOutputFile(outputFileName(".dat"), outputFile_);
209  for (i = 0; i < nWave_; ++i) {
210 
211  #if 0
212  // Construct file suffix for this structure factor
213  suffix = std::string("_");
214  for (j = 0; j < Dimension; ++j) {
215  suffix += toString(waveIntVectors_[i][j]);
216  }
217  suffix += std::string(".dat");
218  outputFile_ << suffix << std::endl;
219  //fileMaster().openOutputFile(outputFileName(suffix), outputFile_);
220  #endif
221 
222  for (j = 0; j < Dimension; ++j) {
223  outputFile_ << Int(waveIntVectors_[i][j], 5);
224  }
225  outputFile_ << Dbl(waveVectors_[i].abs(), 20, 8);
226  outputFile_ << std::endl;
227  accumulators_[i].output(outputFile_);
228  outputFile_ << std::endl;
229  outputFile_ << std::endl;
230  //outputFile_.close();
231 
232  }
233  outputFile_.close();
234 
235  }
236 
237 }
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
std::string toString(int n)
Return string representation of an integer.
Definition: ioUtil.cpp:52
A Vector is a Cartesian vector.
Definition: Vector.h:75
float product(float a, float b)
Product for float Data.
Definition: product.h:22
virtual void setup()
Clear accumulators.
void begin(int speciesId, MoleculeIterator &iterator)
Initialize an iterator for molecules of one species in this System.
Definition: System.h:1147
double dot(const Vector &v) const
Return dot product of this vector and vector v.
Definition: Vector.h:632
An orthorhombic periodic unit cell.
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
static const Vector Zero
Zero Vector = {0.0, 0.0, 0.0}.
Definition: Vector.h:369
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.
Wrapper for a double precision number, for formatted ostream output.
Definition: Dbl.h:39
virtual void output()
Output results to predefined output file.
Forward iterator for a PArray.
Classes used by all simpatico molecular simulations.
void readOutputFileName(std::istream &in)
Read outputFileName from file.
Forward const iterator for an Array or a C array.
Saving / output archive for binary ostream.
virtual void save(Serializable::OArchive &ar)
Save state to an archive.
#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.
const Vector & reciprocalBasisVector(int i) const
Return reciprocal lattice basis vector i.
void readInterval(std::istream &in)
Read interval from file, with error checking.
Utility classes for scientific computation.
Definition: accumulators.mod:1
void sample(long iStep)
Add particle pairs to VanHove histogram.
Wrapper for an int, for formatted ostream output.
Definition: Int.h:36
Template for Analyzer associated with one System.
bool notEnd() const
Is the current pointer not at the end of the array?
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).
int nSpecies() const
Get the number of Species in this Simulation.
virtual void readParameters(std::istream &in)
Read parameters from file.
void setClassName(const char *className)
Set class name string.
virtual void loadParameters(Serializable::IArchive &ar)
Load state from an archive.
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
int nAtomType() const
Get the number of atom types.
bool notEnd() const
Is this not the end of the array?
VanHove(System &system)
Constructor.
static const std::complex< double > Im
Square root of -1.
Definition: Constants.h:40