Proto
Proto_Stencil.H
1 #ifndef _PROTO_STENCIL_H_
2 #define _PROTO_STENCIL_H_
3 #include "Proto_BoxData.H"
4 #include "Proto_DisjointBoxLayout.H"
5 
6 #include <vector>
7 #include <tuple>
8 #include <iostream>
9 #include <iomanip> //for pretty printing
10 #include <set>
11 
12 namespace Proto {
13 
14 //=======================================================================================
15 // SHIFT ||
16 //=======++
17 
18 template <typename T> class Stencil; //forward declaration
19 
22 
24 
30 class Shift {
31 public:
32 
34 
35 
38  Shift() : m_shift(Point::Zeros()){};
39 
41 
47  explicit Shift(const Point& a_pt){m_shift = a_pt;};
48 
50 
57  template<typename... vals>
58  inline explicit Shift(vals... args) : m_shift(args...) {}
59 
62 
63 
66 
73  inline static Shift Basis(int a_dir, int a_scale=1)
74  {return Shift(Point::Basis(a_dir, a_scale));};
75 
77 
81  inline static Shift Zeros(){return Shift(Point::Zeros());};
82 
84 
90  inline static Shift Ones(int a_scale=1){return Shift(Point::Ones(a_scale));};
91 
93  inline Point& shift(){return m_shift;}
94 
96 
107  template<typename T>
108  inline Stencil<T> operator*(T a_coef) const
109  {
110  return Stencil<T>(*this,a_coef);
111  }
112 
114 
118  inline Shift operator*(const Shift& a_shift) const
119  {
120  return Shift(m_shift + a_shift.m_shift);
121  }
122 
124  inline int& operator[](int a_dir)
125  {
126  PROTO_ASSERT(((a_dir >= 0) && (a_dir < DIM)),
127  "Shift::operator[](int a_dir) invalid for a_dir = %i. a_dir must be in [0,DIM=%i)",
128  a_dir, DIM);
129  return m_shift[a_dir];
130  }
133 private:
134  Point m_shift;
135 };
136 
137 //=======================================================================================
138 // LAZYSTENCIL ||
139 //=============++
140 
141 // forward declaration
142  template <typename T, unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
143  class BoxData;
144 
146 
154  template <typename T, unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
155 class LazyStencil {
156 public:
157  inline LazyStencil() {};
158  inline LazyStencil(const Stencil<T>* a_stencil,
159  const BoxData<T,C,MEMTYPE,D,E>* a_src,
160  Box a_box, T a_scale);
161 
162  inline void apply(BoxData<T,C,MEMTYPE,D,E>& a_dest, bool a_overwrite);
163 
164  inline unsigned long long int size(){return m_stencil.size();}
165 
166  Box m_range;
167 
168  std::vector<const Stencil<T>*> m_stencil;
169  std::vector<BoxData<T, C,MEMTYPE, D, E>*> m_src;
170  std::vector<Box> m_box;
171  std::vector<T> m_scale;
172 };
174 //=======================================================================================
175 // STENCIL ||
176 //=========++
177 
179 
211 template <typename T>
212 class Stencil {
213 
214 public:
215 
217  {
218  T elements[64];
219  };
220 
221  ~Stencil()
222  {
223 // using std::cout;
224 // using std::endl;
225 // cout << "in stencil destructor" << endl;
226  if(m_isClosed)
227  {
228 #ifdef PROTO_CUDA
229  protoFreeGPU(d_coeff);
230  protoFreeGPU(d_offset);
231 #endif
232  m_isClosed = false;
233  }
234  }
235  //Set up the coefficients on the device.
236  //Must be called before computations can be performed on the device
237  inline void closeForDevice();
238  template <typename TT, unsigned int C, MemType MEMTYPE , unsigned char D, unsigned char E>
239  friend class LazyStencil;
240 
241  template <typename TT, unsigned int C , MemType MEMTYPE, unsigned char D, unsigned char E>
242  friend class BoxData;
243 
244  template <typename TT, unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
247 
248  template <typename TT, unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
251 
253 
254 
257  Stencil();
258 
260 
273  Stencil(Shift a_shift,
274  T a_coef,
275  Point a_destRefratio = Point::Ones(),
276  Point a_destShift = Point::Zeros(),
277  Point a_srcRefratio = Point::Ones());
278 
280 
282 
283 
286 
292  Stencil<T> operator*(const Stencil<T>& a_stencil) const;
293 
295 
302  Stencil<T> operator*(const T a_coef) const;
303 
305 
309  void operator*=(const Stencil<T>& a_stencil);
310 
312  void operator*=(const T a_coef);
313 
315 
322  Stencil<T> operator+(const Stencil<T>& a_stencil) const;
325 
331  Stencil<T> operator-(const Stencil<T>& a_stencil) const;
334 
338  void operator+=(const Stencil<T>& a_stencil);
339 
341 
345  void operator-=(const Stencil<T>& a_stencil);
346 
348 
350 
351 
359  inline bool operator==(Stencil<T>& a_stencil) const;
360 
366  inline bool operator!=(Stencil<T>& a_stencil) const {return !(*this == a_stencil);}
367 
369 
373  inline const std::vector<T>& coefs() const {return m_coefs;};
374 
376 
380  inline const T* devCoefs() const {return d_coeff;};
381 
383 
387  inline const Point* devOffsets() const {return d_offset;};
388 
390 
394  inline const std::vector<Point>& offsets() const {return m_offsets;};
395 
397 
401  inline unsigned long long int size() const {return m_coefs.size();}
402 
418  inline Box span() const {return m_span;};
419 
421 
426  inline Point spanPoint() const;
427 
429 
432  inline Point ghost() const;
433 
435 
439  inline unsigned long long int numFlops(const Box& a_box) const;
441 
443 
447  inline Point& srcRatio(){return m_srcRefratio;};
448 
450  inline const Point& srcRatio() const {return m_srcRefratio;};
451 
453 
457  inline Point& destRatio(){return m_destRefratio;};
458 
460  inline const Point& destRatio() const {return m_destRefratio;};
461 
463 
466  inline Point& destShift(){return m_destShift;};
467 
469 
472  inline const Point& destShift() const {return m_destShift;};
473 
475 
477 
478 
481 
489  template<unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
491  operator()(const BoxData<T,C,MEMTYPE,D,E>& a_src, T a_scale = 1) const;
492 
494 
503  template<unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
505  operator()(const BoxData<T,C,MEMTYPE,D,E>& a_src, Box a_box, T a_scale = 1) const;
507 
509 
510 
513 
517  inline void invert(int a_dir);
518 
520 
526  inline void transpose(unsigned char a, unsigned char b);
529 
536  inline Box indexRange(Box a_domain) const;
537 
539 
547  inline Box indexDomain(Box a_range) const;
548 
550 
558  inline Box range(Box a_domain) const;
559 
561 
569  inline Box domain(Box a_range) const;
570 
572 
576  T diagonalValue() const;
579 
583  inline void print() const;
585 
586  // End of Stencil Operations Doxygen Module
591 
593 
594 
597 
605  static Stencil<T> Derivative(int a_n, int a_dir = 0, int a_order = 2);
606 
608 
611  static Stencil<T> Laplacian();
612  #if DIM == 2
613  static Stencil<T> Laplacian_9();
615  #elif DIM == 3
616  static Stencil<T> Laplacian_19();
619  static Stencil<T> Laplacian_27();
620  #endif
621 
628  static Stencil<T> LaplacianFace(int a_dir, int a_order = 2);
629 
631 
635  static Stencil<T> CellToEdge(int a_dir, int a_order = 4);
636 
638 
641  static Stencil<T> DiffCellToEdge(int a_dir, int a_order = 4);
642 
644 
650  static Stencil<T> EdgeToCell(int a_dir, int a_order = 4);
651 
653 
661  static Stencil<T> CellToEdgeL(int a_dir, int a_order = 5);
662 
664 
672  static Stencil<T> CellToEdgeH(int a_dir, int a_order = 5);
673 
675 
681  static Stencil<T> AvgDown(int a_refRatio = 2);
682 
684 
690  static Stencil<T> AvgDownEdge(int a_dir, int a_refRatio = 2);
691 
693 
699  static Stencil<T> FluxDivergence(int a_dir);
701 
702  // End of Stencil Operations Doxygen Module
705 
717  template<unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
718  void apply(const BoxData<T,C,MEMTYPE,D,E>& a_src,
719  BoxData<T,C,MEMTYPE,D,E>& a_dest,
720  const Box& a_bx,
721  bool a_initToZero = false,
722  const T a_scale = 1) const;
723 
724 
725 
726 
727  template<unsigned int C, unsigned char D, unsigned char E, MemType MEMTYPE>
728  void protoApply( const BoxData<T,C,MEMTYPE,D,E>& a_src,
730  const Box& a_box,
731  bool a_initToZero = false,
732  T a_scale = 1);
733 
734 
735  template<unsigned int C, unsigned char D, unsigned char E>
736  void hostApply( const BoxData<T,C,MemType::HOST,D,E>& a_src,
738  const Box& a_box,
739  bool a_initToZero = false,
740  T a_scale = 1) const;
741 
742 
743  inline bool getIsClosed() {return m_isClosed;}
744 
745 private:
747 
753  void augment(T a_coef, Point a_offset);
754 
755  std::vector<T> m_coefs;
756  std::vector<Point> m_offsets;
757  Point m_srcRefratio;
758  Point m_destRefratio;
759  Point m_destShift;
760  Box m_span;
761 
762  bool m_isClosed;
763  //this copies to the device
764  T* d_coeff;
765  Point* d_offset;
766  Stencil<T>::coeff_holder c_coeff;
767 
768 };
769 
771 
772 
775 
784 template <typename T>
785 inline Stencil<T> operator*(T a_coef, Shift a_shift)
786 {
787  return Stencil<T>(a_shift, a_coef);
788 }
789 
791 
795 template <typename T>
796 inline Stencil<T> operator*(T a_coef, const Stencil<T> a_stencil)
797 {
798  return a_stencil*a_coef;
799 }
800 
802 
820 template <typename T, unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
822 
824 
842 template <class T, unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
844 
846 
847 //=======================================================================================
848 // InterpStencil ||
849 //===============++
850 
852 
859 template <class T>
861 {
862 public:
864  inline InterpStencil()
865  {
866  m_closed = false;
867  }
868 
870 
876  inline InterpStencil(int a_ratio)
877  {
878  define(Point::Ones(a_ratio));
879  }
880 
882 
888  inline InterpStencil(Point a_ratio)
889  {
890  define(a_ratio);
891  }
892 
893 
895 
901  inline void define(Point a_ratio)
902  {
903  for (int ii = 0; ii < DIM; ii++)
904  {
905  PROTO_ASSERT(a_ratio[ii] > 0,
906  "InterpStencil(Point ratio) invalid. All ratios must be 1 or greater");
907  }
908  m_k = Box(a_ratio - Point::Ones());
909  m_s.resize(m_k.size());
910  m_closed = false;
911  }
912 
913 // inline void close()
914 // {
915 // for (auto iter = m_k.begin(); iter != m_k.end(); ++iter)
916 // {
917 // Stencil<T>& S = (*this)(*iter);
918 // S.destRatio() = m_k.high() + Point::Ones();
919 // S.destShift() = *iter;
920 // }
921 // m_closed = true;
922 // }
923 
925 
932  {
933  PROTO_ASSERT(!m_closed,
934  "Components of InterpStencil are read-only once closed. Use InterpStencil::get instead.");
935  PROTO_ASSERT(m_k.contains(a_p),
936  "InterpStencil::operator()(Point p) invalid.\
937  p is not a member of the InterStencil kernel");
938 
939  return m_s[m_k.index(a_p)];
940  }
941 
943 
949  inline const Stencil<T>& get(Point a_p) const
950  {
951  PROTO_ASSERT(m_k.contains(a_p),
952  "InterpStencil::operator()(Point p) invalid.\
953  p is not a member of the InterStencil kernel");
954 
955  return m_s[m_k.index(a_p)];
956  }
957 
959 
962  inline Box span()
963  {
964  Box span;
965  for (int ii = 0; ii < m_s.size(); ii++)
966  {
967  span = span & m_s[ii].span().low();
968  span = span & m_s[ii].span().high();
969  }
970  return span;
971  }
972 
973  inline Point spanPoint()
974  {
975  Box spanBox = span();
976  int v[DIM];
977  for (int ii = 0; ii < DIM; ii++)
978  {
979  v[ii] = std::max(std::abs(spanBox.low()[ii]), std::abs(spanBox.high()[ii]));
980  }
981  return Point(v);
982  }
983 
985 
994  template<unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
995  inline LazyStencil<T,C,MEMTYPE,D,E> operator()(const BoxData<T,C,MEMTYPE,D,E>& a_src,
996  T a_scale = 1) const;
998 
1008  template<unsigned int C, MemType MEMTYPE, unsigned char D, unsigned char E>
1009  inline LazyStencil<T,C,MEMTYPE,D,E> operator()(const BoxData<T,C,MEMTYPE,D,E>& a_src,
1010  Box a_box,
1011  T a_scale = 1) const;
1013 
1017  static inline InterpStencil<T> PiecewiseConstant(Point a_ratio);
1019 
1023  static inline InterpStencil<T> PiecewiseLinear(Point a_ratio);
1025 
1030  static inline InterpStencil<T> Quadratic(int a_ratio);
1031 
1033 
1041  static inline InterpStencil<T> Build(int a_shiftMax, Box a_shiftKernel,
1042  int a_order, int a_refRatio);
1043 
1045 
1052  static inline InterpStencil<T> Build(
1053  std::vector<Point>& a_shifts,
1054  int a_maxOrder,
1055  int a_refRatio);
1057 
1064  static inline InterpStencil<T> Build(
1065  std::vector<Point>& a_shifts,
1066  const std::vector<Point>& a_orders,
1067  int a_refRatio);
1068 
1070 
1073  inline Box kernel() const {return m_k;}
1075 
1078  inline Point ratio() const {return m_r;}
1080 
1083  inline typename std::vector<Stencil<T>>::iterator begin(){return m_s.begin();}
1085 
1088  inline typename std::vector<Stencil<T>>::iterator end(){return m_s.end();}
1089 
1091 
1094  inline bool empty(){return (m_s.size() <= 0);}
1095 
1097 
1101  inline unsigned long long int size() const {return m_s.size();}
1102 private:
1103  Point m_r;
1104  Box m_k;
1105  std::vector<Stencil<T>> m_s;
1106  bool m_closed = false;
1107 };
1108 
1109 #include "implem/Proto_StencilImplem.H"
1110 #include "implem/Proto_StencilDefs.H"
1111 } //end Proto namespace
1112 #endif
unsigned long long int size() const
Size.
Definition: Proto_Stencil.H:401
Stencil Shift.
Definition: Proto_Stencil.H:30
Point ratio() const
Return Destination Refinement Ratio.
Definition: Proto_Stencil.H:1078
static Shift Basis(int a_dir, int a_scale=1)
Basis Shift.
Definition: Proto_Stencil.H:73
bool empty()
Empty Query.
Definition: Proto_Stencil.H:1094
An Unevaluated Stencil Operation.
Definition: Proto_BoxData.H:66
Point high() const
Access High Corner.
Definition: Proto_Box.H:174
Point low() const
Access Low Corner.
Definition: Proto_Box.H:168
Point & destShift()
Get Destination Shift.
Definition: Proto_Stencil.H:466
Multidimensional Rectangular Array.
Definition: Proto_BoxData.H:458
BoxData< T, C, MEMTYPE, D, E > & operator|=(BoxData< T, C, MEMTYPE, D, E > &a_dest, LazyStencil< T, C, MEMTYPE, D, E > &&a_op)
Application by Replacement.
Definition: Proto_Stencil.H:424
const T * devCoefs() const
Get Vector of Coefficients.
Definition: Proto_Stencil.H:380
Point & shift()
Get Shift Point.
Definition: Proto_Stencil.H:93
Stencil< T > operator*(T a_coef) const
Scalar Multiplication.
Definition: Proto_Stencil.H:108
Point & srcRatio()
Get Source Refinement Ratio.
Definition: Proto_Stencil.H:447
InterpStencil()
Default Constructor.
Definition: Proto_Stencil.H:864
Point & destRatio()
Get Destination Refinement Ratio.
Definition: Proto_Stencil.H:457
A Linear Stencil Operation.
Definition: Proto_BoxData.H:64
Box span()
Span.
Definition: Proto_Stencil.H:962
const std::vector< Point > & offsets() const
Get Vector of Offsets.
Definition: Proto_Stencil.H:394
static CUDA_DECORATION Point Zeros()
Get Zeros.
Definition: Proto_Point.H:37
Interpolation Stencil.
Definition: Proto_Stencil.H:860
Point operator-(Point a_pt)
Unary Negation.
Definition: Proto_Point.H:432
std::vector< Stencil< T > >::iterator end()
Iterate Over Stencil Components.
Definition: Proto_Stencil.H:1088
An interval in DIM dimensional space.
Definition: Proto_Box.H:26
void define(Point a_ratio)
Define.
Definition: Proto_Stencil.H:901
const Point & srcRatio() const
Get Source Refinement Ratio (Const)
Definition: Proto_Stencil.H:450
static Shift Zeros()
Zero Shift.
Definition: Proto_Stencil.H:81
static CUDA_DECORATION Point Basis(int a_dir, int a_scale=1)
Get Basis.
Definition: Proto_Point.H:48
const Point & destShift() const
Get Destination Shift (Const)
Definition: Proto_Stencil.H:472
InterpStencil(int a_ratio)
Isotropic Constructor.
Definition: Proto_Stencil.H:876
bool operator!=(Stencil< T > &a_stencil) const
Inquality Operator.
Definition: Proto_Stencil.H:366
Shift(const Point &a_pt)
Point Constructor.
Definition: Proto_Stencil.H:47
int & operator[](int a_dir)
Componentwise Access.
Definition: Proto_Stencil.H:124
Stencil< T > & operator()(Point a_p)
Get Read-Write Stencil Subcomponent.
Definition: Proto_Stencil.H:931
const std::vector< T > & coefs() const
Get Vector of Coefficients.
Definition: Proto_Stencil.H:373
std::vector< Stencil< T > >::iterator begin()
Iterate Over Stencil Components.
Definition: Proto_Stencil.H:1083
Box span() const
Span.
Definition: Proto_Stencil.H:418
Definition: Proto_Box.H:11
const Point * devOffsets() const
Get Vector of Offsets.
Definition: Proto_Stencil.H:387
unsigned long long int size() const
Size Query.
Definition: Proto_Stencil.H:1101
Definition: Proto_Stencil.H:216
Integer Valued Vector.
Definition: Proto_Point.H:21
static Point Ones(int a_scale=1)
Get Ones.
Definition: Proto_Point.H:25
static Shift Ones(int a_scale=1)
Unit Shift.
Definition: Proto_Stencil.H:90
InterpStencil(Point a_ratio)
Anisotropic Constructor.
Definition: Proto_Stencil.H:888
const Point & destRatio() const
Get Destination Refinement Ratio (Const)
Definition: Proto_Stencil.H:460
BoxData< T, C, MEMTYPE, D, E > & operator+=(BoxData< T, C, MEMTYPE, D, E > &a_dest, LazyStencil< T, C, MEMTYPE, D, E > &&a_op)
Application by Increment.
Definition: Proto_Stencil.H:440
Shift()
Default Constructor.
Definition: Proto_Stencil.H:38
Shift operator*(const Shift &a_shift) const
Convolution.
Definition: Proto_Stencil.H:118
Shift(vals... args)
Variadic Constructor.
Definition: Proto_Stencil.H:58
Box kernel() const
Return Shift Kernel.
Definition: Proto_Stencil.H:1073