00001
00002
00003
00004 #ifndef AMROC_RIM_INTEGRATOR_H
00005 #define AMROC_RIM_INTEGRATOR_H
00006
00011 #include "Integrator.h"
00012
00013 #include <string>
00014
00015 #define f_init_common FORTRAN_NAME(combl, COMBL)
00016
00017 extern "C" {
00018 void f_init_common();
00019 }
00020
00026 template <class VectorType, int dim>
00027 class RIMIntegrator : public Integrator<VectorType,dim> {
00028 typedef typename VectorType::InternalDataType DataType;
00029 typedef Integrator<VectorType,dim> base;
00030
00031 public:
00032 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00033 typedef typename base::vec_grid_data_type vec_grid_data_type;
00034 typedef generic_fortran_func generic_func_type;
00035
00036 typedef void (*check_1_func_type) ( FI(1,VectorType), BI, const INTEGER& meqn,
00037 const INTEGER& mout, INTEGER& result );
00038 typedef void (*check_2_func_type) ( FI(2,VectorType), BI, const INTEGER& meqn,
00039 const INTEGER& mout, INTEGER& result );
00040 typedef void (*check_3_func_type) ( FI(3,VectorType), BI, const INTEGER& meqn,
00041 const INTEGER& mout, INTEGER& result );
00042
00043 typedef void (*step_func_type) (const INTEGER& nx, const INTEGER& ny, const INTEGER& nbc,
00044 const INTEGER& neqn, const DOUBLE& dx,
00045 const DOUBLE& dy, VectorType ux[], VectorType uxold[],
00046 const DOUBLE& dt , DOUBLE& cfl, VectorType fx[], VectorType fy[]);
00047
00048 RIMIntegrator(generic_func_type step) :
00049 base(), f_step(step), f_chk(0),
00050 _order(2), _check(0) {
00051 _name = "";
00052 FluxData = (VectorType*) 0;
00053 }
00054
00055 RIMIntegrator(generic_func_type step, generic_func_type chk) :
00056 base(), f_step(step), f_chk(chk),
00057 _order(2), _check(0) {
00058 _name = "";
00059 FluxData = (VectorType*) 0;
00060 }
00061
00062 ~RIMIntegrator() {
00063 if (FluxData) {
00064 delete [] FluxData;
00065 FluxData = (VectorType*) 0;
00066 }
00067 }
00068
00069 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00070 ControlDevice LocCtrl = Ctrl.getSubDevice(prefix+"RIMIntegrator");
00071 _name = prefix+"RIMIntegrator";
00072 RegisterAt(LocCtrl,"Check",_check);
00073 }
00074 virtual void register_at(ControlDevice& Ctrl) {
00075 register_at(Ctrl, "");
00076 }
00077
00078 virtual void SetupData(GridHierarchy* gh, const int& ghosts) {
00079 base::SetupData(gh,ghosts);
00080 base::SetMaxIntegratorPasses(NMaxPass());
00081 base::_abort = (NCheck()>=10 ? DAGHTrue : DAGHFalse);
00082 f_init_common();
00083 }
00084
00085 virtual double CalculateGrid(vec_grid_data_type& NewStateVec,
00086 vec_grid_data_type& OldStateVec,
00087 vec_grid_data_type* Flux[],
00088 const int& level, const double& t,
00089 const double& dt, const int& mpass) {
00090 double cfl = 0.0;
00091
00092 int mx[DIM], d, per[DIM];
00093 Coords ex = NewStateVec.extents();
00094 for (d=0; d<DIM; d++) {
00095 mx[d] = ex(d)-2*base::NGhosts();
00096 per[d] = base::GH().periodicboundary(d);
00097 }
00098 DCoords dx = base::GH().worldStep(NewStateVec.stepsize());
00099 DCoords lbc = base::GH().worldCoords(NewStateVec.lower(), NewStateVec.stepsize());
00100 DCoords ubc = base::GH().worldCoords(NewStateVec.upper(), NewStateVec.stepsize());
00101
00102 if (NCheck()>0)
00103 base::CheckGrid(OldStateVec, level, OldStateVec.bbox(), t, "CalculateGrid::before f_step");
00104
00105
00106 ((step_func_type) f_step)(mx[0],mx[1],base::NGhosts(),base::NEquations(),
00107 dx(0),dx(1),NewStateVec.data(),OldStateVec.data(),
00108 dt,cfl,Flux[0]->data(),Flux[2]->data());
00109
00110 if (NCheck()>=0)
00111
00112 if (ControlGrid(NewStateVec,level,NewStateVec.bbox(),t,0)==0 || !(cfl>0)) {
00113 ResetGridFluxes(Flux);
00114 NewStateVec.copy(OldStateVec);
00115 if (cfl>0) cfl = std::max(cfl, 2.0);
00116 return cfl;
00117 }
00118
00119 if (NCheck()%10>1)
00120 base::CheckGrid(NewStateVec, level, NewStateVec.bbox(), t, "CalculateGrid::after f_step");
00121
00122 return cfl;
00123 }
00124
00125 virtual void AllocGridFluxes(const BBox &bb, vec_grid_data_type**& Flux) {
00126
00127
00128 FluxData = new VectorType[base::Dim()*bb.size()];
00129 Flux = new vec_grid_data_type* [2*base::Dim()];
00130 for (register int d=0; d<base::Dim(); d++) {
00131 Flux[2*d] = new vec_grid_data_type(bb,&(FluxData[d*bb.size()]));
00132 Flux[2*d+1] = Flux[2*d];
00133 }
00134 }
00135
00136 virtual void DeAllocGridFluxes(vec_grid_data_type**& Flux) {
00137 if (Flux) {
00138 VectorType* dummy;
00139 for (register int d=0; d<base::Dim(); d++)
00140 if (Flux[2*d]) {
00141
00142 Flux[2*d]->deallocate(dummy);
00143 delete Flux[2*d];
00144 }
00145 delete [] Flux;
00146 }
00147 if (FluxData) {
00148 delete [] FluxData;
00149 FluxData = (VectorType*) 0;
00150 }
00151 }
00152
00153 virtual void ResetGridFluxes(vec_grid_data_type**& Flux) {
00154 if (Flux) {
00155 VectorType zero(0.0);
00156 for (register int d=0; d<base::Dim(); d++)
00157 if (Flux[2*d])
00158 Flux[2*d]->equals(zero);
00159 }
00160 }
00161
00162 virtual int ControlGrid(vec_grid_data_type& StateVec, const int& level,
00163 const BBox& where, const double& time, const int verbose) {
00164 int result = 1;
00165 if (!f_chk) return result;
00166 if (dim == 1)
00167 ((check_1_func_type) f_chk)(FA(1,StateVec),BOUNDING_BOX(where),base::NEquations(),
00168 verbose,result);
00169 else if (dim == 2)
00170 ((check_2_func_type) f_chk)(FA(2,StateVec),BOUNDING_BOX(where),base::NEquations(),
00171 verbose,result);
00172 else if (dim == 3)
00173 ((check_3_func_type) f_chk)(FA(3,StateVec),BOUNDING_BOX(where),base::NEquations(),
00174 verbose,result);
00175 return result;
00176 }
00177
00178 inline const int& NCheck() const { return _check; }
00179 virtual int NMethodOrder() const { return _order; }
00180 inline int NMaxPass() const { return 0; }
00181
00182 inline void SetCheckFunc(generic_func_type check) { f_chk = check; }
00183 generic_func_type GetCheckFunc() const { return f_chk; }
00184 inline void SetStepFunc(generic_func_type step) { f_step = step; }
00185 generic_func_type GetStepFunc() const { return f_step; }
00186
00187 protected:
00188 generic_func_type f_step, f_chk;
00189 std::string _name;
00190 int _order, _check;
00191 VectorType* FluxData;
00192 };
00193
00194 #endif