Skip to content

Commit 4e1515a

Browse files
committed
Document FEM Laplacian
1 parent d2869b8 commit 4e1515a

File tree

1 file changed

+81
-15
lines changed

1 file changed

+81
-15
lines changed

source/pbat/fem/LaplacianMatrix.h

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
/**
2+
* @file LaplacianMatrix.h
3+
* @author Quoc-Minh Ton-That ([email protected])
4+
* @brief SymmetricLaplacianMatrix API and implementation.
5+
* @date 2025-02-11
6+
*
7+
* @copyright Copyright (c) 2025
8+
*
9+
*/
10+
111
#ifndef PBAT_FEM_LAPLACIAN_MATRIX_H
212
#define PBAT_FEM_LAPLACIAN_MATRIX_H
313

@@ -13,16 +23,55 @@
1323
namespace pbat {
1424
namespace fem {
1525

26+
/**
27+
* @brief A matrix-free representation of the symmetric part of the Laplacian \f$\Delta u\f$ of a
28+
* finite element discretized function \f$ u(X) \f$ under Galerkin projection.
29+
*
30+
* The precise definition of the Laplacian matrix's symmetric part is given by
31+
* \f$ \mathbf{L}_{ij} = \int_\Omega -\nabla \phi_i \cdot \nabla \phi_j d\Omega \f$.
32+
*
33+
* * @todo Explain the Laplacian matrix and its construction and link to my higher-level FEM crash
34+
* course doc.
35+
*
36+
* This matrix-free Laplacian requires the following inputs:
37+
* - A finite element `mesh` satisfying concept CMesh
38+
* - A vector of element indices `eg`, associating each quadrature point with an element
39+
* - A vector of quadrature weights `wg`
40+
* - A matrix `GNegg` of element shape function gradients at quadrature points (see
41+
* ShapeFunctionGradients())
42+
* - An integer `dims` specifying the dimensionality of the image of the FEM function space
43+
*
44+
* @note
45+
* The user-provided quadrature rule is injected into the Laplacian operator, allowing for
46+
* arbitrary quadrature rules to be used. Since Laplacians of higher-dimensional functions
47+
* are only one-dimensional Laplacian 'kroneckered' with the identity matrix, the Laplacian
48+
* matrix is actually \f$ L \otimes I_{d \times d} \f$ where \f$ d \f$ is the function's
49+
* dimensionality, but we need not store the duplicate entries.
50+
*
51+
* @tparam TMesh Type satisfying concept CMesh
52+
*/
1653
template <CMesh TMesh>
1754
struct SymmetricLaplacianMatrix
1855
{
1956
public:
20-
using SelfType = SymmetricLaplacianMatrix<TMesh>;
21-
using MeshType = TMesh;
22-
using ElementType = typename TMesh::ElementType;
57+
using SelfType = SymmetricLaplacianMatrix<TMesh>; ///< Self type
58+
using MeshType = TMesh; ///< Mesh type
59+
using ElementType = typename TMesh::ElementType; ///< Element type
2360

24-
static int constexpr kOrder = 2 * (ElementType::kOrder - 1);
61+
static int constexpr kOrder =
62+
2 * (ElementType::kOrder - 1); ///< Polynomial order of the Laplacian matrix
2563

64+
/**
65+
* @brief Construct a new symmetric Laplacian operator
66+
*
67+
* @param mesh Finite element mesh
68+
* @param eg Element indices associating each quadrature point with an element
69+
* @param wg Quadrature weights
70+
* @param GNegg Element shape function gradients at quadrature points
71+
* @param dims Dimensionality of the image of the FEM function space
72+
* @pre `eg.size() == wg.size()` and `GNegg.rows() == mesh.E.rows()` and `dims >= 1`
73+
*
74+
*/
2675
SymmetricLaplacianMatrix(
2776
MeshType const& mesh,
2877
Eigen::Ref<IndexVectorX const> const& eg,
@@ -35,38 +84,55 @@ struct SymmetricLaplacianMatrix
3584
/**
3685
* @brief Applies this matrix as a linear operator on x, adding result to y.
3786
*
38-
* @tparam TDerivedIn
39-
* @tparam TDerivedOut
40-
* @param x
41-
* @param y
87+
* @tparam TDerivedIn Input matrix type
88+
* @tparam TDerivedOut Output matrix type
89+
* @param x Input matrix
90+
* @param y Output matrix
91+
* @pre x.rows() == InputDimensions() and y.rows() == OutputDimensions() and y.cols() ==
92+
* x.cols()
4293
*/
4394
template <class TDerivedIn, class TDerivedOut>
4495
void Apply(Eigen::MatrixBase<TDerivedIn> const& x, Eigen::DenseBase<TDerivedOut>& y) const;
4596

4697
/**
4798
* @brief Transforms this matrix-free matrix representation into sparse compressed format.
48-
* @return
99+
* @return CSCMatrix Sparse compressed column matrix representation of this Laplacian matrix
49100
*/
50101
CSCMatrix ToMatrix() const;
51102

103+
/**
104+
* @brief Number of input dimensions
105+
*
106+
* @return Index
107+
*/
52108
Index InputDimensions() const { return dims * mesh.X.cols(); }
109+
/**
110+
* @brief Number of output dimensions
111+
*
112+
* @return Index
113+
*/
53114
Index OutputDimensions() const { return InputDimensions(); }
54115

116+
/**
117+
* @brief Compute and store the element laplacians
118+
*/
55119
void ComputeElementLaplacians();
56-
120+
/**
121+
* @brief Check if the state of this Laplacian matrix is valid
122+
*/
57123
void CheckValidState() const;
58124

59125
MeshType const& mesh; ///< The finite element mesh
60126
Eigen::Ref<IndexVectorX const>
61-
eg; ///< |#quad.pts.|x1 array of elements associated with quadrature points
62-
Eigen::Ref<VectorX const> wg; ///< |#quad.pts.|x1 array of quadrature weights
127+
eg; ///< `|# quad.pts.|x1` array of elements associated with quadrature points
128+
Eigen::Ref<VectorX const> wg; ///< `|# quad.pts.|x1` array of quadrature weights
63129
Eigen::Ref<MatrixX const>
64-
GNeg; ///< |#element nodes|x|#dims * #quad.pts. * #elements|
130+
GNeg; ///< `|# element nodes|x|# dims * # quad.pts. * # elements|`
65131
///< matrix of element shape function gradients at quadrature points
66-
MatrixX deltag; ///< |#element nodes| x |#element nodes * #quad.pts.| matrix of element
132+
MatrixX deltag; ///< `|# element nodes| x |# element nodes * # quad.pts.|` matrix of element
67133
///< laplacians at quadrature points
68134
int dims; ///< Dimensionality of image of FEM function space, i.e. this Laplacian matrix is
69-
///< actually L \kronecker I_{dims \times dims}. Should be >= 1.
135+
///< actually \f$ L \kronecker I_{dims \times dims} \f$. Must have `dims >= 1`.
70136
};
71137

72138
template <CMesh TMesh>

0 commit comments

Comments
 (0)