00001 #ifndef _STENCIL_H_
00002 #define _STENCIL_H_
00003 #include "SPACE.H"
00004 #include <array>
00005 #include <tuple>
00006 #include <iostream>
00007 #include "CH_Timer.H"
00008 #include "Shift.H"
00009 #include "RectMDArray.H"
00010
00011 using namespace std;
00012
00013
00014 template <class T> class Stencil
00015 {
00016 public:
00017
00018 Stencil();
00019
00020
00021 Stencil(pair<Shift,T> a_pair,
00022 Point a_destRefratio=getOnes(),
00023 Shift a_destShift=getZeros(),
00024 Point a_srcRefratio=getOnes());
00025
00026
00027
00028
00029 Stencil<T> operator*(const Stencil<T> a_stencil) const;
00030
00031
00032 void operator*=(const T& a_coef);
00033
00034
00035
00036
00037
00038 Stencil<T> operator+(const Stencil<T> a_stencil) const;
00039
00040
00041
00042
00043
00044
00045
00046 void stencilDump() const;
00047
00048
00049 void setDestRefratio(Point a_pt){m_destRefratio = a_pt;};
00050
00051
00052 void setSrcRefratio(Point a_pt){m_srcRefratio = a_pt;};
00053
00054
00055 void setDestShift(Point a_pt){m_destShift = a_pt;};
00056
00057
00058 Stencil makeInterpStencil(RectMDArray<Stencil>){};
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 std::tuple<const Stencil<T>*, const RectMDArray<T>*, const Box*>
00074 operator()(const RectMDArray<T>& a_phi,
00075 const Box& a_bx) const
00076 {
00077 auto t = std::make_tuple(this, &a_phi, &a_bx);
00078 return t;
00079 }
00080
00081
00082 static void apply(const Stencil<T>& a_stencil,
00083 const RectMDArray<T>& a_phi,
00084 RectMDArray<T>& a_lofPhi,
00085 const Box& a_bx);
00086
00087
00088
00089 const vector<T>& getCoefs() const
00090 {
00091 return m_coef;
00092 }
00093
00094
00095 const vector<Point>& getOffsets() const
00096 {
00097 return m_offsets;
00098 }
00099
00100
00101 void print() const
00102 {
00103 cout << "Coeficients and Shifts: " << endl;
00104 for (int ii = 0; ii < m_coef.size(); ii++) {
00105 cout << m_coef[ii] << ": ";
00106 m_offsets[ii].print();
00107 }
00108 cout << "srcRefratio: ";
00109 m_srcRefratio.print();
00110 cout << "destRefratio: ";
00111 m_destRefratio.print();
00112 cout << "destShift: ";
00113 m_destShift.print();
00114 cout << endl;
00115 }
00116
00117 private:
00118 vector<T> m_coef;
00119 vector<Point> m_offsets;
00120 Point m_srcRefratio;
00121 Point m_destRefratio;
00122 Point m_destShift;
00123 Stencil<T>(vector<T > a_vecT, vector<Point > a_vecPt,
00124 Point a_destRefratio=getOnes(),
00125 Point a_destShift=getZeros(),
00126 Point a_srcRefratio=getOnes());
00127
00128 };
00129
00130 #include "StencilImplem.H"
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 template <class T> Stencil<T>
00141 operator*(T a_coef, Shift a_shift)
00142 {return Stencil<T>(pair<Shift,T>(a_shift,a_coef));};
00143
00144
00145
00146
00147
00148 template <class T>
00149 RectMDArray<T>& operator|=(RectMDArray<T>& a_lofPhi, const std::tuple<const Stencil<T>*, const RectMDArray<T>*,const Box* >& a_token)
00150 {
00151 const Box& b=*(std::get<2>(a_token));
00152 forall<T>(a_lofPhi,[](T& t){ t=0; }, b);
00153 Stencil<T>::apply(*(std::get<0>(a_token)), *(std::get<1>(a_token)), a_lofPhi, b);
00154 return a_lofPhi;
00155 }
00156
00157
00158
00159
00160
00161 template <class T>
00162 RectMDArray<T>& operator+=(RectMDArray<T>& a_lofPhi, const std::tuple<const Stencil<T>*, const RectMDArray<T>*,const Box* >& a_token)
00163 {
00164 const Box& b=*(std::get<2>(a_token));
00165
00166 Stencil<T>::apply(*(std::get<0>(a_token)), *(std::get<1>(a_token)), a_lofPhi, b);
00167 return a_lofPhi;
00168 }
00169
00170
00171
00172
00173
00174
00175 template <class T>
00176 void Stencil<T>::apply(const Stencil<T>& a_stencil,
00177 const RectMDArray<T>& a_phi,
00178 RectMDArray<T>& a_lofPhi,
00179 const Box& a_bx)
00180 {
00181 CH_TIMERS("Stencil::apply");
00182
00183 const vector<T> & coef = a_stencil.m_coef;
00184 const vector<Point> & offsets = a_stencil.m_offsets;
00185 const Point& srcRefratio = a_stencil.m_srcRefratio;
00186 const Point& destRefratio = a_stencil.m_destRefratio;
00187 const Point& destShift = a_stencil.m_destShift;
00188
00189 int ncoef = coef.size();
00190 int tuple[DIM];
00191
00192 int nptsDst = a_bx.getHighCorner()[0] - a_bx.getLowCorner()[0]+1;
00193
00194 int incp[DIM];
00195 incp[0] = 1;
00196 Box bxl = a_lofPhi.getBox();
00197 Box bxp = a_phi.getBox();
00198 for (int l=1;l<DIM;l++)
00199 {
00200 incp[l] = incp[l-1]*
00201 (bxp.getHighCorner()[l-1] - bxp.getLowCorner()[l-1]+1);
00202 tuple[l] = a_bx.getHighCorner()[l];
00203 }
00204 tuple[0]=a_bx.getLowCorner()[0];
00205 Point hicross(tuple);
00206 Box cross(a_bx.getLowCorner(),
00207 a_bx.getHighCorner()*(getOnes()-getUnitv(0))
00208 +getUnitv(0)*a_bx.getLowCorner()[0]);
00209 vector<int> srcOffset;
00210 vector<vector<int > > srcOffsetVec;
00211
00212 srcOffset.resize(coef.size());
00213 srcOffsetVec.resize(coef.size());
00214 int size = cross.sizeOf();
00215 int kbasel0 = 0;
00216
00217 int npts = 0;
00218 int nstencil = 0;
00219 for (int isten = 0; isten < coef.size();isten++)
00220 {
00221 srcOffset[isten] = 0;
00222 for (int dir = 0; dir < DIM ; dir++)
00223 {
00224 srcOffset[isten] += offsets[isten][dir]*incp[dir];
00225 }
00226 }
00227 int desdisp = destRefratio[0];
00228 int srcdisp = srcRefratio[0];
00229 int destshift = destShift[0];
00230
00231 double* phi_ptr = &a_phi[0];
00232
00233 double* lofphi_ptr = &(a_lofPhi.index(0));
00234 for (int kperp = 0; kperp < size; kperp++)
00235 {
00236 Point pt = cross.getPoint(kperp);
00237 int kbasel = bxl.getIndex(pt*destRefratio + destShift);
00238 int kbasep = bxp.getIndex(pt*srcRefratio);
00239 for (int isten = 0;isten < srcOffset.size(); isten++)
00240 {
00241
00242 for (int k0 = 0;k0 < nptsDst ; k0++)
00243 {
00244 int offset = srcOffset[isten];
00245 int k0dest = k0*desdisp;
00246
00247 int k0src = k0*srcdisp;
00248 double coefpt = coef[isten];
00249 double phival = phi_ptr[kbasep + k0src + offset];
00250
00251 lofphi_ptr[kbasel + k0dest] = lofphi_ptr[kbasel + k0dest] + coefpt*phival;
00252
00253 }
00254 }
00255 }
00256
00257 }
00258
00259
00260 template <class T, int SRCCOMP, int DSTCOMP>
00261 void componentApply(const Stencil<T> & a_stencil,
00262 const RectMDArray<T, SRCCOMP>& a_phi,
00263 RectMDArray< T, DSTCOMP>& a_lofPhi,
00264 const Box & a_bx,
00265 const int & a_srccomp,
00266 const int & a_dstcomp)
00267 {
00268 CH_TIMERS("applyOpSlow");
00269 const vector<T> & coef = a_stencil.getCoefs();
00270 const vector<Point> & offsets = a_stencil.getOffsets();
00271 assert(a_dstcomp >= 0);
00272 assert(a_dstcomp < DSTCOMP);
00273
00274 assert(a_srccomp >= 0);
00275 assert(a_srccomp < SRCCOMP);
00276
00277 assert(coef.size() == offsets.size());
00278 int ncoef = coef.size();
00279 for ( Point dstpt = a_bx.getLowCorner();a_bx.notDone(dstpt);a_bx.increment(dstpt))
00280 {
00281 for(int isten = 0; isten < ncoef; isten++)
00282 {
00283 Point srcpt = dstpt + offsets[isten];
00284 double weight = coef[isten];
00285
00286 double lofphi = a_lofPhi(dstpt, a_dstcomp);
00287 double phival = a_phi(srcpt, a_srccomp);
00288 a_lofPhi(dstpt,a_dstcomp) = lofphi + weight*phival;
00289 }
00290 }
00291 }
00292
00293
00294
00295 #endif