Simpatico  v1.10
BlockRadiusGyration.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 "BlockRadiusGyration.h"
9 #include <mcMd/simulation/Simulation.h>
10 #include <simp/species/Species.h>
11 #include <mcMd/chemistry/Molecule.h>
12 #include <mcMd/chemistry/Atom.h>
13 #include <simp/boundary/Boundary.h>
14 #include <util/misc/FileMaster.h>
15 #include <util/archives/Serializable_includes.h>
16 
17 #include <util/format/Dbl.h>
18 
19 namespace McMd
20 {
21 
22  using namespace Util;
23  using namespace Simp;
24 
27  : SystemAnalyzer<System>(system),
28  outputFile_(),
29  accumulators_(),
30  positions_(),
31  rCom_(),
32  iTypeNAtom_(),
33  dRSq_(),
34  dRSqPair_(),
35  speciesPtr_(0),
36  nAtomType_(-1),
37  nAtomTypePairs_(-1),
38  nSamplePerBlock_(-1),
39  speciesId_(-1),
40  nAtom_(-1),
41  isInitialized_(false)
42  { setClassName("BlockRadiusGyration"); }
43 
45  void BlockRadiusGyration::readParameters(std::istream& in)
46  {
47  readInterval(in);
49  nAtomType_ = system().simulation().nAtomType();
50  nAtomTypePairs_ = 0;
51  int i, j;
52  for (i = 0; i < nAtomType_; ++i) {
53  for (j = i+1; j < nAtomType_; ++j) {
54  ++nAtomTypePairs_;
55  }
56  }
57  accumulators_.allocate(nAtomType_ + nAtomTypePairs_);
58 
59  read<int>(in,"nSamplePerBlock", nSamplePerBlock_);
60  for (i = 0; i < nAtomType_+nAtomTypePairs_; ++i) {
61  accumulators_[i].setNSamplePerBlock(nSamplePerBlock_);
62  }
63 
64  // If nSamplePerBlock != 0, open an output file for block averages.
65  if (accumulators_[0].nSamplePerBlock()) {
66  fileMaster().openOutputFile(outputFileName(".dat"), outputFile_);
67  }
68 
69  read<int>(in, "speciesId", speciesId_);
70  if (speciesId_ < 0) {
71  UTIL_THROW("Negative speciesId");
72  }
73 
74  if (speciesId_ >= system().simulation().nSpecies()) {
75  UTIL_THROW("speciesId > nSpecies");
76  }
77 
78  speciesPtr_ = &system().simulation().species(speciesId_);
79  nAtom_ = speciesPtr_->nAtom();
80 
81  // Allocate an array of separation Vectors
82  positions_.allocate(nAtom_);
83 
84  // Allocate an array of center of mass position vectors
85  rCom_.allocate(nAtomType_);
86 
87  // Allocate an array of number of atoms in blocks of different types
88  iTypeNAtom_.allocate(nAtomType_);
89 
90  dRSq_.allocate(nAtomType_);
91  dRSqPair_.allocate(nAtomTypePairs_);
92 
93  isInitialized_ = true;
94  }
95 
96  /*
97  * Load state from an archive.
98  */
100  {
101  // Load (everything but accumulators_)
103  loadParameter<int>(ar,"nSamplePerBlock", nSamplePerBlock_);
104  loadParameter<int>(ar, "speciesId", speciesId_);
105  ar & nAtom_;
106  ar & nAtomType_;
107  ar & nAtomTypePairs_;
108 
109  speciesPtr_ = &system().simulation().species(speciesId_);
110 
111  // Validate
112  if (speciesId_ < 0) {
113  UTIL_THROW("Negative speciesId");
114  }
115  if (speciesId_ >= system().simulation().nSpecies()) {
116  UTIL_THROW("speciesId > nSpecies");
117  }
118  if (nAtom_ != speciesPtr_->nAtom()) {
119  UTIL_THROW("Inconsistent nAtomType");
120  }
121  if (nAtomType_ != system().simulation().nAtomType()) {
122  UTIL_THROW("Inconsistent nAtomType");
123  }
124  {
125  int nPairTypes = 0;
126  int i, j;
127  for (i = 0; i < nAtomType_; ++i) {
128  for (j = i+1; j < nAtomType_; ++j) {
129  ++nPairTypes;
130  }
131  }
132  if (nAtomTypePairs_ != nPairTypes) {
133  UTIL_THROW("Inconsistent nAtomTypePairs");
134  }
135  }
136 
137  // Allocate
138  positions_.allocate(nAtom_);
139  rCom_.allocate(nAtomType_);
140  iTypeNAtom_.allocate(nAtomType_);
141  dRSq_.allocate(nAtomType_);
142  dRSqPair_.allocate(nAtomTypePairs_);
143  accumulators_.allocate(nAtomType_ + nAtomTypePairs_);
144  for (int i = 0; i < nAtomType_+nAtomTypePairs_; ++i) {
145  accumulators_[i].setNSamplePerBlock(nSamplePerBlock_);
146  }
147 
148  ar & accumulators_;
149 
150  // If nSamplePerBlock != 0, open an output file for block averages.
151  if (accumulators_[0].nSamplePerBlock()) {
152  fileMaster().openOutputFile(outputFileName(".dat"), outputFile_);
153  }
154  isInitialized_ = true;
155  }
156 
157  /*
158  * Save state to archive.
159  */
161  { ar & *this; }
162 
163  /*
164  * Clear accumulators.
165  */
167  {
168  if (!isInitialized_) UTIL_THROW("Object is not initialized");
169 
170  for (int i = 0; i < nAtomType_ + nAtomTypePairs_; ++i) {
171  accumulators_[i].clear();
172  }
173  }
174 
175  /*
176  * Evaluate end-to-end vectors of all chains, add to ensemble.
177  */
178  void BlockRadiusGyration::sample(long iStep)
179  {
180  if (isAtInterval(iStep)) {
181 
182  Molecule* moleculePtr;
183  Vector r1, r2, dR;
184  int i, j, k, l, m, typeId, nMolecule;
185 
186  k = 0;
187  for (i = 0; i < nAtomType_; ++i) {
188  dRSq_[i] = 0.0;
189  iTypeNAtom_[i] = 0;
190  for (j = i+1; j < nAtomType_; ++j) {
191  ++k;
192  dRSqPair_[k-1] = 0.0;
193  }
194  }
195 
196  nMolecule = system().nMolecule(speciesId_);
197  moleculePtr = &system().molecule(speciesId_,0);
198  for (j = 0 ; j < nAtom_; j++) {
199  typeId = moleculePtr->atom(j).typeId();
200  iTypeNAtom_[typeId] += 1;
201  }
202 
203  for (i = 0; i < system().nMolecule(speciesId_); i++) {
204  moleculePtr = &system().molecule(speciesId_, i);
205 
206  // Initializing COM positions for different types to zero
207  for (j = 0; j < nAtomType_; ++j) {
208  rCom_[j].zero();
209  }
210 
211  // Construct map of molecule with no periodic boundary conditions
212  positions_[0] = moleculePtr->atom(0).position();
213  typeId = moleculePtr->atom(0).typeId();
214  rCom_[typeId] += positions_[0];
215  for (j = 1 ; j < nAtom_; j++) {
216  typeId = moleculePtr->atom(j).typeId();
217  r1 = moleculePtr->atom(j-1).position();
218  r2 = moleculePtr->atom(j).position();
219  system().boundary().distanceSq(r1, r2, dR);
220  positions_[j] = positions_[j-1];
221  positions_[j] += dR;
222  rCom_[typeId] += positions_[j];
223  }
224  for (l = 0; l < nAtomType_; ++l) {
225  rCom_[l] /= double(iTypeNAtom_[l]);
226  }
227  k = 0;
228  for (l = 0; l < nAtomType_; ++l) {
229  for (m = l+1; m < nAtomType_; ++m) {
230  ++k;
231  dR.subtract(rCom_[l], rCom_[m]);
232  dRSqPair_[k-1] += dR.square();
233  }
234  }
235  for (j = 0 ; j < nAtom_; j++) {
236  typeId = moleculePtr->atom(j).typeId();
237  dR.subtract(positions_[j], rCom_[typeId]);
238  dRSq_[typeId] += dR.square();
239  }
240 
241  }
242  k = 0;
243  for (i = 0; i < nAtomType_; ++i) {
244  dRSq_[i] /= double(nMolecule);
245  dRSq_[i] /= double(iTypeNAtom_[i]);
246  accumulators_[i].sample(dRSq_[i]);
247  outputFile_ << Dbl(dRSq_[i]) << " ";
248  for (j = i+1; j < nAtomType_; ++j) {
249  ++k;
250  dRSqPair_[k-1] /= double(nMolecule);
251  accumulators_[nAtomType_+k-1].sample(dRSqPair_[k-1]);
252  outputFile_ << Dbl(dRSqPair_[k-1]) << " ";
253  }
254  }
255  outputFile_ << std::endl;
256  } // if isAtInterval
257 
258  }
259 
260  /*
261  * Output results to file after simulation is completed.
262  */
264  {
265  int i, j, k;
266 
267  // If outputFile_ was used to write block averages, close it.
268  if (accumulators_[0].nSamplePerBlock()) {
269  outputFile_.close();
270  }
271 
272  // Write parameters to file
273  fileMaster().openOutputFile(outputFileName(".prm"), outputFile_);
274  ParamComposite::writeParam(outputFile_);
275  outputFile_.close();
276 
277  // Write average to file
278  fileMaster().openOutputFile(outputFileName(".ave"), outputFile_);
279  k = 0;
280  for (i = 0; i < nAtomType_; ++i) {
281  accumulators_[i].output(outputFile_);
282  for (j = i+1; j < nAtomType_; ++j) {
283  ++k;
284  accumulators_[nAtomType_+k-1].output(outputFile_);
285  outputFile_ << std::endl;
286  outputFile_ << std::endl;
287  }
288  }
289  outputFile_.close();
290 
291  }
292 
293 }
A Vector is a Cartesian vector.
Definition: Vector.h:75
virtual void save(Serializable::OArchive &ar)
Save state to archive.
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.
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
BlockRadiusGyration(System &system)
Constructor.
virtual void loadParameters(Serializable::IArchive &ar)
Load parameters from archive.
virtual void output()
Output results at end of simulation.
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
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
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
int typeId() const
Get type index for this Atom.
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 sample(long iStep)
Evaluate squared radii of gyration for all molecules, add to ensemble.
virtual void setup()
Clear accumulator.
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 readParameters(std::istream &in)
Read parameters from file, and allocate data array.
virtual void loadParameters(Serializable::IArchive &ar)
Load state from an archive.
Vector & subtract(const Vector &v1, const Vector &v2)
Subtract vector v2 from v1.
Definition: Vector.h:672
void setClassName(const char *className)
Set class name string.
const Atom & atom(int localId) const
Get a specific Atom in this Molecule.
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.
int nAtomType() const
Get the number of atom types.
Species & species(int i)
Get a specific Species by reference.
double square() const
Return square magnitude of this vector.
Definition: Vector.h:616