11#ifndef PBAT_FEM_LAPLACIAN_MATRIX_H
12#define PBAT_FEM_LAPLACIAN_MATRIX_H
21#include <tbb/parallel_for.h>
62 2 * (ElementType::kOrder - 1);
77 Eigen::Ref<IndexVectorX const>
const&
eg,
78 Eigen::Ref<VectorX const>
const&
wg,
79 Eigen::Ref<MatrixX const>
const& GNegg,
94 template <
class TDerivedIn,
class TDerivedOut>
95 void Apply(Eigen::MatrixBase<TDerivedIn>
const& x, Eigen::DenseBase<TDerivedOut>& y)
const;
126 Eigen::Ref<IndexVectorX const>
128 Eigen::Ref<VectorX const>
wg;
129 Eigen::Ref<MatrixX const>
138template <CMesh TMesh>
141 Eigen::Ref<IndexVectorX const>
const&
eg,
142 Eigen::Ref<VectorX const>
const&
wg,
143 Eigen::Ref<MatrixX const>
const&
GNeg,
150template <CMesh TMesh>
156 using SparseIndex =
typename CSCMatrix::StorageIndex;
157 using Triplet = Eigen::Triplet<Scalar, SparseIndex>;
159 std::vector<Triplet> triplets{};
160 triplets.reserve(
static_cast<std::size_t
>(
deltag.size() *
dims));
161 auto const numberOfQuadraturePoints =
wg.size();
162 for (
auto g = 0; g < numberOfQuadraturePoints; ++g)
164 auto const e =
eg(g);
165 auto const nodes =
mesh.E.col(e);
166 auto constexpr kNodesPerElement = ElementType::kNodes;
167 auto const Leg =
deltag.block(0, g * kNodesPerElement, kNodesPerElement, kNodesPerElement);
168 for (
auto j = 0; j < Leg.cols(); ++j)
170 for (
auto i = 0; i < Leg.rows(); ++i)
172 for (
auto d = 0; d <
dims; ++d)
174 auto const ni =
static_cast<SparseIndex
>(
dims * nodes(i) + d);
175 auto const nj =
static_cast<SparseIndex
>(
dims * nodes(j) + d);
176 triplets.push_back(Triplet(ni, nj, Leg(i, j)));
181 L.setFromTriplets(triplets.begin(), triplets.end());
185template <CMesh TMesh>
191 auto constexpr kNodesPerElement = ElementType::kNodes;
192 auto constexpr kDims = MeshType::kDims;
193 auto const numberOfQuadraturePoints =
wg.size();
194 deltag.setZero(kNodesPerElement, kNodesPerElement * numberOfQuadraturePoints);
195 tbb::parallel_for(
Index{0},
Index{numberOfQuadraturePoints}, [&](
Index g) {
196 auto Leg =
deltag.block<kNodesPerElement, kNodesPerElement>(0, g * kNodesPerElement);
200 auto const GP =
GNeg.block<kNodesPerElement, kDims>(0, g * kDims);
201 Leg -=
wg(g) * GP * GP.transpose();
205template <CMesh TMesh>
208 auto const numberOfQuadraturePoints =
wg.size();
209 auto constexpr kExpectedGNegRows = ElementType::kNodes;
210 auto const expectedGNegCols = MeshType::kDims * numberOfQuadraturePoints;
211 bool const bShapeFunctionGradientsHaveCorrectDimensions =
212 (
GNeg.rows() == kExpectedGNegRows) and (
GNeg.cols() == expectedGNegCols);
213 if (not bShapeFunctionGradientsHaveCorrectDimensions)
215 std::string
const what = fmt::format(
216 "Expected shape function gradients at element quadrature points of dimensions "
217 "|#nodes-per-element|={} x |#mesh-dims * #quad.pts.|={} for polynomial but got {}x{} "
223 throw std::invalid_argument(what);
227 std::string
const what =
228 fmt::format(
"Expected output dimensionality >= 1, got {} instead",
dims);
229 throw std::invalid_argument(what);
233template <CMesh TMesh>
234template <
class TDerivedIn,
class TDerivedOut>
236 Eigen::MatrixBase<TDerivedIn>
const& x,
237 Eigen::DenseBase<TDerivedOut>& y)
const
242 bool const bAreInputOutputValid =
243 (x.rows() != numberOfDofs) or (y.rows() != numberOfDofs) or (y.cols() != x.cols());
244 if (bAreInputOutputValid)
246 std::string
const what = fmt::format(
247 "Expected input x and output y with matching dimensions and {} rows, but got {}x{} "
248 "input and {}x{} output",
254 throw std::invalid_argument(what);
257 auto const numberOfQuadraturePoints =
wg.size();
258 for (
auto c = 0; c < x.cols(); ++c)
260 for (
auto g = 0; g < numberOfQuadraturePoints; ++g)
262 auto const e =
eg(g);
263 auto const nodes =
mesh.E.col(e);
264 auto constexpr kNodesPerElement = ElementType::kNodes;
266 deltag.block(0, g * kNodesPerElement, kNodesPerElement, kNodesPerElement);
267 auto ye = y.col(c).reshaped(
dims, y.size() /
dims)(Eigen::placeholders::all, nodes);
269 x.col(c).reshaped(
dims, x.size() /
dims)(Eigen::placeholders::all, nodes);
Profiling utilities for the Physics-Based Animation Toolkit (PBAT)
#define PBAT_PROFILE_NAMED_SCOPE(name)
Definition Profiling.h:32
Eigen adaptors for ranges.
Finite Element Method (FEM)
Definition Concepts.h:19
The main namespace of the library.
Definition Aliases.h:15
Eigen::SparseMatrix< Scalar, Eigen::ColMajor > CSCMatrix
Column-major sparse matrix type.
Definition Aliases.h:52
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic-size matrix type.
Definition Aliases.h:34
std::ptrdiff_t Index
Index type.
Definition Aliases.h:17
MeshType const & mesh
The finite element mesh.
Definition LaplacianMatrix.h:125
void CheckValidState() const
Check if the state of this Laplacian matrix is valid.
Definition LaplacianMatrix.h:206
SymmetricLaplacianMatrix< TMesh > SelfType
Self type.
Definition LaplacianMatrix.h:57
Index OutputDimensions() const
Number of rows.
Definition LaplacianMatrix.h:114
void ComputeElementLaplacians()
Compute and store the element laplacians.
Definition LaplacianMatrix.h:186
static int constexpr kOrder
Polynomial order of the Laplacian matrix.
Definition LaplacianMatrix.h:61
SymmetricLaplacianMatrix(MeshType const &mesh, Eigen::Ref< IndexVectorX const > const &eg, Eigen::Ref< VectorX const > const &wg, Eigen::Ref< MatrixX const > const &GNegg, int dims=1)
Construct a new symmetric Laplacian operator.
Definition LaplacianMatrix.h:139
Index InputDimensions() const
Number of columns.
Definition LaplacianMatrix.h:108
typename TMesh::ElementType ElementType
Element type.
Definition LaplacianMatrix.h:59
CSCMatrix ToMatrix() const
Transforms this matrix-free matrix representation into sparse compressed format.
Definition LaplacianMatrix.h:151
Eigen::Ref< MatrixX const > GNeg
Definition LaplacianMatrix.h:130
Eigen::Ref< VectorX const > wg
|# quad.pts.|x1 array of quadrature weights
Definition LaplacianMatrix.h:128
Eigen::Ref< IndexVectorX const > eg
|# quad.pts.|x1 array of elements associated with quadrature points
Definition LaplacianMatrix.h:127
int dims
Definition LaplacianMatrix.h:134
void Apply(Eigen::MatrixBase< TDerivedIn > const &x, Eigen::DenseBase< TDerivedOut > &y) const
Applies this matrix as a linear operator on x, adding result to y.
Definition LaplacianMatrix.h:235
TMesh MeshType
Mesh type.
Definition LaplacianMatrix.h:58
MatrixX deltag
Definition LaplacianMatrix.h:132