From c57faba1128eb5b8deaaada977eb4ae2ba0a90c6 Mon Sep 17 00:00:00 2001
From: Felix Weinhardt <felix.weinhardt@gmx.de>
Date: Thu, 29 Nov 2018 14:16:44 +0100
Subject: [PATCH] [update exercise-fluidsystem] updated code and readme

---
 exercises/exercise-fluidsystem/2p2cproblem.hh | 42 +++++++++++-------
 exercises/exercise-fluidsystem/2pproblem.hh   | 44 +++++++++++--------
 exercises/exercise-fluidsystem/README.md      | 18 +++++---
 .../exercise-fluidsystem.cc                   | 38 +++++++++-------
 .../h2omycompressiblecomponent.hh             | 18 +++++---
 .../exercise-fluidsystem/2p2cproblem.hh       | 42 +++++++++++-------
 .../exercise-fluidsystem/2pproblem.hh         | 44 +++++++++++--------
 .../exercise-fluidsystem.cc                   | 37 ++++++++--------
 .../h2omycompressiblecomponent.hh             | 14 +++---
 9 files changed, 172 insertions(+), 125 deletions(-)

diff --git a/exercises/exercise-fluidsystem/2p2cproblem.hh b/exercises/exercise-fluidsystem/2p2cproblem.hh
index 8cff7cc7..48868247 100644
--- a/exercises/exercise-fluidsystem/2p2cproblem.hh
+++ b/exercises/exercise-fluidsystem/2p2cproblem.hh
@@ -45,30 +45,38 @@ template <class TypeTag> class ExerciseFluidsystemProblemTwoPTwoC;
 
 namespace Properties {
 // Create a new type tag for the problem
-NEW_TYPE_TAG(ExerciseFluidsystemTwoPTwoCTypeTag, INHERITS_FROM(TwoPTwoC, BoxModel));
+// Create new type tags
+namespace TTag {
+struct ExerciseFluidsystemTwoPTwoCTypeTag { using InheritsFrom = std::tuple<BoxModel, TwoPTwoC>; };
+} // end namespace TTag
 
 // Set the "Problem" property
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, Problem, ExerciseFluidsystemProblemTwoPTwoC<TypeTag>);
+template<class TypeTag>
+struct Problem<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag> { using type = ExerciseFluidsystemProblemTwoPTwoC<TypeTag>; };
 
 // Set the spatial parameters
 SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, SpatialParams,
-              ExerciseFluidsystemSpatialParams<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
-                                         typename GET_PROP_TYPE(TypeTag, Scalar)>);
+              ExerciseFluidsystemSpatialParams<GetPropType<TypeTag, Properties::FVGridGeometry>,
+                                         GetPropType<TypeTag, Properties::Scalar>>);
 
 // Set grid and the grid creator to be used
 #if HAVE_DUNE_ALUGRID
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, Grid, Dune::ALUGrid</*dim=*/2, 2, Dune::cube, Dune::nonconforming>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag> { using type = Dune::ALUGrid</*dim=*/2, 2, Dune::cube, Dune::nonconforming>; };
 #elif HAVE_UG
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, Grid, Dune::UGGrid<2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag> { using type = Dune::UGGrid<2>; };
 #else
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, Grid, Dune::YaspGrid<2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag> { using type = Dune::YaspGrid<2>; };
 #endif // HAVE_DUNE_ALUGRID
 
  // The fluid system property
-SET_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, FluidSystem)
+template<class TypeTag>
+struct FluidSystem<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag>
 {
 private:
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
 public:
     using type = FluidSystems::H2OMyCompressibleComponent<Scalar>;
 };
@@ -84,8 +92,8 @@ template <class TypeTag>
 class ExerciseFluidsystemProblemTwoPTwoC : public PorousMediumFlowProblem<TypeTag>
 {
     using ParentType = PorousMediumFlowProblem<TypeTag>;
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using GridView = GetPropType<TypeTag, Properties::GridView>;
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
 
     // Grid dimension
     enum { dim = GridView::dimension,
@@ -95,12 +103,12 @@ class ExerciseFluidsystemProblemTwoPTwoC : public PorousMediumFlowProblem<TypeTa
     using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
 
     // Dumux specific types
-    using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices;
-    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
-    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+    using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
+    using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
+    using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>;
+    using FVGridGeometry = GetPropType<TypeTag, Properties::FVGridGeometry>;
+    using FVElementGeometry = typename GetPropType<TypeTag, Properties::FVGridGeometry>::LocalView;
+    using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
 
 public:
     ExerciseFluidsystemProblemTwoPTwoC(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
diff --git a/exercises/exercise-fluidsystem/2pproblem.hh b/exercises/exercise-fluidsystem/2pproblem.hh
index c5decbfe..8fa4668b 100644
--- a/exercises/exercise-fluidsystem/2pproblem.hh
+++ b/exercises/exercise-fluidsystem/2pproblem.hh
@@ -68,30 +68,38 @@ template <class TypeTag> class ExerciseFluidsystemProblemTwoP;
 
 namespace Properties {
 // Create a new type tag for the problem
-NEW_TYPE_TAG(ExerciseFluidsystemTwoPTypeTag, INHERITS_FROM(TwoP, BoxModel));
+// Create new type tags
+namespace TTag {
+struct ExerciseFluidsystemTwoPTypeTag { using InheritsFrom = std::tuple<BoxModel, TwoP>; };
+} // end namespace TTag
 
 // Set the "Problem" property
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTypeTag, Problem, ExerciseFluidsystemProblemTwoP<TypeTag>);
+template<class TypeTag>
+struct Problem<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag> { using type = ExerciseFluidsystemProblemTwoP<TypeTag>; };
 
 // Set the spatial parameters
 SET_TYPE_PROP(ExerciseFluidsystemTwoPTypeTag, SpatialParams,
-              ExerciseFluidsystemSpatialParams<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
-                                         typename GET_PROP_TYPE(TypeTag, Scalar)>);
+              ExerciseFluidsystemSpatialParams<GetPropType<TypeTag, Properties::FVGridGeometry>,
+                                         GetPropType<TypeTag, Properties::Scalar>>);
 
 // Set grid to be used
 #if HAVE_DUNE_ALUGRID
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTypeTag, Grid, Dune::ALUGrid</*dim=*/2, 2, Dune::cube, Dune::nonconforming>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag> { using type = Dune::ALUGrid</*dim=*/2, 2, Dune::cube, Dune::nonconforming>; };
 #elif HAVE_UG
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTypeTag, Grid, Dune::UGGrid<2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag> { using type = Dune::UGGrid<2>; };
 #else
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTypeTag, Grid, Dune::YaspGrid<2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag> { using type = Dune::YaspGrid<2>; };
 #endif // HAVE_DUNE_ALUGRID
 
 // we use the immiscible fluid system here
-SET_PROP(ExerciseFluidsystemTwoPTypeTag, FluidSystem)
+template<class TypeTag>
+struct FluidSystem<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag>
 {
 private:
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
     using TabulatedH2O = Components::TabulatedComponent<Components::H2O<Scalar>>;
     using LiquidWaterPhase = typename FluidSystems::OnePLiquid<Scalar, TabulatedH2O>;
     /*!
@@ -115,8 +123,8 @@ template <class TypeTag>
 class ExerciseFluidsystemProblemTwoP : public PorousMediumFlowProblem<TypeTag>
 {
     using ParentType = PorousMediumFlowProblem<TypeTag>;
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using GridView = GetPropType<TypeTag, Properties::GridView>;
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
 
     // Grid dimension
     enum { dim = GridView::dimension,
@@ -126,13 +134,13 @@ class ExerciseFluidsystemProblemTwoP : public PorousMediumFlowProblem<TypeTag>
     using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
 
     // Dumux specific types
-    using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices;
-    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
-    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
-    using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState);
+    using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
+    using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
+    using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>;
+    using FVGridGeometry = GetPropType<TypeTag, Properties::FVGridGeometry>;
+    using FVElementGeometry = typename GetPropType<TypeTag, Properties::FVGridGeometry>::LocalView;
+    using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
+    using FluidState = GetPropType<TypeTag, Properties::FluidState>;
 
     enum {
         waterPressureIdx = Indices::pressureIdx,
diff --git a/exercises/exercise-fluidsystem/README.md b/exercises/exercise-fluidsystem/README.md
index c9db143d..da369d76 100644
--- a/exercises/exercise-fluidsystem/README.md
+++ b/exercises/exercise-fluidsystem/README.md
@@ -39,7 +39,10 @@ In this part of the exercise we will consider a system consisting of two immisci
 the `TwoP` _TypeTag_ (immiscible two-phase model properties) and the `BoxModel` _TypeTag_ (specifies properties of the discretization scheme).
 
 ```c++
-NEW_TYPE_TAG(ExerciseFluidsystemTwoPTypeTag, INHERITS_FROM(TwoP, BoxModel));
+// Create new type tags
+namespace TTag {
+struct ExerciseFluidsystemTwoPTypeTag { using InheritsFrom = std::tuple<BoxModel, TwoP>; };
+} // end namespace TTag
 ```
 
 In order to be able to derive from these _TypeTags_, the declarations of the `TwoP` _TypeTag_ and `BoxModel` _TypeTag_ have to be included.
@@ -95,10 +98,11 @@ the other phase is liquid as well and consists of the incompressible fictitious
 
 ```c++
 // we use the immiscible fluid system here
-SET_PROP(ExerciseFluidsystemTwoPTypeTag, FluidSystem)
+template<class TypeTag>
+struct FluidSystem<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag>
 {
 private:
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
     using TabulatedH2O = Components::TabulatedComponent<Components::H2O<Scalar>>;
     using LiquidWaterPhase = typename FluidSystems::OnePLiquid<Scalar, TabulatedH2O>;
     /*!
@@ -181,7 +185,8 @@ two-component model properties:
 
 ```c++
 // Create a new type tag for the problem
-NEW_TYPE_TAG(ExerciseFluidsystemTwoPTwoCTypeTag, INHERITS_FROM(TwoPTwoC, BoxModel));
+struct ExerciseFluidsystemTwoPTwoCTypeTag { using InheritsFrom = std::tuple<BoxModel, TwoPTwoC>; };
+} // end namespace TTag
 ```
 
 The new fluid system is to be implemented in the file `fluidsystems/h2omycompressiblecomponent.hh`. This is already included in the problem and the fluid system property is set accordingly.
@@ -193,10 +198,11 @@ The new fluid system is to be implemented in the file `fluidsystems/h2omycompres
 
 ```c++
 // The fluid system property
-SET_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, FluidSystem)
+template<class TypeTag>
+struct FluidSystem<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag>
 {
 private:
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
 public:
     using type = FluidSystems::H2OMyCompressibleComponent<Scalar>;
 };
diff --git a/exercises/exercise-fluidsystem/exercise-fluidsystem.cc b/exercises/exercise-fluidsystem/exercise-fluidsystem.cc
index 90a44e1a..61f3df14 100644
--- a/exercises/exercise-fluidsystem/exercise-fluidsystem.cc
+++ b/exercises/exercise-fluidsystem/exercise-fluidsystem.cc
@@ -42,16 +42,17 @@
 #include <dumux/common/defaultusagemessage.hh>
 
 #include <dumux/linear/amgbackend.hh>
-#include <dumux/nonlinear/privarswitchnewtonsolver.hh>
+#include <dumux/nonlinear/newtonsolver.hh>
 
 #include <dumux/assembly/fvassembler.hh>
 #include <dumux/assembly/diffmethod.hh>
 
-#include <dumux/discretization/methods.hh>
+#include <dumux/discretization/method.hh>
 
 #include <dumux/io/vtkoutputmodule.hh>
 #include <dumux/io/grid/gridmanager.hh>
 
+
 ////////////////////////
 // the main function
 ////////////////////////
@@ -61,10 +62,10 @@ int main(int argc, char** argv) try
 
     // define the type tag for this problem
     // TYPETAG is set in CMakeLists.txt as compile time definition
-    // alternatively you could write `using TypeTag = TTAG(ExerciseFluidsystemBoxTwoPTypeTag);`
-    // then, for the 2p2c problem you have to change this line to `using TypeTag = TTAG(ExerciseFluidsystemBoxTwoPTypeTag);`
+    // alternatively you could write `using TypeTag = Properties::TTag::ExerciseFluidsystemBoxTwoPTypeTag;`
+    // then, for the 2p2c problem you have to change this line to `using TypeTag = Properties::TTag::ExerciseFluidsystemBoxTwoPTypeTag;`
     // and recompile the executable
-    using TypeTag = TTAG(TYPETAG);
+    using TypeTag = Properties::TTag::TYPETAG;
 
     // initialize MPI, finalize is done automatically on exit
     const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
@@ -77,7 +78,7 @@ int main(int argc, char** argv) try
     Parameters::init(argc, argv);
 
     // try to create a grid (from the given grid file or the input file)
-    GridManager<typename GET_PROP_TYPE(TypeTag, Grid)> gridManager;
+    GridManager<GetPropType<TypeTag, Properties::Grid>> gridManager;
     gridManager.init();
 
     ////////////////////////////////////////////////////////////
@@ -88,35 +89,38 @@ int main(int argc, char** argv) try
     const auto& leafGridView = gridManager.grid().leafGridView();
 
     // create the finite volume grid geometry
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVGridGeometry = GetPropType<TypeTag, Properties::FVGridGeometry>;
     auto fvGridGeometry = std::make_shared<FVGridGeometry>(leafGridView);
     fvGridGeometry->update();
 
     // the problem (initial and boundary conditions)
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using Problem = GetPropType<TypeTag, Properties::Problem>;
     auto problem = std::make_shared<Problem>(fvGridGeometry);
 
     // the solution vector
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
     SolutionVector x(fvGridGeometry->numDofs());
     problem->applyInitialSolution(x);
     auto xOld = x;
 
     // the grid variables
-    using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
+    using GridVariables = GetPropType<TypeTag, Properties::GridVariables>;
     auto gridVariables = std::make_shared<GridVariables>(problem, fvGridGeometry);
-    gridVariables->init(x, xOld);
+    gridVariables->init(x);
+    
 
     // get some time loop parameters
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
     const auto tEnd = getParam<Scalar>("TimeLoop.TEnd");
     const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize");
     auto dt = getParam<Scalar>("TimeLoop.DtInitial");
 
     // intialize the vtk output module
-    using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields);
-    VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name());
-    VtkOutputFields::init(vtkWriter); //! Add model specific output fields
+    using VtkOutputFields = GetPropType<TypeTag, Properties::VtkOutputFields>;
+    VtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name());
+    using VelocityOutput = GetPropType<TypeTag, Properties::VelocityOutput>;
+    vtkWriter.addVelocityOutput(std::make_shared<VelocityOutput>(*gridVariables));
+    VtkOutputFields::initOutputModule(vtkWriter); //!< Add model specific output fields
 
     // instantiate time loop
     auto timeLoop = std::make_shared<TimeLoop<Scalar>>(/*start time*/0.0, dt, tEnd);
@@ -130,8 +134,8 @@ int main(int argc, char** argv) try
     using LinearSolver = AMGBackend<TypeTag>;
     auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper());
 
-    // the non-linear solver (primary variable switch needed for the 2p2c test in exercise b)
-    using NewtonSolver = Dumux::PriVarSwitchNewtonSolver<Assembler,LinearSolver,typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch)>;
+     // the non-linear solver
+    using NewtonSolver = NewtonSolver<Assembler, LinearSolver>;
     NewtonSolver nonLinearSolver(assembler, linearSolver);
 
     // time loop
