From bab05a4be9be70be072478cd3e5e7f55a6c9b2fe Mon Sep 17 00:00:00 2001
From: DennisGlaeser <dennis.glaeser@iws.uni-stuttgart.de>
Date: Thu, 5 Jan 2017 13:00:21 +0100
Subject: [PATCH] [spatialParams] further changes to spatial params interface

- The laws store a pointer to the spatial parameters instead of an initial field (more user-friendly).
- The permeability type has to be stated publicly in the spatial parameters
---
 dumux/discretization/volumevariables.hh       |  4 --
 .../permeabilitykozenycarman.hh               | 27 ++++-----
 .../porosityprecipitation.hh                  | 19 +++---
 .../2pnc/implicit/volumevariables.hh          |  3 +-
 .../2pncmin/implicit/dissolutionproblem.hh    |  2 +-
 .../implicit/dissolutionspatialparams.hh      | 60 +++++++++++--------
 6 files changed, 57 insertions(+), 58 deletions(-)

diff --git a/dumux/discretization/volumevariables.hh b/dumux/discretization/volumevariables.hh
index 8101de1844..529ca06342 100644
--- a/dumux/discretization/volumevariables.hh
+++ b/dumux/discretization/volumevariables.hh
@@ -70,10 +70,6 @@ class ImplicitVolumeVariablesImplementation<TypeTag, false>
 
 public:
 
-    using PermeabilityType = decltype(std::declval<SpatialParams>().permeability(Element(),
-                                                                                 SubControlVolume(),
-                                                                                 ElementSolutionVector()));
-
     /*!
      * \brief Update all quantities for a given control volume
      *
diff --git a/dumux/material/fluidmatrixinteractions/permeabilitykozenycarman.hh b/dumux/material/fluidmatrixinteractions/permeabilitykozenycarman.hh
index 3535db72e7..1d9363067a 100644
--- a/dumux/material/fluidmatrixinteractions/permeabilitykozenycarman.hh
+++ b/dumux/material/fluidmatrixinteractions/permeabilitykozenycarman.hh
@@ -36,12 +36,13 @@ namespace Dumux
  *        When the porosity is implemented as solution-independent, using this relationship for the
  *        permeability leads to unnecessary overhead.
  */
-template<class TypeTag, class PermType>
+template<class TypeTag>
 class PermeabilityKozenyCarman
 {
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using SpatialParams = typename GET_PROP_TYPE(TypeTag, SpatialParams);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
     using ElementSolution = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector);
@@ -51,18 +52,14 @@ class PermeabilityKozenyCarman
     using Element = typename GridView::template Codim<0>::Entity;
     using Tensor = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
 
-    using InitPoroField = std::function<Scalar(const Element&, const SubControlVolume&)>;
-    using InitPermField = std::function<PermType(const Element&, const SubControlVolume&)>;
+    using PermType = typename SpatialParams::PermeabilityType;
 
 public:
-    PermeabilityKozenyCarman(const Problem& problem) : problemPtr_(&problem) {}
 
     // the initial parameter distribution
-    void init(InitPoroField&& poro,
-              InitPermField&& perm)
+    void init(const SpatialParams& spatialParams)
     {
-        initPoro_ = poro;
-        initPerm_ = perm;
+        spatialParamsPtr_ = &spatialParams;
     }
 
     // calculate permeability for a given scv
@@ -70,15 +67,15 @@ public:
                                   const SubControlVolume& scv,
                                   const ElementSolution& elemSol) const
     {
-        auto initPoro = initPoro_(element, scv);
-        auto poro = problem_().spatialParams().porosity(element, scv, elemSol);
+        auto initPoro = spatialParams().initialPorosity(element, scv);
+        auto poro = spatialParams().porosity(element, scv, elemSol);
         auto factor = std::pow((1.0 - initPoro)/(1.0 - poro), 2) * std::pow(poro/initPoro, 3);
-        return applyFactorToPermeability_(initPerm_(element, scv), factor);
+        return applyFactorToPermeability_(spatialParams().initialPermeability(element, scv), factor);
     }
 
 private:
-    const Problem& problem_() const
-    {return *problemPtr_; }
+    const SpatialParams& spatialParams() const
+    { return *spatialParamsPtr_; }
 
     Scalar applyFactorToPermeability_(Scalar k, Scalar factor) const
     { return k*factor; }
