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

function/formula.hh
Go to the documentation of this file.
00001 /* Formulas 
00002    Formulas defined on FE solution
00003  */
00004 #ifndef funFormula_hh
00005 #define funFormula_hh
00006 
00007 #include <map>
00008 #include "basics/debug.hh"
00009 #include "basics/outputMatlab.hh"
00010 #include "space/formula.hh"
00011 #include "space/function.hh"
00012 #include "function/vector.hh"
00013 
00014 #define PWFormVecBaseConstr_D 0
00015 
00016 namespace concepts {
00017 
00018   // *************************************************** PiecewiseVectorBase **
00019 
00030   template<class F, class G, class H, class I>
00031   class PiecewiseFormulaVectorBase : public PiecewiseFormulaBase<H> {
00032   public:
00035     PiecewiseFormulaVectorBase(const Space<G>& spc, const Vector<F>& coeff,
00036                                const ElementFunction<I,G>& fun);
00037   protected:
00039     const Space<G>& spc_;
00041     Array<F> coeff_;
00043     const ElementFunction<I,G>* fun_;
00045     std::map<uint, const ElementWithCell<G>*> elm_;
00050     const ElementWithCell<G>* element_(const Connector& cell) const;
00051   };
00052 
00053   template<class F, class G, class H, class I>
00054   PiecewiseFormulaVectorBase<F,G,H,I>::PiecewiseFormulaVectorBase
00055   (const Space<G>& spc, const Vector<F>& coeff,
00056    const ElementFunction<I,G>& fun) 
00057     : spc_(spc), coeff_(spc_->dim()), fun_(&fun)
00058   {
00059     memorycpy((F*)coeff_, (const F*)coeff, spc_->dim());
00060     DEBUGL(PWFormVecBaseConstr_D, "Space = " << *spc_);
00061     // scanner over the elements
00062     Scan<Element<G> >* sc = spc_->scan();
00063     while(*sc) {
00064       const Element<G>& e = (*sc)++;
00065       DEBUGL(PWFormVecBaseConstr_D, "Element = " << e);
00066       const ElementWithCell<G>* elm = 
00067         dynamic_cast<const ElementWithCell<G>*>(&e);
00068       conceptsAssert(elm, concepts::Assertion());
00069       elm_[elm->cell().connector().key()] = elm;
00070     }
00071     DEBUGL(PWFormVecBaseConstr_D, "Mapping Cell -> Element = " <<
00072      (OutputMatlab<std::map<uint, const ElementWithCell<G>*> >(elm_)));
00073   }
00074 
00075   template<class F, class G, class H, class I>
00076   const ElementWithCell<G>* 
00077   PiecewiseFormulaVectorBase<F,G,H,I>::element_(const Connector& cell) const {
00078     // look for element to which the cell belongs to
00079     typename std::map<uint, const ElementWithCell<G>*>::
00080       const_iterator i = elm_.find(cell.key());
00081     // if such a cell exists return the element
00082     if (i != elm_.end()) return i->second;
00083     // look at the children cell and call the method recursivly
00084     const Connector* child = 0;
00085     for(uint j = 0; child = cell.child(j); ++j) {
00086       const ElementWithCell<G>* elm = element_(*child);
00087       // if a children cell belongs to a element return the element
00088       if (elm) return elm;
00089     }
00090     // no element found
00091     return 0;
00092   }
00093 
00094   // ************************************************** PiecewiseVector<dim> **
00095 
00096   template<uint dim, class F, class G, class H>
00097   class PiecewiseFormulaVector : 
00098     public PiecewiseFormulaVectorBase<F,G,Point<H,dim>,H> {
00099     public:
00100     PiecewiseFormulaVector(const Space<G>& spc, const Vector<F>& coeff,
00101                            const ElementFunction<H,G>& fun);
00102     virtual PiecewiseFormulaVector<dim,F,G,H>* clone() const {
00103       Array<F> c((const F*)this->coeff_, this->spc_.dim());
00104       const Vector<F> coeff(*this->spc_, (F*)c);
00105       return new PiecewiseFormulaVector<dim,F,G,H>(coeff, *this->fun_);
00106     }
00107     virtual Point<H,dim> operator()(const Connector& cell, const Real p,
00108             const Real t = 0.0) const;
00109     virtual Point<H,dim> operator()(const Connector& cell, const Real2d& p,
00110             const Real t = 0.0) const;
00111     virtual Point<H,dim> operator()(const Connector& cell, const Real3d& p,
00112             const Real t = 0.0) const;
00113   };
00114 
00115   template<uint dim, class F, class G, class H>
00116   PiecewiseFormulaVector<dim,F,G,H>::PiecewiseFormulaVector
00117   (const Space<G>& spc, const Vector<F>& coeff,
00118    const ElementFunction<H,G>& fun) :
00119     PiecewiseFormulaVectorBase<F,G,Point<H,dim>,H>(spc, coeff, fun) {}
00120 
00121   template<uint dim, class F, class G, class H>
00122   Point<H,dim> PiecewiseFormulaVector<dim,F,G,H>::operator()
00123     (const Connector& cell, const Real p, const Real t) const
00124   {
00125     const ElementWithCell<G>* elm = this->element_(cell);
00126     Point<H,dim> res;
00127     if (elm) {
00128       // get's function value
00129       Array<H> val;
00130       (*this->fun_)(*elm, this->coeff_, val, p, t);
00131       conceptsAssert(val.size() == dim, Assertion());
00132       // copy it to a point
00133       memorycpy((H*)res, (const H*)val, dim);
00134     }
00135     return res;
00136   }
00137 
00138   template<uint dim, class F, class G, class H>
00139   Point<H,dim> PiecewiseFormulaVector<dim,F,G,H>::operator()
00140     (const Connector& cell, const Real2d& p, const Real t) const
00141   {
00142     const ElementWithCell<G>* elm = this->element_(cell);
00143     Point<H,dim> res;
00144     if (elm) {
00145       // get's function value
00146       Array<H> val;
00147       (*this->fun_)(*elm, this->coeff_, val, p, t);
00148       conceptsAssert(val.size() == dim, Assertion());
00149       // copy it to a point
00150       memorycpy((H*)res, (const H*)val, dim);
00151     }
00152     return res;
00153   }
00154 
00155   template<uint dim, class F, class G, class H>
00156   Point<H,dim> PiecewiseFormulaVector<dim,F,G,H>::operator()
00157     (const Connector& cell, const Real3d& p, const Real t) const
00158   {
00159     const ElementWithCell<G>* elm = this->element_(cell);
00160     Point<H,dim> res;
00161     if (elm) {
00162       // get's function value
00163       Array<H> val;
00164       (*this->fun_)(*elm, this->coeff_, val, p, t);
00165       conceptsAssert(val.size() == dim, Assertion());
00166       // copy it to a point
00167       memorycpy((H*)res, (const H*)val, dim);
00168     }
00169     return res;
00170   }
00171 
00172   // ********************************************* PiecewiseFormulaVector<1> **
00173 
00174   template<class F, class G, class H>
00175   class PiecewiseFormulaVector<1,F,G,H> : 
00176     public PiecewiseFormulaVectorBase<F,G,H,H> {
00177     public:
00178     PiecewiseFormulaVector(const Space<G>& spc, const Vector<F>& coeff,
00179                            const ElementFunction<H,G>& fun);
00180     virtual PiecewiseFormulaVector<1,F,G,H>* clone() const {
00181       Array<F> c((const F*)this->coeff_, this->spc_.dim());
00182       const Vector<F> coeff(*this->spc_, (F*)c);
00183       return new PiecewiseFormulaVector<1,F,G,H>(coeff, *this->fun_);
00184     }
00185     virtual H operator()(const Connector& cell, const Real p,
00186        const Real t = 0.0) const;
00187     virtual H operator()(const Connector& cell, const Real2d& p,
00188        const Real t = 0.0) const;
00189     virtual H operator()(const Connector& cell, const Real3d& p,
00190        const Real t = 0.0) const;
00191   };
00192 
00193   template<class F, class G, class H>
00194   PiecewiseFormulaVector<1,F,G,H>::PiecewiseFormulaVector
00195   (const Space<G>& spc, const Vector<F>& coeff,
00196    const ElementFunction<H,G>& fun) :
00197     PiecewiseFormulaVectorBase<F,G,H,H>(spc, coeff, fun) {}
00198 
00199   template<class F, class G, class H>
00200   H PiecewiseFormulaVector<1,F,G,H>::operator()
00201     (const Connector& cell, const Real p, const Real t) const
00202   {
00203     const ElementWithCell<G>* elm = this->element_(cell);
00204     if (elm) {
00205       // get's function value
00206       Array<H> val;
00207       (*this->fun_)(*elm, this->coeff_, val, p, t);
00208       conceptsAssert(val.size() == 1, Assertion());
00209       return val[0];
00210     }
00211     return H(0);
00212   }
00213 
00214   template<class F, class G, class H>
00215   H PiecewiseFormulaVector<1,F,G,H>::operator()
00216     (const Connector& cell, const Real2d& p, const Real t) const
00217   {
00218     const ElementWithCell<G>* elm = this->element_(cell);
00219     DEBUGL(0, "Cell = " << cell);
00220     if (elm) {
00221       DEBUGL(0, "Element = " << *elm);
00222       // get's function value
00223       Array<H> val;
00224       (*this->fun_)(*elm, this->coeff_, val, p, t);
00225       conceptsAssert(val.size() == 1, Assertion());
00226       DEBUGL(0, "p = " << p << ", Value = " << val[0]);
00227       return val[0];
00228     }
00229     return H(0);
00230   }
00231 
00232   template<class F, class G, class H>
00233   H PiecewiseFormulaVector<1,F,G,H>::operator()
00234     (const Connector& cell, const Real3d& p, const Real t) const
00235   {
00236     DEBUGL(0, "Cell = " << cell);
00237     const ElementWithCell<G>* elm = this->element_(cell);
00238     if (elm) {
00239       DEBUGL(0, "Element = " << *elm);
00240       // get's function value
00241       Array<H> val;
00242       (*this->fun_)(*elm, this->coeff_, val, p, t);
00243       conceptsAssert(val.size() == 1, Assertion());
00244       DEBUGL(0, "p = " << p << ", Value = " << val[0]);
00245       return val[0];
00246     }
00247     return H(0);
00248   }
00249 
00250 } // namespace concepts
00251 
00252 #endif // funFormula_hh
00253 
00254 

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