\section{Property System}
\label{sec:propertysystem}
A high level overview over the property system's design and principle ideas
are given, then follows a reference and a self-contained example.

\subsection{Motivation and features}
The \Dumux property system is a traits system
which allows easy inheritance.

In the context of the \Dumux property system, a property is an arbitrary
class body which may contain type definitions, values and methods.

Just like normal classes, properties can be arranged in hierarchies. In
the context of the \Dumux property system, nodes of the inheritance
hierarchy are called \emph{type tags}.

It also supports \emph{property nesting}. Property nesting means that the definition of
a property can depend on the value of other properties which may be
defined for arbitrary levels of the inheritance hierarchy.

\subsection{How-to}
All source files which use the property system should include
the header file \path{dumux/common/properties/propertysystem.hh}.
Declaration of type tags and
property tags as well as defining properties must be done inside the
namespace \texttt{Dumux::Properties}.

\subsubsection{Defining Type Tags}
New nodes in the type tag hierarchy can be defined in the \texttt{TTag} namespace using
\begin{lstlisting}[style=DumuxCode]
// Create new type tags
namespace TTag {
struct NewTypeTagName { using InheritsFrom = std::tuple<BaseTagName1, BaseTagName2, ...>; };
} // end namespace TTag
\end{lstlisting}
where the \texttt{InheritsFrom} alias is optional. To avoid
inconsistencies in the hierarchy, each type tag may be defined only
once for a program. If you call \texttt{GetProp} the property system will first look for the properties defined in \texttt{BaseTagName1} in the \texttt{InheritsFrom} list.
If a defined property is found this property is returned. If no defined property is found the search will continue in the ancestors of \texttt{BaseTagName1}.
If again no defined property is found the search will continue in the second \texttt{BaseTagName2} in the list, and so on.
If no defined property is found at all, a compiler error is triggered.

\vskip1ex\noindent
Example:
\begin{lstlisting}[style=DumuxCode]
namespace Dumux {
namespace Properties {
namespace TTag {
struct MyBaseTypeTag1 {};
struct MyBaseTypeTag2 {};

struct MyDerivedTypeTag { using InheritsFrom = std::tuple<MyBaseTypeTag1, MyBaseTypeTag2>; };
} // end namespace TTag
}}
\end{lstlisting}

\subsubsection{Defining new Property Tags}
New property tags are defined using

\begin{lstlisting}[style=DumuxCode]
template<class TypeTag, class MyTypeTag>
struct NewPropTagName { using type = UndefinedProperty; };
\end{lstlisting}

\vskip1ex\noindent
Example:
\begin{lstlisting}[style=DumuxCode]
namespace Dumux {
namespace Properties {
template<class TypeTag, class MyTypeTag>
struct MyPropertyTag { using type = UndefinedProperty; };
}}
\end{lstlisting}

If you need to forward declare a property use

\begin{lstlisting}[style=DumuxCode]
// forward declaration
template<class TypeTag, class MyTypeTag>
struct NewPropTagName;
\end{lstlisting}

\subsubsection{Defining Properties}
The value of a property on a given node of the type tag hierarchy is
defined using
\begin{lstlisting}[style=DumuxCode]
template<class TypeTag>
struct PropertyTagName<TypeTag, TTag::TypeTagName>
{
  // arbitrary body of a struct
};
\end{lstlisting}

This means a property is defined for a specific type tag node \texttt{TTag::TypeTagName}
by providing a partial template specialization of \texttt{PropertyTagName}.
The body typically contains either the alias \texttt{type}, or a data member \texttt{value}.
However, you can of course write in the body whatever you like.

\begin{lstlisting}[style=DumuxCode]
template<class TypeTag>
struct PropertyTagName<TypeTag, TTag::TypeTagName> { using type = type; };

template<class TypeTag>
struct PropertyTagName<TypeTag, TTag::TypeTagName> { static constexpr bool value = booleanValue; };

