Go to the documentation of this file.00001
00008 #ifndef hp2dtraces_hh
00009 #define hp2dtraces_hh
00010
00011 #include "toolbox/sequence.hh"
00012 #include "formula/boundary.hh"
00013 #include "formula/exceptions.hh"
00014 #include "geometry/boundaryConditions.hh"
00015 #include "geometry/cellConditions.hh"
00016 #include "space/space.hh"
00017 #include "hp1D/element.hh"
00018 #include "hp2D/element.hh"
00019 #include "hp2D/edge.hh"
00020
00021 namespace hp2D {
00022
00023 using concepts::Real;
00024
00025
00026 template<typename F>
00027 class Quad;
00028
00029
00030
00044 class TraceSpace : public concepts::SpaceOnCells<Real> {
00045 public:
00046 typedef concepts::Scan<hp1D::Element<Real> > Scan;
00047 typedef concepts::ElementAndFacette<hp2D::Element<Real> > UnderlyingElement;
00048
00049 enum traceTypes { FIRST, MEAN, JUMP };
00050
00051
00058 TraceSpace(const concepts::SpaceOnCells<Real>& spc,
00059 const concepts::Set<uint> edgeAttr,
00060 enum traceTypes type = FIRST);
00061
00070 TraceSpace(concepts::SpaceOnCells<Real>& spc,
00071 const concepts::CellConditions* cc = 0,
00072 enum traceTypes type = FIRST);
00073 TraceSpace(const concepts::SpaceOnCells<Real>& spc,
00074 const concepts::CellConditions* cc = 0,
00075 enum traceTypes type = FIRST);
00076
00077 virtual ~TraceSpace();
00078
00079 virtual uint dim() const { return dim_; }
00080
00082 virtual uint nelm() const { return nelm_; }
00083
00085 virtual Scan* scan() const {
00086 return new concepts::PListScan<hp1D::Element<Real> >(*elm_);
00087 }
00088
00090 const concepts::Sequence<UnderlyingElement>
00091 uelm(const concepts::Edge edge) const {
00092 concepts::HashMap<concepts::Sequence<UnderlyingElement> >::
00093 const_iterator i = uelm_.find(edge.key());
00094 if (i == uelm_.end())
00095 return concepts::Sequence<UnderlyingElement>();
00096 return i->second;
00097 }
00098
00102 const concepts::HashMap<concepts::Sequence<UnderlyingElement> >
00103 uelm() const {
00104 return uelm_;
00105 }
00106
00110 virtual void recomputeShapefunctions();
00111 protected:
00112 virtual std::ostream& info(std::ostream& os) const;
00113 private:
00115 const uint dim_;
00116
00118 uint nelm_;
00119
00121 concepts::Joiner<hp1D::Element<Real>*, 1>* elm_;
00122
00124 concepts::HashMap<concepts::Sequence<UnderlyingElement> > uelm_;
00125
00127 concepts::HashMap<hp1D::Element<Real>* > edges_;
00128
00129 std::auto_ptr<QuadEdgeBase> quadEdge_;
00130
00131 bool warn_edgeBuildMissElem_;
00132
00133 void constructType_(enum traceTypes type);
00134
00138 template<class F>
00139 bool build_(const Quad<Real>* elm, F condition);
00140
00144 template<class F>
00145 void test_(const concepts::ElementWithCell<Real>& elm, F condition);
00146 };
00147
00148 }
00149
00150 namespace concepts {
00151
00152
00153
00161 template<typename F, typename G = typename Realtype<F>::type>
00162 class DirichletElementFormula : public ElementFormula<F,G> {
00163 public:
00164 DirichletElementFormula(const BoundaryConditions bc) : bc_(bc) {}
00165
00166 virtual F operator() (const ElementWithCell<G>& elm, const Real p,
00167 const Real t = 0.0) const;
00168 virtual F operator() (const ElementWithCell<G>& elm, const Real2d& p,
00169 const Real t = 0.0) const;
00170 virtual F operator() (const ElementWithCell<G>& elm, const Real3d& p,
00171 const Real t = 0.0) const;
00173 virtual DirichletElementFormula<F,G>* clone() const {
00174 return new DirichletElementFormula<F,G>(bc_);
00175 }
00176 protected:
00177 virtual std::ostream& info(std::ostream& os) const;
00178 private:
00179 const BoundaryConditions bc_;
00180
00181 template<typename P>
00182 F compute_(const Element<G>& elm, const P& p, const Real t) const {
00183 const ElementWithCell<G>* e =
00184 dynamic_cast<const ElementWithCell<G>*>(&elm);
00185 conceptsAssert(e, Assertion());
00186 const Cell& cell = e->cell();
00187 const Boundary b(bc_(cell.connector().attrib()));
00188 if (b.type() != Boundary::DIRICHLET)
00189 throw(ElementNotInDomainOfFormula(elm, *this));
00190
00191 F val = 0.0;
00192 if (!compute_(dynamic_cast<const Edge2d*>(&cell), b, p, t, val))
00193 throw conceptsException(concepts::MissingFeature
00194 ("element not supported"));
00195
00196 return val;
00197 }
00198
00199 bool compute_(const Edge2d* cell, const Boundary b,
00200 const Real p, const Real t, F& val) const {
00201 if (cell) {
00202 val = b(cell->chi(p), t);
00203 return true;
00204 }
00205 return false;
00206 }
00207
00208 template<typename P>
00209 bool compute_(const Edge2d* cell, const Boundary b,
00210 const P& p, const Real t, F& val) const {
00211 throw conceptsException(concepts::MissingFeature
00212 ("p should be a real"));
00213 return false;
00214 }
00215 };
00216
00217 }
00218
00219 #endif // hp2dtraces_hh