1#include "offset_function.h"
3#include <lf/assemble/assemble.h>
4#include <lf/assemble/coomatrix.h>
5#include <lf/base/base.h>
6#include <lf/mesh/utils/codim_mesh_data_set.h>
7#include <lf/mesh/utils/utils.h>
8#include <lf/uscalfe/lagr_fe.h>
19 std::shared_ptr<const lf::mesh::Mesh> mesh,
21 : mesh_(std::move(mesh)), boundary_(boundary) {}
26 const Eigen::Matrix<double, 2, 3> normals =
29 const auto *geom = entity.
Geometry();
31 const Eigen::MatrixXd ref_grads =
34 const Eigen::MatrixXd J_inv_trans =
35 geom->JacobianInverseGramian(Eigen::VectorXd::Zero(2));
36 const Eigen::MatrixXd grads = J_inv_trans * ref_grads;
37 Eigen::MatrixXd basis_funct(2, 3);
38 basis_funct << grads.row(1), -grads.row(0);
43 int boundary_node_count = 0;
44 int boundary_edge_count = 0;
45 for (
const auto *
const node : nodes) {
47 ++boundary_node_count;
50 for (
const auto *
const edge : edges) {
52 ++boundary_edge_count;
56 Eigen::MatrixXd elem_mat = Eigen::MatrixXd::Zero(
57 std::max(1, boundary_edge_count), std::max(1, boundary_node_count));
59 for (
int node_idx = 0; node_idx < 3; ++node_idx) {
61 const auto &node = *nodes[node_idx];
63 for (
int edge_idx = 0; edge_idx < 3; ++edge_idx) {
64 const auto &edge = *edges[edge_idx];
66 elem_mat(row_idx, col_idx) =
67 normals.col(edge_idx).transpose() * basis_funct.col(node_idx);
78 const std::shared_ptr<const lf::mesh::Mesh> &mesh,
83 const Eigen::SparseMatrix<double> &A) {
104 boundary_node_dofh.NumDofs() + 1);
107 element_matrix_provider, J);
111 J.AddToEntry(boundary_edge_dofh.NumDofs(), i, 1);
114 J.AddToEntry(i, boundary_node_dofh.NumDofs(), 1);
116 Eigen::SparseMatrix<double> Js = J.makeSparse();
118 Eigen::VectorXd rhs = Eigen::VectorXd::Zero(boundary_edge_dofh.NumDofs() + 1);
119 for (
const auto *
const cell : mesh->Entities(0)) {
120 const Eigen::Matrix<double, 2, 3> normals =
122 const auto edges = cell->SubEntities(1);
123 for (
int edge_idx = 0; edge_idx < 3; ++edge_idx) {
124 const auto &edge = *edges[edge_idx];
125 if (boundary(edge)) {
126 rhs[boundary_edge_dofh.GlobalDofIndices(edge)[0]] =
127 normals.col(edge_idx).transpose() * dirichlet_data(edge);
133 Eigen::SparseLU<Eigen::SparseMatrix<double>> solver;
135 const Eigen::VectorXd offset_function_local =
136 solver.solve(rhs).head(boundary_node_dofh.NumDofs());
138 Eigen::VectorXd offset_function = Eigen::VectorXd::Zero(dofh.
NumDofs());
140 node_idx < boundary_node_dofh.NumDofs(); ++node_idx) {
141 const auto &node = boundary_node_dofh.Entity(node_idx);
143 offset_function_local[node_idx];
145 offset_function.tail(mesh->NumEntities(1)) =
146 A.block(mesh->NumEntities(2), 0, mesh->NumEntities(1), A.cols()) *
148 return offset_function;
A temporary data structure for matrix in COO format.
A general (interface) class for DOF handling, see Lecture Document Paragraph 2.7.4....
virtual nonstd::span< const gdof_idx_t > GlobalDofIndices(const lf::mesh::Entity &entity) const =0
access to indices of global dof's belonging to an entity
virtual size_type NumDofs() const =0
total number of dof's handled by the object
Dof handler allowing variable local dof layouts.
Interface class representing a topological entity in a cellular complex
virtual const geometry::Geometry * Geometry() const =0
Describes the geometry of this entity.
virtual nonstd::span< const Entity *const > SubEntities(unsigned rel_codim) const =0
Return all sub entities of this entity that have the given codimension (w.r.t. this entity!...
virtual base::RefEl RefEl() const =0
Describes the reference element type of this entity.
Linear Lagrange finite element on triangular reference element.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Computation of the gradients of all reference shape functions in a number of points.
Local assembler for a matrix mapping boundary basis function coefficients to jumps.
const lf::mesh::utils::MeshDataSet< bool > & boundary_
Eigen::MatrixXd Eval(const lf::mesh::Entity &entity) const
Compute the element matrix for some triangle of the mesh.
PiecewiseBoundaryNormalJumpAssembler(std::shared_ptr< const lf::mesh::Mesh > mesh, const lf::mesh::utils::MeshDataSet< bool > &boundary)
Constructor.
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.
unsigned int size_type
general type for variables related to size of arrays
lf::base::size_type size_type
@ kSegment
Returns the (1-dimensional) reference segment.
@ kPoint
Returns the (0-dimensional) reference point.
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.
Eigen::Matrix< double, 2, 3 > computeOutwardNormals(const lf::mesh::Entity &entity)
Compute the outward pointing normals of a triangle.