\chapter{The \Dumux Property System} \label{sec:propertysytem} This chapter tries to give high-level understanding of the motivation for the \Dumux property system and how to use it. First, an introduction to polymorphism is given. After this, the fundamental motivation and the ideas behind the \Dumux property system are highlighted and the implementation is outlined from a high-level perspective. The chapter concludes with a simple example of how to use the \Dumux property system. \section{Polymorphism} In object oriented programming, it often happens that some functionality make sense for all classes in a hierarchy, but what actually need to be \textit{done} can be quite different. This observation gives rise to \textit{polymorphism}. In polymorphism, a call to an object's method \textit{means} the same thing, but how this method is \textit{implemented} is case specific\footnote{This \textit{poly} of polymorphism: There are multiple ways to achieve the same goal.}. In C++, there are two common approaches to polymorphism: The traditional -- i.e. non-template programming -- dynamic polymorphism, and static polymorphism which is made possible by template programming. \subsection*{Dynamic Polymorphism} To utilize \textit{dynamic polymorphism} in C++, the polymorphic methods are marked with the \texttt{virtual} keyword in the base class. Internally, the compiler realizes dynamic polymorphism by storing a pointer to a so-called \texttt{vtable} within each object of polymorphic classes. The \texttt{vtable} itself stores the entry point of each method which is declared virtual. If such a method is called on an object, the compiler generates code which retrieves the method's address from the object's \texttt{vtable} and then calls it. This explains why this mechanism is called \textbf{dynamic} polymorphism: the methods which are actually called are dynamically determined at run time. \begin{example} A class called \texttt{Car} could feature the methods \texttt{gasUsage} which by default corrosponds to the current $CO_2$ emission goal of the European Union but can be overwritten by the classes representing actual cars. Also, a method called \texttt{fuelTankSize} makes sense for all cars, but since there is no useful default, its \texttt{vtable} entry is set to $0$ in the base class which tells the compiler that this method must mandatorily be specified by all derived classes. Finally the method \texttt{range} may calculate the expected remaining kilometers the car can drive given a fill level of the fuel tank. Since the \texttt{range} method can retrieve information it needs, it does not need to be polymorphic. \begin{verbatim} // the base class class Car {public: virtual double gasUsage() { return 4.5; }; virtual double fuelTankSize() = 0; double range(double fuelTankFillLevel) { return 100*fuelTankFillLevel*fuelTankSize()/gasUsage(); } } \end{verbatim} Actual car models can now derived from the base class: \begin{verbatim} // a Mercedes S-class car class S : public Car {public: virtual double gasUsage() { return 9.0; }; virtual double fuelTankSize() { return 65.0; }; } // A VW Lupo class Lupo : public Car {public: virtual double gasUsage() { return 2.99; }; virtual double fuelTankSize() { return 30.0; }; } \end{verbatim} The \text{range} method called on the base class yields correct result for any car type: \begin{verbatim} void printMaxRange(Car &car) { std::cout << "Maximum Range: " << car.range(1.00) << "\n"; } int main() { Lupo lupo; S s; std::cout << "VW Lupo:" std::cout << "Median range: " << lupo.range(0.50) << "\n"; printMaxRange(lupo); std::cout << "Mercedes S-Class:" std::cout << "Median range: " << s.range(0.50) << "\n"; printMaxRange(s); return 0; } \end{verbatim} For both types of cars, \texttt{Lupo} and \texttt{S} the \texttt{printMaxRange} function works as expected, yielding $1003.3\;\mathrm{km}$ for the Lupo and $722.2\;\mathrm{km}$ for the S-Class. \end{example} \begin{exc} What happens if \dots \begin{itemize} \item \dots the \texttt{gasUsage} method is removed from the \texttt{Lupo} class? \item \dots the \texttt{virtual} qualifier is removed in front of the \texttt{gasUsage} method in the base class? \item \dots the \texttt{fuelTankSize} method is removed from the \texttt{Lupo} class? \item \dots the \texttt{range} method in the \texttt{S} class is overwritten? \end{itemize} \end{exc} \subsection*{Static Polymorphism} % can be written by specifying types as % template parameters % \item For complex software, the number of template arguments can get % quite large % \item If an additional template argument is required for a base % class template, all derived classes must also be adapted % \end{itemize} % \end{frame} % \begin{frame} % \frametitle{Dynamic Polymorphism} % If a class wants to make a callback to a derived class, the % repective method can be declared {\tt virtual}. This has drawbacks: % \begin{itemize} % \item Overhead due to indirect function call % \item No way for the compiler to inline the method % \end{itemize} % \end{frame} % \begin{frame}[fragile] % \frametitle{Static Polymorphism} % Static polymorphism can be used if the type of the derived class is % known at compile time: % \begin{itemize} % \item Additional template parameter {\tt Implementation} for the base class: % {\scriptsize % \begin{verbatim} % template % class Base; % \end{verbatim} % } % \item A static cast to {\tt Implementation} is done before each call-back: % {\scriptsize % \begin{verbatim} % static_cast(this)->callToImplementation(); % \end{verbatim} % } % \item Derived classes are specified like this: % {\scriptsize % \begin{verbatim} % class Derived : public Base {}; % \end{verbatim} % } % \end{itemize} % \end{frame} % \begin{frame}[fragile] % \frametitle{Nested template arguments} % One problem of static Polymorphism: % \begin{itemize} % \item Template arguments often also require template parameters % \item ``Implementation'' arguments are especially nasty: % \begin{itemize} % \item Assume a base class Base % \item Assume a class Derived and that A is C< Derived > % \item To specify Derived: % \end{itemize} % \end{itemize} % {\scriptsize % \begin{verbatim} % template % class Derived : public Base< C >, B, Derived > % \end{verbatim} % } % \end{frame} % \begin{frame}[fragile] % \frametitle{A real-world example} % {\scriptsize % \begin{verbatim} % template % class TwoPTwoCBoxJacobian % : public TwoPTwoCBoxJacobianBase< % ProblemT, % BoxTraitsT, % TwoPTwoCTraitsT, % TwoPTwoCElementData, % TwoPTwoCVertexData, % TwoPTwoCFluxData >, % TwoPTwoCBoxJacobian > % { % // ... % } % \end{verbatim} % } % \end{frame} % \begin{frame}[fragile] % \frametitle{Traits} % A possible solution is to specify a class which specifies the % template parameters as type definitions (often called a Traits % class): {\scriptsize % \begin{verbatim} % class Traits % { public: % typedef int A; % typedef C B; % }; % template % class Base {}; % template % class Derived : public class Base % {}; % \end{verbatim} % } %%% Local Variables: %%% mode: latex %%% TeX-master: "dumux-handbook" %%% End: