Commit 2ad6ee7d authored by Gabi Seitz's avatar Gabi Seitz Committed by Martin Schneider
Browse files

[handbook] update section on propertysystem to new syntax

parent 43e9ae6d
......@@ -37,9 +37,12 @@ namespace \texttt{Dumux::Properties}.
\subsubsection{Defining Type Tags}
New nodes in the type tag hierarchy can be defined using
\begin{lstlisting}[style=DumuxCode]
NEW_TYPE_TAG(NewTypeTagName, INHERITS_FROM(BaseTagName1, BaseTagName2, ...));
// Create new type tags
namespace TTag {
struct NewTypeTagName { using InheritsFrom = std::tuple<..., BaseTagName2, BaseTagName1>; };
} // end namespace TTag
\end{lstlisting}
where the \texttt{INHERITS\_FROM} part is optional. To avoid
where the \texttt{InheritsFrom} part is optional. To avoid
inconsistencies in the hierarchy, each type tag may be defined only
once for a program.
......@@ -48,29 +51,30 @@ Example:
\begin{lstlisting}[style=DumuxCode]
namespace Dumux {
namespace Properties {
NEW_TYPE_TAG(MyBaseTypeTag1);
NEW_TYPE_TAG(MyBaseTypeTag2);
namespace TTag {
struct MyBaseTypeTag1 {};
struct MyBaseTypeTag2 {};
NEW_TYPE_TAG(MyDerivedTypeTag, INHERITS_FROM(MyBaseTypeTag1, MyBaseTypeTag2));
struct MyDerivedTypeTag { using InheritsFrom = std::tuple<MyBaseTypeTag2, MyBaseTypeTag1>; };
} // end namespace TTag
}}
\end{lstlisting}
\subsubsection{Declaring Property Tags}
New property tags, i.e. labels for properties, are declared
New property tags are defined using:
using
\begin{lstlisting}[style=DumuxCode]
NEW_PROP_TAG(NewPropTagName);
template<class TypeTag>
struct NewPropTagName<TypeTag, TTag::MyTypeTag> { using type = UndefinedProperty; };
\end{lstlisting}
A property tag can be declared arbitrarily often, in fact it is
recommended that all properties are declared in each file where they
are used.
\vskip1ex\noindent
Example:
\begin{lstlisting}[style=DumuxCode]
namespace Dumux {
namespace Properties {
NEW_PROP_TAG(MyPropertyTag);
template<class TypeTag>
struct MyPropertyTag<TypeTag, TTag::MyTypeTag> { using type = UndefinedProperty; };
}}
\end{lstlisting}
......@@ -78,7 +82,8 @@ NEW_PROP_TAG(MyPropertyTag);
The value of a property on a given node of the type tag hierarchy is
defined using
\begin{lstlisting}[style=DumuxCode]
SET_PROP(TypeTagName, PropertyTagName)
template<class TypeTag>
struct PropertyTagName<TypeTag, TTag::TypeTagName>
{
// arbitrary body of a struct
};
......@@ -86,13 +91,15 @@ SET_PROP(TypeTagName, PropertyTagName)
For each program, a property itself can be declared at most once,
although properties may be overwritten for derived type tags.
Also, the following convenience macros are available to define simple
properties:
\begin{lstlisting}[style=DumuxCode]
SET_TYPE_PROP(TypeTagName, PropertyTagName, type);
SET_BOOL_PROP(TypeTagName, PropertyTagName, booleanValue);
SET_INT_PROP(TypeTagName, PropertyTagName, integerValue);
SET_SCALAR_PROP(TypeTagName, PropertyTagName, floatingPointValue);
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
......@@ -100,100 +107,63 @@ Example:
\begin{lstlisting}[style=DumuxCode]
namespace Dumux {
namespace Properties {
NEW_TYPE_TAG(MyTypeTag);
NEW_PROP_TAG(MyCustomProperty);
NEW_PROP_TAG(MyType);
// Create new type tag
namespace TTag {
struct MyTypeTag {};
}
NEW_PROP_TAG(MyBoolValue);
NEW_PROP_TAG(MyIntValue);
NEW_PROP_TAG(MyScalarValue);
// Declare the properties
template<class TypeTag, class MyTypeTag> struct MyCustomProperty;
SET_PROP(MyTypeTag, MyCustomProperty)
{
static void print() { std::cout << "Hello, World!\n"; }
};
SET_TYPE_PROP(MyTypeTag, MyType, unsigned int);
template<class TypeTag, class MyTypeTag> struct MyType;
SET_BOOL_PROP(MyTypeTag, MyBoolValue, true);
SET_INT_PROP(MyTypeTag, MyIntValue, 12345);
SET_SCALAR_PROP(MyTypeTag, MyScalarValue, 12345.67890);
}}
\end{lstlisting}
template<class TypeTag, class MyTypeTag> struct MyBoolValue;
\subsubsection{Un-setting Properties}
Sometimes an inherited properties do not make sense for a certain
node in the type tag hierarchy. These properties can be explicitly
un-set using
\begin{lstlisting}[style=DumuxCode]
UNSET_PROP(TypeTagName, PropertyTagName);
\end{lstlisting}
The un-set property can not be set for the same type tag, but of
course derived type tags may set it again.
template<class TypeTag, class MyTypeTag> struct MyIntValue;
\vskip1ex\noindent
Example:
\begin{lstlisting}[style=DumuxCode]
namespace Dumux {
namespace Properties {
NEW_TYPE_TAG(BaseTypeTag);
NEW_TYPE_TAG(DerivedTypeTag, INHERITS_FROM(BaseTypeTag));
template<class TypeTag, class MyTypeTag> struct MyScalarValue;
// Set the properties
template<class TypeTag>
struct MyCustomProperty<TypeTag, TTag::MyTypeTag>
{static void print() { std::cout << "Hello, World!\n"; }};
NEW_PROP_TAG(TestProp);
template<class TypeTag>
struct MyType<TypeTag, TTag::MyTypeTag> { using type = unsigned int; };
SET_TYPE_PROP(BaseTypeTag, TestProp, int);
UNSET_PROP(DerivedTypeTag, TestProp);
// trying to access the 'TestProp' property for 'DerivedTypeTag'
// will trigger a compiler error!
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{Converting Tag Names to Tag Types}
For the \Cplusplus compiler, property and type tags are like ordinary
types. Both can thus be used as template arguments. To convert a
property tag name or a type tag name into the corresponding type, the
macros \texttt{TTAG(TypeTagName)} and \texttt{PTAG(PropertyTagName)}
ought to be used.
\subsubsection{Retrieving Property Values}
The value of a property can be retrieved using
\begin{lstlisting}[style=DumuxCode]
GET_PROP(TypeTag, PropertyTag)
\end{lstlisting}
or using the convenience macros
The type or the value of a property can be retrieved using
\begin{lstlisting}[style=DumuxCode]
GET_PROP_TYPE(TypeTag, PropertyTag)
GET_PROP_VALUE(TypeTag, PropertyTag)
using MyType = GetPropType<TypeTag, Properties::PropertyTag>
auto myValue = getPropValue<TypeTag, Properties::PropertyTag>()
\end{lstlisting}
\vskip1ex
\noindent
The first convenience macro retrieves the type defined using
\texttt{SET\_TYPE\_PROP} and is equivalent to
\begin{lstlisting}[style=DumuxCode]
GET_PROP(TypeTag, PropertyTag)::type
\end{lstlisting}
while the second convenience macro retrieves the value of any property
defined using one of the macros \texttt{SET\_}$\{$\texttt{INT,BOOL,SCALAR}$\}$\texttt{\_PROP} and is
equivalent to
\begin{lstlisting}[style=DumuxCode]
GET_PROP(TypeTag, PropertyTag)::value
\end{lstlisting}
\vskip1ex\noindent
Example:\nolinebreak
\begin{lstlisting}[style=DumuxCode]
template <TypeTag>
class MyClass {
// retrieve the ::value attribute of the 'NumEq' property
enum { numEq = GET_PROP(TypeTag, NumEq)::value };
// retrieve the ::value attribute of the 'NumPhases' property using the convenience macro
enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) };
// retrieve the ::type attribute of the 'NumEq' property
enum { numEq = GetPropType<Properties::ModelTraits>::numEq() };
// retrieve the ::value attribute of the 'UseMoles' property
static constexpr bool useMoles = getPropValue<TypeTag, Properties::UseMoles>();
// retrieve the ::type attribute of the 'Scalar' property
typedef typename GET_PROP(TypeTag, Scalar)::type Scalar;
// retrieve the ::type attribute of the 'Vector' property using the convenience macro
typedef typename GET_PROP_TYPE(TypeTag, Vector) Vector;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
};
\end{lstlisting}
......@@ -201,16 +171,17 @@ class MyClass {
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 keyword
\texttt{TypeTag}. Inside property class bodies this can be used to
retrieve other properties using the \texttt{GET\_PROP} macros.
\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]
SET_PROP(MyModelTypeTag, Vector)
template<class TypeTag>
struct Vector<TypeTag, TTag::MyModelTypeTag>
{
private: typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
public: typedef std::vector<Scalar> type;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using type = std::vector<Scalar>;
};
\end{lstlisting}
......@@ -272,12 +243,15 @@ defined by:
namespace Dumux {
namespace Properties {
NEW_TYPE_TAG(CompactCar);
NEW_TYPE_TAG(Truck);
NEW_TYPE_TAG(Tank);
NEW_TYPE_TAG(Sedan, INHERITS_FROM(CompactCar));
NEW_TYPE_TAG(Pickup, INHERITS_FROM(Sedan, Truck));
NEW_TYPE_TAG(HummerH1, INHERITS_FROM(Pickup, Tank));
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
......@@ -285,12 +259,18 @@ make sense for at least one of the nodes of Figure
\ref{fig:car-hierarchy}. These property names can be declared as
follows:
\begin{lstlisting}[name=propsyscars,style=DumuxCode]
NEW_PROP_TAG(TopSpeed); // [km/h]
NEW_PROP_TAG(NumSeats); // []
NEW_PROP_TAG(CanonCaliber); // [mm]
NEW_PROP_TAG(GasUsage); // [l/100km]
NEW_PROP_TAG(AutomaticTransmission); // true/false
NEW_PROP_TAG(Payload); // [t]
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 CanonCaliber { using type = UndefinedProperty; }; // [mm]
template<class TypeTag, class MyTypeTag>
struct GasUsage { using type = UndefinedProperty; }; // [l/100km]
template<class TypeTag, class MyTypeTag>
struct AutomaticTransmission { using type = UndefinedProperty; }; // true/false
template<class TypeTag, class MyTypeTag>
struct Payload { using type = UndefinedProperty; }; // [t]
\end{lstlisting}
\noindent
......@@ -321,35 +301,52 @@ the following:
Using the \Dumux property system, these assumptions are formulated
using
\begin{lstlisting}[name=propsyscars,style=DumuxCode]
SET_INT_PROP(CompactCar, TopSpeed, GET_PROP_VALUE(TypeTag, GasUsage) * 30);
SET_INT_PROP(CompactCar, NumSeats, 5);
SET_INT_PROP(CompactCar, GasUsage, 4);
template<class TypeTag>
struct TopSpeed<TypeTag, TTag::CompactCar>
{static constexpr int value = getPropValue<TypeTag, Properties::GasUsage>() * 30};
SET_INT_PROP(Truck, TopSpeed, 100);
SET_INT_PROP(Truck, NumSeats, 2);
SET_INT_PROP(Truck, GasUsage, 18);
SET_INT_PROP(Truck, Payload, 35);
template<class TypeTag>
struct NumSeats<TypeTag, TTag::CompactCar> { static constexpr int value = 5; };
SET_INT_PROP(Tank, TopSpeed, 60);
SET_INT_PROP(Tank, GasUsage, 65);
SET_INT_PROP(Tank, CanonCaliber, 120);
template<class TypeTag>
struct GasUsage<TypeTag, TTag::CompactCar> { static constexpr int value = 4; };
SET_INT_PROP(Sedan, GasUsage, 7);
SET_BOOL_PROP(Sedan, AutomaticTransmission, true);
template<class TypeTag>
struct TopSpeed<TypeTag, TTag::Truck> { static constexpr int value = 100; };
SET_INT_PROP(Pickup, TopSpeed, 120);
SET_INT_PROP(Pickup, Payload, 5);
template<class TypeTag>
struct NumSeats<TypeTag, TTag::Truck> { static constexpr int value = 2; };
SET_INT_PROP(HummerH1, TopSpeed, GET_PROP_VALUE(TTAG(Pickup), TopSpeed));
\end{lstlisting}
template<class TypeTag>
struct GasUsage<TypeTag, TTag::Truck> { static constexpr int value = 18; };
\noindent
At this point, the Hummer-H1 has a $\unit[120]{mm}$ canon which it inherited
from its military ancestor. It can be removed by
\begin{lstlisting}[name=propsyscars,style=DumuxCode]
UNSET_PROP(HummerH1, CanonCaliber);
template<class TypeTag>
struct Payload<TypeTag, TTag::Truck> { static constexpr int value = 35; };
}} // close namespaces
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
......@@ -358,30 +355,19 @@ be generated. For example
\begin{lstlisting}[name=propsyscars,style=DumuxCode]
int main()
{
std::cout << "top speed of sedan: " << GET_PROP_VALUE(TTAG(Sedan), TopSpeed) << "\n";
std::cout << "top speed of truck: " << GET_PROP_VALUE(TTAG(Truck), TopSpeed) << "\n";
std::cout << PROP_DIAGNOSTIC(TTAG(Sedan), TopSpeed);
std::cout << PROP_DIAGNOSTIC(TTAG(HummerH1), CanonCaliber);
Dumux::Properties::print<TTAG(Sedan)>();
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
$ Properties for Sedan:
$ bool AutomaticTransmission = 'true' defined at test_propertysystem.cc:68
$ int GasUsage = '7' defined at test_propertysystem.cc:67
$ Inherited from CompactCar:
$ int NumSeats = '5' defined at test_propertysystem.cc:55
$ int TopSpeed = '::Dumux::Properties::GetProperty<TypeTag, ::Dumux::Properties::PTag::GasUsage>::p::value * 30' defined at test_propertysystem.cc:54
\end{lstlisting}
\subsection{Property Values}
To get the value of a property use:
\begin{description}
\item[\texttt{{\small GET\_PROP\_VALUE:}}]
\item[\texttt{{\small getPropValue:}}]
Always returns the \emph{compile-time} specified value of the property.
\end{description}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment