LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
dirac_operator_source_problem.cc
1#include "dirac_operator_source_problem.h"
2
3namespace projects::hldo_sphere {
4
5namespace operators {
6
8 : coo_matrix_(lf::assemble::COOMatrix<complex>(1, 1)) {
9 // create mesh factory for basic mesh
10 std::unique_ptr<lf::mesh::MeshFactory> factory =
11 std::make_unique<lf::mesh::hybrid2d::MeshFactory>(3);
12
13 std::shared_ptr<projects::hldo_sphere::mesh::SphereTriagMeshBuilder> sphere =
14 std::make_shared<projects::hldo_sphere::mesh::SphereTriagMeshBuilder>(
15 std::move(factory));
16 sphere->setRefinementLevel(0);
17 sphere->setRadius(1);
18
19 mesh_p_ = sphere->Build();
20
21 k_ = 1.;
22
23 phi_ = Eigen::Matrix<complex, Eigen::Dynamic, 1>(1);
24
25 mu_ = Eigen::Matrix<complex, Eigen::Dynamic, 1>(1);
26
27 // create basic function
28 auto f_0 = [](Eigen::Matrix<double, 3, 1> x) -> complex { return 0; };
29 auto f_1 = [](Eigen::Matrix<double, 3, 1> x) -> Eigen::Matrix<complex, 3, 1> {
30 return Eigen::Matrix<complex, 3, 1>::Zero();
31 };
32 auto f_2 = [](Eigen::Matrix<double, 3, 1> x) -> complex { return 0; };
33 f0_ = f_0;
34 f1_ = f_1;
35 f2_ = f_2;
36}
37
39 // get Dirac Operator Matrix
41 dirac_operator.SetLoadFunctions(f0_, f1_, f2_);
42 dirac_operator.SetMesh(mesh_p_);
43 dirac_operator.Compute();
44
45 lf::assemble::COOMatrix<complex> coo_mat = dirac_operator.GetGalerkinMatrix();
46
47 // get righthandside vector
48 Eigen::Matrix<complex, Eigen::Dynamic, 1> phi =
49 dirac_operator.GetLoadVector();
50 phi_ = phi;
51
52 //**********************
53 // create mass matrices
54 //**********************
55
56 // Zero form mass matrix
58
59 const lf::assemble::DofHandler &dof_handler_zero =
62 const lf::assemble::size_type n_dofs_zero(dof_handler_zero.NumDofs());
63
64 lf::assemble::COOMatrix<complex> coo_mass_mat_zero(n_dofs_zero, n_dofs_zero);
65 coo_mass_mat_zero.setZero();
66
67 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<complex>>(
68 0, dof_handler_zero, dof_handler_zero, mass_matrix_provider_zero,
69 coo_mass_mat_zero);
70
71 for (Eigen::Triplet<complex> triplet : coo_mass_mat_zero.triplets()) {
72 int col = triplet.col();
73 int row = triplet.row();
74 complex val = std::complex<double>(0., 1.) * k_ * triplet.value();
75 coo_mat.AddToEntry(row, col, val);
76 };
77
78 // one form mass matrix
80 mass_matrix_provider_one;
81 const lf::assemble::DofHandler &dof_handler_one =
84 const lf::assemble::size_type n_dofs_one(dof_handler_one.NumDofs());
85 lf::assemble::COOMatrix<complex> coo_mass_mat_one(n_dofs_one, n_dofs_one);
86 coo_mass_mat_one.setZero();
87 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<complex>>(
88 0, dof_handler_one, dof_handler_one, mass_matrix_provider_one,
89 coo_mass_mat_one);
90
91 for (Eigen::Triplet<complex> triplet : coo_mass_mat_one.triplets()) {
92 int col = triplet.col() + n_dofs_zero;
93 int row = triplet.row() + n_dofs_zero;
94 complex val = std::complex<double>(0., 1.) * k_ * triplet.value();
95 coo_mat.AddToEntry(row, col, val);
96 }
97
98 // two form mass matrix
100 mass_matrix_provider_two;
101 const lf::assemble::DofHandler &dof_handler_two =
103 {{lf::base::RefEl::kTria(), 1}});
104 const lf::assemble::size_type n_dofs_two(dof_handler_two.NumDofs());
105 lf::assemble::COOMatrix<complex> coo_mass_mat_two(n_dofs_two, n_dofs_two);
106 coo_mass_mat_two.setZero();
107 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<complex>>(
108 0, dof_handler_two, dof_handler_two, mass_matrix_provider_two,
109 coo_mass_mat_two);
110
111 for (Eigen::Triplet<complex> triplet : coo_mass_mat_two.triplets()) {
112 // n_dofs_one contains the number of edges and hence the
113 // dimension of A_{11}
114 int col = triplet.col() + n_dofs_zero + n_dofs_one;
115 int row = triplet.row() + n_dofs_zero + n_dofs_one;
116 complex val = std::complex<double>(0., 1.) * k_ * triplet.value();
117 coo_mat.AddToEntry(row, col, val);
118 }
119
120 coo_matrix_ = coo_mat;
121}
122
124 Eigen::SparseLU<Eigen::SparseMatrix<complex>> solver;
125 Eigen::SparseMatrix<complex> sparse_mat = coo_matrix_.makeSparse();
126 sparse_mat.makeCompressed();
127 solver.analyzePattern(sparse_mat);
128 solver.factorize(sparse_mat);
129 if (solver.info() != Eigen::Success) {
130 throw std::runtime_error("Could not decompose the matrix");
131 }
132
133 mu_ = solver.solve(phi_);
134}
135
137 std::shared_ptr<const lf::mesh::Mesh> mesh_p) {
138 // check if cells are triagles
139 for (const lf::mesh::Entity *tria : mesh_p->Entities(0)) {
140 LF_ASSERT_MSG(
141 tria->RefEl() == lf::base::RefEl::kTria(),
142 "Mesh must be Triangular, unsupported cell " << tria->RefEl());
143 }
144
145 // check if dimension of the mesh is 3
146 LF_ASSERT_MSG(mesh_p->DimWorld() == 3,
147 "World Dimension must be 3 but is" << mesh_p->DimWorld());
148
149 // set mesh
150 mesh_p_ = mesh_p;
151}
152
153Eigen::Matrix<double, Eigen::Dynamic, 1> DiracOperatorSourceProblem::GetMu(
154 int index) {
155 LF_ASSERT_MSG(index < 3 && index >= 0,
156 "Index must be in {0,1,2}, given " << index);
157
158 Eigen::Vector3d n;
159 Eigen::Vector3d s;
160 n(0) = mesh_p_->NumEntities(2);
161 s(0) = 0;
162 n(1) = mesh_p_->NumEntities(1);
163 s(1) = n(0);
164 n(2) = mesh_p_->NumEntities(0);
165 s(2) = s(1) + n(1);
166 return mu_.segment(s(index), n(index)).real();
167}
168
169} // namespace operators
170} // namespace projects::hldo_sphere
void setZero()
Erase all entries of the matrix.
Definition: coomatrix.h:98
Eigen::SparseMatrix< Scalar > makeSparse() const
Create an Eigen::SparseMatrix out of the COO format.
Definition: coomatrix.h:172
TripletVec & triplets()
Gives access to the vector of triplets.
Definition: coomatrix.h:124
void AddToEntry(gdof_idx_t i, gdof_idx_t j, SCALAR increment)
Add a value to the specified entry.
Definition: coomatrix.h:87
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.
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.
Computes the Galerkin LSE for the Dirac Operator and the load vector.
void SetMesh(std::shared_ptr< const lf::mesh::Mesh > mesh_p)
Sets the mesh and creates dof_handler.
lf::assemble::COOMatrix< complex > GetGalerkinMatrix()
returns the Galerkin Matrix
Eigen::Matrix< complex, Eigen::Dynamic, 1 > GetLoadVector()
returns the Loadvector
void SetLoadFunctions(std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f0, std::function< Eigen::Matrix< complex, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> f1, std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f2)
Sets the load functions.
void Compute()
Computes the Galerkin LSE.
void Compute()
Computes the Galerkin LSE for the dirac operator source problem.
std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f2_
Eigen::Matrix< double, Eigen::Dynamic, 1 > GetMu(int index)
retunrs the basis expansion coefficiants for the solution of the source problem
DiracOperatorSourceProblem()
Constructor creates basic mesh (Octaeder with radius 1.0)
std::function< Eigen::Matrix< complex, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> f1_
std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f0_
void SetMesh(std::shared_ptr< const lf::mesh::Mesh > mesh_p)
Sets the mesh.
lf::base::size_type size_type
Definition: assemble.h:30
std::complex< double > complex
Implementation of the thesis Hogde Laplacians and Dirac Operators on the surface of the 3-Sphere.
Definition: assemble.h:15