OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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
30
31namespace 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
40ThreeDGrid::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
55ThreeDGrid::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
70ThreeDGrid::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
168void 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
284Mesh::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:15
Base class for meshing routines.
Used to loop over some, or all, points in the mesh, as in stl Enables e.g.
int toInteger() const
Return an integer representation of the iterator.
Mesh::Iterator begin() const
Return an iterator pointing at the first element in the ThreeDGrid.
Definition: ThreeDGrid.cpp:91
void setConstantSpacing()
Autodetect constant spacing with float tolerance of 1e-9.
Definition: ThreeDGrid.cpp:265
std::vector< double > y_m
Definition: ThreeDGrid.h:323
virtual void getPosition(const Mesh::Iterator &it, double *position) const
Fill position with the position of it.
Definition: ThreeDGrid.cpp:101
Mesh * dual() const
Not implemented (returns nullptr)
Definition: ThreeDGrid.cpp:108
static void vectorLowerBound(std::vector< double > vec, double x, int &index)
Custom LowerBound routine like std::lower_bound.
Definition: ThreeDGrid.cpp:168
Mesh::Iterator end() const
Return an iterator pointing at the last+1 element in the ThreeDGrid.
Definition: ThreeDGrid.cpp:95
std::vector< double > x_m
Definition: ThreeDGrid.h:322
virtual Mesh::Iterator & subEquals(Mesh::Iterator &lhs, int difference) const
Subtract difference from lhs and then return lhs.
Definition: ThreeDGrid.cpp:147
void remove(VectorMap *map)
Remove *map from the maps_m list if it has not already been removed.
Definition: ThreeDGrid.cpp:245
std::vector< double > z_m
Definition: ThreeDGrid.h:324
double minY() const
Return the smallest value of y in the grid.
Definition: ThreeDGrid.h:430
ThreeDGrid()
Default constructor.
Definition: ThreeDGrid.cpp:33
virtual Mesh::Iterator & subOne(Mesh::Iterator &lhs) const
Decrement position of lhs by one and then return lhs.
Definition: ThreeDGrid.cpp:215
double & x(const int &i)
Get ith coordinate in x.
Definition: ThreeDGrid.h:122
double & z(const int &k)
Get ith coordinate in z.
Definition: ThreeDGrid.h:134
virtual bool isGreater(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs) const
Return true if rhs is greater than lhs.
Definition: ThreeDGrid.cpp:231
double & y(const int &j)
Get ith coordinate in y.
Definition: ThreeDGrid.h:128
void add(VectorMap *map)
Add *map to the maps_m list if it has not already been added.
Definition: ThreeDGrid.cpp:257
virtual Mesh::Iterator & addOne(Mesh::Iterator &lhs) const
Increment position of lhs by one and then return lhs.
Definition: ThreeDGrid.cpp:202
double minX() const
Return the smallest value of x in the grid.
Definition: ThreeDGrid.h:422
virtual Mesh::Iterator & addEquals(Mesh::Iterator &lhs, int difference) const
Add difference to lhs and then return lhs.
Definition: ThreeDGrid.cpp:125
void lowerBound(const double &x, int &xIndex, const double &y, int &yIndex, const double &z, int &zIndex) const
Find the indices of the nearest point on the grid less than x, y, z.
Definition: ThreeDGrid.h:379
double minZ() const
Return the smallest value of z in the grid.
Definition: ThreeDGrid.h:438
std::vector< VectorMap * > maps_m
Definition: ThreeDGrid.h:328
Mesh::Iterator getNearest(const double *position) const
Return the point in the mesh nearest to position.
Definition: ThreeDGrid.cpp:284
VectorMap is an abstract class that defines mapping from one vector to another.
Definition: VectorMap.h:46
Logical error exception.
Definition: LogicalError.h:33
Definition: Vec.h:22