00001
00002
00003
00004
00005
00006 #ifndef AMROC_WENO_INTEGRATOR_H
00007 #define AMROC_WENO_INTEGRATOR_H
00008
00016 #include "Integrator.h"
00017 #include "CLESLog.h"
00018
00019 #include <string>
00020
00021 #ifndef f_init_common
00022 #define f_init_common FORTRAN_NAME(combl, COMBL)
00023 #endif
00024
00025 #define f_init_weno FORTRAN_NAME(initweno, INITWENO)
00026 #define f_finish_weno FORTRAN_NAME(finishweno, FINISHWENO)
00027
00028 extern "C" {
00029 void f_init_weno(const INTEGER& dim, const INTEGER& meqn, const INTEGER& nvars,
00030 const INTEGER& mghosts,
00031 const INTEGER& order, const INTEGER& optimized,
00032 const INTEGER& use_carbfix, const INTEGER& method,
00033 const INTEGER& viscous, const INTEGER& les,
00034 const INTEGER& usrc,
00035 const INTEGER& noTimeRefine, const DOUBLE& filter_alpha);
00036 void f_finish_weno();
00037 void f_init_common();
00038 }
00039
00040
00049 template <class VectorType, int dim>
00050 class WENOIntegrator : public Integrator<VectorType,dim> {
00051 typedef typename VectorType::InternalDataType DataType;
00052 typedef Integrator<VectorType,dim> base;
00053
00054 public:
00055 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00056 typedef typename base::vec_grid_data_type vec_grid_data_type;
00057 typedef generic_fortran_func generic_func_type;
00058
00059 typedef int DCFlagDataType;
00060 typedef GridData<DCFlagDataType,dim> flag_grid_data_type;
00061
00062 typedef void (*check_1_func_type) ( FI(1,VectorType), BI, const INTEGER& meqn,
00063 const INTEGER& mout, INTEGER& result );
00064 typedef void (*check_2_func_type) ( FI(2,VectorType), BI, const INTEGER& meqn,
00065 const INTEGER& mout, INTEGER& result );
00066 typedef void (*check_3_func_type) ( FI(3,VectorType), BI, const INTEGER& meqn,
00067 const INTEGER& mout, INTEGER& result );
00068
00069 typedef void (*step_func_type) (const INTEGER& rk, VectorType ux[],
00070 VectorType uxold[], const DOUBLE& dt ,
00071 DOUBLE& cfl, VectorType fxi[],
00072 INTEGER dcflag[], INTEGER& iFilter);
00073 typedef void (*bnds_func_type) (INTEGER ix[], DOUBLE lbc[], DOUBLE ubc[],
00074 DOUBLE dx[], const DOUBLE* bnd,
00075 const INTEGER& mb, const INTEGER per[]);
00076
00077 WENOIntegrator(generic_func_type step, generic_func_type bnds, generic_func_type check) :
00078 base(), f_step(step), f_bnds(bnds), f_chk(check),
00079 _order(2), _optimized(0), _use_carbfix(1), _method(0),
00080 _visc(0), _les(0),_usrc(0), _check(0), _DCFlagAdaptBndry(1),
00081 _noTimeRefine(0), _FilterStep(-1), _FilterStrength(0.0)
00082 {
00083 _name = "";
00084 FluxData = (VectorType*) 0;
00085 }
00086
00087 ~WENOIntegrator() {
00088 if (FluxData) {
00089 delete [] FluxData;
00090 FluxData = (VectorType*) 0;
00091 }
00092 }
00093
00094 virtual double PassTimeStepFraction(int mpass) {
00095 switch ( mpass ) {
00096 case 1:
00097 return 0.0;
00098 case 2:
00099 return 1.0;
00100 case 3:
00101 return 0.5;
00102 default:
00103 return 0.0;
00104 }
00105 }
00106
00107 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00108 ControlDevice LocCtrl = Ctrl.getSubDevice(prefix+"WENOIntegrator");
00109 _name = prefix+"WENOIntegrator";
00110 RegisterAt(LocCtrl,"Order",_order);
00111 RegisterAt(LocCtrl,"Optimized",_optimized);
00112 RegisterAt(LocCtrl,"CarbuncleFix",_use_carbfix);
00113 RegisterAt(LocCtrl,"Method",_method);
00114 RegisterAt(LocCtrl,"UseViscous",_visc);
00115 RegisterAt(LocCtrl,"UseLES",_les);
00116 RegisterAt(LocCtrl,"UseSource",_usrc);
00117 RegisterAt(LocCtrl,"Check",_check);
00118 RegisterAt(LocCtrl,"DCFlagAdaptBndry",_DCFlagAdaptBndry);
00119
00120 RegisterAt(LocCtrl,"FilterStep",_FilterStep);
00121 RegisterAt(LocCtrl,"FilterStrength",_FilterStrength);
00122
00123 log.register_at(LocCtrl, "");
00124 }
00125 virtual void register_at(ControlDevice& Ctrl) {
00126 register_at(Ctrl, "");
00127 }
00128
00129 virtual void SetupData(GridHierarchy* gh, const int& ghosts) {
00130 base::SetupData(gh,ghosts);
00131 base::SetMaxIntegratorPasses(NMaxPass());
00132 base::_abort = (NCheck()>=10 ? DAGHTrue : DAGHFalse);
00133 int _dim = dim;
00134
00135 log.initialize();
00136
00137 f_init_weno(_dim, base::NEquations(), NVARS, base::NGhosts(),
00138 _order, _optimized, _use_carbfix, _method, _visc, _les,
00139 _usrc, _noTimeRefine, _FilterStrength);
00140 f_init_common();
00141 }
00142
00143 virtual void finish() { f_finish_weno(); log.finalize(); }
00144
00145 virtual double CalculateGrid(vec_grid_data_type& NewStateVec,
00146 vec_grid_data_type& OldStateVec,
00147 vec_grid_data_type* Flux[],
00148 const int& level, const double& t,
00149 const double& dt, const int& mpass) {
00150 double cfl = 0.0;
00151 #ifdef DEBUG_PRINT_INTEGRATOR
00152 ( comm_service::log() << "on: " << OldStateVec.bbox() ).flush();
00153 #endif
00154
00155 if (mpass==1 || mpass==0) NewStateVec.copy(OldStateVec);
00156
00157 int mx[dim], d, per[dim];
00158 Coords ex = NewStateVec.extents();
00159 for (d=0; d<dim; d++) {
00160 mx[d] = ex(d)-2*base::NGhosts();
00161 per[d] = base::GH().periodicboundary(d);
00162 }
00163
00164 flag_grid_data_type** DCFlag;
00165 DCFlagDataType* DCFlagData;
00166 AllocDCFlag(NewStateVec.bbox(), DCFlag, DCFlagData);
00167 if (mpass==1 || mpass==0) SetDCFlag(NewStateVec.bbox(), DCFlag, level);
00168
00169 DCoords dx = base::GH().worldStep(NewStateVec.stepsize());
00170 DCoords lbc = base::GH().worldCoords(NewStateVec.lower(), NewStateVec.stepsize());
00171 DCoords ubc = base::GH().worldCoords(NewStateVec.upper(), NewStateVec.stepsize());
00172
00173 ((bnds_func_type) f_bnds)(mx,lbc(),ubc(),dx(),base::GH().wholebndry(),
00174 base::GH().nbndry(),per);
00175
00176 if (NCheck()>0 && (mpass==1 || mpass==0))
00177 base::CheckGrid(NewStateVec, level, NewStateVec.bbox(), t, "CalculateGrid::before f_step");
00178
00179 int iFilter = 0;
00180 int Time = CurrentTime(base::GH(), 0 );
00181 if ( _FilterStep>0 && Time%(_FilterStep*StepSize(base::GH(),0)) == 0 ) iFilter = 1;
00182
00183
00184 ((step_func_type) f_step)(mpass,NewStateVec.data(),OldStateVec.data(),
00185 dt,cfl,Flux[0]->data(),DCFlag[0]->data(),iFilter);
00186
00187 if (NCheck()>=0)
00188
00189 if (ControlGrid(NewStateVec,level,NewStateVec.bbox(),t,0)==0 || !(cfl>=0) ||
00190 (!(cfl>0) && (mpass==NMaxPass()))) {
00191 ResetGridFluxes(Flux);
00192 NewStateVec.copy(OldStateVec);
00193 if (cfl>0) cfl = std::max(cfl, 2.0);
00194 }
00195
00196 DeAllocDCFlag(DCFlag,DCFlagData);
00197
00198 #ifdef DEBUG_PRINT_INTEGRATOR
00199 ( comm_service::log() << " CFL = " << cfl <<
00200 " t = " << t << " dt = " << dt << "\n" ).flush();
00201 #endif
00202
00203 return cfl;
00204 }
00205
00206 void SetDCFlag(const BBox &databbox, flag_grid_data_type** DCFlag, const int& l) {
00207 int d;
00208 for (d=0; d<dim; d++) DCFlag[d]->equals(0);
00209
00210 if ( _DCFlagAdaptBndry==0 ) return;
00211
00212 BBox interiorbbox = grow(databbox, -base::NGhosts());
00213
00214
00215 if (base::U().prolongbndrylevel(l)!=0 ) {
00216 for (int s=0; s<2*dim; s++) {
00217 d = s/2;
00218 BBox localbbndry(interiorbbox);
00219 if (s%2 == 0) {
00220 localbbndry.growlower(d,-1);
00221 localbbndry.upper(d) = localbbndry.lower(d);
00222 }
00223 else {
00224 localbbndry.growupper(d,1);
00225 localbbndry.lower(d) = localbbndry.upper(d);
00226 }
00227 BBoxList localbndrylist = *base::U().prolongbndrylevel(l);
00228 localbndrylist *= localbbndry;
00229 for (register BBox* bb=localbndrylist.first();bb;
00230 bb=localbndrylist.next()) {
00231 if (s%2 == 0) {
00232 bb->lower(d) += bb->stepsize(d);
00233 bb->upper(d) = bb->lower(d);
00234 }
00235 DCFlag[d]->equals((-1+2*(s%2)),*bb);
00236 }
00237 }
00238 }
00239
00240 if ( _DCFlagAdaptBndry==1 ) return;
00241
00242
00243 if ( l < FineLevel(base::GH()) ) {
00244 int by = StepSize(base::GH(),l)/StepSize(base::GH(),l+1);
00245 #ifdef _DEBUG_DCFLAG
00246 printf("\nGhost cells %d\n", base::NGhosts());
00247 printf("father(%d) (%d %d) (%d %d) [%d %d]\n",l,
00248 interiorbbox.lower(0), interiorbbox.upper(0),
00249 interiorbbox.lower(1), interiorbbox.upper(1),
00250 interiorbbox.stepsize(0), interiorbbox.stepsize(1));
00251 #endif
00252 GridBoxList* gbchild = base::GH().ggbl(l+1);
00253 if ( gbchild )
00254 for (register GridBox *g=gbchild->first();g;g=gbchild->next())
00255 {
00256
00257 BBox bb(g->gbBBox());
00258 bb.coarsen(by);
00259 #ifdef _DEBUG_DCFLAG
00260 printf("child(%d) (%d %d) (%d %d) [%d %d]\n",l+1,
00261 bb.lower(0), bb.upper(0),
00262 bb.lower(1), bb.upper(1),
00263 bb.stepsize(0), bb.stepsize(1));
00264 #endif
00265
00266 for (int s=0; s<2*dim; s++) {
00267 d = s/2;
00268 BBox localbbndry(bb);
00269 if (s%2 == 0) {
00270 localbbndry.growlower(d,-1);
00271 localbbndry.upper(d) = localbbndry.lower(d);
00272 }
00273 else {
00274 localbbndry.growupper(d,1);
00275 localbbndry.lower(d) = localbbndry.upper(d);
00276 }
00277 #ifdef _DEBUG_DCFLAG
00278 printf("to intersect[%d] (%d %d) (%d %d) [%d %d]\n", s,
00279 localbbndry.lower(0), localbbndry.upper(0),
00280 localbbndry.lower(1), localbbndry.upper(1),
00281 localbbndry.stepsize(0), localbbndry.stepsize(1));
00282 #endif
00283 localbbndry *= interiorbbox;
00284 if ( ! localbbndry.empty() ) {
00285 if ( s%2 == 0 ) {
00286 localbbndry.growlower(d,1);
00287 localbbndry.upper(d) = localbbndry.lower(d);
00288 }
00289 #ifdef _DEBUG_DCFLAG
00290 printf("intersection (%d %d) (%d %d) [%d %d]\n",
00291 localbbndry.lower(0), localbbndry.upper(0),
00292 localbbndry.lower(1), localbbndry.upper(1),
00293 localbbndry.stepsize(0), localbbndry.stepsize(1));
00294 #endif
00295
00296 DCFlag[d]->equals((1-2*(s%2)),localbbndry);
00297 }
00298 }
00299 }
00300 }
00301 }
00302
00303 void AllocDCFlag(const BBox &databbox, flag_grid_data_type**& DCFlag,
00304 DCFlagDataType*& DCFlagData) {
00305 BBox fluxbbox = grow(databbox, -base::NGhosts());
00306 fluxbbox.growupper(1);
00307
00308 DCFlagData = new DCFlagDataType[base::Dim()*fluxbbox.size()];
00309 DCFlag = new flag_grid_data_type* [base::Dim()];
00310 for (register int d=0; d<base::Dim(); d++)
00311 DCFlag[d] = new flag_grid_data_type(fluxbbox,&(DCFlagData[d*fluxbbox.size()]));
00312 }
00313
00314 void DeAllocDCFlag(flag_grid_data_type**& DCFlag, DCFlagDataType*& DCFlagData) {
00315 if (DCFlag) {
00316 DCFlagDataType* dummy;
00317 for (register int d=0; d<base::Dim(); d++)
00318 if (DCFlag[d]) {
00319
00320 DCFlag[d]->deallocate(dummy);
00321 delete DCFlag[d];
00322 }
00323 delete [] DCFlag;
00324 }
00325 if (DCFlagData) {
00326 delete [] DCFlagData;
00327 DCFlagData = (DCFlagDataType*) 0;
00328 }
00329 }
00330
00331 virtual void AllocGridFluxes(const BBox &bb, vec_grid_data_type**& Flux) {
00332
00333
00334 FluxData = new VectorType[base::Dim()*bb.size()];
00335 Flux = new vec_grid_data_type* [2*base::Dim()];
00336 for (register int d=0; d<base::Dim(); d++) {
00337 Flux[2*d] = new vec_grid_data_type(bb,&(FluxData[d*bb.size()]));
00338 Flux[2*d+1] = Flux[2*d];
00339 }
00340 }
00341
00342 virtual void DeAllocGridFluxes(vec_grid_data_type**& Flux) {
00343 if (Flux) {
00344 VectorType* dummy;
00345 for (register int d=0; d<base::Dim(); d++)
00346 if (Flux[2*d]) {
00347
00348 Flux[2*d]->deallocate(dummy);
00349 delete Flux[2*d];
00350 }
00351 delete [] Flux;
00352 }
00353 if (FluxData) {
00354 delete [] FluxData;
00355 FluxData = (VectorType*) 0;
00356 }
00357 }
00358
00359 virtual void ResetGridFluxes(vec_grid_data_type**& Flux) {
00360 if (Flux) {
00361 VectorType zero(0.0);
00362 for (register int d=0; d<base::Dim(); d++)
00363 if (Flux[2*d])
00364 Flux[2*d]->equals(zero);
00365 }
00366 }
00367
00368 virtual int ControlGrid(vec_grid_data_type& StateVec, const int& level,
00369 const BBox& where, const double& time, const int verbose) {
00370 int result = 1;
00371 if (!f_chk) return result;
00372 if (dim == 1)
00373 ((check_1_func_type) f_chk)(FA(1,StateVec),BOUNDING_BOX(where),base::NEquations(),
00374 verbose,result);
00375 else if (dim == 2)
00376 ((check_2_func_type) f_chk)(FA(2,StateVec),BOUNDING_BOX(where),base::NEquations(),
00377 verbose,result);
00378 else if (dim == 3)
00379 ((check_3_func_type) f_chk)(FA(3,StateVec),BOUNDING_BOX(where),base::NEquations(),
00380 verbose,result);
00381 return result;
00382 }
00383
00384 inline const int& NCheck() const { return _check; }
00385 virtual int NMethodOrder() const { return _order; }
00386 inline int NMaxPass() const { return 3; }
00387 virtual void SetNoTimeRefine(int flag) { _noTimeRefine = flag; }
00388
00389 inline void SetCheckFunc(generic_func_type check) { f_chk = check; }
00390 generic_func_type GetCheckFunc() const { return f_chk; }
00391 inline void SetStepFunc(generic_func_type step) { f_step = step; }
00392 generic_func_type GetStepFunc() const { return f_step; }
00393 inline void SetBndsFunc(generic_func_type bnds) { f_bnds = bnds; }
00394 generic_func_type GetBndsFunc() const { return f_bnds; }
00395
00396 protected:
00397 generic_func_type f_step, f_bnds, f_chk;
00398 std::string _name;
00399 int _order,_optimized, _use_carbfix;
00400 int _method, _visc, _les, _usrc, _check;
00401 int _DCFlagAdaptBndry;
00402 int _noTimeRefine;
00403 VectorType* FluxData;
00404 CLESLog log;
00405 int _FilterStep;
00406 double _FilterStrength;
00407 };
00408
00409
00410
00411 #endif