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