OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
ThreeDGrid.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Chris Rogers
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * 1. Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  * 2. Redistributions in binary form must reproduce the above copyright notice,
9  * this list of conditions and the following disclaimer in the documentation
10  * and/or other materials provided with the distribution.
11  * 3. Neither the name of STFC nor the names of its contributors may be used to
12  * endorse or promote products derived from this software without specific
13  * prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
29 #include "Utilities/LogicalError.h"
30 
31 namespace interpolation {
32 
34  : x_m(2, 0), y_m(2, 0), z_m(2, 0), xSize_m(0), ySize_m(0), zSize_m(0),
35  maps_m(0), constantSpacing_m(false) {
37  x_m[1] = y_m[1] = z_m[1] = 1.;
38 }
39 
40 ThreeDGrid::ThreeDGrid(int xSize, const double *x,
41  int ySize, const double *y,
42  int zSize, const double *z)
43  : x_m(x, x+xSize), y_m(y, y+ySize), z_m(z, z+zSize),
44  xSize_m(xSize), ySize_m(ySize), zSize_m(zSize),
45  maps_m(), constantSpacing_m(false) {
47  if (xSize_m < 2 || ySize_m < 2 || zSize_m < 2)
48  throw(LogicalError(
49  "ThreeDGrid::ThreeDGrid(...)",
50  "3D Grid must be at least 2x2x2 grid"
51  )
52  );
53 }
54 
55 ThreeDGrid::ThreeDGrid(std::vector<double> x,
56  std::vector<double> y,
57  std::vector<double> z)
58  : x_m(x), y_m(y), z_m(z),
59  xSize_m(x.size()), ySize_m(y.size()), zSize_m(z.size()),
60  maps_m(), constantSpacing_m(false) {
62  if (xSize_m < 2 || ySize_m < 2 || zSize_m < 2)
63  throw(LogicalError(
64  "ThreeDGrid::ThreeDGrid(...)",
65  "3D Grid must be at least 2x2x2 grid"
66  )
67  );
68 }
69 
70 ThreeDGrid::ThreeDGrid(double dX, double dY, double dZ,
71  double minX, double minY, double minZ,
72  int numberOfXCoords, int numberOfYCoords,
73  int numberOfZCoords)
74  : x_m(numberOfXCoords), y_m(numberOfYCoords), z_m(numberOfZCoords),
75  xSize_m(numberOfXCoords), ySize_m(numberOfYCoords),
76  zSize_m(numberOfZCoords), maps_m(), constantSpacing_m(true) {
77  for (int i = 0; i < numberOfXCoords; i++)
78  x_m[i] = minX+i*dX;
79  for (int j = 0; j < numberOfYCoords; j++)
80  y_m[j] = minY+j*dY;
81  for (int k = 0; k < numberOfZCoords; k++)
82  z_m[k] = minZ+k*dZ;
83 
85 }
86 
88 }
89 
90 // state starts at 1,1,1
92  return Mesh::Iterator(std::vector<int>(3, 1), this);
93 }
94 
96  std::vector<int> end(3, 1);
97  end[0] = xSize_m+1;
98  return Mesh::Iterator(end, this);
99 }
100 
102  double * position) const {
103  position[0] = x(it.state_m[0]);
104  position[1] = y(it.state_m[1]);
105  position[2] = z(it.state_m[2]);
106 }
107 
109  std::vector<double> new_x(x_m.size()-1);
110  std::vector<double> new_y(y_m.size()-1);
111  std::vector<double> new_z(z_m.size()-1);
112  for (size_t i = 0; i < x_m.size()-1; ++i) {
113  new_x[i] = (x_m[i]+x_m[i+1])/2.;
114  }
115  for (size_t i = 0; i < y_m.size()-1; ++i) {
116  new_y[i] = (y_m[i]+y_m[i+1])/2.;
117  }
118  for (size_t i = 0; i < z_m.size()-1; ++i) {
119  new_z[i] = (z_m[i]+z_m[i+1])/2.;
120  }
121  return new ThreeDGrid(new_x, new_y, new_z);
122 }
123 
125  (Mesh::Iterator& lhs, int difference) const {
126  if (difference < 0)
127  return subEquals(lhs, -difference);
128 
129  lhs.state_m[0] += difference/(ySize_m*zSize_m);
130  difference = difference%(ySize_m*zSize_m);
131  lhs.state_m[1] += difference/(zSize_m);
132  lhs.state_m[2] += difference%(zSize_m);
133 
134  if (lhs.state_m[1] > ySize_m) {
135  lhs.state_m[0]++;
136  lhs.state_m[1] -= ySize_m;
137  }
138  if (lhs.state_m[2] > zSize_m) {
139  lhs.state_m[1]++;
140  lhs.state_m[2] -= zSize_m;
141  }
142 
143  return lhs;
144 }
145 
147  (Mesh::Iterator& lhs, int difference) const {
148  if (difference < 0)
149  return addEquals(lhs, -difference);
150 
151  lhs.state_m[0] -= difference/(ySize_m*zSize_m);
152  difference = difference%(ySize_m*zSize_m);
153  lhs.state_m[1] -= difference/(zSize_m);
154  lhs.state_m[2] -= difference%(zSize_m);
155 
156  while (lhs.state_m[2] < 1) {
157  lhs.state_m[1]--;
158  lhs.state_m[2] += zSize_m;
159  }
160  while (lhs.state_m[1] < 1) {
161  lhs.state_m[0]--;
162  lhs.state_m[1] += ySize_m;
163  }
164 
165  return lhs;
166 }
167 
168 void ThreeDGrid::vectorLowerBound(std::vector<double> vec,
169  double x,
170  int& index) {
171  if (x < vec[0]) {
172  index = -1;
173  return;
174  }
175  if (x >= vec.back()) {
176  index = vec.size()-1;
177  return;
178  }
179  size_t xLower = 0;
180  size_t xUpper = vec.size()-1;
181  while (xUpper - xLower > 1) {
182  index = (xUpper+xLower)/2;
183  if (x >= vec[index]) {
184  xLower = index;
185  } else {
186  xUpper = index;
187  }
188  }
189  index = xLower;
190 }
191 
193  (Mesh::Iterator& lhs, const Mesh::Iterator& rhs) const {
194  return addEquals(lhs, rhs.toInteger());
195 }
196 
198  (Mesh::Iterator& lhs, const Mesh::Iterator& rhs) const {
199  return subEquals(lhs, rhs.toInteger());
200 }
201 
203  if (lhs.state_m[1] == ySize_m && lhs.state_m[2] == zSize_m) {
204  ++lhs.state_m[0];
205  lhs.state_m[1] = lhs.state_m[2] = 1;
206  } else if (lhs.state_m[2] == zSize_m) {
207  ++lhs.state_m[1];
208  lhs.state_m[2] = 1;
209  } else {
210  ++lhs.state_m[2];
211  }
212  return lhs;
213 }
214 
216  if (lhs.state_m[1] == 1 && lhs.state_m[2] == 1) {
217  --lhs.state_m[0];
218  lhs.state_m[1] = ySize_m;
219  lhs.state_m[2] = zSize_m;
220  } else if (lhs.state_m[2] == 1) {
221  --lhs.state_m[1];
222  lhs.state_m[2] = zSize_m;
223  } else {
224  --lhs.state_m[2];
225  }
226  return lhs;
227 }
228 
229 // Check relative position
231  (const Mesh::Iterator& lhs, const Mesh::Iterator& rhs) const {
232  if (lhs.state_m[0] > rhs.state_m[0])
233  return true;
234  else if (lhs.state_m[0] == rhs.state_m[0] &&
235  lhs.state_m[1] > rhs.state_m[1])
236  return true;
237  else if (lhs.state_m[0] == rhs.state_m[0] &&
238  lhs.state_m[1] == rhs.state_m[1] &&
239  lhs.state_m[2] > rhs.state_m[2])
240  return true;
241  return false;
242 }
243 
244 // remove *map if it exists; delete this if there are no more VectorMaps
247  std::find(maps_m.begin(), maps_m.end(), map);
248  if (it < maps_m.end()) {
249  maps_m.erase(it);
250  }
251  if (maps_m.begin() == maps_m.end()) {
252  delete this;
253  }
254 }
255 
256 // add *map if it has not already been added
259  std::find(maps_m.begin(), maps_m.end(), map);
260  if (it == maps_m.end()) {
261  maps_m.push_back(map);
262  }
263 }
264 
266  constantSpacing_m = true;
267  for (unsigned int i = 0; i < x_m.size()-1; i++)
268  if (std::abs(1-(x_m[i+1]-x_m[i])/(x_m[1]-x_m[0])) > 1e-9) {
269  constantSpacing_m = false;
270  return;
271  }
272  for (unsigned int i = 0; i < y_m.size()-1; i++)
273  if (std::abs(1-(y_m[i+1]-y_m[i])/(y_m[1]-y_m[0])) > 1e-9) {
274  constantSpacing_m = false;
275  return;
276  }
277  for (unsigned int i = 0; i < z_m.size()-1; i++)
278  if (std::abs(1-(z_m[i+1]-z_m[i])/(z_m[1]-z_m[0])) > 1e-9) {
279  constantSpacing_m = false;
280  return;
281  }
282 }
283 
284 Mesh::Iterator ThreeDGrid::getNearest(const double* position) const {
285  std::vector<int> index(3);
286  lowerBound(position[0], index[0],
287  position[1], index[1],
288  position[2], index[2]);
289  if (index[0] < xSize_m-1 && index[0] >= 0)
290  index[0] += (2*(position[0] - x_m[index[0]]) >
291  x_m[index[0]+1]-x_m[index[0]] ? 2 : 1);
292  else
293  index[0]++;
294  if (index[1] < ySize_m-1 && index[1] >= 0)
295  index[1] += (2*(position[1] - y_m[index[1]]) >
296  y_m[index[1]+1]-y_m[index[1]] ? 2 : 1);
297  else
298  index[1]++;
299  if (index[2] < zSize_m-1 && index[2] >= 0)
300  index[2] += (2*(position[2] - z_m[index[2]]) >
301  z_m[index[2]+1]-z_m[index[2]] ? 2 : 1);
302  else
303  index[2]++;
304  if (index[0] < 1)
305  index[0] = 1;
306  if (index[1] < 1)
307  index[1] = 1;
308  if (index[2] < 1)
309  index[2] = 1;
310  if (index[0] > xSize_m)
311  index[0] = xSize_m;
312  if (index[1] > ySize_m)
313  index[1] = ySize_m;
314  if (index[2] > zSize_m)
315  index[2] = zSize_m;
316  return Mesh::Iterator(index, this);
317 }
318 }
319 
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
const T * find(const T table[], const std::string &name)
Look up name.
Definition: TFind.h:34
constexpr double e
The value of.
Definition: Physics.h:39
std::string::iterator iterator
Definition: MSLang.h:16
Base class for meshing routines.
Definition: Mesh.h:49
std::vector< int > state_m
Definition: Mesh.h:270
Mesh::Iterator begin() const
Definition: ThreeDGrid.cpp:91
std::vector< double > y_m
Definition: ThreeDGrid.h:323
virtual void getPosition(const Mesh::Iterator &it, double *position) const
Definition: ThreeDGrid.cpp:101
static void vectorLowerBound(std::vector< double > vec, double x, int &index)
Definition: ThreeDGrid.cpp:168
Mesh::Iterator end() const
Definition: ThreeDGrid.cpp:95
std::vector< double > x_m
Definition: ThreeDGrid.h:322
virtual Mesh::Iterator & subEquals(Mesh::Iterator &lhs, int difference) const
Definition: ThreeDGrid.cpp:147
void remove(VectorMap *map)
Definition: ThreeDGrid.cpp:245
std::vector< double > z_m
Definition: ThreeDGrid.h:324
virtual Mesh::Iterator & subOne(Mesh::Iterator &lhs) const
Definition: ThreeDGrid.cpp:215
virtual bool isGreater(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs) const
Definition: ThreeDGrid.cpp:231
double & y(const int &j)
Definition: ThreeDGrid.h:128
void add(VectorMap *map)
Definition: ThreeDGrid.cpp:257
virtual Mesh::Iterator & addOne(Mesh::Iterator &lhs) const
Definition: ThreeDGrid.cpp:202
virtual Mesh::Iterator & addEquals(Mesh::Iterator &lhs, int difference) const
Definition: ThreeDGrid.cpp:125
void lowerBound(const double &x, int &xIndex, const double &y, int &yIndex, const double &z, int &zIndex) const
Definition: ThreeDGrid.h:379
double & x(const int &i)
Definition: ThreeDGrid.h:122
std::vector< VectorMap * > maps_m
Definition: ThreeDGrid.h:328
double & z(const int &k)
Definition: ThreeDGrid.h:134
Mesh::Iterator getNearest(const double *position) const
Definition: ThreeDGrid.cpp:284
Logical error exception.
Definition: LogicalError.h:33
Definition: Vec.h:22