18 : coords_(std::move(coords)),
19 alpha_(coords_.rows()),
20 beta_(coords_.rows(), 2),
21 gamma_(coords_.rows(), 2),
22 delta_(coords_.rows()),
23 epsilon_(coords_.rows(), 2),
24 gamma_x_2_(coords_.rows(), 2),
25 epsilon_x_2_(coords_.rows(), 2) {
33 const Eigen::VectorXd& A =
coords_.col(0);
34 const Eigen::VectorXd& B =
coords_.col(1);
35 const Eigen::VectorXd& C =
coords_.col(2);
36 const Eigen::VectorXd& D =
coords_.col(3);
37 const Eigen::VectorXd& E =
coords_.col(4);
38 const Eigen::VectorXd& F =
coords_.col(5);
39 const Eigen::VectorXd& G =
coords_.col(6);
40 const Eigen::VectorXd& H =
coords_.col(7);
43 beta_ << -3. * A - B + 4. * E, -3. * A - D + 4. * H;
44 gamma_ << 2. * (A + B) - 4. * E, 2. * (A + D) - 4. * H;
45 delta_ << 5. * A - B - 3. * C - D - 4. * (E - F - G + H);
46 epsilon_ << -2. * (A + B - C - D) + 4. * (E - G),
47 -2. * (A - B - C + D) - 4. * (F - H);
55 LF_VERIFY_MSG((0. <= local.array()).all() && (local.array() <= 1.).all(),
56 "local coordinates out of bounds for reference element");
58 auto local_squared = local.array().square();
59 return ((
beta_ * local) + (
gamma_ * local_squared.matrix()) +
60 (
delta_ * local.row(0).cwiseProduct(local.row(1))) +
62 (local_squared * local.colwise().reverse().array()).matrix()))
68 LF_VERIFY_MSG((0. <= local.array()).all() && (local.array() <= 1.).all(),
69 "local coordinates out of bounds for reference element");
71 auto local_squared_reversed = local.array().square().colwise().reverse();
72 auto local_colwise_product = local.row(0).cwiseProduct(local.row(1));
74 Eigen::MatrixXd tmp_epsilon(
gamma_.rows(), 2 * local.cols());
75 Eigen::MatrixXd tmp_epsilon_x_2 =
epsilon_x_2_.replicate(1, local.cols());
76 Eigen::MatrixXd tmp_gamma(
gamma_.rows(), 2 * local.cols());
78 for (
long i = 0; i < local.cols(); ++i) {
79 tmp_epsilon.block(0, 2 * i, tmp_epsilon.rows(), 2) =
80 epsilon_.rowwise().reverse().array().rowwise() *
81 local_squared_reversed.col(i).transpose().array();
82 tmp_epsilon_x_2.block(0, 2 * i, tmp_epsilon_x_2.rows(), 2) *=
83 local_colwise_product(i);
84 tmp_gamma.block(0, 2 * i, tmp_gamma.rows(), 2) =
85 gamma_x_2_.array().rowwise() * local.col(i).transpose().array();
88 Eigen::MatrixXd local_reversed = local.colwise().reverse();
89 local_reversed.resize(1, local.size());
91 return beta_.replicate(1, local.cols()) + tmp_gamma + tmp_epsilon +
93 (local_reversed.replicate(
delta_.rows(), 1).array().colwise() *
99 const Eigen::MatrixXd& local)
const {
100 LF_VERIFY_MSG((0. <= local.array()).all() && (local.array() <= 1.).all(),
101 "local coordinates out of bounds for reference element");
103 Eigen::MatrixXd jac =
Jacobian(local);
104 Eigen::MatrixXd jacInvGram(jac.rows(), jac.cols());
107 for (
long i = 0; i < local.cols(); ++i) {
108 auto jacobian = jac.block(0, 2 * i, 2, 2);
109 jacInvGram.block(0, 2 * i, 2, 2) << jacobian(1, 1), -jacobian(1, 0),
110 -jacobian(0, 1), jacobian(0, 0);
111 jacInvGram.block(0, 2 * i, 2, 2) /= jacobian.determinant();
114 for (
long i = 0; i < local.cols(); ++i) {
115 auto jacobian = jac.block(0, 2 * i, jac.rows(), 2);
117 auto A = jacobian.col(0);
118 auto B = jacobian.col(1);
121 Eigen::MatrixXd tmp(2, 2);
122 tmp << B.dot(B), -AB, -AB, A.dot(A);
124 jacInvGram.block(0, 2 * i, jac.rows(), 2) =
125 jacobian * tmp / tmp.determinant();
133 LF_VERIFY_MSG((0. <= local.array()).all() && (local.array() <= 1.).all(),
134 "local coordinates out of bounds for reference element");
136 Eigen::MatrixXd jac =
Jacobian(local);
137 Eigen::VectorXd intElem(local.cols());
140 for (
long i = 0; i < local.cols(); ++i) {
141 intElem(i) = std::abs(jac.block(0, 2 * i, 2, 2).determinant());
144 for (
long i = 0; i < local.cols(); ++i) {
145 auto jacobian = jac.block(0, 2 * i, jac.rows(), 2);
147 auto A = jacobian.col(0);
148 auto B = jacobian.col(1);
151 intElem(i) = std::sqrt(std::abs(A.dot(A) * B.dot(B) - AB * AB));
161 LF_ASSERT_MSG(i == 0,
"i is out of bounds");
162 return std::make_unique<QuadO2>(
coords_);
165 LF_ASSERT_MSG(0 <= i && i <= 3,
"i is out of bounds");
166 return std::make_unique<SegmentO2>(
167 (Eigen::Matrix<double, Eigen::Dynamic, 3>(
DimGlobal(), 3)
173 LF_ASSERT_MSG(0 <= i && i <= 8,
"i is out of bounds");
174 return std::make_unique<Point>(
coords_.col(i));
177 LF_VERIFY_MSG(
false,
"codim is out of bounds")
186 LF_VERIFY_MSG(codim < 3,
"Illegal codim " << codim);
188 const double hLattice = 1. /
static_cast<double>(ref_pat.
LatticeConst());
189 std::vector<std::unique_ptr<Geometry>> childGeoPtrs = {};
192 std::vector<Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic>> childPolygons(
195 const int noChildren = childPolygons.size();
198 "NumChildren " << noChildren <<
" <-> " << ref_pat.
NumChildren(codim));
201 for (
size_t child = 0; child < noChildren; ++child) {
207 childPolygons[child].rows() == 2,
208 "childPolygons[child].rows() = " << childPolygons[child].rows());
210 (childPolygons[child].cols() == (3 - codim)) ||
211 (childPolygons[child].cols() == 4),
212 "childPolygons[child].cols() = " << childPolygons[child].cols());
214 const Eigen::MatrixXd locChildPolygonCoords(
215 hLattice * childPolygons[child].cast<double>());
219 if (childPolygons[child].cols() == 3) {
220 Eigen::MatrixXd locChildCoords(locChildPolygonCoords.rows(), 6);
221 locChildCoords << locChildPolygonCoords,
222 (locChildPolygonCoords.col(0) + locChildPolygonCoords.col(1)) /
224 (locChildPolygonCoords.col(1) + locChildPolygonCoords.col(2)) /
226 (locChildPolygonCoords.col(2) + locChildPolygonCoords.col(0)) /
229 childGeoPtrs.push_back(
230 std::make_unique<TriaO2>(
Global(locChildCoords)));
232 }
else if (childPolygons[child].cols() == 4) {
233 Eigen::MatrixXd locChildCoords(locChildPolygonCoords.rows(), 8);
234 locChildCoords << locChildPolygonCoords,
235 (locChildPolygonCoords.col(0) + locChildPolygonCoords.col(1)) /
237 (locChildPolygonCoords.col(1) + locChildPolygonCoords.col(2)) /
239 (locChildPolygonCoords.col(2) + locChildPolygonCoords.col(3)) /
241 (locChildPolygonCoords.col(3) + locChildPolygonCoords.col(0)) /
244 childGeoPtrs.push_back(
245 std::make_unique<QuadO2>(
Global(locChildCoords)));
248 LF_VERIFY_MSG(
false,
"childPolygons[" << child <<
"].cols() = "
249 << childPolygons[child].cols());
255 Eigen::MatrixXd locChildCoords(locChildPolygonCoords.rows(), 3);
256 locChildCoords << locChildPolygonCoords,
257 (locChildPolygonCoords.col(0) + locChildPolygonCoords.col(1)) / 2.;
259 childGeoPtrs.push_back(
260 std::make_unique<SegmentO2>(
Global(locChildCoords)));
265 childGeoPtrs.push_back(
266 std::make_unique<Point>(
Global(locChildPolygonCoords)));
271 LF_VERIFY_MSG(
false,
"Illegal co-dimension");
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
std::string ToString() const
Return a string representation of this Reference element.
Eigen::Matrix< double, Eigen::Dynamic, 2 > gamma_x_2_
Eigen::MatrixXd Jacobian(const Eigen::MatrixXd &local) const override
Evaluate the jacobian of the mapping simultaneously at numPoints points.
Eigen::Matrix< double, Eigen::Dynamic, 2 > epsilon_x_2_
Eigen::Matrix< double, Eigen::Dynamic, 2 > beta_
Eigen::VectorXd IntegrationElement(const Eigen::MatrixXd &local) const override
The integration element (factor appearing in integral transformation formula, see below) at number of...
Eigen::Matrix< double, Eigen::Dynamic, 2 > gamma_
Eigen::MatrixXd Global(const Eigen::MatrixXd &local) const override
Map a number of points in local coordinates into the global coordinate system.
Eigen::Matrix< double, Eigen::Dynamic, 8 > coords_
Coordinates of the 8 vertices/midpoints, stored in matrix columns.
Eigen::MatrixXd JacobianInverseGramian(const Eigen::MatrixXd &local) const override
Evaluate the Jacobian * Inverse Gramian ( ) simultaneously at numPoints.
std::vector< std::unique_ptr< Geometry > > ChildGeometry(const RefinementPattern &ref_pat, lf::base::dim_t codim) const override
Generate geometry objects for child entities created in the course of refinement.
Eigen::Matrix< double, Eigen::Dynamic, 1 > alpha_
Eigen::Matrix< double, Eigen::Dynamic, 1 > delta_
Eigen::Matrix< double, Eigen::Dynamic, 2 > epsilon_
QuadO2(Eigen::Matrix< double, Eigen::Dynamic, 8 > coords)
Constructor building quadrilateral from vertex/midpoint coordinates.
dim_t DimGlobal() const override
Dimension of the image of this mapping.
std::unique_ptr< Geometry > SubGeometry(dim_t codim, dim_t i) const override
Construct a new Geometry() object that describes the geometry of the i-th sub-entity with codimension...
Abstract interface class for encoding topological local refinement
lf::base::size_type LatticeConst() const
Provides information about lattice constant used.
virtual lf::base::size_type NumChildren(lf::base::dim_t codim) const =0
provide number of child entities of a given co-dimension to be created by refinement
virtual std::vector< Eigen::Matrix< int, Eigen::Dynamic, Eigen::Dynamic > > ChildPolygons(lf::base::dim_t codim) const =0
provide lattice reference coordinates of vertices of child polygons
lf::base::RefEl RefEl() const
Returns topological type of entity for which the current object is set up.
unsigned int dim_t
type for dimensions and co-dimensions and numbers derived from them
Defines the Geometry interface and provides a number of classes that implement this interface + addit...