00001
00002
00003
00004
00005
00006 #ifndef AMROC_CLP_FIXUP_H
00007 #define AMROC_CLP_FIXUP_H
00008
00016 #include "AMRFixup.h"
00017
00018
00019
00020 #include <iostream>
00021 #include <cstdlib>
00022
00023 template <class VectorType, class AuxVectorType, int dim> class ClpIntegrator;
00024
00031 template <class VectorType, int dim>
00032 class ClpFixupVecOps : private FixupOps<VectorType,VectorType,dim> {
00033 public:
00034 ClpFixupVecOps() {}
00035 protected:
00036 inline void copyv_to(GridData<VectorType,minus_1<dim>::dim> &target,
00037 const GridData<VectorType,dim> &source,
00038 const BBox &where, const int s)
00039 { FixupOps<VectorType,VectorType,dim>::copy_to(target, source, where, s); }
00040 };
00041
00042 #define f_rcflx FORTRAN_NAME(rcflx, RCFLX)
00043 extern "C" {
00044 void f_rcflx(const INTEGER& mflx);
00045 }
00046
00053 template <class VectorType, class FixupType, class AuxVectorType, int dim>
00054 class ClpFixup :
00055 public AMRFixup<VectorType,FixupType,dim>,
00056 public ClpFixupVecOps<VectorType,dim> {
00057
00058 typedef typename VectorType::InternalDataType DataType;
00059 typedef AMRFixup<VectorType,FixupType,dim> base;
00060 typedef ClpFixupVecOps<VectorType,dim> ops;
00061
00062 public:
00063 typedef ClpIntegrator<VectorType,AuxVectorType,dim> integrator_type;
00064 typedef typename base::vec_grid_data_type vec_grid_data_type;
00065 typedef typename base::ld_vec_grid_data_type ld_vec_grid_data_type;
00066
00067 ClpFixup(integrator_type& integ) : base(), _Integrator(integ) {}
00068
00069 protected:
00070 void CorrectFirstOrder(const int Time, const int Level, const int c,
00071 const double tc, const double tf,
00072 const double dt, const int& mdim) {
00073
00074 int TimeC = CurrentTime(base::GH(),Level-1);
00075 DCoords dx = base::GH().worldStep(base::U().GF_StepSize(Level));
00076 const int refinefactor = RefineFactor(base::GH(),Level-1);
00077 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00078 ( comm_service::log() << "\n*** Adding First Order Fluxes - "
00079 << base::U().interiorbbox(Time,Level,c) << " ***\n").flush();
00080 #endif
00081
00082 double Fac[2*dim];
00083 int d;
00084 for (d=0; d<dim; d++) {
00085 Fac[2*d] = dt; Fac[2*d+1] = -dt;
00086 for (int dd=0; dd<dim; dd++)
00087 if (d != dd) {
00088 Fac[2*d] *= dx(dd); Fac[2*d+1] *= dx(dd);
00089 }
00090 }
00091
00092 for (d=0; d<2*dim; d++)
00093 if ((mdim==0 || d/2==mdim-1) && base::ValidSide(Time,Level,c,d)) {
00094 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00095 ( comm_service::log() << "Side: " << d << "\n").flush();
00096 #endif
00097 BBox bb(base::StateVecBBox(base::U().interiorbbox(Time,Level,c), d));
00098 BBox bbC(base::StateVecBBox(coarsen(base::U().interiorbbox(Time,Level,c),
00099 refinefactor),d));
00100 BBox workbb(bb); base::AlignBBox(workbb, d);
00101
00102 ld_vec_grid_data_type LeftState(workbb);
00103 ld_vec_grid_data_type RightState(workbb);
00104 ld_vec_grid_data_type NewState(workbb);
00105 BBox bbl(bb), bbr(bb);
00106 double dtl = dt, dtr = dt, tl, tr;
00107
00108
00109 if (d % 2 == 0) {
00110
00111 #ifdef DEBUG_AMR
00112 if (Integrator_().Abort())
00113 Integrator_().CheckGrid(base::U()(Time,Level,c), Level, bb, tf,
00114 "ClpFixup2::CorrectFirstOrder::LeftState,fine");
00115 #endif
00116 ops::copyv_to(LeftState, base::U()(Time,Level,c), bb, d);
00117 tl = tf;
00118
00119
00120 for (register int j=0; j<base::U().parents(Time,Level,c) ; j++) {
00121 BBox wbbC(coarsen(base::U().parentbox(Time,Level,c,j),refinefactor)*bbC);
00122 if (!wbbC.empty()) {
00123 #ifdef DEBUG_AMR
00124 if (Integrator_().Abort())
00125 Integrator_().CheckGrid(base::U()(TimeC,Level-1,base::U().parentidx(Time,Level,c,j)), Level-1,
00126 wbbC, tc, "ClpFixup2::CorrectFirstOrder::RightState,coarse");
00127 #endif
00128 ops::copyv_to(RightState, base::U()(TimeC,Level-1,base::U().parentidx(Time,Level,c,j)), wbbC, d);
00129 }
00130 }
00131 tr = tc;
00132 dtr *= refinefactor;
00133 bbr.coarsen(d/2, refinefactor);
00134 }
00135 else {
00136
00137 for (register int j=0; j<base::U().parents(Time,Level,c) ; j++) {
00138 BBox wbbC(coarsen(base::U().parentbox(Time,Level,c,j),refinefactor)*bbC);
00139 if (!wbbC.empty()) {
00140 #ifdef DEBUG_AMR
00141 if (Integrator_().Abort())
00142 Integrator_().CheckGrid(base::U()(TimeC,Level-1,base::U().parentidx(Time,Level,c,j)), Level-1,
00143 wbbC, tc, "ClpFixup2::CorrectFirstOrder::LeftState,coarse");
00144 #endif
00145 ops::copyv_to(LeftState, base::U()(TimeC,Level-1,base::U().parentidx(Time,Level,c,j)), wbbC, d);
00146 }
00147 }
00148 tl = tc;
00149 dtl *= refinefactor;
00150 bbl.coarsen(d/2, refinefactor);
00151
00152
00153 #ifdef DEBUG_AMR
00154 if (Integrator_().Abort())
00155 Integrator_().CheckGrid(base::U()(Time,Level,c), Level, bb, tf,
00156 "ClpFixup2::CorrectFirstOrder::RightState,fine");
00157 #endif
00158 ops::copyv_to(RightState, base::U()(Time,Level,c), bb, d);
00159 tr = tf;
00160 }
00161
00162 ((integrator_type&)Integrator_()).CalculateRP(LeftState, bbl, tl, dtl,
00163 RightState, bbr, tr, dtr, NewState, d/2+1);
00164
00165 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00166 base::debug_print_ld(base::F(d)(Time,Level,c));
00167 ( comm_service::log() << "\n").flush();
00168 ( comm_service::log() << "LeftState: \n").flush();
00169 base::debug_print_ldv(LeftState); ( comm_service::log() << "\n").flush();
00170 ( comm_service::log() << "RightState: \n").flush();
00171 base::debug_print_ldv(RightState); ( comm_service::log() << "\n").flush();
00172 ( comm_service::log() << "NewState: \n").flush();
00173 base::debug_print_ldv(NewState); ( comm_service::log() << "\n").flush();
00174 #endif
00175 NewState.multiply(Fac[d],workbb);
00176 base::addf_to(base::F(d)(Time,Level,c),NewState,workbb);
00177 #ifdef DEBUG_PRINT_WHOLE_FIXUP
00178 base::debug_print_ld(base::F(d)(Time,Level,c));
00179 ( comm_service::log() << "\n").flush();
00180 #endif
00181 }
00182 }
00183
00184 virtual void AddFluxes(const int Time, const int Level, const int c,
00185 vec_grid_data_type* flux[],
00186 const double tc, const double tf,
00187 const double dt, const int& mdim) {
00188 int mflx;
00189 f_rcflx(mflx);
00190 if (mflx==0) {
00191 if (dim>1 && Integrator_().DimSplit()) {
00192 std::cerr << "\n\nThe fixup is incorrect, if dimensional splitting is used with a\n";
00193 std::cerr << "scheme returning flux differences. Set Method(3)>=0 instead.\n";
00194 std::cerr << "Aborting programm...\n" << std::flush;
00195 std::exit(-1);
00196 }
00197 CorrectFirstOrder(Time, Level, c, tc, tf, dt, mdim);
00198 }
00199
00200 base::AddIntercellFluxes(Time, Level, c, flux, dt, mdim);
00201 }
00202
00203 inline integrator_type& Integrator_() { return _Integrator; }
00204 inline const integrator_type& Integrator_() const { return _Integrator; }
00205 inline const int& NGhosts() const { return _Integrator.NGhosts(); }
00206
00207 private:
00208 integrator_type& _Integrator;
00209 };
00210
00211 #endif