Simpatico  v1.10
IntraStructureFactorGrid.cpp
1 /*
2 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
3 *
4 * Copyright 2010, The Regents of the University of Minnesota
5 * Distributed under the terms of the GNU General Public License.
6 */
7 
8 #include "IntraStructureFactorGrid.h"
9 #include <mcMd/simulation/Simulation.h>
10 #include <mcMd/simulation/McMd_mpi.h>
11 #include <util/crystal/PointGroup.h>
12 #include <util/crystal/PointSymmetry.h>
13 #include <util/archives/Serializable_includes.h>
14 #include <util/format/Int.h>
15 #include <util/format/Dbl.h>
16 
17 namespace McMd
18 {
19 
20  using namespace Util;
21 
22  /*
23  * Constructor.
24  */
26  : IntraStructureFactor(system),
27  hMax_(0),
28  nStar_(0),
29  lattice_(Triclinic),
30  isFirstStep_(true),
31  isInitialized_(false)
32  { setClassName("IntraStructureFactorGrid"); }
33 
34  /*
35  * Destructor.
36  */
38  {}
39 
40  /*
41  * Read parameters from file, and allocate data array.
42  */
44  {
45  readInterval(in);
47  read<int>(in, "speciesId", speciesId_);
48  read<int>(in, "nAtomTypeIdPair", nAtomTypeIdPair_);
50  atomTypeIdPairs_.allocate(nAtomTypeIdPair_);
51  readDArray< Pair<int> >(in, "atomTypeIdPairs", atomTypeIdPairs_, nAtomTypeIdPair_);
52  read<int>(in, "hMax", hMax_);
53  read<Util::LatticeSystem>(in, "lattice", lattice_);
54 
55  // Allocate wavevectors arrays
56  nWave_ = (2*hMax_ + 1)*(2*hMax_ + 1)*(2*hMax_ + 1);
57  waveIntVectors_.allocate(nWave_);
58  waveVectors_.allocate(nWave_);
59  fourierModes_.allocate(nWave_, nAtomType_+1);
62 
63  int i, j, h, k, l, m;
64  IntVector g;
65 
66  // Cubic Symmetry
67  if (lattice_ == Cubic) {
68 
69  nStar_ = (hMax_ + 1 )*(hMax_ + 2)*(hMax_ + 3)/6;
70  starIds_.allocate(nStar_);
71  starSizes_.allocate(nStar_);
72 
73  // Create cubic point group
74  PointGroup group;
75  PointSymmetry a, b, c;
76 
77  a.R(0,1) = 1;
78  a.R(1,0) = 1;
79  a.R(2,2) = 1;
80 
81  b.R(0,0) = -1;
82  b.R(1,1) = 1;
83  b.R(2,2) = 1;
84 
85  c.R(0,1) = 1;
86  c.R(1,2) = 1;
87  c.R(2,0) = 1;
88 
89  group.add(c);
90  group.add(b);
91  group.add(a);
92  group.makeCompleteGroup();
93 
94  // Create grid of wavevectors
96  i = 0;
97  j = 0;
98  for (h = 0; h <= hMax_; ++h) {
99  g[0] = h;
100  for (k = 0; k <= h; ++k) {
101  g[1] = k;
102  for (l = 0; l <= k; ++l) {
103  g[2] = l;
104  starIds_[i] = j;
105  group.makeStar(g, star);
106  starSizes_[i] = star.size();
107  for (m = 0; m < star.size(); ++m) {
108  waveIntVectors_[j] = star[m];
109  ++j;
110  }
111  ++i;
112  }
113  }
114  }
115  if (i != nStar_) {
116  UTIL_THROW("Error");
117  }
118  if (j != nWave_) {
119  UTIL_THROW("Error");
120  }
121  } else if (lattice_ == Tetragonal) {
122 
123  nStar_ = (hMax_ + 1 )*(hMax_ + 1)*(hMax_ + 2)/2;
124  starIds_.allocate(nStar_);
125  starSizes_.allocate(nStar_);
126  // Create tetragonal point group
127  PointGroup group;
128  PointSymmetry a, b, c;
129 
130  a.R(0,0) = 1;
131  a.R(1,2) = 1;
132  a.R(2,1) = 1;
133 
134  b.R(0,0) = -1;
135  b.R(1,1) = 1;
136  b.R(2,2) = 1;
137 
138  c.R(0,0) = 1;
139  c.R(1,1) = -1;
140  c.R(2,2) = 1;
141 
142  group.add(c);
143  group.add(b);
144  group.add(a);
145  group.makeCompleteGroup();
146 
147  // Create grid of wavevectors
149  i = 0;
150  j = 0;
151  for (h = 0; h <= hMax_; ++h) {
152  g[0] = h;
153  for (k = 0; k <= hMax_; ++k) {
154  g[1] = k;
155  for (l = 0; l <= k; ++l) {
156  g[2] = l;
157  starIds_[i] = j;
158  group.makeStar(g, star);
159  starSizes_[i] = star.size();
160  for (m = 0; m < star.size(); ++m) {
161  waveIntVectors_[j] = star[m];
162  ++j;
163  }
164  ++i;
165  }
166  }
167  }
168  if (i != nStar_) {
169  UTIL_THROW("Error");
170  }
171  if (j != nWave_) {
172  UTIL_THROW("Error");
173  }
174  }
175 
176  // Clear accumulators
177  for (i = 0; i < nWave_; ++i) {
178  for (j = 0; j < nAtomTypeIdPair_; ++j) {
179  structureFactors_(i, j) = 0.0;
180  }
181  }
182 
183  nSample_ = 0;
184 
185  isInitialized_ = true;
186  }
187 
188  /*
189  * Load state from an archive.
190  */
192  {
193  // Load from IntraStructureFactor::serialize
195  ar & nAtomType_;
196  loadParameter<int>(ar, "nAtomTypeIdPair", nAtomTypeIdPair_);
197  loadDArray< Pair<int> >(ar, "atomTypeIdPairs", atomTypeIdPairs_, nAtomType_);
198  ar & nWave_;
199  ar & waveIntVectors_;
200  ar & structureFactors_;
201  ar & nSample_;
202 
203  // Load additional from IntraStructureFactorGrid::serialize
204  loadParameter<int>(ar, "hMax", hMax_);
205  loadParameter<Util::LatticeSystem>(ar, "lattice", lattice_);
206  ar & nStar_;
207  ar & starIds_;
208  ar & starSizes_;
209 
210  // Validate
211  if (nWave_ != (2*hMax_ + 1)*(2*hMax_ + 1)*(2*hMax_ + 1)) {
212  UTIL_THROW("Inconsistent value of nWave_");
213  }
214  if (nAtomType_ != system().simulation().nAtomType()) {
215  UTIL_THROW("Inconsistent values of nAtomType_");
216  }
217  if (atomTypeIdPairs_.capacity() != nAtomTypeIdPair_) {
218  UTIL_THROW("Inconsistent capacity1 for atomTypeIdPairs array");
219  }
220  if (waveIntVectors_.capacity() != nWave_) {
221  UTIL_THROW("Inconsistent capacity for waveIntVector");
222  }
223 
224  // Allocate temporary data structures (defined in IntraStructureFactor)
225  waveVectors_.allocate(nWave_);
227 
228  isInitialized_ = true;
229  }
230 
231  /*
232  * Save state to archive.
233  */
235  { ar & *this; }
236 
238  {
239  }
240 
242  {
244 
245  // Select open mode for output files
246  std::ios_base::openmode mode = std::ios_base::out;
247  if (!isFirstStep_) {
248  mode = std::ios_base::out | std::ios_base::app;
249  }
250  fileMaster().openOutputFile(outputFileName(".log"), logFile_, mode);
251  //fileMaster().openOutputFile(outputFileName(".log"),
252  // logFile_, !isFirstStep_);
253  isFirstStep_ = false;
254 
255  // Log structure factors
256  for (int i = 0; i < nStar_; ++i) {
257  int size = starSizes_[i];
258 
259  int k = starIds_[i];
260  for (int n = 0; n < Dimension; ++n) {
261  logFile_ << Int(waveIntVectors_[k][n], 5);
262  }
263  logFile_ << Dbl(waveVectors_[k].abs(), 20, 8);
264 
265  for (int j = 0; j < nAtomTypeIdPair_; ++j) {
266  k = starIds_[i];
267  double avg = 0.0;
268  for (int m = 0; m < size; ++m) {
269  avg += structureFactorDelta_(k,j);
270  ++k;
271  }
272  avg/= size;
273  logFile_ << Dbl(avg, 20, 8);
274  }
275 
276  logFile_ << std::endl;
277  }
278  logFile_ << std::endl;
279  logFile_.close();
280  }
281 
282 
284  {
285  double value, average, size;
286  int i, j, k, m, n;
287 
288  // Echo parameters to a log file
291  outputFile_.close();
292 
293  // Output structure factors to one file
295 
296 
297  // Loop over waves to output structure factor
298  for (i = 0; i < nStar_; ++i) {
299  size = starSizes_[i];
300 
301  k = starIds_[i];
302  for (n = 0; n < Dimension; ++n) {
303  outputFile_ << Int(waveIntVectors_[k][n], 5);
304  }
305  outputFile_ << Dbl(waveVectors_[k].abs(), 20, 8);
306 
307  for (j = 0; j < nAtomTypeIdPair_; ++j) {
308  k = starIds_[i];
309  average = 0.0;
310  for (m = 0; m < size; ++m) {
311  value = structureFactors_(k, j)/double(nSample_);
312  average += value;
313  ++k;
314  }
315  average = average/double(size);
316  outputFile_ << Dbl(average, 20, 8);
317  }
318  outputFile_ << std::endl;
319 
320  }
321  outputFile_.close();
322 
323  }
324 
325 }
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
virtual void save(Serializable::OArchive &ar)
Save state to archive.
int nAtomTypeIdPair_
Number of selected atom type pairs.
void allocate(int capacity1, int capacity2)
Allocate memory for a matrix.
Definition: DMatrix.h:170
virtual void output()
Output structure factors, averaged over stars.
DMatrix< std::complex< double > > fourierModes_
Fourier modes.
Intramolecular contribution to the structure factor S(k)
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
DMatrix< double > structureFactorDelta_
Contribution of current time step to structure factor average.
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
IntraStructureFactorGrid(System &system)
Constructor.
bool add(Symmetry &symmetry)
Add a new element to the group.
void readOutputFileName(std::istream &in)
Read outputFileName from file.
Saving / output archive for binary ostream.
virtual void sample(long iStep)
Add particles to StructureFactor accumulators.
int nSample_
Number of samples thus far.
A fixed capacity (static) contiguous array with a variable logical size.
Definition: FSArray.h:37
#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.
void readInterval(std::istream &in)
Read interval from file, with error checking.
Utility classes for scientific computation.
Definition: accumulators.mod:1
int & R(int i, int j)
Return an element of the matrix by reference.
Wrapper for an int, for formatted ostream output.
Definition: Int.h:36
void makeStar(const IntVector &root, FSArray< IntVector, N > &star)
Generate a set of reciprocal vectors that are related by symmetry.
Definition: PointGroup.h:47
Group of crystal symmetries with no translations.
Definition: PointGroup.h:18
void sample(long iStep)
Add particle pairs to IntraStructureFactor histogram.
int nWave_
Number of wavevectors.
int speciesId_
Index for molecular species.
int nAtomType_
Number of atom types, copied from Simulation::nAtomType().
Saving archive for binary istream.
std::ofstream outputFile_
Output file stream.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
virtual void readParameters(std::istream &in)
Read parameters from file.
virtual void setup()
Set up before a simulation.
void setClassName(const char *className)
Set class name string.
An IntVector is an integer Cartesian vector.
Definition: IntVector.h:73
DMatrix< double > structureFactors_
Structure factor accumulators.
FileMaster & fileMaster()
Get the FileMaster by reference.
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.
void makeCompleteGroup()
Generate a complete group from the current elements.
int size() const
Return logical size of this array (i.e., number of elements).
Definition: FSArray.h:207
virtual void loadParameters(Serializable::IArchive &ar)
Load state from an archive.
A PointSymmetry represents a crystallographic point group symmetry.
Definition: PointSymmetry.h:22