From 693a7970fed24035bf8b400647ec10a56b221230 Mon Sep 17 00:00:00 2001
From: Theresa Kurz <theresa.kurz@iws.uni-stuttgart.de>
Date: Wed, 28 Nov 2018 16:20:22 +0100
Subject: [PATCH] [exercise-grid] update

---
 exercises/exercise-grids/README.md            |  3 +-
 exercises/exercise-grids/exercise_grids.cc    | 45 +++++++++++++-----
 .../exercise-grids/injection2pproblem.hh      | 36 ++++++++------
 .../exercise-grids/exercise_grids_solution.cc | 45 +++++++++++++-----
 .../exercise-grids/injection2pproblem.hh      | 47 +++++++++++--------
 5 files changed, 115 insertions(+), 61 deletions(-)

diff --git a/exercises/exercise-grids/README.md b/exercises/exercise-grids/README.md
index aeffdc23..08b2a508 100644
--- a/exercises/exercise-grids/README.md
+++ b/exercises/exercise-grids/README.md
@@ -44,7 +44,8 @@ In the Problem file, the grid properties are defined using the following command
 
 ```c++
 // Set the grid type
-SET_TYPE_PROP(Injection2pTypeTag, Grid, Dune::YaspGrid<2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::Injection2pTypeTag> { using type = Dune::YaspGrid<2>; };
 ```
 
 This sets the Grid, which belongs to the Injection2pTypeTag type tag, and calls the manager with a basic YaspGrid in the second dimension.
diff --git a/exercises/exercise-grids/exercise_grids.cc b/exercises/exercise-grids/exercise_grids.cc
index 5e56eb4b..4c5a065c 100644
--- a/exercises/exercise-grids/exercise_grids.cc
+++ b/exercises/exercise-grids/exercise_grids.cc
@@ -41,10 +41,11 @@
 #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>
+#include <dumux/io/loadsolution.hh>
 
 // The problem file, where setup-specific boundary and initial conditions are defined.
 #include "injection2pproblem.hh"
@@ -57,7 +58,7 @@ int main(int argc, char** argv) try
     using namespace Dumux;
 
     // define the type tag for this problem
-    using TypeTag = TTAG(Injection2pCCTypeTag);
+    using TypeTag = Properties::TTag::Injection2pCCTypeTag;
 
     // initialize MPI, finalize is done automatically on exit
     const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
@@ -70,7 +71,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();
 
     ////////////////////////////////////////////////////////////
@@ -81,37 +82,55 @@ 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);
 
+    // check if we are about to restart a previously interrupted simulation
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
+    Scalar restartTime = getParam<Scalar>("Restart.Time", 0);
+
     // the solution vector
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
     SolutionVector x(fvGridGeometry->numDofs());
-    problem->applyInitialSolution(x);
+    if (restartTime > 0)
+    {
+        using IOFields = GetPropType<TypeTag, Properties::IOFields>;
+        using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
+        using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
+        using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
+        const auto fileName = getParam<std::string>("Restart.File");
+        const auto pvName = createPVNameFunction<IOFields, PrimaryVariables, ModelTraits, FluidSystem>();
+        loadSolution(x, fileName, pvName, *fvGridGeometry);
+    }
+    else
+        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
     // getParam<TYPE>("GROUPNAME.PARAMNAME") reads and sets parameter PARAMNAME
     // of type TYPE given in the group GROUPNAME from the input file
-    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
+    vtkWriter.write(restartTime);
 
     // instantiate time loop
     auto timeLoop = std::make_shared<TimeLoop<Scalar>>(0.0, dt, tEnd);
