00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011
00012
00013
00014
00015 #ifndef _LEVELDATAOPS_H_
00016 #define _LEVELDATAOPS_H_
00017
00018 #ifdef CH_MPI
00019 #include <string>
00020 #include <sstream>
00021 #endif
00022 #include "LevelData.H"
00023 #include "RefCountedPtr.H"
00024 #include "SPMD.H"
00025 #include "Copier.H"
00026 #include "NamespaceHeader.H"
00027
00028
00029
00030
00031 template <class T>
00032 class LevelDataOps
00033 {
00034 public:
00035 LevelDataOps()
00036 :m_levelFactory( new DefaultDataFactory<T>() )
00037 {
00038 }
00039
00040 LevelDataOps(RefCountedPtr<DataFactory<T> > a_factoryPtr)
00041 : m_levelFactory(a_factoryPtr){;}
00042 virtual ~LevelDataOps(){;}
00043 virtual void define(const RefCountedPtr<DataFactory<T> >& a_factoryPtr)
00044 {m_levelFactory = a_factoryPtr;}
00045 virtual void define(DataFactory<T>* a_rawPointer)
00046 {m_levelFactory = RefCountedPtr<DataFactory<T> >(a_rawPointer);}
00047 virtual void create( LevelData<T>& a_lhs, const LevelData<T>& a_rhs);
00048 virtual void assign( LevelData<T>& a_lhs, const LevelData<T>& a_rhs) ;
00049 virtual Real dotProduct(const LevelData<T>& a_1, const LevelData<T>& a_2) ;
00050 virtual void incr( LevelData<T>& a_lhs, const LevelData<T>& a_x, Real a_scale) ;
00051 virtual void mult( LevelData<T>& a_lhs, const LevelData<T>& a_x);
00052 virtual void axby( LevelData<T>& a_lhs, const LevelData<T>& a_x,
00053 const LevelData<T>& a_y, Real a_a, Real a_b) ;
00054 virtual void scale(LevelData<T>& a_lhs, const Real& a_scale) ;
00055 virtual void plus(LevelData<T>& a_lhs, const Real& a_inc) ;
00056 virtual void setToZero(LevelData<T>& a_lhs);
00057 virtual void copyToZero(LevelData<T>& a_lhs, const Copier& a_copier);
00058
00059
00060 protected:
00061 RefCountedPtr<DataFactory<T> > m_levelFactory;
00062 };
00063
00064
00065
00066
00067
00068
00069 #define ITER(a) for(DataIterator dit = a.dataIterator(); dit.ok(); ++dit) { \
00070 DataIndex d = dit();
00071 #define ENDFOR(a) }
00072
00073 template <class T>
00074 void LevelDataOps<T>:: create(LevelData<T>& a_lhs, const LevelData<T>& a_rhs)
00075 {
00076 a_lhs.define(a_rhs, *m_levelFactory);
00077 }
00078
00079 template <class T>
00080 void LevelDataOps<T>:: assign(LevelData<T>& a_lhs, const LevelData<T>& a_rhs)
00081 {
00082 Interval interv(0, a_rhs.nComp()-1);
00083 a_rhs.copyTo(interv, a_lhs, interv);
00084 }
00085
00086 template <class T>
00087 Real LevelDataOps<T>::dotProduct(const LevelData<T>& a_1, const LevelData<T>& a_2)
00088 {
00089 const DisjointBoxLayout& dbl = a_1.disjointBoxLayout();
00090 Real val = 0.0;
00091 ITER(a_1)
00092 val += a_1[d].dotProduct(a_2[d], dbl.get(d));
00093 ENDFOR(a_1);
00094
00095 #ifdef CH_MPI
00096 Real recv;
00097 int result = MPI_Allreduce(&val, &recv, 1, MPI_CH_REAL,
00098 MPI_SUM, Chombo_MPI::comm);
00099 if( result != 0 ){
00100 std::ostringstream msg;
00101 msg << "LevelDataOps::dotProduct() called MPI_Allreduce() which returned error code " << result ;
00102 MayDay::Warning( msg.str().c_str() );
00103 }
00104 val = recv;
00105 #endif
00106 return val;
00107
00108 }
00109
00110 template <class T>
00111 void LevelDataOps<T>:: incr( LevelData<T>& a_lhs, const LevelData<T>& a_rhs, Real a_scale)
00112 {
00113
00114 int numcomp = a_lhs.nComp();
00115 int startcomp = 0;
00116 ITER(a_lhs)
00117 Box subbox = a_lhs.disjointBoxLayout()[d];
00118 a_lhs[d].plus(a_rhs[d], subbox, subbox, a_scale, startcomp, startcomp, numcomp);
00119 ENDFOR(a_lhs);
00120 }
00121
00122 template <class T>
00123 void LevelDataOps<T>:: mult( LevelData<T>& a_lhs, const LevelData<T>& a_rhs)
00124 {
00125
00126 ITER(a_lhs)
00127 a_lhs[d] *= a_rhs[d];
00128 ENDFOR(a_lhs);
00129 }
00130
00131 template <class T>
00132 void LevelDataOps<T>:: setToZero( LevelData<T>& a_lhs)
00133 {
00134 ITER(a_lhs)
00135 a_lhs[d].setVal(0.0);
00136 ENDFOR(a_lhs);
00137 }
00138
00139 template <class T>
00140 void LevelDataOps<T>:: copyToZero( LevelData<T>& a_lhs, const Copier& a_copier)
00141 {
00142 int nComp = a_lhs.nComp();
00143 for(CopyIterator it(a_copier, CopyIterator::LOCAL); it.ok(); ++it)
00144 {
00145 const MotionItem& item = it();
00146 a_lhs[item.toIndex].setVal(0, item.toRegion, 0, nComp);
00147
00148 }
00149 for(CopyIterator it(a_copier, CopyIterator::TO); it.ok(); ++it)
00150 {
00151 const MotionItem& item = it();
00152 a_lhs[item.toIndex].setVal(0, item.toRegion, 0, nComp);
00153 }
00154 }
00155
00156 template <class T>
00157 void LevelDataOps<T>:: axby( LevelData<T>& a_lhs, const LevelData<T>& a_x,
00158 const LevelData<T>& a_y, Real a, Real b)
00159 {
00160
00161 ITER(a_lhs)
00162 T& data = a_lhs[d];
00163 data.copy(a_x[d]);
00164 data.mult(a);
00165 data.plus(a_y[d], b);
00166 ENDFOR(a_lhs);
00167 }
00168
00169 template <class T>
00170 void LevelDataOps<T>:: scale(LevelData<T>& a_lhs, const Real& a_scale)
00171 {
00172 ITER(a_lhs)
00173 T& data = a_lhs[d];
00174 data.mult(a_scale);
00175 ENDFOR(a_lhs);
00176 }
00177
00178 template <class T>
00179 void LevelDataOps<T>:: plus(LevelData<T>& a_lhs, const Real& a_inc)
00180 {
00181 ITER(a_lhs)
00182 T& data = a_lhs[d];
00183 data += a_inc;
00184 ENDFOR(a_lhs);
00185 }
00186
00187 #undef ITER
00188 #undef ENDFOR
00189
00190 #include "NamespaceFooter.H"
00191 #endif