LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
Loading...
Searching...
No Matches
check_sub_geometry.cc
1
9#include "check_sub_geometry.h"
10
11#include <gtest/gtest.h>
12
13#include <Eigen/Eigen>
14
16
18 const lf::geometry::Geometry &geom,
19 const std::function<lf::quad::QuadRule(lf::base::RefEl)> &qrProvider) {
20 // nodeCoords is a (refEl.Dimension, refEl.NumNodes) matrix
21 const auto refEl = geom.RefEl();
22 const Eigen::MatrixXd &nodeCoords = refEl.NodeCoords();
23
24 // iterate over all relative codimensions
25 for (size_t codim = 0; codim <= geom.RefEl().Dimension(); ++codim) {
26 // iterate over all subEntities in given codimension
27 const auto numSubEntities = refEl.NumSubEntities(codim);
28 for (size_t subEntity = 0; subEntity < numSubEntities; ++subEntity) {
29 // subNodeCoords is a (subRefEl.Dimension, subRefEl.NumNodes) matrix
30 auto subGeom = geom.SubGeometry(codim, subEntity);
31 auto subRefEl = subGeom->RefEl();
32 const Eigen::MatrixXd &subNodeCoords = subRefEl.NodeCoords();
33
34 // iterate over all nodes of subEntity
35 for (size_t subNode = 0; subNode < subRefEl.NumNodes(); ++subNode) {
36 // map coordinates in subRefEl.Dimension to geom.DimGlobal
37 auto globalCoordsFromSub = subGeom->Global(subNodeCoords.col(subNode));
38 // get index of subSubEntity with respect to refEl
39 int subSubIdx = refEl.SubSubEntity2SubEntity(
40 codim, subEntity, geom.DimLocal() - codim, subNode);
41 // map coordinates in RefEl.Dimension to geom.DimGlobal
42 auto globalCoords = geom.Global(nodeCoords.col(subSubIdx));
43
44 EXPECT_TRUE(globalCoordsFromSub.isApprox(globalCoords))
45 << "Global mapping of subNode " << subNode << " of subEntity "
46 << subEntity << " in relative codim " << codim
47 << " differs from global mapping of node " << subSubIdx;
48 }
49
50 // check points inside subEntity
51 if (subRefEl != lf::base::RefEl::kPoint()) {
52 // select nodes of RefEl referenced by subEntity
53 Eigen::MatrixXd mapNodeCoords(nodeCoords.rows(), subRefEl.NumNodes());
54 for (size_t subNode = 0; subNode < subRefEl.NumNodes(); ++subNode) {
55 const auto subSubIdx = refEl.SubSubEntity2SubEntity(
56 codim, subEntity, geom.DimLocal() - codim, subNode);
57 mapNodeCoords.col(subNode) = nodeCoords.col(subSubIdx);
58 }
59
60 auto points = qrProvider(subRefEl).Points();
61
62 // compute mapping: alpha * subNodeCoords + beta = mapNodeCoords
63 Eigen::MatrixXd paddedSubNodeCoords = Eigen::MatrixXd::Ones(
64 subNodeCoords.rows() + 1, subNodeCoords.cols());
65 paddedSubNodeCoords.block(0, 0, subNodeCoords.rows(),
66 subNodeCoords.cols()) = subNodeCoords;
67 Eigen::MatrixXd alphaBeta = paddedSubNodeCoords.transpose()
68 .fullPivLu()
69 .solve(mapNodeCoords.transpose())
70 .transpose();
71
72 // map points onto RefEl
73 Eigen::MatrixXd paddedPoints =
74 Eigen::MatrixXd::Ones(points.rows() + 1, points.cols());
75 paddedPoints.block(0, 0, points.rows(), points.cols()) = points;
76 const Eigen::MatrixXd mappedPoints = alphaBeta * paddedPoints;
77
78 // map coordinates in subRefEl.Dimension to geom.DimGlobal
79 auto globalPointsFromSub = subGeom->Global(points);
80 // map coordinates in RefEl.Dimension to geom.DimGlobal
81 auto globalPoints = geom.Global(mappedPoints);
82
83 EXPECT_TRUE(globalPoints.isApprox(globalPointsFromSub))
84 << "Global mapping of points " << points << " from subEntity "
85 << subEntity << " in relative codim " << codim
86 << " differs from global mapping";
87 }
88 }
89 }
90}
91
92} // namespace lf::geometry::test_utils
Represents a reference element with all its properties.
Definition ref_el.h:109
const Eigen::MatrixXd & NodeCoords() const
Get the coordinates of the nodes of this reference element.
Definition ref_el.h:241
static constexpr RefEl kPoint()
Returns the (0-dimensional) reference point.
Definition ref_el.h:144
Interface class for shape information on a mesh cell in the spirit of parametric finite element metho...
virtual base::RefEl RefEl() const =0
The Reference element that defines the domain of this mapping.
virtual Eigen::MatrixXd Global(const Eigen::MatrixXd &local) const =0
Map a number of points in local coordinates into the global coordinate system.
virtual dim_t DimLocal() const =0
Dimension of the domain of this mapping.
virtual std::unique_ptr< Geometry > SubGeometry(dim_t codim, dim_t i) const =0
Construct a new Geometry() object that describes the geometry of the i-th sub-entity with codimension...
Represents a Quadrature Rule over one of the Reference Elements.
Definition quad_rule.h:58
Defines the Geometry::test_utils module and provides a number of test functions to check geometry obj...
void checkSubGeometry(const lf::geometry::Geometry &geom, const std::function< lf::quad::QuadRule(lf::base::RefEl)> &qrProvider)
Checks that geometry objects obtained through SubGeometry() map the same points on the reference elem...