From 5f3b6fdd088a812f8e224eefe474f0a05709378e Mon Sep 17 00:00:00 2001
From: Gabriele Seitz <gabriele.seitz@iws.uni-stuttgart.de>
Date: Fri, 23 Jun 2017 17:12:13 +0200
Subject: [PATCH] [1pncmin] add model to next

not yet working
---
 dumux/porousmediumflow/1pncmin/CMakeLists.txt |   1 +
 .../1pncmin/implicit/CMakeLists.txt           |  10 +
 .../1pncmin/implicit/indices.hh               |  48 ++
 .../1pncmin/implicit/localresidual.hh         | 115 +++++
 .../1pncmin/implicit/model.hh                 | 478 ++++++++++++++++++
 .../1pncmin/implicit/properties.hh            |  69 +++
 .../1pncmin/implicit/propertydefaults.hh      | 180 +++++++
 .../1pncmin/implicit/volumevariables.hh       | 390 ++++++++++++++
 dumux/porousmediumflow/CMakeLists.txt         |   1 +
 9 files changed, 1292 insertions(+)
 create mode 100644 dumux/porousmediumflow/1pncmin/CMakeLists.txt
 create mode 100644 dumux/porousmediumflow/1pncmin/implicit/CMakeLists.txt
 create mode 100644 dumux/porousmediumflow/1pncmin/implicit/indices.hh
 create mode 100644 dumux/porousmediumflow/1pncmin/implicit/localresidual.hh
 create mode 100644 dumux/porousmediumflow/1pncmin/implicit/model.hh
 create mode 100644 dumux/porousmediumflow/1pncmin/implicit/properties.hh
 create mode 100644 dumux/porousmediumflow/1pncmin/implicit/propertydefaults.hh
 create mode 100644 dumux/porousmediumflow/1pncmin/implicit/volumevariables.hh

