LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
whitney_one_hodge_laplacian.h
1#ifndef HLDO_SPHERE_OPERATORS_WHITNEY_ONE_HODGE_LAPLACE_H
2#define HLDO_SPHERE_OPERATORS_WHITNEY_ONE_HODGE_LAPLACE_H
3
7#include <lf/assemble/assembler.h>
8#include <lf/assemble/coomatrix.h>
9#include <lf/assemble/dofhandler.h>
10#include <lf/mesh/entity.h>
11#include <lf/mesh/hybrid2d/mesh.h>
12#include <lf/mesh/hybrid2d/mesh_factory.h>
13#include <lf/mesh/mesh_interface.h>
14#include <lf/quad/quad.h>
15#include <load_vector_provider.h>
16#include <mass_matrix_provider.h>
17#include <sphere_triag_mesh_builder.h>
18#include <whitney_one_curl_curl_matrix_provider.h>
19#include <whitney_one_grad_matrix_provider.h>
20#include <whitney_one_vector_provider.h>
21
22#include <Eigen/Dense>
23#include <cmath>
24#include <iomanip>
25#include <iostream>
26
27namespace projects::hldo_sphere {
28
29namespace operators {
30
53template <typename SCALAR>
55 public:
63 : coo_matrix_(lf::assemble::COOMatrix<SCALAR>(1, 1)) {
64 // create mesh factory for basic mesh
65 std::unique_ptr<lf::mesh::MeshFactory> factory =
66 std::make_unique<lf::mesh::hybrid2d::MeshFactory>(3);
67
68 std::shared_ptr<projects::hldo_sphere::mesh::SphereTriagMeshBuilder>
69 sphere = std::make_shared<
71 std::move(factory));
72 sphere->setRefinementLevel(0);
73 sphere->setRadius(1);
74
75 mesh_p_ = sphere->Build();
76
77 // create basic function
78 auto f = [](Eigen::Matrix<double, 3, 1> x) -> Eigen::Matrix<SCALAR, 3, 1> {
79 return Eigen::Matrix<SCALAR, 3, 1>::Zero();
80 };
81 f_ = f;
82 }
83
91 void Compute() {
92 // create element matrix provider
94 matrix_curl_provider;
96 matrix_grad_provider;
98
99 const lf::assemble::DofHandler &dof_handler_curl =
102 const lf::assemble::DofHandler &dof_handler_bary =
104 {{lf::base::RefEl::kPoint(), 1}});
105
106 // create COO Matrix
107 const lf::assemble::size_type n_dofs_curl(dof_handler_curl.NumDofs());
108 const lf::assemble::size_type n_dofs_bary(dof_handler_bary.NumDofs());
109
110 lf::assemble::COOMatrix<double> coo_A_11(n_dofs_curl, n_dofs_curl);
111 coo_A_11.setZero();
112 lf::assemble::COOMatrix<double> coo_A_21(n_dofs_curl, n_dofs_bary);
113 coo_A_21.setZero();
114 lf::assemble::COOMatrix<double> coo_A_22(n_dofs_bary, n_dofs_bary);
115 coo_A_22.setZero();
116
117 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<double>>(
118 0, dof_handler_curl, dof_handler_curl, matrix_curl_provider, coo_A_11);
119
120 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<double>>(
121 0, dof_handler_bary, dof_handler_curl, matrix_grad_provider, coo_A_21);
122
123 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<double>>(
124 0, dof_handler_bary, dof_handler_bary, matrix_mass_provider, coo_A_22);
125
126 // create full matrix
127 lf::assemble::COOMatrix<SCALAR> full_matrix(n_dofs_curl + n_dofs_bary,
128 n_dofs_curl + n_dofs_bary);
129 full_matrix.setZero();
130
131 // iterate over all triplets of the previously computed matrice and add up
132 // entries
133 const std::vector<Eigen::Triplet<double>> triplets_A_11 =
134 coo_A_11.triplets();
135 const std::vector<Eigen::Triplet<double>> triplets_A_21 =
136 coo_A_21.triplets();
137 const std::vector<Eigen::Triplet<double>> triplets_A_22 =
138 coo_A_22.triplets();
139
140 // Add A_11
141 for (Eigen::Triplet<double> triplet : triplets_A_11) {
142 int col = triplet.col();
143 int row = triplet.row();
144 SCALAR val = triplet.value();
145 full_matrix.AddToEntry(row, col, val);
146 }
147
148 // Add A_12 and A_21
149 for (Eigen::Triplet<double> triplet : triplets_A_21) {
150 int col = triplet.col() + n_dofs_curl;
151 int row = triplet.row();
152 SCALAR val = triplet.value();
153
154 // Add A_12
155 full_matrix.AddToEntry(row, col, -val);
156
157 // Add A_21
158 full_matrix.AddToEntry(col, row, val);
159 }
160
161 // Add A_22
162 for (Eigen::Triplet<double> triplet : triplets_A_22) {
163 int col = triplet.col() + n_dofs_curl;
164 int row = triplet.row() + n_dofs_curl;
165 SCALAR val = triplet.value();
166 full_matrix.AddToEntry(row, col, val);
167 }
168
169 coo_matrix_ = full_matrix;
170
171 // create element vector provider
173 vector_provider(f_);
174
175 // create load vector
176 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> phi(n_dofs_curl);
177 phi.setZero();
178
179 // assemble the global vector over entities with codim=0:
180 AssembleVectorLocally(0, dof_handler_curl, vector_provider, phi);
181
182 // create full vector
183 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> full_vec(n_dofs_curl +
184 n_dofs_bary);
185 full_vec.setZero();
186 full_vec.head(n_dofs_curl) = phi;
187
188 // set the class attributes
189 phi_ = full_vec;
190 }
191
199 void SetMesh(std::shared_ptr<const lf::mesh::Mesh> mesh_p) {
200 // check if cells are triagles
201 for (const lf::mesh::Entity *tria : mesh_p->Entities(0)) {
202 LF_ASSERT_MSG(
203 tria->RefEl() == lf::base::RefEl::kTria(),
204 "Mesh must be Triangular, unsupported cell " << tria->RefEl());
205 }
206
207 // check if dimension of the mesh is 3
208 LF_ASSERT_MSG(mesh_p->DimWorld() == 3,
209 "World Dimension must be 3 but is" << mesh_p->DimWorld());
210
211 // set mesh
212 mesh_p_ = mesh_p;
213 }
214
227 void SetLoadFunction(std::function<Eigen::Matrix<SCALAR, 3, 1>(
228 const Eigen::Matrix<double, 3, 1> &)> &f) {
229 f_ = f;
230 }
231
241 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> GetLoadVector() { return phi_; }
242
253
254 private:
255 std::shared_ptr<const lf::mesh::Mesh> mesh_p_;
256 std::function<Eigen::Matrix<SCALAR, 3, 1>(
257 const Eigen::Matrix<double, 3, 1> &)>
260 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> phi_;
261};
262
263} // namespace operators
264
265} // namespace projects::hldo_sphere
266
267#endif // HLDO_SPHERE_OPERATORS_WHITNEY_ONE_HODGE_LAPLACE_H
A temporary data structure for matrix in COO format.
Definition: coomatrix.h:52
void setZero()
Erase all entries of the matrix.
Definition: coomatrix.h:98
TripletVec & triplets()
Gives access to the vector of triplets.
Definition: coomatrix.h:124
A general (interface) class for DOF handling, see Lecture Document Paragraph 2.7.4....
Definition: dofhandler.h:109
virtual size_type NumDofs() const =0
total number of dof's handled by the object
Dofhandler for uniform finite element spaces.
Definition: dofhandler.h:257
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
Definition: ref_el.h:150
constexpr RefEl(RefElType type) noexcept
Create a RefEl from a lf::base::RefElType enum.
Definition: ref_el.h:172
static constexpr RefEl kPoint()
Returns the (0-dimensional) reference point.
Definition: ref_el.h:141
static constexpr RefEl kTria()
Returns the reference triangle.
Definition: ref_el.h:158
Interface class representing a topological entity in a cellular complex
Definition: entity.h:39
Element Matrix Provider for the mass matrix using picewise linear barycentric basis functions.
An elment matrix provider computed with the Whitney one forms, vector valued basis function.
Element matrix provider Whitney one forms, surface vector fields.
void setRefinementLevel(lf::base::size_type n)
Set the refinement level.
Computes the Galerkin LSE for the Hodge Laplacian of the whitney one form.
lf::assemble::COOMatrix< SCALAR > GetGalerkinMatrix()
returns the Galerkin Matrix
Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > GetLoadVector()
returns the Loadvector
void SetLoadFunction(std::function< Eigen::Matrix< SCALAR, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> &f)
Sets the load function.
WhitneyOneHodgeLaplace()
Constructor initializes basic mesh (Octaeder with radius 1.0) initializes zerovalued function f.
void SetMesh(std::shared_ptr< const lf::mesh::Mesh > mesh_p)
Sets the mesh and creates dof_handler.
std::function< Eigen::Matrix< SCALAR, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> f_
void AssembleVectorLocally(dim_t codim, const DofHandler &dof_handler, ENTITY_VECTOR_PROVIDER &entity_vector_provider, VECTOR &resultvector)
entity-local assembly of (right-hand-side) vectors from element vectors
Definition: assembler.h:297
lf::base::size_type size_type
Definition: assemble.h:30
Implementation of the thesis Hogde Laplacians and Dirac Operators on the surface of the 3-Sphere.
Definition: assemble.h:15