OPAL (Object Oriented Parallel Accelerator Library)  2024.1
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 
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or and a work based on the Program means either the Program or any derivative work under copyright a work containing the Program or a portion of it
Definition: LICENSE:43
std::vector< double > z_m
Definition: ThreeDGrid.h:324
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
double & x(const int &i)
Definition: ThreeDGrid.h:122
virtual bool isGreater(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs) const
Definition: ThreeDGrid.cpp:231
std::vector< double > x_m
Definition: ThreeDGrid.h:322
void add(VectorMap *map)
Definition: ThreeDGrid.cpp:257
Mesh::Iterator begin() const
Definition: ThreeDGrid.cpp:91
void lowerBound(const double &x, int &xIndex, const double &y, int &yIndex, const double &z, int &zIndex) const
Definition: ThreeDGrid.h:379
Base class for meshing routines.
Definition: Mesh.h:49
std::vector< int > state_m
Definition: Mesh.h:270
std::vector< VectorMap * > maps_m
Definition: ThreeDGrid.h:328
void remove(VectorMap *map)
Definition: ThreeDGrid.cpp:245
virtual void getPosition(const Mesh::Iterator &it, double *position) const
Definition: ThreeDGrid.cpp:101
virtual Mesh::Iterator & subEquals(Mesh::Iterator &lhs, int difference) const
Definition: ThreeDGrid.cpp:147
const T * find(const T table[], const std::string &name)
Look up name.
Definition: TFind.h:34
std::string::iterator iterator
Definition: MSLang.h:15
std::vector< double > y_m
Definition: ThreeDGrid.h:323
Definition: Vec.h:21
virtual Mesh::Iterator & subOne(Mesh::Iterator &lhs) const
Definition: ThreeDGrid.cpp:215
Mesh::Iterator getNearest(const double *position) const
Definition: ThreeDGrid.cpp:284
double & y(const int &j)
Definition: ThreeDGrid.h:128
virtual Mesh::Iterator & addEquals(Mesh::Iterator &lhs, int difference) const
Definition: ThreeDGrid.cpp:125
static void vectorLowerBound(std::vector< double > vec, double x, int &index)
Definition: ThreeDGrid.cpp:168
double & z(const int &k)
Definition: ThreeDGrid.h:134
Mesh::Iterator end() const
Definition: ThreeDGrid.cpp:95
constexpr double e
The value of .
Definition: Physics.h:39
Logical error exception.
Definition: LogicalError.h:33
virtual Mesh::Iterator & addOne(Mesh::Iterator &lhs) const
Definition: ThreeDGrid.cpp:202