Simpatico  v1.10
OrthorhombicBoundary.cpp
1 /*
2 * Util Package - C++ Utilities for Scientific Computation
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 "OrthorhombicBoundary.h"
9 #include <util/space/Vector.h>
10 #include <util/space/Dimension.h>
11 #include <util/random/Random.h>
12 #include <util/math/Constants.h>
13 #include <util/math/feq.h>
14 #include <util/format/Dbl.h>
15 #include <util/global.h>
16 
17 namespace Simp
18 {
19 
20  using namespace Util;
21 
22  /*
23  * Default constructor.
24  */
26  : OrthoRegion(),
27  lattice_(Orthorhombic)
28  {
29  for (int i = 0; i < Dimension; ++i) {
30  invLengths_[i] = 1.0/lengths_[i];
31  bravaisBasisVectors_.append(Vector::Zero);
32  bravaisBasisVectors_[i][i] = lengths_[i];
33  reciprocalBasisVectors_.append(Vector::Zero);
34  reciprocalBasisVectors_[i][i] = 2.0*Constants::Pi/lengths_[i];
35  }
36  minLength_ = lengths_[0];
37  for (int i = 1; i < Dimension; ++i) {
38  if (lengths_[i] < minLength_) {
39  minLength_ = lengths_[i];
40  }
41  }
42  }
43 
44  /*
45  * Set box lengths and then call reset.
46  */
48  {
49  maxima_ = lengths;
50  lattice_ = Orthorhombic;
51  reset();
52  }
53 
54  /*
55  * Set box lengths and then call reset.
56  */
57  void OrthorhombicBoundary::setTetragonal(double a, double bc)
58  {
59  maxima_[0] = a;
60  maxima_[1] = bc;
61  maxima_[2] = bc;
62  lattice_ = Tetragonal;
63  reset();
64  }
65 
66  /*
67  * Set box lengths and call reset.
68  */
70  {
71  maxima_[0] = a;
72  maxima_[1] = a;
73  maxima_[2] = a;
74  lattice_ = Cubic;
75  reset();
76  }
77 
78  /*
79  * Reset all quantities that depend on unit cell lengths.
80  */
81  void OrthorhombicBoundary::reset()
82  {
83  resetRegion();
84  for (int i = 0; i < Dimension; ++i) {
85  invLengths_[i] = 1.0/lengths_[i];
86  bravaisBasisVectors_[i][i] = lengths_[i];
87  reciprocalBasisVectors_[i][i] = 2.0*Constants::Pi/lengths_[i];
88  }
89 
90  minLength_ = lengths_[0];
91  for (int i = 1; i < Dimension; ++i) {
92  if (lengths_[i] < minLength_) {
93  minLength_ = lengths_[i];
94  }
95  }
96 
97  }
98 
99  /*
100  * Generate a random position within the box
101  *
102  * \param random random number generator object
103  * \param r Vector of random coordinates
104  */
106  {
107  for (int i=0; i < Dimension; ++i) {
108  r[i] = random.uniform(minima_[i], maxima_[i]);
109  }
110  }
111 
112  /*
113  * Check consistency of data.
114  */
116  {
117  double dot;
118  double twoPi = 2.0*Constants::Pi;
119  int i, j;
120 
122  for (i = 0; i < Dimension; ++i) {
123  if (!feq(minima_[i], 0.0)) {
124  UTIL_THROW("minima_[i] != 0");
125  }
126  if (!feq(lengths_[i]*invLengths_[i], 1.0)) {
127  UTIL_THROW("invLengths_[i]*lengths_[i] != 1.0");
128  }
129  if (!feq(lengths_[i], bravaisBasisVectors_[i][i])) {
130  UTIL_THROW("bravaisBasisVectors_[i][i] != lengths_[i]");
131  }
132  for (j = 0; j < Dimension; ++j) {
133  dot = bravaisBasisVectors_[i].dot(reciprocalBasisVectors_[j]);
134  if (i == j) {
135  if (!feq(dot, twoPi)) {
136  UTIL_THROW("a[i].b[i] != twoPi");
137  }
138  } else {
139  if (!feq(dot, 0.0)) {
140  UTIL_THROW("a[i].b[j] != 0 for i != j");
141  }
142  if (!feq(bravaisBasisVectors_[i][j], 0.0)) {
143  UTIL_THROW("Nonzero off-diagonal element of bravaisBasisVectors_");
144  }
145  if (!feq(reciprocalBasisVectors_[i][j], 0.0)) {
146  UTIL_THROW("Nonzero off-diagonal element of reciprocalBasisVectors_");
147  }
148  }
149  }
150  }
151  return true;
152  }
153 
154  /*
155  * Input a OrthorhombicBoundary from an istream, without line breaks.
156  */
157  std::istream& operator >> (std::istream& in, OrthorhombicBoundary &boundary)
158  {
159  LatticeSystem lattice;
160  in >> lattice;
161  if (lattice == Orthorhombic) {
162  in >> boundary.maxima_;
163  } else
164  if (lattice == Tetragonal) {
165  double a, bc;
166  in >> a >> bc;
167  boundary.maxima_[0] = a;
168  boundary.maxima_[1] = bc;
169  boundary.maxima_[2] = bc;
170  } else
171  if (lattice == Cubic) {
172  double a;
173  in >> a;
174  boundary.maxima_[0] = a;
175  boundary.maxima_[1] = a;
176  boundary.maxima_[2] = a;
177  } else {
178  UTIL_THROW("Lattice must be orthorhombic, tetragonal or cubic");
179  }
180  boundary.lattice_ = lattice;
181  boundary.reset();
182  return in;
183  }
184 
185  /*
186  * Output an OrthorhombicBoundary to an ostream, without line breaks.
187  */
188  std::ostream&
189  operator << (std::ostream& out, const OrthorhombicBoundary &boundary)
190  {
191  out << boundary.lattice_ << " ";
192  if (boundary.lattice_ == Orthorhombic) {
193  out << boundary.lengths_;
194  } else
195  if (boundary.lattice_ == Tetragonal) {
196  out << Dbl(boundary.lengths_[0]);
197  out << Dbl(boundary.lengths_[2]);
198  } else
199  if (boundary.lattice_ == Cubic) {
200  out << Dbl(boundary.lengths_[0]);
201  }
202  return out;
203  }
204 }
205 
206 #ifdef UTIL_MPI
207 namespace Util {
208 
209  template <>
210  void send<Simp::OrthorhombicBoundary>(MPI::Comm& comm,
211  Simp::OrthorhombicBoundary& data, int dest, int tag)
212  {
213  Vector lengths = data.lengths();
214  send<Vector>(comm, lengths, dest, tag);
215  }
216 
217  template <>
218  void recv<Simp::OrthorhombicBoundary>(MPI::Comm& comm,
219  Simp::OrthorhombicBoundary& data, int source, int tag)
220  {
221  Vector lengths;
222  recv<Vector>(comm, lengths, source, tag);
223  data.setOrthorhombic(lengths);
224  }
225 
226  template <>
227  void bcast<Simp::OrthorhombicBoundary>(MPI::Intracomm& comm,
228  Simp::OrthorhombicBoundary& data, int root)
229  {
230  Vector lengths;
231  int rank = comm.Get_rank();
232  if (rank == root) {
233  lengths = data.lengths();
234  }
235  bcast<Vector>(comm, lengths, root);
236  if (rank != root) {
237  data.setOrthorhombic(lengths);
238  }
239  }
240 
241  /*
242  * Initialize MPI Datatype.
243  */
244  MPI::Datatype MpiTraits<Simp::OrthorhombicBoundary>::type = MPI::BYTE;
246 
247 }
248 #endif
bool isValid()
Return true if valid, or throw Exception.
Definition: OrthoRegion.cpp:50
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
A Vector is a Cartesian vector.
Definition: Vector.h:75
void resetRegion()
Set lengths and volume to values consistent with minima and maxima.
Definition: OrthoRegion.cpp:37
void setTetragonal(double a, double bc)
Set unit cell dimensions for tetragonal boundary.
void randomPosition(Random &random, Vector &r) const
Generate random position within the primary unit cell.
void setOrthorhombic(const Vector &lengths)
Set unit cell dimensions for orthorhombic boundary.
const Vector & lengths() const
Get Vector of unit cell lengths by const reference.
An orthorhombic periodic unit cell.
bool isValid()
Return true if valid, or throw Exception.
static const Vector Zero
Zero Vector = {0.0, 0.0, 0.0}.
Definition: Vector.h:369
void setCubic(double a)
Set unit cell dimensions for a cubic boundary.
Wrapper for a double precision number, for formatted ostream output.
Definition: Dbl.h:39
friend std::istream & operator>>(std::istream &in, Simp::OrthorhombicBoundary &boundary)
istream extractor
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
double uniform()
Return a random floating point number x, uniformly distributed in the range 0 <= x < 1...
Definition: Random.h:203
Vector minima_
Minimum coordinates: Require r[i] >= minima_[i].
Definition: OrthoRegion.h:33
Vector lengths_
OrthoRegion lengths: lengths_[i] = maxima_[i] - minima_[i].
Definition: OrthoRegion.h:39
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
Utility classes for scientific computation.
Definition: accumulators.mod:1
Default MpiTraits class.
Definition: MpiTraits.h:39
Vector maxima_
Maximum coordinates: Require r[i] < maxima_[i].
Definition: OrthoRegion.h:36
LatticeSystem
Enumeration of the 7 possible Bravais lattice systems.
Definition: LatticeSystem.h:29
friend std::ostream & operator<<(std::ostream &out, const Simp::OrthorhombicBoundary &boundary)
ostream inserter
static const double Pi
Trigonometric constant Pi.
Definition: Constants.h:35
Random number generator.
Definition: Random.h:46
bool feq(double x, double y, double eps=1.0E-10)
Are two floating point numbers equal to within round-off error?
Definition: feq.h:27
A region with orthogonal edges parallel to the x, y, and z axes.
Definition: OrthoRegion.h:27