Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)

space/formula.hh
Go to the documentation of this file.
00001 
00004 #ifndef spcFormula_hh
00005 #define spcFormula_hh
00006 
00007 #include "basics/vectorsMatrices.hh"
00008 #include "toolbox/sharedPointer.hh"
00009 #include "formula/boundary.hh"
00010 #include "formula/formula.hh"
00011 #include "formula/vectorElementFormula.hh"
00012 #include "geometry/boundaryConditions.hh"
00013 #include "space/element.hh"
00014 
00015 namespace concepts {
00016 
00017   // forward declaration
00018   template<typename F, typename G>
00019   class ElementFormula;             // defined in formula/elementFormula.hh
00020 
00021 
00022 
00023   // **************************************************** ElementFormulaLiCo **
00024 
00025   /* Linear combination of two element formulas of type \c F and \c G.
00026 
00027      @param F type of the 1st element formula and the return value
00028      @param G type of the 2nd element formula
00029      @param H type of the factors in the linear combination
00030      @param J type of the element, mostly Real
00031 
00032      @author Kersten Schmidt, 2004
00033    */
00034 
00035   template<class F = Real, class G = F, class H = F,
00036            class J = typename Realtype<F>::type>
00037   class ElementFormulaLiCo : public ElementFormula<F,J> {
00038   public:
00039     ElementFormulaLiCo(const ElementFormula<F,J>& frm1,
00040                        const ElementFormula<G,J>& frm2,
00041                        H a = 1.0, H b = 1.0) :
00042       frm1_(frm1.clone()), frm2_(frm2.clone()), a_(a), b_(b) {}
00043     ElementFormulaLiCo(const ElementFormulaLiCo<F,G,H,J>& frm) :
00044       frm1_(frm.frm1_->clone()), frm2_(frm.frm2_->clone()), 
00045       a_(frm.a_), b_(frm.b_) {}
00046     virtual ~ElementFormulaLiCo() {
00047       frm1_.reset(0); frm2_.reset(0);
00048     }
00049     virtual F operator() (const ElementWithCell<J>& elm, const Real p,
00050         const Real t = 0.0) const { 
00051       return combine_(elm,p,t);
00052     }
00053     virtual F operator() (const ElementWithCell<J>& elm, const Real2d& p,
00054         const Real t = 0.0) const  { 
00055       return combine_(elm,p,t);
00056     }
00057     virtual F operator() (const ElementWithCell<J>& elm, const Real3d& p,
00058         const Real t = 0.0) const  { 
00059       return combine_(elm,p,t);
00060     }
00061     virtual ElementFormulaLiCo<F,G,H,J>* clone() const {
00062       return new ElementFormulaLiCo<F,G,H,J>(*frm1_, *frm2_);
00063     }
00064   protected:
00065     virtual std::ostream& info(std::ostream& os) const;
00066   private:
00068     std::auto_ptr<const ElementFormula<F,J> > frm1_;
00070     std::auto_ptr<const ElementFormula<G,J> > frm2_;
00072     const H a_, b_;
00074     template<typename P>
00075     F combine_(const ElementWithCell<J>& elm, const P& p,
00076          const Real t = 0.0) const;
00077   };
00078 
00079   template<typename F, typename G, typename H, typename J>
00080   template<typename P>
00081   F ElementFormulaLiCo<F,G,H,J>::combine_(const ElementWithCell<J>& elm, 
00082             const P& p, const Real t) const {
00083     F val1 = (*frm1_)(elm, p, t);
00084     G val2 = (*frm2_)(elm, p, t);
00085     return val1 * (F)a_ + val2 * (F)b_;
00086   }
00087 
00088   template<typename F, typename G, typename H, typename J>
00089   std::ostream& ElementFormulaLiCo<F,G,H,J>::info(std::ostream& os) const {
00090     return os << "ElementFormulaLiCo(" << a_ << " * " << *frm1_ << "+ " 
00091         << b_ << " * " << *frm2_ << ")";
00092   }
00093 
00094 //   template<class F, class G>
00095 //   ElementFormulaLiCo<F,G,Real> 
00096 //   operator+(const ElementFormula<F>& frm1,
00097 //             const ElementFormula<G>& frm2) 
00098 //   {
00099 //     return ElementFormulaLiCo<F,G,Real>(frm1, frm2, 1.0,  1.0);
00100 //   }
00101 
00102 //   template<class F, class G>
00103 //   ElementFormulaLiCo<F,G,Real> 
00104 //   operator-(const ElementFormula<F>& frm1,
00105 //             const ElementFormula<G>& frm2) 
00106 //   {
00107 //     return ElementFormulaLiCo<F,G,Real>(frm1, frm2, 1.0, -1.0);
00108 //   }
00109 
00110   // ************************************************* ElementFormulaCompose **
00111 
00112   /* Composition of two element formulas of type \c H to one of type \c F.
00113 
00114      \c F has to have a constructor of two \c H, like Real2d.
00115 
00116      @param F type of the return value, e.g. Real2d
00117      @param G type of the element, mostly Real
00118      @param H type of one element formula, e.g. Real
00119 
00120      @author Kersten Schmidt, 2004
00121    */
00122 
00123   template<typename F, typename G, typename H>
00124   class ElementFormulaCompose : public ElementFormula<F,G> {
00125   public:
00126     ElementFormulaCompose(const ElementFormula<H,G>& frm1,
00127                           const ElementFormula<H,G>& frm2) :
00128       frm1_(frm1.clone()), frm2_(frm2.clone()) {}
00129     ElementFormulaCompose(const ElementFormulaCompose<F,G,H>& frm) :
00130       frm1_(frm.frm1_->clone()), frm2_(frm.frm2_->clone()) {}
00131     virtual ~ElementFormulaCompose() {
00132       frm1_.reset(0); frm2_.reset(0);
00133     }
00134     virtual F operator() (const ElementWithCell<G>& elm, const Real p,
00135                           const Real t = 0.0) const { 
00136       return compose_(elm,p,t);
00137     }
00138     virtual F operator() (const ElementWithCell<G>& elm, const Real2d& p,
00139                           const Real t = 0.0) const  { 
00140       return compose_(elm,p,t);
00141     }
00142     virtual F operator() (const ElementWithCell<G>& elm, const Real3d& p,
00143                           const Real t = 0.0) const  { 
00144       return compose_(elm,p,t);
00145     }
00146     virtual ElementFormulaCompose<F,G,H>* clone() const {
00147       return new ElementFormulaCompose<F,G,H>(*frm1_, *frm2_);
00148     }
00149   protected:
00150     virtual std::ostream& info(std::ostream& os) const;
00151   private:
00152     std::auto_ptr<const ElementFormula<H,G> > frm1_, frm2_;
00153 
00154     template<typename P>
00155     F compose_(const ElementWithCell<G>& elm, const P& p, const Real t = 0.0) const;
00156   };
00157 
00158   template<typename F, typename G, typename H>
00159   template<typename P>
00160   F ElementFormulaCompose<F,G,H>::compose_(const ElementWithCell<G>& elm, 
00161              const P& p, const Real t) const {
00162     return F((*frm1_)(elm,p,t),(*frm2_)(elm,p,t));
00163   }
00164 
00165   template<typename F, typename G, typename H>
00166   std::ostream& ElementFormulaCompose<F,G,H>::info(std::ostream& os) const {
00167     return os << "ElementFormulaCompose(" << *frm1_ << ", " <<  *frm2_ << ")";
00168   }
00169 
00170   // ************************************************ ElementBoundaryFormula **
00171 
00174   class ElementFormulaBoundary : public ElementFormula<Real> {
00175   public:
00176     ElementFormulaBoundary
00177     (const BoundaryConditions bc,
00178      const Boundary::boundaryTypes bType = Boundary::DIRICHLET);
00184     virtual Real operator() (const ElementWithCell<Real>& elm, const Real p,
00185                              const Real t = 0.0) const;
00186     virtual Real operator() (const ElementWithCell<Real>& elm, const Real2d& p,
00187                              const Real t = 0.0) const;
00188     virtual Real operator() (const ElementWithCell<Real>& elm, const Real3d& p,
00189                              const Real t = 0.0) const;
00191     virtual ElementFormulaBoundary* clone() const;
00192   protected:
00193     virtual std::ostream& info(std::ostream& os) const;
00194   private:
00195     const BoundaryConditions bc_;
00196     const Boundary::boundaryTypes bType_;
00197   };
00198   
00199 
00200   // ************************************************ ElementFormulaRotate2D **
00201 
00206   template<class F>
00207   class ElementFormulaRotate2D : public ElementFormula<Point<F,2> > {
00208   public:
00210     ElementFormulaRotate2D
00211     (const ElementFormulaContainer<Point<F,2> > frm)
00212       : frm_(frm) {}
00213     virtual Point<F,2> operator()(const ElementWithCell<Real>& elm,
00214                                   const Real p, const Real t = 0.0) const;
00215     virtual Point<F,2> operator()(const ElementWithCell<Real>& elm,
00216                                   const Real2d& p, const Real t = 0.0) const;
00217     virtual Point<F,2> operator()(const ElementWithCell<Real>& elm,
00218                                   const Real3d& p, const Real t = 0.0) const;
00220     virtual ElementFormulaRotate2D<F>* clone() const {
00221       return new ElementFormulaRotate2D<F>(this->frm_);
00222     }
00223   protected:
00224     virtual std::ostream& info(std::ostream& os) const;
00225   private:
00226     const ElementFormulaContainer<Point<F,2> > frm_;
00227   };
00228 
00229 
00230   // ***************************************** FrmE_ScalarProductNormalEdge2d **
00231 
00241   template< class F = Real>
00242   class FrmE_ScalarProductNormalEdge2d : public ElementFormula< F > 
00243   {
00244   public:
00245     FrmE_ScalarProductNormalEdge2d
00246     (RCP<const ElementFormula< Point<F, 2> > > vf) 
00247       : vf_(vf)
00248     { }
00249 
00250     virtual FrmE_ScalarProductNormalEdge2d* clone() const {
00251       return new FrmE_ScalarProductNormalEdge2d(*this);
00252     }
00253 
00255     inline RCP<const ElementFormula< Point<F, 2> > > frm() const
00256     {
00257       return vf_;
00258     }
00259 
00261     inline RCP<const ElementFormula< Point<F, 2> > >& frm() 
00262     {
00263       return vf_;
00264     }
00265 
00266     virtual F operator() (const ElementWithCell<Real>& elm,
00267                           const Real p, const Real t = 0.0) const;
00268     virtual F operator() (const ElementWithCell<Real>& elm, 
00269                           const Real2d& p, const Real t = 0.0) const 
00270     {
00271       // In the same manner as for Real3d, albeit not that needed.
00272       return (*this)(elm, p[0], t);
00273     }
00274 
00275     virtual F operator() (const ElementWithCell<Real>& elm,
00276                           const Real3d& p, const Real t = 0.0) const {
00277       // This is necessary for general integration routine
00278       // (see space/integral.hh)
00279       return (*this)(elm, p[0], t);
00280     }
00281   protected:
00282     virtual std::ostream& info(std::ostream& os) const;
00283   public:
00284     RCP<const ElementFormula< Point<F, 2> > > vf_;
00285   };
00286 
00287 
00288 } // namespace concepts
00289 
00290 #endif // spcFormula_hh
00291 

Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)