version 0.4.2
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
11#include <ranges>
12#include <utility>
13
14#include <dune/functions/backends/istlvectorbackend.hh>
15
16#include <Eigen/Core>
17#include <Eigen/Sparse>
18
23
24namespace Ikarus {
33template <typename FEC, typename DV>
35{
36public:
37 using FEContainerRaw = std::remove_cvref_t<FEC>;
38 using FERequirement = typename FEContainerRaw::value_type::Requirement;
40 using GlobalIndex = typename FEContainerRaw::value_type::GlobalIndex;
41 using Basis = typename DV::Basis;
42 using GridView = typename Basis::GridView;
43 using FEContainer = FEC;
44 using FEContainerType = std::conditional_t<std::is_reference_v<FEContainer>, const FEContainer, FEContainer>;
47
55 : feContainer_{std::forward<FEContainer>(fes)},
56 dirichletValues_{&dirichletValues} {
57 constraintsBelow_.reserve(dirichletValues_->size());
58 size_t counter = 0;
59 for (auto iv : std::ranges::iota_view{decltype(dirichletValues_->size())(0), dirichletValues_->size()}) {
60 constraintsBelow_.emplace_back(counter);
61 if (dirichletValues_->isConstrained(iv))
62 ++counter;
63 }
64 fixedDofs_ = dirichletValues_->fixedDOFsize();
65 }
66
71 size_t reducedSize() { return dirichletValues_->size() - fixedDofs_; }
72
77 size_t size() { return dirichletValues_->size(); }
78
86 Eigen::VectorXd createFullVector(Eigen::Ref<const Eigen::VectorXd> reducedVector);
87
92 auto& finiteElements() const { return feContainer_; }
93
100 [[nodiscard]] size_t constraintsBelow(size_t i) const { return constraintsBelow_[i]; }
101
108 [[nodiscard]] bool isConstrained(size_t i) const { return dirichletValues_->isConstrained(i); }
109
116 [[nodiscard]] size_t estimateOfConnectivity() const {
117 return dirichletValues_->basis().gridView().size(GridView::dimension) * 8;
118 }
119
121
129 DBCOption dbcOption = DBCOption::Full) {
130 req_ = std::make_optional<FERequirement>(req);
131 affordances_ = std::make_optional<AffordanceCollectionType>(affordanceCollection);
132 dBCOption_ = std::make_optional<DBCOption>(dbcOption);
133 }
134
140 void bind(const FERequirement& req) { req_ = std::make_optional<FERequirement>(req); }
141
148 affordances_ = std::make_optional<AffordanceCollectionType>(affordanceCollection);
149 }
150
156 void bind(DBCOption dbcOption) { dBCOption_ = std::make_optional<DBCOption>(dbcOption); }
157
163 [[nodiscard]]
164 bool bound() const {
166 return true;
167 else
168 DUNE_THROW(Dune::InvalidStateException, "The assembler is not bound to a requirement, affordance or dBCOption.");
169 }
170
176 [[nodiscard]]
177 bool boundToRequirement() const {
178 return req_.has_value();
179 }
180
186 [[nodiscard]]
188 return affordances_.has_value();
189 }
190
196 [[nodiscard]]
197 bool boundToDBCOption() const {
198 return dBCOption_.has_value();
199 }
200
206 if (req_.has_value())
207 return req_.value();
208 else
209 DUNE_THROW(Dune::InvalidStateException, "The requirement can only be obtained after binding");
210 }
211
217 if (affordances_.has_value())
218 return affordances_.value();
219 else
220 DUNE_THROW(Dune::InvalidStateException, "The affordance can only be obtained after binding");
221 }
222
228 if (dBCOption_.has_value())
229 return dBCOption_.value();
230 else
231 DUNE_THROW(Dune::InvalidStateException, "The dBCOption can only be obtained after binding");
232 }
233
234private:
235 FEContainerType feContainer_;
236 const DirichletValuesType* dirichletValues_;
237 std::optional<FERequirement> req_;
238 std::optional<AffordanceCollectionType> affordances_;
239 std::vector<size_t> constraintsBelow_{};
240 size_t fixedDofs_{};
241 std::optional<DBCOption> dBCOption_;
242};
243
244#ifndef DOXYGEN
245template <class T, class DirichletValuesType>
246FlatAssemblerBase(T&& fes, const DirichletValuesType& dirichletValues) -> FlatAssemblerBase<T, DirichletValuesType>;
247#endif
248
256template <typename FEC, typename DV>
257class ScalarAssembler : public FlatAssemblerBase<FEC, DV>
258{
259 using FEContainerRaw = std::remove_cvref_t<FEC>;
261
262public:
263 using typename Base::Basis;
264 using typename Base::DirichletValuesType;
265 using typename Base::FEContainer;
266 using typename Base::FERequirement;
267 using typename Base::GlobalIndex;
268
277
285 const double& scalar(const FERequirement& feRequirements, ScalarAffordance affordance) {
286 return getScalarImpl(feRequirements, affordance);
287 }
288
294 const double& scalar() { return getScalarImpl(this->requirement(), this->affordanceCollection().scalarAffordance()); }
295
296private:
303 double& getScalarImpl(const FERequirement& feRequirements, ScalarAffordance affordance) {
304 scal_ = 0.0;
305 for (auto& fe : this->finiteElements()) {
306 scal_ += calculateScalar(fe, feRequirements, affordance);
307 }
308 return scal_;
309 }
310
311 double scal_{0.0};
312};
313
314#ifndef DOXYGEN
315template <class T, class DirichletValuesType>
316ScalarAssembler(T&& fes, const DirichletValuesType& dirichletValues) -> ScalarAssembler<T, DirichletValuesType>;
317#endif
318
326template <typename FEC, typename DV>
328{
329 using FEContainerRaw = std::remove_cvref_t<FEC>;
331
332public:
333 using typename Base::Basis;
334 using typename Base::DirichletValuesType;
335 using typename Base::FEContainer;
336 using typename Base::FERequirement;
337 using typename Base::GlobalIndex;
338
339public:
348
362 const Eigen::VectorXd& vector(const FERequirement& feRequirements, VectorAffordance affordance,
363 DBCOption dbcOption = DBCOption::Full) {
364 if (dbcOption == DBCOption::Raw) {
365 return getRawVectorImpl(feRequirements, affordance);
366 } else if (dbcOption == DBCOption::Reduced) {
367 return getReducedVectorImpl(feRequirements, affordance);
368 } else if (dbcOption == DBCOption::Full) {
369 return getVectorImpl(feRequirements, affordance);
370 }
371 __builtin_unreachable();
372 }
373
384 const Eigen::VectorXd& vector(DBCOption dbcOption) {
385 return vector(this->requirement(), this->affordanceCollection().vectorAffordance(), dbcOption);
386 }
387
396 const Eigen::VectorXd& vector() { return vector(this->dBCOption()); }
397
398private:
399 void assembleRawVectorImpl(const FERequirement& feRequirements, VectorAffordance affordance,
400 Eigen::VectorXd& assemblyVec);
401 Eigen::VectorXd& getRawVectorImpl(const FERequirement& feRequirements, VectorAffordance affordance);
402 Eigen::VectorXd& getVectorImpl(const FERequirement& feRequirements, VectorAffordance affordance);
403
404 Eigen::VectorXd& getReducedVectorImpl(const FERequirement& feRequirements, VectorAffordance affordance);
405
406 Eigen::VectorXd vecRaw_{};
407 Eigen::VectorXd vec_{};
408 Eigen::VectorXd vecRed_{};
409};
410
411#ifndef DOXYGEN
412template <class T, class DirichletValuesType>
413VectorFlatAssembler(T&& fes, const DirichletValuesType& dirichletValues) -> VectorFlatAssembler<T, DirichletValuesType>;
414#endif
415
424template <typename FEC, typename DV>
426{
427public:
428 using FEContainerRaw = std::remove_cvref_t<FEC>;
430
431 using typename Base::Basis;
432 using typename Base::DirichletValuesType;
433 using typename Base::FEContainer;
434 using typename Base::FERequirement;
435 using typename Base::GlobalIndex;
436
445
446 using GridView = typename Basis::GridView;
447
459 const Eigen::SparseMatrix<double>& matrix(const FERequirement& feRequirements, MatrixAffordance affordance,
460 DBCOption dbcOption = DBCOption::Full) {
461 if (dbcOption == DBCOption::Raw) {
462 return getRawMatrixImpl(feRequirements, affordance);
463 } else if (dbcOption == DBCOption::Reduced) {
464 return getReducedMatrixImpl(feRequirements, affordance);
465 } else if (dbcOption == DBCOption::Full) {
466 return getMatrixImpl(feRequirements, affordance);
467 }
468 __builtin_unreachable();
469 }
470
479 const Eigen::SparseMatrix<double>& matrix(DBCOption dbcOption) {
480 return matrix(this->requirement(), this->affordanceCollection().matrixAffordance(), dbcOption);
481 }
482
491 const Eigen::SparseMatrix<double>& matrix() { return matrix(this->dBCOption()); }
492
493private:
494 void assembleRawMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance,
495 Eigen::SparseMatrix<double>& assemblyMat);
496 Eigen::SparseMatrix<double>& getRawMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance);
497 Eigen::SparseMatrix<double>& getMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance);
498 Eigen::SparseMatrix<double>& getReducedMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance);
499
502 void createOccupationPattern(Eigen::SparseMatrix<double>& assemblyMat);
503
506 void createReducedOccupationPattern(Eigen::SparseMatrix<double>& assemblyMat);
507
509 void createLinearDOFsPerElement(Eigen::SparseMatrix<double>& assemblyMat);
510
513 void createLinearDOFsPerElementReduced(Eigen::SparseMatrix<double>& assemblyMat);
514
516 void preProcessSparseMatrix(Eigen::SparseMatrix<double>& assemblyMat);
517
519 void preProcessSparseMatrixReduced(Eigen::SparseMatrix<double>& assemblyMat);
520
521 Eigen::SparseMatrix<double> spMatRaw_;
522 Eigen::SparseMatrix<double> spMat_;
523 Eigen::SparseMatrix<double> spMatReduced_;
524 std::vector<std::vector<Eigen::Index>>
525 elementLinearIndices_;
526 std::vector<std::vector<Eigen::Index>>
527 elementLinearReducedIndices_;
528 bool sparsePreProcessorRaw_{}, sparsePreProcessor_{},
529 sparsePreProcessorReduced_{};
530};
531
532#ifndef DOXYGEN
533template <class FEC, class DV>
534SparseFlatAssembler(FEC&& fes, const DV& dirichletValues) -> SparseFlatAssembler<FEC, DV>;
535#endif
536
537template <typename FEC, typename DV>
538auto makeSparseFlatAssembler(FEC&& fes, const DV& dirichletValues) {
539 return std::make_shared<SparseFlatAssembler<FEC, DV>>(std::forward<FEC>(fes), dirichletValues);
540}
541
551template <typename FEC, typename DV>
553{
554public:
555 using FEContainerRaw = std::remove_cvref_t<FEC>;
557
558 using typename Base::Basis;
559 using typename Base::DirichletValuesType;
560 using typename Base::FEContainer;
561 using typename Base::FERequirement;
562 using typename Base::GlobalIndex;
563
572
585 const Eigen::MatrixXd& matrix(const FERequirement& feRequirements, MatrixAffordance affordance,
586 DBCOption dbcOption = DBCOption::Full) {
587 if (dbcOption == DBCOption::Raw) {
588 return getRawMatrixImpl(feRequirements, affordance);
589 } else if (dbcOption == DBCOption::Reduced) {
590 return getReducedMatrixImpl(feRequirements, affordance);
591 } else if (dbcOption == DBCOption::Full) {
592 return getMatrixImpl(feRequirements, affordance);
593 }
594 __builtin_unreachable();
595 }
596
606 const Eigen::MatrixXd& matrix(DBCOption dbcOption) {
607 return matrix(this->requirement(), this->affordanceCollection().matrixAffordance(), dbcOption);
608 }
609
616 const Eigen::MatrixXd& matrix() { return matrix(this->dBCOption()); }
617
618private:
619 void assembleRawMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance,
620 Eigen::MatrixXd& assemblyMat);
621 Eigen::MatrixXd& getRawMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance);
622 Eigen::MatrixXd& getMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance);
623 Eigen::MatrixXd& getReducedMatrixImpl(const FERequirement& feRequirements, MatrixAffordance affordance);
624
625 Eigen::MatrixXd matRaw_{};
626 Eigen::MatrixXd mat_{};
627 Eigen::MatrixXd matRed_{};
628};
629
630#ifndef DOXYGEN
631// https://en.cppreference.com/w/cpp/language/class_template_argument_deduction
632template <class FEC, class DV>
633DenseFlatAssembler(FEC&& fes, const DV& dirichletValues) -> DenseFlatAssembler<FEC, DV>;
634#endif
635
636template <typename FEC, typename DV>
637auto makeDenseFlatAssembler(FEC&& fes, const DV& dirichletValues) {
638 return std::make_shared<DenseFlatAssembler<FEC, DV>>(std::forward<FEC>(fes), dirichletValues);
639}
640} // namespace Ikarus
641
642#include "simpleassemblers.inl"
Implementation of assembler functions.
Definition of the LinearElastic class for finite element mechanics computations.
STL namespace.
Definition: dirichletbcenforcement.hh:6
auto vectorAffordance(MatrixAffordance affordanceM)
Definition: ferequirements.hh:176
MatrixAffordance
A strongly typed enum class representing the matrix affordance.
Definition: ferequirements.hh:63
auto makeSparseFlatAssembler(FEC &&fes, const DV &dirichletValues)
Definition: simpleassemblers.hh:538
auto scalarAffordance(MatrixAffordance affordanceM)
Definition: ferequirements.hh:185
DBCOption
Definition: dirichletbcenforcement.hh:7
auto makeDenseFlatAssembler(FEC &&fes, const DV &dirichletValues)
Definition: simpleassemblers.hh:637
VectorAffordance
A strongly typed enum class representing the vector affordance.
Definition: ferequirements.hh:48
ScalarAffordance
A strongly typed enum class representing the scalar affordance.
Definition: ferequirements.hh:37
def dirichletValues(basis)
Definition: dirichlet_values.py:7
The FlatAssemblerBase takes care of common subtasks done by flat assemblers.
Definition: simpleassemblers.hh:35
void bind(AffordanceCollectionType affordanceCollection)
Binds the assembler to an affordance collection.
Definition: simpleassemblers.hh:147
std::remove_cvref_t< FEC > FEContainerRaw
Type of the raw finite element container.
Definition: simpleassemblers.hh:37
FlatAssemblerBase(FEContainer &&fes, const DirichletValuesType &dirichletValues)
Constructor for FlatAssemblerBase.
Definition: simpleassemblers.hh:54
void bind(const FERequirement &req, AffordanceCollectionType affordanceCollection, DBCOption dbcOption=DBCOption::Full)
Binds the assembler to a set of finite element requirement and affordance.
Definition: simpleassemblers.hh:128
typename FEContainerRaw::value_type::Requirement FERequirement
Type of the finite element requirement.
Definition: simpleassemblers.hh:39
void bind(DBCOption dbcOption)
Binds the assembler to an affordance collection.
Definition: simpleassemblers.hh:156
void bind(const FERequirement &req)
Binds the assembler to a finite element requirement.
Definition: simpleassemblers.hh:140
bool boundToAffordanceCollection() const
Returns true if the assembler is bound to an affordance collection.
Definition: simpleassemblers.hh:187
FEC FEContainer
Type of the finite element container.
Definition: simpleassemblers.hh:43
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
FERequirement & requirement()
Returns the requirement.
Definition: simpleassemblers.hh:205
bool boundToRequirement() const
Returns true if the assembler is bound to a finite element requirement.
Definition: simpleassemblers.hh:177
bool boundToDBCOption() const
Returns true if the assembler is bound to an affordance collection.
Definition: simpleassemblers.hh:197
DBCOption dBCOption() const
Returns the dirichlet boundary condition enforcement option.
Definition: simpleassemblers.hh:227
bool isConstrained(size_t i) const
Returns true if a given degree of freedom is fixed by a Dirichlet boundary condition.
Definition: simpleassemblers.hh:108
size_t reducedSize()
Returns the size of the free degrees of freedom, which are not fixed by a Dirichlet boundary conditio...
Definition: simpleassemblers.hh:71
typename FEContainerRaw::value_type::GlobalIndex GlobalIndex
Type of the global index.
Definition: simpleassemblers.hh:40
size_t constraintsBelow(size_t i) const
Returns the number of constraints below a given degrees of freedom index.
Definition: simpleassemblers.hh:100
auto & finiteElements() const
Returns the container of finite elements.
Definition: simpleassemblers.hh:92
DV DirichletValuesType
Type of the Dirichlet values.
Definition: simpleassemblers.hh:46
typename Basis::GridView GridView
Type of the grid view.
Definition: simpleassemblers.hh:42
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:45
bool bound() const
Returns true if the assembler is bound to a finite element requirement and affordance.
Definition: simpleassemblers.hh:164
size_t estimateOfConnectivity() const
Coarse estimate of node connectivity, i.e., this relates to the bandwidth of a sparse matrix....
Definition: simpleassemblers.hh:116
AffordanceCollectionType affordanceCollection() const
Returns the affordance.
Definition: simpleassemblers.hh:216
size_t size()
Returns the size of nodes, i.e., the number of degrees of freedom.
Definition: simpleassemblers.hh:77
typename DV::Basis Basis
Type of the basis.
Definition: simpleassemblers.hh:41
ScalarAssembler assembles scalar quantities.
Definition: simpleassemblers.hh:258
const double & scalar(const FERequirement &feRequirements, ScalarAffordance affordance)
Calculates the scalar quantity requested by feRequirements and affordance.
Definition: simpleassemblers.hh:285
const double & scalar()
Calculates the scalar quantity requested by the bound feRequirements and returns a reference.
Definition: simpleassemblers.hh:294
typename FEContainerRaw::value_type::Requirement FERequirement
Type of the finite element requirement.
Definition: simpleassemblers.hh:39
FEC FEContainer
Type of the finite element container.
Definition: simpleassemblers.hh:43
typename FEContainerRaw::value_type::GlobalIndex GlobalIndex
Type of the global index.
Definition: simpleassemblers.hh:40
DV DirichletValuesType
Type of the Dirichlet values.
Definition: simpleassemblers.hh:46
ScalarAssembler(FEContainer &&fes, const DirichletValuesType &dirichletValues)
Constructor for ScalarAssembler.
Definition: simpleassemblers.hh:275
typename DV::Basis Basis
Type of the basis.
Definition: simpleassemblers.hh:41
VectorFlatAssembler assembles vector quantities using a flat basis Indexing strategy.
Definition: simpleassemblers.hh:328
const Eigen::VectorXd & vector()
Calculates the vectorial quantity requested by the bound feRequirements, the affordance and the dBCOp...
Definition: simpleassemblers.hh:396
typename FEContainerRaw::value_type::Requirement FERequirement
Type of the finite element requirement.
Definition: simpleassemblers.hh:39
FEC FEContainer
Type of the finite element container.
Definition: simpleassemblers.hh:43
const Eigen::VectorXd & vector(const FERequirement &feRequirements, VectorAffordance affordance, DBCOption dbcOption=DBCOption::Full)
Calculates the vectorial quantity requested by the feRequirements and the affordance....
Definition: simpleassemblers.hh:362
typename FEContainerRaw::value_type::GlobalIndex GlobalIndex
Type of the global index.
Definition: simpleassemblers.hh:40
DV DirichletValuesType
Type of the Dirichlet values.
Definition: simpleassemblers.hh:46
const Eigen::VectorXd & vector(DBCOption dbcOption)
Calculates the vectorial quantity requested by the bound feRequirements and the affordance....
Definition: simpleassemblers.hh:384
VectorFlatAssembler(FEContainer &&fes, const DirichletValuesType &dirichletValues)
Constructor for VectorFlatAssembler.
Definition: simpleassemblers.hh:346
typename DV::Basis Basis
Type of the basis.
Definition: simpleassemblers.hh:41
SparseFlatAssembler assembles matrix quantities using a flat basis Indexing strategy....
Definition: simpleassemblers.hh:426
typename FEContainerRaw::value_type::Requirement FERequirement
Type of the finite element requirement.
Definition: simpleassemblers.hh:39
const Eigen::SparseMatrix< double > & matrix(const FERequirement &feRequirements, MatrixAffordance affordance, DBCOption dbcOption=DBCOption::Full)
Calculates the matrix quantity requested by feRequirements and the affordance. For DBCOption::Full a ...
Definition: simpleassemblers.hh:459
const Eigen::SparseMatrix< double > & matrix(DBCOption dbcOption)
Calculates the matrix quantity requested by the bound feRequirements and the affordance.
Definition: simpleassemblers.hh:479
const Eigen::SparseMatrix< double > & matrix()
Calculates the matrix quantity requested by the bound feRequirements, the affordance and the dBCOptio...
Definition: simpleassemblers.hh:491
SparseFlatAssembler(FEContainer &&fes, const DirichletValuesType &dirichletValues)
Constructor for SparseFlatAssembler.
Definition: simpleassemblers.hh:443
DenseFlatAssembler assembles matrix quantities using a flat basis Indexing strategy....
Definition: simpleassemblers.hh:553
typename FEContainerRaw::value_type::Requirement FERequirement
Type of the finite element requirement.
Definition: simpleassemblers.hh:39
const Eigen::MatrixXd & matrix(DBCOption dbcOption)
Calculates the matrix quantity requested by the bound feRequirements and the affordance....
Definition: simpleassemblers.hh:606
const Eigen::MatrixXd & matrix(const FERequirement &feRequirements, MatrixAffordance affordance, DBCOption dbcOption=DBCOption::Full)
Calculates the matrix quantity requested by feRequirements and the affordance. For DBCOption::Full a ...
Definition: simpleassemblers.hh:585
const Eigen::MatrixXd & matrix()
Definition: simpleassemblers.hh:616
DenseFlatAssembler(FEContainer &&fes, const DirichletValuesType &dirichletValues)
< Type of the global index.
Definition: simpleassemblers.hh:570
Struct representing a collection of affordances.
Definition: ferequirements.hh:105
Definition of DirichletValues class for handling Dirichlet boundary conditions.