diff --git a/dumux/porousmediumflow/1pncmin/CMakeLists.txt b/dumux/porousmediumflow/1pncmin/CMakeLists.txt
new file mode 100644
index 0000000000..ba8341c614
--- /dev/null
+++ b/dumux/porousmediumflow/1pncmin/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory("implicit")
diff --git a/dumux/porousmediumflow/1pncmin/implicit/CMakeLists.txt b/dumux/porousmediumflow/1pncmin/implicit/CMakeLists.txt
new file mode 100644
index 0000000000..92b891fb7b
--- /dev/null
+++ b/dumux/porousmediumflow/1pncmin/implicit/CMakeLists.txt
@@ -0,0 +1,10 @@
+
+#install headers
+install(FILES
+indices.hh
+localresidual.hh
+model.hh
+properties.hh
+propertydefaults.hh
+volumevariables.hh
+DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/porousmediumflow/1pncmin/implicit)
diff --git a/dumux/porousmediumflow/1pncmin/implicit/indices.hh b/dumux/porousmediumflow/1pncmin/implicit/indices.hh
new file mode 100644
index 0000000000..4c5a2085c1
--- /dev/null
+++ b/dumux/porousmediumflow/1pncmin/implicit/indices.hh
@@ -0,0 +1,48 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+
+/*!
+ * \file
+ * \brief Defines the indices required for the one-phase n-component mineralization
+ *        fully implicit model.
+ */
+#ifndef DUMUX_1PNCMIN_INDICES_HH
+#define DUMUX_1PNCMIN_INDICES_HH
+
+#include <dumux/porousmediumflow/1pnc/implicit/indices.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup OnePNCMinModel
+ * \ingroup ImplicitIndices
+ * \brief The indices for the isothermal one-phase n-component mineralization model.
+ *
+ * \tparam PVOffset The first index in a primary variable vector.
+ */
+template <class TypeTag, int PVOffset = 0>
+    class OnePNCMinIndices: public OnePNCIndices<TypeTag, PVOffset>
+{
+};
+
+// \}
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/1pncmin/implicit/localresidual.hh b/dumux/porousmediumflow/1pncmin/implicit/localresidual.hh
new file mode 100644
index 0000000000..0a9cdae818
--- /dev/null
+++ b/dumux/porousmediumflow/1pncmin/implicit/localresidual.hh
@@ -0,0 +1,115 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the one-phase n-component mineralisation box model.
+ */
+
+#ifndef DUMUX_1PNCMIN_LOCAL_RESIDUAL_BASE_HH
+#define DUMUX_1PNCMIN_LOCAL_RESIDUAL_BASE_HH
+
+#include "properties.hh"
+#include <dumux/porousmediumflow/compositional/localresidual.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup OnePNCMinModel
+ * \ingroup ImplicitLocalResidual
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the one-phase n-component mineralization fully implicit model.
+ *
+ * This class is used to fill the gaps in ImplicitLocalResidual for the one-phase n-component flow.
+ */
+template<class TypeTag>
+class OnePNCMinLocalResidual: public OnePNCLocalResidual<TypeTag>
+{
+protected:
+//     typedef OnePNCLocalResidual<TypeTag> ParentType;
+    using ParentType = CompositionalLocalResidual<TypeTag>;
+    using ThisType = TwoPNCMinLocalResidual<TypeTag>;
+    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
+    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
+
+    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables)
+//     typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+//     typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+//     typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+//     typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+//     typedef typename GET_PROP_TYPE(TypeTag, ElementSolutionVector) ElementSolutionVector;
+//     typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
+//     typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
+
+
+    enum
+    {
+        numEq = GET_PROP_VALUE(TypeTag, NumEq),
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numSPhases = GET_PROP_VALUE(TypeTag, NumSPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+
+        pressureIdx = Indices::pressureIdx,
+        firstMoleFracIdx = Indices::firstMoleFracIdx,
+
+        phaseIdx = Indices::phaseIdx,
+        sPhaseIdx = 1, // don't use the sPhaseIdx of the fluidsystem
+
+        conti0EqIdx = Indices::conti0EqIdx,
+    };
+
+//     typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+//     typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
+//     typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+//     typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+
+public:
+    /*!
+     * \brief Evaluate the amount all conservation quantities
+     *        (e.g. phase mass) within a sub-control volume.
+     *
+     * The result should be averaged over the volume (e.g. phase mass
+     * inside a sub control volume divided by the volume).
+     * In contrast to the 1pnc model, here, the storage of solid phases is included too.
+     *
+     *  \param scv the SCV (sub-control-volume)
+     *  \param volVars The volume variables of the right time step
+     */
+    PrimaryVariables computeStorage(const SubControlVolume& scv,
+                                    const VolumeVariables& volVars) const
+    {
+        //call parenttype function
+        auto storage = ParentType::computeStorage(scv, volVars);
+
+        // Compute storage term of all solid (precipitated) phases (excluding the non-reactive matrix)
+         for (int Idx = sPhaseIdx; Idx < numPhases + numSPhases; ++Idx)
+        {
+            auto eqIdx = conti0EqIdx + numComponents-numPhases + Idx;
+            storage[eqIdx] += volVars.precipitateVolumeFraction(Idx)*volVars.molarDensity(Idx);
+        }
+
+        return storage;
+    }
+};
+
+} // end namespace Dumux
+
+#endif
diff --git a/dumux/porousmediumflow/1pncmin/implicit/model.hh b/dumux/porousmediumflow/1pncmin/implicit/model.hh
new file mode 100644
index 0000000000..419fbec093
--- /dev/null
+++ b/dumux/porousmediumflow/1pncmin/implicit/model.hh
@@ -0,0 +1,478 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+* \file
+*
+* \brief Adaption of the fully implicit box scheme to the two-phase n-component flow model.
+*/
+
+#ifndef DUMUX_1PNCMIN_MODEL_HH
+#define DUMUX_1PNCMIN_MODEL_HH
+
+#include "properties.hh"
+#include "indices.hh"
+#include "localresidual.hh"
+
+// #include <dumux/material/constants.hh>
+#include <dumux/porousmediumflow/1pnc/implicit/model.hh>
+#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup OnePNCMinModel
+ * \brief Adaption of the fully implicit scheme to the
+ *        two-phase n-component fully implicit model with additional solid/mineral phases.
+ *
+ * This model implements two-phase n-component flow of two compressible and
+ * partially miscible fluids \f$\alpha \in \{ w, n \}\f$ composed of the n components
+ * \f$\kappa \in \{ w, n,\cdots \}\f$ in combination with mineral precipitation and dissolution.
+ * The solid phases. The standard multiphase Darcy
+ * approach is used as the equation for the conservation of momentum:
+ * \f[
+ v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K}
+ \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right)
+ * \f]
+ *
+ * By inserting this into the equations for the conservation of the
+ * components, one gets one transport equation for each component
+ * \f{eqnarray}
+ && \frac{\partial (\sum_\alpha \varrho_\alpha X_\alpha^\kappa \phi S_\alpha )}
+ {\partial t}
+ - \sum_\alpha  \text{div} \left\{ \varrho_\alpha X_\alpha^\kappa
+ \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K}
+ (\text{grad}\, p_\alpha - \varrho_{\alpha}  \mbox{\bf g}) \right\}
+ \nonumber \\ \nonumber \\
+    &-& \sum_\alpha \text{div} \left\{{\bf D_{\alpha, pm}^\kappa} \varrho_{\alpha} \text{grad}\, X^\kappa_{\alpha} \right\}
+ - \sum_\alpha q_\alpha^\kappa = 0 \qquad \kappa \in \{w, a,\cdots \} \, ,
+ \alpha \in \{w, g\}
+ \f}
+ *
+ * The solid or mineral phases are assumed to consist of a single component.
+ * Their mass balance consist only of a storage and a source term:
+ *  \f$\frac{\partial \varrho_\lambda \phi_\lambda )} {\partial t}
+ *  = q_\lambda\f$
+ *
+ * All equations are discretized using a vertex-centered finite volume (box)
+ * or cell-centered finite volume scheme (this is not done for 2pnc approach yet, however possible) as
+ * spatial and the implicit Euler method as time discretization.
+ *
+ * By using constitutive relations for the capillary pressure \f$p_c =
+ * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking
+ * advantage of the fact that \f$S_w + S_n = 1\f$ and \f$X^\kappa_w + X^\kappa_n = 1\f$, the number of
+ * unknowns can be reduced to number of components.
+ *
+ * The used primary variables are, like in the two-phase model, either \f$p_w\f$ and \f$S_n\f$
+ * or \f$p_n\f$ and \f$S_w\f$. The formulation which ought to be used can be
+ * specified by setting the <tt>Formulation</tt> property to either
+ * TwoPTwoCIndices::pWsN or TwoPTwoCIndices::pNsW. By
+ * default, the model uses \f$p_w\f$ and \f$S_n\f$.
+ *
+ * Moreover, the second primary variable depends on the phase state, since a
+ * primary variable switch is included. The phase state is stored for all nodes
+ * of the system. The model is uses mole fractions.
+ *Following cases can be distinguished:
+ * <ul>
+ *  <li> Both phases are present: The saturation is used (either \f$S_n\f$ or \f$S_w\f$, dependent on the chosen <tt>Formulation</tt>),
+ *      as long as \f$ 0 < S_\alpha < 1\f$</li>.
+ *  <li> Only wetting phase is present: The mole fraction of, e.g., air in the wetting phase \f$x^a_w\f$ is used,
+ *      as long as the maximum mole fraction is not exceeded (\f$x^a_w<x^a_{w,max}\f$)</li>
+ *  <li> Only non-wetting phase is present: The mole fraction of, e.g., water in the non-wetting phase, \f$x^w_n\f$, is used,
+ *      as long as the maximum mole fraction is not exceeded (\f$x^w_n<x^w_{n,max}\f$)</li>
+ * </ul>
+ *
+ * For the other components, the mole fraction \f$x^\kappa_w\f$ is the primary variable.
+ * The primary variable of the solid phases is the volume fraction \f$\phi_\lambda = \frac{V_\lambda}{V_{total}}\f$.
+ *
+ * The source an sink terms link the mass balances of the n-transported component to the solid phases.
+ * The porosity \f$\phi\f$ is updated according to the reduction of the initial (or solid-phase-free porous medium) porosity \f$\phi_0\f$
+ * by the accumulated volume fractions of the solid phases:
+ * \f$ \phi = \phi_0 - \sum (\phi_\lambda)\f$
+ * Additionally, the permeability is updated depending on the current porosity.
+ */
+
+template<class TypeTag>
+class OnePNCMinModel: public OnePNCModel<TypeTag>
+{
+    typedef Dumux::OnePNCMinModel<TypeTag> ThisType;
+    typedef Dumux::OnePNCModel<TypeTag> ParentType;
+
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+
+    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
+    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
+
+    //old
+//     typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+//     typedef Dumux::Constants<Scalar> Constant;
+//     typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+
+    using Element = typename GridView::template Codim<0>::Entity;
+    using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
+    using CoordScalar = typename GridView::ctype;
+    using Tensor = Dune::FieldMatrix<CoordScalar, dimWorld, dimWorld>;
+
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld,
+
+        numEq = GET_PROP_VALUE(TypeTag, NumEq),
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numSPhases = GET_PROP_VALUE(TypeTag, NumSPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+        numSComponents = FluidSystem::numSComponents,
+
+        pressureIdx = Indices::pressureIdx,
+        firstMoleFracIdx = Indices::firstMoleFracIdx,
+
+        phaseIdx = Indices::phaseIdx,
+    };
+
+    //old
+//     typedef typename GridView::template Codim<dim>::Entity Vertex;
+//     typedef Dune::FieldVector<Scalar, numPhases> PhasesVector;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+public:
+
+    /*!
+     * \brief Apply the initial conditions to the model.
+     *
+     * \param problem The object representing the problem which needs to
+     *             be simulated.
+     */
+    void init(Problem& problem)
+    {
+        ParentType::init(problem);
+
+       // register standardized vtk output fields
+        auto& vtkOutputModule = problem.vtkOutputModule();
+        vtkOutputModule.addSecondaryVariable("p", [](const VolumeVariables& v){ return v.pressure(phaseIdx); });
+        vtkOutputModule.addSecondaryVariable("pw", [](const VolumeVariables& v){ return v.pressure(phaseIdx); });
+        vtkOutputModule.addSecondaryVariable("rho", [](const VolumeVariables& v){ return v.density(phaseIdx); });
+        vtkOutputModule.addSecondaryVariable("porosity", [](const VolumeVariables& v){ return v.porosity(); });
+        vtkOutputModule.addSecondaryVariable("permeabilityFactor", [](const VolumeVariables& v){ return v.permeabilityFactor(); });
+
+        vtkOutputModule.addSecondaryVariable("temperature", [](const VolumeVariables& v){ return v.temperature(); });
+
+        for (int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
+            vtkOutputModule.addSecondaryVariable("precipitateVolumeFraction_" + FluidSystem::phaseName(numPhases + sPhaseIdx),
+                                                 [sPhaseIdx](const VolumeVariables& v)
+                                                 { return v.precipitateVolumeFraction(numPhases + sPhaseIdx); });
+
+        vtkOutputModule.addSecondaryVariable("Kxx",
+                                             [this](const VolumeVariables& v){ return this->perm_(v.permeability())[0][0]; });
+        if (dim >= 2)
+            vtkOutputModule.addSecondaryVariable("Kyy",
+                                                 [this](const VolumeVariables& v){ return this->perm_(v.permeability())[1][1]; });
+        if (dim >= 3)
+            vtkOutputModule.addSecondaryVariable("Kzz",
+                                                 [this](const VolumeVariables& v){ return this->perm_(v.permeability())[2][2]; });
+
+        for (int i = 0; i < numComponents; ++i)
+                vtkOutputModule.addSecondaryVariable("x_" + FluidSystem::componentName(i),[i](const VolumeVariables& v){ return     v.moleFraction(phaseIdx,i); });
+
+        for (int i = 0; i < numComponents; ++i)
+           vtkOutputModule.addSecondaryVariable("m^w_" + FluidSystem::componentName(i),
+                                                 [i](const VolumeVariables& v){ return v.molarity(phaseIdx,i); });
+    }
+
+    /*!
+     * \brief Append all quantities of interest which can be derived
+     *        from the solution of the current time step to the VTK
+     *        writer.
+     *
+     * \param sol The solution vector
+     * \param writer The writer for multi-file VTK datasets
+     */
+//     template<class MultiWriter>
+//     //additional output of the permeability and the precipitate volume fractions
+//     void addOutputVtkFields(const SolutionVector &sol, MultiWriter &writer)
+//     {
+//         typedef Dune::BlockVector<Dune::FieldVector<Scalar, 1> > ScalarField;
+//         typedef Dune::BlockVector<Dune::FieldVector<double, dim> > VectorField;
+//
+//         // get the number of degrees of freedom
+//         auto numDofs = this->numDofs();
+//         ScalarField *p           = writer.allocateManagedBuffer (numDofs);
+//         ScalarField *rho         = writer.allocateManagedBuffer (numDofs);
+//         ScalarField *temperature  = writer.allocateManagedBuffer (numDofs);
+//         ScalarField *poro         = writer.allocateManagedBuffer (numDofs);
+//         ScalarField *permeabilityFactor = writer.allocateManagedBuffer (numDofs);
+//         ScalarField *precipitateVolumeFraction[numSPhases];
+//
+//         for (int i = 0; i < numSPhases; ++i)
+//             precipitateVolumeFraction[i] = writer.allocateManagedBuffer(numDofs);
+//
+// //         ScalarField *massFraction[numPhases][numComponents];
+// //         for (int i = 0; i < numPhases; ++i)
+// //             for (int j = 0; j < numComponents; ++j)
+// //                 massFraction[i][j] = writer.allocateManagedBuffer(numDofs);
+//
+//         ScalarField *molarity[numComponents];
+//         for (int j = 0; j < numComponents ; ++j)
+//             molarity[j] = writer.allocateManagedBuffer(numDofs);
+//
+//         ScalarField *moleFraction[numComponents];
+//             for (int j = 0; j < numComponents; ++j)
+//                 moleFraction[j] = writer.allocateManagedBuffer(numDofs);
+//
+//        ScalarField *moleFractionSolid[numSComponents];
+//             for (int j = numComponents; j < numSComponents; ++j)
+//                 moleFractionSolid[j] = writer.allocateManagedBuffer(numDofs);
+//
+//         ScalarField *Perm[dim];
+//         for (int j = 0; j < dim; ++j) //Permeability only in main directions xx and yy
+//             Perm[j] = writer.allocateManagedBuffer(numDofs);
+//
+//         VectorField *velocity = writer.template allocateManagedBuffer<double, dim>(numDofs);
+//
+//         ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
+//
+//         if (velocityOutput.enableOutput()) // check if velocity output is demanded
+//         {
+//             // initialize velocity fields
+//             for (unsigned int i = 0; i < numDofs; ++i)
+//             {
+//                 (*velocity)[i] = Scalar(0);
+//             }
+//         }
+//
+//         auto numElements = this->gridView_().size(0);
+//         ScalarField *rank = writer.allocateManagedBuffer(numElements);
+//
+//         for (const auto& element : elements(this->gridView_()))
+//         {
+//             auto eIdxGlobal = this->problem_().elementMapper().index(element);
+//             (*rank)[eIdxGlobal] = this->gridView_().comm().rank();
+//             FVElementGeometry fvGeometry;
+//             fvGeometry.update(this->gridView_(), element);
+//
+//             ElementVolumeVariables elemVolVars;
+//             elemVolVars.update(this->problem_(),
+//                                element,
+//                                fvGeometry,
+//                                false /* oldSol? */);
+//
+//             for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+//             {
+//                 auto dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
+//
+//                 (*p)[dofIdxGlobal] = elemVolVars[scvIdx].pressure(phaseIdx);
+//                 (*rho)[dofIdxGlobal] = elemVolVars[scvIdx].density(phaseIdx);
+//                 (*poro)[dofIdxGlobal] = elemVolVars[scvIdx].porosity();
+//
+//                 for (int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx){
+//                     (*precipitateVolumeFraction[sPhaseIdx])[dofIdxGlobal] = elemVolVars[scvIdx].precipitateVolumeFraction(sPhaseIdx + numPhases);
+//                  }
+//
+//                 (*temperature)[dofIdxGlobal] = elemVolVars[scvIdx].temperature();
+//                 (*permeabilityFactor)[dofIdxGlobal] = elemVolVars[scvIdx].permeabilityFactor();
+//
+// //                     for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+// //                         (*massFraction[phaseIdx][compIdx])[dofIdxGlobal]= elemVolVars[scvIdx].massFraction(phaseIdx,compIdx);
+//
+//                 for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+//                     (*molarity[compIdx])[dofIdxGlobal] = (elemVolVars[scvIdx].molarity(compIdx));
+//
+//                 for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+//                     (*moleFraction[compIdx])[dofIdxGlobal]= elemVolVars[scvIdx].moleFraction(compIdx);
+//
+//                  for (int compIdx = numComponents; compIdx < numSComponents; ++compIdx)
+//                     (*moleFractionSolid[compIdx])[dofIdxGlobal]= elemVolVars[scvIdx].moleFraction(compIdx);
+//
+//                 Tensor K = this->perm_(this->problem_().spatialParams().intrinsicPermeability(element, fvGeometry, scvIdx));
+//
+//                 for (int j = 0; j<dim; ++j)
+//                     (*Perm[j])[dofIdxGlobal] = K[j][j] * elemVolVars[scvIdx].permeabilityFactor();
+//             };
+//
+//             // velocity output
+//             if(velocityOutput.enableOutput()){
+//                 velocityOutput.calculateVelocity(*velocity, elemVolVars, fvGeometry, element, phaseIdx);
+//             }
+//         }  // loop over element
+//
+//         writer.attachDofData(*p, "pressure", isBox);
+//         writer.attachDofData(*rho, "rho", isBox);
+//         writer.attachDofData(*poro, "porosity", isBox);
+//         writer.attachDofData(*permeabilityFactor, "permeabilityFactor", isBox);
+//         writer.attachDofData(*temperature, "temperature", isBox);
+//
+//         for (int i = 0; i < numSPhases; ++i)
+//         {
+//             std::cout << "test1" <<  "\n";
+//             std::ostringstream oss;
+//             oss << "precipitateVolumeFraction_" << FluidSystem::componentName(numComponents + i);
+//             writer.attachDofData(*precipitateVolumeFraction[i], oss.str(), isBox);
+//         }
+//
+//         writer.attachDofData(*Perm[0], "Kxx", isBox);
+//         if (dim >= 2)
+//             writer.attachDofData(*Perm[1], "Kyy", isBox);
+//         if (dim == 3)
+//             writer.attachDofData(*Perm[2], "Kzz", isBox);
+//
+//
+// //             for (int j = 0; j < numComponents; ++j)
+// //             {
+// //                 std::ostringstream oss;
+// //                 oss << "X^" << FluidSystem::phaseName(i) << "_" << FluidSystem::componentName(j);
+// //                 writer.attachDofData(*massFraction[i][j], oss.str(), isBox);
+// //             }
+//
+//         for (int j = 0; j < numComponents; ++j)
+//         {
+//             std::ostringstream oss;
+//             oss << "m^w_" << FluidSystem::componentName(j);
+//             writer.attachDofData(*molarity[j], oss.str(), isBox);
+//         }
+//
+//         for (int j = 0; j < numComponents; ++j)
+//             {
+//                 std::ostringstream oss;
+//                 oss << "x"
+//                     << FluidSystem::componentName(j);
+//                 writer.attachDofData(*moleFraction[j], oss.str(), isBox);
+//             }
+//
+//         for (int j = numComponents; j < numSComponents; ++j)
+//         {
+//             std::ostringstream oss;
+//             oss << "m^w_" << FluidSystem::componentName(j);
+//             writer.attachDofData(*molarity[j], oss.str(), isBox);
+//         }
+//
+//         for (int j = numComponents; j < numSComponents; ++j)
+//             {
+//                 std::ostringstream oss;
+//                 oss << "x"
+//                     << FluidSystem::componentName(j);
+//                 writer.attachDofData(*moleFraction[j], oss.str(), isBox);
+//             }
+//
+//         if (velocityOutput.enableOutput()) // check if velocity output is demanded
+//         {
+//             writer.attachDofData(*velocity,  "velocity", isBox, dim);
+//         }
+//
+//         writer.attachCellData(*rank, "process rank");
+//     }
+
+    /*!
+     * \brief Update the static data of all vertices in the grid.
+     *
+     * \param curGlobalSol The current global solution
+     * \param oldGlobalSol The previous global solution
+     */
+    void updateStaticData(SolutionVector &curGlobalSol,
+                          const SolutionVector &oldGlobalSol)
+    {
+        for (unsigned i = 0; i < this->staticDat_.size(); ++i)
+            this->staticDat_[i].visited = false;
+
+        for (const auto& element : elements(this->gridView_()))
+        {
+            FVElementGeometry fvGeometry;
+            fvGeometry.update(this->gridView_(), element);
+            for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+            {
+                auto dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
+
+                if (this->staticDat_[dofIdxGlobal].visited)
+                    continue;
+
+                this->staticDat_[dofIdxGlobal].visited = true;
+                VolumeVariables volVars;
+                volVars.update(curGlobalSol[dofIdxGlobal],
+                               this->problem_(),
+                               element,
+                               fvGeometry,
+                               scvIdx,
+                               false);
+            }
+        }
+    }
+
+       /*!
+     * \brief Write the current solution to a restart file.
+     *
+     * \param outStream The output stream of one entity for the restart file
+     * \param entity The entity, either a vertex or an element
+     */
+    template<class Entity>
+    void serializeEntity(std::ostream &outStream, const Entity &entity)
+    {
+        // write primary variables
+        ParentType::serializeEntity(outStream, entity);
+
+        int dofIdxGlobal = this->dofMapper().index(entity);
+
+        if (!outStream.good())
+            DUNE_THROW(Dune::IOError, "Could not serialize entity " << dofIdxGlobal);
+
+    }
+
+    /*!
+     * \brief Reads the current solution from a restart file.
+     *
+     * \param inStream The input stream of one entity from the restart file
+     * \param entity The entity, either a vertex or an element
+     */
+    template<class Entity>
+    void deserializeEntity(std::istream &inStream, const Entity &entity)
+    {
+        // read primary variables
+        ParentType::deserializeEntity(inStream, entity);
+
+        // read phase presence
+        int dofIdxGlobal = this->dofMapper().index(entity);
+
+        if (!inStream.good())
+            DUNE_THROW(Dune::IOError, "Could not deserialize entity " << dofIdxGlobal);
+    }
+
+
+    Tensor perm_(Scalar perm) const
+    {
+        Tensor K(0.0);
+
+        for(int i=0; i<dim; i++)
+            K[i][i] = perm;
+
+       return K;
+    }
+
+    const Tensor& perm_(const Tensor& perm) const
+    {
+       return perm;
+    }
+};
+
+}
+
+#include "propertydefaults.hh"
+
+#endif
diff --git a/dumux/porousmediumflow/1pncmin/implicit/properties.hh b/dumux/porousmediumflow/1pncmin/implicit/properties.hh
new file mode 100644
index 0000000000..bfe7ee8998
--- /dev/null
+++ b/dumux/porousmediumflow/1pncmin/implicit/properties.hh
@@ -0,0 +1,69 @@
+// -**- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup OnePNCMinModel
+ *
+ * \file
+ *
+ * \brief Defines the properties required for the one-phase n-component mineralization
+ *        fully implicit model.
+ */
+#ifndef DUMUX_1PNCMIN_PROPERTIES_HH
+#define DUMUX_1PNCMIN_PROPERTIES_HH
+
+#include <dumux/porousmediumflow/1pnc/implicit/properties.hh>
+
+namespace Dumux
+{
+
+namespace Properties
+{
+//////////////////////////////////////////////////////////////////
+// Type tags
+//////////////////////////////////////////////////////////////////
+
+//! The type tag for the isothermal two phase n component mineralisation problems
+NEW_TYPE_TAG(OnePNCMin, INHERITS_FROM(OnePNC));
+NEW_TYPE_TAG(BoxOnePNCMin, INHERITS_FROM(BoxModel, OnePNCMin));
+NEW_TYPE_TAG(CCOnePNCMin, INHERITS_FROM(CCModel, OnePNCMin));
+
+//! The type tags for the corresponding non-isothermal problems
+NEW_TYPE_TAG(OnePNCMinNI, INHERITS_FROM(OnePNCMin, NonIsothermal));
+NEW_TYPE_TAG(BoxOnePNCMinNI, INHERITS_FROM(BoxModel, OnePNCMinNI));
+NEW_TYPE_TAG(CCOnePNCMinNI, INHERITS_FROM(CCModel, OnePNCMinNI));
+
+//////////////////////////////////////////////////////////////////
+// Property tags
+//////////////////////////////////////////////////////////////////
+
+NEW_PROP_TAG(NumSPhases); //!< Number of solid phases in the system
+NEW_PROP_TAG(NumFSPhases); //!< Number of fluid and solid phases in the system
+NEW_PROP_TAG(NumSComponents); //!< Number of solid components in the system
+NEW_PROP_TAG(NumPSComponents); //!< Number of fluid and solid components in the system
+NEW_PROP_TAG(NumTraceComponents); //!< Number of trace fluid components which are not considered in the calculation of the phase density
+NEW_PROP_TAG(NumSecComponents); //!< Number of secondary components which are not primary variables
+NEW_PROP_TAG(OnePNCMinIndices); //!< Enumerations for the 2pncMin models
+NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
+
+}
+}
+
+#endif
diff --git a/dumux/porousmediumflow/1pncmin/implicit/propertydefaults.hh b/dumux/porousmediumflow/1pncmin/implicit/propertydefaults.hh
new file mode 100644
index 0000000000..a17763e6f1
--- /dev/null
+++ b/dumux/porousmediumflow/1pncmin/implicit/propertydefaults.hh
@@ -0,0 +1,180 @@
+// -**- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup OnePNCMinModel
+ * \file
+ *
+ * \brief Defines default values for most properties required by the
+ *        two-phase n-component mineralization fully implicit model.
+ */
+#ifndef DUMUX_1PNCMIN_PROPERTY_DEFAULTS_HH
+#define DUMUX_1PNCMIN_PROPERTY_DEFAULTS_HH
+
+#include "model.hh"
+#include "indices.hh"
+#include "volumevariables.hh"
+#include "properties.hh"
+
+#include <dumux/porousmediumflow/1pnc/implicit/newtoncontroller.hh>
+#include <dumux/porousmediumflow/implicit/darcyfluxvariables.hh>
+#include <dumux/material/spatialparams/implicit.hh>
+#include <dumux/material/fluidmatrixinteractions/1p/thermalconductivityaverage.hh>
+
+namespace Dumux
+{
+
+namespace Properties {
+//////////////////////////////////////////////////////////////////
+// Property values
+//////////////////////////////////////////////////////////////////
+
+/*!
+ * \brief Set the property for the number of secondary components.
+ * Secondary components are components calculated from
+ * primary components by equilibrium relations and
+ * do not have mass balance equation on their own.
+ * These components are important in the context of bio-mineralization applications.
+ * We just forward the number from the fluid system
+ *
+ */
+SET_PROP(OnePNCMin, NumSComponents)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+public:
+    static const int value = FluidSystem::numSComponents;
+};
+/*!
+ * \brief Set the property for the number of solid phases, excluding the non-reactive matrix.
+ *
+ * We just forward the number from the fluid system
+ *
+ */
+SET_PROP(OnePNCMin, NumSPhases)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numSPhases;
+};
+
+/*!
+ * \brief Set the property for the number of equations.
+ * For each component and each precipitated mineral/solid phase one equation has to
+ * be solved.
+ */
+SET_PROP(OnePNCMin, NumEq)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+//     static const int value = FluidSystem::numComponents + FluidSystem::numSPhases;
+    static const int value = FluidSystem::numComponents + FluidSystem::numSComponents; //steamaircao2h2 has 2 components in the fluidphase
+};
+
+/*!
+ * \brief The fluid state which is used by the volume variables to
+ *        store the thermodynamic state. This should be chosen
+ *        appropriately for the model ((non-)isothermal, equilibrium, ...).
+ *        This can be done in the problem.
+ */
+SET_PROP(OnePNCMin, FluidState){
+    private:
+        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    public:
+        typedef CompositionalFluidState<Scalar, FluidSystem> type;
+};
+
+//! Use the 2pncmin local residual operator
+SET_TYPE_PROP(OnePNCMin,
+              LocalResidual,
+              OnePNCMinLocalResidual<TypeTag>);
+
+//! the Model property
+SET_TYPE_PROP(OnePNCMin, Model, OnePNCMinModel<TypeTag>);
+
+//! the VolumeVariables property
+SET_TYPE_PROP(OnePNCMin, VolumeVariables, OnePNCMinVolumeVariables<TypeTag>);
+
+//! the FluxVariables property
+// SET_TYPE_PROP(OnePNCMin, FluxVariables, OnePNCMinFluxVariables<TypeTag>);
+
+//! The indices required by the isothermal 2pNcMin model
+SET_TYPE_PROP(OnePNCMin, Indices, OnePNCMinIndices <TypeTag, /*PVOffset=*/0>);
+
+//! default value for the forchheimer coefficient
+// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90.
+//        Actually the Forchheimer coefficient is also a function of the dimensions of the
+//        porous medium. Taking it as a constant is only a first approximation
+//        (Nield, Bejan, Convection in porous media, 2006, p. 10)
+SET_SCALAR_PROP(OnePNCMin, SpatialParamsForchCoeff, 0.55);
+
+//set isothermal VolumeVariables
+SET_TYPE_PROP(OnePNCMin, IsothermalVolumeVariables, OnePNCMinVolumeVariables<TypeTag>);
+
+//! Somerton is used as default model to compute the effective thermal heat conductivity
+SET_PROP(OnePNCMinNI, ThermalConductivityModel)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+public:
+    typedef ThermalConductivityAverage<Scalar> type;
+};
+
+
+SET_BOOL_PROP(OnePNCMinNI, NiOutputLevel, 0);
+
+//////////////////////////////////////////////////////////////////
+// Property values for isothermal model required for the general non-isothermal model
+//////////////////////////////////////////////////////////////////
+
+// set isothermal Model
+SET_TYPE_PROP(OnePNCMinNI, IsothermalModel, OnePNCMinModel<TypeTag>);
+
+// set isothermal FluxVariables
+//SET_TYPE_PROP(OnePNCMinNI, IsothermalFluxVariables, OnePNCMinFluxVariables<TypeTag>);
+
+//set isothermal VolumeVariables
+SET_TYPE_PROP(OnePNCMinNI, IsothermalVolumeVariables, OnePNCMinVolumeVariables<TypeTag>);
+
+//set isothermal LocalResidual
+SET_TYPE_PROP(OnePNCMinNI, IsothermalLocalResidual, OnePNCMinLocalResidual<TypeTag>);
+
+//set isothermal Indices
+SET_TYPE_PROP(OnePNCMinNI, IsothermalIndices, OnePNCMinIndices<TypeTag, /*PVOffset=*/0>);
+
+//set isothermal NumEq
+SET_PROP(OnePNCMinNI, IsothermalNumEq)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numComponents +FluidSystem::numSComponents;// in NonIsothermal 1 is substracted by default
+};
+}
+}
+
+#endif
diff --git a/dumux/porousmediumflow/1pncmin/implicit/volumevariables.hh b/dumux/porousmediumflow/1pncmin/implicit/volumevariables.hh
new file mode 100644
index 0000000000..70fafae134
--- /dev/null
+++ b/dumux/porousmediumflow/1pncmin/implicit/volumevariables.hh
@@ -0,0 +1,390 @@
+// -**- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Contains the quantities which are constant within a
+ *        finite volume in the two-phase, n-component mineralization model.
+ */
+#ifndef DUMUX_1PNCMIN_VOLUME_VARIABLES_HH
+#define DUMUX_1PNCMIN_VOLUME_VARIABLES_HH
+
+
+#include <dumux/common/math.hh>
+#include <dumux/implicit/model.hh>
+#include <dumux/material/fluidstates/compositional.hh>
+#include <dumux/porousmediumflow/1pnc/implicit/volumevariables.hh>
+
+#include "properties.hh"
+#include "indices.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup OnePNCMinModel
+ * \ingroup ImplicitVolumeVariables
+ * \brief Contains the quantities which are are constant within a
+ *        finite volume in the two-phase, n-component model.
+ */
+template <class TypeTag>
+class OnePNCMinVolumeVariables : public OnePNCVolumeVariables<TypeTag>
+{
+    // base type is used for energy related quantites
+    using BaseType = ImplicitVolumeVariables<TypeTag>;
+
+    using ParentType = OnePNCVolumeVariables<TypeTag>;
+    using Implementation = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    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 FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
+    using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector);
+    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
+
+//     typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+
+    enum
+    {
+        dim = GridView::dimension,
+        dimWorld=GridView::dimensionworld,
+
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numSPhases =  GET_PROP_VALUE(TypeTag, NumSPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+        numSComponents = GET_PROP_VALUE(TypeTag, NumSComponents), //if there is more than 1 component in the solid phase
+
+        phaseCompIdx = Indices::phaseCompIdx,
+
+        // phase indices
+        phaseIdx = FluidSystem::gPhaseIdx,
+        cPhaseIdx = Indices::phaseIdx +1,
+        hPhaseIdx = Indices::phaseIdx +2,
+
+        // primary variable indices
+        pressureIdx = Indices::pressureIdx,
+        firstMoleFracIdx = Indices::firstMoleFracIdx,
+
+    };
+
+    using Element = typename GridView::template Codim<0>::Entity;
+    using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
+    using CoordScalar = typename Grid::ctype;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+public:
+
+    using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState);
+
+    /*!
+     * \copydoc ImplicitVolumeVariables::update
+     */
+    void update(const ElementSolutionVector &elemSol,
+                const Problem &problem,
+                const Element &element,
+                const SubControlVolume& scv)
+    {
+        ParentType::update(elemSol, problem, element, scv);
+
+//         ParentType::update(priVars, problem, element, fvGeometry, scvIdx, isOldSol);
+//         completeFluidState(priVars, problem, element, fvGeometry, scvIdx, this->fluidState_, isOldSol);
+
+        /////////////
+        // calculate the remaining quantities
+        /////////////
+
+        auto&& priVars = isBox ? elemSol[scv.index()] : elemSol[0];
+
+        // porosity evaluation
+        initialPorosity_ = problem.spatialParams().porosity(element, scv);
+        minimumPorosity_ = problem.spatialParams().porosityMin(element, scv);
+        maximumPorosity_ = problem.spatialParams().porosityMax(element, scv);
+
+        sumPrecipitates_ = 0.0;
+        for(int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
+        {
+           precipitateVolumeFraction_[sPhaseIdx] = priVars[numComponents + sPhaseIdx];
+           sumPrecipitates_+= precipitateVolumeFraction_[sPhaseIdx];
+
+        }
+
+        // TODO/FIXME: The salt crust porosity is not clearly defined. However form literature review it is
+        // found that the salt crust have porosity of approx. 10 %. Thus we restrict the decrease in porosity
+        // to this limit. Moreover in the Problem files the precipitation should also be made dependent on local
+        // porosity value, as the porous media media properties change related to salt precipitation will not be
+        // accounted otherwise.
+
+        this->porosity_ = 1 - sumPrecipitates_;
+
+        permeabilityFactor_  =  std::pow(((1-initialPorosity_)/(1-this->porosity_)), 2)
+                                * std::pow((this->porosity_/initialPorosity_), 3);
+
+        // Verma-Pruess relation
+        // permeabilityFactor_  =  100 * std::pow(((this->porosity_/initialPorosity_)-0.9),2);
+
+        // Modified Fair-Hatch relation with final porosity set to 0.2 and E1=1
+        // permeabilityFactor_  =  std::pow((this->porosity_/initialPorosity_),3)
+        //                         * std::pow((std::pow((1 - initialPorosity_),2/3))+(std::pow((0.2 - initialPorosity_),2/3)),2)
+        //                         / std::pow((std::pow((1 -this->porosity_),2/3))+(std::pow((0.2 -this->porosity_),2/3)),2);
+
+        //Timur relation with residual water saturation set to 0.001
+        // permeabilityFactor_ =  0.136 * (std::pow(this->porosity_,4.4)) / (2000 * (std::pow(0.001,2)));
+
+        //Timur relation1 with residual water saturation set to 0.001
+        // permeabilityFactor_ =  0.136 * (std::pow(this->porosity_,4.4)) / (200000 * (std::pow(0.001,2)));
+
+        // Bern. relation
+        // permeabilityFactor_ = std::pow((this->porosity_/initialPorosity_),8);
+
+        //Tixier relation with residual water saturation set to 0.001
+        // permeabilityFactor_ = (std::pow((250 * (std::pow(this->porosity_,3)) / 0.001),2)) / initialPermeability_;
+
+        //Coates relation with residual water saturation set to 0.001
+        // permeabilityFactor_ = (std::pow((100 * (std::pow(this->porosity_,2)) * (1-0.001) / 0.001,2))) / initialPermeability_ ;
+
+//         energy related quantities not contained in the fluid state
+        asImp_().updateEnergy_(elemSol, problem, element, scv);
+    }
+
+   /*!
+    * \copydoc ImplicitModel::completeFluidState
+    * \param isOldSol Specifies whether this is the previous solution or the current one
+    */
+    static void completeFluidState(const ElementSolutionVector& elemSol,
+                                   const Problem& problem,
+                                   const Element& element,
+                                   const SubControlVolume& scv,
+                                   FluidState& fluidState)
+
+    {
+//         Scalar t = ParentType::temperature(elemSol, problem, element, scv); //old
+        Scalar t = BaseType::temperature(elemSol, problem, element, scv);
+        fluidState.setTemperature(t);
+
+        /////////////
+        // set the saturations
+        /////////////
+
+        fluidState.setSaturation(phaseIdx, 1.0 );
+
+        /////////////
+        // set the pressures of the fluid phase
+        /////////////
+        const auto& priVars = ParentType::extractDofPriVars(elemSol, scv);
+        fluidState.setPressure(phaseIdx, priVars[pressureIdx]);
+
+        /////////////
+        // calculate the phase compositions
+        /////////////
+
+        typename FluidSystem::ParameterCache paramCache;
+
+        Dune::FieldVector<Scalar, numComponents> moleFrac;
+
+        Scalar sumMoleFracNotWater = 0;
+        for (int compIdx=firstMoleFracIdx; compIdx<numComponents; ++compIdx)
+        {
+            moleFrac[compIdx] = priVars[compIdx];
+            sumMoleFracNotWater+=moleFrac[compIdx];
+        }
+
+        moleFrac[0] = 1 -sumMoleFracNotWater;
+
+//         //mole fractions for the solid phase
+//         moleFrac[firstMoleFracIdx+1]= priVars[firstMoleFracIdx+1];
+//         moleFrac[firstMoleFracIdx +2] = 1- moleFrac[firstMoleFracIdx+1];
+
+        // convert mass to mole fractions and set the fluid state
+        for (int compIdx=0; compIdx<numComponents; ++compIdx)
+        {
+            fluidState.setMoleFraction(phaseIdx, compIdx, moleFrac[compIdx]);
+        }
+
+//         // set mole fractions for the solid phase
+//         fluidState.setMoleFraction(cPhaseIdx, firstMoleFracIdx+1, moleFrac[firstMoleFracIdx+1]);
+//         fluidState.setMoleFraction(hPhaseIdx, firstMoleFracIdx+2, moleFrac[firstMoleFracIdx+2]);
+
+        paramCache.updateAll(fluidState);
+
+//         Scalar h = Implementation::enthalpy_(fluidState, paramCache, phaseIdx);
+        Scalar h = BaseType::enthalpy(fluidState, paramCache, phaseIdx);
+        fluidState.setEnthalpy(phaseIdx, h);
+    }
+    /*!
+     * \brief Returns the volume fraction of the precipitate (solid phase)
+     * for the given phaseIdx
+     *
+     * \param phaseIdx the index of the solid phase
+     */
+    Scalar precipitateVolumeFraction(int phaseIdx) const
+    {
+        return precipitateVolumeFraction_[phaseIdx - numPhases];
+    }
+
+    /*!
+     * \brief Returns the inital porosity of the
+     * pure, precipitate-free porous medium
+     */
+    Scalar initialPorosity() const
+    { return initialPorosity_;}
+
+    /*!
+     * \brief Returns the inital permeability of the
+     * pure, precipitate-free porous medium
+     */
+    Scalar initialPermeability() const
+    { return initialPermeability_;}
+
+    /*!
+     * \brief Returns the factor for the reduction of the initial permeability
+     * due precipitates in the porous medium
+     */
+    Scalar permeabilityFactor() const
+    { return permeabilityFactor_; }
+
+    /*!
+     * \brief Returns the density of the phase for all fluid and solid phases
+     *
+     * \param phaseIdx the index of the fluid phase
+     */
+    Scalar density(int phaseIdx) const
+    {
+        if (phaseIdx <= numPhases)
+            return this->fluidState_.density(phaseIdx);
+        else if (phaseIdx > numPhases)
+            return FluidSystem::precipitateDensity(phaseIdx);
+        else
+            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
+    }
+    /*!
+     * \brief Returns the mass density of a given phase within the
+     *        control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar molarDensity(int phaseIdx) const
+    {
+        if (phaseIdx <  1)
+            return this->fluidState_.molarDensity(phaseIdx);
+        else if (phaseIdx >= 1){
+            /*Attention: sPhaseIdx of the fluidsystem and the model can be different.*/
+//             std::cout << "FluidSystem::precipitateMolarDensity("<<phaseIdx<<") = " << FluidSystem::precipitateMolarDensity(phaseIdx) << "\n";
+//             for (int phaseIdx=1; phaseIdx<numSPhases; ++phaseIdx)
+            return FluidSystem::precipitateMolarDensity(phaseIdx);
+        }
+        else
+            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
+    }
+
+    /*!
+     * \brief Returns the molality of a component in the phase
+     *
+     * \param phaseIdx the index of the fluid phase
+     * \param compIdx the index of the component
+     * \f$\mathrm{molality}=\frac{n_\mathrm{component}}{m_\mathrm{solvent}}
+     * =\frac{n_\mathrm{component}}{n_\mathrm{solvent}*M_\mathrm{solvent}}\f$
+     * compIdx of the main component (solvent) in the
+     * phase is equal to the phaseIdx
+     */
+    Scalar molality(int phaseIdx, int compIdx) const // [moles/Kg]
+    { return this->fluidState_.moleFraction(phaseIdx, compIdx)
+                  /(this->fluidState_.moleFraction(phaseIdx, phaseIdx)
+                  * FluidSystem::molarMass(phaseIdx));}
+
+   /*!
+    * Circumvents the inheritance architecture of the nonisothermal model
+    */
+    static Scalar callProtectedTemperature(const ElementSolutionVector& elemSol,
+                                        const Problem& problem,
+                                        const Element& element,
+                                        const SubControlVolume& scv)
+    {
+//          return Implementation::temperature_(priVars, problem,element, fvGeometry, scvIdx);
+        return BaseType::temperature(elemSol, problem, element, scv);
+    }
+
+    /*!
+    * Circumvents the inheritance architecture of the ninisothermal model
+    */
+    void callProtectedUpdateEnergy(const ElementSolutionVector& elemSol,
+                                        const Problem& problem,
+                                        const Element& element,
+                                        const SubControlVolume& scv)
+    {
+        asImp_().updateEnergy_(elemSol, problem, element, scv);
+    };
+
+protected:
+    friend class OnePNCVolumeVariables<TypeTag>;
+    static Scalar temperature_(const ElementSolutionVector& elemSol,
+                                        const Problem& problem,
+                                        const Element& element,
+                                        const SubControlVolume& scv)
+    {
+        return problem.temperatureAtPos(scv);
+    }
+
+    template<class ParameterCache>
+    static Scalar enthalpy_(const FluidState& fluidState,
+                            const ParameterCache& paramCache,
+                            int phaseIdx)
+    {
+        return 0;
+    }
+
+   /*!
+    * \brief Update all quantities for a given control volume.
+    *
+    * \param priVars The solution primary variables
+    * \param problem The problem
+    * \param element The element
+    * \param fvGeometry Evaluate function with solution of current or previous time step
+    * \param scvIdx The local index of the SCV (sub-control volume)
+    * \param isOldSol Evaluate function with solution of current or previous time step
+    */
+    void updateEnergy_(const ElementSolutionVector& elemSol,
+                       const Problem& problem,
+                       const Element& element,
+                       const SubControlVolume& scv)
+    { };
+
+    Scalar precipitateVolumeFraction_[numSPhases];
+    Scalar permeabilityFactor_;
+    Scalar initialPorosity_;
+    Scalar initialPermeability_;
+    Scalar minimumPorosity_;
+    Scalar maximumPorosity_;
+    Scalar sumPrecipitates_;
+
+
+private:
+    Implementation &asImp_()
+    { return *static_cast<Implementation*>(this); }
+
+    const Implementation &asImp_() const
+    { return *static_cast<const Implementation*>(this); }
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/CMakeLists.txt b/dumux/porousmediumflow/CMakeLists.txt
index 6bc244e01f..013eb52802 100644
--- a/dumux/porousmediumflow/CMakeLists.txt
+++ b/dumux/porousmediumflow/CMakeLists.txt
@@ -1,6 +1,7 @@
 add_subdirectory("1p")
 add_subdirectory("1p2c")
 add_subdirectory("1pnc")
+add_subdirectory("1pncmin")
 add_subdirectory("2p")
 add_subdirectory("2p1c")
 add_subdirectory("2p2c")
-- 
GitLab