Simpatico  v1.10
StructureFactorPGrid.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 "StructureFactorPGrid.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/format/Int.h>
14 #include <util/format/Dbl.h>
15 
16 namespace McMd
17 {
18 
19  using namespace Util;
20 
21  /*
22  * Constructor.
23  */
25  : StructureFactorP(system),
26  hMax_(0),
27  nStar_(0),
28  lattice_(Triclinic),
29  isInitialized_(false)
30  { setClassName("StructureFactorPGrid"); }
31 
32  /*
33  * Read parameters from file, and allocate memory.
34  */
35  void StructureFactorPGrid::readParameters(std::istream& in)
36  {
37  readInterval(in);
40  read<int>(in, "nAtomTypeIdPair", nAtomTypeIdPair_);
42  readDArray< Pair<int> >(in, "atomTypeIdPairs", atomTypeIdPairs_,
44  read<int>(in, "hMax", hMax_);
45  read<Util::LatticeSystem>(in, "lattice", lattice_);
46 
47  // Allocate wavevectors arrays
48  nWave_ = (2*hMax_ +1 )*(2*hMax_ + 1)*(2*hMax_ + 1);
49  waveIntVectors_.allocate(nWave_);
50  waveVectors_.allocate(nWave_);
51  fourierModes_.allocate(nWave_, nAtomType_ + 1);
53 
54  makeStars();
55 
56  #if 0
57  int i, j, h, k, l, m;
58  IntVector g;
59 
60  // Cubic Symmetry
61  if (lattice_ == Cubic) {
62 
63  nStar_ = (hMax_ +1 )*(hMax_ + 2)*(hMax_ + 3)/6;
64  starIds_.allocate(nStar_);
65  starSizes_.allocate(nStar_);
66 
67  // Create cubic point group
68  PointGroup group;
69  PointSymmetry a, b, c;
70 
71  a.R(0,1) = 1;
72  a.R(1,0) = 1;
73  a.R(2,2) = 1;
74 
75  b.R(0,0) = -1;
76  b.R(1,1) = 1;
77  b.R(2,2) = 1;
78 
79  c.R(0,1) = 1;
80  c.R(1,2) = 1;
81  c.R(2,0) = 1;
82 
83  group.add(c);
84  group.add(b);
85  group.add(a);
86  group.makeCompleteGroup();
87 
88  // Create grid of wavevectors
90  i = 0;
91  j = 0;
92  for (h = 0; h <= hMax_; ++h) {
93  g[0] = h;
94  for (k = 0; k <= h; ++k) {
95  g[1] = k;
96  for (l = 0; l <= k; ++l) {
97  g[2] = l;
98  starIds_[i] = j;
99  group.makeStar(g, star);
100  starSizes_[i] = star.size();
101  for (m = 0; m < star.size(); ++m) {
102  waveIntVectors_[j] = star[m];
103  ++j;
104  }
105  ++i;
106  }
107  }
108  }
109  if (i != nStar_) {
110  UTIL_THROW("Error");
111  }
112  if (j != nWave_) {
113  UTIL_THROW("Error");
114  }
115  }
116  #endif
117 
118  // Clear accumulators
119  int i, j;
120  for (i = 0; i < nWave_; ++i) {
121  for (j = 0; j < nAtomTypeIdPair_; ++j) {
122  structureFactors_(i, j) = 0.0;
123  }
124  }
125  nSample_ = 0;
126  isInitialized_ = true;
127  }
128 
129  /*
130  * Load state from archive.
131  */
133  {
134  // Parameters in StructureFactorP::serialize()
136  ar & nAtomType_;
137  loadParameter<int>(ar, "nAtomTypeIdPair", nAtomTypeIdPair_);
138  loadDArray< Pair<int> >(ar, "atomTypeIdPairs", atomTypeIdPairs_,
140  ar & nWave_;
141  ar & waveIntVectors_;
142  ar & structureFactors_;
143  ar & nSample_;
144 
145  // Load addition parameters in StructureFactorPGrid::serialize()
146  loadParameter<int>(ar, "hMax", hMax_);
147  loadParameter<Util::LatticeSystem>(ar, "lattice", lattice_);
148 
149  // Validate
150  if (nWave_ != (2*hMax_ + 1)*(2*hMax_ + 1)*(2*hMax_ + 1)) {
151  UTIL_THROW("Inconsistent value of nWave_");
152  }
153  if (nAtomType_ != system().simulation().nAtomType()) {
154  UTIL_THROW("Inconsistent values of nAtomType_");
155  }
156  if (atomTypeIdPairs_.capacity() != nAtomTypeIdPair_) {
157  UTIL_THROW("Inconsistent capacity1 for modes array");
158  }
159  if (waveIntVectors_.capacity() != nWave_) {
160  UTIL_THROW("Inconsistent capacity for waveIntVector");
161  }
162 
163  // Allocate arrays for temporary storage
164  waveVectors_.allocate(nWave_);
165  fourierModes_.allocate(nWave_, nAtomType_ + 1);
166  }
167 
168  /*
169  * Save state to archive.
170  */
172  { ar << *this; }
173 
174  void StructureFactorPGrid::makeStars()
175  {
176  int i, j, h, k, l, m;
177  IntVector g;
178 
179  // Cubic Symmetry
180  if (lattice_ == Cubic) {
181 
182  nStar_ = (hMax_ +1 )*(hMax_ + 2)*(hMax_ + 3)/6;
183  starIds_.allocate(nStar_);
184  starSizes_.allocate(nStar_);
185 
186  // Create cubic point group
187  PointGroup group;
188  PointSymmetry a, b, c;
189 
190  a.R(0,1) = 1;
191  a.R(1,0) = 1;
192  a.R(2,2) = 1;
193 
194  b.R(0,0) = -1;
195  b.R(1,1) = 1;
196  b.R(2,2) = 1;
197 
198  c.R(0,1) = 1;
199  c.R(1,2) = 1;
200  c.R(2,0) = 1;
201 
202  group.add(c);
203  group.add(b);
204  group.add(a);
205  group.makeCompleteGroup();
206 
207  // Create grid of wavevectors
209  i = 0;
210  j = 0;
211  for (h = 0; h <= hMax_; ++h) {
212  g[0] = h;
213  for (k = 0; k <= h; ++k) {
214  g[1] = k;
215  for (l = 0; l <= k; ++l) {
216  g[2] = l;
217  starIds_[i] = j;
218  group.makeStar(g, star);
219  starSizes_[i] = star.size();
220  for (m = 0; m < star.size(); ++m) {
221  waveIntVectors_[j] = star[m];
222  ++j;
223  }
224  ++i;
225  }
226  }
227  }
228  if (i != nStar_) {
229  UTIL_THROW("Error");
230  }
231  if (j != nWave_) {
232  UTIL_THROW("Error");
233  }
234  }
235  }
236 
238  {}
239 
241  {
242  double value, average, size;
243  int i, j, k, m, n;
244 
245  // Echo parameters to a log file
248  outputFile_.close();
249 
250  // Output structure factors to one file
252 
253  // Loop over waves to output structure factor
254  for (i = 0; i < nStar_; ++i) {
255  size = starSizes_[i];
256 
257  #if 0
258  // Output individual waves in star
259  k = starIds_[i];
260  for (m = 0; m < size; ++m) {
261  for (n = 0; n < Dimension; ++n) {
262  outputFile_ << Int(waveIntVectors_[k][n], 5);
263  }
264  outputFile_ << Dbl(waveVectors_[k].abs(), 20, 8);
265  for (j = 0; j < nAtomTypeIdPair_; ++j) {
266  value = structureFactors_(k, j)/double(nSample_);
267  outputFile_ << Dbl(value, 20, 8);
268  }
269  outputFile_ << std::endl;
270  ++k;
271  }
272  outputFile_ << std::endl;
273  #endif
274 
275  k = starIds_[i];
276  for (n = 0; n < Dimension; ++n) {
277  outputFile_ << Int(waveIntVectors_[k][n], 5);
278  }
279  outputFile_ << Dbl(waveVectors_[k].abs(), 20, 8);
280  for (j = 0; j < nAtomTypeIdPair_; ++j) {
281  k = starIds_[i];
282  average = 0.0;
283  for (m = 0; m < size; ++m) {
284  value = structureFactors_(k, j)/double(nSample_);
285  average += value;
286  ++k;
287  }
288  average = average/double(size);
289  outputFile_ << Dbl(average, 20, 8);
290  }
291  outputFile_ << std::endl;
292 
293  }
294 
295  outputFile_.close();
296 
297  #if 0
298  // Output each structure factor to a separate file
299  std::string suffix;
300  int typeId;
301  for (j = 0; j < nAtomTypeIdPair_; ++j) {
302 
303  // Construct file suffix for this structure factor
304  suffix = std::string(".");
305  for (k = 0; k < 2; k++) {
306  typeId = atomTypeIdPairs_[j][k];
307  if (typeId < 0) {
308  suffix += std::string("A");
309  } else {
310  suffix += toString(typeId);
311  }
312  }
313  suffix += std::string(".dat");
314 
316 
317 
318 
319  // Loop over waves to output structure factor
320 
321  outputFile_.close();
322  }
323  #endif
324 
325  }
326 
327 }
StructureFactorP evaluates partial structure factors in Fourier space.
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
int nAtomTypeIdPair_
Number of selected atom type pairs.
std::string toString(int n)
Return string representation of an integer.
Definition: ioUtil.cpp:52
void allocate(int capacity1, int capacity2)
Allocate memory for a matrix.
Definition: DMatrix.h:170
std::ofstream outputFile_
Output file stream.
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.
Wrapper for a double precision number, for formatted ostream output.
Definition: Dbl.h:39
bool add(Symmetry &symmetry)
Add a new element to the group.
virtual void setup()
Set up before a simulation.
void readOutputFileName(std::istream &in)
Read outputFileName from file.
Saving / output archive for binary ostream.
A fixed capacity (static) contiguous array with a variable logical size.
Definition: FSArray.h:37
DArray< IntVector > waveIntVectors_
Array of miller index IntVectors for wavevectors.
#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 save(Serializable::OArchive &ar)
Save state to an archive.
void readInterval(std::istream &in)
Read interval from file, with error checking.
Utility classes for scientific computation.
Definition: accumulators.mod:1
virtual void loadParameters(Serializable::IArchive &ar)
Load state from an archive.
int nAtomType_
Number of atom types, copied from Simulation::nAtomType().
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
StructureFactorPGrid(System &system)
Constructor.
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
int nSample_
Number of samples thus far.
Saving archive for binary istream.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
DMatrix< double > structureFactors_
Structure factor accumulators.
void setClassName(const char *className)
Set class name string.
virtual void readParameters(std::istream &in)
Read parameters from file.
An IntVector is an integer Cartesian vector.
Definition: IntVector.h:73
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.
DArray< Vector > waveVectors_
Array of wave vectors (temporary)
int size() const
Return logical size of this array (i.e., number of elements).
Definition: FSArray.h:207
virtual void output()
Output structure factors, averaged over stars.
DArray< Pair< int > > atomTypeIdPairs_
Array of atom type indices (-1 indicates a sum of all types)
A PointSymmetry represents a crystallographic point group symmetry.
Definition: PointSymmetry.h:22
int nWave_
Number of wavevectors.