00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef AMROC_CLP_INTEGRATORBASE_H
00010 #define AMROC_CLP_INTEGRATORBASE_H
00011
00019 #include "Integrator.h"
00020 #include "Timing.h"
00021 #include "FixupBase.h"
00022
00023 #include <iostream>
00024 #include <string>
00025 #include <cfloat>
00026
00027 #define FACTOR 1.0e5
00028
00029 #define f_init_common FORTRAN_NAME(combl, COMBL)
00030 extern "C" {
00031 void f_init_common();
00032 }
00033
00042 template <class VectorType, class AuxVectorType, int dim>
00043 class ClpIntegratorBase : public Integrator<VectorType,dim> {
00044 typedef typename VectorType::InternalDataType DataType;
00045 typedef Integrator<VectorType,dim> base;
00046 typedef ClpIntegratorBase<VectorType,AuxVectorType,dim> self;
00047
00048 public:
00049 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00050 typedef typename base::vec_grid_data_type vec_grid_data_type;
00051 typedef GridData<VectorType,minus_1<dim>::dim> ld_vec_grid_data_type;
00052 typedef GridData<AuxVectorType,minus_1<dim>::dim> ld_aux_grid_data_type;
00053 typedef generic_fortran_func generic_func_type;
00054
00055 typedef void (*check_1_func_type) ( FI(1,VectorType), BI, const INTEGER& meqn,
00056 const INTEGER& mout, INTEGER& result );
00057 typedef void (*check_2_func_type) ( FI(2,VectorType), BI, const INTEGER& meqn,
00058 const INTEGER& mout, INTEGER& result );
00059 typedef void (*check_3_func_type) ( FI(3,VectorType), BI, const INTEGER& meqn,
00060 const INTEGER& mout, INTEGER& result );
00061
00062 typedef void (*aux_1_func_type) ( const INTEGER& maxmx,
00063 const INTEGER& meqn, const INTEGER& mbc,
00064 const INTEGER& ibx,
00065 const INTEGER& mx, VectorType q[],
00066 DOUBLE aux[], const INTEGER& maux,
00067 const DOUBLE& cornx,
00068 const DOUBLE& dx,
00069 const DOUBLE& t, const DOUBLE& dt );
00070 typedef void (*aux_2_func_type) ( const INTEGER& maxmx, const INTEGER& maxmy,
00071 const INTEGER& meqn, const INTEGER& mbc,
00072 const INTEGER& ibx, const INTEGER& iby,
00073 const INTEGER& mx, const INTEGER& my, VectorType q[],
00074 DOUBLE aux[], const INTEGER& maux,
00075 const DOUBLE& cornx, const DOUBLE& corny,
00076 const DOUBLE& dx, const DOUBLE& dy,
00077 const DOUBLE& t, const DOUBLE& dt );
00078 typedef void (*aux_3_func_type) ( const INTEGER& maxmx, const INTEGER& maxmy, const INTEGER& maxmz,
00079 const INTEGER& meqn, const INTEGER& mbc,
00080 const INTEGER& ibx, const INTEGER& iby, const INTEGER& ibz,
00081 const INTEGER& mx, const INTEGER& my, const INTEGER& mz, VectorType q[],
00082 DOUBLE aux[], const INTEGER& maux,
00083 const DOUBLE& cornx, const DOUBLE& corny, const DOUBLE& cornz,
00084 const DOUBLE& dx, const DOUBLE& dy, const DOUBLE& dz,
00085 const DOUBLE& t, const DOUBLE& dt );
00086
00087 typedef void (*source_1_func_type) ( const INTEGER& maxmx,
00088 const INTEGER& meqn, const INTEGER& mbc,
00089 const INTEGER& ibx,
00090 const INTEGER& mx,
00091 VectorType q[],
00092 const DOUBLE aux[], const INTEGER& maux,
00093 const DOUBLE& t, const DOUBLE& dt, const INTEGER& ibnd );
00094 typedef void (*source_2_func_type) ( const INTEGER& maxmx, const INTEGER& maxmy,
00095 const INTEGER& meqn, const INTEGER& mbc,
00096 const INTEGER& ibx, const INTEGER& iby,
00097 const INTEGER& mx, const INTEGER& my,
00098 VectorType q[],
00099 const DOUBLE aux[], const INTEGER& maux,
00100 const DOUBLE& t, const DOUBLE& dt, const INTEGER& ibnd );
00101 typedef void (*source_3_func_type) ( const INTEGER& maxmx, const INTEGER& maxmy, const INTEGER& maxmz,
00102 const INTEGER& meqn, const INTEGER& mbc,
00103 const INTEGER& ibx, const INTEGER& iby, const INTEGER& ibz,
00104 const INTEGER& mx, const INTEGER& my, const INTEGER& mz,
00105 VectorType q[],
00106 const DOUBLE aux[], const INTEGER& maux,
00107 const DOUBLE& t, const DOUBLE& dt, const INTEGER& ibnd );
00108
00109 ClpIntegratorBase(const int equ, const int wv) :
00110 base(), _EqUsed(equ), _Waves(wv), f_chk(0), f_aux(0), f_src(0)
00111 { ConsInit(); }
00112 ClpIntegratorBase(const int equ, const int wv, generic_func_type check,
00113 generic_func_type aux, generic_func_type source) :
00114 base(), _EqUsed(equ), _Waves(wv), f_chk(check), f_aux(aux), f_src(source)
00115 { ConsInit(); }
00116
00117 void ConsInit() {
00118 limiter = new int[NWaves()];
00119 mthlim = new int[NWaves()];
00120 for (int i=0; i<NWaves(); i++) {
00121 limiter[i] = -1; mthlim[i] = -1;
00122 }
00123 _name = "";
00124 for (int d=0; d<7; d++) method[d] = 0;
00125 }
00126
00127 ~ClpIntegratorBase() {
00128 if (limiter) delete [] limiter;
00129 if (mthlim) delete [] mthlim;
00130 }
00131
00132
00133
00134
00135 virtual void ComputeRP(ld_vec_grid_data_type& LeftState, ld_aux_grid_data_type& auxl,
00136 ld_vec_grid_data_type& RightState, ld_aux_grid_data_type& auxr,
00137 ld_vec_grid_data_type& NewState, const int& direction) = 0;
00138 virtual double ComputeGrid(vec_grid_data_type& StateVec,
00139 vec_grid_data_type* Flux[], DataType* aux,
00140 const double& t, const double& dt, const int& mpass) = 0;
00141
00142
00143 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00144 ControlDevice LocCtrl = Ctrl.getSubDevice(prefix+"ClawpackIntegrator");
00145 _name = prefix+"ClawpackIntegrator";
00146 char MethodName[16];
00147 register int d;
00148 for (d=0; d<7; d++) {
00149 sprintf(MethodName,"Method(%d)",d+1);
00150 RegisterAt(LocCtrl,MethodName,method[d]);
00151 }
00152 char LimiterName[16];
00153 for (d=0; d<NWaves(); d++) {
00154 sprintf(LimiterName,"Limiter(%d)",d+1);
00155 RegisterAt(LocCtrl,LimiterName,limiter[d]);
00156 }
00157 }
00158 virtual void register_at(ControlDevice& Ctrl) {
00159 register_at(Ctrl, "");
00160 }
00161
00162 virtual void SetupData(GridHierarchy* gh, const int& ghosts) {
00163 for (int i=0; i<NWaves(); i++)
00164 if (limiter[i] > 0) mthlim[i] = limiter[i];
00165 else mthlim[i] = limiter[0];
00166 if (NAux()!=0 && NAux()!=AuxVectorType::Length())
00167 method[6] = 0;
00168 base::SetMaxIntegratorPasses(NMaxPass());
00169 base::_abort = (NCheck()>=10 ? DAGHTrue : DAGHFalse);
00170 f_init_common();
00171 base::SetupData(gh,ghosts);
00172 }
00173
00174 virtual void finish() {
00175 if (limiter) {
00176 delete [] limiter;
00177 limiter = (int *) 0;
00178 }
00179 if (mthlim) {
00180 delete [] mthlim;
00181 mthlim = (int *) 0;
00182 }
00183 base::finish();
00184 }
00185
00186 void CalculateRP(ld_vec_grid_data_type &LeftState, BBox& bbl, double tl, double dtl,
00187 ld_vec_grid_data_type &RightState, BBox& bbr, double tr, double dtr,
00188 ld_vec_grid_data_type &NewState, const int& direction) {
00189
00190
00191
00192
00193 vec_grid_data_type left(bbl, LeftState.data());
00194 vec_grid_data_type right(bbr, RightState.data());
00195 AllocError::SetTexts("ClpIntegrator","calculate_Riemann_Problem(): aux arrays");
00196 DataType* auxldata = new DataType[LeftState.bbox().size()*NAux()];
00197 DataType* auxrdata = new DataType[RightState.bbox().size()*NAux()];
00198
00199
00200 if (NAux()>0) {
00201 SetAux(auxldata,left,tl,dtl);
00202 SetAux(auxrdata,right,tr,dtr);
00203 }
00204
00205
00206 START_INTERMEDIATE_WATCH
00207 START_WATCH
00208 if (NSrc() > 0) {
00209
00210 int srcbnd = 1;
00211 if (tl < tr) {
00212 SetSrc(auxldata,left,tl,tr-tl,srcbnd);
00213 tl += tr-tl;
00214 }
00215 if (tl > tr) {
00216 SetSrc(auxrdata,right,tr,tl-tr,srcbnd);
00217 tr += tl-tr;
00218 }
00219
00220 if (NSrc() > 1) {
00221 double dt = Min(dtl,dtr);
00222 if (NSrc()==2) {
00223 SetSrc(auxldata,left,tl,dt/2.0,srcbnd);
00224 SetSrc(auxrdata,right,tr,dt/2.0,srcbnd);
00225 }
00226 if (NSrc()==3) {
00227 SetSrc(auxldata,left,tl,dt,srcbnd);
00228 SetSrc(auxrdata,right,tr,dt,srcbnd);
00229 }
00230 if (NAux()>0) {
00231 SetAux(auxldata,left,tl,dtl);
00232 SetAux(auxrdata,right,tr,dtr);
00233 }
00234 }
00235 }
00236 END_WATCH_SOURCE_INTEGRATION
00237 END_INTERMEDIATE_WATCH
00238 VectorType* data_dummy;
00239 left.deallocate(data_dummy);
00240 right.deallocate(data_dummy);
00241 ld_aux_grid_data_type auxl(LeftState.bbox(), (AuxVectorType*) auxldata);
00242 ld_aux_grid_data_type auxr(RightState.bbox(), (AuxVectorType*) auxrdata);
00243
00244
00245 ComputeRP(LeftState, auxl, RightState, auxr, NewState, direction);
00246
00247 AuxVectorType* aux_data_dummy;
00248 auxl.deallocate(aux_data_dummy);
00249 auxr.deallocate(aux_data_dummy);
00250 delete [] auxldata; delete [] auxrdata;
00251 }
00252
00253 virtual double CalculateGrid(vec_grid_data_type& NewStateVec,
00254 vec_grid_data_type& OldStateVec,
00255 vec_grid_data_type* Flux[],
00256 const int& level, const double& t,
00257 const double& dt, const int& mpass) {
00258
00259 double cfl = 0.0;
00260 #ifdef DEBUG_PRINT_INTEGRATOR
00261 ( comm_service::log() << "on: " << OldStateVec.bbox() ).flush();
00262 #endif
00263
00264 if (NMaxPass()==0 || mpass==1)
00265 NewStateVec.copy(OldStateVec);
00266
00267 if (dt >= DBL_EPSILON*FACTOR) {
00268 AllocError::SetTexts("ClpIntegrator","calculate_time_step(): aux");
00269 DataType* aux = new DataType[OldStateVec.bbox().size()*NAux()];
00270 if (NAux() > 0) SetAux(aux,NewStateVec,t,dt);
00271
00272 #ifdef DEBUG_AMR
00273 if (NCheck()%10>1 && (NSrc()==2 || NSrc()==3))
00274 base::CheckGrid(NewStateVec, level, NewStateVec.bbox(), t, "CalculateGrid::before SrcInt");
00275 #endif
00276
00277
00278
00279 START_INTERMEDIATE_WATCH
00280 START_WATCH
00281 if (NSrc()>1 && (NMaxPass()==0 || mpass==1)) {
00282 int srcbnd = 1;
00283 if (NSrc()==2) SetSrc(aux,NewStateVec,t,dt/2.0,srcbnd);
00284 if (NSrc()==3) SetSrc(aux,NewStateVec,t,dt,srcbnd);
00285 if (NAux()>0) SetAux(aux,NewStateVec,t,dt);
00286 if (NCheck()>=0) if (ControlGrid(NewStateVec,level,NewStateVec.bbox(),t,0)==0) {
00287 ResetGrid(NewStateVec,OldStateVec,Flux,cfl,level,t,mpass);
00288 delete [] aux;
00289 if (cfl>0) cfl = std::max(cfl, 2.0);
00290 return cfl;
00291 }
00292 }
00293 END_WATCH_SOURCE_INTEGRATION
00294 END_INTERMEDIATE_WATCH
00295
00296 if (NCheck()>0 && (NMaxPass()==0 || mpass==1))
00297 base::CheckGrid(NewStateVec, level, NewStateVec.bbox(), t, "CalculateGrid::before f_step");
00298
00299
00300 cfl = ComputeGrid(NewStateVec, Flux, aux, t, dt, mpass);
00301
00302 if (NCheck()>=0)
00303
00304 if (ControlGrid(NewStateVec,level,NewStateVec.bbox(),t,0)==0 || !(cfl>0)) {
00305 ResetGrid(NewStateVec,OldStateVec,Flux,cfl,level,t,mpass);
00306 delete [] aux;
00307 if (cfl>0) cfl = std::max(cfl, 2.0);
00308 return cfl;
00309 }
00310
00311 #ifdef DEBUG_AMR
00312 if (NCheck()%10>1 && (NMaxPass()==0 || mpass==NMaxPass()))
00313 base::CheckGrid(NewStateVec, level, NewStateVec.bbox(), t, "CalculateGrid::after f_step");
00314 #endif
00315
00316
00317
00318 START_INTERMEDIATE_WATCH
00319 START_WATCH
00320 if (NSrc()>0 && NSrc()<3 && (NMaxPass()==0 || mpass==NMaxPass())) {
00321 int srcbnd = 0;
00322 if (NAux()>0) SetAux(aux,NewStateVec,t,dt);
00323 if (NSrc()==2) SetSrc(aux, NewStateVec, t+dt/2.0, dt/2.0, srcbnd);
00324 if (NSrc()==1) SetSrc(aux, NewStateVec, t, dt, srcbnd);
00325 if (NCheck()>=0) if (ControlGrid(NewStateVec,level,NewStateVec.bbox(),t,0)==0) {
00326 ResetGrid(NewStateVec,OldStateVec,Flux,cfl,level,t,mpass);
00327 delete [] aux;
00328 if (cfl>0) cfl = std::max(cfl, 2.0);
00329 return cfl;
00330 }
00331 }
00332 END_WATCH_SOURCE_INTEGRATION
00333 END_INTERMEDIATE_WATCH
00334
00335 #ifdef DEBUG_AMR
00336 if (NCheck()%10>1 && (NSrc()==2 || NSrc()==1) && (mpass==0 || mpass==NMaxPass()))
00337 base::CheckGrid(NewStateVec, level, NewStateVec.bbox(), t, "CalculateGrid::after SrcInt");
00338 #endif
00339
00340 delete [] aux;
00341 }
00342 else {
00343 VectorType zero(0.0);
00344 for (int d=0; d<dim; d++)
00345 Flux[d]->equals(zero);
00346 #ifdef DEBUG_PRINT_INTEGRATOR
00347 ( comm_service::log() << "dt < eps*1.0e5 " ).flush();
00348 #endif
00349 }
00350
00351 #ifdef DEBUG_PRINT_INTEGRATOR
00352 ( comm_service::log() << " CFL = " << cfl <<
00353 " t = " << t << " dt = " << dt << "\n" ).flush();
00354 #endif
00355
00356 return cfl;
00357 }
00358
00359 virtual void AllocGridFluxes(const BBox &bb, vec_grid_data_type**& Flux) {
00360 Flux = new vec_grid_data_type* [2*base::Dim()];
00361 for (register int d=0; d<2*base::Dim(); d++)
00362 Flux[d] = new vec_grid_data_type(bb);
00363 }
00364
00365 virtual void DeAllocGridFluxes(vec_grid_data_type**& Flux) {
00366 if (Flux) {
00367 for (register int d=0; d<2*base::Dim(); d++)
00368 if (Flux[d]) delete Flux[d];
00369 delete [] Flux;
00370 }
00371 }
00372
00373 virtual void ResetGridFluxes(vec_grid_data_type**& Flux) {
00374 if (Flux) {
00375 VectorType zero(0.0);
00376 for (register int d=0; d<2*base::Dim(); d++)
00377 if (Flux[d])
00378 Flux[d]->equals(zero);
00379 }
00380 }
00381
00382 virtual int ControlGrid(vec_grid_data_type& StateVec, const int& level,
00383 const BBox& where, const double& time, const int verbose) {
00384 int result = 1;
00385 if (!f_chk) return result;
00386 if (dim == 1)
00387 ((check_1_func_type) f_chk)(FA(1,StateVec),BOUNDING_BOX(where),base::NEquations(),
00388 verbose,result);
00389 else if (dim == 2)
00390 ((check_2_func_type) f_chk)(FA(2,StateVec),BOUNDING_BOX(where),base::NEquations(),
00391 verbose,result);
00392 else if (dim == 3)
00393 ((check_3_func_type) f_chk)(FA(3,StateVec),BOUNDING_BOX(where),base::NEquations(),
00394 verbose,result);
00395 return result;
00396 }
00397
00398 void ResetGrid(vec_grid_data_type& StateVec, vec_grid_data_type& RecoverStateVec,
00399 vec_grid_data_type* Flux[], double& cfl, const int& level,
00400 const double& t, const int& mpass) {
00401 ResetGridFluxes(Flux);
00402 StateVec.copy(RecoverStateVec);
00403 if (cfl>0) cfl = std::max(cfl, 2.0);
00404
00405 #ifdef DEBUG_PRINT
00406 ( comm_service::log() << "Data in " << StateVec.bbox()
00407 << " recovered (Level " << level << " Time = " << t << " mpass = "
00408 << mpass << "). Using CFL=" << cfl << "." << std::endl ).flush();
00409 #endif
00410 }
00411
00412 void SetAux(DataType* aux, vec_grid_data_type& StateVec, const double& t, const double& dt) {
00413 if (NAux() <=0 || !f_aux) return;
00414 DCoords dx = base::GH().worldStep(StateVec.stepsize());
00415 DCoords lbcorner = base::GH().worldCoords(StateVec.lower(),StateVec.stepsize());
00416 int mx[3], ibx[3];
00417 DimExtBBox(StateVec.bbox(), mx, ibx);
00418 if (dim == 1)
00419 ((aux_1_func_type) f_aux)(AA(1,mx),base::NEquations(),base::NGhosts(),AA(1,ibx),AA(1,mx),
00420 StateVec.data(),aux,NAux(),AA(1,lbcorner()),AA(1,dx()),t,dt);
00421 else if (dim == 2)
00422 ((aux_2_func_type) f_aux)(AA(2,mx),base::NEquations(),base::NGhosts(),AA(2,ibx),AA(2,mx),
00423 StateVec.data(),aux,NAux(),AA(2,lbcorner()),AA(2,dx()),t,dt);
00424 else if (dim == 3)
00425 ((aux_3_func_type) f_aux)(AA(3,mx),base::NEquations(),base::NGhosts(),AA(3,ibx),AA(3,mx),
00426 StateVec.data(),aux,NAux(),AA(3,lbcorner()),AA(3,dx()),t,dt);
00427 }
00428
00429 virtual void SetSrc(DataType* aux, vec_grid_data_type& StateVec, const double t,
00430 const double dt, const int& bnd) {
00431 if (NSrc() <=0 || !f_src) return;
00432 DCoords dx = base::GH().worldStep(StateVec.stepsize());
00433 DCoords lbcorner = base::GH().worldCoords(StateVec.lower(),StateVec.stepsize());
00434 int mx[3], ibx[3];
00435 DimExtBBox(StateVec.bbox(), mx, ibx);
00436 if (dim == 1)
00437 ((source_1_func_type) f_src)(AA(1,mx),base::NEquations(),base::NGhosts(),AA(1,ibx),AA(1,mx),
00438 StateVec.data(),aux,NAux(),t,dt,bnd);
00439 else if (dim == 2)
00440 ((source_2_func_type) f_src)(AA(2,mx),base::NEquations(),base::NGhosts(),AA(2,ibx),AA(2,mx),
00441 StateVec.data(),aux,NAux(),t,dt,bnd);
00442 else if (dim == 3)
00443 ((source_3_func_type) f_src)(AA(3,mx),base::NEquations(),base::NGhosts(),AA(3,ibx),AA(3,mx),
00444 StateVec.data(),aux,NAux(),t,dt,bnd);
00445 }
00446
00447 void DimExtBBox(const BBox& bb, int mx[], int ibx[]) {
00448 for (int d=0; d<dim; d++)
00449 if (bb.extents(d)-2*base::NGhosts()<1)
00450 { mx[d] = bb.extents(d); ibx[d] = 0; }
00451 else
00452 { mx[d] = bb.extents(d)-2*base::NGhosts(); ibx[d] = 1; }
00453 }
00454
00455 virtual int NMethodOrder() const { return (std::max(method[1],2)); }
00456 inline const int& NCheck() const { return method[3]; }
00457 inline int NSrc() const { return (method[4]%10); }
00458 inline bool DimSplit() const { return (method[2]<0); }
00459 inline int NMaxPass() const { return (method[2]<-1 && dim>1 ? dim : 0); }
00460 inline const int& NAux() const { return method[6]; }
00461 inline void SetEqUsed(const int& eq) { _EqUsed = eq; }
00462 inline const int& NEqUsed() const { return _EqUsed; }
00463 inline void SetWaves(const int& wv) { _Waves = wv; }
00464 inline const int& NWaves() const { return _Waves; }
00465
00466 inline void SetCheckFunc(generic_func_type check) { f_chk = check; }
00467 generic_func_type GetCheckFunc() const { return f_chk; }
00468 inline void SetAuxFunc(generic_func_type aux) { f_aux = aux; }
00469 generic_func_type GetAuxFunc() const { return f_aux; }
00470 inline void SetSrcFunc(generic_func_type src) { f_src = src; }
00471 generic_func_type GetSrcFunc() const { return f_src; }
00472
00473 std::ostream& debug(std::ostream& out, const self& P) {
00474 out << "ClpIntegrator registered at " << P._name << "\n";
00475 out << " Methods:";
00476 for (int i=0; i<7; i++)
00477 out << " " << P.method[i];
00478 out << " Limiter:";
00479 for (int j=0; j<P.NWaves(); j++)
00480 out << " " << P.limiter[j];
00481 out << "\n";
00482 return out;
00483 }
00484
00485 protected:
00486 int _EqUsed, _Waves;
00487 int method[7];
00488 int *limiter, *mthlim;
00489 std::string _name;
00490 generic_func_type f_chk, f_aux, f_src;
00491 int order;
00492 };
00493
00494
00495 template <class VectorType, class AuxVectorType, int dim> class ClpIntegrator;
00496
00497 #endif