template<class TypeTag>
struct PropertyTagName<TypeTag, TTag::TypeTagName> { static constexpr int value = integerValue; };
\end{lstlisting}

\vskip1ex\noindent
Example:
\begin{lstlisting}[style=DumuxCode]
namespace Dumux {
namespace Properties {

// Create new type tag
namespace TTag {
struct MyTypeTag {};
}

// Define some properties
template<class TypeTag, class MyTypeTag> struct MyCustomProperty { using type = UndefinedProperty; };
template<class TypeTag, class MyTypeTag> struct MyType { using type = UndefinedProperty; };
template<class TypeTag, class MyTypeTag> struct MyBoolValue { using type = UndefinedProperty; };
template<class TypeTag, class MyTypeTag> struct MyIntValue { using type = UndefinedProperty; };
template<class TypeTag, class MyTypeTag> struct MyScalarValue { using type = UndefinedProperty; };

// Set the properties for the new type tag
template<class TypeTag>
struct MyCustomProperty<TypeTag, TTag::MyTypeTag>
{
    static void print()
    { std::cout << "Hello, World!\n"; }
};

template<class TypeTag>
struct MyType<TypeTag, TTag::MyTypeTag> { using type = unsigned int; };

template<class TypeTag>
struct MyBoolValue<TypeTag, TTag::MyTypeTag> { static constexpr bool value = true; };

template<class TypeTag>
struct MyIntValue<TypeTag, TTag::MyTypeTag> { static constexpr int value = 12345; };

template<class TypeTag>
struct MyScalarValue<TypeTag, TTag::MyTypeTag> { static constexpr double value = 12345.67890; };
}}
\end{lstlisting}

\subsubsection{Retrieving Property Values}
The type of a property can be retrieved using
\begin{lstlisting}[style=DumuxCode]
using Prop = GetProp<TypeTag, Properties::PropertyTag>;
\end{lstlisting}

There is a helper struct and a helper function to retrieve the \texttt{type} and \texttt{value}
members of a property

\begin{lstlisting}[style=DumuxCode]
using PropType = GetPropType<TypeTag, Properties::PropertyTag>;
constexpr auto propValue = getPropValue<TypeTag, Properties::PropertyTag>();
\end{lstlisting}

\vskip1ex\noindent
Example:\nolinebreak
\begin{lstlisting}[style=DumuxCode]
template <TypeTag>
class MyClass {
    // retrieve the ::value attribute of the 'UseMoles' property
    static constexpr bool useMoles = getPropValue<TypeTag, Properties::UseMoles>();
    static constexpr bool useMoles2 = GetProp<TypeTag, Properties::UseMoles>::value; // equivalent

    // retrieve the ::type attribute of the 'Scalar' property
    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
    using Scalar2 = GetProp<TypeTag, Properties::Scalar>::type; // equivalent
};
\end{lstlisting}

\subsubsection{Nesting Property Definitions}
Inside property definitions there is access to all other properties
which are defined somewhere on the type tag hierarchy. The node for
which the current property is requested is available via the template argument
\texttt{TypeTag}. Inside property class bodies \texttt{GetPropType} can be used to
retrieve other properties and create aliases.

\vskip1ex\noindent
Example:
\begin{lstlisting}[style=DumuxCode]
template<class TypeTag>
struct Vector<TypeTag, TTag::MyModelTypeTag>
{
    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
    using type = std::vector<Scalar>;
};
\end{lstlisting}

\subsection{A Self-Contained Example}
As a concrete example, let us consider some kinds of cars: Compact
cars, sedans, trucks, pickups, military tanks and the Hummer-H1 sports
utility vehicle. Since all these cars share some characteristics, it
makes sense to inherit those from the closest matching car type and
only specify the properties which are different. Thus, an inheritance
diagram for the car types above might look like outlined in Figure
\ref{fig:car-hierarchy}.