diff --git a/exercises/exercise-grids/injection2pproblem.hh b/exercises/exercise-grids/injection2pproblem.hh
index ab11ae93..0b9e4308 100644
--- a/exercises/exercise-grids/injection2pproblem.hh
+++ b/exercises/exercise-grids/injection2pproblem.hh
@@ -40,25 +40,31 @@ class InjectionProblem2P;
 
 namespace Properties {
 // define the TypeTag for this problem with a cell-centered two-point flux approximation spatial discretization.
-NEW_TYPE_TAG(Injection2pTypeTag, INHERITS_FROM(TwoP));
-NEW_TYPE_TAG(Injection2pCCTypeTag, INHERITS_FROM(CCTpfaModel, Injection2pTypeTag));
+// Create new type tags
+namespace TTag {
+struct Injection2pTypeTag { using InheritsFrom = std::tuple<TwoP>; };
+struct Injection2pCCTypeTag { using InheritsFrom = std::tuple<Injection2pTypeTag, CCTpfaModel>; };
+} // end namespace TTag
 
 // Set the grid type
-SET_TYPE_PROP(Injection2pTypeTag, Grid, Dune::YaspGrid<2>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::Injection2pTypeTag> { using type = Dune::YaspGrid<2>; };
 // TODO: Task 2: Replace the above Grid Property definition with a more flexible grid (Use Dune::TensorProductCoordinates)
 // TODO: Task 4: Replace the above Grid Property definition to read in a external structured grid via a .msh file (Use Dune::ALUGrid and Dune:cube)
 // TODO: Task 5: Replace the above Grid Property definition to read in a external unstructured grid via a .msh file (Use Dune::ALUGrid and Dune::simplex)
 
 // Set the problem property
-SET_TYPE_PROP(Injection2pTypeTag, Problem, InjectionProblem2P<TypeTag>);
+template<class TypeTag>
+struct Problem<TypeTag, TTag::Injection2pTypeTag> { using type = InjectionProblem2P<TypeTag>; };
 
 // Set the spatial parameters
 SET_TYPE_PROP(Injection2pTypeTag, SpatialParams,
-              InjectionSpatialParams<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
-                                     typename GET_PROP_TYPE(TypeTag, Scalar)>);
+              InjectionSpatialParams<GetPropType<TypeTag, Properties::FVGridGeometry>,
+                                     GetPropType<TypeTag, Properties::Scalar>>);
 
 // Set fluid configuration
-SET_TYPE_PROP(Injection2pTypeTag, FluidSystem, FluidSystems::H2ON2<typename GET_PROP_TYPE(TypeTag, Scalar), FluidSystems::H2ON2DefaultPolicy</*fastButSimplifiedRelations=*/ true>>);
+template<class TypeTag>
+struct FluidSystem<TypeTag, TTag::Injection2pTypeTag> { using type = FluidSystems::H2ON2<GetPropType<TypeTag, Properties::Scalar>, FluidSystems::H2ON2DefaultPolicy</*fastButSimplifiedRelations=*/ true>>; };
 } // end namespace Properties
 
 /*!
@@ -86,14 +92,14 @@ template<class TypeTag>
 class InjectionProblem2P : public PorousMediumFlowProblem<TypeTag>
 {
     using ParentType = PorousMediumFlowProblem<TypeTag>;
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    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 GridView = GetPropType<TypeTag, Properties::GridView>;
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
+    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>;
 
     enum { dimWorld = GridView::dimensionworld };
     using Element = typename GridView::template Codim<0>::Entity;
diff --git a/exercises/solution/exercise-grids/exercise_grids_solution.cc b/exercises/solution/exercise-grids/exercise_grids_solution.cc
index 9da491d6..6a907538 100644
--- a/exercises/solution/exercise-grids/exercise_grids_solution.cc
+++ b/exercises/solution/exercise-grids/exercise_grids_solution.cc
@@ -41,10 +41,11 @@
 #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>
+#include <dumux/io/loadsolution.hh>
 
 // The problem file, where setup-specific boundary and initial conditions are defined.
 #include "injection2pproblem.hh"
@@ -57,7 +58,7 @@ int main(int argc, char** argv) try
     using namespace Dumux;
 
     // define the type tag for this problem
-    using TypeTag = TTAG(Injection2pCCTypeTag);
+    using TypeTag = Properties::TTag::Injection2pCCTypeTag;
 
     // initialize MPI, finalize is done automatically on exit
     const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
@@ -70,7 +71,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();
 
     ////////////////////////////////////////////////////////////
@@ -81,37 +82,55 @@ 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);
 
+    // check if we are about to restart a previously interrupted simulation
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
+    Scalar restartTime = getParam<Scalar>("Restart.Time", 0);
+
     // the solution vector
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
     SolutionVector x(fvGridGeometry->numDofs());
-    problem->applyInitialSolution(x);
+    if (restartTime > 0)
+    {
+        using IOFields = GetPropType<TypeTag, Properties::IOFields>;
+        using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
+        using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
+        using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
+        const auto fileName = getParam<std::string>("Restart.File");
+        const auto pvName = createPVNameFunction<IOFields, PrimaryVariables, ModelTraits, FluidSystem>();
+        loadSolution(x, fileName, pvName, *fvGridGeometry);
+    }
+    else
+        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
     // getParam<TYPE>("GROUPNAME.PARAMNAME") reads and sets parameter PARAMNAME
     // of type TYPE given in the group GROUPNAME from the input file
-    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
+    vtkWriter.write(restartTime);
 
     // instantiate time loop
     auto timeLoop = std::make_shared<TimeLoop<Scalar>>(0.0, dt, tEnd);
diff --git a/exercises/solution/exercise-grids/injection2pproblem.hh b/exercises/solution/exercise-grids/injection2pproblem.hh
index 0ac137c4..616105a0 100644
--- a/exercises/solution/exercise-grids/injection2pproblem.hh
+++ b/exercises/solution/exercise-grids/injection2pproblem.hh
@@ -40,30 +40,39 @@ class InjectionProblem2P;
 
 namespace Properties {
 // define the TypeTag for this problem with a cell-centered two-point flux approximation spatial discretization.
-NEW_TYPE_TAG(Injection2pTypeTag, INHERITS_FROM(TwoP));
-NEW_TYPE_TAG(Injection2pCCTypeTag, INHERITS_FROM(CCTpfaModel, Injection2pTypeTag));
+// Create new type tags
+namespace TTag {
+struct Injection2pTypeTag { using InheritsFrom = std::tuple<TwoP>; };
+struct Injection2pCCTypeTag { using InheritsFrom = std::tuple<Injection2pTypeTag, CCTpfaModel>; };
+} // end namespace TTag
 
-// Set the grid type
-SET_TYPE_PROP(Injection2pTypeTag, Grid, Dune::YaspGrid<2>);
+//Set the grid type
+template<class TypeTag>
+struct Grid<TypeTag, TTag::Injection2pTypeTag> { using type = Dune::YaspGrid<2>; };
 // TODO: Task 2: Replace the above Grid Property definition with a more flexible grid (Use Dune::TensorProductCoordinates)
-//SET_TYPE_PROP(Injection2pTypeTag, Grid, Dune::YaspGrid<2, Dune::TensorProductCoordinates<double, 2> >);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::Injection2pTypeTag> { using type = Dune::YaspGrid<2, Dune::TensorProductCoordinates<double, 2> >; };
 
 // TODO: Task 4: Replace the above Grid Property definition to read in a external structured grid via a .msh file (Use Dune::ALUGrid and Dune:cube)
-//SET_TYPE_PROP(Injection2pTypeTag, Grid, Dune::ALUGrid<2, 2, Dune::cube, Dune::nonconforming>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::Injection2pTypeTag> { using type = Dune::ALUGrid<2, 2, Dune::cube, Dune::nonconforming>; };
 
 // TODO: Task 5: Replace the above Grid Property definition to read in a external unstructured grid via a .msh file (Use Dune::ALUGrid and Dune::simplex)
-// SET_TYPE_PROP(Injection2pTypeTag, Grid, Dune::ALUGrid<2, 2, Dune::simplex, Dune::nonconforming>);
+template<class TypeTag>
+struct Grid<TypeTag, TTag::Injection2pTypeTag> { using type = Dune::ALUGrid<2, 2, Dune::simplex, Dune::nonconforming>; };
 
 // Set the problem property
-SET_TYPE_PROP(Injection2pTypeTag, Problem, InjectionProblem2P<TypeTag>);
+template<class TypeTag>
+struct Problem<TypeTag, TTag::Injection2pTypeTag> { using type = InjectionProblem2P<TypeTag>; };
 
 // Set the spatial parameters
 SET_TYPE_PROP(Injection2pTypeTag, SpatialParams,
-              InjectionSpatialParams<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
-                                     typename GET_PROP_TYPE(TypeTag, Scalar)>);
+              InjectionSpatialParams<GetPropType<TypeTag, Properties::FVGridGeometry>,
+                                     GetPropType<TypeTag, Properties::Scalar>>);
 
 // Set fluid configuration
-SET_TYPE_PROP(Injection2pTypeTag, FluidSystem, FluidSystems::H2ON2<typename GET_PROP_TYPE(TypeTag, Scalar), FluidSystems::H2ON2DefaultPolicy</*fastButSimplifiedRelations=*/ true>>);
+template<class TypeTag>
+struct FluidSystem<TypeTag, TTag::Injection2pTypeTag> { using type = FluidSystems::H2ON2<GetPropType<TypeTag, Properties::Scalar>, FluidSystems::H2ON2DefaultPolicy</*fastButSimplifiedRelations=*/ true>>; };
 } // end namespace Properties
 
 /*!
@@ -91,14 +100,14 @@ template<class TypeTag>
 class InjectionProblem2P : public PorousMediumFlowProblem<TypeTag>
 {
     using ParentType = PorousMediumFlowProblem<TypeTag>;
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    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 GridView = GetPropType<TypeTag, Properties::GridView>;
+    using Scalar = GetPropType<TypeTag, Properties::Scalar>;
+    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>;
 
     enum { dimWorld = GridView::dimensionworld };
     using Element = typename GridView::template Codim<0>::Entity;
-- 
GitLab