SpatialOps
IndexTriplet.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_IndexTriplet_h
24 #define SpatialOps_IndexTriplet_h
25 
33 #include <spatialops/SpatialOpsConfigure.h>
36 
38 
39 #include <iomanip>
40 #include <string>
41 #include <sstream>
42 #include <stdexcept>
43 
44 namespace SpatialOps{
45 
53  template< int I > struct Abs{ enum{ result = (I>=0) ? I : -I }; };
54 
62  template< int i1, int i2 > struct Max{ enum{ result = i1>i2 ? i1 : i2 }; };
63 
72  template< int i1, int i2 > struct Min{ enum{ result = i1<i2 ? i1 : i2 }; };
73 
83  template< int i1, int i2 > struct LThan{ enum{ result = (i1 < i2) ? 1 : 0 }; };
84 
94  template< int i1, int i2 > struct GThan{ enum{ result = (i1 > i2) ? 1 : 0 }; };
95 
120  template< int i1, int i2, int i3 >
122  {
123  enum Component{
124  X=i1,
125  Y=i2,
126  Z=i3
127  };
128 
134 
140 
153  typedef IndexTriplet< -i1, -i2, -i3 > Negate;
154 
159  static std::string print(){
160  std::stringstream s;
161  s << "("
162  << std::setw(2) << X << ","
163  << std::setw(2) << Y << ","
164  << std::setw(2) << Z << " )";
165  return s.str();
166  }
167 
168  static inline int x_value(){ return int(X); }
169  static inline int y_value(){ return int(Y); }
170  static inline int z_value(){ return int(Z); }
171 
172  static inline int value(int const direction) {
173  switch( direction ){
174  case 0: return int(X);
175  case 1: return int(Y);
176  case 2: return int(Z);
177  }
178 # ifndef NDEBUG
179  std::ostringstream msg;
180  msg << "IndexTriplet value() given bad direction; given: " << direction << "\n";
181  throw(std::runtime_error(msg.str()));
182 # else
183  return 0; // should not get here. This just helps eliminate compiler warnings.
184 # endif
185  };
186 
187  static inline IntVec int_vec(){
188  return IntVec( i1, i2, i3 );
189  }
190 
191 # ifdef __CUDACC__
192  __device__ static inline int x_value_gpu() { return int(X); }
193  __device__ static inline int y_value_gpu() { return int(Y); }
194  __device__ static inline int z_value_gpu() { return int(Z); }
195 
196  __device__ static inline int value_gpu(int const direction)
197  {
198  if ( direction == 0 ) return int(X);
199  else if( direction == 1 ) return int(Y);
200  else if( direction == 2 ) return int(Z);
201  else return 9001; //Error: Cannot throw an error on a GPU
202  }
203 # endif
204  };
205 
206 
218  template< typename DirT > struct UnitTriplet{
222  > type;
223  };
224 
225 
237  template< typename IT, typename DirT > struct IndexTripletExtract;
238 
239  template< int i1, int i2, int i3 > struct IndexTripletExtract<IndexTriplet<i1,i2,i3>,XDIR>{ enum{ value = i1 }; };
240  template< int i1, int i2, int i3 > struct IndexTripletExtract<IndexTriplet<i1,i2,i3>,YDIR>{ enum{ value = i2 }; };
241  template< int i1, int i2, int i3 > struct IndexTripletExtract<IndexTriplet<i1,i2,i3>,ZDIR>{ enum{ value = i3 }; };
242  template< int i1, int i2, int i3 > struct IndexTripletExtract<IndexTriplet<i1,i2,i3>,NODIR>; // invalid
243 
244 
253  template< int i1, int i2 > struct Kronecker { enum{value=0}; };
254  template< int i1 > struct Kronecker<i1,i1>{ enum{value=1}; };
255 
256 
272  template< typename FieldT, typename DirT >
273  struct IndexStagger{
275  };
276 
277  //------------------------------------------------------------------
278 
292  template< typename IX1, typename IX2 >
293  struct Add
294  {
295  typedef IndexTriplet< IX1::X + IX2::X,
296  IX1::Y + IX2::Y,
297  IX1::Z + IX2::Z > result;
298  };
299 
313  template< typename IX1, typename IX2 >
314  struct Subtract
315  {
316  typedef IndexTriplet< IX1::X - IX2::X,
317  IX1::Y - IX2::Y,
318  IX1::Z - IX2::Z > result;
319  };
320 
334  template< typename IX1, typename IX2 >
335  struct Multiply
336  {
337  typedef IndexTriplet< IX1::X * IX2::X,
338  IX1::Y * IX2::Y,
339  IX1::Z * IX2::Z > result;
340  };
341 
355  template< typename IX1, typename IX2 >
356  struct LessThan
357  {
361  };
362 
376  template< typename IX1, typename IX2 >
377  struct GreaterThan
378  {
382  };
383 
391  template< typename IT > struct GetNonzeroDir;
392  template<> struct GetNonzeroDir< IndexTriplet< 1, 0, 0> >{ typedef SpatialOps::XDIR DirT; };
393  template<> struct GetNonzeroDir< IndexTriplet<-1, 0, 0> >{ typedef SpatialOps::XDIR DirT; };
394  template<> struct GetNonzeroDir< IndexTriplet< 0, 1, 0> >{ typedef SpatialOps::YDIR DirT; };
395  template<> struct GetNonzeroDir< IndexTriplet< 0,-1, 0> >{ typedef SpatialOps::YDIR DirT; };
396  template<> struct GetNonzeroDir< IndexTriplet< 0, 0, 1> >{ typedef SpatialOps::ZDIR DirT; };
397  template<> struct GetNonzeroDir< IndexTriplet< 0, 0,-1> >{ typedef SpatialOps::ZDIR DirT; };
398  template<> struct GetNonzeroDir< IndexTriplet< 0, 0, 0> >{ typedef SpatialOps::NODIR DirT; };
399 
400 } // namespace SpatialOps
401 
406 #endif /* SpatialOps_IndexTriplet_h */
Assuming that only a single direction is active (1) in the IndexTriplet type, this identifies the dir...
Definition: IndexTriplet.h:391
Obtain the "unit vector" IndexTriplet for the supplied direction.
Definition: IndexTriplet.h:218
Perform compile-time subtraction over a list of IndexTriplet types.
Definition: IndexTriplet.h:314
Used for specifying field type traits.
Definition: IndexTriplet.h:121
Select the maximum of two integer values.
Definition: IndexTriplet.h:62
Perform compile-time compare of two IndexTriplet types.
Definition: IndexTriplet.h:377
Obtain the result of comparing two integers at compile time.
Definition: IndexTriplet.h:94
Perform compile-time addition of two IndexTriplet types.
Definition: IndexTriplet.h:293
Defines a type to represent no direction.
static std::string print()
Writes the IndexTriplet to a string.
Definition: IndexTriplet.h:159
IndexTriplet< Abs< i1 >::result, Abs< i2 >::result, Abs< i3 >::result > Abs
The absolute value of this IndexTriplet.
Definition: IndexTriplet.h:133
Perform compile-time multiplication of two IndexTriplet types.
Definition: IndexTriplet.h:335
Perform compile-time compare of two IndexTriplet types.
Definition: IndexTriplet.h:356
Obtain the absolute value of an integer at compile time.
Definition: IndexTriplet.h:53
Select the minimum of two integer values.
Definition: IndexTriplet.h:72
Defines a type for the x-direction.
Defines a type for the y-direction.
Obtain the index value for how far the given field type is staggered relative to a scalar cell center...
Definition: IndexTriplet.h:273
Defines a type for the z-direction.
IndexTriplet< -i1, -i2, -i3 > Negate
Negates this IndexTriplet Example:
Definition: IndexTriplet.h:153
Extracts the value for the IndexTriplet in the requested dimension.
Definition: IndexTriplet.h:237
Obtain the result of comparing two integers at compile time.
Definition: IndexTriplet.h:83
IndexTriplet< Max< 0, i1 >::result, Max< 0, i2 >::result, Max< 0, i3 >::result > PositiveOrZero
Preserves positive elements, zeros others.
Definition: IndexTriplet.h:139
Compares two types for equality.
Implements a Kronecker delta function on two int values.
Definition: IndexTriplet.h:253