Skip to content
Snippets Groups Projects
Commit bd66a3a3 authored by Timo Koch's avatar Timo Koch
Browse files

new slides

parent 28203b71
No related branches found
No related tags found
1 merge request!270[properties][slides] Renew properties slides
Pipeline #47220 passed
......@@ -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
}
};
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment