diff --git a/exercises/exercise-fractures/exercise_fractures.cc b/exercises/exercise-fractures/exercise_fractures.cc
index ac6a9f1b3223a6bc4c189cd1e340e616e9b13296..7a61562d8c06a710d93cc4f1d61eeec01ef7d0e5 100644
--- a/exercises/exercise-fractures/exercise_fractures.cc
+++ b/exercises/exercise-fractures/exercise_fractures.cc
@@ -50,10 +50,10 @@
 
 // Define some types for this test  so that we can set them as properties below and
 // reuse them again in the main function with only one single definition of them here
-using MatrixTypeTag = TTAG(MatrixProblemTypeTag);
-using FractureTypeTag = TTAG(FractureProblemTypeTag);
-using MatrixFVGridGeometry = typename GET_PROP_TYPE(MatrixTypeTag, FVGridGeometry);
-using FractureFVGridGeometry = typename GET_PROP_TYPE(FractureTypeTag, FVGridGeometry);
+using MatrixTypeTag = Dumux::Properties::TTag::MatrixProblemTypeTag;
+using FractureTypeTag = Dumux::Properties::TTag::FractureProblemTypeTag;
+using MatrixFVGridGeometry = Dumux::GetPropType<MatrixTypeTag, Dumux::Properties::FVGridGeometry>;
+using FractureFVGridGeometry = Dumux::GetPropType<FractureTypeTag, Dumux::Properties::FVGridGeometry>;
 using TheMultiDomainTraits = Dumux::MultiDomainTraits<MatrixTypeTag, FractureTypeTag>;
 using TheCouplingMapper = Dumux::FacetCouplingMapper<MatrixFVGridGeometry, FractureFVGridGeometry>;
 using TheCouplingManager = Dumux::FacetCouplingManager<TheMultiDomainTraits, TheCouplingMapper>;
@@ -61,8 +61,13 @@ using TheCouplingManager = Dumux::FacetCouplingManager<TheMultiDomainTraits, The
 // set the coupling manager property in the sub-problems
 namespace Dumux {
 namespace Properties {
-SET_TYPE_PROP(MatrixProblemTypeTag, CouplingManager, TheCouplingManager);
-SET_TYPE_PROP(FractureProblemTypeTag, CouplingManager, TheCouplingManager);
+
+template<class TypeTag>
+struct CouplingManager<TypeTag, TTag::MatrixProblemTypeTag> { using type = TheCouplingManager; };
+
+template<class TypeTag>
+struct CouplingManager<TypeTag, TTag::FractureProblemTypeTag> { using type = TheCouplingManager; };
+
 } // end namespace Properties
 } // end namespace Dumux
 
@@ -85,8 +90,8 @@ int main(int argc, char** argv) try
     // This requires the grids used to be passed as template arguments, where
     // they are assumed to be ordered in descending grid dimension. Thus,
     // we pass the matrix grid as first and the fracture grid as second argument.
-    using MatrixGrid = typename GET_PROP_TYPE(MatrixTypeTag, Grid);
-    using FractureGrid = typename GET_PROP_TYPE(FractureTypeTag, Grid);
+    using MatrixGrid = GetPropType<MatrixTypeTag, Properties::Grid>;
+    using FractureGrid = GetPropType<FractureTypeTag, Properties::Grid>;
     using GridManager = Dumux::FacetCouplingGridManager<MatrixGrid, FractureGrid>;
     GridManager gridManager;
 
@@ -114,8 +119,8 @@ int main(int argc, char** argv) try
     fractureFvGridGeometry->update();
 
     // the problems (boundary/initial conditions etc)
-    using MatrixProblem = typename GET_PROP_TYPE(MatrixTypeTag, Problem);
-    using FractureProblem = typename GET_PROP_TYPE(FractureTypeTag, Problem);
+    using MatrixProblem = GetPropType<MatrixTypeTag, Properties::Problem>;
+    using FractureProblem = GetPropType<FractureTypeTag, Properties::Problem>;
 
     // pass the model parameter group to the spatial params so that they obtain the right
     // values from the input file since we use groups for matrix and fracture
