OPAL (Object Oriented Parallel Accelerator Library) 2022.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
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: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
double & x(const int &i)
Definition: ThreeDGrid.h:122
double & z(const int &k)
Definition: ThreeDGrid.h:134
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
std::vector< VectorMap * > maps_m
Definition: ThreeDGrid.h:328
Mesh::Iterator getNearest(const double *position) const
Definition: ThreeDGrid.cpp:284
Logical error exception.
Definition: LogicalError.h:33
Definition: Vec.h:22