dune-geometry 2.12-git
Loading...
Searching...
No Matches
localfiniteelementgeometry.hh
Go to the documentation of this file.
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_LOCALFINITEELEMENTGEOMETRY_HH
6#define DUNE_GEOMETRY_LOCALFINITEELEMENTGEOMETRY_HH
7
8#include <cassert>
9#include <functional>
10#include <limits>
11#include <type_traits>
12#include <vector>
13
17#include <dune/common/math.hh>
20
23#include <dune/geometry/type.hh>
27
28namespace Dune {
29
39template <class LFE, int cdim>
41{
42 using LocalFiniteElement = LFE;
43 using LocalBasis = typename LFE::Traits::LocalBasisType;
44 using LocalBasisTraits = typename LocalBasis::Traits;
45
46public:
48 using ctype = typename LocalBasisTraits::DomainFieldType;
49
51 static constexpr int mydimension = LocalBasisTraits::dimDomain;
52
54 static constexpr int coorddimension = cdim;
55
58
61
63 using Volume = decltype(power(std::declval<ctype>(),mydimension));
64
67
70
73
76
77public:
81
82protected:
83 using MatrixHelper = Impl::FieldMatrixHelper<ctype>;
84
85public:
88
105 const LocalFiniteElement& localFE,
107 : refElement_(refElement)
108 , localFE_(localFE)
109 , vertices_(std::move(vertices))
110 {
111 assert(localFE_.size() == vertices_.size());
112 }
113
127 template <class Param,
130 const LocalFiniteElement& localFE,
131 Param&& parametrization)
132 : refElement_(refElement)
133 , localFE_(localFE)
134 {
135 localFE_.localInterpolation().interpolate(parametrization, vertices_);
136 }
137
144 template <class... Args>
145 explicit LocalFiniteElementGeometry (GeometryType gt, Args&&... args)
146 : LocalFiniteElementGeometry(ReferenceElements::general(gt), std::forward<Args>(args)...)
147 {}
148
150 int order () const
151 {
152 return localBasis().order();
153 }
154
160 bool affine () const
161 {
162 if (!affine_)
163 affine_.emplace(affineImpl());
164 return *affine_;
165 }
166
169 {
170 return refElement_.type();
171 }
172
174 int corners () const
175 {
176 return refElement_.size(mydimension);
177 }
178
181 {
182 assert( (i >= 0) && (i < corners()) );
183 return global(refElement_.position(i, mydimension));
184 }
185
188 {
189 return global(refElement_.position(0, 0));
190 }
191
204 {
206 localBasis().evaluateFunction(local, shapeValues);
207 assert(shapeValues.size() == vertices_.size());
208
209 GlobalCoordinate out(0);
210 for (std::size_t i = 0; i < shapeValues.size(); ++i)
211 out.axpy(Impl::asNumber(shapeValues[i]), vertices_[i]);
212
213 return out;
214 }
215
233 LocalCoordinate local (const GlobalCoordinate& y, Impl::GaussNewtonOptions<ctype> opts = {}) const
234 {
235 LocalCoordinate x = refElement_.position(0,0);
236 Impl::GaussNewtonErrorCode err = Impl::gaussNewton(
237 [&](const LocalCoordinate& local) { return this->global(local); },
238 [&](const LocalCoordinate& local) { return this->jacobianTransposed(local); },
239 y, x, opts
240 );
241
242 if (err != Impl::GaussNewtonErrorCode::OK)
244 "Local coordinate can not be recovered from global coordinate, error code = " << int(err) << "\n"
245 << " (global(x) - y).two_norm() = " << (global(x) - y).two_norm()
246 << " > tol = " << opts.absTol);
247
248 return x;
249 }
250
262 {
263 return MatrixHelper::sqrtDetAAT(jacobianTransposed(local));
264 }
265
277 Volume volume (Impl::ConvergenceOptions<ctype> opts = {}) const
278 {
280 if (affine())
281 return vol0;
282
283 using std::abs;
284 for (int p = 2; p < opts.maxIt; ++p) {
286 if (abs(vol1 - vol0) < opts.absTol)
287 return vol1;
288
289 vol0 = vol1;
290 }
291 return vol0;
292 }
293
296 {
297 Volume vol(0);
298 for (const auto& qp : quadRule)
299 vol += integrationElement(qp.position()) * qp.weight();
300 return vol;
301 }
302
309 {
311 localBasis().evaluateJacobian(local, shapeJacobians);
312 assert(shapeJacobians.size() == vertices_.size());
313
314 Jacobian out(0);
315 for (std::size_t i = 0; i < shapeJacobians.size(); ++i) {
316 for (int j = 0; j < Jacobian::rows; ++j) {
317 shapeJacobians[i].umtv(vertices_[i][j], out[j]);
318 }
319 }
320 return out;
321 }
322
332
341 {
342 JacobianInverse out;
343 MatrixHelper::leftInvA(jacobian(local), out);
344 return out;
345 }
346
358
361 {
362 return geometry.refElement_;
363 }
364
366 const LocalFiniteElement& finiteElement () const
367 {
368 return localFE_;
369 }
370
373 {
374 return vertices_;
375 }
376
378 const LocalBasis& localBasis () const
379 {
380 return localFE_.localBasis();
381 }
382
383private:
384
385 bool affineImpl () const
386 {
387 if constexpr(mydimension == 0)
388 // point geometries are always affine mappings
389 return true;
390 else {
391 if (order() > 1)
392 // higher-order parametrizations are by definition not affine
393 return false;
394 if constexpr(mydimension == 1)
395 // linear line geometries are affine mappings
396 return true;
397 else {
398 if (type().isSimplex())
399 // linear simplex geometries are affine mappings
400 return true;
401
402 // multi-linear mappings on non-simplex geometries might be affine
403 // as well. This is tested explicitly for all vertices by constructing
404 // an affine mapping from dim+1 affine-independent corners and evaluating
405 // at the other corners.
406 auto refSimplex = referenceElement<ctype,mydimension>(GeometryTypes::simplex(mydimension));
407 auto simplexIndices = Dune::range(refSimplex.size(mydimension));
408 auto simplexCorners = Dune::transformedRangeView(simplexIndices,
409 [&](int i) { return this->global(refSimplex.position(i,mydimension)); });
410 AffineGeometry<ctype,mydimension,coorddimension> affineGeo(refSimplex,simplexCorners);
411 using std::sqrt;
412 const ctype tol = sqrt(std::numeric_limits<ctype>::epsilon());
413 for (int i = 0; i < corners(); ++i) {
414 const auto corner = refElement_.position(i,mydimension);
415 if ((affineGeo.global(corner) - global(corner)).two_norm() > tol)
416 return false;
417 }
418 return true;
419 }
420 }
421 }
422
423private:
425 ReferenceElement refElement_{};
426
428 LocalFiniteElement localFE_{};
429
432
433 mutable std::optional<bool> affine_ = std::nullopt;
434};
435
436namespace Impl {
437
438// extract the LocalCoordinate type from a LocalFiniteElement
439template <class LFE>
440using LocalCoordinate_t
441 = FieldVector<typename LFE::Traits::LocalBasisType::Traits::DomainFieldType,
442 LFE::Traits::LocalBasisType::Traits::dimDomain>;
443
444} // end namespace Impl
445
446
447// deduction guides
448template <class I, class LFE, class GlobalCoordinate>
451
452template <class I, class LFE, class F,
456
457template <class LFE, class GlobalCoordinate>
460
461template <class LFE, class F,
465
466} // namespace Dune
467
468#endif // DUNE_GEOMETRY_LOCALFINITEELEMENTGEOMETRY_HH
A unique label for each type of element that can occur in a grid.
STL namespace.
auto transformedRangeView(R &&range, F &&f)
static constexpr IntegralRange< T > range(T from, T to) noexcept
#define DUNE_THROW(E,...)
const GlobalIndex & global() const
LocalIndex & local()
constexpr Base power(Base m, Exponent p)
static constexpr std::integral_constant< int, ROWS > rows
constexpr FieldMatrix< K, COLS, ROWS > transposed() const
constexpr derived_type & axpy(const field_type &a, const DenseVector< Other > &x)
This class provides access to geometric and topological properties of a reference element.
Definition referenceelement.hh:52
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
Geometry implementation based on local-basis function parametrization.
Definition localfiniteelementgeometry.hh:41
GeometryType type() const
Obtain the name of the reference element.
Definition localfiniteelementgeometry.hh:168
decltype(power(std::declval< ctype >(), mydimension)) Volume
type of volume
Definition localfiniteelementgeometry.hh:63
LocalCoordinate local(const GlobalCoordinate &y, Impl::GaussNewtonOptions< ctype > opts={}) const
Evaluate the inverse coordinate mapping.
Definition localfiniteelementgeometry.hh:233
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:104
JacobianTransposed jacobianTransposed(const LocalCoordinate &local) const
Obtain the transposed of the Jacobian.
Definition localfiniteelementgeometry.hh:328
static constexpr int coorddimension
coordinate dimension
Definition localfiniteelementgeometry.hh:54
const LocalBasis & localBasis() const
The local basis of the stored local finite-element.
Definition localfiniteelementgeometry.hh:378
typename LocalBasisTraits::DomainFieldType ctype
coordinate type
Definition localfiniteelementgeometry.hh:48
JacobianInverseTransposed jacobianInverseTransposed(const LocalCoordinate &local) const
Obtain the transposed of the Jacobian's inverse.
Definition localfiniteelementgeometry.hh:354
friend ReferenceElement referenceElement(const LocalFiniteElementGeometry &geometry)
Obtain the reference-element related to this geometry.
Definition localfiniteelementgeometry.hh:360
LocalFiniteElementGeometry()=default
Default constructed geometry results in an empty/invalid representation.
bool affine() const
Is this mapping affine? Geometries of order 1 might be affine, but it needs to be checked on non-simp...
Definition localfiniteelementgeometry.hh:160
Jacobian jacobian(const LocalCoordinate &local) const
Obtain the Jacobian.
Definition localfiniteelementgeometry.hh:308
Volume volume(const QuadratureRule< ctype, mydimension > &quadRule) const
Obtain the volume of the mapping's image by given quadrature rules.
Definition localfiniteelementgeometry.hh:295
const std::vector< GlobalCoordinate > & coefficients() const
Obtain the coefficients of the parametrization.
Definition localfiniteelementgeometry.hh:372
LocalFiniteElementGeometry(GeometryType gt, Args &&... args)
Constructor, forwarding to the other constructors that take a reference-element.
Definition localfiniteelementgeometry.hh:145
int corners() const
Obtain number of corners of the corresponding reference element.
Definition localfiniteelementgeometry.hh:174
GlobalCoordinate center() const
Obtain the centroid of the mapping's image.
Definition localfiniteelementgeometry.hh:187
const LocalFiniteElement & finiteElement() const
Obtain the local finite-element.
Definition localfiniteelementgeometry.hh:366
GlobalCoordinate global(const LocalCoordinate &local) const
Evaluate the coordinate mapping.
Definition localfiniteelementgeometry.hh:203
Impl::FieldMatrixHelper< ctype > MatrixHelper
Definition localfiniteelementgeometry.hh:83
typename ReferenceElements::ReferenceElement ReferenceElement
Definition localfiniteelementgeometry.hh:80
GlobalCoordinate corner(int i) const
Obtain coordinates of the i-th corner.
Definition localfiniteelementgeometry.hh:180
Volume volume(Impl::ConvergenceOptions< ctype > opts={}) const
Obtain the volume of the mapping's image.
Definition localfiniteelementgeometry.hh:277
JacobianInverse jacobianInverse(const LocalCoordinate &local) const
Obtain the Jacobian's inverse.
Definition localfiniteelementgeometry.hh:340
ctype integrationElement(const LocalCoordinate &local) const
Obtain the integration element.
Definition localfiniteelementgeometry.hh:261
static constexpr int mydimension
geometry dimension
Definition localfiniteelementgeometry.hh:51
int order() const
Obtain the (highest) polynomial order of the parametrization.
Definition localfiniteelementgeometry.hh:150
FieldVector< ctype, mydimension > LocalCoordinate
type of local coordinates
Definition localfiniteelementgeometry.hh:57
LocalFiniteElementGeometry(const ReferenceElement &refElement, const LocalFiniteElement &localFE, Param &&parametrization)
Constructor from a local parametrization function, mapping local to (curved) global coordinates.
Definition localfiniteelementgeometry.hh:129
Abstract base class for quadrature rules.
Definition quadraturerules.hh:214
A container for all quadrature rules of dimension dim
Definition quadraturerules.hh:260
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
T emplace(T... args)
T size(T... args)
T sqrt(T... args)