LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
mesh_function_whitney_one.h
1#ifndef HLDO_SPHERE_MESH_FUNCTION_WHITNEY_ONE_H
2#define HLDO_SPHERE_MESH_FUNCTION_WHITNEY_ONE_H
3/*
4 * @file mesh_function_whitney_one.h
5 */
6
7#include <lf/uscalfe/uscalfe.h>
8
10
17template <typename SCALAR>
19 public:
41 MeshFunctionWhitneyOne(const Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>& mu,
42 const std::shared_ptr<const lf::mesh::Mesh> mesh)
43 : mu_(mu), mesh_(mesh) {
44 // make sure mu has the right size
45 lf::base::size_type n = mesh->NumEntities(1);
46 int mu_size = mu.size();
47 LF_VERIFY_MSG(
48 n == mu_size,
49 "Not the right number of basis expansion coefficiants in mu expected: "
50 << n << " given: " << mu_size);
51 };
52
91 std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>> operator()(
92 const lf::mesh::Entity& e, const Eigen::MatrixXd& local) const {
93 // Only triangles are supported
94 LF_VERIFY_MSG(e.RefEl() == lf::base::RefEl::kTria(),
95 "Unsupported cell type " << e.RefEl());
96
97 // Get the geometry of the entity
98 const auto* geom = e.Geometry();
99
100 // Compute the global vertex coordinates
101 Eigen::MatrixXd vertices = geom->Global(e.RefEl().NodeCoords());
102
103 // get the lambdas
105
106 // The gradients are constant on the triangle
107 const Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> ref_grads =
108 hat_func.GradientsReferenceShapeFunctions(Eigen::VectorXd::Zero(2))
109 .transpose();
110
111 // The JacobianInverseGramian is constant on the triangle
112 const Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> J_inv_trans =
113 geom->JacobianInverseGramian(Eigen::VectorXd::Zero(2));
114
115 // get the gradients
116 const Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> grad =
117 J_inv_trans * ref_grads;
118
119 // get lambda values
120 const Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> lambda =
121 hat_func.EvalReferenceShapeFunctions(local);
122
123 // correct for orientation
124 auto edgeOrientations = e.RelativeOrientations();
125
126 // define return vector
127 std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>> vals(local.cols());
128
129 // get global indices of the edges
130 std::vector<lf::base::size_type> global_indices(3);
131 auto edges = e.SubEntities(1);
132 for (lf::base::size_type i = 0; i < 3; i++) {
133 global_indices[i] = mesh_->Index(*edges[i]);
134 }
135
136 // for each point evaluate the basis functions and add the
137 // values together
138 for (int i = 0; i < local.cols(); i++) {
139 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> bs(grad.rows(), 3);
140 bs.col(0) = lambda(0, i) * grad.col(1) - lambda(1, i) * grad.col(0);
141 bs.col(1) = lambda(1, i) * grad.col(2) - lambda(2, i) * grad.col(1);
142 bs.col(2) = lambda(2, i) * grad.col(0) - lambda(0, i) * grad.col(2);
143
144 bs.col(0) *= lf::mesh::to_sign(edgeOrientations[0]);
145 bs.col(1) *= lf::mesh::to_sign(edgeOrientations[1]);
146 bs.col(2) *= lf::mesh::to_sign(edgeOrientations[2]);
147
148 vals[i] = mu_(global_indices[0]) * bs.col(0) +
149 mu_(global_indices[1]) * bs.col(1) +
150 mu_(global_indices[2]) * bs.col(2);
151 }
152
153 return vals;
154 }
155
156 private:
157 const Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>& mu_;
158 const std::shared_ptr<const lf::mesh::Mesh> mesh_;
159};
160
161} // namespace projects::hldo_sphere::post_processing
162#endif // HLDO_SPHERE_MESH_FUNCTION_WHITNEY_ONE_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 Entity *const > SubEntities(unsigned rel_codim) const =0
Return all sub entities of this entity that have the given codimension (w.r.t. 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.
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
Provides Mesh Function for given basis expansion coefficients.
MeshFunctionWhitneyOne(const Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > &mu, const std::shared_ptr< const lf::mesh::Mesh > mesh)
basic constructor
unsigned int size_type
general type for variables related to size of arrays
Definition: base.h:24
int to_sign(Orientation o)
Definition: entity.cc:7
Postprocessing such as computing norms and Mesh Functions and plot scripts.