version 0.4
simpleassemblers.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2024 The Ikarus Developers mueller@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
9#pragma once
10#include <mutex>
11#include <ranges>
12#include <utility>
13
14#include <dune/functions/backends/istlvectorbackend.hh>
15
16#include <Eigen/Core>
17#include <Eigen/Sparse>
18
20
21namespace Ikarus {
30 template <typename FEContainer_, typename DirichletValuesType_>
32 public:
33 using FEContainerRaw = std::remove_cvref_t<FEContainer_>;
34 using FERequirementType = typename FEContainerRaw::value_type::FERequirementType;
36 using GlobalIndex = typename FEContainerRaw::value_type::GlobalIndex;
37 using Basis = typename DirichletValuesType_::Basis;
38 using GridView = typename Basis::GridView;
39 using FEContainer = FEContainer_;
40 using FEContainerType = std::conditional_t<std::is_reference_v<FEContainer>, const FEContainer, FEContainer>;
42 using DirichletValuesType = DirichletValuesType_;
43
50 FlatAssemblerBase(FEContainer&& fes, const DirichletValuesType& p_dirichletValues)
51 : feContainer{std::forward<FEContainer>(fes)}, dirichletValues{&p_dirichletValues} {
52 constraintsBelow_.reserve(dirichletValues->size());
53 size_t counter = 0;
54 for (auto iv : std::ranges::iota_view{decltype(dirichletValues->size())(0), dirichletValues->size()}) {
55 constraintsBelow_.emplace_back(counter);
56 if (dirichletValues->isConstrained(iv)) ++counter;
57 }
58 fixedDofs = dirichletValues->fixedDOFsize();
59 }
60
65 size_t reducedSize() { return dirichletValues->size() - fixedDofs; }
66
71 size_t size() { return dirichletValues->size(); }
72
80 Eigen::VectorXd createFullVector(Eigen::Ref<const Eigen::VectorXd> reducedVector);
81
86 auto& finiteElements() const { return feContainer; }
87
94 [[nodiscard]] size_t constraintsBelow(size_t i) const { return constraintsBelow_[i]; }
95
102 [[nodiscard]] bool isConstrained(size_t i) const { return dirichletValues->isConstrained(i); }
103
110 [[nodiscard]] size_t estimateOfConnectivity() const {
111 return dirichletValues->basis().gridView().size(GridView::dimension) * 8;
112 }
113
114 private:
115 FEContainerType feContainer;
116 DirichletValuesType const* dirichletValues;
117 std::vector<size_t> constraintsBelow_{};
118 size_t fixedDofs{};
119 };
120
121#ifndef DOXYGEN
122 template <class T, class DirichletValuesType>
123 FlatAssemblerBase(T&& fes, const DirichletValuesType& dirichletValues_) -> FlatAssemblerBase<T, DirichletValuesType>;
124#endif
125
133 template <typename FEContainer_, typename DirichletValuesType_>
134 class ScalarAssembler : public FlatAssemblerBase<FEContainer_, DirichletValuesType_> {
135 using FEContainerRaw = std::remove_cvref_t<FEContainer_>;
137
138 public:
139 using typename Base::Basis;
140 using typename Base::DirichletValuesType;
141 using typename Base::FEContainer;
142 using typename Base::FERequirementType;
143 using typename Base::GlobalIndex;
144
151 ScalarAssembler(FEContainer&& fes, const DirichletValuesType& dirichletValues_)
152 : FlatAssemblerBase<FEContainer, DirichletValuesType>(std::forward<FEContainer>(fes), dirichletValues_) {}
153
160 const double& getScalar(const FERequirementType& feRequirements) { return getScalarImpl(feRequirements); }
161
162 private:
169 double& getScalarImpl(const FERequirementType& feRequirements) {
170 scal = 0.0;
171 for (auto& fe : this->finiteElements()) {
172 scal += fe.calculateScalar(feRequirements);
173 }
174 return scal;
175 }
176
177 double scal{0.0};
178 };
179
180#ifndef DOXYGEN
181 template <class T, class DirichletValuesType>
182 ScalarAssembler(T&& fes, const DirichletValuesType& dirichletValues_) -> ScalarAssembler<T, DirichletValuesType>;
183#endif
184
192 template <typename FEContainer_, typename DirichletValuesType_>
193 class VectorFlatAssembler : public ScalarAssembler<FEContainer_, DirichletValuesType_> {
194 using FEContainerRaw = std::remove_cvref_t<FEContainer_>;
196
197 public:
198 using typename Base::Basis;
199 using typename Base::DirichletValuesType;
200 using typename Base::FEContainer;
201 using typename Base::FERequirementType;
202 using typename Base::GlobalIndex;
203
204 public:
212 : ScalarAssembler<FEContainer, DirichletValuesType>(std::forward<FEContainer>(fes), dirichletValues_) {}
213
220 const Eigen::VectorXd& getRawVector(const FERequirementType& feRequirements) {
221 return getRawVectorImpl(feRequirements);
222 }
223
231 const Eigen::VectorXd& getVector(const FERequirementType& feRequirements) { return getVectorImpl(feRequirements); }
232
240 const Eigen::VectorXd& getReducedVector(const FERequirementType& feRequirements) {
241 return getReducedVectorImpl(feRequirements);
242 }
243
244 private:
245 void assembleRawVectorImpl(const FERequirementType& feRequirements, Eigen::VectorXd& assemblyVec);
246 Eigen::VectorXd& getRawVectorImpl(const FERequirementType& feRequirements);
247 Eigen::VectorXd& getVectorImpl(const FERequirementType& feRequirements);
248
249 Eigen::VectorXd& getReducedVectorImpl(const FERequirementType& feRequirements);
250
251 Eigen::VectorXd vecRaw{};
252 Eigen::VectorXd vec{};
253 Eigen::VectorXd vecRed{};
254 };
255
256#ifndef DOXYGEN
257 template <class T, class DirichletValuesType>
258 VectorFlatAssembler(T&& fes, const DirichletValuesType& dirichletValues_)
259 -> VectorFlatAssembler<T, DirichletValuesType>;
260#endif
261
270 template <typename FEContainer_, typename DirichletValuesType_>
271 class SparseFlatAssembler : public VectorFlatAssembler<FEContainer_, DirichletValuesType_> {
272 public:
273 using FEContainerRaw = std::remove_cvref_t<FEContainer_>;
275
276 using typename Base::Basis;
277 using typename Base::DirichletValuesType;
278 using typename Base::FEContainer;
279 using typename Base::FERequirementType;
280 using typename Base::GlobalIndex;
281
289 : VectorFlatAssembler<FEContainer, DirichletValuesType>(std::forward<FEContainer>(fes), dirichletValues_) {}
290
291 using GridView = typename Basis::GridView;
292
299 const Eigen::SparseMatrix<double>& getRawMatrix(const FERequirementType& feRequirements) {
300 return getRawMatrixImpl(feRequirements);
301 }
302
310 const Eigen::SparseMatrix<double>& getMatrix(const FERequirementType& feRequirements) {
311 return getMatrixImpl(feRequirements);
312 }
313
321 const Eigen::SparseMatrix<double>& getReducedMatrix(const FERequirementType& feRequirements) {
322 return getReducedMatrixImpl(feRequirements);
323 }
324
325 private:
326 void assembleRawMatrixImpl(const FERequirementType& feRequirements, Eigen::SparseMatrix<double>& assemblyMat);
327 Eigen::SparseMatrix<double>& getRawMatrixImpl(const FERequirementType& feRequirements);
328 Eigen::SparseMatrix<double>& getMatrixImpl(const FERequirementType& feRequirements);
329 Eigen::SparseMatrix<double>& getReducedMatrixImpl(const FERequirementType& feRequirements);
330
333 void createOccupationPattern(Eigen::SparseMatrix<double>& assemblyMat);
334
337 void createReducedOccupationPattern(Eigen::SparseMatrix<double>& assemblyMat);
338
340 void createLinearDOFsPerElement(Eigen::SparseMatrix<double>& assemblyMat);
341
344 void createLinearDOFsPerElementReduced(Eigen::SparseMatrix<double>& assemblyMat);
345
347 void preProcessSparseMatrix(Eigen::SparseMatrix<double>& assemblyMat);
348
350 void preProcessSparseMatrixReduced(Eigen::SparseMatrix<double>& assemblyMat);
351
352 Eigen::SparseMatrix<double> spMatRaw;
353 Eigen::SparseMatrix<double> spMat;
354 Eigen::SparseMatrix<double> spMatReduced;
355 std::vector<std::vector<Eigen::Index>>
356 elementLinearIndices;
357 std::vector<std::vector<Eigen::Index>>
358 elementLinearReducedIndices;
359 std::once_flag sparsePreProcessorRaw, sparsePreProcessor,
360 sparsePreProcessorReduced;
361 };
362
363#ifndef DOXYGEN
364 template <class T, class DirichletValuesType>
365 SparseFlatAssembler(T&& fes, const DirichletValuesType& dirichletValues_)
366 -> SparseFlatAssembler<T, DirichletValuesType>;
367#endif
368
378 template <typename FEContainer_, typename DirichletValuesType_>
379 class DenseFlatAssembler : public VectorFlatAssembler<FEContainer_, DirichletValuesType_> {
380 public:
381 using FEContainerRaw = std::remove_cvref_t<FEContainer_>;
383
384 using typename Base::Basis;
385 using typename Base::DirichletValuesType;
386 using typename Base::FEContainer;
387 using typename Base::FERequirementType;
388 using typename Base::GlobalIndex;
389
396 explicit DenseFlatAssembler(FEContainer&& fes, const DirichletValuesType& dirichletValues_)
397 : VectorFlatAssembler<FEContainer, DirichletValuesType>(std::forward<FEContainer>(fes), dirichletValues_) {}
398
405 const Eigen::MatrixXd& getRawMatrix(const FERequirementType& feRequirements) {
406 return getRawMatrixImpl(feRequirements);
407 }
408
416 const Eigen::MatrixXd& getMatrix(const FERequirementType& feRequirements) { return getMatrixImpl(feRequirements); }
417
425 const Eigen::MatrixXd& getReducedMatrix(const FERequirementType& feRequirements) {
426 return getReducedMatrixImpl(feRequirements);
427 }
428
429 private:
430 void assembleRawMatrixImpl(const FERequirementType& feRequirements, Eigen::MatrixXd& assemblyMat);
431 Eigen::MatrixXd& getRawMatrixImpl(const FERequirementType& feRequirements);
432 Eigen::MatrixXd& getMatrixImpl(const FERequirementType& feRequirements);
433 Eigen::MatrixXd& getReducedMatrixImpl(const FERequirementType& feRequirements);
434
435 Eigen::MatrixXd matRaw{};
436 Eigen::MatrixXd mat{};
437 Eigen::MatrixXd matRed{};
438 };
439
440#ifndef DOXYGEN
441 // https://en.cppreference.com/w/cpp/language/class_template_argument_deduction
442 template <class T, class DirichletValuesType>
443 DenseFlatAssembler(T&& fes, const DirichletValuesType& dirichletValues_)
444 -> DenseFlatAssembler<T, DirichletValuesType>;
445#endif
446} // namespace Ikarus
447
448#include "simpleassemblers.inl"
Implementation of assembler functions.
Definition: simpleassemblers.hh:21
The FlatAssemblerBase takes care of common subtasks done by flat assemblers.
Definition: simpleassemblers.hh:31
FEContainer_ FEContainer
Type of the finite element container.
Definition: simpleassemblers.hh:39
typename Basis::GridView GridView
Type of the grid view.
Definition: simpleassemblers.hh:38
typename FEContainerRaw::value_type::GlobalIndex GlobalIndex
Type of the global index.
Definition: simpleassemblers.hh:36
bool isConstrained(size_t i) const
Returns true if a given degree of freedom is fixed by a Dirichlet boundary condition.
Definition: simpleassemblers.hh:102
std::conditional_t< std::is_reference_v< FEContainer >, const FEContainer, FEContainer > FEContainerType
Type of the finite element container (reference or by value).
Definition: simpleassemblers.hh:41
size_t estimateOfConnectivity() const
Coarse estimate of node connectivity, i.e., this relates to the bandwidth of a sparse matrix....
Definition: simpleassemblers.hh:110
Eigen::VectorXd createFullVector(Eigen::Ref< const Eigen::VectorXd > reducedVector)
Creates the full-sized vector of size Dof and inserts the values of a reduced vector at the "free" de...
Definition: simpleassemblers.inl:15
size_t constraintsBelow(size_t i) const
Returns the number of constraints below a given degrees of freedom index.
Definition: simpleassemblers.hh:94
std::remove_cvref_t< FEContainer_ > FEContainerRaw
Type of the raw finite element container.
Definition: simpleassemblers.hh:33
size_t reducedSize()
Returns the size of the free degrees of freedom, which are not fixed by a Dirichlet boundary conditio...
Definition: simpleassemblers.hh:65
auto & finiteElements() const
Returns the container of finite elements.
Definition: simpleassemblers.hh:86
FlatAssemblerBase(FEContainer &&fes, const DirichletValuesType &p_dirichletValues)
Constructor for FlatAssemblerBase.
Definition: simpleassemblers.hh:50
DirichletValuesType_ DirichletValuesType
Type of the Dirichlet values.
Definition: simpleassemblers.hh:42
typename FEContainerRaw::value_type::FERequirementType FERequirementType
Type of the finite element requirement.
Definition: simpleassemblers.hh:35
size_t size()
Returns the size of nodes, i.e., the number of degrees of freedom.
Definition: simpleassemblers.hh:71
typename DirichletValuesType_::Basis Basis
Type of the basis.
Definition: simpleassemblers.hh:37
ScalarAssembler assembles scalar quantities.
Definition: simpleassemblers.hh:134
FEContainer_ FEContainer
Type of the finite element container.
Definition: simpleassemblers.hh:39
const double & getScalar(const FERequirementType &feRequirements)
Calculates the scalar quantity requested by feRequirements and returns a reference.
Definition: simpleassemblers.hh:160
typename FEContainerRaw::value_type::GlobalIndex GlobalIndex
Type of the global index.
Definition: simpleassemblers.hh:36
ScalarAssembler(FEContainer &&fes, const DirichletValuesType &dirichletValues_)
Constructor for ScalarAssembler.
Definition: simpleassemblers.hh:151
DirichletValuesType_ DirichletValuesType
Type of the Dirichlet values.
Definition: simpleassemblers.hh:42
typename FEContainerRaw::value_type::FERequirementType FERequirementType
Type of the finite element requirement.
Definition: simpleassemblers.hh:35
typename DirichletValuesType_::Basis Basis
Type of the basis.
Definition: simpleassemblers.hh:37
VectorFlatAssembler assembles vector quantities using a flat basis Indexing strategy.
Definition: simpleassemblers.hh:193
FEContainer_ FEContainer
Type of the finite element container.
Definition: simpleassemblers.hh:39
typename FEContainerRaw::value_type::GlobalIndex GlobalIndex
Type of the global index.
Definition: simpleassemblers.hh:36
const Eigen::VectorXd & getRawVector(const FERequirementType &feRequirements)
Calculates the vectorial quantity requested by feRequirements and returns a reference.
Definition: simpleassemblers.hh:220
const Eigen::VectorXd & getReducedVector(const FERequirementType &feRequirements)
Calculates the vectorial quantity requested by feRequirements and returns a reference....
Definition: simpleassemblers.hh:240
const Eigen::VectorXd & getVector(const FERequirementType &feRequirements)
Calculates the vectorial quantity requested by feRequirements and returns a reference....
Definition: simpleassemblers.hh:231
DirichletValuesType_ DirichletValuesType
Type of the Dirichlet values.
Definition: simpleassemblers.hh:42
VectorFlatAssembler(FEContainer &&fes, const DirichletValuesType &dirichletValues_)
Constructor for VectorFlatAssembler.
Definition: simpleassemblers.hh:211
typename FEContainerRaw::value_type::FERequirementType FERequirementType
Type of the finite element requirement.
Definition: simpleassemblers.hh:35
typename DirichletValuesType_::Basis Basis
Type of the basis.
Definition: simpleassemblers.hh:37
SparseFlatAssembler assembles matrix quantities using a flat basis Indexing strategy....
Definition: simpleassemblers.hh:271
SparseFlatAssembler(FEContainer &&fes, const DirichletValuesType &dirichletValues_)
Constructor for SparseFlatAssembler.
Definition: simpleassemblers.hh:288
const Eigen::SparseMatrix< double > & getReducedMatrix(const FERequirementType &feRequirements)
Calculates the matrix quantity requested by feRequirements and returns a reference....
Definition: simpleassemblers.hh:321
const Eigen::SparseMatrix< double > & getRawMatrix(const FERequirementType &feRequirements)
Calculates the matrix quantity requested by feRequirements and returns a reference.
Definition: simpleassemblers.hh:299
const Eigen::SparseMatrix< double > & getMatrix(const FERequirementType &feRequirements)
Calculates the matrix quantity requested by feRequirements and returns a reference....
Definition: simpleassemblers.hh:310
typename FEContainerRaw::value_type::FERequirementType FERequirementType
Type of the finite element requirement.
Definition: simpleassemblers.hh:35
DenseFlatAssembler assembles matrix quantities using a flat basis Indexing strategy....
Definition: simpleassemblers.hh:379
const Eigen::MatrixXd & getMatrix(const FERequirementType &feRequirements)
Calculates the matrix quantity requested by feRequirements and returns a reference....
Definition: simpleassemblers.hh:416
const Eigen::MatrixXd & getReducedMatrix(const FERequirementType &feRequirements)
Calculates the matrix quantity requested by feRequirements and returns a reference....
Definition: simpleassemblers.hh:425
const Eigen::MatrixXd & getRawMatrix(const FERequirementType &feRequirements)
Calculates the matrix quantity requested by feRequirements and returns a reference.
Definition: simpleassemblers.hh:405
DenseFlatAssembler(FEContainer &&fes, const DirichletValuesType &dirichletValues_)
< Type of the global index.
Definition: simpleassemblers.hh:396
typename FEContainerRaw::value_type::FERequirementType FERequirementType
Type of the finite element requirement.
Definition: simpleassemblers.hh:35
typename PreBasis::GridView GridView
The type of the grid view.
Definition: utils/basis.hh:32
Definition of DirichletValues class for handling Dirichlet boundary conditions.