OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
TwoDGrid.cpp
Go to the documentation of this file.
1 // MAUS WARNING: THIS IS LEGACY CODE.
2 #include "Interface/Mesh.hh"
3 #include "Utils/Exception.hh"
4 #include <iomanip>
5 #include <math.h>
6 
8 TwoDGrid::TwoDGrid() : _x(2,0), _y(2,0), _xSize(2), _ySize(2), _maps(), _constantSpacing(false)
9 {
10  _x[1] = 1.; _y[1] = 1.;
11 }
12 
13 TwoDGrid::TwoDGrid(double dX, double dY, double minX, double minY, int numberOfXCoords, int numberOfYCoords)
14  : _x(), _y(), _xSize(numberOfXCoords), _ySize(numberOfYCoords), _maps(), _constantSpacing(true)
15 {
16  if(numberOfXCoords < 2 || numberOfYCoords < 2) throw(MAUS::Exception(MAUS::Exception::recoverable, "2D Grid must be at least 2x2 grid", "TwoDGrid::TwoDGrid(...)"));
17  for(int i=0; i<numberOfXCoords; i++) _x.push_back(minX+i*dX);
18  for(int j=0; j<numberOfYCoords; j++) _y.push_back(minY+j*dY);
20 }
21 
22 TwoDGrid::TwoDGrid(int xSize, const double *x, int ySize, const double *y) : _x(x, x+xSize), _y(y, y+ySize), _xSize(xSize), _ySize(ySize), _maps(), _constantSpacing(false)
23 {
24  if(xSize < 2 || ySize < 2) throw(MAUS::Exception(MAUS::Exception::recoverable, "2D Grid must be at least 2x2 grid", "TwoDGrid::TwoDGrid(...)"));
26  delete [] x;
27  delete [] y;
28 }
29 
30 TwoDGrid::TwoDGrid(std::vector<double> x, std::vector<double> y) : _x (x), _y(y), _xSize(x.size()), _ySize(y.size()), _maps(), _constantSpacing(false)
31 {
32  if(_xSize < 2 || _ySize < 2) throw(MAUS::Exception(MAUS::Exception::recoverable, "2D Grid must be at least 2x2 grid", "TwoDGrid::TwoDGrid(...)"));
34 }
35 
37 {
38 }
39 
40 Mesh::Iterator TwoDGrid::Begin() const
41 {
42  return Mesh::Iterator(std::vector<int>(2,1), this);
43 }
44 
45 Mesh::Iterator TwoDGrid::End() const
46 {
47  std::vector<int> end(2, 1); end[0] = _xSize+1; return Mesh::Iterator(end, this);
48 }
49 
50 void TwoDGrid::Position(const Mesh::Iterator& it, double * position) const
51 {
52  position[0] = x(it._state[0]);
53  position[1] = y(it._state[1]);
54 }
55 
56 void TwoDGrid::CentrePosition(const Mesh::Iterator& it, double * position) const
57 {
58  if( it._state[0]>=xSize() ) position[0] = MaxX() + ( x(xSize() ) - x(xSize()-1) )*(it._state[0]-xSize()+0.5) ;
59  else if( it._state[0]<0 ) position[0] = MinX() + (x(2)-x(1))*(it._state[0]-0.5);
60  else position[0] = 0.5*(x(it._state[0]+1)+x(it._state[0]));
61 
62  if( it._state[1]>=ySize() ) position[1] = MaxY() + ( y(ySize() ) - y(ySize()-1) )*(it._state[1]-ySize()+0.5) ;
63  else if( it._state[1]<0 ) position[1] = MinY() + (y(2)-y(1))*(it._state[1]-0.5);
64  else position[1] = 0.5*(y(it._state[1]+1)+y(it._state[1]));
65 }
66 
67 Mesh::Iterator& TwoDGrid::AddEquals(Mesh::Iterator& lhs, int difference) const
68 {
69  if(difference < 0) return SubEquals(lhs, -difference);
70  lhs._state[0] += difference/(_ySize);
71  lhs._state[1] += difference%(_ySize);
72  if(lhs._state[1] > _ySize) {lhs._state[1] -= _ySize; lhs._state[0]++;}
73  return lhs;
74 }
75 
76 Mesh::Iterator& TwoDGrid::SubEquals(Mesh::Iterator& lhs, int difference) const
77 {
78  if(difference < 0) return AddEquals(lhs, -difference);
79  lhs._state[0] -= difference/(_ySize);
80  lhs._state[1] -= difference%(_ySize);
81  if(lhs._state[1] < 1) {lhs._state[1] += _ySize; lhs._state[0]--;}
82  return lhs;
83 }
84 
85 Mesh::Iterator& TwoDGrid::AddEquals(Mesh::Iterator& lhs, const Mesh::Iterator& rhs) const
86 {
87  return AddEquals(lhs, rhs.ToInteger());
88 }
89 
90 Mesh::Iterator& TwoDGrid::SubEquals(Mesh::Iterator& lhs, const Mesh::Iterator& rhs) const
91 {
92  return SubEquals(lhs, rhs.ToInteger());
93 }
94 
95 Mesh::Iterator& TwoDGrid::AddOne (Mesh::Iterator& lhs) const
96 {
97  if(lhs._state[1] == this->ySize()) {lhs._state[1] = 1; ++lhs._state[0];}
98  else ++lhs._state[1];
99  return lhs;
100 }
101 
102 Mesh::Iterator& TwoDGrid::SubOne (Mesh::Iterator& lhs) const
103 {
104  if(lhs._state[1] == 1) {lhs._state[1] = this->ySize(); --lhs._state[0];}
105  else --lhs._state[1];
106  return lhs;
107 }
108 //Check relative position
109 bool TwoDGrid::IsGreater(const Mesh::Iterator& lhs, const Mesh::Iterator& rhs) const
110 {
111  if(lhs._state[0] > rhs._state[0]) return true;
112  else if (lhs._state[0] == rhs._state[0] && lhs._state[1] > rhs._state[1]) return true;
113  return false;
114 }
115 
116 void TwoDGrid::Remove(VectorMap* map) //remove *map if it exists; delete this if there are no more VectorMaps
117 {
118  std::vector<VectorMap*>::iterator it = std::find(_maps.begin(), _maps.end(), map);
119  if(it<_maps.end()) { _maps.erase(it); }
120  if(_maps.begin() == _maps.end()) { delete this; }
121 }
122 
123 void TwoDGrid::Add(VectorMap* map) //add *map if it has not already been added
124 {
125  std::vector<VectorMap*>::iterator it = std::find(_maps.begin(), _maps.end(), map);
126  if(it==_maps.end()) { _maps.push_back(map); }
127 }
128 
130 {
131  _constantSpacing = true;
132  for (unsigned int i = 0; i < _x.size()-1; i++)
133  if (fabs(1-(_x[i+1]-_x[i])/(_x[1]-_x[0])) > 1e-9)
134  _constantSpacing = false;
135  for (unsigned int i = 0; i < _y.size()-1; i++)
136  if (fabs(1-(_y[i+1]-_y[i])/(_y[1]-_y[0])) > 1e-9)
137  _constantSpacing = false;
138 }
139 
140 Mesh::Iterator TwoDGrid::Nearest(const double* position) const
141 {
142  std::vector<int> index(2);
143  LowerBound(position[0], index[0], position[1], index[1]);
144  if(index[0] < _xSize-1 && index[0] >= 0)
145  index[0] += (2*(position[0] - _x[index[0]]) > _x[index[0]+1]-_x[index[0]] ? 2 : 1);
146  else
147  index[0] += 1;
148  if(index[1] < _ySize-1 && index[1] >= 0)
149  index[1] += (2*(position[1] - _y[index[1]]) > _y[index[1]+1]-_y[index[1]] ? 2 : 1);
150  else
151  index[1] += 1;
152  if(index[0] < 1) index[0] = 1;
153  if(index[1] < 1) index[1] = 1;
154  if(index[0] > _xSize) index[0] = _xSize;
155  if(index[1] > _ySize) index[1] = _ySize;
156  return Mesh::Iterator(index, this);
157 }
158 
159 
161 
162 
164 NDGrid::NDGrid() : _coord(), _maps(), _constantSpacing(false)
165 {
166  for(unsigned int i=0; i<2; i++) {_coord.push_back(std::vector<double>(2,0)); _coord.back()[1] = 1.;}
167 }
168 
169 
170 
171 NDGrid::NDGrid(std::vector<int> size, std::vector<const double *> gridCoordinates) : _coord(), _maps(), _constantSpacing(false)
172 {
173  for(unsigned int i=0; i<size.size(); i++)
174  {
175  if(size[i] < 2)
176  throw(MAUS::Exception(MAUS::Exception::recoverable, "ND Grid must be at least 2x2x...x2 grid", "NDGrid::NDGrid(...)"));
177  _coord.push_back(std::vector<double>(gridCoordinates[i], gridCoordinates[i] + size[i]) );
178  }
180 }
181 
182 NDGrid::NDGrid(int nDimensions, int* size, double* spacing, double* min) : _coord(nDimensions), _maps(), _constantSpacing(true)
183 {
184  for(int i=0; i<nDimensions; i++)
185  {
186  if(size[i] < 2) throw(MAUS::Exception(MAUS::Exception::recoverable, "ND Grid must be at least 2x2x...x2 grid", "NDGrid::NDGrid(...)"));
187  _coord[i] = std::vector<double>(size[i]);
188  for(unsigned int j=0; j<_coord[i].size(); j++) _coord[i][j] = min[i] + j*spacing[i];
189  }
190 }
191 
192 NDGrid::NDGrid(std::vector< std::vector<double> > gridCoordinates) : _coord(gridCoordinates), _maps(), _constantSpacing(false)
193 {
194  for(unsigned int i=0; i<gridCoordinates.size(); i++)
195  if(gridCoordinates[i].size() < 2) throw(MAUS::Exception(MAUS::Exception::recoverable, "ND Grid must be at least 2x2x...x2 grid", "NDGrid::NDGrid(...)"));
197 }
198 
199 
200 double* NDGrid::newCoordArray ( const int& dimension) const
201 {
202  double * array = new double[_coord[dimension].size() ];
203  for(unsigned int i=0; i<_coord[dimension].size(); i++) array[i] = _coord[dimension][i];
204  return array;
205 }
206 
207 //Mesh::Iterator wraps around a std::vector<int>
208 //it[0] is least significant, it[max] is most signifcant
209 Mesh::Iterator& NDGrid::AddEquals(Mesh::Iterator& lhs, int difference) const
210 {
211  if(difference < 0) return SubEquals(lhs, -difference);
212  std::vector<int> index (_coord.size(),0);
213  std::vector<int> content(_coord.size(),1);
214  for(int i=int(index.size()-2); i>=0; i--) content[i] = content[i+1]*_coord[i+1].size(); //content could be member variable
215  for(int i=0; i<int(index.size()); i++)
216  {
217  index[i] = difference/content[i];
218  difference -= index[i] * content[i];
219  }
220  for(unsigned int i=0; i<index.size(); i++) lhs._state[i] += index[i];
221  for(int i=int(index.size())-1; i>0; i--)
222  {
223  if(lhs._state[i] > int(_coord[i].size()) )
224  {
225  lhs._state[i-1]++;
226  lhs._state[i] -= _coord[i].size();
227  }
228  }
229 
230  return lhs;
231 }
232 
233 Mesh::Iterator& NDGrid::SubEquals(Mesh::Iterator& lhs, int difference) const
234 {
235  if(difference < 0) return AddEquals(lhs, -difference);
236  std::vector<int> index (_coord.size(),0);
237  std::vector<int> content(_coord.size(),1);
238  for(int i=int(index.size()-2); i>=0; i--) content[i] = content[i+1]*_coord[i+1].size(); //content could be member variable
239  for(int i=0; i<int(index.size()); i++)
240  {
241  index[i] = difference/content[i];
242  difference -= index[i] * content[i];
243  }
244  for(unsigned int i=0; i<index.size(); i++) lhs._state[i] -= index[i];
245  for(int i=int(index.size())-1; i>0; i--)
246  {
247  if(lhs._state[i] < 1)
248  {
249  lhs._state[i-1]--;
250  lhs._state[i] += _coord[i].size();
251  }
252  }
253  return lhs;
254 }
255 
256 Mesh::Iterator& NDGrid::AddEquals(Mesh::Iterator& lhs, const Mesh::Iterator& rhs) const
257 {
258  return AddEquals(lhs, rhs.ToInteger());
259 }
260 
261 Mesh::Iterator& NDGrid::SubEquals(Mesh::Iterator& lhs, const Mesh::Iterator& rhs) const
262 {
263  return SubEquals(lhs, rhs.ToInteger());
264 }
265 
266 Mesh::Iterator& NDGrid::AddOne (Mesh::Iterator& lhs) const
267 {
268  int i=_coord.size()-1;
269  while(lhs[i] == int(_coord[i].size()) && i>0) {lhs[i]=1; i--;}
270  lhs[i]++;
271  return lhs;
272 }
273 
274 Mesh::Iterator& NDGrid::SubOne (Mesh::Iterator& lhs) const
275 {
276  lhs[_coord.size()-1] -= 1;
277 
278  int i = _coord.size()-1;
279  while(lhs[i] == 0 && i>0)
280  {
281  lhs._state[i] = _coord[i].size();
282  i--;
283  lhs._state[i]--;
284  }
285  return lhs;
286 }
287 
289 {
290  _constantSpacing = true;
291  for(unsigned int i=0; i<_coord.size(); i++)
292  for(unsigned int j=0; j<_coord[i].size()-1; j++)
293  if( fabs(1-(_coord[i][j+1]-_coord[i][j])/(_coord[i][1]-_coord[i][0])) > 1e-9 )
294  {_constantSpacing = false; return;}
295 }
296 
297 bool NDGrid::IsGreater(const Mesh::Iterator& lhs, const Mesh::Iterator& rhs) const
298 {
299  unsigned int i = 0;
300  while(lhs._state[i] == rhs._state[i] && i<rhs._state.size()-1) i++; //if all equal; rhs[i] = rhs.last
301  return (lhs[i] > rhs[i]);
302 }
303 
304 int NDGrid::ToInteger(const Mesh::Iterator& lhs) const
305 {
306  int difference = 0;
307  std::vector<int> index (_coord.size(),0);
308  std::vector<int> content(_coord.size(),1);
309  for(int i=int(index.size()-2); i>=0; i--) content[i] = content[i+1]*_coord[i+1].size(); //content could be member variable
310  for(int i=0; i<int(index.size()); i++) difference += (lhs._state[i]-1) * (content[i]);
311 
312  return difference;
313 }
314 
315 Mesh::Iterator NDGrid::Nearest(const double* position) const
316 {
317  std::vector<int> index(_coord.size());
318  std::vector<double> pos (position, position+_coord.size());
319  LowerBound (pos, index);
320  for(unsigned int i=0; i<_coord.size(); i++)
321  {
322  if(index[i] < int(_coord[i].size()-1) && index[i] >= 0) index[i] += (2*(position[i] - _coord[i][index[i]]) > _coord[i][index[i]+1]-_coord[i][index[i]] ? 2 : 1);
323  else index[i]++;
324  if(index[i] < 1) index[i] = 1;
325  if(index[i] > int(_coord[i].size())) index[i] = _coord[i].size();
326  }
327  return Mesh::Iterator(index, this);
328 }
329 
virtual Mesh::Iterator & SubOne(Mesh::Iterator &lhs) const
Definition: TwoDGrid.cpp:274
std::vector< VectorMap * > _maps
Definition: TwoDGrid.h:94
void SetConstantSpacing()
Definition: TwoDGrid.cpp:288
double & y(const int &j)
Definition: TwoDGrid.h:30
constexpr double e
The value of .
Definition: Physics.h:40
void LowerBound(const std::vector< double > &pos, std::vector< int > &xIndex) const
Definition: TwoDGrid.h:150
bool IsGreater(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs) const
Definition: TwoDGrid.cpp:109
double & x(const int &i)
Definition: TwoDGrid.h:29
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
Definition: PETE.h:815
bool _constantSpacing
Definition: TwoDGrid.h:95
double MinY() const
Definition: TwoDGrid.h:53
int _xSize
Definition: TwoDGrid.h:92
void Add(VectorMap *map)
Definition: TwoDGrid.cpp:123
virtual bool IsGreater(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs) const
Definition: TwoDGrid.cpp:297
virtual void Position(const Mesh::Iterator &it, double *position) const
Definition: TwoDGrid.cpp:50
std::vector< double > _x
Definition: TwoDGrid.h:90
std::vector< std::vector< double > > _coord
Definition: TwoDGrid.h:182
double MaxX() const
Definition: TwoDGrid.h:52
Mesh::Iterator & SubEquals(Mesh::Iterator &lhs, int difference) const
Definition: TwoDGrid.cpp:76
virtual void CentrePosition(const Mesh::Iterator &it, double *position) const
Definition: TwoDGrid.cpp:56
double MaxY() const
Definition: TwoDGrid.h:54
Mesh::Iterator End() const
Definition: TwoDGrid.cpp:45
virtual Mesh::Iterator & AddEquals(Mesh::Iterator &lhs, int difference) const
Definition: TwoDGrid.cpp:209
virtual Mesh::Iterator & AddOne(Mesh::Iterator &lhs) const
Definition: TwoDGrid.cpp:266
void LowerBound(const double &x, int &xIndex, const double &y, int &yIndex) const
Definition: TwoDGrid.h:48
virtual Mesh::Iterator & SubEquals(Mesh::Iterator &lhs, int difference) const
Definition: TwoDGrid.cpp:233
NDGrid()
////// NDGrid ///////
Definition: TwoDGrid.cpp:164
Mesh::Iterator Nearest(const double *position) const
Definition: TwoDGrid.cpp:315
double MinX() const
Definition: TwoDGrid.h:51
Mesh::Iterator & SubOne(Mesh::Iterator &lhs) const
Definition: TwoDGrid.cpp:102
Mesh::Iterator Nearest(const double *position) const
Definition: TwoDGrid.cpp:140
std::vector< double > _y
Definition: TwoDGrid.h:91
int _ySize
Definition: TwoDGrid.h:93
Mesh::Iterator & AddOne(Mesh::Iterator &lhs) const
Definition: TwoDGrid.cpp:95
const T * find(const T table[], const std::string &name)
Look up name.
Definition: TFind.h:34
int size(const int &dimension) const
Definition: TwoDGrid.h:138
void SetConstantSpacing()
Definition: TwoDGrid.cpp:129
void Remove(VectorMap *map)
Definition: TwoDGrid.cpp:116
int ToInteger(const Mesh::Iterator &lhs) const
Definition: TwoDGrid.cpp:304
Mesh::Iterator Begin() const
Definition: TwoDGrid.cpp:40
TwoDGrid()
Definition: TwoDGrid.cpp:8
~TwoDGrid()
Definition: TwoDGrid.cpp:36
std::string::iterator iterator
Definition: MSLang.h:16
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95
int ySize() const
Definition: TwoDGrid.h:34
bool _constantSpacing
Definition: TwoDGrid.h:184
Mesh::Iterator & AddEquals(Mesh::Iterator &lhs, int difference) const
Definition: TwoDGrid.cpp:67
double * newCoordArray(const int &dimension) const
Definition: TwoDGrid.cpp:200
int xSize() const
Definition: TwoDGrid.h:33