version 0.4.1
utils/concepts.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2025 The Ikarus Developers mueller@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
9#pragma once
10
11#include <concepts>
12#include <type_traits>
13#include <utility>
14#include <vector>
15
16#include <dune/functions/functionspacebases/basistags.hh>
17#include <dune/functions/functionspacebases/lagrangebasis.hh>
18
19#include <Eigen/Dense>
20#include <Eigen/Sparse>
21
22#include <autodiff/forward/dual/dual.hpp>
23
27
28namespace Eigen {
29template <typename Derived>
30struct EigenBase;
31}
32
33namespace Ikarus {
34
35template <typename Derived>
37namespace Concepts {
38
47 template <typename Basis>
48 concept FlatInterLeavedBasis = requires {
49 std::is_same_v<typename Basis::PreBasis::IndexMergingStrategy, Dune::Functions::BasisFactory::FlatInterleaved>;
50 };
51
52 namespace Impl {
53 template <template <typename, int, typename> class U, typename T>
54 struct LagrangeNodeHelper : std::false_type
55 {
56 };
57 template <template <typename, int, typename> class U, typename GV, int k, typename R>
58 struct LagrangeNodeHelper<U, U<GV, k, R>> : std::true_type
59 {
60 };
61
62 template <template <typename, int, typename> class U, typename T, int k>
63 struct LagrangeNodeHelperOfOrder : std::false_type
64 {
65 };
66 template <template <typename, int, typename> class U, typename GV, int k, typename R>
67 struct LagrangeNodeHelperOfOrder<U, U<GV, k, R>, k> : std::true_type
68 {
69 };
70 } // namespace Impl
71
79 template <typename N>
80 concept LagrangeNode = Impl::LagrangeNodeHelper<Dune::Functions::LagrangeNode, N>::value;
81
89 template <typename N, int order>
90 concept LagrangeNodeOfOrder = Impl::LagrangeNodeHelperOfOrder<Dune::Functions::LagrangeNode, N, order>::value;
91
100 template <typename B>
101 concept FlatLexicographicBasis = requires {
102 std::is_same_v<typename B::PreBasis::IndexMergingStrategy, Dune::Functions::BasisFactory::FlatLexicographic>;
103 };
104
113 template <typename B>
115
124 template <typename Basis>
125 concept BlockedInterLeavedBasis = requires {
126 std::is_same_v<typename Basis::PreBasis::IndexMergingStrategy, Dune::Functions::BasisFactory::BlockedInterleaved>;
127 };
128
137 template <typename B>
138 concept BlockedLexicographicBasis = requires {
139 std::is_same_v<typename B::PreBasis::IndexMergingStrategy, Dune::Functions::BasisFactory::BlockedLexicographic>;
140 };
141
147 template <typename DLB>
148 concept DuneLocalBasis = requires(DLB& duneLocalBasis) {
149 typename DLB::Traits::RangeType;
150 typename DLB::Traits::JacobianType;
151 DLB::Traits::dimDomain;
152 typename DLB::Traits::DomainType;
153
154 typename DLB::Traits::DomainFieldType;
155 typename DLB::Traits::RangeFieldType;
156
157 duneLocalBasis.evaluateFunction(std::declval<typename DLB::Traits::DomainType>(),
158 std::declval<std::vector<typename DLB::Traits::RangeType>&>());
159 duneLocalBasis.evaluateJacobian(std::declval<typename DLB::Traits::DomainType>(),
160 std::declval<std::vector<typename DLB::Traits::JacobianType>&>());
161 };
162
172 template <typename B>
174
182 template <typename PF, typename NLO, typename SA>
183 concept PathFollowingStrategy = requires(PF pft, NLO nop, SA args) {
184 { pft(args) } -> std::same_as<void>;
185 { pft.initialPrediction(nop, args) } -> std::same_as<void>;
186 { pft.intermediatePrediction(nop, args) } -> std::same_as<void>;
187 };
188
197 template <typename ASS, typename NLSI, typename SA, typename NonLinearOperator>
198 concept AdaptiveStepSizingStrategy = requires(ASS adaptiveStepSizing, NLSI info, SA args, NonLinearOperator nop) {
199 { adaptiveStepSizing(info, args, nop) } -> std::same_as<void>;
200 { adaptiveStepSizing.targetIterations() } -> std::same_as<int>;
201 { adaptiveStepSizing.setTargetIterations(std::declval<int>()) } -> std::same_as<void>;
202 };
203
212 template <typename LS, typename M, typename V>
213 concept LinearSolverCheck = requires(LS& linearSolver, M& A, V& vec) {
214 linearSolver.analyzePattern(A);
215 linearSolver.factorize(A);
216 linearSolver.solve(vec, vec);
217 };
218
226 template <typename NLS>
228 std::tuple_size<typename NLS::NonLinearOperator::ParameterValues>::value == 2;
229 not(std::is_same_v<typename NLS::NonLinearOperator::ValueType, double> and
230 ((traits::isSpecializationTypeAndNonTypes<Eigen::Matrix,
231 typename NLS::NonLinearOperator::DerivativeType>::value) or
232 (traits::isSpecializationTypeNonTypeAndType<Eigen::SparseMatrix,
233 typename NLS::NonLinearOperator::DerivativeType>::value)));
234 };
235
243 template <typename L, typename R>
244 concept MultiplyAble = requires(L x, R y) { x* y; };
245
253 template <typename L, typename R>
254 concept AddAble = requires(L x, R y) { x + y; };
255
263 template <typename L, typename R>
264 concept SubstractAble = requires(L x, R y) { x - y; };
265
274 template <typename L, typename R>
275 concept MultiplyAssignAble = requires(L x, R y) { x *= y; };
276
285 template <typename L, typename R>
286 concept DivideAssignAble = requires(L x, R y) { x /= y; };
287
296 template <typename L, typename R>
297 concept AddAssignAble = requires(L x, R y) { x += y; };
298
307 template <typename L, typename R>
308 concept SubstractAssignAble = requires(L x, R y) { x -= y; };
309
317 template <typename L, typename R>
318 concept DivideAble = requires(L x, R y) { x / y; };
319
326 template <typename L>
327 concept NegateAble = requires(L x) { -x; };
328
335 template <typename L>
336 concept TransposeAble = requires(L x) { transpose(x); };
337
344 template <typename Op, typename... Args>
345 concept IsFunctorWithArgs = requires(Op op, Args... args) { op(args...); };
346
352 template <typename V>
353 concept EigenVector = static_cast<bool>(V::IsVectorAtCompileTime);
354
360 template <typename M>
361 concept EigenMatrix = traits::isSpecializationTypeAndNonTypes<Eigen::Matrix, M>::value;
362
363#define MAKE_EIGEN_FIXED_VECTOR_CONCEPT(Size) \
364 template <typename V> \
365 concept EigenVector##Size = \
366 static_cast<bool>(V::IsVectorAtCompileTime) and static_cast<bool>(V::SizeAtCompileTime == Size);
367
374
375#define MAKE_EIGEN_FIXED_MATRIX_CONCEPT(Size1, Size2) \
376 template <typename M> \
377 concept EigenMatrix##Size1##Size2 = static_cast<bool>(std::remove_cvref_t<M>::RowsAtCompileTime == Size1) and \
378 static_cast<bool>(std::remove_cvref_t<M>::ColsAtCompileTime == Size2);
379
381
384
389
396
405
416
417#define MAKE_EIGEN_FIXED_MATRIX_OR_VOIGT_CONCEPT(Size1, Size2) \
418 template <typename M> \
419 concept EigenMatrixOrVoigtNotation##Size1 = EigenMatrix##Size1##Size1<M> or EigenVector##Size2<M>;
420
424
425 namespace Impl {
426 template <template <typename...> class MaterialToCheck, typename Material>
427 consteval bool isMaterial() {
428 if constexpr (traits::isSpecialization<MaterialToCheck, Material>::value)
429 return true;
430
431 if constexpr (Material::isReduced) {
432 if constexpr (traits::isSpecialization<MaterialToCheck, typename Material::Underlying>::value) {
433 return true;
434 } else {
435 return false;
436 }
437 } else
438 return false;
439 }
440 } // namespace Impl
441
454 template <template <typename...> class MaterialToCheck, typename Material>
455 concept IsMaterial = Impl::isMaterial<MaterialToCheck, Material>();
456
457 namespace Impl {
458 template <typename T>
459 concept ResultType = requires(T t) {
460 typename T::type; // The nested type 'type'
461 typename T::Vectorizer; // The nested type 'Vectorizer'
462 typename T::Matricizer; // The nested type 'Matricizer'
463 { toString(t) } -> std::same_as<std::string>; // The toString function
464 };
465 } // namespace Impl
466
473 template <typename MAT>
475
485 template <template <typename, int, int> typename RT>
486 concept ResultType =
487 Impl::ResultType<RT<double, 1, 1>> or Impl::ResultType<RT<double, 1, 2>> or Impl::ResultType<RT<double, 1, 3>> or
488 Impl::ResultType<RT<double, 2, 3>> or Impl::ResultType<RT<double, 3, 3>>;
489
497 template <typename T>
498 concept FlatAssembler = requires(T t, const typename T::FERequirement& req,
499 typename T::AffordanceCollectionType affordance, DBCOption dbcOption) {
500 { t.requirement() } -> std::convertible_to<typename T::FERequirement&>;
501 { t.affordanceCollection() } -> std::convertible_to<typename T::AffordanceCollectionType>;
502 { t.dBCOption() } -> std::convertible_to<DBCOption>;
503
504 { t.bind(req, affordance, dbcOption) } -> std::same_as<void>;
505 { t.bind(req) } -> std::same_as<void>;
506 { t.bind(affordance) } -> std::same_as<void>;
507 { t.bind(dbcOption) } -> std::same_as<void>;
508
509 { t.bound() } -> std::convertible_to<bool>;
510 { t.boundToRequirement() } -> std::convertible_to<bool>;
511 { t.boundToAffordanceCollection() } -> std::convertible_to<bool>;
512 { t.boundToDBCOption() } -> std::convertible_to<bool>;
513 { t.estimateOfConnectivity() } -> std::convertible_to<size_t>;
514
515 { t.createFullVector(std::declval<Eigen::Ref<const Eigen::VectorXd>>()) } -> std::convertible_to<Eigen::VectorXd>;
516 { t.constraintsBelow(std::declval<size_t>()) } -> std::convertible_to<size_t>;
517 { t.isConstrained(std::declval<size_t>()) } -> std::convertible_to<bool>;
518 { t.size() } -> std::convertible_to<size_t>;
519 { t.reducedSize() } -> std::convertible_to<size_t>;
520 };
521
528 template <typename T>
530 Concepts::FlatAssembler<T> and requires(T t, const typename T::FERequirement& req,
531 typename T::AffordanceCollectionType affordance, DBCOption dbcOption) {
532 { t.scalar(req, affordance.scalarAffordance()) } -> std::convertible_to<const double&>;
533 { t.scalar() } -> std::convertible_to<const double&>;
534 };
535
542 template <typename T>
544 requires(T t, const typename T::FERequirement& req,
545 typename T::AffordanceCollectionType affordance, DBCOption dbcOption) {
546 {
547 t.vector(req, affordance.vectorAffordance(), dbcOption)
548 } -> std::convertible_to<const Eigen::VectorXd&>;
549 { t.vector(dbcOption) } -> std::convertible_to<const Eigen::VectorXd&>;
550 { t.vector() } -> std::convertible_to<const Eigen::VectorXd&>;
551 };
552
559 template <typename T>
561 requires(T t, const typename T::FERequirement& req,
562 typename T::AffordanceCollectionType affordance, DBCOption dbcOption) {
563 { t.matrix(req, affordance.matrixAffordance(), dbcOption) };
564 { t.matrix(dbcOption) };
565 { t.matrix() };
566 };
567
568 // adapted from /dune/dune-vtk/dune/vtk/utility/concepts.hh
569 template <class DC>
570 concept DataCollector = requires(DC dc) {
571 typename DC::GridView;
572 { dc.update() } -> std::same_as<void>;
573 { dc.numPoints() } -> std::convertible_to<std::uint64_t>;
574 { dc.numCells() } -> std::convertible_to<std::uint64_t>;
575 { dc.gridView() } -> std::same_as<const typename DC::GridView&>;
576 };
577
578 template <class GV>
579 concept GridView = requires(GV g) {
580 typename GV::Grid;
581 GV::dimension;
582 GV::dimensionworld;
583
584 { g.grid() };
585 };
586
587 namespace Impl {
588 template <typename T>
589 struct is_dual : std::false_type
590 {
591 };
592
593 // Specialization for Dual<T, U>: this will be true for Dual types
594 template <typename T, typename U>
595 struct is_dual<autodiff::detail::Dual<T, U>> : std::true_type
596 {
597 };
598 } // namespace Impl
599
605 template <typename T>
606 concept AutodiffScalar = Impl::is_dual<T>::value;
607
608} // namespace Concepts
609} // namespace Ikarus
Contains stl-like type traits.
Definition of several material related enums.
Definition: assemblermanipulatorbuildingblocks.hh:22
DBCOption
Definition: dirichletbcenforcement.hh:7
NonLinearOperator(const Impl::Functions< DerivativeArgs &&... > &a, const Impl::Parameter< ParameterArgs... > &b) -> NonLinearOperator< Impl::Functions< DerivativeArgs... >, Impl::Parameter< ParameterArgs... > >
auto transpose(const Eigen::EigenBase< Derived > &A)
constexpr std::string toString(DBCOption _e)
Definition: dirichletbcenforcement.hh:7
Definition: truncatedconjugategradient.hh:24
Definition: utils/concepts.hh:30
Concept to check if a basis uses FlatInterleaved indexing strategy.
Definition: utils/concepts.hh:48
Concept to check if a node in a basis tree is a Lagrangian node.
Definition: utils/concepts.hh:80
Definition: utils/concepts.hh:90
Concept to check if a basis uses FlatLexicographic indexing strategy.
Definition: utils/concepts.hh:101
Concept to check if a basis uses FlatIndex indexing strategy.
Definition: utils/concepts.hh:114
Concept to check if a basis uses BlockedInterleaved indexing strategy.
Definition: utils/concepts.hh:125
Concept to check if a basis uses BlockedLexicographic indexing strategy.
Definition: utils/concepts.hh:138
Concept to check if a local basis is a duneLocalBasis.
Definition: utils/concepts.hh:148
Concept to check if a basis uses either BlockedLexicographic or BlockedInterleaved indexing strategy.
Definition: utils/concepts.hh:173
Concept defining the requirements for a path-following strategy.
Definition: utils/concepts.hh:183
Concept to check if a type implements all the needed functions to be an adaptive step sizing method.
Definition: utils/concepts.hh:198
Concept to check if a linear solver implements all the needed functions for given vector and matrix t...
Definition: utils/concepts.hh:213
Concept to check if a non-linear solver with its non-linear operator satisfies requirements for path ...
Definition: utils/concepts.hh:227
Concept defining the requirements for types that support multiplication.
Definition: utils/concepts.hh:244
Concept defining the requirements for types that support addition.
Definition: utils/concepts.hh:254
Concept defining the requirements for types that support subtraction.
Definition: utils/concepts.hh:264
Concept defining the requirements for types that support in-place multiplication.
Definition: utils/concepts.hh:275
Concept defining the requirements for types that support in-place division.
Definition: utils/concepts.hh:286
Concept defining the requirements for types that support in-place addition.
Definition: utils/concepts.hh:297
Concept defining the requirements for types that support in-place subtraction.
Definition: utils/concepts.hh:308
Concept defining the requirements for types that support division.
Definition: utils/concepts.hh:318
Concept defining the requirements for types that support negation.
Definition: utils/concepts.hh:327
Concept defining the requirements for types that support transposition.
Definition: utils/concepts.hh:336
Concept defining the requirements for functors with arguments.
Definition: utils/concepts.hh:345
Concept defining the requirements for Eigen vectors.
Definition: utils/concepts.hh:353
Concept defining the requirements for Eigen matrices. This also includes Eigen vectors.
Definition: utils/concepts.hh:361
Concept defining the requirements for a material type.
Definition: utils/concepts.hh:455
Concepts defining the requirements for a material to be geometrically linear This is the case when th...
Definition: utils/concepts.hh:474
A concept to check if a template type satisfies the ResultType requirements.
Definition: utils/concepts.hh:486
Concept representing the requirements for a FlatAssembler.A type T satisfies FlatAssembler if it prov...
Definition: utils/concepts.hh:498
Concept representing the requirements for a ScalarFlatAssembler.A type T satisfies ScalarFlatAssemble...
Definition: utils/concepts.hh:529
Concept representing the requirements for a VectorFlatAssembler.A type T satisfies VectorFlatAssemble...
Definition: utils/concepts.hh:543
Concept representing the requirements for a MatrixFlatAssembler.A type T satisfies MatrixFlatAssemble...
Definition: utils/concepts.hh:560
Definition: utils/concepts.hh:570
Definition: utils/concepts.hh:579
Concept to check if the underlying scalar type is a dual type.
Definition: utils/concepts.hh:606
#define MAKE_EIGEN_FIXED_MATRIX_CONCEPT(Size1, Size2)
Definition: utils/concepts.hh:375
#define MAKE_EIGEN_FIXED_MATRIX_OR_VOIGT_CONCEPT(Size1, Size2)
Definition: utils/concepts.hh:417
#define MAKE_EIGEN_FIXED_VECTOR_CONCEPT(Size)
Definition: utils/concepts.hh:363