DUNE-FEM (unstable)

space.hh
1#ifndef DUNE_FEM_SPACE_RAVIARTTHOMAS_SPACE_HH
2#define DUNE_FEM_SPACE_RAVIARTTHOMAS_SPACE_HH
3
4#if HAVE_DUNE_LOCALFUNCTIONS
5
6// C++ includes
7#include <array>
8#include <tuple>
9
10// dune-common includes
12
13// dune-geometry includes
14#include <dune/geometry/type.hh>
15
16// dune-localfunction includes
17#include <dune/localfunctions/raviartthomas/raviartthomas02d.hh>
18#include <dune/localfunctions/raviartthomas/raviartthomas03d.hh>
19#include <dune/localfunctions/raviartthomas/raviartthomas0cube2d.hh>
20#include <dune/localfunctions/raviartthomas/raviartthomas0cube3d.hh>
21#include <dune/localfunctions/raviartthomas/raviartthomas12d.hh>
22#include <dune/localfunctions/raviartthomas/raviartthomas1cube2d.hh>
23#include <dune/localfunctions/raviartthomas/raviartthomas1cube3d.hh>
24#include <dune/localfunctions/raviartthomas/raviartthomas2cube2d.hh>
25#include <dune/localfunctions/raviartthomas/raviartthomas3cube2d.hh>
26#include <dune/localfunctions/raviartthomas/raviartthomas4cube2d.hh>
27#include <dune/localfunctions/common/virtualwrappers.hh>
28
29// dune-fem includes
30#include <dune/fem/space/common/uniquefacetorientation.hh>
31#include <dune/fem/space/basisfunctionset/piolatransformation.hh>
32#include <dune/fem/space/localfiniteelement/space.hh>
33
34
35namespace Dune
36{
37
38 namespace Fem
39 {
40
41 namespace Impl
42 {
43 // RaviartThomasLocalFiniteElement
44 // -------------------------------
45
46 template< unsigned int id, class DomainField, class RangeField, int dimension, int order >
47 struct RaviartThomasLocalFiniteElement
48 {
49 // 0 here means that the element is not implemented
50 static constexpr std::size_t numOrientations = 0;
51
52 RaviartThomasLocalFiniteElement()
53 {
54 DUNE_THROW(NotImplemented,"RaviartThomasLocalFiniteElement not implemented for your choice." );
55 }
56 };
57
58 // 2d, Simplex, 0th order
59 template< class D, class R >
60 struct RaviartThomasLocalFiniteElement< Dune::GeometryTypes::simplex( 2 ).id(), D, R, 2, 0 >
61 : public RT02DLocalFiniteElement< D, R >
62 {
63 static constexpr std::size_t numOrientations = 8; // 2^3
64 using RT02DLocalFiniteElement< D, R >::RT02DLocalFiniteElement;
65 };
66
67 // 2d, Simplex, 1st order
68 template< class D, class R >
69 struct RaviartThomasLocalFiniteElement< Dune::GeometryTypes::simplex( 2 ).id(), D, R, 2, 1 >
70 : public RT12DLocalFiniteElement< D, R >
71 {
72 static constexpr std::size_t numOrientations = 8; // 2^3
73 using RT12DLocalFiniteElement< D, R >::RT12DLocalFiniteElement;
74 };
75
76 // 3d, Simplex, 0th order
77 template< class D, class R >
78 struct RaviartThomasLocalFiniteElement< Dune::GeometryTypes::simplex( 3 ).id(), D, R, 3, 0 >
79 : public RT03DLocalFiniteElement< D, R >
80 {
81 static constexpr std::size_t numOrientations = 16; // 2^4
82 using RT03DLocalFiniteElement< D, R >::RT03DLocalFiniteElement;
83 };
84
85 // 2d, Cube, 0th order
86 template< class D, class R >
87 struct RaviartThomasLocalFiniteElement< Dune::GeometryTypes::cube( 2 ).id(), D, R, 2, 0 >
88 : public RT0Cube2DLocalFiniteElement< D, R >
89 {
90 static constexpr std::size_t numOrientations = 16; // 2^4
91 using RT0Cube2DLocalFiniteElement< D, R >::RT0Cube2DLocalFiniteElement;
92 };
93
94 // 2d, Cube, 1st order
95 template< class D, class R >
96 struct RaviartThomasLocalFiniteElement< Dune::GeometryTypes::cube( 2 ).id(), D, R, 2, 1 >
97 : public RT1Cube2DLocalFiniteElement< D, R >
98 {
99 static constexpr std::size_t numOrientations = 16; // 2^4
100 using RT1Cube2DLocalFiniteElement< D, R >::RT1Cube2DLocalFiniteElement;
101 };
102
103 // 2d, Cube, 2nd order
104 template< class D, class R >
105 struct RaviartThomasLocalFiniteElement< Dune::GeometryTypes::cube( 2 ).id(), D, R, 2, 2 >
106 : public RT2Cube2DLocalFiniteElement< D, R >
107 {
108 static constexpr std::size_t numOrientations = 16; // 2^4
109 using RT2Cube2DLocalFiniteElement< D, R >::RT2Cube2DLocalFiniteElement;
110 };
111
112 // 2d, Cube, 3rd order
113 template< class D, class R >
114 struct RaviartThomasLocalFiniteElement< Dune::GeometryTypes::cube( 2 ).id(), D, R, 2, 3 >
115 : public RT3Cube2DLocalFiniteElement< D, R >
116 {
117 static constexpr std::size_t numOrientations = 16; // 2^4
118 using RT3Cube2DLocalFiniteElement< D, R >::RT3Cube2DLocalFiniteElement;
119 };
120
121 // 2d, Cube, 4th order
122 template< class D, class R >
123 struct RaviartThomasLocalFiniteElement< Dune::GeometryTypes::cube( 2 ).id(), D, R, 2, 4 >
124 : public RT4Cube2DLocalFiniteElement< D, R >
125 {
126 static constexpr std::size_t numOrientations = 16; // 2^4
127 using RT4Cube2DLocalFiniteElement< D, R >::RT4Cube2DLocalFiniteElement;
128 };
129
130 // 3d, Cube, 0th order
131 template< class D, class R >
132 struct RaviartThomasLocalFiniteElement< Dune::GeometryTypes::cube( 3 ).id(), D, R, 3, 0 >
133 : public RT0Cube3DLocalFiniteElement< D, R >
134 {
135 static constexpr std::size_t numOrientations = 64; // 2^6
136 using RT0Cube3DLocalFiniteElement< D, R >::RT0Cube3DLocalFiniteElement;
137 };
138
139 // 3d, Cube, 1st order
140 template< class D, class R >
141 struct RaviartThomasLocalFiniteElement< Dune::GeometryTypes::cube( 3 ).id(), D, R, 3, 1 >
142 : public RT1Cube3DLocalFiniteElement< D, R >
143 {
144 static constexpr std::size_t numOrientations = 64; // 2^6
145 using RT1Cube3DLocalFiniteElement< D, R >::RT1Cube3DLocalFiniteElement;
146 };
147
148 } // namespace Impl
149
150 // RaviartThomasLocalFiniteElementMap
151 // ----------------------------------
152
153 template< class GridPart, class FunctionSpace, int polOrder = -1 >
154 class RaviartThomasLocalFiniteElementMap
155 {
156 using hasSingleGeometryType = GridPartCapabilities::hasSingleGeometryType< GridPart >;
157
158 static_assert( hasSingleGeometryType::v, "`GridPart` has more the one geometry type." );
159
160 static constexpr int dimLocal = GridPart::dimension;
161 static constexpr unsigned int topologyId = hasSingleGeometryType::topologyId;
162
163 static_assert( dimLocal == FunctionSpace::dimRange, "`dimRange` has to be equal to `GridPart::dimension`" );
164
165 using Geometry = typename GridPart::template Codim< 0 >::EntityType::Geometry;
166
167 public:
168 using GridPartType = GridPart;
169
170 using DomainFieldType = typename FunctionSpace::DomainFieldType;
171 using RangeFieldType = typename FunctionSpace::RangeFieldType;
172
173 typedef unsigned int KeyType;
174
175 using TransformationType = PiolaTransformation< Geometry, FunctionSpace::dimRange >;
176
177 protected:
178 // for dynamic space the polOrder is passed as negative value
179 static constexpr bool dynamicOrder = polOrder < 0;
180
181 using DomainType = typename FunctionSpace::DomainType;
182 using RangeType = typename FunctionSpace::RangeType;
183 typedef LocalBasisTraits<DomainFieldType, FunctionSpace::dimDomain, DomainType,
184 RangeFieldType, FunctionSpace::dimRange, RangeType,
186
187 // this is the same for each order, so take order 0 which exists for all combinations
188 static constexpr std::size_t numOrientations =
189 Impl::RaviartThomasLocalFiniteElement< topologyId, DomainFieldType, RangeFieldType, dimLocal, 0 >::numOrientations;
190
191 public:
192 // type of LocalFiniteElement
193 typedef typename std::conditional< dynamicOrder,
194 // virtual LFE type
195 LocalFiniteElementVirtualInterface< LBT >,
196 // real implementation type
197 Impl::RaviartThomasLocalFiniteElement< topologyId, DomainFieldType,
198 RangeFieldType, dimLocal, polOrder > > :: type LocalFiniteElementType;
199
200 using LocalBasisType = typename LocalFiniteElementType::Traits::LocalBasisType;
201 using LocalCoefficientsType = typename LocalFiniteElementType::Traits::LocalCoefficientsType;
202 using LocalInterpolationType = typename LocalFiniteElementType::Traits::LocalInterpolationType;
203
204 static constexpr auto size () -> std::size_t { return numOrientations; }
205
206 RaviartThomasLocalFiniteElementMap ( const GridPartType& gridPart, const unsigned int ord )
207 : orientation_( gridPart ), order_( dynamicOrder ? ord : polOrder )
208 {
209 if constexpr ( dynamicOrder )
210 {
211 if ( order_ == 0 )
212 this->template createLFE< 0 > ();
213 else if ( order_ == 1 )
214 this->template createLFE< 1 > ();
215 else if ( order_ == 2 )
216 this->template createLFE< 2 > ();
217 else if ( order_ == 3 )
218 this->template createLFE< 3 > ();
219 else if ( order_ == 4 )
220 this->template createLFE< 4 > ();
221 }
222 else
223 {
224 for ( auto i : range( size() ) )
225 map_[ i ].reset( new LocalFiniteElementType( i ) );
226 }
227 }
228
229 int order () const { return order_; }
230
231 template< class Entity >
232 int order ( const Entity& entity ) const { return order(); }
233
234 template< class Entity >
235 auto operator() ( const Entity& entity ) const
236 -> std::tuple< std::size_t, const LocalBasisType&, const LocalInterpolationType& >
237 {
238 auto o = orientation_( entity );
239 return std::tuple< std::size_t, const LocalBasisType&, const LocalInterpolationType& >(
240 static_cast< std::size_t >( o ), map( o ).localBasis(), map( o ).localInterpolation() );
241 }
242
243 auto localCoefficients ( const GeometryType& type ) const -> const LocalCoefficientsType&
244 {
245 return map( 0 ).localCoefficients();
246 }
247
248 bool hasCoefficients ( const GeometryType& type ) const { return type == GeometryType( topologyId, dimLocal ); }
249 auto gridPart () const -> const GridPartType& { return orientation_.gridPart(); }
250
251 private:
252 template <int p>
253 void createLFE()
254 {
255 using LFEImpl = Impl::RaviartThomasLocalFiniteElement< topologyId, DomainFieldType, RangeFieldType, dimLocal, p >;
256 if constexpr ( LFEImpl::numOrientations > 0 )
257 {
258 using LFEObject = LocalFiniteElementVirtualImp< LFEImpl >;
259 for ( auto i : range( size() ) )
260 {
261 LFEImpl imp( i );
262 map_[ i ].reset( new LFEObject( imp ) );
263 }
264 }
265 else
266 {
267 DUNE_THROW(NotImplemented,"RaviartThomasLocalFiniteElement not implemented for your choice." );
268 }
269 }
270
271 const LocalFiniteElementType& map( const size_t i ) const
272 {
273 assert( map_[i] );
274 return *(map_[i]);
275 }
276
277 UniqueFacetOrientation< GridPartType > orientation_;
278 std::array< std::unique_ptr< LocalFiniteElementType >, numOrientations > map_;
279
280 const int order_;
281 };
282
283
284 // RaviartThomasSpace
285 // ------------------
286
287 template< class FunctionSpace, class GridPart, int polOrder, class Storage = CachingStorage >
288 using RaviartThomasSpace
289 = LocalFiniteElementSpace< RaviartThomasLocalFiniteElementMap< GridPart, FunctionSpace, polOrder >, FunctionSpace, Storage >;
290
291 // dynamic polynomial order choice in this case
292 template< class FunctionSpace, class GridPart, class Storage = CachingStorage >
293 using DynamicRaviartThomasSpace
294 = LocalFiniteElementSpace< RaviartThomasLocalFiniteElementMap< GridPart, FunctionSpace >, FunctionSpace, Storage >;
295
296
297 } // namespace Fem
298
299} // namespace Dune
300
301#endif // HAVE_DUNE_LOCALFUNCTIONS
302
303#endif // #ifndef DUNE_FEM_SPACE_RAVIARTTHOMAS_SPACE_HH
FunctionSpaceTraits::DomainFieldType DomainFieldType
Intrinsic type used for values in the domain field (usually a double)
Definition: functionspaceinterface.hh:60
FunctionSpaceTraits::RangeType RangeType
Type of range vector (using type of range field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:71
@ dimDomain
dimension of domain vector space
Definition: functionspaceinterface.hh:46
@ dimRange
dimension of range vector space
Definition: functionspaceinterface.hh:48
FunctionSpaceTraits::LinearMappingType JacobianRangeType
Intrinsic type used for the jacobian values has a Dune::FieldMatrix type interface.
Definition: functionspaceinterface.hh:75
FunctionSpaceTraits::DomainType DomainType
Type of domain vector (using type of domain field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:67
FunctionSpaceTraits::RangeFieldType RangeFieldType
Intrinsic type used for values in the range field (usually a double)
Definition: functionspaceinterface.hh:63
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:462
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:453
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
free standing function for setting up a range based for loop over an integer range for (auto i: range...
Definition: rangeutilities.hh:288
Dune namespace
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
A unique label for each type of element that can occur in a grid.
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (May 9, 22:32, 2026)