00001
00002
00003 #ifndef AMROC_AMR_ACCUMULATION_H
00004 #define AMROC_AMR_ACCUMULATION_H
00005
00013 #include <string>
00014 #include <cstdio>
00015
00022 template <class DataType, int dim>
00023 class AMRAccumulation : public controlable {
00024 public:
00025 typedef GridFunction<DataType,dim> grid_fct_type;
00026 typedef GridData<DataType,dim> grid_data_type;
00027
00028 AMRAccumulation() : _Ghosts(0), _Dim(dim), _AccLevel(0) {
00029 _Hierarchy = (GridHierarchy*) 0;
00030 char Name[16];
00031 std::sprintf(Name,"acc");
00032 _AccName = Name;
00033 _Accfunc = (grid_fct_type *) 0;
00034 }
00035
00036 virtual ~AMRAccumulation() {
00037 if (_Accfunc) delete _Accfunc;
00038 }
00039
00040 virtual inline void GridInitializationOp(grid_data_type& accgd)
00041 { accgd.equals(0.0); }
00042 virtual inline void GridAccumulationOp(grid_data_type& accgd, grid_data_type& gd)
00043 { accgd.maximum(gd); }
00044 virtual inline void PointAccumulationOp(DataType& AccPoint, const DataType& value)
00045 { if (value > AccPoint) AccPoint = value; }
00046
00047
00048 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00049 LocCtrl = Ctrl.getSubDevice(prefix+"Accumulation");
00050 RegisterAt(LocCtrl,"GridLevel",_AccLevel);
00051 RegisterAt(LocCtrl,"OutputName",_AccName);
00052 }
00053 virtual void register_at(ControlDevice& Ctrl) { register_at(Ctrl, ""); }
00054
00055 virtual void finish() {
00056 if (_Accfunc) delete _Accfunc;
00057 _Accfunc = (grid_fct_type *) 0;
00058 }
00059
00060 virtual void SetupData(GridHierarchy* gh, const int& ghosts) {
00061 _Hierarchy = gh;
00062 _Ghosts = ghosts;
00063
00064 int t_sten = 0;
00065 int s_sten = 0;
00066 if (_AccLevel > TotalLevels(GH())-1) _AccLevel = TotalLevels(GH())-1;
00067 if (_AccLevel < 0) _AccLevel = 0;
00068 _Accfunc = new grid_fct_type(AccName(), t_sten, s_sten, GH(),
00069 DAGHCellCentered, -_AccLevel, 1, DAGH_All,
00070 DAGHNoComm, DAGHNoBoundary, DAGHNoAdaptBoundary,
00071 DAGHNoExternalGhost);
00072 SetProlongFlag(AccFunc(), DAGHFalse);
00073 SetCheckpointFlag(AccFunc(), DAGHTrue);
00074 }
00075
00076 virtual void Initialize() {
00077 forall (AccFunc(),0,0,c)
00078 GridInitializationOp(AccFunc()(0,0,c));
00079 end_forall
00080 }
00081
00082 virtual void Accumulate(grid_fct_type& u, const int& Time,
00083 const int& Level, const double& t) {
00084
00085 int ATime = CurrentTime(GH(),0);
00086 Coords offset(dim,0);
00087
00088 forall (u,Time,Level,c)
00089 forall (AccFunc(),ATime,0,mc)
00090 AccumulateGrid(u(Time,Level,c),u.interiorbbox(Time,Level,c),
00091 AccFunc()(ATime,0,mc),AccFunc().interiorbbox(ATime,0,mc),offset);
00092 end_forall
00093 end_forall
00094 }
00095
00096 void AccumulateGrid(grid_data_type& gd, const BBox frombb,
00097 grid_data_type& accgd, BBox tobb,
00098 Coords offset) {
00099 Coords toss(tobb.stepsize());
00100 bool sum;
00101 if (tobb.stepsize(0)<=frombb.stepsize(0)) {
00102 sum = false;
00103 tobb *= refine(frombb,frombb.stepsize()/toss);
00104 }
00105 else {
00106 sum = true;
00107 tobb *= coarsen(frombb,toss/frombb.stepsize());
00108 }
00109 if (tobb.empty()) return;
00110
00111 if (dim==1) {
00112 BeginFastIndex1(u, gd.bbox(), gd.data(), DataType);
00113 BeginFastIndex1(acc, accgd.bbox(), accgd.data(), DataType);
00114 for_1 (i, tobb, toss)
00115 DataType value = 0.0;
00116 if (!sum)
00117 value = FastIndex1(u,i-i%frombb.stepsize(0));
00118 else {
00119 BBox AddOver(1,i,i,tobb.stepsize(0));
00120 AddOver.refine(toss/frombb.stepsize());
00121 DataType count = 0.0;
00122 for_1 (l, AddOver, AddOver.stepsize())
00123 if (frombb.inside(l)) {
00124 value += FastIndex1(u,l);
00125 count += 1.0;
00126 }
00127 end_for
00128 if (count > 0.0) value /= count;
00129 }
00130 if (accgd.bbox().inside(i+offset(0)))
00131 PointAccumulationOp(FastIndex1(acc,i+offset(0)),value);
00132 end_for
00133 EndFastIndex1(acc);
00134 EndFastIndex1(u);
00135 }
00136 else if (dim==2) {
00137 BeginFastIndex2(u, gd.bbox(), gd.data(), DataType);
00138 BeginFastIndex2(acc, accgd.bbox(), accgd.data(), DataType);
00139 for_2 (i, j, tobb, toss)
00140 DataType value = 0.0;
00141 if (!sum)
00142 value = FastIndex2(u,i-i%frombb.stepsize(0),j-j%frombb.stepsize(1));
00143 else {
00144 BBox AddOver(2,i,j,i,j,tobb.stepsize(0),tobb.stepsize(1));
00145 AddOver.refine(toss/frombb.stepsize());
00146 DataType count = 0.0;
00147 for_2 (l, m, AddOver, AddOver.stepsize())
00148 if (frombb.inside(l,m)) {
00149 value += FastIndex2(u,l,m);
00150 count += 1.0;
00151 }
00152 end_for
00153 if (count > 0.0) value /= count;
00154 }
00155 if (accgd.bbox().inside(i+offset(0),j+offset(1)))
00156 PointAccumulationOp(FastIndex2(acc,i+offset(0),j+offset(1)),value);
00157 end_for
00158 EndFastIndex2(acc);
00159 EndFastIndex2(u);
00160 }
00161 else if (dim==3) {
00162 BeginFastIndex3(u, gd.bbox(), gd.data(), DataType);
00163 BeginFastIndex3(acc, accgd.bbox(), accgd.data(), DataType);
00164 for_3 (i, j, k, tobb, toss)
00165 DataType value = 0.0;
00166 if (!sum)
00167 value = FastIndex3(u,i-i%frombb.stepsize(0),j-j%frombb.stepsize(1),
00168 k-k%frombb.stepsize(2));
00169 else {
00170 BBox AddOver(3,i,j,k,i,j,k,tobb.stepsize(0),tobb.stepsize(1),
00171 tobb.stepsize(2));
00172 AddOver.refine(toss/frombb.stepsize());
00173 DataType count = 0.0;
00174 for_3 (l, m, n, AddOver, AddOver.stepsize())
00175 if (frombb.inside(l,m,n)) {
00176 value += FastIndex3(u,l,m,n);
00177 count += 1.0;
00178 }
00179 end_for
00180 if (count > 0.0) value /= count;
00181 }
00182 if (accgd.bbox().inside(i+offset(0),j+offset(1),k+offset(2)))
00183 PointAccumulationOp(FastIndex3(acc,i+offset(0),j+offset(1),k+offset(2)),value);
00184 end_for
00185 EndFastIndex3(acc);
00186 EndFastIndex3(u);
00187 }
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 GridHierarchy& GH() { return *_Hierarchy; }
00238 const GridHierarchy& GH() const { return *_Hierarchy; }
00239
00240 const int& NGhosts() const { return _Ghosts; }
00241 const int& Dim() const { return _Dim; }
00242
00243 inline grid_fct_type& AccFunc() { return *_Accfunc;}
00244 inline const char* AccName() { return _AccName.c_str(); }
00245 inline const int& AccLevel() const { return _AccLevel; }
00246 inline int AccLevel() { return _AccLevel; }
00247
00248 protected:
00249 int _Ghosts;
00250 int _Dim;
00251 int _AccLevel;
00252 std::string _AccName;
00253 grid_fct_type *_Accfunc;
00254 GridHierarchy* _Hierarchy;
00255 ControlDevice LocCtrl;
00256 };
00257
00258
00259 #endif