00001
00002
00003
00004
00005
00006 #ifndef AMROC_GFMSOLVER_H
00007 #define AMROC_GFMSOLVER_H
00008
00016 #include "AMRSolver.h"
00017 #include "GhostFluidMethod.h"
00018 #include "Criteria/RefinePhi.h"
00019 #include "Criteria/ResolvePhi.h"
00020 #include "Criteria/UnflagPhi.h"
00021
00028 template <class VectorType, class FixupType, class FlagType, int dim>
00029 class AMRGFMSolver : public AMRSolver<VectorType,FixupType,FlagType,dim> {
00030 typedef typename VectorType::InternalDataType DataType;
00031 typedef AMRSolver<VectorType,FixupType,FlagType,dim> base;
00032 typedef AMRGFMSolver<VectorType,FixupType,FlagType,dim> self;
00033 public:
00034 typedef GhostFluidMethod<VectorType,dim> gfm_type;
00035 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00036 typedef typename base::vec_grid_data_type vec_grid_data_type;
00037 typedef typename base::grid_fct_type grid_fct_type;
00038 typedef typename base::grid_data_type grid_data_type;
00039
00040 typedef typename base::integrator_type integrator_type;
00041 typedef typename base::initial_condition_type initial_condition_type;
00042 typedef typename base::boundary_conditions_type boundary_conditions_type;
00043 typedef typename base::leveltransfer_type leveltransfer_type;
00044 typedef typename base::flagging_type flagging_type;
00045 typedef typename base::fixup_type fixup_type;
00046
00047 typedef GFRecomposeSpecificFunc<self,VectorType,dim> gfm_recompose_functor_type;
00048
00049 typedef GridData<bool,dim> bool_grid_data_type;
00050 typedef GridFunction<bool,dim> bool_grid_fct_type;
00051
00052 AMRGFMSolver(integrator_type& integ,
00053 initial_condition_type& init,
00054 boundary_conditions_type& bc) : base(integ, init, bc), _MaxRecomposeLevel(-1),
00055 _RecoverExterior(0) {
00056 _bf = (bool_grid_fct_type *) 0;
00057 _bf_sh = (bool_grid_fct_type *) 0;
00058 _GFMRecomposeFunc = (gfm_recompose_functor_type *) 0;
00059 _GFM = (gfm_type**) 0;
00060 _nGFM = 0;
00061 }
00062
00063 virtual ~AMRGFMSolver() {
00064 if (_bf) delete _bf;
00065 if (_bf_sh) delete _bf_sh;
00066 if (_GFMRecomposeFunc) delete _GFMRecomposeFunc;
00067 }
00068
00069 virtual void init() {
00070 base::Flagging_().AddCriterion(new RefinePhi<VectorType,FixupType,FlagType,dim>(*this));
00071 base::Flagging_().AddCriterion(new UnflagPhi<VectorType,FixupType,FlagType,dim>(*this));
00072 base::Flagging_().AddCriterion(new ResolvePhi<VectorType,FixupType,FlagType,dim>(*this,false));
00073 base::Flagging_().AddCriterion(new ResolvePhi<VectorType,FixupType,FlagType,dim>(*this,true));
00074 base::init();
00075 for (register int n=0; n<NGFM(); n++)
00076 GFM(n).init();
00077 }
00078
00079 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00080 base::register_at(Ctrl,prefix);
00081 for (register int n=0; n<NGFM(); n++) {
00082 char text[5];
00083 std::sprintf(text,"%d-",n+1);
00084 GFM(n).register_at(base::LocCtrl, std::string(text));
00085 }
00086 RegisterAt(base::LocCtrl,"RecoverExterior",_RecoverExterior);
00087 }
00088 virtual void register_at(ControlDevice& Ctrl) {
00089 register_at(Ctrl, "");
00090 }
00091
00092 virtual void update() {
00093 base::update();
00094 for (register int n=0; n<NGFM(); n++)
00095 GFM(n).update();
00096 }
00097 virtual void finish() {
00098 if (_bf) {
00099 delete _bf;
00100 _bf = (bool_grid_fct_type *) 0;
00101 }
00102 if (_bf_sh) {
00103 delete _bf_sh;
00104 _bf_sh = (bool_grid_fct_type *) 0;
00105 }
00106 base::finish();
00107 for (register int n=0; n<NGFM(); n++)
00108 GFM(n).finish();
00109 }
00110 virtual void SetupData() {
00111 base::SetupGridHierarchy();
00112 for (register int n=0; n<NGFM(); n++) {
00113 GFM(n).SetErrorEstimation(base::ErrorEstimation());
00114 GFM(n).SetupData(base::PGH(), base::NGhosts());
00115 }
00116
00117 int t_sten = 1;
00118 int s_sten = base::NGhosts();
00119 std::sprintf(BFName,"BFlags");
00120 _bf = new bool_grid_fct_type(BFName, t_sten, s_sten, base::GH(),
00121 DAGHCellCentered, DAGHNoComm, DAGHNoBoundary,
00122 DAGHNoAdaptBoundary, DAGHNoExternalGhost);
00123 SetCheckpointFlag(BF(), DAGHFalse);
00124 SetTimeAlias(BF(), -1, 1);
00125 if (base::ErrorEstimation()) {
00126 std::sprintf(BFNamesh,"BFlagssh");
00127 _bf_sh = new bool_grid_fct_type(BFNamesh, t_sten, s_sten, base::GH(),
00128 DAGHCellCentered, 0, DAGHShadowFactor,
00129 DAGH_All, DAGHNoComm, DAGHNoBoundary,
00130 DAGHNoAdaptBoundary, DAGHNoExternalGhost);
00131 SetCheckpointFlag(BFsh(), DAGHFalse);
00132 SetTimeAlias(BFsh(), -1, 1);
00133 }
00134
00135 base::SetupData();
00136 _GFMRecomposeFunc = new gfm_recompose_functor_type(this, &self::SetRecomposeBndry);
00137 base::U().GF_SetRecomposeFunc(_GFMRecomposeFunc);
00138 if (base::ErrorEstimation())
00139 base::Ush().GF_SetRecomposeFunc(_GFMRecomposeFunc);
00140 for (register int n=0; n<NGFM(); n++)
00141 GFM(n).SetGridFunctions(base::_u,base::_u_sh);
00142 }
00143
00144 virtual void SetBndry(vec_grid_fct_type& u, const int Time,
00145 const int Level, double t) {
00146 base::SetBndry(u,Time,Level,t);
00147 forall (BF(u),Time,Level,c)
00148 BF(u)(Time,Level,c).equals(false);
00149 end_forall
00150 for (register int n=0; n<NGFM(); n++) {
00151 if (!GFM(n).Stationary() || Time==0)
00152 GFM(n).SetLevelSet(u,Time,Level,t);
00153 GFM(n).SetBndry(u,BF(u),Time,Level,t);
00154 }
00155 }
00156
00157 virtual double IntegrateLevel(vec_grid_fct_type& u, const int Time, const int Level,
00158 double t, double dt, bool DoFixup, double tc,
00159 const int which) {
00160 double cfl = base::IntegrateLevel(u,Time,Level,t,dt,DoFixup,tc,which);
00161
00162 int TStep = TimeStep(u,Level);
00163 if (_RecoverExterior) {
00164 forall (u,Time,Level,c)
00165 if (base::Dim() == 1) {
00166 BeginFastIndex1(u_old, u(Time,Level,c).bbox(),
00167 u(Time,Level,c).data(), VectorType);
00168 BeginFastIndex1(u_new, u(Time+TStep,Level,c).bbox(),
00169 u(Time+TStep,Level,c).data(), VectorType);
00170 BeginFastIndex1(bf, BF(u)(Time,Level,c).bbox(),
00171 BF(u)(Time,Level,c).data(), bool);
00172 for_1 (n, BF(u)(Time,Level,c).bbox(), BF(u)(Time,Level,c).bbox().stepsize())
00173 if (FastIndex1(bf,n))
00174 FastIndex1(u_new,n) = FastIndex1(u_old,n);
00175 end_for
00176 EndFastIndex1(bf);
00177 EndFastIndex1(u_new);
00178 EndFastIndex1(u_old);
00179 }
00180 else if (base::Dim() == 2) {
00181 BeginFastIndex2(u_old, u(Time,Level,c).bbox(),
00182 u(Time,Level,c).data(), VectorType);
00183 BeginFastIndex2(u_new, u(Time+TStep,Level,c).bbox(),
00184 u(Time+TStep,Level,c).data(), VectorType);
00185 BeginFastIndex2(bf, BF(u)(Time,Level,c).bbox(),
00186 BF(u)(Time,Level,c).data(), bool);
00187 for_2 (n, m, BF(u)(Time,Level,c).bbox(), BF(u)(Time,Level,c).bbox().stepsize())
00188 if (FastIndex2(bf,n,m))
00189 FastIndex2(u_new,n,m) = FastIndex2(u_old,n,m);
00190 end_for
00191 EndFastIndex2(bf);
00192 EndFastIndex2(u_new);
00193 EndFastIndex2(u_old);
00194 }
00195 else if (base::Dim() == 3) {
00196 BeginFastIndex3(u_old, u(Time,Level,c).bbox(),
00197 u(Time,Level,c).data(), VectorType);
00198 BeginFastIndex3(u_new, u(Time+TStep,Level,c).bbox(),
00199 u(Time+TStep,Level,c).data(), VectorType);
00200 BeginFastIndex3(bf, BF(u)(Time,Level,c).bbox(),
00201 BF(u)(Time,Level,c).data(), bool);
00202 for_3 (n, m, l, BF(u)(Time,Level,c).bbox(), BF(u)(Time,Level,c).bbox().stepsize())
00203 if (FastIndex3(bf,n,m,l))
00204 FastIndex3(u_new,n,m,l) = FastIndex3(u_old,n,m,l);
00205 end_for
00206 EndFastIndex3(bf);
00207 EndFastIndex3(u_new);
00208 EndFastIndex3(u_old);
00209 }
00210 end_forall
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 for (register int n=0; n<NGFM(); n++)
00220 if (Level<MaxLevel(base::GH()))
00221 GFM(n).SetBndry(u,BF(u),Time,Level,t,true);
00222
00223 SwapTimeLevels(u,Level,Time,Time+TStep);
00224 SwapTimeLevels(BF(u),Level,Time,Time+TStep);
00225 for (register int n=0; n<NGFM(); n++)
00226 GFM(n).SetBndry(u,BF(u),Time,Level,t,true);
00227 SwapTimeLevels(u,Level,Time,Time+TStep);
00228 SwapTimeLevels(BF(u),Level,Time,Time+TStep);
00229
00230 return cfl;
00231 }
00232
00233 virtual void RecomposeGridHierarchy(const int Time, const int Level,
00234 bool ShadowAllowed, bool DoFixup,
00235 bool RecomposeBaseLev, bool RecomposeHighLev) {
00236
00237
00238
00239 _MaxRecomposeLevel = DAGHNull;
00240 for (register int n=0; n<NGFM(); n++)
00241 GFM(n).SetMaxRecomposeLevel(_MaxRecomposeLevel);
00242 BF().GF_SetMaxRecomposeLevel(_MaxRecomposeLevel);
00243 if (base::ErrorEstimation())
00244 BFsh().GF_SetMaxRecomposeLevel(_MaxRecomposeLevel);
00245 base::RecomposeGridHierarchy(Time,Level,ShadowAllowed,DoFixup,
00246 RecomposeBaseLev,RecomposeHighLev);
00247 }
00248
00249 virtual void SetRecomposeBndry(vec_grid_fct_type& u, const int& Time,
00250 const int& Level, const double& t) {
00251 if (Time>0 && CurrentTime(base::GH(),Level)==Time &&
00252 Level>_MaxRecomposeLevel) {
00253 forall (BF(u),Time,Level,c)
00254 BF(u)(Time,Level,c).equals(false);
00255 end_forall
00256 for (register int n=0; n<NGFM(); n++) {
00257 GFM(n).SetLevelSet(u,Time,Level,t);
00258 GFM(n).SetBndry(u,BF(u),Time,Level,t);
00259 }
00260 }
00261 }
00262
00263 virtual void Initialize_(const double& dt_start) {
00264 int* v = new int[NGFM()];
00265 for (register int n=0; n<NGFM(); n++) {
00266 v[n] = GFM(n).Boundary().GetVerbose();
00267 GFM(n).Boundary().SetVerbose(0);
00268 }
00269 base::Initialize_(dt_start);
00270 for (register int n=0; n<NGFM(); n++)
00271 GFM(n).Boundary().SetVerbose(v[n]);
00272 delete [] v;
00273 }
00274
00275 virtual void Output() {
00276 if (CurrentTime(base::GH(),0) == base::LastOutputTime()) return;
00277 if (base::_FileOutput) {
00278 START_WATCH
00279 for (register int n=0; n<NGFM(); n++)
00280 if (GFM(n).LevelSet().PlotPhi()) {
00281 double t = GetPhysicalTime(base::U(),CurrentTime(base::GH(),0),0);
00282 char name[DAGHBktGFNameWidth+16];
00283 std::sprintf(name,"phi_%d",n+1);
00284 for (int l=0; l<=FineLevel(base::GH()); l++) {
00285 int Time = CurrentTime(base::GH(),l);
00286 base::FileOutput_().WritePlain(GFM(n).Phi(), name, Time, l, t);
00287 }
00288 }
00289 END_WATCH_OUPUT
00290 }
00291 base::Output();
00292 }
00293
00294 virtual bool Restart_(const char* CheckpointFile) {
00295 bool ret = base::Restart_(CheckpointFile);
00296 if (ret) {
00297 START_WATCH
00298 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00299 int Time = CurrentTime(base::GH(),l);
00300 for (register int n=0; n<NGFM(); n++) {
00301 SetPhysicalTime(GFM(n).Phi(),Time,l,base::t[l]);
00302 if (base::ErrorEstimation()) {
00303 SetPhysicalTime(GFM(n).Phish(),Time,l,base::t[l]);
00304 }
00305 }
00306 _MaxRecomposeLevel = DAGHNull;
00307 SetRecomposeBndry(base::U(),Time,l,base::t[l]);
00308 if (base::ErrorEstimation())
00309 SetRecomposeBndry(base::Ush(),Time,l,base::t[l]);
00310 }
00311 END_WATCH_INITIALIZATION
00312 }
00313 return ret;
00314 }
00315
00316 virtual void Checkpointing_(const char* CheckpointFile) {
00317 for (register int n=0; n<NGFM(); n++) {
00318 SetCheckpointFlag(GFM(n).Phi(), DAGHFalse);
00319 if (base::ErrorEstimation())
00320 SetCheckpointFlag(GFM(n).Phish(), DAGHFalse);
00321 }
00322
00323 base::Checkpointing_(CheckpointFile);
00324
00325 for (register int n=0; n<NGFM(); n++) {
00326 SetCheckpointFlag(GFM(n).Phi(), DAGHTrue);
00327 if (base::ErrorEstimation())
00328 SetCheckpointFlag(GFM(n).Phish(), DAGHTrue);
00329 }
00330 }
00331
00332
00333 void AddGFM(gfm_type* gfm) {
00334 if (gfm) {
00335 gfm_type** _GFM_new = new gfm_type*[_nGFM+1];
00336 if (_GFM) {
00337 for (register int n=0; n<_nGFM; n++)
00338 _GFM_new[n] = _GFM[n];
00339 delete [] _GFM;
00340 }
00341 _GFM = _GFM_new;
00342 _GFM[_nGFM] = gfm;
00343 _nGFM++;
00344 }
00345 }
00346
00347 void EliminateGFM(gfm_type* gfm) {
00348 if (gfm) {
00349 int c=0;
00350 for (register int n=0; n<_nGFM; n++)
00351 if (_GFM[n] == gfm) c++;
00352 if (c>0) {
00353 gfm_type** _GFM_new = (gfm_type**) 0;
00354 if (_nGFM-c>0) {
00355 _GFM_new = new gfm_type*[_nGFM-c];
00356 for (register int n=0, m=0; n<_nGFM; n++)
00357 if (_GFM[n] != gfm)
00358 _GFM_new[m++] = _GFM[n];
00359 }
00360 delete [] _GFM;
00361 _GFM = _GFM_new;
00362 _nGFM = _nGFM-c;
00363 }
00364 }
00365 }
00366
00367 void DeleteGFM(gfm_type* gfm) {
00368 EliminateGFM(gfm);
00369 if (gfm) {
00370 delete gfm->GetBoundaryP();
00371 delete gfm->GetLevelSetP();
00372 delete gfm;
00373 }
00374 }
00375
00376 inline bool_grid_fct_type* BFP() { return _bf; }
00377 inline bool_grid_fct_type& BF() { return *_bf; }
00378 inline const bool_grid_fct_type& BF() const { return *_bf; }
00379 inline bool_grid_fct_type& BFsh() { return *_bf_sh; }
00380 inline const bool_grid_fct_type& BFsh() const{ return *_bf_sh; }
00381 inline bool_grid_fct_type& BF(vec_grid_fct_type& u)
00382 { return (&u==base::_u_sh ? *_bf_sh : *_bf); }
00383 inline const bool_grid_fct_type& BF(vec_grid_fct_type& u) const
00384 { return (&u==base::_u_sh ? *_bf_sh : *_bf); }
00385
00386 inline gfm_type* GFMP(const int n) { assert (n>=0 && n<_nGFM); return _GFM[n]; }
00387 inline gfm_type& GFM(const int n) { assert (n>=0 && n<_nGFM); return *(_GFM[n]); }
00388 inline const gfm_type& GFM(const int n) const { assert (n>=0 && n<_nGFM); return *(_GFM[n]); }
00389
00390 inline const int& NGFM() const { return _nGFM; }
00391
00392 protected:
00393 bool_grid_fct_type *_bf, *_bf_sh;
00394 gfm_recompose_functor_type* _GFMRecomposeFunc;
00395 gfm_type** _GFM;
00396 int _nGFM;
00397 int _MaxRecomposeLevel, _RecoverExterior;
00398 char BFName[DAGHBktGFNameWidth], BFNamesh[DAGHBktGFNameWidth];
00399 };
00400
00401
00402 #endif