vtf-logo

AMRGFMSolver.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2007 California Institute of Technology
00004 // Ralf Deiterding, ralf@amroc.net
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     // Revert GFM boundary cells back to values from interior.
00214     // This allows for moving boundaries and enables the creation
00215     // of new refinement regions along the GFM boundary just using
00216     // interior cell values.
00217     // Swapping time levels also for BF(u) ensures correct flags
00218     // also in (BF(u(Time+TStep)).
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     // Recomposition of GridFunction requires LevelTransfer and a BoundaryConditions functor.
00238     // This is currently not available for Levelset functions.
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

Generated on Fri Aug 24 13:00:46 2007 for AMROC Fluid-solver Framework - by  doxygen 1.4.7