diff --git a/exercises/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh b/exercises/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh
index b2446b79..62965b2a 100644
--- a/exercises/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh
+++ b/exercises/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh
@@ -47,14 +47,14 @@ namespace FluidSystems {
 template <class Scalar,
           class H2OType = Dumux::Components::TabulatedComponent<Dumux::Components::H2O<Scalar> > >
 class H2OMyCompressibleComponent
-    : public BaseFluidSystem< Scalar, H2OMyCompressibleComponent<Scalar, H2OType> >
+    : public Base< Scalar, H2OMyCompressibleComponent<Scalar, H2OType> >
 {
-    typedef H2OMyCompressibleComponent<Scalar, H2OType> ThisType;
-    typedef BaseFluidSystem<Scalar, ThisType> Base;
-
+    using ThisType = H2OMyCompressibleComponent<Scalar, H2OType>;
+    using Base = Dumux::FluidSystems::Base<Scalar, ThisType>;
+    
 public:
-    typedef Dumux::MyCompressibleComponent<Scalar> MyCompressibleComponent;
-    typedef H2OType H2O;
+    using H2O = H2OType;
+    using MyCompressibleComponent = Dumux::MyCompressibleComponent<Scalar>;
 
     static constexpr int numPhases = 2;
     static constexpr int numComponents = 2;
@@ -121,7 +121,11 @@ public:
         assert(0 <= phaseIdx && phaseIdx < numPhases);
         return true;
     }
-
+    static constexpr bool isGas(int phaseIdx)
+    {
+        assert(0 <= phaseIdx && phaseIdx < numPhases);
+        return phaseIdx == phase1Idx;
+    }
     static constexpr bool isIdealGas(int phaseIdx)
     { return H2O::gasIsIdeal() && MyCompressibleComponent::gasIsIdeal(); }
 
diff --git a/exercises/solution/exercise-fluidsystem/2p2cproblem.hh b/exercises/solution/exercise-fluidsystem/2p2cproblem.hh
index 13eb748b..b46b9f01 100644
--- a/exercises/solution/exercise-fluidsystem/2p2cproblem.hh
+++ b/exercises/solution/exercise-fluidsystem/2p2cproblem.hh
@@ -45,30 +45,38 @@ template <class TypeTag> class ExerciseFluidsystemProblemTwoPTwoC;
 
 namespace Properties {
 // Create a new type tag for the problem
-NEW_TYPE_TAG(ExerciseFluidsystemTwoPTwoCTypeTag, INHERITS_FROM(TwoPTwoC, BoxModel));
+// Create new type tags
+namespace TTag {
+struct ExerciseFluidsystemTwoPTwoCTypeTag { using InheritsFrom = std::tuple<BoxModel, TwoPTwoC>; };
+} // end namespace TTag
 
 // Set the "Problem" property
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, Problem, ExerciseFluidsystemProblemTwoPTwoC<TypeTag>);
+template<class TypeTag>
+struct Problem<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag> { using type = ExerciseFluidsystemProblemTwoPTwoC<TypeTag>; };
 
 // Set the spatial parameters
 SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, SpatialParams,
-              ExerciseFluidsystemSpatialParams<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
-                                         typename GET_PROP_TYPE(TypeTag, Scalar)>);
+              ExerciseFluidsystemSpatialParams<GetPropType<TypeTag, Properties::FVGridGeometry>,
+                                         GetPropType<TypeTag, Properties::Scalar>>);
 
 // Set grid and the grid creator to be used
 #if HAVE_DUNE_ALUGRID
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, Grid, Dune::ALUGrid</*dim=*/2, 2, Dune::cube, Dune::nonconforming>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag> { using type = Dune::ALUGrid</*dim=*/2, 2, Dune::cube, Dune::nonconforming>; };
 #elif HAVE_UG
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, Grid, Dune::UGGrid<2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag> { using type = Dune::UGGrid<2>; };
 #else
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, Grid, Dune::YaspGrid<2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag> { using type = Dune::YaspGrid<2>; };
 #endif // HAVE_DUNE_ALUGRID
 
  // The fluid system property
