00001
00002
00003 #ifndef AMROC_PROBLEM_H
00004 #define AMROC_PROBLEM_H
00005
00006 #define DIM 3
00007 #define NEQUATIONS 9 // Euler equations for gases in 3D (5 fields),
00008
00009
00010
00011
00012 #define NVARS 6 // Fixup used only for vector of state and 2 scalars
00013
00014
00015
00016 #define OWN_AMRSOLVER
00017 #define OWN_FLAGGING
00018
00019 #include "WENOProblem.h"
00020 #ifdef SYNCTIME
00021 #include "WENOStdSyncTimeProblem.h"
00022 #else
00023 #include "WENOStdProblem.h"
00024 #endif
00025 #include "AMRInterpolation.h"
00026 #include "WENOStatistics.h"
00027 #include "F77Interfaces/F77FileInitialCondition.h"
00028
00029 #define f_init_commongm FORTRAN_NAME(comblgm, COMBLGM)
00030
00031 extern "C" {
00032 void f_init_commongm(const INTEGER& meqn, INTEGER* shape, DOUBLE* geom,
00033 const INTEGER& dcmin);
00034 }
00035
00036 #ifdef OWN_INITIALCONDITION
00037
00038 class InitialConditionSpecific :
00039 public F77FileInitialCondition<VectorType,DIM> {
00040 public:
00041 InitialConditionSpecific() :
00042 F77FileInitialCondition<VectorType,DIM>(f_initial,f_flgout,f_flgin,f_prolong) {}
00043 };
00044 #endif
00045
00046 #ifdef OWN_FLAGGING
00047
00048
00049 template <class VectorType, class FlagType, int dim>
00050 class F77ByThreshold : public F77OutBase<VectorType,dim>,
00051 public ByValue<VectorType,FlagType,dim> {
00052 typedef typename VectorType::InternalDataType DataType;
00053 typedef ByValue<VectorType,FlagType,dim> base;
00054 typedef F77OutBase<VectorType,dim> out_base;
00055 public:
00056 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00057 typedef typename base::grid_fct_type grid_fct_type;
00058 typedef typename base::flag_fct_type flag_fct_type;
00059 typedef typename out_base::generic_func_type generic_func_type;
00060 typedef typename base::max_vector_type max_vector_type;
00061
00062 F77ByThreshold(generic_func_type out) : out_base(out), base() {
00063 for ( int i = 0 ; i < MAXCOMPONENTS ; i++ ) {
00064 _ValueMin[i] = _ValueMax[i] = 0.0;
00065 }
00066 }
00067
00068 virtual void register_at(ControlDevice& Ctrl) {}
00069 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00070 base::LocCtrl = Ctrl.getSubDevice(prefix+"F77ByThreshold");
00071 char Name[16];
00072 for (int d=0; d<max_vector_type::Length(); d++) {
00073 std::sprintf(Name,"ValueMin(%d)",d+1);
00074 RegisterAt(base::LocCtrl,Name,_ValueMin[d]);
00075 std::sprintf(Name,"ValueMax(%d)",d+1);
00076 RegisterAt(base::LocCtrl,Name,_ValueMax[d]);
00077 std::sprintf(Name,"MaxLev(%d)",d+1);
00078 RegisterAt(base::LocCtrl,Name,base::_MaxLevel[d]);
00079 std::sprintf(Name,"Type(%d)",d+1);
00080 RegisterAt(base::LocCtrl,Name,base::_Comparison[d]);
00081 }
00082 RegisterAt(base::LocCtrl,"Output",base::_Output);
00083 }
00084
00085 virtual void update() {
00086 int d=max_vector_type::Length();
00087
00088 if (d>0) {
00089 base::SetNcnt(d);
00090 base::SetIsUsed(true);
00091 }
00092 else
00093 base::SetIsUsed(false);
00094 }
00095
00096 virtual void FlagByThreshold(grid_fct_type& work, flag_fct_type& flags,
00097 const int& Time, const int& Level,
00098 const DataType& ValueMin, const DataType& ValueMax,
00099 const FlagType& FlagValue,
00100 const int comparison = 0, const int growby = 0) {
00101
00102 int TStep = TimeStep(work,Level);
00103 forall(flags, Time, Level, c)
00104 BeginFastIndex3(work, work(Time+TStep,Level,c).bbox(),
00105 work(Time+TStep,Level,c).data(), DataType);
00106 BeginFastIndex3(flags, flags(Time,Level,c).bbox(),
00107 flags(Time,Level,c).data(), FlagType);
00108
00109 BBox OpBox = flags.interiorbbox(Time,Level,c);
00110 Coords& Os = OpBox.stepsize();
00111 BBox OpwBox = work(Time+TStep,Level,c).bbox();
00112 Coords& Ows = OpwBox.stepsize();
00113
00114 for_3 (n, m, l, OpBox, Os)
00115 DataType val;
00116 val = FastIndex3(work,n-n%Ows(0),m-m%Ows(1),l-l%Ows(2));
00117 if ((comparison==0 && val < ValueMax && val > ValueMin) ||
00118 (comparison==1 && val > ValueMax && val < ValueMin)) {
00119 if (growby<=0)
00120 FastIndex3(flags,n,m,l) = FlagValue;
00121 else {
00122 BBox bbflag(3,n,m,l,n,m,l,Os(0),Os(1),Os(2)); bbflag.grow(growby);
00123 flags(Time,Level,c).equals(FlagValue,bbflag);
00124 }
00125 }
00126 end_for
00127
00128 EndFastIndex3(work);
00129 EndFastIndex3(flags);
00130 end_forall
00131 }
00132
00133 virtual bool SetFlags(vec_grid_fct_type& u, grid_fct_type& work, flag_fct_type& flags,
00134 const int& cnt, const int& Time, const int& Level, const double& t,
00135 const FlagType& FlagValue) {
00136 if ( _ValueMin[cnt] >= _ValueMax[cnt] ||
00137 (base::MaxLevel(cnt)<Level && base::MaxLevel(cnt)>=0)) return false;
00138 int TStep = TimeStep(work,Level);
00139 out_base::Transform(u,work,Time,Level,cnt+1,t);
00140
00141 forall(u,Time,Level,c)
00142 work(Time+TStep,Level,c).equals(work(Time,Level,c));
00143 end_forall
00144
00145 FlagByThreshold(work, flags, Time, Level, _ValueMin[cnt], _ValueMax[cnt],
00146 FlagValue, base::_Comparison[cnt]);
00147 return true;
00148 }
00149
00150 virtual void OutputName(char* name, int cnt) { std::sprintf(name,"f77threshold_%d",cnt+1); }
00151
00152 private:
00153 DataType _ValueMin[MAXCOMPONENTS], _ValueMax[MAXCOMPONENTS];
00154 };
00155
00156
00157 #define NZONES 1
00158
00159 class FlaggingSpecific :
00160 public AMRFlagging<VectorType,FixupType,FlagType,DIM> {
00161 typedef AMRFlagging<VectorType,FixupType,FlagType,DIM> base;
00162 public:
00163 FlaggingSpecific(base::solver_type& solver) : base(solver) {
00164 base::AddCriterion(new ByValue<VectorType,FlagType,DIM>());
00165 base::AddCriterion(new ScaledGradient<VectorType,FlagType,DIM>());
00166 base::AddCriterion(new LimiterType<VectorType,FlagType,DIM>());
00167 base::AddCriterion(new AbsoluteError<VectorType,FixupType,FlagType,DIM>(solver));
00168 base::AddCriterion(new RelativeError<VectorType,FixupType,FlagType,DIM>(solver));
00169 #ifdef f_flgout
00170 base::AddCriterion(new F77ByValue<VectorType,FlagType,DIM>(f_flgout));
00171 base::AddCriterion(new F77ScaledGradient<VectorType,FlagType,DIM>(f_flgout));
00172 base::AddCriterion(new F77LimiterType<VectorType,FlagType,DIM>(f_flgout));
00173 base::AddCriterion(new F77AbsoluteError<VectorType,FixupType,FlagType,DIM>(solver,f_flgout));
00174 base::AddCriterion(new F77RelativeError<VectorType,FixupType,FlagType,DIM>(solver,f_flgout));
00175 base::AddCriterion(new F77ByThreshold<VectorType,FlagType,DIM>(f_flgout));
00176 #endif
00177 }
00178
00179 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00180 base::register_at(Ctrl, prefix);
00181 char VariableName[32];
00182 for (int iz=0; iz < NZONES ; iz++)
00183 for (int d=0; d<DIM; d++) {
00184 sprintf(VariableName,"DCellsMin%d(%d)",iz+1,d+1);
00185 RegisterAt(base::LocCtrl,VariableName,dcmin[iz][d]);
00186 sprintf(VariableName,"DCellsMax%d(%d)",iz+1,d+1);
00187 RegisterAt(base::LocCtrl,VariableName,dcmax[iz][d]);
00188 }
00189 for (int d=0; d<DIM; d++) {
00190 sprintf(VariableName,"FCellsMin(%d)",d+1);
00191 RegisterAt(base::LocCtrl,VariableName,scmin[d]);
00192 sprintf(VariableName,"FCellsMax(%d)",d+1);
00193 RegisterAt(base::LocCtrl,VariableName,scmax[d]);
00194 }
00195 }
00196 virtual void register_at(ControlDevice& Ctrl) {
00197 register_at(Ctrl, "");
00198 }
00199
00200 virtual void SetFlags(const int Time, const int Level, double t, double dt) {
00201 base::SetFlags(Time, Level, t, dt);
00202 int max_level = MaxLevel(base::GH());
00203 for ( int iz = 0 ; iz < NZONES ; iz ++ ) {
00204 Coords lb(base::Dim(), dcmin[iz]), ub(base::Dim(), dcmax[iz]),
00205 s(base::Dim(),1);
00206 BBox bbox(lb*StepSize(base::GH(),0), ub*StepSize(base::GH(),0),
00207 s*StepSize(base::GH(),0));
00208 bbox.refine(StepSize(base::GH(),0)/StepSize(base::GH(),Level));
00209
00210 forall (base::Flags(),Time,Level,c)
00211 if ( Level > max_level - (2+iz) )
00212 base::Flags()(Time,Level,c).equals(GoodPoint, bbox);
00213 end_forall
00214 }
00215
00216 Coords lb(base::Dim(), scmin), ub(base::Dim(), scmax), s(base::Dim(),1);
00217 BBox bbox(lb*StepSize(base::GH(),0), ub*StepSize(base::GH(),0),
00218 s*StepSize(base::GH(),0));
00219 bbox.refine(StepSize(base::GH(),0)/StepSize(base::GH(),Level));
00220
00221 forall (base::Flags(),Time,Level,c)
00222 base::Flags()(Time,Level,c).equals(BadPoint, bbox);
00223 end_forall
00224 }
00225
00226 ~FlaggingSpecific() { DeleteAllCriterions(); }
00227
00228 int LowCut(int i, int dim) { return dcmin[i][dim]; }
00229
00230 private:
00231 int dcmin[NZONES][DIM], dcmax[NZONES][DIM];
00232 int scmin[DIM], scmax[DIM];
00233 };
00234 #endif
00235
00236 #ifdef OWN_AMRSOLVER
00237
00238 class SolverSpecific :
00239 #ifdef SYNCTIME
00240 public AMRSolverSyncTime<VectorType,FixupType,FlagType,DIM> {
00241 typedef AMRSolverSyncTime<VectorType,FixupType,FlagType,DIM> base;
00242 #else
00243 public AMRSolver<VectorType,FixupType,FlagType,DIM> {
00244 typedef AMRSolver<VectorType,FixupType,FlagType,DIM> base;
00245 #endif
00246 typedef AMRInterpolation<VectorType,DIM> interpolation_type;
00247 typedef WENOF77FileOutput<VectorType,DIM> output_type;
00248 typedef WENOStatistics<VectorType,interpolation_type,output_type,DIM> stat_type;
00249 public:
00250 SolverSpecific(IntegratorSpecific& integ,
00251 base::initial_condition_type& init,
00252 base::boundary_conditions_type& bc) :
00253 #ifdef SYNCTIME
00254 AMRSolverSyncTime<VectorType,FixupType,FlagType,DIM>(integ, init, bc) {
00255 #else
00256 AMRSolver<VectorType,FixupType,FlagType,DIM>(integ, init, bc) {
00257 #endif
00258 SetLevelTransfer(new F77LevelTransfer<VectorType,DIM>(f_prolong, f_restrict));
00259 #ifdef f_flgout
00260 SetFileOutput(new WENOF77FileOutput<VectorType,DIM>(f_flgout,f_bounds));
00261 #else
00262 SetFileOutput(new FileOutput<VectorType,DIM>());
00263 #endif
00264 SetFixup(new FixupSpecific());
00265 SetFlagging(new FlaggingSpecific(*this));
00266 _Interpolation = new interpolation_type();
00267 _Stats = new stat_type(_Interpolation, (output_type*)_FileOutput);
00268 }
00269
00270 ~SolverSpecific() {
00271 delete _LevelTransfer;
00272 delete _Flagging;
00273 delete _Fixup;
00274 delete _FileOutput;
00275 delete _Interpolation;
00276 delete _Stats;
00277 }
00278
00279 virtual void register_at(ControlDevice& Ctrl) { base::register_at(Ctrl); }
00280 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00281 base::register_at(Ctrl, prefix);
00282 if (_Stats) _Stats->register_at(base::LocCtrl, "");
00283 }
00284
00285 virtual void SetupData() {
00286 base::SetupData();
00287 int dim = DIM;
00288 int dcmin = ((FlaggingSpecific*)_Flagging)->LowCut(0, 0);
00289 f_init_commongm(dim,shape,geom,dcmin);
00290 _Interpolation->SetupData(base::PGH(), base::NGhosts());
00291 _Stats->Setup(base::PGH(), base::NGhosts(), base::shape, base::geom);
00292 }
00293
00294 virtual void Advance(double& t, double& dt) {
00295 base::Advance(t, dt);
00296 _Stats->Evaluate(base::t, base::U(), base::Work());
00297 }
00298
00299 virtual void Initialize_(const double& dt_start) {
00300 base::Initialize_(dt_start);
00301 _Stats->Evaluate(base::t, base::U(), base::Work());
00302 }
00303
00304 protected:
00305 interpolation_type* _Interpolation;
00306 stat_type* _Stats;
00307 };