00001
00002
00003
00004
00005
00006 #ifndef AMROC_UNFLAGPHI_H
00007 #define AMROC_UNFLAGPHI_H
00008
00015 #include "Criteria/ResolvePhi.h"
00016
00023 template <class VectorType, class Fixup, class FlagType, int dim>
00024 class UnflagPhi :
00025 public PhiCriterion<VectorType,FlagType,dim> {
00026 typedef typename VectorType::InternalDataType DataType;
00027 typedef PhiCriterion<VectorType,FlagType,dim> base;
00028 public:
00029 typedef AMRGFMSolver<VectorType,FixupType,FlagType,dim> gfm_solver_type;
00030 typedef GhostFluidMethod<VectorType,dim> gfm_type;
00031 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00032 typedef typename base::grid_fct_type grid_fct_type;
00033 typedef typename base::flag_fct_type flag_fct_type;
00034 typedef typename base::max_vector_type max_vector_type;
00035
00036 UnflagPhi(gfm_solver_type& solver) : base(), _solver(solver) {
00037 base::SetShadowCriterion(false);
00038 for (register int i=0; i<MAXCOMPONENTS; i++) {
00039 if (i<solver.NGFM()) Use[i] = 1;
00040 else Use[i] = 0;
00041 }
00042 }
00043
00044 virtual ~UnflagPhi() {}
00045
00046 virtual void register_at(ControlDevice& Ctrl) {}
00047 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00048 base::LocCtrl = Ctrl.getSubDevice(prefix+"UnflagPhi");
00049 char Name[16];
00050 for (int d=0; d<max_vector_type::Length(); d++) {
00051 std::sprintf(Name,"Use(%d)",d+1);
00052 RegisterAt(base::LocCtrl,Name,Use[d]);
00053 std::sprintf(Name,"MinLev(%d)",d+1);
00054 RegisterAt(base::LocCtrl,Name,base::_MaxLevel[d]);
00055 }
00056 RegisterAt(base::LocCtrl,"Output",base::_Output);
00057 }
00058
00059 virtual void update() {
00060 int d=max_vector_type::Length();
00061 for (; d>0; d--)
00062 if (Use[d-1] > 0)
00063 break;
00064 if (d>0) {
00065 base::SetNcnt(d);
00066 base::SetIsUsed(true);
00067 }
00068 else
00069 base::SetIsUsed(false);
00070 }
00071
00072 virtual bool SetFlags(vec_grid_fct_type& u, grid_fct_type& work, flag_fct_type& flags,
00073 const int& cnt, const int& Time, const int& Level, const double& t,
00074 const FlagType& FlagValue) {
00075
00076 if (Use[cnt] <= 0 || cnt>=NGFM()) return false;
00077 int TStep = TimeStep(work,Level);
00078 if (Level<base::MaxLevel(cnt) && base::MaxLevel(cnt)>=0) {
00079 if (base::OutputFlags()) {
00080 forall(work,Time,Level,c)
00081 work(Time+TStep,Level,c) = static_cast<DataType>(0.0);
00082 end_forall
00083 }
00084 return true;
00085 }
00086
00087 DataType md = -GFM(cnt).Boundary().Cutoff();
00088 forall(work,Time+TStep,Level,c)
00089 work(Time+TStep,Level,c).equals((GFM(cnt).Phi())(Time,Level,c));
00090 base::Sgn(work(Time+TStep,Level,c),md);
00091 end_forall
00092
00093 base::FlagByValue(work, flags, Time, Level, static_cast<DataType>(0.0),
00094 GoodPoint, 1);
00095
00096 return true;
00097 }
00098
00099 inline gfm_type& GFM(const int& n) { return _solver.GFM(n); }
00100 inline const int& NGFM() { return _solver.NGFM(); }
00101
00102 virtual void OutputName(char* name, int cnt) {
00103 std::sprintf(name,"unflag_phi_%d",cnt+1);
00104 }
00105
00106 protected:
00107 gfm_solver_type _solver;
00108 int Use[MAXCOMPONENTS];
00109 };
00110
00111 #endif