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
+
1
11
#ifndef PBAT_FEM_LAPLACIAN_MATRIX_H
2
12
#define PBAT_FEM_LAPLACIAN_MATRIX_H
3
13
13
23
namespace pbat {
14
24
namespace fem {
15
25
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
+ */
16
53
template <CMesh TMesh>
17
54
struct SymmetricLaplacianMatrix
18
55
{
19
56
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
23
60
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
25
63
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
+ */
26
75
SymmetricLaplacianMatrix (
27
76
MeshType const & mesh,
28
77
Eigen::Ref<IndexVectorX const > const & eg,
@@ -35,38 +84,55 @@ struct SymmetricLaplacianMatrix
35
84
/* *
36
85
* @brief Applies this matrix as a linear operator on x, adding result to y.
37
86
*
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()
42
93
*/
43
94
template <class TDerivedIn , class TDerivedOut >
44
95
void Apply (Eigen::MatrixBase<TDerivedIn> const & x, Eigen::DenseBase<TDerivedOut>& y) const ;
45
96
46
97
/* *
47
98
* @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
49
100
*/
50
101
CSCMatrix ToMatrix () const ;
51
102
103
+ /* *
104
+ * @brief Number of input dimensions
105
+ *
106
+ * @return Index
107
+ */
52
108
Index InputDimensions () const { return dims * mesh.X .cols (); }
109
+ /* *
110
+ * @brief Number of output dimensions
111
+ *
112
+ * @return Index
113
+ */
53
114
Index OutputDimensions () const { return InputDimensions (); }
54
115
116
+ /* *
117
+ * @brief Compute and store the element laplacians
118
+ */
55
119
void ComputeElementLaplacians ();
56
-
120
+ /* *
121
+ * @brief Check if the state of this Laplacian matrix is valid
122
+ */
57
123
void CheckValidState () const ;
58
124
59
125
MeshType const & mesh; // /< The finite element mesh
60
126
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
63
129
Eigen::Ref<MatrixX const >
64
- GNeg; // /< |# element nodes|x|#dims * #quad.pts. * #elements|
130
+ GNeg; // /< `|# element nodes|x|# dims * # quad.pts. * # elements|`
65
131
// /< 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
67
133
// /< laplacians at quadrature points
68
134
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` .
70
136
};
71
137
72
138
template <CMesh TMesh>
0 commit comments