Dune Core Modules (2.9.0)

localfiniteelementvariant.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3// SPDX-FileCopyrightInfo: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5#ifndef DUNE_LOCALFUNCTIONS_COMMON_LOCALFINITEELEMENTVARIANT_HH
6#define DUNE_LOCALFUNCTIONS_COMMON_LOCALFINITEELEMENTVARIANT_HH
7
8#include <cstddef>
9#include <type_traits>
10#include <variant>
11
13#include <dune/common/std/type_traits.hh>
14#include <dune/common/overloadset.hh>
15
16#include <dune/geometry/type.hh>
17
18#include <dune/localfunctions/common/localfiniteelementtraits.hh>
19#include <dune/localfunctions/common/localbasis.hh>
20#include <dune/localfunctions/common/localkey.hh>
21
22
23namespace Dune {
24
25namespace Impl {
26
27 // Helper for visiting a variant containing monostate.
28 // Since a generic lambda will in most cases not compile
29 // for monostate, we add special empty overloads for monostate.
30 // Hence visitIf will simply do nothing in the case of a
31 // monostate value.
32 template<class Visitor, class Variant>
33 void visitIf(Visitor&& visitor, Variant&& variant)
34 {
35 auto visitorWithFallback = overload([&](std::monostate&) {}, [&](const std::monostate&) {}, visitor);
36 std::visit(visitorWithFallback, variant);
37 }
38
39 template<class... Implementations>
40 class LocalBasisVariant
41 {
42
43 template<class I0, class... II>
44 struct FirstType
45 { using type = I0; };
46
47 using FirstImpTraits = typename FirstType<Implementations...>::type::Traits;
48
49 public:
50
51 // We do not simply copy Implementation::LocalBasisTraits because this
52 // may be implementation specific. To stay clean, we simply put all its
53 // data into the default LocalBasisTraits.
54 using Traits = typename Dune::LocalBasisTraits<
55 typename FirstImpTraits::DomainFieldType,
56 FirstImpTraits::dimDomain,
57 typename FirstImpTraits::DomainType,
58 typename FirstImpTraits::RangeFieldType,
59 FirstImpTraits::dimRange,
60 typename FirstImpTraits::RangeType,
61 typename FirstImpTraits::JacobianType>;
62
63 template<class Implementation>
64 LocalBasisVariant(const Implementation& impl) :
65 impl_(&impl),
66 size_(impl.size()),
67 order_(impl.order())
68 {}
69
70 LocalBasisVariant() = default;
71 LocalBasisVariant(const LocalBasisVariant& other) = default;
72 LocalBasisVariant(LocalBasisVariant&& other) = default;
73 LocalBasisVariant& operator=(const LocalBasisVariant& other) = default;
74 LocalBasisVariant& operator=(LocalBasisVariant&& other) = default;
75
79 unsigned int size() const
80 {
81 return size_;
82 }
83
87 unsigned int order() const
88 {
89 return order_;
90 }
91
95 inline void evaluateFunction(
96 const typename Traits::DomainType& x,
97 std::vector<typename Traits::RangeType>& out) const
98 {
99 Impl::visitIf([&](const auto* impl) { impl->evaluateFunction(x, out); }, impl_);
100 }
101
105 inline void evaluateJacobian(
106 const typename Traits::DomainType& x,
107 std::vector<typename Traits::JacobianType>& out) const
108 {
109 Impl::visitIf([&](const auto* impl) { impl->evaluateJacobian(x, out); }, impl_);
110 }
111
119 void partial(
120 const std::array<unsigned int,Traits::dimDomain>& order,
121 const typename Traits::DomainType& x,
122 std::vector<typename Traits::RangeType>& out) const
123 {
124 Impl::visitIf([&](const auto* impl) { impl->partial(order, x, out); }, impl_);
125 }
126
127 private:
128 std::variant<std::monostate, const Implementations*...> impl_;
129 std::size_t size_;
130 std::size_t order_;
131 };
132
133
134 template<class... Implementations>
135 class LocalCoefficientsVariant
136 {
137 public:
138
139 template<class Implementation>
140 LocalCoefficientsVariant(const Implementation& impl) :
141 impl_(&impl),
142 size_(impl.size())
143 {}
144
145 LocalCoefficientsVariant() = default;
146 LocalCoefficientsVariant(const LocalCoefficientsVariant& other) = default;
147 LocalCoefficientsVariant(LocalCoefficientsVariant&& other) = default;
148 LocalCoefficientsVariant& operator=(const LocalCoefficientsVariant& other) = default;
149 LocalCoefficientsVariant& operator=(LocalCoefficientsVariant&& other) = default;
150
154 unsigned int size() const
155 {
156 return size_;
157 }
158
159 const Dune::LocalKey& localKey (std::size_t i) const
160 {
161 // We can't use visitIf since we have to return something
162 // even for a monostate value. Since the return type is
163 // an l-value reference, we use a default constructed
164 // dummy LocalKey value.
165 static const Dune::LocalKey dummyLocalKey;
166 return std::visit(overload(
167 [&](const std::monostate&) -> decltype(auto) { return (dummyLocalKey);},
168 [&](const auto* impl) -> decltype(auto) { return impl->localKey(i); }), impl_);
169 }
170
171 private:
172 std::variant<std::monostate, const Implementations*...> impl_;
173 std::size_t size_;
174 };
175
176
177 template<class... Implementations>
178 class LocalInterpolationVariant
179 {
180 public:
181
182 template<class Implementation>
183 LocalInterpolationVariant(const Implementation& impl) :
184 impl_(&impl)
185 {}
186
187 LocalInterpolationVariant() = default;
188 LocalInterpolationVariant(const LocalInterpolationVariant& other) = default;
189 LocalInterpolationVariant(LocalInterpolationVariant&& other) = default;
190 LocalInterpolationVariant& operator=(const LocalInterpolationVariant& other) = default;
191 LocalInterpolationVariant& operator=(LocalInterpolationVariant&& other) = default;
192
193 template<typename F, typename C>
194 void interpolate (const F& ff, std::vector<C>& out) const
195 {
196 Impl::visitIf([&](const auto* impl) { impl->interpolate(ff, out); }, impl_);
197 }
198
199 private:
200 std::variant<std::monostate, const Implementations*...> impl_;
201 };
202
203} // namespace Impl
204
205
234 template<class... Implementations>
236 {
237
238 // In each LocalFooVariant we store a std::variant<std::monostate, const FooImpl*...>, i.e. a std::variant
239 // with the pointer to the Foo implementation unless LocalFiniteElementVariant stores a monostate. In this
240 // case each LocalFooVariant also stores a monostate (and not a monostate*).
241 using LocalBasis = Impl::LocalBasisVariant<typename Implementations::Traits::LocalBasisType...>;
242 using LocalCoefficients = Impl::LocalCoefficientsVariant<typename Implementations::Traits::LocalCoefficientsType...>;
243 using LocalInterpolation = Impl::LocalInterpolationVariant<typename Implementations::Traits::LocalInterpolationType...>;
244
245 // Update members after changing impl_
246 void updateMembers()
247 {
248 std::visit(overload(
249 [&](std::monostate&) {
250 localBasis_ = LocalBasis();
251 localCoefficients_ = LocalCoefficients();
252 localInterpolation_ = LocalInterpolation();
253 size_ = 0;
254 geometryType_ = GeometryType{};
255 }, [&](auto&& impl) {
256 localBasis_ = LocalBasis(impl.localBasis());
257 localCoefficients_ = LocalCoefficients(impl.localCoefficients());
258 localInterpolation_ = LocalInterpolation(impl.localInterpolation());
259 size_ = impl.size();
260 geometryType_ = impl.type();
261 }), impl_);
262 }
263
264 public:
265
270
275
279 LocalFiniteElementVariant(const std::monostate& monostate)
280 {}
281
288 template<class Implementation,
289 std::enable_if_t<std::disjunction<std::is_same<std::decay_t<Implementation>, Implementations>...>::value, int> = 0>
290 LocalFiniteElementVariant(Implementation&& impl) :
291 impl_(std::forward<Implementation>(impl))
292 {
293 updateMembers();
294 }
295
300 impl_(other.impl_)
301 {
302 updateMembers();
303 }
304
309 impl_(std::move(other.impl_))
310 {
311 updateMembers();
312 }
313
318 {
319 impl_ = other.impl_;
320 updateMembers();
321 return *this;
322 }
323
328 {
329 impl_ = std::move(other.impl_);
330 updateMembers();
331 return *this;
332 }
333
337 template<class Implementation,
338 std::enable_if_t<std::disjunction<std::is_same<std::decay_t<Implementation>, Implementations>...>::value, int> = 0>
339 LocalFiniteElementVariant& operator=(Implementation&& impl)
340 {
341 impl_ = std::forward<Implementation>(impl);
342 updateMembers();
343 return *this;
344 }
345
346
350 const typename Traits::LocalBasisType& localBasis() const
351 {
352 return localBasis_;
353 }
354
358 const typename Traits::LocalCoefficientsType& localCoefficients() const
359 {
360 return localCoefficients_;
361 }
362
366 const typename Traits::LocalInterpolationType& localInterpolation() const
367 {
368 return localInterpolation_;
369 }
370
374 unsigned int size() const
375 {
376 return size_;
377 }
378
382 constexpr GeometryType type() const
383 {
384 return geometryType_;
385 }
386
398 const auto& variant() const
399 {
400 return impl_;
401 }
402
408 operator bool () const
409 {
410 return not(std::holds_alternative<std::monostate>(variant()));
411 }
412
413 private:
414 std::variant<std::monostate, Implementations...> impl_;
415 std::size_t size_;
416 GeometryType geometryType_;
417 LocalBasis localBasis_;
418 LocalCoefficients localCoefficients_;
419 LocalInterpolation localInterpolation_;
420 };
421
422} // end namespace Dune
423
424#endif // DUNE_LOCALFUNCTIONS_COMMON_LOCALFINITEELEMENTVARIANT_HH
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:125
Type erasure class for wrapping LocalFiniteElement classes.
Definition: localfiniteelementvariant.hh:236
typename Dune::LocalFiniteElementTraits< LocalBasis, LocalCoefficients, LocalInterpolation > Traits
Export LocalFiniteElementTraits.
Definition: localfiniteelementvariant.hh:269
const auto & variant() const
Provide access to underlying std::variant.
Definition: localfiniteelementvariant.hh:398
unsigned int size() const
Number of shape functions.
Definition: localfiniteelementvariant.hh:374
constexpr GeometryType type() const
Number of shape functions.
Definition: localfiniteelementvariant.hh:382
LocalFiniteElementVariant(LocalFiniteElementVariant &&other)
Move constructor.
Definition: localfiniteelementvariant.hh:308
LocalFiniteElementVariant & operator=(Implementation &&impl)
Assignment from implementation.
Definition: localfiniteelementvariant.hh:339
const Traits::LocalBasisType & localBasis() const
Provide access to LocalBasis implementation of this LocalFiniteElement.
Definition: localfiniteelementvariant.hh:350
LocalFiniteElementVariant & operator=(const LocalFiniteElementVariant &other)
Copy assignment.
Definition: localfiniteelementvariant.hh:317
LocalFiniteElementVariant(const std::monostate &monostate)
Construct empty LocalFiniteElementVariant.
Definition: localfiniteelementvariant.hh:279
LocalFiniteElementVariant(const LocalFiniteElementVariant &other)
Copy constructor.
Definition: localfiniteelementvariant.hh:299
const Traits::LocalCoefficientsType & localCoefficients() const
Provide access to LocalCoefficients implementation of this LocalFiniteElement.
Definition: localfiniteelementvariant.hh:358
LocalFiniteElementVariant(Implementation &&impl)
Construct LocalFiniteElementVariant.
Definition: localfiniteelementvariant.hh:290
LocalFiniteElementVariant & operator=(LocalFiniteElementVariant &&other)
Move assignment.
Definition: localfiniteelementvariant.hh:327
const Traits::LocalInterpolationType & localInterpolation() const
Provide access to LocalInterpolation implementation of this LocalFiniteElement.
Definition: localfiniteelementvariant.hh:366
LocalFiniteElementVariant()=default
Construct empty LocalFiniteElementVariant.
Describe position of one degree of freedom.
Definition: localkey.hh:23
auto overload(F &&... f)
Create an overload set.
Definition: overloadset.hh:61
Dune namespace.
Definition: alignedallocator.hh:13
STL namespace.
Type traits for LocalBasisVirtualInterface.
Definition: localbasis.hh:34
traits helper struct
Definition: localfiniteelementtraits.hh:13
A unique label for each type of element that can occur in a grid.
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)