From bd66a3a32397034e9e1e8f51ad6c892299ac0ed7 Mon Sep 17 00:00:00 2001 From: Timo Koch <timokoch@uio.no> Date: Thu, 18 Jul 2024 08:58:25 +0200 Subject: [PATCH] new slides --- slides/properties.md | 137 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 112 insertions(+), 25 deletions(-) diff --git a/slides/properties.md b/slides/properties.md index d49b4246..fb8ab2a9 100644 --- a/slides/properties.md +++ b/slides/properties.md @@ -3,22 +3,40 @@ title: The DuMuX property system subtitle: Flexible compile-time customization --- -# System Design +# Property System Design ## Goals -- Easy to change parts of the simulation - - Add a energy equation +- Change parts of the simulation + - e.g. add a energy equation - Reuse specializations efficiently - - Test various discretization schemes for same application -- Group properties of the simulations + - e.g. test various discretization schemes for same application +- Group properties of the simulation - Improves readability +- Efficiency (runtime and implementation time) + +## Customization points + +- Simulations have many possible customization points! + - fluid system, constitutive relations + - the type of the grid (incl. dimension) + - the terms in the equation + - discretization scheme + - details of the discretization scheme + - ... + +## Challenges + +- Simulations have many possible customization points + - This means many properties +- Composing and reusing properties while keeping flexibility is technically challenging # A C++ solution ## Template parameters - C++ supports _generic programming_ via __templates__ - - e.g. classes defined in terms of other types - - concrete versions of templates are stamped out upon compilation + - e.g. classes parameterized in terms of other types + - concrete versions of templates are defined by specifying concrete types + - the actual type has to be known at compilation time - __Flexible__: implementation not restricted to _concrete types_ - __Efficient__: decisions made at compile-time @@ -32,20 +50,12 @@ An example - `std::vector` template<typename T, typename A = std::allocator<T>> class vector; - // Instantiation of a concrete vector - a vector of ints. // The compiler will define this concrete type for us, // using the definition of the class template. std::vector<int> v; ``` -## Template parameters - -An example - `std::vector` - -<img src="./img/template_example.png" width="800"/> - - ## Template specializations Template implementations can be specialized for concrete types @@ -64,7 +74,23 @@ class MyVector<int> }; ``` -## Too many template parameters +## Templates in algorithms + +Using class templates, we can write _generic_ algorithms + +```cpp + +template<typename T> +double two_norm(const MyVector<T>& v) +{ + double norm = 0.0; + for (int i = 0; i < v.size(); ++i) + norm += v[i]*v[i]; + return std::sqrt(norm); +} +``` + +## Challenge: Too many parameters For some classes, providing all template parameters can be very cumbersome and error-prone. @@ -78,7 +104,7 @@ using GOF0 = Dune::GridOperator< ``` -## Traits classes +## Technique 1: Traits classes A usual way to group template parameters @@ -97,7 +123,7 @@ struct TwoPVolumeVariablesTraits }; ``` -## Type traits +## Technique 2: Type traits Why do we need the type? @@ -114,7 +140,7 @@ template<typename T, int size> struct ValueType<Dune::FieldVector<T, size>> { using type = T; }; ``` -## Type traits +## Technique 2: Type traits ```cpp @@ -125,7 +151,7 @@ class TwoPVolumeVariables ... using FluidSystem = typename Traits::FluidSystem ... - + ``` Usage: these VolumeVariables will work for various FluidSystems: @@ -134,7 +160,7 @@ Usage: these VolumeVariables will work for various FluidSystems: Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); ``` -## Inheriting from traits classes +## Challenge: Inheritance Inheritance may lead to unexpected results @@ -153,8 +179,8 @@ struct MyDoubleTraits : public MyBaseTraits // this is a vector of ints! typename MyDoubleTraits::Vector v{1.14142, 1.73205}; ``` -# The DuMuX Property System +# The DuMuX Property System ## Property System Design - Based on __C++ template specialization__ (_type traits_) @@ -190,7 +216,7 @@ A simplified example to illustrate the idea ```cpp template<class TypeTag> -class GenericClass +class GenericClass // e.g. LocalResidual { using PropA = typename Properties::PropTagA<TypeTag>::type; using PropB = typename Properties::PropTagB<TypeTag>::type; @@ -232,8 +258,8 @@ struct Scalar<TypeTag, TTag::BaseTag> { using type = int; }; // specialization of the Vector property for BaseTag template<class TypeTag> struct Vector<TypeTag, TTag::BaseTag> { - private: using Scalar = GetPropType<TypeTag, Properties::Scalar>; - public: using type = std::vector<Scalar>; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using type = std::vector<Scalar>; }; ``` @@ -409,3 +435,64 @@ class Problem * e.g. <span style="color:blue">TwoP, TwoPTwoC, TwoPNI</span> - By deriving your __type tag__ from those, your problem inherits all type information needed to set up the model at compile time! - Example: see Exercise + +# Alternatives to properties +## Should I create new properties + +- Not necessary for most problems +- Only when designing a complex class of models (e.g. porous medium flow models) +- When there is many customization points + +## Alternative 1: + +- Use a simple template argument + +```cpp +template <bool useNeummanBoundaryConditions> +class Problem +{ + ... + if constexpr (useNeummanBoundaryConditions) + ... + else + ... +}; +``` + +## Alternative 2: + +C++ type traits + +```cpp +template<class CouplingManager> +struct SupportsMultithreadedAssembly +: public std::false_type {} +``` + +## Alternative 2: + +C++ type traits + +```cpp +class MyCouplingManager { ... }; + +template<> +struct SupportsMultithreadedAssembly<MyCouplingManager> +: public std::true_type {} +``` + +## Alternative 2: + +Generic algorithm + +```cpp +template<class CouplingManager> +class Assembler { + void assemble() { + if (SupportsMultithreadedAssembly<CouplingManager>::value) + // assembly multi-threaded + else + // assembly single-threaded + } +}; +``` -- GitLab