Dune Core Modules (2.8.0)

referenceelements.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_GEOMETRY_REFERENCEELEMENTS_HH
4#define DUNE_GEOMETRY_REFERENCEELEMENTS_HH
5
6#include <cassert>
7
8#include <algorithm>
9#include <limits>
10#include <tuple>
11#include <utility>
12#include <vector>
13#include <array>
14
16#include <dune/common/std/type_traits.hh>
18
19#include <dune/geometry/dimension.hh>
20#include <dune/geometry/type.hh>
21#include <dune/geometry/referenceelement.hh>
22#include <dune/geometry/referenceelementimplementation.hh>
23
24namespace Dune
25{
26
27 namespace Geo
28 {
29
30#ifndef DOXYGEN
31
32
33 template<typename ctype, int dim>
34 class DeprecatedReferenceElement
35 : public ReferenceElement<ReferenceElementImplementation<ctype,dim>>
36 {
37
38 protected:
39
40 DeprecatedReferenceElement() = default;
41
42 public:
43
44 DeprecatedReferenceElement(const DeprecatedReferenceElement&) = delete;
45 DeprecatedReferenceElement& operator=(const DeprecatedReferenceElement&) = delete;
46
47 DeprecatedReferenceElement(const ReferenceElementImplementation<ctype,dim>& impl)
48 : ReferenceElement<ReferenceElementImplementation<ctype,dim>>(impl)
49 {}
50
51 };
52
53
54 template<typename ctype, int dim>
55 class ConstructibleDeprecatedReferenceElement
56 : public DeprecatedReferenceElement<ctype,dim>
57 {
58 public:
59 ConstructibleDeprecatedReferenceElement() = default;
60 };
61
62
63 namespace Impl
64 {
65
66 // ReferenceElementContainer
67 // -------------------------
68
69 template< class ctype, int dim >
70 class ReferenceElementContainer
71 {
72 static const unsigned int numTopologies = dim >= 0 ? (1u << dim) : 0;
73
74 using Implementation = ReferenceElementImplementation< ctype, dim >;
75 using ConstructibleDeprecatedReferenceElement = Dune::Geo::ConstructibleDeprecatedReferenceElement<ctype,dim>;
76
77 public:
78
79 using DeprecatedReferenceElement = Dune::Geo::DeprecatedReferenceElement<ctype,dim>;
80
82 using value_type = ReferenceElement;
83 using const_iterator = const value_type*;
84
85 ReferenceElementContainer ()
86 {
87 for( unsigned int topologyId = 0; topologyId < numTopologies; ++topologyId )
88 {
89 implementations_[ topologyId ].initialize( topologyId );
90 reference_elements_[ topologyId ].setImplementation( implementations_[ topologyId ] );
91 }
92 }
93
94 const ReferenceElement& operator() ( const GeometryType &type ) const
95 {
96 assert( type.dim() == dim );
97 return reference_elements_[ type.id() ];
98 }
99
100 const ReferenceElement& simplex () const
101 {
102 return reference_elements_[ Dune::GeometryTypes::simplex(dim).id() ];
103 }
104
105 const ReferenceElement& cube () const
106 {
107 return reference_elements_[ Dune::GeometryTypes::cube(dim).id() ];
108 }
109
110 const ReferenceElement& pyramid () const
111 {
112 return reference_elements_[ Dune::GeometryTypes::pyramid.id() ];
113 }
114
115 const ReferenceElement& prism () const
116 {
117 return reference_elements_[ Dune::GeometryTypes::prism.id() ];
118 }
119
120 const_iterator begin () const
121 {
122 return reference_elements_.data();
123 }
124
125 const_iterator end () const
126 {
127 return reference_elements_.data() + numTopologies;
128 }
129
130 // here, we make sure to actually return a const reference to something
131 // that is guaranteed not to become invalid, as otherwise, we might run
132 // straight into debugging hell when a user binds the return value to a
133 // const ref and the temporary goes out of scope.
134 const DeprecatedReferenceElement& deprecated(const ReferenceElement& v) const
135 {
136 return reference_elements_[v.impl().type(0,0).id()];
137 }
138
139 private:
140
141 std::array<Implementation,numTopologies> implementations_;
142 std::array<ConstructibleDeprecatedReferenceElement,numTopologies> reference_elements_;
143
144 };
145
146
147 } // namespace Impl
148
149
150#endif // DOXYGEN
151
152
153 // ReferenceElements
154 // ------------------------
155
166 template< class ctype_, int dim >
168 {
169
171 using ctype = ctype_;
172
175
177 static constexpr int dimension = dim;
178
179 private:
180
181 using Container = Impl::ReferenceElementContainer< ctype, dim >;
182
183 public:
184
187
189 using Iterator = typename Container::const_iterator;
190
193
195 static const ReferenceElement&
196 general ( const GeometryType& type )
197 {
198 return container() ( type );
199 }
200
202 static const ReferenceElement& simplex ()
203 {
204 return container().simplex();
205 }
206
208 static const ReferenceElement& cube ()
209 {
210 return container().cube();
211 }
212
213 static Iterator begin ()
214 {
215 return container().begin();
216 }
217
218 static Iterator end ()
219 {
220 return container().end();
221 }
222
223#ifndef DOXYGEN
224 static const typename Container::DeprecatedReferenceElement&
225 deprecated(const ReferenceElement& v)
226 {
227 return container().deprecated(v);
228 }
229#endif // DOXYGEN
230
231 private:
232
233 DUNE_EXPORT static const Container& container ()
234 {
235 static Container container;
236 return container;
237 }
238 };
239
240 } // namespace Geo
241
243 using Geo::ReferenceElements;
244
245
246#ifdef DOXYGEN
247
249
292 template<typename... T>
293 unspecified-value-type referenceElement(T&&... t);
294
295#endif
296
297
299
312 template<typename T, int dim>
314 {
316 }
317
318
320
332 template<typename T, int dim, std::enable_if_t<IsNumber<std::decay_t<T>>::value, int> = 0>
334 {
336 }
337
338
339#ifndef DOXYGEN
340
341 // helpers for the ReferenceElement<> meta function
342
343 namespace Impl {
344
345 // Evaluates to the correct reference element iff <T...> matches the pattern <number_type,Dim<int>>
346 // otherwise, it's ill-formed. Should be used with detected_or and friends.
347
348 template<typename... T>
349 struct DefaultReferenceElementExtractor;
350
351 template<typename T, typename std::enable_if<IsNumber<T>::value,int>::type dim>
352 struct DefaultReferenceElementExtractor<T,Dim<dim>>
353 {
355 };
356
357 template<typename... T>
358 using DefaultReferenceElement = typename DefaultReferenceElementExtractor<T...>::type;
359
360 }
361
362 // looks up the type of a reference element by trying to instantiate the correct overload
363 // of referenceElement() for the given arguments. This will fail if there is no valid
364 // overload and should be used with detected_or or some other utility that places the
365 // instantation in SFINAE context.
366 //
367 // this is placed directly in namespace Dune to avoid any weird surprises
368
369 template<typename... T>
370 using LookupReferenceElement = decltype(referenceElement(std::declval<T>()...));
371
372#endif // DOXYGEN
373
374 namespace Transitional {
375
376#ifndef DOXYGEN
377
378 // this abomination checks whether the template signature matches the special case
379 // ReferenceElement<number_type,Dune::Dim<int>> and otherwise defers the type lookup
380 // to a decltype on a call to referenceElement(std::declval<T>())
381
382 template<typename... T>
384 Std::detected_t<LookupReferenceElement,T...>,
385 Impl::DefaultReferenceElement,
386 T...
387 >;
388
389#else // DOXYGEN
390
392
414 template<typename... T>
415 using ReferenceElement = unspecified-type;
416
417#endif //DOXYGEN
418
419 }
420
421#ifndef DOXYGEN
422
423 namespace Impl {
424
425 // helpers for triggering a deprecation warning for occurences of the old
426 // ReferenceElement syntax (Dune::ReferenceElement<T,int>)
427
428 // this looks a little weird, encoding the type in the return type of a nested function,
429 // but it was the only reliable way to trigger the warning iff the compiler encounters
430 // an invalid use. Other solutions either miss some (or all) uses or trigger false alarms.
431
432 template<typename T>
433 struct ValidReferenceElementTypeSignature
434 {
436 };
437
438 template<typename T>
439 struct DeprecatedReferenceElementTypeSignature
440 {
441 [[deprecated("Dune::ReferenceElement<T,int> is deprecated, please use Dune::ReferenceElement<Geometry> (if you have a geometry), Dune::ReferenceElements<T,int>::ReferenceElement or Dune::Transitional::ReferenceElement<T,Dune::Dim<int>> instead. After Dune 2.6, you will be able to use Dune::ReferenceElement<T,Dune::Dim<int>>.")]] T check();
442 };
443
444 } // namespace Impl
445
446 // This just makes sure the user doesn't use invalid syntax (by checking against the -1 default for
447 // the dimension, and then either hands back the old-style type along with a deprecation warning or
448 // forwards to the transitional version
449 template<typename T, int dim = -1>
450 using ReferenceElement = decltype(
451 std::declval<
452 typename std::conditional<
453 dim == -1,
454 Impl::ValidReferenceElementTypeSignature<T>,
455 Impl::DeprecatedReferenceElementTypeSignature<Geo::DeprecatedReferenceElement<T,dim>>
456 >::type
457 >().check());
458
459#else // DOXYGEN
460
462
494 template<typename T, int dim>
495 using ReferenceElement = unspecified-type;
496
497#endif // DOXYGEN
498
499
500
501} // namespace Dune
502
503#endif // #ifndef DUNE_GEOMETRY_REFERENCEELEMENTS_HH
This class provides access to geometric and topological properties of a reference element.
Definition: referenceelement.hh:50
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:123
constexpr unsigned int id() const
Return the topology id of the type.
Definition: type.hh:374
Traits for type conversions and type information.
typename detected_or< Default, Op, Args... >::type detected_or_t
Returns Op<Args...> if that is valid; otherwise returns the fallback type Default.
Definition: type_traits.hh:370
typename detected_or< nonesuch, Op, Args... >::type detected_t
Returns Op<Args...> if that is valid; otherwise returns nonesuch.
Definition: type_traits.hh:355
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:156
unspecified-type ReferenceElement
Returns the type of reference element for the argument types T...
Definition: referenceelements.hh:415
unspecified value type referenceElement(T &&... t)
Returns a reference element for the objects t....
unspecified-type ReferenceElement
Returns the type of reference element for the argument type T.
Definition: referenceelements.hh:495
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:470
constexpr GeometryType prism
GeometryType representing a 3D prism.
Definition: type.hh:540
constexpr GeometryType pyramid
GeometryType representing a 3D pyramid.
Definition: type.hh:534
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:461
Dune namespace.
Definition: alignedallocator.hh:11
Static tag representing a dimension.
Definition: dimension.hh:14
Class providing access to the singletons of the reference elements.
Definition: referenceelements.hh:168
Iterator iterator
Iterator over available reference elements.
Definition: referenceelements.hh:192
typename Container::ReferenceElement ReferenceElement
The reference element type.
Definition: referenceelements.hh:186
static const ReferenceElement & cube()
get hypercube reference elements
Definition: referenceelements.hh:208
ctype_ ctype
The coordinate field type of the contained reference elements.
Definition: referenceelements.hh:171
static const ReferenceElement & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:196
static const ReferenceElement & simplex()
get simplex reference elements
Definition: referenceelements.hh:202
typename Container::const_iterator Iterator
Iterator over available reference elements.
Definition: referenceelements.hh:189
static constexpr int dimension
The dimension of the contained reference elements.
Definition: referenceelements.hh:177
ctype CoordinateField
The coordinate field type of the contained reference elements.
Definition: referenceelements.hh:174
A unique label for each type of element that can occur in a grid.
Definition of macros controlling symbol visibility at the ABI level.
#define DUNE_EXPORT
Export a symbol as part of the public ABI.
Definition: visibility.hh:18
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)