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

function/elementFormula.hh
Go to the documentation of this file.
00001 
00005 #ifndef elementFormVector_hh
00006 #define elementFormVector_hh
00007 
00008 #include "toolbox/hashMap.hh"
00009 #include "formula/exceptions.hh"
00010 #include "geometry/cell.hh"
00011 #include "space/element.hh"
00012 #include "space/formula.hh"
00013 #include "function/vector.hh"
00014 
00015 
00016 namespace concepts {
00017 
00018   template<typename F, typename G>
00019   class ElementFunction;     // declared in space/function.hh
00020 
00021   // **************************************************** ElementFormulaBase **
00022 
00033   template<typename F, class G, class H, class I>
00034   class ElementFormulaVectorBase : public ElementFormula<H,G> {
00035   public:
00041     ElementFormulaVectorBase(const Space<G>& spc, const Vector<F>& v,
00042                              const ElementFunction<I,G>& f);
00043   protected:
00044     const Space<G>& spc_;
00045     const Vector<F>& v_;
00047     std::auto_ptr<const ElementFunction<I,G> > f_;
00048 
00049     mutable const Element<G> *lastElm_, *lastElmOur_;
00050 
00051     mutable Array<F> coeff_;
00052 
00054     template<typename J, typename P>
00055     void compute_(const Element<G>& elm, Array<J>& val, const P& p,
00056                   const Real t = 0.0) const;
00057   private:
00059     __gnu_cxx::hash_map<uint, const Element<G>*> elementPointer_;
00060 
00062     uint getKey_(const Element<G>& elm) const;
00064     void getElement_(const Element<G>& elm, const Element<G>*& elmOur) const;
00065   };
00066 
00067   template<class F, class G, class H, class I>
00068   ElementFormulaVectorBase<F,G,H,I>::ElementFormulaVectorBase
00069   (const Space<G>& spc, const Vector<F>& v, const ElementFunction<I,G>& f) 
00070     : spc_(spc), v_(v), f_(f.clone()), lastElm_(0), lastElmOur_(0), coeff_(0)
00071   {
00072     Scan<Element<G> >* sc = spc_.scan();
00073     while (!sc->eos()) {
00074       const Element<G>& elm = (*sc)++;
00075       uint key = getKey_(elm);
00076       elementPointer_.insert
00077         (std::pair<uint, const Element<G>*>(key, &elm));
00078     }
00079   }
00080 
00081   template<class F, class G, class H, class I>
00082   uint ElementFormulaVectorBase<F,G,H,I>::getKey_(const Element<G>& elm) const{
00083     const ElementWithCell<G>* elmC =
00084       dynamic_cast<const ElementWithCell<G>*>(&elm);
00085     conceptsAssert(elmC, Assertion());
00086     const Cell& cell = elmC->cell();
00087     uint key = cell.connector().key().key();
00088     return key;
00089   }
00090 
00091   template<class F, class G, class H, class I>
00092   void ElementFormulaVectorBase<F,G,H,I>::getElement_
00093   (const Element<G>& elm, const Element<G>*& elmOur) const {
00094     uint key = getKey_(elm);
00095     typename __gnu_cxx::hash_map<uint, const Element<G>*>::const_iterator i =
00096       elementPointer_.find(key);
00097     if (i == elementPointer_.end())
00098       throw(ElementNotInDomainOfFormula(elm)); // this
00099     
00100     lastElmOur_ = elmOur = i->second;
00101     lastElm_    = &elm;
00102   }
00103 
00104   template<class F, class G, class H, class I>
00105   template<typename J, typename P>
00106   void ElementFormulaVectorBase<F,G,H,I>::compute_
00107   (const Element<G>& elm, Array<J>& val, const P& p, const Real t) const {
00108     const Element<G>* elmOur = 0;
00109     getElement_(elm, elmOur);
00110     conceptsAssert(elmOur, Assertion());
00111     elmOur->T().extract(v_, coeff_);
00112     (*f_)(*elmOur, coeff_, val, p, t);
00113   }
00114 
00115   // ********************************************* ElementFormulaVector<dim> **
00116 
00127   template<uint dim, class F = Real, class G = F,
00128            class H = typename Realtype<F>::type>
00129   class ElementFormulaVector : 
00130     public ElementFormulaVectorBase<F,H,Point<G,dim>,G> {
00131   public:
00136     ElementFormulaVector(const Space<H>& spc, const Vector<F>& v,
00137                          const ElementFunction<G,H>& f);
00138     virtual Point<G,dim> operator() (const ElementWithCell<H>& elm,
00139                                      const Real p, const Real t = 0.0) const;
00140     virtual Point<G,dim> operator() (const ElementWithCell<H>& elm,
00141                                      const Real2d& p, const Real t = 0.0) const;
00142     virtual Point<G,dim> operator() (const ElementWithCell<H>& elm,
00143                                      const Real3d& p, const Real t = 0.0) const;
00144 
00145     virtual ElementFormulaVector<dim,F,G,H>* clone() const {
00146       return new ElementFormulaVector(this->spc_, this->v_, *this->f_);
00147     }
00148   protected:
00149     virtual std::ostream& info(std::ostream& os) const;
00150   };
00151 
00152   template<uint dim, class F, class G, class H>
00153   ElementFormulaVector<dim,F,G,H>::ElementFormulaVector
00154   (const Space<H>& spc, const Vector<F>& v, const ElementFunction<G,H>& f) : 
00155     ElementFormulaVectorBase<F,H,Point<G,dim>,G>(spc, v, f) {
00156     conceptsAssert3(this->f_->n() == dim, Assertion(), "not matching "
00157         "number of vector components of element function");
00158   }
00159 
00160   template<uint dim, class F, class G, class H>
00161   Point<G,dim> ElementFormulaVector<dim,F,G,H>::operator()
00162     (const ElementWithCell<H>& elm, const Real p, const Real t) const {
00163     // get's function value
00164     Array<G> val;
00165     this->compute_(elm, val, p, t);
00166     conceptsAssert(val.size() == dim, Assertion());
00167     // copy it to a point
00168     Point<G,dim> res;
00169     memorycpy((G*)res, (const G*)val, dim);
00170     return res;
00171   }
00172 
00173   template<uint dim, class F, class G, class H>
00174   Point<G,dim> ElementFormulaVector<dim,F,G,H>::operator()
00175     (const ElementWithCell<H>& elm, const Real2d& p, const Real t) const {
00176     // get's function value
00177     Array<G> val;
00178     this->compute_(elm, val, p, t);
00179     conceptsAssert(val.size() == dim, Assertion());
00180     // copy it to a point
00181     Point<G,dim> res;
00182     memorycpy((G*)res, (const G*)val, dim);
00183     return res;
00184   }
00185 
00186 
00187   template<uint dim, class F, class G, class H>
00188   Point<G,dim> ElementFormulaVector<dim,F,G,H>::operator()
00189     (const ElementWithCell<H>& elm, const Real3d& p, const Real t) const {
00190     // get's function value
00191     Array<G> val;
00192     this->compute_(elm, val, p, t);
00193     conceptsAssert(val.size() == dim, Assertion());
00194     // copy it to a point
00195     Point<G,dim> res;
00196     memorycpy((G*)res, (const G*)val, dim);
00197     return res;
00198   }
00199 
00200   template<uint dim, class F, class G, class H>
00201   std::ostream& ElementFormulaVector<dim,F,G,H>::info(std::ostream& os) const {
00202     return os << "ElementFormulaVector<" << dim << ">(" << *this->f_ << ", "
00203         << this->v_ << ")";
00204   }
00205 
00206   // *********************************************** ElementFormulaVector<1> **
00207 
00213   template<class F, class G, class H>
00214   class ElementFormulaVector<1,F,G,H> : 
00215     public ElementFormulaVectorBase<F,H,G,G> {
00216   public:
00222     ElementFormulaVector(const Space<H>& spc, const Vector<F>& v,
00223                          const ElementFunction<G,H>& f);
00224     virtual G operator() (const ElementWithCell<H>& elm, const Real p,
00225                           const Real t = 0.0) const;
00226     virtual G operator() (const ElementWithCell<H>& elm, const Real2d& p,
00227                           const Real t = 0.0) const;
00228     virtual G operator() (const ElementWithCell<H>& elm, const Real3d& p,
00229                           const Real t = 0.0) const;
00230 
00231     virtual ElementFormulaVector<1,F,G,H>* clone() const {
00232       return new ElementFormulaVector(this->spc_, this->v_, *this->f_); 
00233     }
00234   protected:
00235     virtual std::ostream& info(std::ostream& os) const;
00236   };
00237 
00238   template<class F, class G, class H>
00239   ElementFormulaVector<1,F,G,H>::ElementFormulaVector
00240   (const Space<H>& spc, const Vector<F>& v, const ElementFunction<G,H>& f) : 
00241     ElementFormulaVectorBase<F,H,G,G>(spc, v, f) {
00242     conceptsAssert3(this->f_->n() == 1, Assertion(),
00243                     "only scalar element functions");
00244   }
00245 
00246   template<class F, class G, class H>
00247   G ElementFormulaVector<1,F,G,H>::operator()
00248     (const ElementWithCell<H>& elm, const Real p, const Real t) const {
00249     Array<G> res;
00250     this->compute_(elm, res, p, t);
00251     return res[0];
00252   }
00253 
00254   template<class F, class G, class H>
00255   G ElementFormulaVector<1,F,G,H>::operator()
00256     (const ElementWithCell<H>& elm, const Real2d& p, const Real t) const {
00257     Array<G> res;
00258     this->compute_(elm, res, p, t);
00259     return res[0];
00260   }
00261 
00262 
00263   template<class F, class G, class H>
00264   G ElementFormulaVector<1,F,G,H>::operator()
00265     (const ElementWithCell<H>& elm, const Real3d& p, const Real t) const {
00266     Array<G> res;
00267     this->compute_(elm, res, p, t);
00268     return res[0];
00269   }
00270 
00271   template<class F, class G, class H>
00272   std::ostream& ElementFormulaVector<1,F,G,H>::info(std::ostream& os) const {
00273     return os << "ElementFormulaVector<1>(" << *this->f_ << ", " << this->v_
00274         << ")";
00275   }
00276 
00277 } // namespace concepts
00278 
00279 #endif // elementFormVector_hh

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