LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
whitney_one_vector_provider.h
1#ifndef HLDO_SPHERE_ASSEMBLE_WHITNEY_ONE_VECTOR_PROVIDER_H
2#define HLDO_SPHERE_ASSEMBLE_WHITNEY_ONE_VECTOR_PROVIDER_H
3
9#include <lf/base/base.h>
10#include <lf/mesh/entity.h>
11#include <lf/mesh/utils/mesh_data_set.h>
12#include <lf/quad/quad.h>
13#include <lf/uscalfe/lagr_fe.h>
14
15#include <Eigen/Dense>
16#include <functional>
17#include <utility>
18
19namespace projects::hldo_sphere {
20
21namespace assemble {
22
55template <typename SCALAR>
57 public:
68 const std::function<Eigen::Matrix<SCALAR, 3, 1>(const Eigen::Vector3d &)>
69 &f)
70 : f_(std::move(f)) {}
71
79 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> Eval(
80 const lf::mesh::Entity &entity) const {
81 LF_ASSERT_MSG(entity.RefEl() == lf::base::RefEl::kTria(),
82 "Only Triangles are supported no " << entity.RefEl());
83
84 const auto *const geom = entity.Geometry();
85
86 // Compute the global vertex coordinates
87 Eigen::MatrixXd vertices = geom->Global(entity.RefEl().NodeCoords());
88
89 // define quad rule with sufficiantly high degree
91
92 // Construct the whitney one form basis functions
94 const Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> ref_grads =
95 hat_func.GradientsReferenceShapeFunctions(Eigen::VectorXd::Zero(2))
96 .transpose();
97 const Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> J_inv_trans =
98 geom->JacobianInverseGramian(Eigen::VectorXd::Zero(2));
99 const Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> grads =
100 J_inv_trans * ref_grads;
101
102 // get edge orientations
103 auto edgeOrientations = entity.RelativeOrientations();
104 Eigen::Vector3d s;
105 s(0) = lf::mesh::to_sign(edgeOrientations[0]);
106 s(1) = lf::mesh::to_sign(edgeOrientations[1]);
107 s(2) = lf::mesh::to_sign(edgeOrientations[2]);
108
109 const auto b_hat = [&](Eigen::Vector2d x_hat)
110 -> Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> {
111 Eigen::Matrix<SCALAR, 3, 3> b_hat;
112 Eigen::Matrix<SCALAR, 3, 1> lambda_hat =
113 hat_func.EvalReferenceShapeFunctions(x_hat);
114 for (int i = 0; i < 3; i++) {
115 int ip1 = (i + 1) % 3;
116
117 b_hat.col(i) = s(i) * (lambda_hat(i) * grads.col(ip1) -
118 lambda_hat(ip1) * grads.col(i));
119 }
120
121 return b_hat;
122 };
123
124 // returns evaluation of @f$\textbf{f} * \textbf{b}@f$ for at a given point
125 // on the reference triangle f is evaluated at the global coordinates of the
126 // triangle radially projected on the sphere
127 const auto f_tilde_hat =
128 [&](Eigen::Vector2d x_hat) -> Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> {
129 Eigen::Vector3d x = geom->Global(x_hat);
130 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> result =
131 b_hat(x_hat).transpose() * f_(x);
132 return result;
133 };
134
135 // Compute the elements of the vector with given quadrature rule
136 Eigen::Matrix<SCALAR, 3, 1> element_vector;
137 element_vector.setZero();
138 const Eigen::MatrixXd points = quadrule.Points();
139 const Eigen::VectorXd weights =
140 (geom->IntegrationElement(points).array() * quadrule.Weights().array())
141 .matrix();
142 for (lf::base::size_type n = 0; n < quadrule.NumPoints(); ++n) {
143 const Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> f_eval =
144 f_tilde_hat(points.col(n));
145 element_vector += weights[n] * f_eval;
146 }
147 return element_vector;
148 }
149
153 bool isActive(const lf::mesh::Entity &entity) const { return true; }
154
155 private:
156 const std::function<Eigen::Matrix<SCALAR, 3, 1>(const Eigen::Vector3d &)> f_;
157};
158
159} // end namespace assemble
160
161} // namespace projects::hldo_sphere
162
163#endif // HLDO_SPHERE_ASSEMBLE_WHITNEY_ONE_VECTOR_PROVIDER_H
const Eigen::MatrixXd & NodeCoords() const
Get the coordinates of the nodes of this reference element.
Definition: ref_el.h:238
static constexpr RefEl kTria()
Returns the reference triangle.
Definition: ref_el.h:158
virtual Eigen::MatrixXd Global(const Eigen::MatrixXd &local) const =0
Map a number of points in local coordinates into the global coordinate system.
Interface class representing a topological entity in a cellular complex
Definition: entity.h:39
virtual const geometry::Geometry * Geometry() const =0
Describes the geometry of this entity.
virtual nonstd::span< const Orientation > RelativeOrientations() const =0
return span of relative orientations of sub-entities of the next higher co-dimension.
virtual base::RefEl RefEl() const =0
Describes the reference element type of this entity.
Represents a Quadrature Rule over one of the Reference Elements.
Definition: quad_rule.h:58
Linear Lagrange finite element on triangular reference element.
Definition: lagr_fe.h:58
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Computation of the gradients of all reference shape functions in a number of points.
Definition: lagr_fe.h:117
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > EvalReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Evaluation of all reference shape functions in a number of points.
Definition: lagr_fe.h:104
WhitneyOneVectorProvider(const std::function< Eigen::Matrix< SCALAR, 3, 1 >(const Eigen::Vector3d &)> &f)
Constructor.
const std::function< Eigen::Matrix< SCALAR, 3, 1 >(const Eigen::Vector3d &)> f_
Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > Eval(const lf::mesh::Entity &entity) const
Compute the element vector for a given triangle off the mesh.
bool isActive(const lf::mesh::Entity &entity) const
All entities are regarded as active.
unsigned int size_type
general type for variables related to size of arrays
Definition: base.h:24
QuadRule make_TriaQR_EdgeMidpointRule()
edge midpoint quadrature rule for reference triangles
int to_sign(Orientation o)
Definition: entity.cc:7
Implementation of the thesis Hogde Laplacians and Dirac Operators on the surface of the 3-Sphere.
Definition: assemble.h:15