00001
00002
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
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
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
00079 typename std::map<uint, const ElementWithCell<G>*>::
00080 const_iterator i = elm_.find(cell.key());
00081
00082 if (i != elm_.end()) return i->second;
00083
00084 const Connector* child = 0;
00085 for(uint j = 0; child = cell.child(j); ++j) {
00086 const ElementWithCell<G>* elm = element_(*child);
00087
00088 if (elm) return elm;
00089 }
00090
00091 return 0;
00092 }
00093
00094
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
00129 Array<H> val;
00130 (*this->fun_)(*elm, this->coeff_, val, p, t);
00131 conceptsAssert(val.size() == dim, Assertion());
00132
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
00146 Array<H> val;
00147 (*this->fun_)(*elm, this->coeff_, val, p, t);
00148 conceptsAssert(val.size() == dim, Assertion());
00149
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
00163 Array<H> val;
00164 (*this->fun_)(*elm, this->coeff_, val, p, t);
00165 conceptsAssert(val.size() == dim, Assertion());
00166
00167 memorycpy((H*)res, (const H*)val, dim);
00168 }
00169 return res;
00170 }
00171
00172
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
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
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
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 }
00251
00252 #endif // funFormula_hh
00253
00254