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