Simpatico  v1.10
Domain.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 "Domain.h"
9 #include <util/space/Dimension.h>
10 
11 namespace DdMd
12 {
13 
14  using namespace Util;
15 
16  /*
17  * Constructor.
18  */
20  : ParamComposite(),
21  sourceRanks_(),
22  destRanks_(),
23  shift_(),
24  gridDimensions_(),
25  gridCoordinates_(),
26  gridRank_(-1),
27  gridIsPeriodic_(),
28  #if UTIL_MPI
29  intracommPtr_(0),
30  #endif
31  boundaryPtr_(0),
32  isInitialized_(false)
33  { setClassName("Domain"); }
34 
35  /*
36  * Destructor.
37  */
39  {}
40 
41  #if UTIL_MPI
42  /*
43  * Set the grid intracommunicator.
44  */
45  void Domain::setGridCommunicator(MPI::Intracomm& intraCommunicator)
46  {
47  intracommPtr_ = &intraCommunicator;
48  gridRank_ = intracommPtr_->Get_rank();
49  }
50  #else
51  void Domain::setRank(int rank)
52  { gridRank_ = rank; }
53  #endif
54 
55  /*
56  * Set the Boundary object.
57  */
58  void Domain::setBoundary(Boundary& boundary)
59  { boundaryPtr_ = &boundary; }
60 
61  /*
62  * Read parameters and initialize.
63  */
64  void Domain::readParameters(std::istream& in)
65  {
66 
67  #ifdef UTIL_MPI
68  if (intracommPtr_ == 0) {
69  UTIL_THROW("Intra-communicator not set before readParam");
70  }
71  #endif
72  if (gridRank_ < 0) {
73  UTIL_THROW("grid rank not set before readParam");
74  }
75  if (!hasBoundary()) {
76  UTIL_THROW("Boundary not set before readParam");
77  }
78  if (isInitialized_) {
79  UTIL_THROW("Already initialized");
80  }
81 
82  // Read processor grid dimensions and initialize
83  read<IntVector>(in, "gridDimensions", gridDimensions_);
84  initialize();
85  }
86 
87  /*
88  * Read parameters and initialize.
89  */
91  {
92  #ifdef UTIL_MPI
93  if (intracommPtr_ == 0) {
94  UTIL_THROW("Intra-communicator not set before readParam");
95  }
96  #endif
97  if (gridRank_ < 0) {
98  UTIL_THROW("grid rank not set before readParam");
99  }
100  if (!hasBoundary()) {
101  UTIL_THROW("Boundary not set before readParam");
102  }
103  if (isInitialized_) {
104  UTIL_THROW("Already initialized");
105  }
106 
107  // Read processor grid dimensions and initialize
108  loadParameter<IntVector>(ar, "gridDimensions", gridDimensions_);
109  initialize();
110  }
111 
112  /*
113  * Save internal state to an archive.
114  */
116  { ar << gridDimensions_; }
117 
118  /*
119  * Initialize data - called by readParameters and loadParameters (private).
120  */
121  void Domain::initialize()
122  {
123  // Validate gridDimensions
124  int nproc = 1;
125  for (int i = 0; i < Dimension; i++) {
126  if (gridDimensions_[i] <= 0) {
127  UTIL_THROW("Processor grid dimensions must be greater than 0");
128  }
129  nproc *= gridDimensions_[i];
130  }
131  int commSize = 1;
132  #ifdef UTIL_MPI
133  commSize = intracommPtr_->Get_size();
134  #endif
135  if (nproc != commSize) {
136  UTIL_THROW("Grid dimensions inconsistent with communicator size");
137  }
138 
139  // Set grid dimensions
140  grid_.setDimensions(gridDimensions_);
141 
142  // Mark all directions as periodic.
143  for (int i = 0; i < Dimension; i++) {
144  gridIsPeriodic_[i] = true;
145  }
146 
147  // Find grid coordinates for this processor
148  gridCoordinates_ = grid_.position(gridRank_);
149 
150  IntVector sourceCoordinates;
151  int i, j, k, jp;
152 
153  // Loop over Cartesian direction for send
154  for (i = 0; i < Dimension; ++i) {
155 
156  // Loop over increment sign (+1 or -1 grid coordinate i)
157  for (j = 0; j < 2; ++j) {
158 
159  // Increment to source along coordinate i
160  k = (j == 0 ? 1 : -1);
161 
162  // Complementary index (other direction)
163  jp = (j == 0 ? 1 : 0);
164 
165  //Initialize coordinates of the partner processor
166  sourceCoordinates = gridCoordinates_;
167  sourceCoordinates[i] = gridCoordinates_[i] + k;
168 
169  // Check for transfer past boundary
170  if (gridIsPeriodic_[i] == true) {
171  shift_(i, j) = grid_.shift(sourceCoordinates[i], i);
172  sourceRanks_(i, j) = grid_.rank(sourceCoordinates);
173  destRanks_(i, jp) = sourceRanks_(i, j);
174  } else {
175  shift_(i, j) = 0;
176  if (!grid_.isInGrid(sourceCoordinates[i], i)) {
177  destRanks_(i, j) = -1;
178  sourceRanks_(i, jp) = -1;
179  }
180  }
181 
182  }
183  }
184  isInitialized_ = true;
185  }
186 
187  /*
188  * Return one of the boundaries of the domain owned by this processor.
189  */
190  double Domain::domainBound(int i, int j) const
191  {
192  // Preconditions
193  assert(isInitialized_);
194  assert(boundaryPtr_);
195  assert(i >= 0);
196  assert(i < Dimension);
197  assert(j >= 0);
198  assert(j < 2);
199 
200  double dL;
201  dL = 1.0 / double(gridDimensions_[i]);
202  return (gridCoordinates_[i] + j)*dL;
203  }
204 
205  /*
206  * Return rank of processor whose domain contains a position Vector.
207  */
208  int Domain::ownerRank(const Vector& position) const
209  {
210  // Preconditions
211  assert(isInitialized_);
212  assert(boundaryPtr_);
213 
214  double dL;
215  IntVector r;
216  for (int i = 0; i < Dimension; ++i) {
217  dL = 1.0 / double(gridDimensions_[i]);
218  r[i] = int(position[i] / dL);
219  if (r[i] < 0 || r[i] >= gridDimensions_[i]) {
220  Log::file() << "Cart i = " << i << std::endl;
221  Log::file() << "position = " << position[i] << std::endl;
222  Log::file() << "dL = " << dL << std::endl;
223  Log::file() << "r = " << r[i] << std::endl;
224  Log::file() << "gridDim = " << gridDimensions_[i] << std::endl;
225  UTIL_THROW("Invalid grid coordinate");
226  }
227  }
228  return grid_.rank(r);
229  }
230 
231  /*
232  * Does a Vector lie in the domain owned by this processor?
233  */
234  bool Domain::isInDomain(const Vector& position) const
235  {
236  // Preconditions
237  assert(isInitialized_);
238  assert(boundaryPtr_);
239 
240  double dL;
241  bool isIn = true;
242  for (int i = 0; i < Dimension; ++i) {
243  dL = 1.0 / double(gridDimensions_[i]);
244  if (position[i] < gridCoordinates_[i]*dL) {
245  isIn = false;
246  }
247  if (position[i] >= (gridCoordinates_[i] + 1)*dL) {
248  isIn = false;
249  }
250  }
251  return isIn;
252  }
253 
254 }
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
virtual void readParameters(std::istream &in)
Read parameters and initialize.
Definition: Domain.cpp:64
A Vector is a Cartesian vector.
Definition: Vector.h:75
An orthorhombic periodic unit cell.
void setGridCommunicator(MPI::Intracomm &communicator)
Set the grid communicator.
Definition: Domain.cpp:45
int ownerRank(const Vector &position) const
Return rank of the processor whose domain contains a position.
Definition: Domain.cpp:208
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Definition: Domain.cpp:115
IntVector position(int rank) const
Get the position IntVector of a grid point with a specified rank.
Definition: Grid.cpp:64
Parallel domain decomposition (DD) MD simulation.
bool isInGrid(int coordinate, int i) const
Is this coordinate in range?
Definition: Grid.cpp:78
int shift(int &coordinate, int i) const
Shift a periodic coordinate into range.
Definition: Grid.cpp:100
virtual ~Domain()
Destructor.
Definition: Domain.cpp:38
Saving / output archive for binary ostream.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Definition: Domain.cpp:90
Utility classes for scientific computation.
Definition: accumulators.mod:1
int rank(const IntVector &position) const
Get the rank of a grid point with specified position.
Definition: Grid.cpp:49
void setBoundary(Boundary &boundary)
Set the associated Boundary object.
Definition: Domain.cpp:58
static std::ostream & file()
Get log ostream by reference.
Definition: Log.cpp:57
bool isInDomain(const Vector &position) const
Is a position in the domain owned by this processor?
Definition: Domain.cpp:234
Saving archive for binary istream.
double domainBound(int i, int j) const
Get one boundary of the domain owned by this processor.
Definition: Domain.cpp:190
Domain()
Constructor.
Definition: Domain.cpp:19
void setClassName(const char *className)
Set class name string.
An IntVector is an integer Cartesian vector.
Definition: IntVector.h:73
void setDimensions(const IntVector &dimensions)
Set the grid dimensions in all directions.
Definition: Grid.cpp:32
bool hasBoundary() const
Has an associated Boundary been set?
Definition: Domain.h:355
An object that can read multiple parameters from file.