00001
00002
00003
00004
00005
00006 #ifndef AMROC_AMRFIXUP_H
00007 #define AMROC_AMRFIXUP_H
00008
00016 #include "Fixup1.h"
00017 #include "Fixup2.h"
00018 #include "Fixup3.h"
00019
00020 #include "Timing.h"
00021
00022 #include <string>
00023
00044 template <class VectorType, class FixupType, int dim>
00045 class AMRFixup : public Fixup<VectorType,FixupType,dim>,
00046 public FixupOps<VectorType,FixupType,dim> {
00047
00048 typedef Fixup<VectorType,FixupType,dim> base;
00049 typedef FixupOps<VectorType,FixupType,dim> ops;
00050 typedef typename VectorType::InternalDataType DataType;
00051
00052 public:
00053 typedef GridData<VectorType,dim> vec_grid_data_type;
00054
00055 typedef GridData<VectorType,minus_1<dim>::dim> ld_vec_grid_data_type;
00056 typedef GridData<FixupType,minus_1<dim>::dim> ld_fixup_grid_data_type;
00057
00058 typedef GridFunction<VectorType,dim> vec_grid_fct_type;
00059 typedef GridFunction<FixupType,minus_1<dim>::dim> ld_fixup_grid_fct_type;
00060
00061 AMRFixup() : base() {
00062 _u = (vec_grid_fct_type *) 0;
00063 sprintf(GFName,"u-fixup");
00064 }
00065
00066 virtual ~AMRFixup() {}
00067
00068 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00069 base::LocCtrl = Ctrl.getSubDevice(prefix+"AMRFixup");
00070 RegisterAt(base::LocCtrl,"Equations",base::_FixupEquations);
00071 }
00072 virtual void register_at(ControlDevice& Ctrl) { register_at(Ctrl, ""); }
00073
00074 virtual void SaveFluxes(const int Time, const int Level, const int c,
00075 vec_grid_data_type* flux[],
00076 const double dt, const int& mdim) {
00077
00078 if (!U().has_children(Time,Level,c)) return;
00079 DCoords dx = base::GH().worldStep(U().GF_StepSize(Level));
00080 const int refinefactor = RefineFactor(base::GH(),Level);
00081
00082 int d;
00083 DataType Fac = -dt;
00084 for (d=0; d<dim; d++)
00085 Fac *= dx(d);
00086
00087 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00088 ( comm_service::log() << "\n*** Saving Coarse Fluxes - "
00089 << U().interiorbbox(Time,Level,c) << " ***\n").flush();
00090 #endif
00091 for (register int j=0; j<U().children(Time,Level,c); j++) {
00092 BBox work(U().childbox(Time,Level,c,j)*U().interiorbbox(Time,Level,c));
00093 if (!work.empty()) {
00094 const int& idx = U().childidx(Time,Level,c,j);
00095 for (d=0; d<2*dim; d++)
00096 if ((mdim==0 || d/2==mdim-1) && ValidSide(Time,Level+1,idx,d)) {
00097 BBox bb(FixupBBox(coarsen(U().interiorbbox(Time,Level+1,idx),refinefactor),d)*work);
00098 if (!bb.empty()) {
00099 bb = FluxBBox(bb,d);
00100 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00101 ( comm_service::log() << "To " << U().interiorbbox(Time,Level+1,idx)
00102 << " Side: " << d << " using " << bb << " into "
00103 << base::F(d)(Time,Level+1,idx).bbox() << "\n").flush();
00104 #endif
00105 (*flux[d]).multiply(Fac/dx(d/2), bb);
00106 copyf_to(base::F(d)(Time,Level+1,idx),(*flux[d]),bb,d);
00107 (*flux[d]).divide(Fac/dx(d/2), bb);
00108 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00109 ops::AlignBBox(bb,d);
00110 base::debug_print_ld(base::F(d)(Time,Level+1,idx),bb);
00111 ( comm_service::log() << "\n" ).flush();
00112 #endif
00113 }
00114 }
00115 }
00116 }
00117 }
00118
00119 virtual void AddFluxes(const int Time, const int Level, const int c,
00120 vec_grid_data_type* flux[],
00121 const double tc, const double tf,
00122 const double dtc, const double dtf,
00123 const int& mdim) {
00124 AddIntercellFluxes(Time, Level, c, flux, dtf, mdim);
00125 }
00126
00127 virtual void AddIntercellFluxes(const int Time, const int Level, const int c,
00128 vec_grid_data_type* flux[], const double dt,
00129 const int& mdim) {
00130
00131 DCoords dx = base::GH().worldStep(U().GF_StepSize(Level));
00132
00133 int d;
00134 DataType Fac = dt;
00135 for (d=0; d<dim; d++)
00136 Fac *= dx(d);
00137
00138 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00139 ( comm_service::log() << "\n*** Adding Higher Order Fluxes - "
00140 << U().interiorbbox(Time,Level,c) << " ***\n").flush();
00141 #endif
00142 for (d=0; d<2*dim; d++)
00143 if ((mdim==0 || d/2==mdim-1) && ValidSide(Time,Level,c,d)) {
00144 BBox bb(FluxBBox(U().interiorbbox(Time,Level,c), d));
00145 (*flux[d]).multiply(Fac/dx(d/2), bb);
00146 addf_to(base::F(d)(Time,Level,c),(*flux[d]),bb,d);
00147 (*flux[d]).divide(Fac/dx(d/2), bb);
00148 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00149 base::debug_print_ld(base::F(d)(Time,Level,c));
00150 ( comm_service::log() << "\n").flush();
00151 #endif
00152 }
00153 }
00154
00155 virtual void Correction(const int Time, const int WTime, const int Level, const double t, const double dt) {
00156 int t_sten = 0;
00157 int s_sten = 1;
00158 vec_grid_fct_type uh(GFName, t_sten, s_sten, CurrentTime(base::GH(),Level), Level,
00159 base::GH(), DAGHCellCentered, 0, 1, DAGHCommSimple,
00160 DAGHNoBoundary, DAGHNoAdaptBoundary, DAGHNoExternalGhost);
00161
00162 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00163 ( comm_service::log() << "\n*********** Conservative Fixup ***********\n").flush();
00164 #endif
00165
00166 for (int d=0; d<2*dim; d++)
00167 ParallelFixup(Time, Level, d, uh);
00168 }
00169
00170 inline void SetGridFunctions(vec_grid_fct_type* u) { _u = u; }
00171 inline vec_grid_fct_type& U() { return *_u; }
00172 inline const vec_grid_fct_type& U() const { return *_u; }
00173
00174 protected:
00175 int ValidSide(const int Time, const int Level, const int c, const int s) const {
00176 return (U().has_adaptiveboundary(Time,Level,c,s));
00177 }
00178
00179 void ParallelFixup(const int Time, const int Level,
00180 const int d, vec_grid_fct_type& uh) {
00181
00182 int TimeF = CurrentTime(base::GH(),Level+1);
00183 int TimeC = CurrentTime(base::GH(),Level);
00184 const int refinefactor = RefineFactor(base::GH(),Level);
00185 DCoords dx = base::GH().worldStep(U().GF_StepSize(Level));
00186
00187 DataType Fac = 1.0;
00188 for (int dd=0; dd<dim; dd++)
00189 Fac *= dx(dd);
00190
00191 forall (uh,TimeC,Level,c)
00192 uh(TimeC,Level,c) = 0.0;
00193 end_forall
00194
00195 forall (U(),TimeF,Level+1,c)
00196 if (ValidSide(TimeF,Level+1,c,d)) {
00197 BBox to(FixupBBox(coarsen(U().interiorbbox(TimeF,Level+1,c),refinefactor),d));
00198 for (register int j=0; j<U().parents(TimeF,Level+1,c) ; j++) {
00199 BBox wto(coarsen(U().parentbox(TimeF,Level+1,c,j),refinefactor)*to);
00200 const int& idx = U().parentidx(TimeF,Level+1,c,j);
00201 wto *= uh(TimeC,Level,idx).bbox();
00202 if (!wto.empty()) {
00203 copyf_from(uh(TimeC,Level,idx),wto,base::F(d)(TimeF,Level+1,c),d);
00204 uh(TimeC,Level,idx).multiply((d%2==0 ? -1.0 : 1.0) / Fac,wto);
00205 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00206 ( comm_service::log() << "Writing at Side: " << d << " of "
00207 << U().interiorbbox(TimeF,Level+1,c) << " using " << wto << "\n").flush();
00208 base::debug_print(uh(TimeC,Level,idx), wto);
00209 ( comm_service::log() << "\n" ).flush();
00210 #endif
00211 }
00212 }
00213 }
00214 end_forall
00215
00216 END_WATCH_FIXUP_WHOLE
00217 START_WATCH
00218 Sync(uh,TimeC,Level);
00219 END_WATCH_FIXUP_SYNC
00220 START_WATCH
00221
00222 forall (U(),Time,Level,c)
00223 BBox to = U().interiorbbox(Time,Level,c);
00224 BBox from(to);
00225 from.shift(d/2, d%2 ? -1 : 1);
00226 U()(Time,Level,c).plus(uh(TimeC,Level,c), to, from);
00227 end_forall
00228 }
00229
00230 BBox StateVecBBox(const BBox& interior, const int s) {
00231 int d = s/2;
00232 #ifdef DEBUG_PRINT
00233 assert (d>=0 && d<dim);
00234 #endif
00235 BBox bb(interior);
00236 if (s%2 == 0) {
00237 bb.growlower(d,-1);
00238 bb.upper(d) = bb.lower(d);
00239 }
00240 else {
00241 bb.growupper(d,1);
00242 bb.lower(d) = bb.upper(d);
00243 }
00244 return bb;
00245 }
00246
00247 BBox FixupBBox(const BBox& interior, const int s) {
00248 int d = s/2;
00249 #ifdef DEBUG_PRINT
00250 assert (d>=0 && d<dim);
00251 #endif
00252 BBox bb(interior);
00253 if (s%2 == 0)
00254 bb.upper(d) = bb.lower(d);
00255 else
00256 bb.lower(d) = bb.upper(d);
00257 return bb;
00258 }
00259
00260 virtual BBox FluxBBox(const BBox& interior, const int s) {
00261 int d = s/2;
00262 #ifdef DEBUG_PRINT
00263 assert (d>=0 && d<dim);
00264 #endif
00265 BBox bb(interior);
00266 if (s%2 == 0)
00267 bb.upper(d) = bb.lower(d);
00268 else {
00269 bb.growupper(d,1);
00270 bb.lower(d) = bb.upper(d);
00271 }
00272 return bb;
00273 }
00274
00275 protected:
00276 inline void copyf_to(ld_fixup_grid_data_type &target, const BBox &to,
00277 const vec_grid_data_type &source,
00278 const BBox &from, const int s)
00279 { ops::copy_to(target, to, source, from, s); }
00280 inline void copyf_to(ld_fixup_grid_data_type &target,
00281 const vec_grid_data_type &source,
00282 const BBox &where, const int s)
00283 { ops::copy_to(target, source, where, s); }
00284
00285 inline void copyf_from(vec_grid_data_type &target, const BBox &to,
00286 const ld_fixup_grid_data_type &source,
00287 const BBox &from, const int s)
00288 { ops::copy_from(target, to, source, from, s); }
00289 inline void copyf_from(vec_grid_data_type &target, const BBox &where,
00290 const ld_fixup_grid_data_type &source, const int s)
00291 { ops::copy_from(target, where, source, s); }
00292
00293 inline void addf_to(ld_fixup_grid_data_type &target, const BBox &to,
00294 const vec_grid_data_type &source,
00295 const BBox &from, const int s)
00296 { ops::add_to(target, to, source, from, s); }
00297 inline void addf_to(ld_fixup_grid_data_type &target,
00298 const vec_grid_data_type &source,
00299 const BBox &where, const int s)
00300 { ops::add_to(target, source, where, s); }
00301
00302 inline void addf_from(vec_grid_data_type &target, const BBox &to,
00303 const ld_fixup_grid_data_type &source,
00304 const BBox &from, const int s)
00305 { ops::add_from(target, to, source, from, s); }
00306 inline void addf_from(vec_grid_data_type &target, const BBox &where,
00307 const ld_fixup_grid_data_type &source, const int s)
00308 { ops::add_from(target, where, source, s); }
00309
00310 inline void addf_to(ld_fixup_grid_data_type &target, const BBox &to,
00311 const ld_vec_grid_data_type &source,
00312 const BBox &from)
00313 { ops::add_to(target, to, source, from); }
00314 inline void addf_to(ld_fixup_grid_data_type &target,
00315 const ld_vec_grid_data_type &source,
00316 const BBox &where)
00317 { ops::add_to(target, source, where); }
00318
00319 protected:
00320 vec_grid_fct_type* _u;
00321 char GFName[DAGHBktGFNameWidth];
00322 };
00323
00324 #endif