3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
pq1bubblelocalfiniteelement.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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_DISCRETIZATION_PQ1BUBBLE_LOCAL_FINITE_ELEMENT_HH
25#define DUMUX_DISCRETIZATION_PQ1BUBBLE_LOCAL_FINITE_ELEMENT_HH
26
27#include <array>
28#include <vector>
29#include <numeric>
30#include <algorithm>
31
32#include <dune/common/fmatrix.hh>
33#include <dune/common/fvector.hh>
34#include <dune/common/exceptions.hh>
35
36#include <dune/geometry/type.hh>
37#include <dune/geometry/referenceelements.hh>
38
39#include <dune/localfunctions/common/localbasis.hh>
40#include <dune/localfunctions/common/localfiniteelementtraits.hh>
41#include <dune/localfunctions/common/localinterpolation.hh>
42#include <dune/localfunctions/common/localkey.hh>
43
44#include <dune/localfunctions/lagrange/lagrangesimplex.hh>
45#include <dune/localfunctions/lagrange/lagrangecube.hh>
46
47namespace Dumux::Detail {
48
57template<class D, class R, unsigned int dim, Dune::GeometryType::Id typeId>
59{
60 using PQ1FiniteElement = std::conditional_t<
61 Dune::GeometryType{ typeId } == Dune::GeometryTypes::cube(dim),
62 Dune::LagrangeCubeLocalFiniteElement<D, R, dim, 1>,
63 Dune::LagrangeSimplexLocalFiniteElement<D, R, dim, 1>
64 >;
65 static constexpr std::size_t numDofs
66 = Dune::GeometryType{ typeId } == Dune::GeometryTypes::cube(dim) ? (1<<dim)+1 : (dim+1)+1;
67public:
68 using Traits = Dune::LocalBasisTraits<
69 D, dim, Dune::FieldVector<D, dim>,
70 R, 1, Dune::FieldVector<R, 1>,
71 Dune::FieldMatrix<R, 1, dim>
72 >;
73
75 : pq1FiniteElement_{}
76 {
77 // precompute center values for normalization
78 const auto& p1Basis = pq1FiniteElement_.localBasis();
79 const auto refElement = Dune::referenceElement<typename Traits::DomainFieldType, dim>(type());
80 const auto& center = refElement.position(0, 0);
81 p1Basis.evaluateFunction(center, pq1AtCenter_);
82 }
83
87 static constexpr unsigned int size()
88 { return numDofs; }
89
93 void evaluateFunction(const typename Traits::DomainType& x,
94 std::vector<typename Traits::RangeType>& out) const
95 {
96 out.reserve(size());
97 const auto& p1Basis = pq1FiniteElement_.localBasis();
98 p1Basis.evaluateFunction(x, out);
99 const auto bubble = evaluateBubble_(x);
100 out.resize(size());
101 out.back() = bubble;
102 for (int i = 0; i < numDofs-1; ++i)
103 out[i] -= pq1AtCenter_[i]*out.back();
104 }
105
109 void evaluateJacobian(const typename Traits::DomainType& x,
110 std::vector<typename Traits::JacobianType>& out) const
111 {
112 out.reserve(size());
113 const auto& p1Basis = pq1FiniteElement_.localBasis();
114 p1Basis.evaluateJacobian(x, out);
115
116 std::vector<typename Traits::RangeType> shapeValues;
117 p1Basis.evaluateFunction(x, shapeValues);
118
119 const auto bubbleJacobian = evaluateBubbleJacobian_(x);
120
121 for (int i = 0; i < numDofs-1; ++i)
122 for (int k = 0; k < dim; ++k)
123 out[i][0][k] -= pq1AtCenter_[i]*bubbleJacobian[0][k];
124
125 out.resize(size());
126 out.back() = bubbleJacobian;
127 }
128
135 void partial(const std::array<unsigned int, dim>& order,
136 const typename Traits::DomainType& in,
137 std::vector<typename Traits::RangeType>& out) const
138 {
139 DUNE_THROW(Dune::NotImplemented, "Partial derivatives");
140 }
141
146 static constexpr unsigned int order()
147 {
148 return 1;
149 }
150
154 static constexpr Dune::GeometryType type()
155 {
156 return { typeId };
157 }
158private:
159 // evaluate bubble function at x
160 typename Traits::RangeType evaluateBubble_(const typename Traits::DomainType& x) const
161 {
162 if constexpr (type() == Dune::GeometryTypes::simplex(dim))
163 {
164 if constexpr (dim == 2)
165 return 27*x[0]*x[1]*(1-x[0]-x[1]);
166 else if constexpr (dim == 3)
167 return 256*x[0]*x[1]*x[2]*(1-x[0]-x[1]-x[2]);
168 }
169 else if constexpr (type() == Dune::GeometryTypes::cube(dim))
170 {
171 if constexpr (dim == 2)
172 return 16*x[0]*x[1]*(1-x[0])*(1-x[1]);
173 else if constexpr (dim == 3)
174 return 64*x[0]*x[1]*x[2]*(1-x[0])*(1-x[1])*(1-x[2]);
175 }
176 else
177 DUNE_THROW(Dune::NotImplemented, "Bubble function for " << type());
178 }
179
180 // evaluate bubble function at x
181 typename Traits::JacobianType evaluateBubbleJacobian_(const typename Traits::DomainType& x) const
182 {
183 if constexpr (type() == Dune::GeometryTypes::simplex(dim))
184 {
185 if constexpr (dim == 2)
186 return {{27*(x[1]*(1-x[0]-x[1]) - x[0]*x[1]),
187 27*(x[0]*(1-x[0]-x[1]) - x[0]*x[1])}};
188 else if constexpr (dim == 3)
189 return {{256*(x[1]*x[2]*(1-x[0]-x[1]-x[2]) - x[0]*x[1]*x[2]),
190 256*(x[0]*x[2]*(1-x[0]-x[1]-x[2]) - x[0]*x[1]*x[2]),
191 256*(x[0]*x[1]*(1-x[0]-x[1]-x[2]) - x[0]*x[1]*x[2])}};
192 }
193 else if constexpr (type() == Dune::GeometryTypes::cube(dim))
194 {
195 if constexpr (dim == 2)
196 return {{16*(x[1]*(1-x[0])*(1-x[1]) - x[0]*x[1]*(1-x[1])),
197 16*(x[0]*(1-x[0])*(1-x[1]) - x[0]*x[1]*(1-x[0]))}};
198 else if constexpr (dim == 3)
199 return {{64*(x[1]*x[2]*(1-x[0])*(1-x[1])*(1-x[2]) - x[0]*x[1]*x[2]*(1-x[1]))*(1-x[2]),
200 64*(x[0]*x[2]*(1-x[0])*(1-x[1])*(1-x[2]) - x[0]*x[1]*x[2]*(1-x[0]))*(1-x[2]),
201 64*(x[0]*x[1]*(1-x[0])*(1-x[1])*(1-x[2]) - x[0]*x[1]*x[2]*(1-x[0]))*(1-x[1])}};
202 }
203 else
204 DUNE_THROW(Dune::NotImplemented, "Bubble function for " << type() << " dim = " << dim);
205 }
206
207 PQ1FiniteElement pq1FiniteElement_;
208 std::vector<typename Traits::RangeType> pq1AtCenter_;
209};
210
216template<int dim, Dune::GeometryType::Id typeId>
218{
219 static constexpr std::size_t numDofs
220 = Dune::GeometryType{ typeId } == Dune::GeometryTypes::cube(dim) ? (1<<dim)+1 : (dim+1)+1;
221public:
222
224 {
225 // Dune::LocalKey is constructed with
226 // - the local index with respect to the subentity type
227 // - the codim of the subentity the dof is attached to
228 // - the local number of the function to evaluate
229
230 // vertex dofs
231 for (std::size_t i=0; i<size()-1; i++)
232 localKeys_[i] = Dune::LocalKey(i, dim, 0);
233
234 // cell dof
235 localKeys_.back() = Dune::LocalKey(0, 0, 0);
236 }
237
239 static constexpr std::size_t size ()
240 { return numDofs; }
241
243 const Dune::LocalKey& localKey (std::size_t i) const
244 { return localKeys_[i]; }
245
246private:
247 std::array<Dune::LocalKey, numDofs> localKeys_;
248};
249
255template<class LocalBasis>
257{
258public:
267 template<typename F, typename C>
268 void interpolate (const F& f, std::vector<C>& out) const
269 {
270 constexpr auto dim = LocalBasis::Traits::dimDomain;
271
272 out.resize(LocalBasis::size());
273
274 const auto refElement = Dune::referenceElement<typename LocalBasis::Traits::DomainFieldType,dim>(LocalBasis::type());
275
276 // Evaluate at the vertices and at the center
277 for (int i = 0; i < refElement.size(dim); ++i)
278 out[i] = f(refElement.position(i, dim));
279 out.back() = f(refElement.position(0, 0));
280 }
281};
282
283} // end namespace Dumux::Detail
284
285namespace Dumux {
286
295template<class D, class R, int dim, Dune::GeometryType::Id typeId>
297{
301
302 static constexpr Dune::GeometryType gt = Dune::GeometryType{ typeId };
303 static_assert(
304 gt == Dune::GeometryTypes::cube(dim) || gt == Dune::GeometryTypes::simplex(dim),
305 "Only implemented for cubes and simplices"
306 );
307
308public:
309 using Traits = Dune::LocalFiniteElementTraits<Basis, Coefficients, Interpolation>;
310
314 const typename Traits::LocalBasisType& localBasis() const
315 {
316 return basis_;
317 }
318
322 const typename Traits::LocalCoefficientsType& localCoefficients() const
323 {
324 return coefficients_;
325 }
326
330 const typename Traits::LocalInterpolationType& localInterpolation() const
331 {
332 return interpolation_;
333 }
334
338 static constexpr std::size_t size()
339 {
340 return Basis::size();
341 }
342
346 static constexpr Dune::GeometryType type()
347 {
348 return Traits::LocalBasisType::type();
349 }
350
351private:
352 Basis basis_;
353 Coefficients coefficients_;
354 Interpolation interpolation_;
355};
356
357} // end namespace Dumux
358
359#endif
Corners::value_type center(const Corners &corners)
The center of a given list of corners.
Definition: center.hh:36
Adaption of the non-isothermal two-phase two-component flow model to problems with CO2.
Definition: adapt.hh:29
Distance implementation details.
Definition: cvfelocalresidual.hh:37
P1/Q1 + Bubble on the reference element.
Definition: pq1bubblelocalfiniteelement.hh:59
void evaluateJacobian(const typename Traits::DomainType &x, std::vector< typename Traits::JacobianType > &out) const
Evaluate the Jacobians of all shape functions.
Definition: pq1bubblelocalfiniteelement.hh:109
static constexpr Dune::GeometryType type()
The reference element type.
Definition: pq1bubblelocalfiniteelement.hh:154
Dune::LocalBasisTraits< D, dim, Dune::FieldVector< D, dim >, R, 1, Dune::FieldVector< R, 1 >, Dune::FieldMatrix< R, 1, dim > > Traits
Definition: pq1bubblelocalfiniteelement.hh:72
static constexpr unsigned int order()
Evaluate the Jacobians of all shape functions we are actually cubic/quartic but cannot represent all ...
Definition: pq1bubblelocalfiniteelement.hh:146
void evaluateFunction(const typename Traits::DomainType &x, std::vector< typename Traits::RangeType > &out) const
Evaluate all shape functions.
Definition: pq1bubblelocalfiniteelement.hh:93
void partial(const std::array< unsigned int, dim > &order, const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate partial derivatives of any order of all shape functions.
Definition: pq1bubblelocalfiniteelement.hh:135
PQ1BubbleLocalBasis()
Definition: pq1bubblelocalfiniteelement.hh:74
static constexpr unsigned int size()
Number of shape functions (one for each vertex and one in the element)
Definition: pq1bubblelocalfiniteelement.hh:87
Associations of the P1/Q1 + Bubble degrees of freedom to the facets of the reference element.
Definition: pq1bubblelocalfiniteelement.hh:218
static constexpr std::size_t size()
Number of coefficients.
Definition: pq1bubblelocalfiniteelement.hh:239
PQ1BubbleLocalCoefficients()
Definition: pq1bubblelocalfiniteelement.hh:223
const Dune::LocalKey & localKey(std::size_t i) const
Get i-th local key.
Definition: pq1bubblelocalfiniteelement.hh:243
Evaluate the degrees of freedom of a P1 + Bubble basis.
Definition: pq1bubblelocalfiniteelement.hh:257
void interpolate(const F &f, std::vector< C > &out) const
Evaluate a given function at the vertices and the cell midpoint.
Definition: pq1bubblelocalfiniteelement.hh:268
P1/Q1 + Bubble finite element.
Definition: pq1bubblelocalfiniteelement.hh:297
const Traits::LocalInterpolationType & localInterpolation() const
Returns object that evaluates degrees of freedom.
Definition: pq1bubblelocalfiniteelement.hh:330
Dune::LocalFiniteElementTraits< Basis, Coefficients, Interpolation > Traits
Definition: pq1bubblelocalfiniteelement.hh:309
static constexpr std::size_t size()
The number of coefficients in the basis.
Definition: pq1bubblelocalfiniteelement.hh:338
static constexpr Dune::GeometryType type()
The reference element type that the local finite element is defined on.
Definition: pq1bubblelocalfiniteelement.hh:346
const Traits::LocalBasisType & localBasis() const
Returns the local basis, i.e., the set of shape functions.
Definition: pq1bubblelocalfiniteelement.hh:314
const Traits::LocalCoefficientsType & localCoefficients() const
Returns the assignment of the degrees of freedom to the element subentities.
Definition: pq1bubblelocalfiniteelement.hh:322