@@ -140,8 +145,8 @@ int main(int argc, char** argv) try
     // in case you have more subdomains involved. We domain ids
     // correspond to the order of the type tags passed to the multidomain
     // traits (see definition of the traits class at the beginning of this file)
-    static const auto matrixDomainId = typename TheMultiDomainTraits::template DomainIdx<0>();
-    static const auto fractureDomainId = typename TheMultiDomainTraits::template DomainIdx<1>();
+    static const auto matrixDomainId = typename TheMultiDomainTraits::template SubDomain<0>::Index();
+    static const auto fractureDomainId = typename TheMultiDomainTraits::template SubDomain<1>::Index();
 
     // resize the solution vector and write initial solution to it
     x[matrixDomainId].resize(matrixFvGridGeometry->numDofs());
@@ -167,23 +172,25 @@ int main(int argc, char** argv) try
     fractureProblem->setCouplingManager(couplingManager);
 
     // the grid variables
-    using MatrixGridVariables = typename GET_PROP_TYPE(MatrixTypeTag, GridVariables);
-    using FractureGridVariables = typename GET_PROP_TYPE(FractureTypeTag, GridVariables);
+    using MatrixGridVariables = GetPropType<MatrixTypeTag, Properties::GridVariables>;
+    using FractureGridVariables = GetPropType<FractureTypeTag, Properties::GridVariables>;
     auto matrixGridVariables = std::make_shared<MatrixGridVariables>(matrixProblem, matrixFvGridGeometry);
     auto fractureGridVariables = std::make_shared<FractureGridVariables>(fractureProblem, fractureFvGridGeometry);
     xOld = x;
-    matrixGridVariables->init(x[matrixDomainId], xOld[matrixDomainId]);
-    fractureGridVariables->init(x[fractureDomainId], xOld[fractureDomainId]);
+    matrixGridVariables->init(x[matrixDomainId]);
+    fractureGridVariables->init(x[fractureDomainId]);
 
     // intialize the vtk output modules
-    VtkOutputModule<MatrixTypeTag> matrixVtkWriter(*matrixProblem, *matrixFvGridGeometry, *matrixGridVariables, x[matrixDomainId], matrixProblem->name());
-    VtkOutputModule<FractureTypeTag> fractureVtkWriter(*fractureProblem, *fractureFvGridGeometry, *fractureGridVariables, x[fractureDomainId], fractureProblem->name());
+    using MatrixVtkOutputModule = VtkOutputModule<MatrixGridVariables, GetPropType<MatrixTypeTag, Properties::SolutionVector>>;
+    using FractureVtkOutputModule = VtkOutputModule<FractureGridVariables, GetPropType<FractureTypeTag, Properties::SolutionVector>>;
+    MatrixVtkOutputModule matrixVtkWriter(*matrixGridVariables, x[matrixDomainId], matrixProblem->name());
+    FractureVtkOutputModule fractureVtkWriter(*fractureGridVariables, x[fractureDomainId], fractureProblem->name());
 
     // Add model specific output fields
-    using MatrixVtkOutputFields = typename GET_PROP_TYPE(MatrixTypeTag, VtkOutputFields);
-    using FractureVtkOutputFields = typename GET_PROP_TYPE(FractureTypeTag, VtkOutputFields);
-    MatrixVtkOutputFields::init(matrixVtkWriter);
-    FractureVtkOutputFields::init(fractureVtkWriter);
+    using MatrixVtkOutputFields = GetPropType<MatrixTypeTag, Properties::VtkOutputFields>;
+    using FractureVtkOutputFields = GetPropType<FractureTypeTag, Properties::VtkOutputFields>;
+    MatrixVtkOutputFields::initOutputModule(matrixVtkWriter);
+    FractureVtkOutputFields::initOutputModule(fractureVtkWriter);
 
     // add domain markers to output
     std::vector<int> matrixDomainMarkers(matrixFvGridGeometry->gridView().size(0));
