SpatialOps
GhostData.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2017 The University of Utah
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20  * IN THE SOFTWARE.
21  */
22 
23 #ifndef SpatialOps_GhostData_h
24 #define SpatialOps_GhostData_h
25 
33 #include <spatialops/SpatialOpsConfigure.h>
36 
38 
39 #include <string>
40 #include <sstream>
41 #include <stdexcept>
42 
43 #define GHOST_MAX 9001
44 
45 namespace SpatialOps{
46 
54  class GhostData
55  {
56  // note that this is a header-only class to inline its methods to improve performance.
57 
58  IntVec minus_, plus_;
59  bool isInf_;
60 
61  // If any value is infinite (>= GHOST_MAX), then return true
62  // Infinite ghost data is used within Nebo to account for scalars
63  inline bool is_IntVec_infinite(const IntVec & values) {
64  return (values[0] >= GHOST_MAX &&
65  values[1] >= GHOST_MAX &&
66  values[2] >= GHOST_MAX);
67  }
68 
69  // If any value is infinite (>= GHOST_MAX), then return true
70  // Infinite ghost data is used within Nebo to account for scalars
71  inline bool is_ghost_infinite(const IntVec & minus, const IntVec & plus) {
72  return (is_IntVec_infinite(minus) &&
73  is_IntVec_infinite(plus));
74  }
75 
76  public:
77 
87  GhostData( const int nx, const int px,
88  const int ny, const int py,
89  const int nz, const int pz )
90  : minus_( nx, ny, nz ),
91  plus_ ( px, py, pz ),
92  isInf_(is_ghost_infinite(minus_,plus_))
93  {}
94 
95 
101  GhostData( const IntVec& minus,
102  const IntVec& plus )
103  : minus_( minus ),
104  plus_ ( plus ),
105  isInf_(is_ghost_infinite(minus_,plus_))
106  {}
107 
112  GhostData( const int n=0 )
113  : minus_( n, n, n ),
114  plus_ ( n, n, n ),
115  isInf_(is_ghost_infinite(minus_,plus_))
116  {}
117 
118  GhostData( const GhostData& rhs )
119  : minus_( rhs.minus_ ),
120  plus_ ( rhs.plus_ ),
121  isInf_( rhs.isInf_ )
122  {}
123 
124  inline GhostData& operator=( const GhostData& rhs )
125  {
126  minus_ = rhs.minus_;
127  plus_ = rhs.plus_;
128  isInf_ = rhs.isInf_;
129  return *this;
130  }
131 
135  inline IntVec get_minus() const{ return minus_; }
136 
140  inline int get_minus( const int i ) const{ return minus_[i]; }
141 
145  inline IntVec get_plus() const{ return plus_; }
146 
150  inline int get_plus( const int i ) const{ return plus_[i]; }
151 
155  inline void set_minus( const IntVec& minus){
156  minus_ = minus;
157  isInf_ = is_ghost_infinite(minus_,plus_);
158  }
159 
160 
164  inline void set_plus( const IntVec& plus ){
165  plus_ = plus;
166  isInf_ = is_ghost_infinite(minus_,plus_);
167  }
168 
169  inline GhostData operator+ ( const GhostData& rhs ) const{
170  GhostData g(*this);
171  g += rhs;
172  return g;
173  }
174 
175  inline GhostData& operator+=( const GhostData& rhs ){
176  if(!isInf_) {
177  if(rhs.isInf_) {
178  *this = rhs;
179  }
180  else {
181  minus_ += rhs.minus_;
182  plus_ += rhs.plus_;
183  }
184  }
185  return *this;
186  }
187 
188  inline GhostData operator- ( const GhostData& rhs ) const{
189  GhostData g(*this);
190  g -= rhs;
191  return g;
192  }
193 
194  inline GhostData& operator-=( const GhostData& rhs ){
195  if(rhs.isInf_) {
196  throw(std::runtime_error("Cannot use infinite ghost data on the right-hand side of subtraction."));
197  }
198  minus_ -= rhs.minus_;
199  plus_ -= rhs.plus_;
200  return *this;
201  }
202 
203  inline bool operator==( const GhostData& rhs ) const{
204  return (minus_ == rhs.minus_) && (plus_ == rhs.plus_);
205  }
206 
207  inline GhostData limit_by_extent( IntVec const & extent) const {
208  return GhostData((extent[0] <= 1 ? 0 : minus_[0]),
209  (extent[0] <= 1 ? 0 : plus_[0]),
210  (extent[1] <= 1 ? 0 : minus_[1]),
211  (extent[1] <= 1 ? 0 : plus_[1]),
212  (extent[2] <= 1 ? 0 : minus_[2]),
213  (extent[2] <= 1 ? 0 : plus_[2]));
214  }
215  };
216 
217  inline GhostData min( const GhostData& first, const GhostData& second )
218  {
219  return GhostData( min( first.get_minus(), second.get_minus() ),
220  min( first.get_plus(), second.get_plus() ));
221  }
222 
223  inline GhostData max( const GhostData& first, const GhostData& second )
224  {
225  return GhostData( max( first.get_minus(), second.get_minus() ),
226  max( first.get_plus(), second.get_plus() ));
227  }
228 
229  inline GhostData point_to_ghost( const IntVec& given )
230  {
231  return GhostData((given[0] < 0 ? - given[0] : 0),
232  (given[0] > 0 ? given[0] : 0),
233  (given[1] < 0 ? - given[1] : 0),
234  (given[1] > 0 ? given[1] : 0),
235  (given[2] < 0 ? - given[2] : 0),
236  (given[2] > 0 ? given[2] : 0));
237  }
238 
239  inline GhostData reductive_point_to_ghost( const IntVec& given )
240  {
241  return GhostData((given[0] < 0 ? given[0] : 0),
242  (given[0] > 0 ? - given[0] : 0),
243  (given[1] < 0 ? given[1] : 0),
244  (given[1] > 0 ? - given[1] : 0),
245  (given[2] < 0 ? given[2] : 0),
246  (given[2] > 0 ? - given[2] : 0));
247  }
248 
249  inline GhostData additive_point_to_ghost( const IntVec& given )
250  {
251  return GhostData((given[0] > 0 ? given[0] : 0),
252  (given[0] < 0 ? - given[0] : 0),
253  (given[1] > 0 ? given[1] : 0),
254  (given[1] < 0 ? - given[1] : 0),
255  (given[2] > 0 ? given[2] : 0),
256  (given[2] < 0 ? - given[2] : 0));
257  }
258 
259  inline GhostData additive_reductive_point_to_ghost( const IntVec& given )
260  {
261  return additive_point_to_ghost(given) + reductive_point_to_ghost(given);
262  }
263 
264  inline std::ostream& operator<<( std::ostream& out, const GhostData& gd )
265  {
266  out << "{ " << gd.get_minus() << " " << gd.get_plus() << " }";
267  return out;
268  }
269 
270 } // namespace SpatialOps
271 
272 #endif /* SpatialOps_GhostData_h */
int get_plus(const int i) const
obtain the number of ghost cells on the requested (+) face (0=x, 1=y, 2=z)
Definition: GhostData.h:150
GhostData(const int nx, const int px, const int ny, const int py, const int nz, const int pz)
Construct a GhostData.
Definition: GhostData.h:87
void set_minus(const IntVec &minus)
set the number of ghost cells on the requested (-) face (0=x, 1=y, 2=z)
Definition: GhostData.h:155
IntVec get_plus() const
obtain the IntVec containing the number of ghost cells on the (+) faces
Definition: GhostData.h:145
int get_minus(const int i) const
obtain the number of ghost cells on the requested (-) face (0=x, 1=y, 2=z)
Definition: GhostData.h:140
Holds information about the number of ghost cells on each side of the domain.
Definition: GhostData.h:54
GhostData(const int n=0)
construct a GhostData with the same number of ghost cells on each face
Definition: GhostData.h:112
GhostData(const IntVec &minus, const IntVec &plus)
Construct a GhostData.
Definition: GhostData.h:101
void set_plus(const IntVec &plus)
set the number of ghost cells on the requested (+) face (0=x, 1=y, 2=z)
Definition: GhostData.h:164
IntVec get_minus() const
obtain the IntVec containing the number of ghost cells on the (-) faces
Definition: GhostData.h:135