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;
00020
00021
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));
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
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
00164 Array<G> val;
00165 this->compute_(elm, val, p, t);
00166 conceptsAssert(val.size() == dim, Assertion());
00167
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
00177 Array<G> val;
00178 this->compute_(elm, val, p, t);
00179 conceptsAssert(val.size() == dim, Assertion());
00180
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
00191 Array<G> val;
00192 this->compute_(elm, val, p, t);
00193 conceptsAssert(val.size() == dim, Assertion());
00194
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
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 }
00278
00279 #endif // elementFormVector_hh