OPALX (Object Oriented Parallel Accelerator Library for Exascale) MINIorX
OPALX
NDGrid.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017, 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
28#include <cmath>
29#include <iomanip>
33
34namespace interpolation {
36NDGrid::NDGrid() : coord_m(), maps_m(), constantSpacing_m(false) {
37}
38
39NDGrid::NDGrid(const NDGrid& rhs) : coord_m(rhs.coord_m), maps_m(rhs.maps_m),
40 constantSpacing_m(rhs.constantSpacing_m) {
41}
42
43NDGrid::NDGrid(std::vector<int> size, std::vector<const double *> gridCoordinates)
44 : coord_m(), maps_m(), constantSpacing_m(false) {
45 for (unsigned int i=0; i<size.size(); i++) {
46 if (size[i] < 1) {
47 throw(OpalException("NDGrid::NDGrid(...)",
48 "ND Grid must be at least 1x1x...x1 grid"));
49 }
50 coord_m.push_back(std::vector<double>(gridCoordinates[i],
51 gridCoordinates[i] + size[i]));
52 }
54}
55
56NDGrid::NDGrid(int nDimensions, int* size, double* spacing, double* min)
57 : coord_m(nDimensions), maps_m(), constantSpacing_m(true) {
58 for (int i=0; i<nDimensions; i++) {
59 if (size[i] < 1) {
60 throw(OpalException("NDGrid::NDGrid(...)",
61 "ND Grid must be at least 1x1x...x1 grid"));
62 }
63 coord_m[i] = std::vector<double>(size[i]);
64 for (unsigned int j=0; j<coord_m[i].size(); j++) {
65 coord_m[i][j] = min[i] + j*spacing[i];
66 }
67 }
68}
69
70NDGrid::NDGrid(std::vector< std::vector<double> > gridCoordinates)
71 : coord_m(gridCoordinates), maps_m(), constantSpacing_m(false) {
72 for (unsigned int i=0; i<gridCoordinates.size(); i++) {
73 if (gridCoordinates[i].size() < 1) {
74 throw (OpalException("NDGrid::NDGrid(...)",
75 "ND Grid must be at least 1x1x...x1 grid"));
76 }
77 }
79}
80
81
82double* NDGrid::newCoordArray ( const int& dimension) const {
83 double * array = new double[coord_m[dimension].size() ];
84 for (unsigned int i=0; i<coord_m[dimension].size(); i++) {
85 array[i] = coord_m[dimension][i];
86 }
87 return array;
88}
89
90//Mesh::Iterator wraps around a std::vector<int>
91//it[0] is least significant, it[max] is most signifcant
92Mesh::Iterator& NDGrid::addEquals(Mesh::Iterator& lhs, int difference) const {
93 if (difference < 0) {
94 return subEquals(lhs, -difference);
95 }
96 std::vector<int> index(coord_m.size(),0);
97 std::vector<int> content(coord_m.size(),1);
98 for (int i = int(index.size()-2); i >= 0; i--) {
99 content[i] = content[i+1]*coord_m[i+1].size(); //content could be member variable
100 }
101 for (int i = 0; i < int(index.size()); i++) {
102 index[i] = difference/content[i];
103 difference -= index[i] * content[i];
104 }
105 for (unsigned int i=0; i<index.size(); i++) {
106 lhs.state_m[i] += index[i];
107 }
108 for (int i = int(index.size())-1; i > 0; i--) {
109 if (lhs.state_m[i] > int(coord_m[i].size())) {
110 lhs.state_m[i-1]++;
111 lhs.state_m[i] -= coord_m[i].size();
112 }
113 }
114
115 return lhs;
116}
117
118Mesh::Iterator& NDGrid::subEquals(Mesh::Iterator& lhs, int difference) const {
119 if (difference < 0) {
120 return addEquals(lhs, -difference);
121 }
122 std::vector<int> index(coord_m.size(),0);
123 std::vector<int> content(coord_m.size(),1);
124 for (int i = int(index.size()-2); i >= 0; i--) {
125 content[i] = content[i+1]*coord_m[i+1].size(); //content could be member variable
126 }
127 for (int i = 0; i < int(index.size()); i++) {
128 index[i] = difference/content[i];
129 difference -= index[i] * content[i];
130 }
131 for (unsigned int i = 0; i < index.size(); i++) {
132 lhs.state_m[i] -= index[i];
133 }
134 for (int i=int(index.size())-1; i>0; i--) {
135 if (lhs.state_m[i] < 1) {
136 lhs.state_m[i-1]--;
137 lhs.state_m[i] += coord_m[i].size();
138 }
139 }
140 return lhs;
141}
142
144 return addEquals(lhs, rhs.toInteger());
145}
146
148 return subEquals(lhs, rhs.toInteger());
149}
150
152 int i = coord_m.size()-1;
153 while (lhs[i] == int(coord_m[i].size()) && i>0) {
154 lhs[i]=1; i--;
155 }
156 lhs[i]++;
157 return lhs;
158}
159
161 lhs[coord_m.size()-1] -= 1;
162
163 int i = coord_m.size()-1;
164 while (lhs[i] == 0 && i>0) {
165 lhs.state_m[i] = coord_m[i].size();
166 i--;
167 lhs.state_m[i]--;
168 }
169 return lhs;
170}
171
172void NDGrid::setConstantSpacing(double tolerance_m) {
173 constantSpacing_m = true;
174 for (unsigned int i = 0; i < coord_m.size(); i++) {
175 for (unsigned int j = 0; j < coord_m[i].size()-1; j++) {
176 double coord_j1 = coord_m[i][j+1];
177 double coord_j0 = coord_m[i][j];
178 double coord_1 = coord_m[i][1];
179 double coord_0 = coord_m[i][0];
180 if (std::abs(1-(coord_j1-coord_j0)/(coord_1-coord_0)) > tolerance_m) {
181 constantSpacing_m = false;
182 return;
183 }
184 }
185 }
186}
187
188bool NDGrid::isGreater(const Mesh::Iterator& lhs, const Mesh::Iterator& rhs) const {
189 unsigned int i = 0;
190 // if all equal; rhs[i] = rhs.last
191 while (i < rhs.state_m.size()-1 && lhs.state_m[i] == rhs.state_m[i]) {
192 i++;
193 }
194 return (lhs[i] > rhs[i]);
195}
196
197int NDGrid::toInteger(const Mesh::Iterator& lhs) const {
198 int difference = 0;
199 std::vector<int> index (coord_m.size(),0);
200 std::vector<int> content(coord_m.size(),1);
201 for (int i = int(index.size()-2); i >= 0; i--) {
202 content[i] = content[i+1]*coord_m[i+1].size();
203 }
204 for (int i = 0; i < int(index.size()); i++) {
205 difference += (lhs.state_m[i]-1) * (content[i]);
206 }
207 return difference;
208}
209
210Mesh::Iterator NDGrid::getNearest(const double* position) const {
211 std::vector<int> index(coord_m.size());
212 std::vector<double> pos(position, position+coord_m.size());
213 lowerBound(pos, index);
214 for (unsigned int i = 0; i < coord_m.size(); i++)
215 {
216 if (index[i] < int(coord_m[i].size()-1) && index[i] >= 0) {
217 index[i] += (2*(position[i] - coord_m[i][index[i]]) > coord_m[i][index[i]+1]-coord_m[i][index[i]] ? 2 : 1);
218 } else {
219 index[i]++;
220 }
221 if (index[i] < 1) {
222 index[i] = 1;
223 }
224 if (index[i] > int(coord_m[i].size())) {
225 index[i] = coord_m[i].size();
226 }
227 }
228 return Mesh::Iterator(index, this);
229}
230
231
233 std::vector<std::vector<double> > coord(coord_m.size());
234 for (size_t i = 0; i < coord.size(); ++i) {
235 if (coord_m[i].size() <= 1) {
236 throw(OpalException("NDGrid::dual(...)",
237 "ND Grid must be at least 2x2x...x2 grid"));
238 }
239 coord[i] = std::vector<double>(coord_m[i].size()-1);
240 for (size_t j = 0; j < coord[i].size(); ++j) {
241 coord[i][j] = (coord_m[i][j] + coord_m[i][j+1])/2.;
242 }
243 }
244 return new NDGrid(coord);
245}
246
247
249}
KOKKOS_INLINE_FUNCTION Vector< T, Dim > min(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
Definition: Vector.hpp:217
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.
NDGrid holds grid information for a rectilinear grid in some arbitrary dimensional space.
Definition: NDGrid.h:57
virtual Mesh::Iterator & addEquals(Mesh::Iterator &lhs, int difference) const
Add difference to lhs and then return lhs.
Definition: NDGrid.cpp:92
virtual Mesh::Iterator & addOne(Mesh::Iterator &lhs) const
Increment position of lhs by one and then return lhs.
Definition: NDGrid.cpp:151
virtual Mesh::Iterator & subOne(Mesh::Iterator &lhs) const
Decrement position of lhs by one and then return lhs.
Definition: NDGrid.cpp:160
int toInteger(const Mesh::Iterator &lhs) const
Return an integer corresponding to the iterator position.
Definition: NDGrid.cpp:197
std::vector< std::vector< double > > coord_m
Definition: NDGrid.h:281
Mesh::Iterator getNearest(const double *position) const
Return an iterator corresponding to nearest mesh point to position.
Definition: NDGrid.cpp:210
double min(const int &dimension) const
Return the lowest grid coordinate in the given dimension.
Definition: NDGrid.h:342
double * newCoordArray(const int &dimension) const
Get an array of grid points along a particular dimension.
Definition: NDGrid.cpp:82
NDGrid()
Build a default, empty grid with zero dimension.
Definition: NDGrid.cpp:36
void lowerBound(const std::vector< double > &pos, std::vector< int > &xIndex) const
Get the grid point of the grid lower bound.
Definition: NDGrid.h:335
void setConstantSpacing(bool spacing)
Set to true to flag the Mesh as a regular grid.
Definition: NDGrid.h:384
virtual Mesh::Iterator & subEquals(Mesh::Iterator &lhs, int difference) const
Subtract difference from lhs and then return lhs.
Definition: NDGrid.cpp:118
Mesh * dual() const
Not implemented.
Definition: NDGrid.cpp:232
int size(const int &dimension) const
Get the size of the grid along a given dimension.
Definition: NDGrid.h:310
double & coord(const int &index, const int &dimension)
Get the coordinate of a set of grid points.
Definition: NDGrid.h:302
virtual bool isGreater(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs) const
Return true if rhs is greater than lhs.
Definition: NDGrid.cpp:188
The base class for all OPAL exceptions.
Definition: OpalException.h:28