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 
23 namespace Dune {
24 
25 namespace 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
LocalFiniteElementVariant & operator=(const LocalFiniteElementVariant &other)
Copy assignment.
Definition: localfiniteelementvariant.hh:317
const Traits::LocalInterpolationType & localInterpolation() const
Provide access to LocalInterpolation implementation of this LocalFiniteElement.
Definition: localfiniteelementvariant.hh:366
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(const std::monostate &monostate)
Construct empty LocalFiniteElementVariant.
Definition: localfiniteelementvariant.hh:279
const Traits::LocalCoefficientsType & localCoefficients() const
Provide access to LocalCoefficients implementation of this LocalFiniteElement.
Definition: localfiniteelementvariant.hh:358
LocalFiniteElementVariant(const LocalFiniteElementVariant &other)
Copy constructor.
Definition: localfiniteelementvariant.hh:299
LocalFiniteElementVariant(Implementation &&impl)
Construct LocalFiniteElementVariant.
Definition: localfiniteelementvariant.hh:290
const auto & variant() const
Provide access to underlying std::variant.
Definition: localfiniteelementvariant.hh:398
LocalFiniteElementVariant & operator=(LocalFiniteElementVariant &&other)
Move assignment.
Definition: localfiniteelementvariant.hh:327
const Traits::LocalBasisType & localBasis() const
Provide access to LocalBasis implementation of this LocalFiniteElement.
Definition: localfiniteelementvariant.hh:350
LocalFiniteElementVariant & operator=(Implementation &&impl)
Assignment from implementation.
Definition: localfiniteelementvariant.hh:339
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
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.80.0 (Apr 27, 22:29, 2024)