00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef AMROC_LIMITERTYPE_H
00010 #define AMROC_LIMITERTYPE_H
00011
00018 #include "Criteria/LimiterCriterion.h"
00019
00026 template <class VectorType, class FlagType, int dim>
00027 class LimiterType :
00028 public LimiterCriterion<VectorType,FlagType,dim> {
00029 typedef typename VectorType::InternalDataType DataType;
00030 typedef LimiterCriterion<VectorType,FlagType,dim> base;
00031 public:
00032 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00033 typedef typename base::grid_fct_type grid_fct_type;
00034 typedef typename base::flag_fct_type flag_fct_type;
00035 typedef typename base::max_vector_type max_vector_type;
00036
00037 LimiterType() : base() {
00038 base::SetShadowCriterion(false);
00039 Maxv = static_cast<DataType>(0.0);
00040 Tol = static_cast<DataType>(0.0);
00041 Sc = static_cast<DataType>(0.0);
00042 ScTol = static_cast<DataType>(0.0);
00043 }
00044
00045 virtual ~LimiterType() {}
00046
00047 virtual void register_at(ControlDevice& Ctrl) {}
00048 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00049 base::LocCtrl = Ctrl.getSubDevice(prefix+"LimiterType");
00050 char Name[16];
00051 for (int d=0; d<max_vector_type::Length(); d++) {
00052 std::sprintf(Name,"Max(%d)",d+1);
00053 RegisterAt(base::LocCtrl,Name,Maxv(d));
00054 std::sprintf(Name,"Tol(%d)",d+1);
00055 RegisterAt(base::LocCtrl,Name,Tol(d));
00056 std::sprintf(Name,"ScTol(%d)",d+1);
00057 RegisterAt(base::LocCtrl,Name,ScTol(d));
00058 std::sprintf(Name,"MaxLev(%d)",d+1);
00059 RegisterAt(base::LocCtrl,Name,base::_MaxLevel[d]);
00060 }
00061 RegisterAt(base::LocCtrl,"Output",base::_Output);
00062 }
00063
00064 virtual void update() {
00065 Sc = ScTol*Maxv;
00066 int d=max_vector_type::Length();
00067 for (; d>0; d--)
00068 if (Tol(d-1)>static_cast<DataType>(0.0) &&
00069 Sc(d-1)>static_cast<DataType>(0.0))
00070 break;
00071 if (d>0) {
00072 base::SetNcnt(d);
00073 base::SetIsUsed(true);
00074 }
00075 else
00076 base::SetIsUsed(false);
00077 }
00078
00079 virtual bool SetFlags(vec_grid_fct_type& u, grid_fct_type& work, flag_fct_type& flags,
00080 const int& cnt, const int& Time, const int& Level, const double& t,
00081 const FlagType& FlagValue) {
00082 if (Tol(cnt)<=0.0 || Sc(cnt)<=0.0) return false;
00083 int TStep = TimeStep(work,Level);
00084 if (base::MaxLevel(cnt)<Level && base::MaxLevel(cnt)>=0) {
00085 if (base::OutputFlags()) {
00086 forall(work,Time,Level,c)
00087 work(Time+TStep,Level,c) = static_cast<DataType>(0.0);
00088 end_forall
00089 }
00090 return true;
00091 }
00092
00093 forall(work,Time,Level,c)
00094 equals_from(work(Time,Level,c), u(Time,Level,c), cnt);
00095 end_forall
00096 return FlagByLimiter(work, flags, Time, Level, Tol(cnt), Sc(cnt), FlagValue);
00097 }
00098
00099 virtual bool FlagByLimiter(grid_fct_type& work, flag_fct_type& flags,
00100 const int& Time, const int& Level,
00101 const DataType& TolVal, const DataType& ScVal,
00102 const FlagType& FlagValue) {
00103 if (TolVal<=0.0 || ScVal<=0.0) return false;
00104 int TStep = TimeStep(work,Level);
00105 forall(work,Time,Level,c)
00106 work(Time+TStep,Level,c) = static_cast<DataType>(1.0);
00107 end_forall
00108
00109 int OffsetX[3] = { 1, 0, 0 }; int OffsetY[3] = { 0, 1, 0 }; int OffsetZ[3] = { 0, 0, 1 };
00110 base::Limiter(work, Time, Level, OffsetX, ScVal);
00111 if (dim > 1) base::Limiter(work, Time, Level, OffsetY, ScVal);
00112 if (dim > 2) base::Limiter(work, Time, Level, OffsetZ, ScVal);
00113 base::FlagByValue(work, flags, Time, Level, TolVal, FlagValue, 1);
00114 return true;
00115 }
00116
00117 virtual void OutputName(char* name, int cnt) { std::sprintf(name,"limtype_%d",cnt+1); }
00118
00119 virtual DataType phi(const DataType theta) {
00120 return (4.*theta/((1.+theta)*(1.+theta)));
00121 }
00122
00123 max_vector_type Tol, ScTol, Sc, Maxv;
00124 };
00125
00126 #endif