vtf-logo

ScaledGradient.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2002 Ralf Deiterding
00004 // Brandenburgische Universitaet Cottbus
00005 //
00006 // Copyright (C) 2003-2007 California Institute of Technology
00007 // Ralf Deiterding, ralf@amroc.net
00008 
00009 #ifndef AMROC_SCALEDGRADIENT_H
00010 #define AMROC_SCALEDGRADIENT_H
00011 
00018 #include "StdCriterion.h"
00019 
00026 template <class VectorType, class FlagType, int dim>
00027 class ScaledGradient : 
00028   public StdCriterion<VectorType,FlagType,dim> {
00029   typedef typename VectorType::InternalDataType DataType;
00030   typedef StdCriterion<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   ScaledGradient() : base() {
00038     base::SetShadowCriterion(false);
00039     Tol = static_cast<DataType>(0.0);
00040   }
00041 
00042   virtual ~ScaledGradient() {}
00043   
00044   virtual void register_at(ControlDevice& Ctrl) {}
00045   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00046     base::LocCtrl = Ctrl.getSubDevice(prefix+"ScaledGradient");
00047     char Name[16];
00048     for (int d=0; d<max_vector_type::Length(); d++) {
00049       std::sprintf(Name,"Tol(%d)",d+1);
00050       RegisterAt(base::LocCtrl,Name,Tol(d));
00051       std::sprintf(Name,"MaxLev(%d)",d+1);
00052       RegisterAt(base::LocCtrl,Name,base::_MaxLevel[d]);
00053     }    
00054     RegisterAt(base::LocCtrl,"Output",base::_Output);
00055   }
00056 
00057   virtual void update() { 
00058     int d=max_vector_type::Length();
00059     for (; d>0; d--) 
00060       if (Tol(d-1) > static_cast<DataType>(0.0)) 
00061         break;
00062     if (d>0) {
00063       base::SetNcnt(d);
00064       base::SetIsUsed(true);
00065     }
00066     else 
00067       base::SetIsUsed(false);
00068   }
00069 
00070   virtual bool SetFlags(vec_grid_fct_type& u, grid_fct_type& work, flag_fct_type& flags, 
00071                         const int& cnt, const int& Time, const int& Level, const double& t, 
00072                         const FlagType& FlagValue) {
00073     if (Tol(cnt) <= 0.0) return false;
00074     int TStep = TimeStep(work,Level);
00075     if (base::MaxLevel(cnt)<Level && base::MaxLevel(cnt)>=0) {
00076       if (base::OutputFlags()) {
00077         forall(work,Time,Level,c)
00078           work(Time+TStep,Level,c) = static_cast<DataType>(0.0);
00079         end_forall 
00080       }
00081       return true;
00082     }
00083 
00084     forall(work,Time,Level,c)
00085       equals_from(work(Time,Level,c), u(Time,Level,c), cnt);
00086     end_forall 
00087     return FlagByScaledGradient(work, flags, Time, Level, Tol(cnt), FlagValue);
00088   }
00089 
00090   virtual bool FlagByScaledGradient(grid_fct_type& work, flag_fct_type& flags,
00091                                     const int& Time, const int& Level, 
00092                                     const DataType& TolVal, const FlagType& FlagValue) { 
00093     if (TolVal <= 0.0) return false;
00094 
00095     int TStep = TimeStep(work,Level);
00096     forall(work,Time,Level,c)
00097       work(Time+TStep,Level,c) = static_cast<DataType>(0.0);
00098     end_forall 
00099 
00100     if (dim == 1) {
00101       int East[1]  = { 1 }; int West[1]  = { -1 };
00102       base::Difference(work, Time, Level, East, West);
00103     }
00104     else if (dim == 2) {
00105       int East[2]  = { 1, 0 }; int West[2]  = { -1, 0 };
00106       int North[2] = { 0, 1 }; int South[2] = { 0, -1 };
00107       base::Difference(work, Time, Level, East, West);
00108       base::Difference(work, Time, Level, North, South);
00109       
00110       int NorthEast[2] = {  1, 1 }; int SouthWest[2] = { -1, -1 };
00111       int NorthWest[2] = { -1, 1 }; int SouthEast[2] = {  1, -1 };
00112       base::Difference(work, Time, Level, NorthEast, SouthWest);
00113       base::Difference(work, Time, Level, NorthWest, SouthEast);
00114     }
00115     else if (dim == 3) {
00116       int East[3]  = { 1, 0, 0 }; int West[3]   = {-1,  0,  0 };
00117       int North[3] = { 0, 1, 0 }; int South[3]  = { 0, -1,  0 };
00118       int Top[3]   = { 0, 0, 1 }; int Bottom[3] = { 0,  0, -1 };
00119       base::Difference(work, Time, Level, East, West);
00120       base::Difference(work, Time, Level, North, South);
00121       base::Difference(work, Time, Level, Top, Bottom);
00122 
00123       int NorthEastTop[3]    = {  1, 1,  1}; int SouthWestBottom[3] = { -1, -1, -1};
00124       int NorthEastBottom[3] = {  1, 1, -1}; int SouthWestTop[3]    = { -1, -1,  1};
00125       int NorthWestTop[3]    = { -1, 1,  1}; int SouthEastBottom[3] = {  1, -1, -1};
00126       int NorthWestBottom[3] = { -1, 1, -1}; int SouthEastTop[3]    = {  1, -1,  1};
00127       base::Difference(work, Time, Level, NorthEastTop, SouthWestBottom);
00128       base::Difference(work, Time, Level, NorthEastBottom, SouthWestTop);
00129       base::Difference(work, Time, Level, NorthWestTop, SouthEastBottom);
00130       base::Difference(work, Time, Level, NorthWestBottom, SouthEastTop);
00131     }      
00132     base::FlagByValue(work, flags, Time, Level, TolVal, FlagValue);
00133     return true;
00134   }
00135 
00136   virtual void OutputName(char* name, int cnt) { std::sprintf(name,"grad_%d",cnt+1); }
00137 
00138   max_vector_type Tol;
00139 };
00140 
00141 #endif

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