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
00018 template<typename F, typename G>
00019 class ElementFormula;
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
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
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
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
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
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
00278
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 }
00289
00290 #endif // spcFormula_hh
00291