1#ifndef HLDO_SPHERE_OPERATORS_HODGE_LAPLACIANS_SOURCE_PROBLEMS_H
2#define HLDO_SPHERE_OPERATORS_HODGE_LAPLACIANS_SOURCE_PROBLEMS_H
9#include <mass_matrix_provider.h>
10#include <whitney_one_hodge_laplacian.h>
11#include <whitney_one_mass_matrix_provider.h>
12#include <whitney_two_hodge_laplacian.h>
13#include <whitney_two_mass_matrix_provider.h>
14#include <whitney_zero_hodge_laplacian.h>
33template <
typename SCALAR>
48 std::unique_ptr<lf::mesh::MeshFactory> factory =
49 std::make_unique<lf::mesh::hybrid2d::MeshFactory>(3);
51 std::shared_ptr<projects::hldo_sphere::mesh::SphereTriagMeshBuilder>
52 sphere = std::make_shared<
63 coo_matrix_ = std::vector<lf::assemble::COOMatrix<SCALAR>>{
68 phi_ = std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>(3);
70 mu_ = std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>(3);
73 auto f_0 = [](Eigen::Matrix<double, 3, 1> x) -> SCALAR {
return 0; };
75 [](Eigen::Matrix<double, 3, 1> x) -> Eigen::Matrix<SCALAR, 3, 1> {
76 return Eigen::Matrix<double, 3, 1>::Zero();
78 auto f_2 = [](Eigen::Matrix<double, 3, 1> x) -> SCALAR {
return 0; };
109 coo_mat_zero_pos.
cols());
112 for (Eigen::Triplet<SCALAR> triplet : coo_mat_zero_pos.
triplets()) {
113 int col = triplet.col();
114 int row = triplet.row();
116 SCALAR val = triplet.value();
123 mass_matrix_provider_zero;
134 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<double>>(
135 0, dof_handler_zero, dof_handler_zero, mass_matrix_provider_zero,
139 for (Eigen::Triplet<double> triplet : coo_mass_mat_zero.
triplets()) {
140 int row = triplet.row();
141 int col = triplet.col();
142 SCALAR val =
k_ *
k_ * triplet.value();
149 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> phi_zero =
166 coo_mat_one_pos.
cols());
169 for (Eigen::Triplet<SCALAR> triplet : coo_mat_one_pos.
triplets()) {
170 int col = triplet.col();
171 int row = triplet.row();
172 SCALAR val = triplet.value();
178 mass_matrix_provider_one;
186 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<double>>(
187 0, dof_handler_one, dof_handler_one, mass_matrix_provider_one,
191 for (Eigen::Triplet<double> triplet : coo_mass_mat_one.
triplets()) {
192 int col = triplet.col();
193 int row = triplet.row();
194 SCALAR val =
k_ *
k_ * triplet.value();
200 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> phi_one =
218 coo_mat_two_pos.
cols());
221 for (Eigen::Triplet<SCALAR> triplet : coo_mat_two_pos.
triplets()) {
222 int col = triplet.col();
223 int row = triplet.row();
224 SCALAR val = triplet.value();
230 mass_matrix_provider_two;
237 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<double>>(
238 0, dof_handler_two, dof_handler_two, mass_matrix_provider_two,
242 for (Eigen::Triplet<double> triplet : coo_mass_mat_two.
triplets()) {
245 int col = triplet.col() + n_dofs_one;
246 int row = triplet.row() + n_dofs_one;
247 SCALAR val =
k_ *
k_ * triplet.value();
254 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> phi_two =
277 Eigen::SparseLU<Eigen::SparseMatrix<SCALAR>> solver;
278 for (
int l = 0; l < 3; l++) {
279 Eigen::SparseMatrix<SCALAR> sparse_mat =
coo_matrix_[l].makeSparse();
280 solver.compute(sparse_mat);
281 if (solver.info() != Eigen::Success) {
282 throw std::runtime_error(
"Could not decompose the matrix");
285 mu_[l] = solver.solve(
phi_[l]);
296 void SetMesh(std::shared_ptr<const lf::mesh::Mesh> mesh_p) {
301 "Mesh must be Triangular, unsupported cell " << tria->
RefEl());
305 LF_ASSERT_MSG(mesh_p->DimWorld() == 3,
306 "World Dimension must be 3 but is" << mesh_p->DimWorld());
319 std::function<SCALAR(
const Eigen::Matrix<double, 3, 1> &)> &f0,
321 Eigen::Matrix<SCALAR, 3, 1>(
const Eigen::Matrix<double, 3, 1> &)> &f1,
322 std::function<SCALAR(
const Eigen::Matrix<double, 3, 1> &)> &f2) {
374 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>
GetMuZero() {
return mu_[0]; }
398 std::tuple<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>,
399 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>
403 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> u =
mu_[1].head(numEdges);
404 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> p =
mu_[1].tail(numPoints);
405 return std::make_tuple(u, p);
431 std::tuple<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>,
432 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>
436 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> j =
mu_[2].head(numEdges);
437 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> u =
mu_[2].tail(numCells);
438 return std::make_tuple(j, u);
442 std::shared_ptr<const lf::mesh::Mesh>
mesh_p_;
443 std::function<SCALAR(
const Eigen::Matrix<double, 3, 1> &)>
f0_;
444 std::function<Eigen::Matrix<SCALAR, 3, 1>(
445 const Eigen::Matrix<double, 3, 1> &)>
447 std::function<SCALAR(
const Eigen::Matrix<double, 3, 1> &)>
f2_;
449 std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>
phi_;
450 std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>
mu_;
A temporary data structure for matrix in COO format.
void setZero()
Erase all entries of the matrix.
Index cols() const
return number of column
TripletVec & triplets()
Gives access to the vector of triplets.
Index rows() const
return number of rows
void AddToEntry(gdof_idx_t i, gdof_idx_t j, SCALAR increment)
Add a value to the specified entry.
A general (interface) class for DOF handling, see Lecture Document Paragraph 2.7.4....
virtual size_type NumDofs() const =0
total number of dof's handled by the object
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
constexpr RefEl(RefElType type) noexcept
Create a RefEl from a lf::base::RefElType enum.
static constexpr RefEl kPoint()
Returns the (0-dimensional) reference point.
static constexpr RefEl kTria()
Returns the reference triangle.
Interface class representing a topological entity in a cellular complex
Element Matrix Provider for the mass matrix using picewise linear barycentric basis functions.
Element matrix provider for the Whitney one mass matrix that is the dot product of two Whitney one ba...
Element matrix provider for the bilinear form with cellwise constant basis functions.
A mesh builder for regular 3-Sphere.
void setRefinementLevel(lf::base::size_type n)
Set the refinement level.
Creates and solves the discretised Hodge Laplacian source problems.
std::vector< Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > > mu_
void Solve()
solves the linear systems build in Compute
std::shared_ptr< const lf::mesh::Mesh > mesh_p_
void SetMesh(std::shared_ptr< const lf::mesh::Mesh > mesh_p)
Sets the mesh and creates dof_handler.
Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > GetMuZero()
retunrs the basis expansion coefficiants for the solution of the zero form
std::tuple< Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 >, Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > > GetMuOne()
retunrs the basis expansion coefficiants for the solution of the one form
Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > GetLoadVector(int index)
returns the Loadvector
lf::assemble::COOMatrix< SCALAR > GetGalerkinMatrix(int index)
returns the Galerkin Matrix
std::vector< lf::assemble::COOMatrix< SCALAR > > coo_matrix_
void SetLoadFunctions(std::function< SCALAR(const Eigen::Matrix< double, 3, 1 > &)> &f0, std::function< Eigen::Matrix< SCALAR, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> &f1, std::function< SCALAR(const Eigen::Matrix< double, 3, 1 > &)> &f2)
Sets the load functions.
std::function< Eigen::Matrix< SCALAR, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> f1_
void SetK(double k)
Sets k for the souce problems.
std::function< SCALAR(const Eigen::Matrix< double, 3, 1 > &)> f2_
HodgeLaplaciansSourceProblems()
Constructor initializes basic mesh (Octaeder with radius 1.0)
std::function< SCALAR(const Eigen::Matrix< double, 3, 1 > &)> f0_
std::tuple< Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 >, Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > > GetMuTwo()
retunrs the basis expansion coefficiants for the solution of the two form
std::vector< Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > > phi_
void Compute()
Computes the Galerkin LSE for all three source problems.
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.
void SetMesh(std::shared_ptr< const lf::mesh::Mesh > mesh_p)
Sets the mesh and creates dof_handler.
void Compute()
Computes the Galerkin LSE.
Computes the Galerkin LSE for the Hodge Laplacian of the whitney two form.
void SetMesh(std::shared_ptr< const lf::mesh::Mesh > mesh_p)
Sets the mesh and creates dof_handler.
lf::assemble::COOMatrix< SCALAR > GetGalerkinMatrix()
returns the Galerkin Matrix
void SetLoadFunction(std::function< SCALAR(const Eigen::Matrix< double, 3, 1 > &)> &f)
Sets the load function.
void Compute()
Computes the Galerkin LSE.
Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > GetLoadVector()
returns the Loadvector
Computes the Galerkin LSE for the Hodge Laplacian of the whitney zero form.
void Compute()
Computes the Galerkin LSE.
void SetMesh(std::shared_ptr< const lf::mesh::Mesh > mesh_p)
Sets the mesh for later computations.
lf::assemble::COOMatrix< SCALAR > GetGalerkinMatrix()
returns the Galerkin Matrix
Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > GetLoadVector()
returns the Loadvector
void SetLoadFunction(std::function< SCALAR(const Eigen::Matrix< double, 3, 1 > &)> &f)
Sets the load function for later computations.
unsigned int size_type
general type for variables related to size of arrays
lf::base::size_type size_type
Implementation of the thesis Hogde Laplacians and Dirac Operators on the surface of the 3-Sphere.