LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
build_system_matrix.cc
1#include "build_system_matrix.h"
2
3#include <lf/assemble/assemble.h>
4#include <lf/base/base.h>
5#include <lf/io/vtk_writer.h>
6#include <lf/mesh/utils/utils.h>
7#include <lf/uscalfe/lagr_fe.h>
8
9#include <vector>
10
11#include "offset_function.h"
12#include "piecewise_const_element_matrix_provider.h"
13#include "piecewise_const_element_vector_provider.h"
14#include "solution_to_mesh_data_set.h"
15#include "utils.h"
16
18
19std::tuple<lf::assemble::COOMatrix<double>, Eigen::VectorXd>
21 const std::shared_ptr<const lf::mesh::Mesh> &mesh,
22 const lf::assemble::DofHandler &dofh,
23 const std::function<Eigen::Vector2d(const Eigen::Vector2d &)> &f,
24 const std::function<Eigen::Vector2d(const lf::mesh::Entity &)>
25 &dirichlet_data,
26 double sigma, const lf::quad::QuadRule &quadrule, bool modified_penalty) {
27 // Compute the boundary elements
28 const auto boundary = lf::mesh::utils::flagEntitiesOnBoundary(mesh);
29 // Compute the dirichlet data
31 for (const auto *ep : mesh->Entities(1)) {
32 dirichlet(*ep) = dirichlet_data(*ep);
33 }
34 // Assemble the system matrix
36 const auto elem_mat_builder =
38 sigma, boundary, modified_penalty);
39 lf::assemble::AssembleMatrixLocally(0, dofh, dofh, elem_mat_builder, A);
40 // Assemble the right hand side
41 Eigen::VectorXd rhs = Eigen::VectorXd::Zero(dofh.NumDofs());
42 const auto elem_vec_builder =
44 sigma, f, quadrule, boundary, dirichlet);
45 lf::assemble::AssembleVectorLocally(0, dofh, elem_vec_builder, rhs);
46
47 // Enforce no-flow boundary conditions
48 auto selector = [&](lf::base::size_type idx) -> std::pair<bool, double> {
49 const auto &e = dofh.Entity(idx);
50 return {e.RefEl() == lf::base::RefElType::kPoint && boundary(e), 0};
51 };
53
54 // Return the computed LSE
55 return {A, rhs};
56}
57
58std::tuple<lf::assemble::COOMatrix<double>, Eigen::VectorXd, Eigen::VectorXd>
60 const std::shared_ptr<const lf::mesh::Mesh> &mesh,
61 const lf::assemble::DofHandler &dofh,
62 const std::function<Eigen::Vector2d(const Eigen::Vector2d &)> &f,
63 const std::function<Eigen::Vector2d(const lf::mesh::Entity &)>
64 &dirichlet_data,
65 double sigma, const lf::quad::QuadRule &quadrule, bool modified_penalty) {
66 // Compute the boundary elements
67 const auto boundary = lf::mesh::utils::flagEntitiesOnBoundary(mesh);
68 // Compute the dirichlet data
70 for (const auto *ep : mesh->Entities(1)) {
71 dirichlet(*ep) = dirichlet_data(*ep);
72 }
73 // Assemble the system matrix
75 const auto elem_mat_builder =
77 sigma, boundary, modified_penalty);
78 lf::assemble::AssembleMatrixLocally(0, dofh, dofh, elem_mat_builder, A);
79 // Assemble the right hand side
80 Eigen::VectorXd rhs = Eigen::VectorXd::Zero(dofh.NumDofs());
81 const auto elem_vec_builder =
83 sigma, f, quadrule, boundary, dirichlet);
84 lf::assemble::AssembleVectorLocally(0, dofh, elem_vec_builder, rhs);
85
86 // Compute the offset function
87 const Eigen::VectorXd offset_function = createOffsetFunction(
88 mesh, boundary, dofh, dirichlet_data, A.makeSparse());
89
90 // Apply offset function technique to the LSE
91 rhs -= A.makeSparse().block(0, 0, dofh.NumDofs(), mesh->NumEntities(2)) *
92 offset_function.head(mesh->NumEntities(2));
93 auto selector = [&](lf::base::size_type idx) -> std::pair<bool, double> {
94 const auto &e = dofh.Entity(idx);
95 return {e.RefEl() == lf::base::RefElType::kPoint && boundary(e), 0};
96 };
98
99 // Return the computed LSE
100 return {A, rhs, offset_function};
101}
102
103} // end namespace projects::ipdg_stokes::assemble
A temporary data structure for matrix in COO format.
Definition: coomatrix.h:52
Eigen::SparseMatrix< Scalar > makeSparse() const
Create an Eigen::SparseMatrix out of the COO format.
Definition: coomatrix.h:172
A general (interface) class for DOF handling, see Lecture Document Paragraph 2.7.4....
Definition: dofhandler.h:109
virtual const lf::mesh::Entity & Entity(gdof_idx_t dofnum) const =0
retrieve unique entity at which a basis function is located
virtual size_type NumDofs() const =0
total number of dof's handled by the object
Interface class representing a topological entity in a cellular complex
Definition: entity.h:39
virtual base::RefEl RefEl() const =0
Describes the reference element type of this entity.
A MeshDataSet that attaches data of type T to every entity of a mesh that has a specified codimension...
Represents a Quadrature Rule over one of the Reference Elements.
Definition: quad_rule.h:58
void AssembleMatrixLocally(dim_t codim, const DofHandler &dof_handler_trial, const DofHandler &dof_handler_test, ENTITY_MATRIX_PROVIDER &entity_matrix_provider, TMPMATRIX &matrix)
Assembly function for standard assembly of finite element matrices.
Definition: assembler.h:113
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
unsigned int size_type
general type for variables related to size of arrays
Definition: base.h:24
void FixFlaggedSolutionComponents(SELECTOR &&selectvals, COOMatrix< SCALAR > &A, RHSVECTOR &b)
enforce prescribed solution components
Definition: fix_dof.h:87
@ kPoint
Returns the (0-dimensional) reference point.
CodimMeshDataSet< bool > flagEntitiesOnBoundary(const std::shared_ptr< const Mesh > &mesh_p, lf::base::dim_t codim)
flag entities of a specific co-dimension located on the boundary
Eigen::VectorXd createOffsetFunction(const std::shared_ptr< const lf::mesh::Mesh > &mesh, const lf::mesh::utils::MeshDataSet< bool > &boundary, const lf::assemble::DofHandler &dofh, const std::function< Eigen::Vector2d(const lf::mesh::Entity &)> &dirichlet_data, const Eigen::SparseMatrix< double > &A)
Compute the offset function for given boundary conditions.
std::tuple< lf::assemble::COOMatrix< double >, Eigen::VectorXd, Eigen::VectorXd > buildSystemMatrixInOutFlow(const std::shared_ptr< const lf::mesh::Mesh > &mesh, const lf::assemble::DofHandler &dofh, const std::function< Eigen::Vector2d(const Eigen::Vector2d &)> &f, const std::function< Eigen::Vector2d(const lf::mesh::Entity &)> &dirichlet_data, double sigma, const lf::quad::QuadRule &quadrule, bool modified_penalty)
Build the system matrix for the stokes system with in- and out flow boundary conditions.
std::tuple< lf::assemble::COOMatrix< double >, Eigen::VectorXd > buildSystemMatrixNoFlow(const std::shared_ptr< const lf::mesh::Mesh > &mesh, const lf::assemble::DofHandler &dofh, const std::function< Eigen::Vector2d(const Eigen::Vector2d &)> &f, const std::function< Eigen::Vector2d(const lf::mesh::Entity &)> &dirichlet_data, double sigma, const lf::quad::QuadRule &quadrule, bool modified_penalty)
Build the system matrix for the stokes system with no flow boundary conditions.