diff --git a/exercises/exercise-fractures/fractureproblem.hh b/exercises/exercise-fractures/fractureproblem.hh
index 297aa3479178b28b77a2890161d6f4ec74fb514c..68153d271483efc1a4a2b959e3011453f39313b5 100644
--- a/exercises/exercise-fractures/fractureproblem.hh
+++ b/exercises/exercise-fractures/fractureproblem.hh
@@ -48,24 +48,36 @@ namespace Dumux {
 template<class TypeTag> class FractureSubProblem;
 
 namespace Properties {
-NEW_PROP_TAG(GridData); // forward declaration of property
 
-// create the type tag nodes
-NEW_TYPE_TAG(FractureProblemTypeTag, INHERITS_FROM(CCTpfaModel, TwoP));
+// Create new type tag node
+namespace TTag {
+struct FractureProblemTypeTag { using InheritsFrom = std::tuple<CCTpfaModel, TwoP>; };
+} // end namespace TTag
+
 // Set the grid type
-SET_TYPE_PROP(FractureProblemTypeTag, Grid, Dune::FoamGrid<1, 2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::FractureProblemTypeTag> { using type = Dune::FoamGrid<1, 2>; };
+
 // Set the problem type
-SET_TYPE_PROP(FractureProblemTypeTag, Problem, FractureSubProblem<TypeTag>);
+template<class TypeTag>
+struct Problem<TypeTag, TTag::FractureProblemTypeTag> { using type = FractureSubProblem<TypeTag>; };
+
 // set the spatial params
-SET_TYPE_PROP(FractureProblemTypeTag,
-              SpatialParams,
-              FractureSpatialParams< typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
-                                     typename GET_PROP_TYPE(TypeTag, Scalar) >);
+template<class TypeTag>
+struct SpatialParams<TypeTag, TTag::FractureProblemTypeTag>
+{
+    using type = FractureSpatialParams< GetPropType<TypeTag, Properties::FVGridGeometry>,
+                                        GetPropType<TypeTag, Properties::Scalar> >;
+};
+
 // the fluid system
-SET_TYPE_PROP(FractureProblemTypeTag,
-              FluidSystem,
-              Dumux::FluidSystems::H2ON2< typename GET_PROP_TYPE(TypeTag, Scalar),
-                                          FluidSystems::H2ON2DefaultPolicy</*fastButSimplifiedRelations=*/true> >);
+template<class TypeTag>
+struct FluidSystem<TypeTag, TTag::FractureProblemTypeTag>
+{
+    using type = Dumux::FluidSystems::H2ON2< GetPropType<TypeTag, Properties::Scalar>,
+                                             FluidSystems::H2ON2DefaultPolicy</*fastButSimplifiedRelations=*/true> >;
+};
+
 } // end namespace Properties
 
 /*!
@@ -79,10 +91,10 @@ class FractureSubProblem : public PorousMediumFlowProblem<TypeTag>
 {
     using ParentType = PorousMediumFlowProblem<TypeTag>;
 
-    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
-    using CouplingManager = typename GET_PROP_TYPE(TypeTag, CouplingManager);
-    using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
+    using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>;
+    using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>;
+    using NumEqVector = GetPropType<TypeTag, Properties::NumEqVector>;
+    using GridVariables = GetPropType<TypeTag, Properties::GridVariables>;
     using ElementVolumeVariables = typename GridVariables::GridVolumeVariables::LocalView;
     using PrimaryVariables = typename GridVariables::PrimaryVariables;
     using Scalar = typename GridVariables::Scalar;
@@ -95,7 +107,7 @@ class FractureSubProblem : public PorousMediumFlowProblem<TypeTag>
     using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
 
     // some indices for convenience
-    using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices;
+    using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
     enum
     {
         pressureIdx = Indices::pressureIdx,
@@ -112,7 +124,7 @@ public:
     {
         // initialize the fluid system, i.e. the tabulation
         // of water properties. Use the default p/T ranges.
-        using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+        using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
         FluidSystem::init();
     }
 
diff --git a/exercises/exercise-fractures/matrixproblem.hh b/exercises/exercise-fractures/matrixproblem.hh
index c4a83952e551265c947d899381457c93830abc13..854902ae7cbc8aae170be0d2d8d9b0d1d637aa76 100644
--- a/exercises/exercise-fractures/matrixproblem.hh
+++ b/exercises/exercise-fractures/matrixproblem.hh
@@ -56,28 +56,36 @@ namespace Dumux {
 template<class TypeTag> class MatrixSubProblem;
 
 namespace Properties {
-NEW_PROP_TAG(GridData); // forward declaration of property
-
-// create the type tag node for the matrix sub-problem
-// We need to put the facet-coupling type tag after the physics-related type tag
-// because it overwrites some of the properties inherited from "TwoP". This is
-// necessary because we need e.g. a modified implementation of darcys law that
-// evaluates the coupling conditions on faces that coincide with the fractures.
-NEW_TYPE_TAG(MatrixProblemTypeTag, INHERITS_FROM(TwoP, CCTpfaFacetCouplingModel));
+
+// create the type tag node
+namespace TTag {
+struct MatrixProblemTypeTag { using InheritsFrom = std::tuple<CCTpfaFacetCouplingModel, TwoP>; };
+} // end namespace TTag
+
 // Set the grid type
-SET_TYPE_PROP(MatrixProblemTypeTag, Grid, Dune::ALUGrid<2, 2, Dune::simplex, Dune::conforming>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::MatrixProblemTypeTag> { using type = Dune::ALUGrid<2, 2, Dune::simplex, Dune::conforming>; };
+
 // Set the problem type
-SET_TYPE_PROP(MatrixProblemTypeTag, Problem, MatrixSubProblem<TypeTag>);
+template<class TypeTag>
+struct Problem<TypeTag, TTag::MatrixProblemTypeTag> { using type = MatrixSubProblem<TypeTag>; };
+
 // set the spatial params
-SET_TYPE_PROP(MatrixProblemTypeTag,
-              SpatialParams,
-              MatrixSpatialParams< typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
-                                   typename GET_PROP_TYPE(TypeTag, Scalar) >);
+template<class TypeTag>
+struct SpatialParams<TypeTag, TTag::MatrixProblemTypeTag>
+{
+    using type = MatrixSpatialParams< GetPropType<TypeTag, Properties::FVGridGeometry>,
+                                      GetPropType<TypeTag, Properties::Scalar> >;
+};
+
 // the fluid system
-SET_TYPE_PROP(MatrixProblemTypeTag,
-              FluidSystem,
-              Dumux::FluidSystems::H2ON2< typename GET_PROP_TYPE(TypeTag, Scalar),
-                                          FluidSystems::H2ON2DefaultPolicy</*fastButSimplifiedRelations=*/true> >);
+template<class TypeTag>
+struct FluidSystem<TypeTag, TTag::MatrixProblemTypeTag>
+{
+    using type = Dumux::FluidSystems::H2ON2< GetPropType<TypeTag, Properties::Scalar>,
+                                             FluidSystems::H2ON2DefaultPolicy</*fastButSimplifiedRelations=*/true> >;
+};
+
 } // end namespace Properties
 
 /*!
@@ -91,10 +99,10 @@ class MatrixSubProblem : public PorousMediumFlowProblem<TypeTag>
 {
     using ParentType = PorousMediumFlowProblem<TypeTag>;
 
-    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
-    using CouplingManager = typename GET_PROP_TYPE(TypeTag, CouplingManager);
-    using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
+    using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>;
+    using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>;
+    using NumEqVector = GetPropType<TypeTag, Properties::NumEqVector>;
+    using GridVariables = GetPropType<TypeTag, Properties::GridVariables>;
     using PrimaryVariables = typename GridVariables::PrimaryVariables;
     using Scalar = typename GridVariables::Scalar;
 
@@ -107,7 +115,7 @@ class MatrixSubProblem : public PorousMediumFlowProblem<TypeTag>
     using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
 
     // some indices for convenience
-    using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices;
+    using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
     enum
     {
         pressureIdx = Indices::pressureIdx,
@@ -125,7 +133,7 @@ public:
     {
         // initialize the fluid system, i.e. the tabulation
         // of water properties. Use the default p/T ranges.
-        using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+        using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
         FluidSystem::init();
     }