Go to the documentation of this file.00001 #ifndef advection_hh
00002 #define advection_hh
00003
00004 #include "basics/typedefs.hh"
00005 #include "toolbox/inputOutput.hh"
00006 #include "formula/boundary.hh"
00007 #include "geometry/boundaryConditions.hh"
00008 #include "operator/compositions.hh"
00009 #include "operator/diagonal.hh"
00010 #include "timestepping/vectors.hh"
00011 #include "linDG3D/element.hh"
00012 #include "linDG3D/space.hh"
00013 #include "linDG3D/elementPair.hh"
00014
00015 #include <map>
00016 #include <vector>
00017 #include <utility>
00018 #include <numeric>
00019
00020 #define DEBUG_ADVECTION 0
00021 #define DEBUG_FLUXES 0
00022 #define DEBUG_ADAPT_LIM_ELM 0
00023 #define DEBUG_ADAPT_LIM_INDICATOR 0
00024 #define DEBUG_REF_ASSIGNMENT 0
00025
00026 using concepts::Real;
00027
00028
00029
00033 class BurgerFlux {
00034 public:
00037 BurgerFlux() :
00038 normal_(concepts::Real3d(1., 1., 1.)) {}
00042 concepts::Real3d flux(const Real u) const {
00043 return normal_*(0.5*u*u);
00044 }
00049 Real flux(const Real u, const concepts::Real3d& direction) const {
00050 return normal_*direction*(0.5*u*u);
00051 }
00055 concepts::Real3d deriv(const Real u) const {
00056 return normal_*u;
00057 }
00063 Real deriv(const Real u, const concepts::Real3d& direction) const {
00064 return normal_*direction*u;
00065 }
00073 bool isConvex(const concepts::Real3d& normal) const {
00074 return normal*normal_ > 0.;
00075 }
00077 Real uMin(const concepts::Real3d& normal) const { return 0; }
00078
00079 private:
00080 const concepts::Real3d normal_;
00081 };
00082
00086 class LinearAdvectionFlux {
00087 public:
00090 LinearAdvectionFlux() :
00091 normal_(concepts::Real3d(1., 1., 1.)) {}
00095 concepts::Real3d flux(const Real u) const { return normal_*u;}
00101 Real flux(const Real u, const concepts::Real3d& direction) const {
00102 return normal_*direction*u;
00103 }
00107 concepts::Real3d deriv(const Real u) const { return normal_; }
00114 Real deriv(const Real u, const concepts::Real3d& direction) const {
00115 return normal_*direction;
00116 }
00117 private:
00118 const concepts::Real3d normal_;
00119 };
00120
00121
00122
00123
00127 template<typename NumFlux>
00128 class Advection : public concepts::Operator<Real> {
00129 public:
00137 Advection(const NumFlux& fvFlux,
00138 const linDG3D::FvdgSpace& spc,
00139 const bool pcb,
00140 concepts::BoundaryConditions* bc = 0)
00141 : concepts::Operator<Real>(spc.dim(), spc.dim())
00142 , numFlux_(fvFlux),
00143 spc_(spc),
00144 innerList_(spc.innerElmPairList()),
00145 boundaryList_(spc.boundaryElmPairList()),
00146 time_(0),
00147 pcb_(pcb),
00148 bc_(bc) {};
00156 void operator()
00157 (const concepts::Function<Real>& fncY, concepts::Function<Real>& fncX);
00159 const concepts::Space<Real>& spaceX() const { return spc_; }
00161 const concepts::Space<Real>& spaceY() const { return spc_; }
00162 protected:
00163 virtual std::ostream& info (std::ostream &os) const;
00164 private:
00165 const NumFlux& numFlux_;
00166 const linDG3D::FvdgSpace& spc_;
00167 const concepts::ElementPairList<Real>& innerList_;
00168 const concepts::ElementPairList<Real>& boundaryList_;
00169 Real time_;
00170 const bool pcb_;
00171 concepts::BoundaryConditions* bc_;
00178 Real uBoundary_(const linDG3D::FvdgElement& elm,
00179 const uint faceIdx,
00180 const concepts::Real3d &x) const;
00181 };
00182
00183
00184
00185
00190 template <typename T>
00191 class LaxFriedrichs {
00192 public:
00193 friend class Advection<LaxFriedrichs>;
00195 LaxFriedrichs() : fluxFct_() {}
00204 Real operator()
00205 (Real u1, Real u2, const concepts::Real3d& normal) const;
00206 private:
00207 const T fluxFct_;
00208 };
00209
00210
00214 template <typename T>
00215 class Upwind {
00216 friend class Advection<Upwind>;
00217 public:
00219 Upwind() : fluxFct_() {}
00227 Real operator()
00228 (Real u1, Real u2, const concepts::Real3d& normal) const;
00229 private:
00230 const T fluxFct_;
00231 };
00232
00233
00238 template <typename T>
00239 class Godunov {
00240 public:
00241 friend class Advection<Godunov>;
00243 Godunov() : fluxFct_() {}
00251 Real operator() (Real u1, Real u2,
00252 const concepts::Real3d& normal) const;
00253 private:
00254 const T fluxFct_;
00255 };
00256
00257
00262 template <typename T>
00263 class Osher {
00264 public:
00265 friend class Advection<Osher>;
00267 Osher() : fluxFct_() {}
00275 Real operator()
00276 (Real u1, Real u2, const concepts::Real3d& normal) const;
00277 private:
00278 const T fluxFct_;
00279 };
00280
00281
00282
00283
00287 class FvdgPi0Limiter : public concepts::Operator<Real> {
00288 public:
00294 FvdgPi0Limiter(const linDG3D::FvdgSpace& spc);
00296 virtual void operator() (const concepts::Function<Real> &fncY,
00297 concepts::Function<Real> &fncX) {
00298 diag_(fncY, fncX);
00299 }
00300 protected:
00301 concepts::DiagonalMatrix<Real> diag_;
00302 };
00303
00304
00308 class FvdgAdaptiveLimiter : public concepts::Operator<Real> {
00309 public:
00316 FvdgAdaptiveLimiter(const linDG3D::FvdgSpace& spc,
00317 const Real alpha,
00318 const Real lambda,
00319 concepts::BoundaryConditions* bc);
00321 virtual const concepts::Space<Real>& spaceX() const {
00322 return spc_;
00323 }
00325 virtual const concepts::Space<Real>& spaceY() const {
00326 return spc_;
00327 }
00332 virtual void operator() (const concepts::Function<Real> &fncY,
00333 concepts::Function<Real> &fncX);
00337 void getIndicator(concepts::Vector<Real> &indicator);
00338 protected:
00339 const linDG3D::FvdgSpace& spc_;
00340 concepts::BoundaryConditions* bc_;
00341 const Real alpha_;
00342 Real lambda_;
00343 std::map<const linDG3D::FvdgElement*, Real> elmIndicator_;
00344
00345 void limit_(concepts::Vector<Real>& vecX,
00346 const linDG3D::FvdgElement& elm) const;
00348 void reset_();
00351 void innerContrib_(const concepts::Vector<Real>& vecY,
00352 concepts::Vector<Real>& vecX);
00355 void bndryContrib_(const concepts::Vector<Real>& vecY,
00356 concepts::Vector<Real>& vecX);
00360 Real elmVolume_(const linDG3D::FvdgElement& elm) const;
00361 };
00362
00363 #endif // advection_hh