00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef AMROC_ABSOLUTE_ERROR_H
00010 #define AMROC_ABSOLUTE_ERROR_H
00011
00018 #include "StdCriterion.h"
00019 #include "AMRSolverBase.h"
00020
00027 template <class VectorType, class FixupType, class FlagType, int dim>
00028 class AbsoluteError :
00029 public StdCriterion<VectorType,FlagType,dim> {
00030 typedef typename VectorType::InternalDataType DataType;
00031 typedef StdCriterion<VectorType,FlagType,dim> base;
00032 public:
00033 typedef AMRSolverBase<VectorType,FixupType,FlagType,dim> solver_type;
00034 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00035 typedef typename base::grid_fct_type grid_fct_type;
00036 typedef typename base::flag_fct_type flag_fct_type;
00037 typedef typename base::max_vector_type max_vector_type;
00038
00039 AbsoluteError(solver_type& solver) : base() {
00040 base::SetShadowCriterion(true);
00041 base::SetUpdateShadow(true);
00042 Order = std::pow(2.0,static_cast<DataType>(solver.NMethodOrder())+1.0) - 2.0;
00043 Tol = static_cast<DataType>(0.0);
00044 }
00045
00046 virtual ~AbsoluteError() {}
00047
00048 virtual void register_at(ControlDevice& Ctrl) {}
00049 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00050 base::LocCtrl = Ctrl.getSubDevice(prefix+"AbsoluteError");
00051 char Name[16];
00052 for (int d=0; d<max_vector_type::Length(); d++) {
00053 std::sprintf(Name,"Tol(%d)",d+1);
00054 RegisterAt(base::LocCtrl,Name,Tol(d));
00055 std::sprintf(Name,"MaxLev(%d)",d+1);
00056 RegisterAt(base::LocCtrl,Name,base::_MaxLevel[d]);
00057 }
00058 RegisterAt(base::LocCtrl,"Output",base::_Output);
00059 }
00060
00061 virtual void update() {
00062 int d=max_vector_type::Length();
00063 for (; d>0; d--)
00064 if (Tol(d-1) > static_cast<DataType>(0.0))
00065 break;
00066 if (d>0) {
00067 base::SetNcnt(d);
00068 base::SetIsUsed(true);
00069 }
00070 else
00071 base::SetIsUsed(false);
00072 }
00073
00074 virtual bool SetFlags(vec_grid_fct_type& u, grid_fct_type& work, flag_fct_type& flags,
00075 const int& cnt, const int& Time, const int& Level, const double& t,
00076 const FlagType& FlagValue) {
00077 if (Tol(cnt) <= 0.0) return false;
00078 int TStep = TimeStep(work,Level);
00079 if (Time==0 || (base::MaxLevel(cnt)<Level && base::MaxLevel(cnt)>=0)) {
00080 if (base::OutputFlags()) {
00081 forall(work,Time,Level,c)
00082 work(Time+TStep,Level,c) = static_cast<DataType>(0.0);
00083 end_forall
00084 }
00085 return true;
00086 }
00087
00088 forall(u,Time,Level,c)
00089 equals_from(work(Time+TStep,Level,c), u(Time+TStep,Level,c), cnt);
00090 minus_from(work(Time+TStep,Level,c), u(Time,Level,c), cnt);
00091 base::Abs(work(Time+TStep,Level,c));
00092 work(Time+TStep,Level,c).divide(Order);
00093 end_forall
00094 base::FlagByValue(work, flags, Time, Level, Tol(cnt), FlagValue);
00095 return true;
00096 }
00097
00098 virtual void OutputName(char* name, int cnt) { std::sprintf(name,"abserr_%d",cnt+1); }
00099
00100 max_vector_type Tol;
00101 DataType Order;
00102 };
00103
00104 #endif