@@ -91,9 +88,7 @@ private:
         return result;
     }
 
-    const Problem* problemPtr_;
-    InitPoroField initPoro_;
-    InitPermField initPerm_;
+    const SpatialParams* spatialParamsPtr_;
 };
 
 } // namespace Dumux
diff --git a/dumux/material/fluidmatrixinteractions/porosityprecipitation.hh b/dumux/material/fluidmatrixinteractions/porosityprecipitation.hh
index 7ea4762bbb..d863efaa87 100644
--- a/dumux/material/fluidmatrixinteractions/porosityprecipitation.hh
+++ b/dumux/material/fluidmatrixinteractions/porosityprecipitation.hh
@@ -42,6 +42,7 @@ class PorosityPrecipitation
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using SpatialParams = typename GET_PROP_TYPE(TypeTag, SpatialParams);
     using ElementSolution = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector);
     using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
     using ScvOperator = SubControlVolumeOperator<TypeTag>;
@@ -52,16 +53,11 @@ class PorosityPrecipitation
     static const int numSolidPhases = GET_PROP_VALUE(TypeTag, NumSPhases);
 
     using Element = typename GridView::template Codim<0>:: Entity;
-    using Tensor = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
-
-    using InitPoroField = std::function<Scalar(const Element&, const SubControlVolume&)>;
 
 public:
-    void init(InitPoroField&& initPoro,
-              InitPoroField&& minPoro)
+    void init(const SpatialParams& spatialParams)
     {
-        initPoro_ = initPoro;
-        minPoro_ = minPoro;
+        spatialParamsPtr_ = &spatialParams;
     }
 
     // calculates the porosity in a sub-control volume
@@ -75,12 +71,15 @@ public:
         for (unsigned int solidPhaseIdx = 0; solidPhaseIdx < numSolidPhases; ++solidPhaseIdx)
             sumPrecipitates += priVars[numComponents + solidPhaseIdx];
 
-        return std::max(minPoro_(element, scv), initPoro_(element, scv) - sumPrecipitates);
+        auto minPoro = spatialParams_().minPorosity(element, scv);
+        return std::max(minPoro, minPoro - sumPrecipitates);
     }
 
 private:
-    InitPoroField initPoro_;
-    InitPoroField minPoro_;
+    const SpatialParams& spatialParams_() const
+    { return *spatialParamsPtr_; }
+
+    const SpatialParams* spatialParamsPtr_;
 };
 
 } // namespace Dumux
diff --git a/dumux/porousmediumflow/2pnc/implicit/volumevariables.hh b/dumux/porousmediumflow/2pnc/implicit/volumevariables.hh
index 0205ee47e4..b137257bc3 100644
--- a/dumux/porousmediumflow/2pnc/implicit/volumevariables.hh
+++ b/dumux/porousmediumflow/2pnc/implicit/volumevariables.hh
@@ -55,6 +55,7 @@ class TwoPNCVolumeVariables : public ImplicitVolumeVariables<TypeTag>
     using Grid = typename GET_PROP_TYPE(TypeTag, Grid);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using SpatialParams = typename GET_PROP_TYPE(TypeTag, SpatialParams);
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
     using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
     using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector);
@@ -107,7 +108,7 @@ class TwoPNCVolumeVariables : public ImplicitVolumeVariables<TypeTag>
 public:
 
     using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState);
