Simpatico  v1.10
OrthorhombicBoundary.h
1 #ifndef SIMP_ORTHORHOMBIC_BOUNDARY_H
2 #define SIMP_ORTHORHOMBIC_BOUNDARY_H
3 
4 /*
5 * Util Package - C++ Utilities for Scientific Computation
6 *
7 * Copyright 2010 - 2017, The Regents of the University of Minnesota
8 * Distributed under the terms of the GNU General Public License.
9 */
10 
11 #include "OrthoRegion.h" // base class
12 #include <util/crystal/LatticeSystem.h> // member
13 #include <util/containers/FSArray.h> // member template
14 #include <util/space/Vector.h> // member template argument
15 #include <util/space/IntVector.h> // inline functions
16 #include <util/space/Dimension.h> // member template argument
17 #include <util/global.h> // asserts in inline functions
18 
19 #include <cmath>
20 #include <iostream>
21 
22 class OrthorhombicBoundaryTest;
23 
24 namespace Util {
25  class Random;
26 }
27 
28 namespace Simp
29 {
30 
31  using namespace Util;
32 
39  {
40 
41  public:
42 
47 
48  // Use default copy constructor.
49 
57  void setOrthorhombic(const Vector &lengths);
58 
65  void setTetragonal(double a, double bc);
66 
72  void setCubic(double a);
73 
80  template <class Archive>
81  void serialize(Archive& ar, const unsigned int version);
82 
84 
85 
98  void shift(Vector &r) const;
99 
114  void shift(Vector &r, IntVector& shift) const;
115 
129  void applyShift(Vector &r, int i, int t) const;
130 
142  void shiftGen(Vector &r) const;
143 
157  void shiftGen(Vector &r, IntVector& shift) const;
158 
160 
162 
173  double distanceSq(const Vector &r1, const Vector &r2) const;
174 
189  double distanceSq(const Vector &r1, const Vector &r2, IntVector& shift)
190  const;
191 
205  double distanceSq(const Vector &r1, const Vector &r2, Vector &dr) const;
206 
208 
210 
222  bool isMinImageGen(const Vector &dr);
223 
234  bool isMinImageCart(const Vector &dr);
235 
237 
239 
249  void transformCartToGen(const Vector& Rc, Vector& Rg) const;
250 
257  void transformGenToCart(const Vector& Rg, Vector& Rc) const;
258 
260 
262 
269 
273  const Vector& lengths() const;
274 
280  double length(int i) const;
281 
285  double minLength() const;
286 
290  double volume() const;
291 
297  const Vector& bravaisBasisVector(int i) const;
298 
304  const Vector& reciprocalBasisVector(int i) const;
305 
314  void randomPosition(Random &random, Vector &r) const;
315 
319  bool isValid();
320 
322 
323  private:
324 
328  FSArray<Vector, Dimension> bravaisBasisVectors_;
329 
333  FSArray<Vector, Dimension> reciprocalBasisVectors_;
334 
338  Vector invLengths_;
339 
343  double minLength_;
344 
348  LatticeSystem lattice_;
349 
350  // friends:
351 
353  friend class ::OrthorhombicBoundaryTest;
354 
356  friend std::istream& operator >> (std::istream& in,
357  Simp::OrthorhombicBoundary& boundary);
358 
360  friend std::ostream& operator << (std::ostream& out,
361  const Simp::OrthorhombicBoundary& boundary);
362 
366  void reset();
367 
368  };
369 
370  // Friend function declarations
371 
379  std::istream& operator >> (std::istream& in, OrthorhombicBoundary& boundary);
380 
388  std::ostream& operator << (std::ostream& out,
389  const OrthorhombicBoundary& boundary);
390 
391  // Inline member function definitions
392 
393  /*
394  * Return Vector of lengths by const reference.
395  */
396  inline const Vector& OrthorhombicBoundary::lengths() const
397  { return lengths_; }
398 
399  /*
400  * Get length = maximum - minimum in direction i.
401  */
402  inline double OrthorhombicBoundary::length(int i) const
403  { return lengths_[i]; }
404 
405  /*
406  * Return the maximum validity range of the distances.
407  */
408  inline double OrthorhombicBoundary::minLength() const
409  { return minLength_; }
410 
411  /*
412  * Return region volume.
413  */
414  inline double OrthorhombicBoundary::volume() const
415  { return volume_; }
416 
417  /*
418  * Return Bravais lattice basis vector number i.
419  */
421  { return bravaisBasisVectors_[i]; }
422 
423  /*
424  * Return reciprocal lattice basis vector number i.
425  */
427  { return reciprocalBasisVectors_[i]; }
428 
429  /*
430  * Shift Cartesian Vector r to primitive unit cell.
431  */
432  inline void OrthorhombicBoundary::shift(Vector& r) const
433  {
434  for (int i = 0; i < Dimension; ++i) {
435  if( r[i] >= maxima_[i] ) {
436  r[i] = r[i] - lengths_[i];
437  assert(r[i] < maxima_[i]);
438  } else
439  if ( r[i] < minima_[i] ) {
440  r[i] = r[i] + lengths_[i];
441  assert(r[i] >= minima_[i]);
442  }
443  }
444  }
445 
446  /*
447  * Shift Vector r to periodic cell, R[axis] < r[axis] < maxima_[axis].
448  */
450  {
451  for (int i = 0; i < Dimension; ++i) {
452  if (r[i] >= maxima_[i]) {
453  r[i] = r[i] - lengths_[i];
454  ++(shift[i]);
455  assert(r[i] < maxima_[i]);
456  } else
457  if (r[i] < minima_[i]) {
458  r[i] = r[i] + lengths_[i];
459  --(shift[i]);
460  assert(r[i] >= minima_[i]);
461  }
462  }
463  }
464 
465  /*
466  * Shift Cartesian Vector r by multiple t of a Bravais lattice vector.
467  */
468  inline void OrthorhombicBoundary::applyShift(Vector &r, int i, int t) const
469  { r[i] += t*lengths_[i]; }
470 
471  /*
472  * Shift generalized Vector r to primitive unit cell.
473  */
475  {
476  for (int i = 0; i < Dimension; ++i) {
477  if( r[i] >= 1.0 ) {
478  r[i] = r[i] - 1.0;
479  assert(r[i] < 1.0);
480  } else
481  if ( r[i] < 0.0 ) {
482  r[i] = r[i] + 1.0;
483  assert(r[i] >= 0.0);
484  }
485  }
486  }
487 
488  /*
489  * Shift generalized Vector r to primitive cell, 0 < r[axis] < 1.0.
490  */
491  inline
493  {
494  for (int i = 0; i < Dimension; ++i) {
495  if (r[i] >= 1.0) {
496  r[i] = r[i] - 1.0;
497  ++(shift[i]);
498  assert(r[i] < 1.0);
499  } else
500  if (r[i] < 0.0) {
501  r[i] = r[i] + 1.0;
502  --(shift[i]);
503  assert(r[i] >= 0.0);
504  }
505  }
506  }
507 
508  /*
509  * Calculate squared distance by minimum image convention.
510  */
511  inline
512  double OrthorhombicBoundary::distanceSq(const Vector &r1, const Vector &r2,
513  IntVector& translate) const
514  {
515  double dr;
516  double norm = 0.0;
517  for (int i = 0; i < Dimension; ++i) {
518  dr = r1[i] - r2[i];
519  if ( fabs(dr) > halfLengths_[i] ) {
520  if (dr > 0.0) {
521  dr -= lengths_[i];
522  translate[i] = -1;
523  } else {
524  dr += lengths_[i];
525  translate[i] = +1;
526  }
527  assert(fabs(dr) <= halfLengths_[i]);
528  } else {
529  translate[i] = 0;
530  }
531  norm += dr*dr;
532  }
533  return norm;
534  }
535 
536  /*
537  * Return squared distance and separation with minimum image convention.
538  */
539  inline
540  double OrthorhombicBoundary::distanceSq(const Vector &r1, const Vector &r2) const
541  {
542  double dr;
543  double norm = 0.0;
544  for (int i = 0; i < Dimension; ++i) {
545  dr = r1[i] - r2[i];
546  if (fabs(dr) > halfLengths_[i]) {
547  if (dr > 0.0) {
548  dr -= lengths_[i];
549  } else {
550  dr += lengths_[i];
551  }
552  assert(fabs(dr) <= halfLengths_[i]);
553  }
554  norm += dr*dr;
555  }
556  return norm;
557  }
558 
559  /*
560  * Calculate squared distance between two positions, and separation vector,
561  * using the minimum image convention.
562  */
563  inline
564  double OrthorhombicBoundary::distanceSq(const Vector &r1, const Vector &r2,
565  Vector &dr) const
566  {
567  for (int i = 0; i < Dimension; ++i) {
568  dr[i] = r1[i] - r2[i];
569  if (fabs(dr[i]) > halfLengths_[i]) {
570  if (dr[i] > 0.0) {
571  dr[i] -= lengths_[i];
572  } else {
573  dr[i] += lengths_[i];
574  }
575  assert(fabs(dr[i]) <= halfLengths_[i]);
576  }
577  }
578  return ( dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2] );
579  }
580 
581  /*
582  * Return actual lattice system.
583  */
585  { return lattice_; }
586 
587  /*
588  * Transform Cartesian Vector Rc to generalized Vector Rg.
589  */
590  inline void
592  const
593  {
594  for (int i = 0; i < Dimension; ++i) {
595  Rg[i] = Rc[i] * invLengths_[i];
596  }
597  }
598 
599  /*
600  * Transform Cartesian Vector Rc to generalized Vector Rg.
601  */
602  inline void
604  const
605  {
606  for (int i = 0; i < Dimension; ++i) {
607  Rc[i] = Rg[i] * lengths_[i];
608  }
609  }
610 
611  /*
612  * Is a generalized separation vector a minimimum image of itself?
613  */
614  inline
616  {
617  for (int i = 0; i < Dimension; ++i) {
618  if (fabs(dr[i]) > 0.5) {
619  return false;
620  }
621  }
622  return true;
623  }
624 
625  /*
626  * Is Cartesian separation vector dr a minimimum image of itself?
627  */
628  inline
630  {
631  for (int i = 0; i < Dimension; ++i) {
632  if (fabs(dr[i]) > halfLengths_[i]) {
633  return false;
634  }
635  }
636  return true;
637  }
638 
639  // Member function template
640 
641  /*
642  * Serialize an OrthorhombicBoundary to/from an archive.
643  */
644  template <class Archive> void
645  OrthorhombicBoundary::serialize(Archive& ar, const unsigned int version)
646  {
647  OrthoRegion::serialize(ar, version);
648  ar & bravaisBasisVectors_;
649  ar & reciprocalBasisVectors_;
650  ar & invLengths_;
651  ar & minLength_;
652  serializeEnum(ar, lattice_, version);
653  if (Archive::is_loading()) {
654  isValid();
655  }
656  }
657 
658 }
659 
660 #ifdef UTIL_MPI
661 #include <util/mpi/MpiSendRecv.h>
662 #include <util/mpi/MpiTraits.h>
663 
664 namespace Util
665 {
666 
667  using namespace Simp;
668 
672  template <>
673  void send<Simp::OrthorhombicBoundary>(MPI::Comm& comm,
674  Simp::OrthorhombicBoundary& data, int dest, int tag);
675 
679  template <>
680  void recv<Simp::OrthorhombicBoundary>(MPI::Comm& comm,
681  Simp::OrthorhombicBoundary& data, int source, int tag);
682 
686  template <>
687  void bcast<Simp::OrthorhombicBoundary>(MPI::Intracomm& comm,
688  Simp::OrthorhombicBoundary& data, int root);
689 
693  template <>
695  {
696  public:
697  static MPI::Datatype type;
698  static bool hasType;
699  };
700 
701 }
702 #endif // ifdef UTIL_MPI
703 
704 #endif // ifndef UTIL_ORTHORHOMBIC_BOUNDARY_H
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
void shiftGen(Vector &r) const
Shift generalized Vector r to its primary image.
A Vector is a Cartesian vector.
Definition: Vector.h:75
void setTetragonal(double a, double bc)
Set unit cell dimensions for tetragonal boundary.
bool isMinImageGen(const Vector &dr)
Is a generalized separation vector a minimimum image of itself?
double distanceSq(const Vector &r1, const Vector &r2) const
Return square distance between positions r1 and r2.
void serialize(Archive &ar, const unsigned int version)
Serialize to/from an archive.
double volume() const
Return unit cell volume.
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.
const Vector & bravaisBasisVector(int i) const
Return Bravais lattice vector i.
void setCubic(double a)
Set unit cell dimensions for a cubic boundary.
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.
LatticeSystem latticeSystem()
Return actual lattice system.
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
A fixed capacity (static) contiguous array with a variable logical size.
Definition: FSArray.h:37
const Vector & reciprocalBasisVector(int i) const
Return reciprocal lattice basis vector i.
Utility classes for scientific computation.
Definition: accumulators.mod:1
Default MpiTraits class.
Definition: MpiTraits.h:39
void serializeEnum(Archive &ar, T &data, const unsigned int version=0)
Serialize an enumeration value.
Definition: serialize.h:42
void shift(Vector &r) const
Shift Cartesian Vector r to its primary image.
double length(int i) const
Get length in Cartesian direction i.
void transformGenToCart(const Vector &Rg, Vector &Rc) const
Transform Vector of generalized coordinates to Cartesian Vector.
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
void applyShift(Vector &r, int i, int t) const
Shift Cartesian Vector r by multiple t of a Bravais lattice vector.
friend std::ostream & operator<<(std::ostream &out, const Simp::OrthorhombicBoundary &boundary)
ostream inserter
void serialize(Archive &ar, const unsigned int version)
Serialize to/from an archive.
Definition: OrthoRegion.h:79
This file contains templates for global functions send<T>, recv<T> and bcast<T>.
An IntVector is an integer Cartesian vector.
Definition: IntVector.h:73
double volume_
Volume: V = lengths_[0]*lengths_[1]*lengths_[2].
Definition: OrthoRegion.h:45
Random number generator.
Definition: Random.h:46
static bool hasType
Is the MPI type initialized?
A region with orthogonal edges parallel to the x, y, and z axes.
Definition: OrthoRegion.h:27
Vector halfLengths_
Half region lengths: halfLengths_[i] = 0.5*lengths_[i].
Definition: OrthoRegion.h:42
bool isMinImageCart(const Vector &dr)
Is a Cartesian separation vector a minimimum image of itself?
double minLength() const
Get minimum length across primitive unit cell.
void transformCartToGen(const Vector &Rc, Vector &Rg) const
Transform Cartesian Vector to scaled / generalized coordinates.