lambdaFormula.hh

Go to the documentation of this file.
1 
9 #ifndef CONCEPTS_LAMBDAFORMULA
10 #define CONCEPTS_LAMBDAFORMULA
11 
12 #if __cplusplus >= 201103L
13 
14 #include "formula/formula.hh"
15 #include "elementFormula.hh"
16 #include "space/element.hh"
17 #include <type_traits>
18 
19 #if defined(__clang__)
20 #include <functional>
21 #endif
22 
23 #if defined(__GNUC__)
24 #if __GNUC__ >= 7
25 #include <functional>
26 #endif
27 #endif
28 
33 
34 namespace concepts {
35 
36  namespace detail {
37 
39  template<int CoordDim>
40  using CoordinateT = typename concepts::Coordinate<CoordDim>::type ;
41 
43  template<int CoordDim>
44  using CoordinateParamT = typename concepts::CoordinateParam<CoordDim>::type ;
45 
46  template<int Dim> struct CoordinateTag {};
48  template<int ParamDim, int Dim>
49  typename std::enable_if<Dim!=1,Point<Real,Dim>>::type elemMap_ (const concepts::ElementWithCell<concepts::Real> &elm,
50  CoordinateParamT<ParamDim> p,
51  CoordinateTag<ParamDim>,
52  CoordinateTag<Dim>) {
53  return elm.cell().elemMap(p);
54  }
55 
56  CoordinateT<1> elemMap_ (const concepts::ElementWithCell<concepts::Real> &elm,
57  CoordinateParamT<1> p,
58  CoordinateTag<1>,
59  CoordinateTag<1>);
60  CoordinateT<1> elemMap_ (const concepts::ElementWithCell<concepts::Real> &elm,
61  CoordinateParamT<2> p,
62  CoordinateTag<2>,
63  CoordinateTag<1>);
64  CoordinateT<1> elemMap_ (const concepts::ElementWithCell<concepts::Real> &elm,
65  CoordinateParamT<3> p,
66  CoordinateTag<3>,
67  CoordinateTag<1>);
68  }
69 
70  // **************************************** BaseLambdaElementFormula ***
71 
76  template<class Derived, class F>
77  class BaseLambdaElementFormula : public concepts::ElementFormula<F> {
78  public:
79  F operator() (const concepts::ElementWithCell<concepts::Real> &elm, detail::CoordinateParamT<1> p, const Real t=0.) const {
80  return static_cast<const Derived*>(this)->template impl_<1>(elm,p,t);
81  }
82  F operator() (const concepts::ElementWithCell<concepts::Real> &elm, detail::CoordinateParamT<2> p, const Real t=0.) const {
83  return static_cast<const Derived*>(this)->template impl_<2>(elm,p,t);
84  }
85  F operator() (const concepts::ElementWithCell<concepts::Real> &elm, detail::CoordinateParamT<3> p, const Real t=0.) const {
86  return static_cast<const Derived*>(this)->template impl_<3>(elm,p,t);
87  }
88  };
89 
90  // *********************************************** BaseLambdaFormula ***
91 
96  template<class Derived, class F>
97  class BaseLambdaFormula : public concepts::Formula<F> {
98  public:
99  F operator() (detail::CoordinateParamT<1> p, const Real t=0.) const {
100  return static_cast<const Derived*>(this)->template impl_<1>(p,t);
101  }
102  F operator() (detail::CoordinateParamT<2> p, const Real t=0.) const {
103  return static_cast<const Derived*>(this)->template impl_<2>(p,t);
104  }
105  F operator() (detail::CoordinateParamT<3> p, const Real t=0.) const {
106  return static_cast<const Derived*>(this)->template impl_<3>(p,t);
107  }
108  };
109 
110  // *************************************************** LambdaFormula ***
111 
117  template<int Dim, class F = concepts::Real>
118  class LambdaFormula :
119  public BaseLambdaFormula<LambdaFormula<Dim,F>,F> {
120  public:
121  using FieldT = F;
122  using FuncT = std::function<F(detail::CoordinateParamT<Dim>)>;
123 
124  template<class FuncParamT>
125  LambdaFormula(const FuncParamT& func) : func_(func) {}
126 
127  LambdaFormula* clone() const {
128  return new LambdaFormula(*this);
129  }
130 
131  private:
132  FuncT func_;
133 
134  template<int ParamDim>
135  F impl_ (detail::CoordinateParamT<ParamDim> p, const Real t) const
136  {
137  return func_(p);
138  }
139  friend class BaseLambdaFormula<LambdaFormula<Dim,F>,F>;
140  };
141 
142  // ******************************************** LambdaElementFormula ***
143 
148  template<int Dim, class F = concepts::Real>
149  class LambdaElementFormula :
150  public BaseLambdaElementFormula<LambdaElementFormula<Dim,F>,F> {
151  public:
152  using FieldT = F;
153  using FuncT = std::function<F(
155  detail::CoordinateParamT<Dim>)>;
156 
157  template<class FuncParamT>
158  LambdaElementFormula(const FuncParamT& func) : func_(func) {}
159 
160  LambdaElementFormula* clone() const {
161  return new LambdaElementFormula(*this);
162  }
163 
164  private:
165  FuncT func_;
166 
167  template<int ParamDim>
168  F impl_ (const concepts::ElementWithCell<concepts::Real> &elm,
169  detail::CoordinateParamT<ParamDim> p,
170  const concepts::Real t) const {
171  return /*Dim == ParamDim ? */
172  func_(elm,p) /*:
173  throw concepts::Assertion()*/;
174  }
175 
176  friend class BaseLambdaElementFormula<LambdaElementFormula<Dim,F>,F>;
177  };
178 }
179 
180 #endif // __cplusplus >= 201103L
181 
182 #endif // CONCEPTS_LAMBDAFORMULA
Interface for a formula.
Definition: lform.hh:18
Interface for a formula defined element by element.
virtual Real3d elemMap(const Real coord_local) const
Element map from point local coordinates in 1D.
virtual const Cell & cell() const =0
Returns the cell on which the element is built.
double Real
Type normally used for a floating point number.
Definition: typedefs.hh:36
Basic namespace for Concepts-2.
Definition: pml_formula.h:16
Page URL: http://wiki.math.ethz.ch/bin/view/Concepts/WebHome
21 August 2020
© 2020 Eidgenössische Technische Hochschule Zürich