-    using typename ParentType::PermeabilityType;
+    using PermeabilityType = typename SpatialParams::PermeabilityType;
 
     /*!
      * \copydoc ImplicitVolumeVariables::update
diff --git a/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh b/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh
index d4442559b3..4d626bc179 100644
--- a/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh
+++ b/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh
@@ -353,7 +353,7 @@ public:
         Scalar massFracNaCl_Max_lPhase = this->spatialParams().solubilityLimit();
         Scalar moleFracNaCl_Max_lPhase = massToMoleFrac_(massFracNaCl_Max_lPhase);
         Scalar moleFracNaCl_Max_gPhase = moleFracNaCl_Max_lPhase / volVars.pressure(nPhaseIdx);
-        Scalar saltPorosity = this->spatialParams().porosityMin(element, scv);
+        Scalar saltPorosity = this->spatialParams().minPorosity(element, scv);
 
         // liquid phase
         Scalar precipSalt = volVars.porosity() * volVars.molarDensity(wPhaseIdx)
diff --git a/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh b/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh
index c1972aab7d..3aed233fbe 100644
--- a/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh
+++ b/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh
@@ -88,12 +88,14 @@ class DissolutionSpatialparams : public ImplicitSpatialParams<TypeTag>
     using Element = typename GridView::template Codim<0>::Entity;
 
     using PorosityLaw = PorosityPrecipitation<TypeTag>;
-    using PermeabilityLaw = PermeabilityKozenyCarman<TypeTag, Scalar>;
+    using PermeabilityLaw = PermeabilityKozenyCarman<TypeTag>;
 
 public:
+    // type used for the permeability (i.e. tensor or scalar)
+    using PermeabilityType = Scalar;
+
     DissolutionSpatialparams(const Problem& problem, const GridView &gridView)
-    : ParentType(problem, gridView),
-      permLaw_(problem)
+    : ParentType(problem, gridView)
     {
         // residual saturations
         materialParams_.setSwr(0.2);
@@ -109,24 +111,16 @@ public:
      */
     void init()
     {
-        using namespace std::placeholders;
-        using InitParamFunction = std::function<Scalar(const Element&, const SubControlVolume&)>;
-
-        InitParamFunction minPoro = std::bind(&ThisType::porosityMin, this, _1, _2);
-        InitParamFunction initPoro = [](const Element&, const SubControlVolume&) { return 0.11; };
-        InitParamFunction initPerm = [](const Element&, const SubControlVolume&) { return 2.23e-14; };
-
-        poroLaw_.init(std::move(initPoro), std::move(minPoro));
-        initPoro = [](const Element&, const SubControlVolume&) { return 0.11; };
-        permLaw_.init(std::move(initPoro), std::move(initPerm));
+        //! Intitialize the parameter laws
+        poroLaw_.init(*this);
+        permLaw_.init(*this);
     }
 
     /*! Intrinsic permeability tensor K \f$[m^2]\f$ depending
      *  on the position in the domain
      *
      *  \param element The finite volume element
-     *  \param fvGeometry The finite-volume geometry in the box scheme
-     *  \param scvIdx The local vertex index
+     *  \param scv The sub-control volume
      *
      *  Solution dependent permeability function
      */
@@ -136,23 +130,37 @@ public:
     { return permLaw_.evaluatePermeability(element, scv, elemSol); }
 
     /*!
-     * \brief Define the minimum porosity \f$[-]\f$ after salt precipitation
+     *  \brief Define the minimum porosity \f$[-]\f$ distribution
      *
-     * \param element The finite element
-     * \param fvGeometry The finite volume geometry
-     * \param scvIdx The local index of the sub-control volume where
-     *                    the porosity needs to be defined
+     *  \param element The finite element
+     *  \param scv The sub-control volume
      */
-    Scalar porosityMin(const Element& element, const SubControlVolume &scv) const
+    Scalar minPorosity(const Element& element, const SubControlVolume &scv) const
     { return 1e-5; }
 
     /*!
-     * \brief Define the minimum porosity \f$[-]\f$ after clogging caused by mineralization
+     *  \brief Define the initial porosity \f$[-]\f$ distribution
+     *
+     *  \param element The finite element
+     *  \param scv The sub-control volume
+     */
+    Scalar initialPorosity(const Element& element, const SubControlVolume &scv) const
+    { return 0.11; }
+
+    /*!
+     *  \brief Define the initial permeability \f$[m^2]\f$ distribution
+     *
+     *  \param element The finite element
+     *  \param scv The sub-control volume
+     */
+    Scalar initialPermeability(const Element& element, const SubControlVolume &scv) const
+    { return 2.23e-14; }
+
+    /*!
+     *  \brief Define the minimum porosity \f$[-]\f$ after clogging caused by mineralization
      *
-     * \param element The finite element
-     * \param fvGeometry The finite volume geometry
-     * \param scvIdx The local index of the sub-control volume where
-     *                    the porosity needs to be defined
+     *  \param element The finite element
+     *  \param scv The sub-control volume
      */
     Scalar porosity(const Element& element,
                     const SubControlVolume& scv,
-- 
GitLab