\begin{figure}[t]
  \centering
  \subfloat[]{
    \begin{tikzpicture}
      [cars/.style={rectangle,draw=black,rounded corners,minimum width=2.5cm,node distance=0.5cm}]
      % place nodes
      \node[cars] (compact) {Compact car};
      \node[cars] (sedan) [below=of compact] {Sedan};
      \node[cars] (truck) [right=of compact] {Truck};
      \node[cars] (pickup) [below right= of sedan] {Pickup};
      \node[cars] (tank) [right=of truck] {Tank};
      \node[cars] (hummer) [below right= of pickup] {Hummer};
      % add edges
      \draw [-latex',thick] (compact) -- (sedan);
      \draw [-latex',thick] (sedan) -- (pickup);
      \draw [-latex',thick] (truck) -- (pickup);
      \draw [-latex',thick] (tank) -- (hummer);
      \draw [-latex',thick] (pickup) -- (hummer);
    \end{tikzpicture}
    \label{fig:car-hierarchy}
  }
  \hspace*{0.5cm}
  \subfloat[]{
    \begin{tikzpicture}
      [propertyBox/.style={rectangle,draw=black,minimum width=4.5cm,node distance=0.1cm}]
      \node[propertyBox] (gasUsage) {GasUsage};
      \node[propertyBox] (speed) [below=of gasUsage] {TopSpeed};
      \node[propertyBox] (seats) [below=of speed] {NumSeats};
      \node[propertyBox] (automatic) [below=of seats] {AutomaticTransmission};
      \node[propertyBox] (calibre) [below=of automatic] {CannonCalibre};
      \node[propertyBox] (payload) [below=of calibre] {Payload};
    \end{tikzpicture}
    \label{fig:car-propertynames}
  }
  \caption{\textbf{(a)}~A possible property inheritance graph for
    various kinds of cars.  The lower nodes inherit from higher ones;
    Inherited properties from nodes on the right take precedence over the
    properties defined on the left. \textbf{(b)}~Property names
    which make sense for at least one of the car types of (a).}
\end{figure}

Using the \Dumux property system, this inheritance hierarchy is
defined by:
\begin{lstlisting}[name=propsyscars,style=DumuxCode]
#include <dumux/common/propertysystem.hh>
#include <iostream>

namespace Dumux {
namespace Properties {
namespace TTag{
struct CompactCar {};
struct Truck {};
struct Tank {};

struct Sedan { using InheritsFrom = std::tuple<CompactCar>; };
struct Pickup { using InheritsFrom = std::tuple<Truck, Sedan>; };
struct HummerH1 { using InheritsFrom = std::tuple<Tank, Pickup>; };
}}} // end namespace TTag
\end{lstlisting}

Figure \ref{fig:car-propertynames} lists a few property names which
make sense for at least one of the nodes of Figure
\ref{fig:car-hierarchy}. These property names can be defined as
follows:
\begin{lstlisting}[name=propsyscars,style=DumuxCode]
template<class TypeTag, class MyTypeTag>
struct GasUsage { using type = UndefinedProperty; }; // [l/100km]
template<class TypeTag, class MyTypeTag>
struct TopSpeed { using type = UndefinedProperty; }; // [km/h]
template<class TypeTag, class MyTypeTag>
struct NumSeats { using type = UndefinedProperty; }; // []
template<class TypeTag, class MyTypeTag>
struct AutomaticTransmission { using type = UndefinedProperty; }; // true/false
template<class TypeTag, class MyTypeTag>
struct CanonCaliber { using type = UndefinedProperty; }; // [mm]
template<class TypeTag, class MyTypeTag>
struct Payload { using type = UndefinedProperty; }; // [t]
\end{lstlisting}

\noindent
So far, the inheritance hierarchy and the property names are completely
separate. What is missing is setting some values for the property
names on specific nodes of the inheritance hierarchy. Let us assume
the following:
\begin{itemize}
\item For a compact car, the top speed is the gas usage in $\unitfrac{l}{100km}$
  times $30$, the number of seats is $5$ and the gas usage is
  $\unitfrac[4]{l}{100km}$.
\item A truck is by law limited to $\unitfrac[100]{km}{h}$ top speed, the number
  of seats is $2$, it uses $\unitfrac[18]{l}{100km}$ and has a cargo payload of
  $\unit[35]{t}$.
\item A tank exhibits a top speed of $\unitfrac[60]{km}{h}$, uses $\unitfrac[65]{l}{100km}$
  and features a $\unit[120]{mm}$ diameter canon
\item A sedan has a gas usage of $\unitfrac[7]{l}{100km}$, as well as an automatic
  transmission, in every other aspect it is like a compact car.
\item A pick-up truck has a top speed of $\unitfrac[120]{km}{h}$ and a payload of
  $\unit[5]{t}$. In every other aspect it is like a sedan or a truck but if in
  doubt, it is more like a truck.
\item The Hummer-H1 SUV exhibits the same top speed as a pick-up
  truck.  In all other aspects it is similar to a pickup and a tank,
  but, if in doubt, more like a tank.
\end{itemize}

\noindent
Using the \Dumux property system, these assumptions are formulated
using
\begin{lstlisting}[name=propsyscars,style=DumuxCode]
template<class TypeTag>
struct TopSpeed<TypeTag, TTag::CompactCar>
{static constexpr int value = getPropValue<TypeTag, Properties::GasUsage>() * 30};

template<class TypeTag>
struct NumSeats<TypeTag, TTag::CompactCar> { static constexpr int value = 5; };

template<class TypeTag>
struct GasUsage<TypeTag, TTag::CompactCar> { static constexpr int value = 4; };

template<class TypeTag>
struct TopSpeed<TypeTag, TTag::Truck> { static constexpr int value = 100; };

template<class TypeTag>
struct NumSeats<TypeTag, TTag::Truck> { static constexpr int value = 2; };

template<class TypeTag>
struct GasUsage<TypeTag, TTag::Truck> { static constexpr int value = 18; };

template<class TypeTag>
struct Payload<TypeTag, TTag::Truck> { static constexpr int value = 35; };

template<class TypeTag>
struct TopSpeed<TypeTag, TTag::Tank> { static constexpr int value = 60; };

template<class TypeTag>
struct GasUsage<TypeTag, TTag::Tank> { static constexpr int value = 65; };

template<class TypeTag>
struct CanonCaliber<TypeTag, TTag::Tank> { static constexpr int value = 120; };

template<class TypeTag>
struct GasUsage<TypeTag, TTag::Sedan> { static constexpr int value = 7; };

template<class TypeTag>
struct AutomaticTransmission<TypeTag, TTag::Sedan> { static constexpr bool value = true; };

template<class TypeTag>
struct TopSpeed<TypeTag, TTag::Pickup> { static constexpr int value = 120; };

template<class TypeTag>
struct Payload<TypeTag, TTag::Pickup> { static constexpr int value = 5; };

template<class TypeTag>
struct TopSpeed<TypeTag, TTag::HummerH1>
{ static constexpr int value = getPropValue<TypeTag, TTag::Pickup::TopSpeed<TypeTag>>(); };
\end{lstlisting}

\noindent
Now property values can be retrieved and some diagnostic messages can
be generated. For example
\begin{lstlisting}[name=propsyscars,style=DumuxCode]
int main()
{
    std::cout << "top speed of sedan: " << getPropValue<Properties::TTag::Sedan, Properties::TopSpeed>() << "\n";
    std::cout << "top speed of truck: " << getPropValue<Properties::TTag::Truck, Properties::TopSpeed>() << "\n";
}
\end{lstlisting}
will yield the following output:
\begin{lstlisting}[style=Bash, basicstyle=\ttfamily\scriptsize\let\textcolor\textcolordummy]
$ top speed of sedan: 210
$ top speed of truck: 100
\end{lstlisting}
