Dune Core Modules (unstable)

localfiniteelementgeometry.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 © 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_GEOMETRY_PARAMETRIZEDGEOMETRY_HH
6#define DUNE_GEOMETRY_PARAMETRIZEDGEOMETRY_HH
7
8#include <cassert>
9#include <functional>
10#include <limits>
11#include <type_traits>
12#include <vector>
13
16#include <dune/common/math.hh>
18#include <dune/common/std/type_traits.hh>
19
20#include <dune/geometry/affinegeometry.hh> // for FieldMatrixHelper
22#include <dune/geometry/referenceelements.hh>
23#include <dune/geometry/type.hh>
24#include <dune/geometry/utility/algorithms.hh>
25#include <dune/geometry/utility/convergence.hh>
26
27namespace Dune {
28
38template <class LFE, int cdim>
40{
41 using LocalFiniteElement = LFE;
42 using LocalBasis = typename LFE::Traits::LocalBasisType;
43 using LocalBasisTraits = typename LocalBasis::Traits;
44
45public:
48
51
53 static const int coorddimension = cdim;
54
57
60
62 using Volume = decltype(power(std::declval<ctype>(),mydimension));
63
66
69
72
75
76public:
79 using ReferenceElement = typename ReferenceElements::ReferenceElement;
80
81protected:
82 using MatrixHelper = Impl::FieldMatrixHelper<ctype>;
83
84public:
87
103 LocalFiniteElementGeometry (const ReferenceElement& refElement,
104 const LocalFiniteElement& localFE,
105 std::vector<GlobalCoordinate> vertices)
106 : refElement_(refElement)
107 , localFE_(localFE)
108 , vertices_(std::move(vertices))
109 {
110 assert(localFE_.size() == vertices_.size());
111 }
112
126 template <class Param,
127 std::enable_if_t<std::is_invocable_r_v<GlobalCoordinate,Param,LocalCoordinate>, int> = 0>
128 LocalFiniteElementGeometry (const ReferenceElement& refElement,
129 const LocalFiniteElement& localFE,
130 Param&& parametrization)
131 : refElement_(refElement)
132 , localFE_(localFE)
133 {
134 localFE_.localInterpolation().interpolate(parametrization, vertices_);
135 }
136
143 template <class... Args>
144 explicit LocalFiniteElementGeometry (GeometryType gt, Args&&... args)
145 : LocalFiniteElementGeometry(ReferenceElements::general(gt), std::forward<Args>(args)...)
146 {}
147
149 int order () const
150 {
151 return localBasis().order();
152 }
153
155 bool affine () const
156 {
157 if (!affine_)
158 affine_.emplace(affineImpl());
159 return *affine_;
160 }
161
164 {
165 return refElement_.type();
166 }
167
169 int corners () const
170 {
171 return refElement_.size(mydimension);
172 }
173
176 {
177 assert( (i >= 0) && (i < corners()) );
178 return global(refElement_.position(i, mydimension));
179 }
180
183 {
184 return global(refElement_.position(0, 0));
185 }
186
199 {
200 thread_local std::vector<typename LocalBasisTraits::RangeType> shapeValues;
201 localBasis().evaluateFunction(local, shapeValues);
202 assert(shapeValues.size() == vertices_.size());
203
204 GlobalCoordinate out(0);
205 for (std::size_t i = 0; i < shapeValues.size(); ++i)
206 out.axpy(shapeValues[i], vertices_[i]);
207
208 return out;
209 }
210
228 LocalCoordinate local (const GlobalCoordinate& y, Impl::GaussNewtonOptions<ctype> opts = {}) const
229 {
230 LocalCoordinate x = refElement_.position(0,0);
231 Impl::GaussNewtonErrorCode err = Impl::gaussNewton(
232 [&](const LocalCoordinate& local) { return this->global(local); },
233 [&](const LocalCoordinate& local) { return this->jacobianTransposed(local); },
234 y, x, opts
235 );
236
237 if (err != Impl::GaussNewtonErrorCode::OK)
239 "Local coordinate can not be recovered from global coordinate, error code = " << int(err) << "\n"
240 << " (global(x) - y).two_norm() = " << (global(x) - y).two_norm()
241 << " > tol = " << opts.absTol);
242
243 return x;
244 }
245
257 {
258 return MatrixHelper::sqrtDetAAT(jacobianTransposed(local));
259 }
260
269 Volume volume (Impl::ConvergenceOptions<ctype> opts = {}) const
270 {
272 if (affine())
273 return vol0;
274
275 using std::abs;
276 for (int p = 2; p < opts.maxIt; ++p) {
278 if (abs(vol1 - vol0) < opts.absTol)
279 return vol1;
280
281 vol0 = vol1;
282 }
283 return vol0;
284 }
285
288 {
289 Volume vol(0);
290 for (const auto& qp : quadRule)
291 vol += integrationElement(qp.position()) * qp.weight();
292 return vol;
293 }
294
300 Jacobian jacobian (const LocalCoordinate& local) const
301 {
302 thread_local std::vector<typename LocalBasisTraits::JacobianType> shapeJacobians;
303 localBasis().evaluateJacobian(local, shapeJacobians);
304 assert(shapeJacobians.size() == vertices_.size());
305
306 Jacobian out(0);
307 for (std::size_t i = 0; i < shapeJacobians.size(); ++i) {
308 for (int j = 0; j < Jacobian::rows; ++j) {
309 shapeJacobians[i].umtv(vertices_[i][j], out[j]);
310 }
311 }
312 return out;
313 }
314
321 {
322 return jacobian(local).transposed();
323 }
324
333 {
334 JacobianInverse out;
335 MatrixHelper::leftInvA(jacobian(local), out);
336 return out;
337 }
338
347 {
348 return jacobianInverse(local).transposed();
349 }
350
352 friend ReferenceElement referenceElement (const LocalFiniteElementGeometry& geometry)
353 {
354 return geometry.refElement_;
355 }
356
358 const LocalFiniteElement& finiteElement () const
359 {
360 return localFE_;
361 }
362
364 const std::vector<GlobalCoordinate>& coefficients () const
365 {
366 return vertices_;
367 }
368
370 const LocalBasis& localBasis () const
371 {
372 return localFE_.localBasis();
373 }
374
375private:
376
377 bool affineImpl () const
378 {
379 if constexpr(mydimension == 0)
380 // point geometries are always affine mappings
381 return true;
382 else {
383 if (order() > 1)
384 // higher-order parametrizations are by definition not affine
385 return false;
386 if constexpr(mydimension == 1)
387 // linear line geometries are affine mappings
388 return true;
389 else {
390 if (type().isSimplex())
391 // linear simplex geometries are affine mappings
392 return true;
393
394 // multi-linear mappings on non-simplex geometries might be affine
395 // as well. This is tested explicitly for all vertices by constructing
396 // an affine mapping from dim+1 affine-independent corners and evaluating
397 // at the other corners.
398 auto refSimplex = referenceElement<ctype,mydimension>(GeometryTypes::simplex(mydimension));
399 auto simplexIndices = Dune::range(refSimplex.size(mydimension));
400 auto simplexCorners = Dune::transformedRangeView(simplexIndices,
401 [&](int i) { return this->global(refSimplex.position(i,mydimension)); });
402 AffineGeometry<ctype,mydimension,coorddimension> affineGeo(refSimplex,simplexCorners);
403 using std::sqrt;
404 const ctype tol = sqrt(std::numeric_limits<ctype>::epsilon());
405 for (int i = 0; i < corners(); ++i) {
406 const auto corner = refElement_.position(i,mydimension);
407 if ((affineGeo.global(corner) - global(corner)).two_norm() > tol)
408 return false;
409 }
410 return true;
411 }
412 }
413 }
414
415private:
417 ReferenceElement refElement_{};
418
420 LocalFiniteElement localFE_{};
421
423 std::vector<GlobalCoordinate> vertices_{};
424
425 mutable std::optional<bool> affine_ = std::nullopt;
426};
427
428namespace Impl {
429
430// extract the LocalCoordinate type from a LocalFiniteElement
431template <class LFE>
432using LocalCoordinate_t
433 = FieldVector<typename LFE::Traits::LocalBasisType::Traits::DomainFieldType,
434 LFE::Traits::LocalBasisType::Traits::dimDomain>;
435
436} // end namespace Impl
437
438
439// deduction guides
440template <class I, class LFE, class GlobalCoordinate>
441LocalFiniteElementGeometry (Geo::ReferenceElement<I>, const LFE&, std::vector<GlobalCoordinate>)
442 -> LocalFiniteElementGeometry<LFE, GlobalCoordinate::dimension>;
443
444template <class I, class LFE, class F,
445 class Range = std::invoke_result_t<F,Impl::LocalCoordinate_t<LFE>>>
446LocalFiniteElementGeometry (Geo::ReferenceElement<I>, const LFE&, const F&)
447 -> LocalFiniteElementGeometry<LFE, Range::dimension>;
448
449template <class LFE, class GlobalCoordinate>
450LocalFiniteElementGeometry (GeometryType, const LFE& localFE, std::vector<GlobalCoordinate>)
451 -> LocalFiniteElementGeometry<LFE, GlobalCoordinate::dimension>;
452
453template <class LFE, class F,
454 class Range = std::invoke_result_t<F,Impl::LocalCoordinate_t<LFE>>>
455LocalFiniteElementGeometry (GeometryType, const LFE&, const F&)
456 -> LocalFiniteElementGeometry<LFE, Range::dimension>;
457
458} // namespace Dune
459
460#endif // DUNE_GEOMETRY_PARAMETRIZEDGEOMETRY_HH
An implementation of the Geometry interface for affine geometries.
derived_type & axpy(const field_type &a, const DenseVector< Other > &x)
vector space axpy operation ( *this += a x )
Definition: densevector.hh:575
Base class for Dune-Exceptions.
Definition: exceptions.hh:96
static constexpr int rows
The number of rows.
Definition: fmatrix.hh:123
FieldMatrix< K, COLS, ROWS > transposed() const
Return transposed of the matrix as FieldMatrix.
Definition: fmatrix.hh:171
vector space out of a tensor product of fields.
Definition: fvector.hh:95
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:114
constexpr bool isSimplex() const
Return true if entity is a simplex of any dimension.
Definition: type.hh:319
Geometry implementation based on local-basis function parametrization.
Definition: localfiniteelementgeometry.hh:40
GeometryType type() const
Obtain the name of the reference element.
Definition: localfiniteelementgeometry.hh:163
decltype(power(std::declval< ctype >(), mydimension)) Volume
type of volume
Definition: localfiniteelementgeometry.hh:62
LocalFiniteElementGeometry(const ReferenceElement &refElement, const LocalFiniteElement &localFE, std::vector< GlobalCoordinate > vertices)
Constructor from a vector of coefficients of the LocalBasis parametrizing the geometry.
Definition: localfiniteelementgeometry.hh:103
JacobianTransposed jacobianTransposed(const LocalCoordinate &local) const
Obtain the transposed of the Jacobian.
Definition: localfiniteelementgeometry.hh:320
const LocalBasis & localBasis() const
The local basis of the stored local finite-element.
Definition: localfiniteelementgeometry.hh:370
typename LocalBasisTraits::DomainFieldType ctype
coordinate type
Definition: localfiniteelementgeometry.hh:47
JacobianInverseTransposed jacobianInverseTransposed(const LocalCoordinate &local) const
Obtain the transposed of the Jacobian's inverse.
Definition: localfiniteelementgeometry.hh:346
friend ReferenceElement referenceElement(const LocalFiniteElementGeometry &geometry)
Obtain the reference-element related to this geometry.
Definition: localfiniteelementgeometry.hh:352
LocalFiniteElementGeometry()=default
Default constructed geometry results in an empty/invalid representation.
bool affine() const
Is this mapping affine? This is only true for flat affine geometries.
Definition: localfiniteelementgeometry.hh:155
Jacobian jacobian(const LocalCoordinate &local) const
Obtain the Jacobian.
Definition: localfiniteelementgeometry.hh:300
Volume volume(const QuadratureRule< ctype, mydimension > &quadRule) const
Obtain the volume of the mapping's image by given quadrature rules.
Definition: localfiniteelementgeometry.hh:287
const std::vector< GlobalCoordinate > & coefficients() const
Obtain the coefficients of the parametrization.
Definition: localfiniteelementgeometry.hh:364
LocalFiniteElementGeometry(GeometryType gt, Args &&... args)
Constructor, forwarding to the other constructors that take a reference-element.
Definition: localfiniteelementgeometry.hh:144
static const int coorddimension
coordinate dimension
Definition: localfiniteelementgeometry.hh:53
int corners() const
Obtain number of corners of the corresponding reference element.
Definition: localfiniteelementgeometry.hh:169
GlobalCoordinate center() const
Obtain the centroid of the mapping's image.
Definition: localfiniteelementgeometry.hh:182
const LocalFiniteElement & finiteElement() const
Obtain the local finite-element.
Definition: localfiniteelementgeometry.hh:358
GlobalCoordinate global(const LocalCoordinate &local) const
Evaluate the coordinate mapping.
Definition: localfiniteelementgeometry.hh:198
GlobalCoordinate corner(int i) const
Obtain coordinates of the i-th corner.
Definition: localfiniteelementgeometry.hh:175
Volume volume(Impl::ConvergenceOptions< ctype > opts={}) const
Obtain the volume of the mapping's image.
Definition: localfiniteelementgeometry.hh:269
static const int mydimension
geometry dimension
Definition: localfiniteelementgeometry.hh:50
JacobianInverse jacobianInverse(const LocalCoordinate &local) const
Obtain the Jacobian's inverse.
Definition: localfiniteelementgeometry.hh:332
ctype integrationElement(const LocalCoordinate &local) const
Obtain the integration element.
Definition: localfiniteelementgeometry.hh:256
int order() const
Obtain the polynomial order of the parametrization.
Definition: localfiniteelementgeometry.hh:149
FieldVector< ctype, mydimension > LocalCoordinate
type of local coordinates
Definition: localfiniteelementgeometry.hh:56
LocalFiniteElementGeometry(const ReferenceElement &refElement, const LocalFiniteElement &localFE, Param &&parametrization)
Constructor from a local parametrization function, mapping local to (curved) global coordinates.
Definition: localfiniteelementgeometry.hh:128
Abstract base class for quadrature rules.
Definition: quadraturerules.hh:214
A container for all quadrature rules of dimension dim
Definition: quadraturerules.hh:260
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:158
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:453
auto transformedRangeView(R &&range, F &&f)
Create a TransformedRangeView.
Definition: rangeutilities.hh:670
Some useful basic math stuff.
Dune namespace.
Definition: alignedallocator.hh:13
constexpr Base power(Base m, Exponent p)
Power method for integer exponents.
Definition: math.hh:75
STL namespace.
Class providing access to the singletons of the reference elements.
Definition: referenceelements.hh:128
typename Container::ReferenceElement ReferenceElement
The reference element type.
Definition: referenceelements.hh:146
DF DomainFieldType
Export type for domain field.
Definition: localbasis.hh:37
static constexpr int dimDomain
dimension of the domain
Definition: localbasis.hh:40
A unique label for each type of element that can occur in a grid.
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)