LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
dirac_operator.cc
1#include "dirac_operator.h"
2
3namespace projects::hldo_sphere {
4
5namespace operators {
6
8 // create element matrix provider for the matrices A12, A21
10 matrix_grad_provider;
11
12 // create matrix provider for -A23, -A32
14 matrix_div_provider;
15
16 const lf::assemble::DofHandler &dof_handler_vert =
19 const lf::assemble::DofHandler &dof_handler_edge =
22 const lf::assemble::DofHandler &dof_handler_cell =
24 {{lf::base::RefEl::kTria(), 1}});
25
26 // create COO Matrix
27 const lf::assemble::size_type n_dofs_vert(dof_handler_vert.NumDofs());
28 const lf::assemble::size_type n_dofs_edge(dof_handler_edge.NumDofs());
29 const lf::assemble::size_type n_dofs_cell(dof_handler_cell.NumDofs());
30
31 lf::assemble::COOMatrix<double> coo_A_21(n_dofs_edge, n_dofs_vert);
32 coo_A_21.setZero();
33
34 // the m stands for minus
35 // note that the RotWOneFormDivElementMatrixProvider returns the
36 // negative of the elements we want
37 lf::assemble::COOMatrix<double> coo_A_23_m(n_dofs_edge, n_dofs_cell);
38 coo_A_23_m.setZero();
39
40 // create s matrix with n_dofs_edge rows and n_dofs_vert columns
41 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<double>>(
42 0, dof_handler_vert, dof_handler_edge, matrix_grad_provider, coo_A_21);
43
44 // create matrix with n_dof_edge_rows and n_dof_cell columns
45 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<double>>(
46 0, dof_handler_cell, dof_handler_edge, matrix_div_provider, coo_A_23_m);
47
48 // create full matrix
50 n_dofs_vert + n_dofs_edge + n_dofs_cell,
51 n_dofs_vert + n_dofs_edge + n_dofs_cell);
52
53 full_matrix.setZero();
54
55 // iterate over all triplets of the previously computed matrice and add up
56 // entries
57 const std::vector<Eigen::Triplet<double>> triplets_A_21 = coo_A_21.triplets();
58 const std::vector<Eigen::Triplet<double>> triplets_A_23_m =
59 coo_A_23_m.triplets();
60
61 // Add A_12 and A_21
62 for (Eigen::Triplet<double> triplet : triplets_A_21) {
63 int col = triplet.col();
64 int row = triplet.row();
65 complex val = complex(triplet.value(), 0.);
66 // A_21
67 full_matrix.AddToEntry(row + n_dofs_vert, col, val);
68 // A_12
69 full_matrix.AddToEntry(col, row + n_dofs_vert, val);
70 }
71
72 // Add A_23 and A_32
73 for (Eigen::Triplet<double> triplet : triplets_A_23_m) {
74 int col = triplet.col();
75 int row = triplet.row();
76 complex val = complex(triplet.value(), 0.);
77
78 // Add A_23
79 full_matrix.AddToEntry(row + n_dofs_vert, col + n_dofs_vert + n_dofs_edge,
80 val);
81
82 // Add A_32
83 full_matrix.AddToEntry(col + n_dofs_vert + n_dofs_edge, row + n_dofs_vert,
84 val);
85 }
86
87 coo_matrix_ = full_matrix;
88
89 // create element vector provider
91 vector_provider_0(f0_);
92
94 vector_provider_1(f1_);
95
97 vector_provider_2(f2_);
98
99 // create load vector
100 Eigen::Matrix<complex, Eigen::Dynamic, 1> phi0(n_dofs_vert);
101 phi0.setZero();
102 Eigen::Matrix<complex, Eigen::Dynamic, 1> phi1(n_dofs_edge);
103 phi1.setZero();
104 Eigen::Matrix<complex, Eigen::Dynamic, 1> phi2(n_dofs_cell);
105 phi2.setZero();
106
107 // assemble the global vector over entities with codim=0:
108 AssembleVectorLocally(0, dof_handler_vert, vector_provider_0, phi0);
109 AssembleVectorLocally(0, dof_handler_edge, vector_provider_1, phi1);
110 AssembleVectorLocally(0, dof_handler_cell, vector_provider_2, phi2);
111
112 // create full vector
113 Eigen::Matrix<complex, Eigen::Dynamic, 1> full_vec(n_dofs_vert + n_dofs_edge +
114 n_dofs_cell);
115 full_vec.setZero();
116 full_vec.head(n_dofs_vert) = phi0;
117 full_vec.segment(n_dofs_vert, n_dofs_edge) = phi1;
118 full_vec.tail(n_dofs_cell) = phi2;
119
120 // set the class attributes
121 phi_ = full_vec;
122}
123
131void DiracOperator::SetMesh(std::shared_ptr<const lf::mesh::Mesh> mesh_p) {
132 // check if cells are triagles
133 for (const lf::mesh::Entity *tria : mesh_p->Entities(0)) {
134 LF_ASSERT_MSG(
135 tria->RefEl() == lf::base::RefEl::kTria(),
136 "Mesh must be Triangular, unsupported cell " << tria->RefEl());
137 }
138
139 // check if dimension of the mesh is 3
140 LF_ASSERT_MSG(mesh_p->DimWorld() == 3,
141 "World Dimension must be 3 but is" << mesh_p->DimWorld());
142
143 // set mesh
144 mesh_p_ = mesh_p;
145}
146
147} // namespace operators
148} // namespace projects::hldo_sphere
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 Vector Provider for scalar valued load functions using picewise linear barycentric basis func...
Element matrix provider Whitney one forms, surface vector fields.
Element vector provider for piecewise constant whitney two forms.
std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f0_
void SetMesh(std::shared_ptr< const lf::mesh::Mesh > mesh_p)
Sets the mesh and creates dof_handler.
std::shared_ptr< const lf::mesh::Mesh > mesh_p_
Eigen::Matrix< complex, Eigen::Dynamic, 1 > phi_
std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f2_
std::function< Eigen::Matrix< complex, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> f1_
void Compute()
Computes the Galerkin LSE.
lf::assemble::COOMatrix< complex > coo_matrix_
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
std::complex< double > complex
Implementation of the thesis Hogde Laplacians and Dirac Operators on the surface of the 3-Sphere.
Definition: assemble.h:15