-SET_PROP(ExerciseFluidsystemTwoPTwoCTypeTag, FluidSystem)
+template<class TypeTag>
+struct FluidSystem<TypeTag, TTag::ExerciseFluidsystemTwoPTwoCTypeTag>
 {
 private:
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
 public:
     using type = FluidSystems::H2OMyCompressibleComponent<Scalar>;
 };
@@ -84,8 +92,8 @@ template <class TypeTag>
 class ExerciseFluidsystemProblemTwoPTwoC : public PorousMediumFlowProblem<TypeTag>
 {
     using ParentType = PorousMediumFlowProblem<TypeTag>;
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using GridView = GetPropType<TypeTag, Properties::GridView>;
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
 
     // Grid dimension
     enum { dim = GridView::dimension,
@@ -95,12 +103,12 @@ class ExerciseFluidsystemProblemTwoPTwoC : public PorousMediumFlowProblem<TypeTa
     using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
 
     // Dumux specific types
-    using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices;
-    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
-    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+    using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
+    using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
+    using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>;
+    using FVGridGeometry = GetPropType<TypeTag, Properties::FVGridGeometry>;
+    using FVElementGeometry = typename GetPropType<TypeTag, Properties::FVGridGeometry>::LocalView;
+    using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
 
 public:
     ExerciseFluidsystemProblemTwoPTwoC(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
diff --git a/exercises/solution/exercise-fluidsystem/2pproblem.hh b/exercises/solution/exercise-fluidsystem/2pproblem.hh
index c228046e..f27c36b9 100644
--- a/exercises/solution/exercise-fluidsystem/2pproblem.hh
+++ b/exercises/solution/exercise-fluidsystem/2pproblem.hh
@@ -68,30 +68,38 @@ template <class TypeTag> class ExerciseFluidsystemProblemTwoP;
 
 namespace Properties {
 // Create a new type tag for the problem
-NEW_TYPE_TAG(ExerciseFluidsystemTwoPTypeTag, INHERITS_FROM(TwoP, BoxModel));
+// Create new type tags
+namespace TTag {
+struct ExerciseFluidsystemTwoPTypeTag { using InheritsFrom = std::tuple<BoxModel, TwoP>; };
+} // end namespace TTag
 
 // Set the "Problem" property
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTypeTag, Problem, ExerciseFluidsystemProblemTwoP<TypeTag>);
+template<class TypeTag>
+struct Problem<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag> { using type = ExerciseFluidsystemProblemTwoP<TypeTag>; };
 
 // Set the spatial parameters
 SET_TYPE_PROP(ExerciseFluidsystemTwoPTypeTag, SpatialParams,
-              ExerciseFluidsystemSpatialParams<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
-                                         typename GET_PROP_TYPE(TypeTag, Scalar)>);
+              ExerciseFluidsystemSpatialParams<GetPropType<TypeTag, Properties::FVGridGeometry>,
+                                         GetPropType<TypeTag, Properties::Scalar>>);
 
 // Set grid to be used
 #if HAVE_DUNE_ALUGRID
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTypeTag, Grid, Dune::ALUGrid</*dim=*/2, 2, Dune::cube, Dune::nonconforming>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag> { using type = Dune::ALUGrid</*dim=*/2, 2, Dune::cube, Dune::nonconforming>; };
 #elif HAVE_UG
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTypeTag, Grid, Dune::UGGrid<2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag> { using type = Dune::UGGrid<2>; };
 #else
-SET_TYPE_PROP(ExerciseFluidsystemTwoPTypeTag, Grid, Dune::YaspGrid<2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag> { using type = Dune::YaspGrid<2>; };
 #endif // HAVE_DUNE_ALUGRID
 
 // we use the immiscible fluid system here
-SET_PROP(ExerciseFluidsystemTwoPTypeTag, FluidSystem)
+template<class TypeTag>
+struct FluidSystem<TypeTag, TTag::ExerciseFluidsystemTwoPTypeTag>
 {
 private:
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
     using TabulatedH2O = Components::TabulatedComponent<Components::H2O<Scalar>>;
     using LiquidWater = typename FluidSystems::OnePLiquid<Scalar, TabulatedH2O>;
     /*!
@@ -115,8 +123,8 @@ template <class TypeTag>
 class ExerciseFluidsystemProblemTwoP : public PorousMediumFlowProblem<TypeTag>
 {
     using ParentType = PorousMediumFlowProblem<TypeTag>;
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using GridView = GetPropType<TypeTag, Properties::GridView>;
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
 
     // Grid dimension
     enum { dim = GridView::dimension,
@@ -126,13 +134,13 @@ class ExerciseFluidsystemProblemTwoP : public PorousMediumFlowProblem<TypeTag>
     using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
 
     // Dumux specific types
-    using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices;
-    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
-    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
-    using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState);
+    using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
+    using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
+    using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>;
+    using FVGridGeometry = GetPropType<TypeTag, Properties::FVGridGeometry>;
+    using FVElementGeometry = typename GetPropType<TypeTag, Properties::FVGridGeometry>::LocalView;
+    using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
+    using FluidState = GetPropType<TypeTag, Properties::FluidState>;
 
     enum {
         waterPressureIdx = Indices::pressureIdx,
diff --git a/exercises/solution/exercise-fluidsystem/exercise-fluidsystem.cc b/exercises/solution/exercise-fluidsystem/exercise-fluidsystem.cc
index de882492..ce136ff9 100644
--- a/exercises/solution/exercise-fluidsystem/exercise-fluidsystem.cc
+++ b/exercises/solution/exercise-fluidsystem/exercise-fluidsystem.cc
@@ -42,12 +42,12 @@
 #include <dumux/common/defaultusagemessage.hh>
 
 #include <dumux/linear/amgbackend.hh>
-#include <dumux/nonlinear/privarswitchnewtonsolver.hh>
+#include <dumux/nonlinear/newtonsolver.hh>
 
 #include <dumux/assembly/fvassembler.hh>
 #include <dumux/assembly/diffmethod.hh>
 
-#include <dumux/discretization/methods.hh>
+#include <dumux/discretization/method.hh>
 
 #include <dumux/io/vtkoutputmodule.hh>
 #include <dumux/io/grid/gridmanager.hh>
@@ -61,10 +61,10 @@ int main(int argc, char** argv) try
 
     // define the type tag for this problem
     // TYPETAG is set in CMakeLists.txt as compile time definition
-    // alternatively you could write `using TypeTag = TTAG(ExerciseFluidsystemTwoPTypeTag);`
-    // then, for the 2p2c problem you have to change this line to `using TypeTag = TTAG(ExerciseFluidsystemTwoPTwoCTypeTag);`
+    // alternatively you could write `using TypeTag = Properties::TTag::ExerciseFluidsystemTwoPTypeTag;`
+    // then, for the 2p2c problem you have to change this line to `using TypeTag = Properties::TTag::ExerciseFluidsystemTwoPTwoCTypeTag;`
     // and recompile the executable
-    using TypeTag = TTAG(TYPETAG);
+    using TypeTag = Properties::TTag::TYPETAG;
 
     // initialize MPI, finalize is done automatically on exit
     const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
@@ -77,7 +77,7 @@ int main(int argc, char** argv) try
     Parameters::init(argc, argv);
 
     // try to create a grid (from the given grid file or the input file)
-    GridManager<typename GET_PROP_TYPE(TypeTag, Grid)> gridManager;
+    GridManager<GetPropType<TypeTag, Properties::Grid>> gridManager;
     gridManager.init();
 
     ////////////////////////////////////////////////////////////
@@ -88,35 +88,36 @@ int main(int argc, char** argv) try
     const auto& leafGridView = gridManager.grid().leafGridView();
 
     // create the finite volume grid geometry
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVGridGeometry = GetPropType<TypeTag, Properties::FVGridGeometry>;
     auto fvGridGeometry = std::make_shared<FVGridGeometry>(leafGridView);
     fvGridGeometry->update();
 
     // the problem (initial and boundary conditions)
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using Problem = GetPropType<TypeTag, Properties::Problem>;
     auto problem = std::make_shared<Problem>(fvGridGeometry);
 
     // the solution vector
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
     SolutionVector x(fvGridGeometry->numDofs());
     problem->applyInitialSolution(x);
     auto xOld = x;
 
     // the grid variables
-    using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
+    using GridVariables = GetPropType<TypeTag, Properties::GridVariables>;
     auto gridVariables = std::make_shared<GridVariables>(problem, fvGridGeometry);
     gridVariables->init(x, xOld);
 
     // get some time loop parameters
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
     const auto tEnd = getParam<Scalar>("TimeLoop.TEnd");
     const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize");
     auto dt = getParam<Scalar>("TimeLoop.DtInitial");
-
     // intialize the vtk output module
-    using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields);
-    VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name());
-    VtkOutputFields::init(vtkWriter); //! Add model specific output fields
+    using VtkOutputFields = GetPropType<TypeTag, Properties::VtkOutputFields>;
+    VtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name());
+    using VelocityOutput = GetPropType<TypeTag, Properties::VelocityOutput>;
+    vtkWriter.addVelocityOutput(std::make_shared<VelocityOutput>(*gridVariables));
+    VtkOutputFields::initOutputModule(vtkWriter); //!< Add model specific output fields
 
     // instantiate time loop
     auto timeLoop = std::make_shared<TimeLoop<Scalar>>(/*start time*/0.0, dt, tEnd);
@@ -129,9 +130,9 @@ int main(int argc, char** argv) try
     // the linear solver
     using LinearSolver = AMGBackend<TypeTag>;
     auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper());
-
-    // the non-linear solver (primary variable switch needed for the 2p2c test in exercise b)
-    using NewtonSolver = Dumux::PriVarSwitchNewtonSolver<Assembler,LinearSolver,typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch)>;
+    
+     // the non-linear solver
+    using NewtonSolver = NewtonSolver<Assembler, LinearSolver>;
     NewtonSolver nonLinearSolver(assembler, linearSolver);
 
     // time loop
diff --git a/exercises/solution/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh b/exercises/solution/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh
index 212c0feb..6f4d9be4 100644
--- a/exercises/solution/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh
+++ b/exercises/solution/exercise-fluidsystem/fluidsystems/h2omycompressiblecomponent.hh
@@ -39,7 +39,7 @@
 
 namespace Dumux {
 namespace FluidSystems {
-
+    
 /*!
  * \brief A compositional fluid consisting of two liquid phases,
  *        which are water and a fictitious component from exercise-fluidsystem a.
@@ -47,14 +47,14 @@ namespace FluidSystems {
 template <class Scalar,
           class H2OType = Dumux::Components::TabulatedComponent<Dumux::Components::H2O<Scalar> > >
 class H2OMyCompressibleComponent
-    : public BaseFluidSystem< Scalar, H2OMyCompressibleComponent<Scalar, H2OType> >
+    : public Base< Scalar, H2OMyCompressibleComponent<Scalar, H2OType> >
 {
-    typedef H2OMyCompressibleComponent<Scalar, H2OType> ThisType;
-    typedef BaseFluidSystem<Scalar, ThisType> Base;
-
+    using ThisType = H2OMyCompressibleComponent<Scalar, H2OType>;
+    using Base = Dumux::FluidSystems::Base<Scalar, ThisType>;
+    
 public:
-    typedef Dumux::MyCompressibleComponent<Scalar> MyCompressibleComponent;
-    typedef H2OType H2O;
+    using H2O = H2OType;
+    using MyCompressibleComponent = Dumux::MyCompressibleComponent<Scalar>;
 
     static constexpr int numPhases = 2;
     static constexpr int numComponents = 2;
-- 
GitLab