version 3.11-dev
pq2hierarchicallocalfiniteelement.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_DISCRETIZATION_PQ2_HIERARCHICAL_LOCAL_FINITE_ELEMENT_HH
13#define DUMUX_DISCRETIZATION_PQ2_HIERARCHICAL_LOCAL_FINITE_ELEMENT_HH
14
15#include <array>
16#include <vector>
17
18#include <dune/common/fvector.hh>
19#include <dune/common/fmatrix.hh>
20
21#include <dune/geometry/type.hh>
22#include <dune/geometry/referenceelements.hh>
23
24#include <dune/localfunctions/common/localbasis.hh>
25#include <dune/localfunctions/common/localfiniteelementtraits.hh>
26#include <dune/localfunctions/common/localkey.hh>
27
28#include <dune/localfunctions/lagrange/lagrangesimplex.hh>
29#include <dune/localfunctions/lagrange/lagrangecube.hh>
30
31namespace Dumux::Detail {
32
33template<class D, class R, unsigned int dim, Dune::GeometryType::Id typeId>
35{
36 using PQ1FE = std::conditional_t<
37 Dune::GeometryType{ typeId } == Dune::GeometryTypes::cube(dim),
38 Dune::LagrangeCubeLocalFiniteElement<D, R, dim, 1>,
39 Dune::LagrangeSimplexLocalFiniteElement<D, R, dim, 1>
40 >;
41 using PQ2FE = std::conditional_t<
42 Dune::GeometryType{ typeId } == Dune::GeometryTypes::cube(dim),
43 Dune::LagrangeCubeLocalFiniteElement<D, R, dim, 2>,
44 Dune::LagrangeSimplexLocalFiniteElement<D, R, dim, 2>
45 >;
46
47public:
48 using Traits = Dune::LocalBasisTraits<
49 D, dim, Dune::FieldVector<D, dim>,
50 R, 1, Dune::FieldVector<R, 1>,
51 Dune::FieldMatrix<R, 1, dim>
52 >;
53
55 {
56 const auto refElement = Dune::referenceElement<D, dim>(type());
57 numVertices_ = refElement.size(dim);
58 }
59
60 static constexpr unsigned int size()
61 { return PQ2FE{}.size(); }
62
63 void evaluateFunction(const typename Traits::DomainType& x,
64 std::vector<typename Traits::RangeType>& out) const
65 {
66 out.resize(size());
67
68 // Evaluate both P1 and P2 bases
69 std::vector<typename Traits::RangeType> pq1Values, pq2Values;
70 pq1FE_.localBasis().evaluateFunction(x, pq1Values);
71 pq2FE_.localBasis().evaluateFunction(x, pq2Values);
72
73 // Hierarchical splitting
74 const auto& pq2Coeff = pq2FE_.localCoefficients();
75 for (std::size_t i = 0; i < size(); ++i)
76 {
77 const auto& key = pq2Coeff.localKey(i);
78 if (key.codim() == dim) // vertex DOF
79 out[i] = pq1Values[key.subEntity()];
80 else // remaining DOF
81 out[i] = pq2Values[i];
82 }
83 }
84
85 void evaluateJacobian(const typename Traits::DomainType& x,
86 std::vector<typename Traits::JacobianType>& out) const
87 {
88 out.resize(size());
89
90 std::vector<typename Traits::JacobianType> pq1Jac, pq2Jac;
91 pq1FE_.localBasis().evaluateJacobian(x, pq1Jac);
92 pq2FE_.localBasis().evaluateJacobian(x, pq2Jac);
93
94 // For each P2 DOF, use P1 if it's a vertex, otherwise use P2
95 const auto& pq2Coeff = pq2FE_.localCoefficients();
96 for (std::size_t i = 0; i < size(); ++i)
97 {
98 const auto& key = pq2Coeff.localKey(i);
99 if (key.codim() == dim) // vertex DOF
100 out[i] = pq1Jac[key.subEntity()];
101 else // remaining DOF
102 out[i] = pq2Jac[i];
103 }
104 }
105
106 void partial(const std::array<unsigned int, dim>& order,
107 const typename Traits::DomainType& in,
108 std::vector<typename Traits::RangeType>& out) const
109 {
110 out.resize(size());
111 std::vector<typename Traits::RangeType> pq1Partial, pq2Partial;
112 pq1FE_.localBasis().partial(order, in, pq1Partial);
113 pq2FE_.localBasis().partial(order, in, pq2Partial);
114
115 const auto& pq2Coeff = pq2FE_.localCoefficients();
116 for (std::size_t i = 0; i < size(); ++i)
117 {
118 const auto& key = pq2Coeff.localKey(i);
119 if (key.codim() == dim) // vertex DOF
120 out[i] = pq1Partial[key.subEntity()];
121 else // remaining DOF
122 out[i] = pq2Partial[i];
123 }
124 }
125
126 static constexpr unsigned int order()
127 { return 2; }
128
129 static constexpr Dune::GeometryType type()
130 { return { typeId }; }
131
132private:
133 PQ1FE pq1FE_;
134 PQ2FE pq2FE_;
135 std::size_t numVertices_;
136};
137
138template<int dim, Dune::GeometryType::Id typeId>
140{
141 using PQ2FE = std::conditional_t<
142 Dune::GeometryType{ typeId } == Dune::GeometryTypes::cube(dim),
143 Dune::LagrangeCubeLocalFiniteElement<double, double, dim, 2>,
144 Dune::LagrangeSimplexLocalFiniteElement<double, double, dim, 2>
145 >;
146
147public:
149 : p2Coeff_(PQ2FE{}.localCoefficients())
150 {}
151
152 static constexpr std::size_t size()
153 { return PQ2FE{}.size(); }
154
155 const Dune::LocalKey& localKey(std::size_t i) const
156 { return p2Coeff_.localKey(i); }
157
158 static constexpr Dune::GeometryType type()
159 { return { typeId }; }
160
161private:
162 typename PQ2FE::Traits::LocalCoefficientsType p2Coeff_;
163};
164
165template<class LocalBasis>
167{
168public:
169 template<typename F, typename C>
170 void interpolate(const F& f, std::vector<C>& out) const
171 {
172 DUNE_THROW(Dune::NotImplemented, "Local interpolation not implemented for PQ2 basis.");
173 }
174};
175
176} // end namespace Dumux::Detail
177
178namespace Dumux {
179
191template<class D, class R, int dim, Dune::GeometryType::Id typeId>
193{
197
198 static constexpr Dune::GeometryType gt = Dune::GeometryType{ typeId };
199 static_assert(
200 gt == Dune::GeometryTypes::cube(dim) || gt == Dune::GeometryTypes::simplex(dim),
201 "Only implemented for cubes and simplices"
202 );
203
204public:
205 using Traits = Dune::LocalFiniteElementTraits<Basis, Coefficients, Interpolation>;
206
207 const typename Traits::LocalBasisType& localBasis() const
208 { return basis_; }
209
210 const typename Traits::LocalCoefficientsType& localCoefficients() const
211 { return coefficients_; }
212
213 const typename Traits::LocalInterpolationType& localInterpolation() const
214 { return interpolation_; }
215
216 static constexpr std::size_t size()
217 { return Basis::size(); }
218
219 static constexpr Dune::GeometryType type()
220 { return Traits::LocalBasisType::type(); }
221
222private:
223 Basis basis_;
224 Coefficients coefficients_;
225 Interpolation interpolation_;
226};
227
228} // end namespace Dumux
229
230#endif
Definition: pq2hierarchicallocalfiniteelement.hh:35
void evaluateFunction(const typename Traits::DomainType &x, std::vector< typename Traits::RangeType > &out) const
Definition: pq2hierarchicallocalfiniteelement.hh:63
Dune::LocalBasisTraits< D, dim, Dune::FieldVector< D, dim >, R, 1, Dune::FieldVector< R, 1 >, Dune::FieldMatrix< R, 1, dim > > Traits
Definition: pq2hierarchicallocalfiniteelement.hh:52
static constexpr unsigned int order()
Definition: pq2hierarchicallocalfiniteelement.hh:126
static constexpr Dune::GeometryType type()
Definition: pq2hierarchicallocalfiniteelement.hh:129
static constexpr unsigned int size()
Definition: pq2hierarchicallocalfiniteelement.hh:60
void partial(const std::array< unsigned int, dim > &order, const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Definition: pq2hierarchicallocalfiniteelement.hh:106
void evaluateJacobian(const typename Traits::DomainType &x, std::vector< typename Traits::JacobianType > &out) const
Definition: pq2hierarchicallocalfiniteelement.hh:85
PQ2HierarchicalLocalBasis()
Definition: pq2hierarchicallocalfiniteelement.hh:54
Definition: pq2hierarchicallocalfiniteelement.hh:140
static constexpr std::size_t size()
Definition: pq2hierarchicallocalfiniteelement.hh:152
static constexpr Dune::GeometryType type()
Definition: pq2hierarchicallocalfiniteelement.hh:158
const Dune::LocalKey & localKey(std::size_t i) const
Definition: pq2hierarchicallocalfiniteelement.hh:155
PQ2HierarchicalLocalCoefficients()
Definition: pq2hierarchicallocalfiniteelement.hh:148
Definition: pq2hierarchicallocalfiniteelement.hh:167
void interpolate(const F &f, std::vector< C > &out) const
Definition: pq2hierarchicallocalfiniteelement.hh:170
Hierarchical P2/Q2 finite element.
Definition: pq2hierarchicallocalfiniteelement.hh:193
static constexpr Dune::GeometryType type()
Definition: pq2hierarchicallocalfiniteelement.hh:219
const Traits::LocalCoefficientsType & localCoefficients() const
Definition: pq2hierarchicallocalfiniteelement.hh:210
static constexpr std::size_t size()
Definition: pq2hierarchicallocalfiniteelement.hh:216
const Traits::LocalBasisType & localBasis() const
Definition: pq2hierarchicallocalfiniteelement.hh:207
Dune::LocalFiniteElementTraits< Basis, Coefficients, Interpolation > Traits
Definition: pq2hierarchicallocalfiniteelement.hh:205
const Traits::LocalInterpolationType & localInterpolation() const
Definition: pq2hierarchicallocalfiniteelement.hh:213
Definition: cvfelocalresidual.hh:30
Definition: adapt.hh:17