OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
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),
35 y_m(2, 0),
36 z_m(2, 0),
37 xSize_m(0),
38 ySize_m(0),
39 zSize_m(0),
40 maps_m(0),
41 constantSpacing_m(false) {
43 x_m[1] = y_m[1] = z_m[1] = 1.;
44 }
45
47 int xSize, const double* x, int ySize, const double* y, int zSize, const double* z)
48 : x_m(x, x + xSize),
49 y_m(y, y + ySize),
50 z_m(z, z + zSize),
51 xSize_m(xSize),
52 ySize_m(ySize),
53 zSize_m(zSize),
54 maps_m(),
55 constantSpacing_m(false) {
57 if (xSize_m < 2 || ySize_m < 2 || zSize_m < 2)
58 throw(LogicalError(
59 "ThreeDGrid::ThreeDGrid(...)", "3D Grid must be at least 2x2x2 grid"));
60 }
61
62 ThreeDGrid::ThreeDGrid(std::vector<double> x, std::vector<double> y, std::vector<double> z)
63 : x_m(x),
64 y_m(y),
65 z_m(z),
66 xSize_m(x.size()),
67 ySize_m(y.size()),
68 zSize_m(z.size()),
69 maps_m(),
70 constantSpacing_m(false) {
72 if (xSize_m < 2 || ySize_m < 2 || zSize_m < 2)
73 throw(LogicalError(
74 "ThreeDGrid::ThreeDGrid(...)", "3D Grid must be at least 2x2x2 grid"));
75 }
76
78 double dX, double dY, double dZ, double minX, double minY, double minZ,
79 int numberOfXCoords, int numberOfYCoords, int numberOfZCoords)
80 : x_m(numberOfXCoords),
81 y_m(numberOfYCoords),
82 z_m(numberOfZCoords),
83 xSize_m(numberOfXCoords),
84 ySize_m(numberOfYCoords),
85 zSize_m(numberOfZCoords),
86 maps_m(),
87 constantSpacing_m(true) {
88 for (int i = 0; i < numberOfXCoords; i++)
89 x_m[i] = minX + i * dX;
90 for (int j = 0; j < numberOfYCoords; j++)
91 y_m[j] = minY + j * dY;
92 for (int k = 0; k < numberOfZCoords; k++)
93 z_m[k] = minZ + k * dZ;
94
96 }
97
99
100 // state starts at 1,1,1
102 return Mesh::Iterator(std::vector<int>(3, 1), this);
103 }
104
106 std::vector<int> end(3, 1);
107 end[0] = xSize_m + 1;
108 return Mesh::Iterator(end, this);
109 }
110
111 void ThreeDGrid::getPosition(const Mesh::Iterator& it, double* position) const {
112 position[0] = x(it.state_m[0]);
113 position[1] = y(it.state_m[1]);
114 position[2] = z(it.state_m[2]);
115 }
116
118 std::vector<double> new_x(x_m.size() - 1);
119 std::vector<double> new_y(y_m.size() - 1);
120 std::vector<double> new_z(z_m.size() - 1);
121 for (size_t i = 0; i < x_m.size() - 1; ++i) {
122 new_x[i] = (x_m[i] + x_m[i + 1]) / 2.;
123 }
124 for (size_t i = 0; i < y_m.size() - 1; ++i) {
125 new_y[i] = (y_m[i] + y_m[i + 1]) / 2.;
126 }
127 for (size_t i = 0; i < z_m.size() - 1; ++i) {
128 new_z[i] = (z_m[i] + z_m[i + 1]) / 2.;
129 }
130 return new ThreeDGrid(new_x, new_y, new_z);
131 }
132
134 if (difference < 0) return subEquals(lhs, -difference);
135
136 lhs.state_m[0] += difference / (ySize_m * zSize_m);
137 difference = difference % (ySize_m * zSize_m);
138 lhs.state_m[1] += difference / (zSize_m);
139 lhs.state_m[2] += difference % (zSize_m);
140
141 if (lhs.state_m[1] > ySize_m) {
142 lhs.state_m[0]++;
143 lhs.state_m[1] -= ySize_m;
144 }
145 if (lhs.state_m[2] > zSize_m) {
146 lhs.state_m[1]++;
147 lhs.state_m[2] -= zSize_m;
148 }
149
150 return lhs;
151 }
152
154 if (difference < 0) return addEquals(lhs, -difference);
155
156 lhs.state_m[0] -= difference / (ySize_m * zSize_m);
157 difference = difference % (ySize_m * zSize_m);
158 lhs.state_m[1] -= difference / (zSize_m);
159 lhs.state_m[2] -= difference % (zSize_m);
160
161 while (lhs.state_m[2] < 1) {
162 lhs.state_m[1]--;
163 lhs.state_m[2] += zSize_m;
164 }
165 while (lhs.state_m[1] < 1) {
166 lhs.state_m[0]--;
167 lhs.state_m[1] += ySize_m;
168 }
169
170 return lhs;
171 }
172
173 void ThreeDGrid::vectorLowerBound(std::vector<double> vec, double x, int& index) {
174 if (x < vec[0]) {
175 index = -1;
176 return;
177 }
178 if (x >= vec.back()) {
179 index = vec.size() - 1;
180 return;
181 }
182 size_t xLower = 0;
183 size_t xUpper = vec.size() - 1;
184 while (xUpper - xLower > 1) {
185 index = (xUpper + xLower) / 2;
186 if (x >= vec[index]) {
187 xLower = index;
188 } else {
189 xUpper = index;
190 }
191 }
192 index = xLower;
193 }
194
196 return addEquals(lhs, rhs.toInteger());
197 }
198
200 return subEquals(lhs, rhs.toInteger());
201 }
202
204 if (lhs.state_m[1] == ySize_m && lhs.state_m[2] == zSize_m) {
205 ++lhs.state_m[0];
206 lhs.state_m[1] = lhs.state_m[2] = 1;
207 } else if (lhs.state_m[2] == zSize_m) {
208 ++lhs.state_m[1];
209 lhs.state_m[2] = 1;
210 } else {
211 ++lhs.state_m[2];
212 }
213 return lhs;
214 }
215
217 if (lhs.state_m[1] == 1 && lhs.state_m[2] == 1) {
218 --lhs.state_m[0];
219 lhs.state_m[1] = ySize_m;
220 lhs.state_m[2] = zSize_m;
221 } else if (lhs.state_m[2] == 1) {
222 --lhs.state_m[1];
223 lhs.state_m[2] = zSize_m;
224 } else {
225 --lhs.state_m[2];
226 }
227 return lhs;
228 }
229
230 // Check relative position
231 bool ThreeDGrid::isGreater(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] && lhs.state_m[1] > rhs.state_m[1])
235 return true;
236 else if (
237 lhs.state_m[0] == rhs.state_m[0] && lhs.state_m[1] == rhs.state_m[1]
238 && lhs.state_m[2] > rhs.state_m[2])
239 return true;
240 return false;
241 }
242
243 // remove *map if it exists; delete this if there are no more VectorMaps
245 std::vector<VectorMap*>::iterator it = std::find(maps_m.begin(), maps_m.end(), map);
246 if (it < maps_m.end()) {
247 maps_m.erase(it);
248 }
249 if (maps_m.begin() == maps_m.end()) {
250 delete this;
251 }
252 }
253
254 // add *map if it has not already been added
256 std::vector<VectorMap*>::iterator it = std::find(maps_m.begin(), maps_m.end(), map);
257 if (it == maps_m.end()) {
258 maps_m.push_back(map);
259 }
260 }
261
263 constantSpacing_m = true;
264 for (unsigned int i = 0; i < x_m.size() - 1; i++)
265 if (std::abs(1 - (x_m[i + 1] - x_m[i]) / (x_m[1] - x_m[0])) > 1e-9) {
266 constantSpacing_m = false;
267 return;
268 }
269 for (unsigned int i = 0; i < y_m.size() - 1; i++)
270 if (std::abs(1 - (y_m[i + 1] - y_m[i]) / (y_m[1] - y_m[0])) > 1e-9) {
271 constantSpacing_m = false;
272 return;
273 }
274 for (unsigned int i = 0; i < z_m.size() - 1; i++)
275 if (std::abs(1 - (z_m[i + 1] - z_m[i]) / (z_m[1] - z_m[0])) > 1e-9) {
276 constantSpacing_m = false;
277 return;
278 }
279 }
280
281 Mesh::Iterator ThreeDGrid::getNearest(const double* position) const {
282 std::vector<int> index(3);
283 lowerBound(position[0], index[0], position[1], index[1], position[2], index[2]);
284 if (index[0] < xSize_m - 1 && index[0] >= 0)
285 index[0] +=
286 (2 * (position[0] - x_m[index[0]]) > x_m[index[0] + 1] - x_m[index[0]] ? 2 : 1);
287 else
288 index[0]++;
289 if (index[1] < ySize_m - 1 && index[1] >= 0)
290 index[1] +=
291 (2 * (position[1] - y_m[index[1]]) > y_m[index[1] + 1] - y_m[index[1]] ? 2 : 1);
292 else
293 index[1]++;
294 if (index[2] < zSize_m - 1 && index[2] >= 0)
295 index[2] +=
296 (2 * (position[2] - z_m[index[2]]) > z_m[index[2] + 1] - z_m[index[2]] ? 2 : 1);
297 else
298 index[2]++;
299 if (index[0] < 1) index[0] = 1;
300 if (index[1] < 1) index[1] = 1;
301 if (index[2] < 1) index[2] = 1;
302 if (index[0] > xSize_m) index[0] = xSize_m;
303 if (index[1] > ySize_m) index[1] = ySize_m;
304 if (index[2] > zSize_m) index[2] = zSize_m;
305 return Mesh::Iterator(index, this);
306 }
307} // namespace interpolation
Logical error exception.
std::vector< int > state_m
Definition Mesh.h:235
Base class for meshing routines.
Definition Mesh.h:49
Mesh::Iterator begin() const
std::vector< double > y_m
Definition ThreeDGrid.h:315
virtual void getPosition(const Mesh::Iterator &it, double *position) const
static void vectorLowerBound(std::vector< double > vec, double x, int &index)
Mesh::Iterator end() const
std::vector< double > x_m
Definition ThreeDGrid.h:314
virtual Mesh::Iterator & subEquals(Mesh::Iterator &lhs, int difference) const
void remove(VectorMap *map)
std::vector< double > z_m
Definition ThreeDGrid.h:316
virtual Mesh::Iterator & subOne(Mesh::Iterator &lhs) const
double & x(const int &i)
Definition ThreeDGrid.h:119
double & z(const int &k)
Definition ThreeDGrid.h:131
virtual bool isGreater(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs) const
double & y(const int &j)
Definition ThreeDGrid.h:125
void add(VectorMap *map)
virtual Mesh::Iterator & addOne(Mesh::Iterator &lhs) const
virtual Mesh::Iterator & addEquals(Mesh::Iterator &lhs, int difference) const
void lowerBound(const double &x, int &xIndex, const double &y, int &yIndex, const double &z, int &zIndex) const
Definition ThreeDGrid.h:361
std::vector< VectorMap * > maps_m
Definition ThreeDGrid.h:320
Mesh::Iterator getNearest(const double *position) const