From e2e8d492ea3f26cb2c2f2fa118e59b8e80107693 Mon Sep 17 00:00:00 2001
From: vishal jambhekar <vishal.jambhekar@iws.uni-stuttgart.de>
Date: Tue, 21 Jul 2015 16:49:57 +0000
Subject: [PATCH] New model 2pncmin moved from dumux-devel to dumux-stable. The
 changes are reviewed by J.Hommel. The model was directly or indirectly used
 in publications (Jambhekar et. al 2015 and Hommel. et.al 2015)

git-svn-id: svn://svn.iws.uni-stuttgart.de/DUMUX/dumux/trunk@15137 2fb0f335-1f38-0410-981e-8018bf24f1b0
---
 .../implicit/2pncmin/2pncminfluxvariables.hh  | 162 +++++
 dumux/implicit/2pncmin/2pncminindices.hh      |  48 ++
 .../implicit/2pncmin/2pncminlocalresidual.hh  | 140 +++++
 dumux/implicit/2pncmin/2pncminmodel.hh        | 586 ++++++++++++++++++
 dumux/implicit/2pncmin/2pncminproperties.hh   |  63 ++
 .../2pncmin/2pncminpropertydefaults.hh        | 129 ++++
 .../2pncmin/2pncminvolumevariables.hh         | 554 +++++++++++++++++
 7 files changed, 1682 insertions(+)
 create mode 100644 dumux/implicit/2pncmin/2pncminfluxvariables.hh
 create mode 100644 dumux/implicit/2pncmin/2pncminindices.hh
 create mode 100644 dumux/implicit/2pncmin/2pncminlocalresidual.hh
 create mode 100644 dumux/implicit/2pncmin/2pncminmodel.hh
 create mode 100644 dumux/implicit/2pncmin/2pncminproperties.hh
 create mode 100644 dumux/implicit/2pncmin/2pncminpropertydefaults.hh
 create mode 100644 dumux/implicit/2pncmin/2pncminvolumevariables.hh

diff --git a/dumux/implicit/2pncmin/2pncminfluxvariables.hh b/dumux/implicit/2pncmin/2pncminfluxvariables.hh
new file mode 100644
index 0000000000..50d5ce61c4
--- /dev/null
+++ b/dumux/implicit/2pncmin/2pncminfluxvariables.hh
@@ -0,0 +1,162 @@
+// -*- 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 data which is required to calculate
+ *        all fluxes of components over a face of a finite volume for
+ *        the two-phase two-component mineralization model fully implicit model.
+ */
+#ifndef DUMUX_2PNCMIN_FLUX_VARIABLES_HH
+#define DUMUX_2PNCMIN_FLUX_VARIABLES_HH
+
+#include <dumux/common/math.hh>
+#include <dumux/common/spline.hh>
+#include <dumux/implicit/2pnc/2pncfluxvariables.hh>
+#include "2pncminproperties.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup TwoPNCMinModel
+ * \ingroup ImplicitFluxVariables
+ * \brief Contains the data which is required to calculate
+ *        all fluxes of components over a face of a finite volume for
+ *        the two-phase n-component mineralization fully implicit model.
+ *
+ * This means pressure and concentration gradients, phase densities at
+ * the integration point, etc.
+ */
+
+template <class TypeTag>
+class TwoPNCMinFluxVariables : public TwoPNCFluxVariables<TypeTag>
+{
+    typedef TwoPNCFluxVariables<TypeTag> ParentType;
+    typedef TwoPNCMinFluxVariables<TypeTag> ThisType;
+    
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+
+    typedef typename GridView::ctype CoordScalar;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld,
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename FVElementGeometry::SubControlVolume SCV;
+    typedef typename FVElementGeometry::SubControlVolumeFace SCVFace;
+
+    typedef Dune::FieldVector<CoordScalar, dimWorld> DimVector;
+    typedef Dune::FieldMatrix<CoordScalar, dim, dim> DimMatrix;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        wPhaseIdx = FluidSystem::wPhaseIdx,
+        nPhaseIdx = FluidSystem::nPhaseIdx,
+        wCompIdx  = FluidSystem::wCompIdx,
+    };
+
+public:
+    /*!
+     * \brief The constructor
+     *
+     * \param problem The problem
+     * \param element The finite element
+     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
+     * \param fIdx The local index of the sub-control-volume face
+     * \param elemVolVars The volume variables of the current element
+     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
+     */
+    TwoPNCMinFluxVariables(const Problem &problem,
+                     const Element &element,
+                     const FVElementGeometry &fvGeometry,
+                     const int fIdx,
+                     const ElementVolumeVariables &elemVolVars,
+                     const bool onBoundary = false)
+    : ParentType(problem, element, fvGeometry, fIdx, elemVolVars, onBoundary) 
+    {
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
+            this->density_[phaseIdx] = Scalar(0);
+            this->molarDensity_[phaseIdx] = Scalar(0);
+            this->potentialGrad_[phaseIdx] = Scalar(0);
+            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+            {
+            	this->massFractionGrad_[phaseIdx][compIdx] = Scalar(0);
+            	this->moleFractionGrad_[phaseIdx][compIdx] = Scalar(0);
+            }
+        }
+        this->calculateGradients_(problem, element, elemVolVars);
+        this->calculateVelocities_(problem, element, elemVolVars);
+        this->calculateporousDiffCoeff_(problem, element, elemVolVars);
+    };
+
+protected:    
+    void calculateVelocities_(const Problem &problem,
+                              const Element &element,
+                              const ElementVolumeVariables &elemVolVars)
+    {
+        const SpatialParams &spatialParams = problem.spatialParams();
+        // multiply the pressure potential with the intrinsic permeability
+        DimMatrix K(0.0);
+
+        for (int phaseIdx=0; phaseIdx < numPhases; phaseIdx++)
+        {
+            const VolumeVariables &volVarsI = elemVolVars[this->face().i];
+            const VolumeVariables &volVarsJ = elemVolVars[this->face().j];
+
+            auto K_i = spatialParams.intrinsicPermeability(element,this->fvGeometry_,this->face().i);
+            K_i *= volVarsI.permFactor();
+
+            auto K_j = spatialParams.intrinsicPermeability(element,this->fvGeometry_,this->face().j);
+            K_j *= volVarsJ.permFactor();
+
+            spatialParams.meanK(K,K_i,K_j);
+
+            K.mv(this->potentialGrad_[phaseIdx], this->Kmvp_[phaseIdx]);
+            this->KmvpNormal_[phaseIdx] = - (this->Kmvp_[phaseIdx] * this->face().normal);
+        }
+
+        // set the upstream and downstream vertices
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            this->upstreamIdx_[phaseIdx] = this->face().i;
+            this->downstreamIdx_[phaseIdx] = this->face().j;
+
+            if (this->KmvpNormal_[phaseIdx] < 0) {
+                std::swap(this->upstreamIdx_[phaseIdx],
+                          this->downstreamIdx_[phaseIdx]);
+            }
+        }
+    }
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/implicit/2pncmin/2pncminindices.hh b/dumux/implicit/2pncmin/2pncminindices.hh
new file mode 100644
index 0000000000..dc1b2e9e0c
--- /dev/null
+++ b/dumux/implicit/2pncmin/2pncminindices.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 two-phase n-component mineralization 
+ *        fully implicit model.
+ */
+#ifndef DUMUX_2PNCMIN_INDICES_HH
+#define DUMUX_2PNCMIN_INDICES_HH
+
+#include <dumux/implicit/2pnc/2pncindices.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPNCMinModel
+ * \ingroup ImplicitIndices
+ * \brief The indices for the isothermal two-phase n-component mineralization model.
+ *
+ * \tparam PVOffset The first index in a primary variable vector.
+ */
+template <class TypeTag, int PVOffset = 0>
+	class TwoPNCMinIndices: public TwoPNCIndices<TypeTag, PVOffset>
+{ 
+};
+
+// \}
+
+}
+
+#endif
diff --git a/dumux/implicit/2pncmin/2pncminlocalresidual.hh b/dumux/implicit/2pncmin/2pncminlocalresidual.hh
new file mode 100644
index 0000000000..c0fc7f9529
--- /dev/null
+++ b/dumux/implicit/2pncmin/2pncminlocalresidual.hh
@@ -0,0 +1,140 @@
+// -*- 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 two-phase n-component mineralisation box model.
+ */
+
+#ifndef DUMUX_2PNCMIN_LOCAL_RESIDUAL_BASE_HH
+#define DUMUX_2PNCMIN_LOCAL_RESIDUAL_BASE_HH
+
+#include "2pncminproperties.hh"
+#include <dumux/implicit/2pnc/2pnclocalresidual.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPNCMinModel
+ * \ingroup ImplicitLocalResidual
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the two-phase n-component mineralization fully implicit box model.
+ *
+ * This class is used to fill the gaps in ImplicitLocalResidual for the two-phase n-component flow.
+ */
+template<class TypeTag>
+class TwoPNCMinLocalResidual: public TwoPNCLocalResidual<TypeTag>
+{
+protected:
+	typedef TwoPNCLocalResidual<TypeTag> ParentType;
+    typedef TwoPNCMinLocalResidual<TypeTag> ThisType; 
+	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, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    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),
+
+        replaceCompEqIdx = GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx),
+
+        pressureIdx = Indices::pressureIdx,
+        switchIdx = Indices::switchIdx,
+
+        wPhaseIdx = FluidSystem::wPhaseIdx,
+        nPhaseIdx = FluidSystem::nPhaseIdx,
+
+        wCompIdx = FluidSystem::wCompIdx,
+        nCompIdx = FluidSystem::nCompIdx,
+
+        conti0EqIdx = Indices::conti0EqIdx,
+
+        wPhaseOnly = Indices::wPhaseOnly,
+        nPhaseOnly = Indices::nPhaseOnly,
+        bothPhases = Indices::bothPhases,
+
+        plSg = TwoPNCFormulation::plSg,
+        pgSl = TwoPNCFormulation::pgSl,
+        formulation = GET_PROP_VALUE(TypeTag, Formulation)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
+    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+
+public:
+    /*!
+     * \brief Constructor. Sets the upwind weight.
+     */
+    TwoPNCMinLocalResidual()
+    {
+        // retrieve the upwind weight for the mass conservation equations. Use the value
+        // specified via the property system as default, and overwrite
+        // it by the run-time parameter from the Dune::ParameterTree
+        this->massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
+    };
+
+    /*!
+     * \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 2pnc model, here, the storage of solid phases is included too.
+     *
+     *  \param storage the mass of the component within the sub-control volume
+     *  \param scvIdx The SCV (sub-control-volume) index
+     *  \param usePrevSol Evaluate function with solution of current or previous time step
+     */
+  void computeStorage(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const
+  {
+      //call parenttype function
+      ParentType::computeStorage(storage, scvIdx, usePrevSol);
+      
+      const ElementVolumeVariables &elemVolVars = usePrevSol ? this->prevVolVars_()
+      : this->curVolVars_();
+    const VolumeVariables &volVars = elemVolVars[scvIdx];
+
+    // Compute storage term of all solid (precipitated) phases (excluding the non-reactive matrix)
+    for (int phaseIdx = numPhases; phaseIdx < numPhases + numSPhases; ++phaseIdx)
+    {
+      int eqIdx = conti0EqIdx + numComponents-numPhases + phaseIdx;
+      storage[eqIdx] += volVars.precipitateVolumeFraction(phaseIdx)*volVars.molarDensity(phaseIdx);
+    }
+
+      Valgrind::CheckDefined(storage);
+  }
+};
+} // end namespace
+
+#endif
diff --git a/dumux/implicit/2pncmin/2pncminmodel.hh b/dumux/implicit/2pncmin/2pncminmodel.hh
new file mode 100644
index 0000000000..54c5d0b3fc
--- /dev/null
+++ b/dumux/implicit/2pncmin/2pncminmodel.hh
@@ -0,0 +1,586 @@
+// -*- 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_2PNCMIN_MODEL_HH
+#define DUMUX_2PNCMIN_MODEL_HH
+
+#include "2pncminproperties.hh"
+#include "2pncminindices.hh"
+
+#include <dumux/material/constants.hh>
+ #include <dumux/implicit/2pnc/2pncmodel.hh>
+#include "2pncminlocalresidual.hh"
+#include <dumux/implicit/common/implicitvelocityoutput.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPNCMinModel
+ * \brief Adaption of the fully implicit scheme to the
+ *        two-phase n-component fully implicit model.
+ *
+ * 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, a,\cdots \}\f$. 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}
+ && \phi \frac{\partial (\sum_\alpha \varrho_\alpha X_\alpha^\kappa 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}
+ *
+ * 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 mass fraction of, e.g., air in the wetting phase \f$X^a_w\f$ is used,
+ *      as long as the maximum mass fraction is not exceeded (\f$X^a_w<X^a_{w,max}\f$)</li>
+ *  <li> Only non-wetting phase is present: The mass fraction of, e.g., water in the non-wetting phase, \f$X^w_n\f$, is used,
+ *      as long as the maximum mass fraction is not exceeded (\f$X^w_n<X^w_{n,max}\f$)</li>
+ * </ul>
+ */
+
+template<class TypeTag>
+class TwoPNCMinModel: public TwoPNCModel<TypeTag>
+{
+    typedef TwoPNCMinModel<TypeTag> ThisType;
+    typedef TwoPNCModel<TypeTag> ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
+    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementMapper) ElementMapper;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    typedef Dumux::Constants<Scalar> Constant;
+
+    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),
+        numSecComponents = GET_PROP_VALUE(TypeTag, NumSecComponents),
+        numMajorComponents = GET_PROP_VALUE(TypeTag, NumMajorComponents),
+
+        pressureIdx = Indices::pressureIdx,
+        switchIdx = Indices::switchIdx,
+
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+
+        wCompIdx = FluidSystem::wCompIdx,
+        nCompIdx = FluidSystem::nCompIdx,
+
+        wPhaseOnly = Indices::wPhaseOnly,
+        nPhaseOnly = Indices::nPhaseOnly,
+        bothPhases = Indices::bothPhases,
+
+        plSg = TwoPNCFormulation::plSg,
+        pgSl = TwoPNCFormulation::pgSl,
+        formulation = GET_PROP_VALUE(TypeTag, Formulation),
+		useElectrochem = GET_PROP_VALUE(TypeTag, useElectrochem)
+    };
+
+    typedef typename GridView::template Codim<dim>::Entity Vertex;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+    typedef typename GridView::template Codim<dim>::Iterator VertexIterator;
+
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+    typedef typename GridView::ctype CoordScalar;
+    typedef Dune::FieldMatrix<CoordScalar, dimWorld, dimWorld> Tensor;
+    typedef Dune::FieldVector<Scalar, numPhases> PhasesVector;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+        enum { dofCodim = isBox ? dim : 0 };
+
+public:
+
+    /*!
+     * \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
+        unsigned numDofs = this->numDofs();
+
+        // create the required scalar fields
+
+        ScalarField *Sg		   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *Sl 	   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *pg		   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *pl		   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *pc 	   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *rhoL	   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *rhoG	   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *mobL	   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *mobG 	   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *phasePresence = writer.allocateManagedBuffer (numDofs);
+        ScalarField *temperature   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *poro          = writer.allocateManagedBuffer (numDofs);
+        ScalarField *boxVolume     = writer.allocateManagedBuffer (numDofs);
+//      ScalarField *potential     = writer.allocateManagedBuffer (numDofs);
+        ScalarField *cellNum 	   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *permFactor    = writer.allocateManagedBuffer (numDofs);
+        ScalarField *precipitateVolumeFraction[numSPhases] ;
+//      ScalarField *saturationIdx[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 *Perm[dim];
+        for (int j = 0; j < dim; ++j) //Permeability only in main directions xx and yy
+            Perm[j] = writer.allocateManagedBuffer(numDofs);
+
+        *boxVolume = 0;
+
+        VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numDofs);
+        VectorField *velocityW = 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)
+                  {
+                      (*velocityN)[i] = Scalar(0);
+                      (*velocityW)[i] = Scalar(0);
+                      (*cellNum)[i] = Scalar(0.0);
+                  }
+              }
+
+        unsigned numElements = this->gridView_().size(0);
+        ScalarField *rank =
+                writer.allocateManagedBuffer (numElements);
+
+        FVElementGeometry fvGeometry;
+        VolumeVariables volVars;
+        ElementVolumeVariables elemVolVars;
+
+        ElementIterator elemIt = this->gridView_().template begin<0>();
+        ElementIterator elemEndIt = this->gridView_().template end<0>();
+        for (; elemIt != elemEndIt; ++elemIt)
+        {
+            int idx = this->problem_().elementMapper().map(*elemIt);
+            (*rank)[idx] = this->gridView_().comm().rank();
+            fvGeometry.update(this->gridView_(), *elemIt);
+            
+            elemVolVars.update(this->problem_(),
+                    *elemIt,
+                    fvGeometry,
+                    false /* oldSol? */);
+
+#if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
+            int numVerts = elemIt->subEntities(dim);
+#else
+            int numVerts = elemIt->template count<dim> ();
+#endif   
+            for (int i = 0; i < numVerts; ++i)
+            {
+                int globalIdx = this->vertexMapper().map(*elemIt, i, dim);
+                volVars.update(sol[globalIdx],
+                               this->problem_(),
+                               *elemIt,
+                               fvGeometry,
+                               i,
+                               false);
+
+                (*Sg)[globalIdx]     		 = volVars.saturation(nPhaseIdx);
+                (*Sl)[globalIdx]     		 = volVars.saturation(wPhaseIdx);
+                (*pg)[globalIdx]  	 		 = volVars.pressure(nPhaseIdx);
+                (*pl)[globalIdx]   	 		 = volVars.pressure(wPhaseIdx);
+                (*pc)[globalIdx]	 		 = volVars.capillaryPressure();
+                (*rhoL)[globalIdx]	 	 	 = volVars.fluidState().density(wPhaseIdx);
+                (*rhoG)[globalIdx]	  		 = volVars.fluidState().density(nPhaseIdx);
+                (*mobL)[globalIdx] 	 	     = volVars.mobility(wPhaseIdx);
+                (*mobG)[globalIdx] 	 	     = volVars.mobility(nPhaseIdx);
+                (*boxVolume)[globalIdx]		+= fvGeometry.subContVol[i].volume;
+                (*poro)[globalIdx] 		     = volVars.porosity();
+
+                for (int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
+                {
+                    (*precipitateVolumeFraction[sPhaseIdx])[globalIdx]   = volVars.precipitateVolumeFraction(sPhaseIdx + numPhases);
+                }
+                (*temperature)[globalIdx] 	 = volVars.temperature();
+                (*permFactor)[globalIdx] 	 = volVars.permFactor();
+                (*phasePresence)[globalIdx]  = this->staticDat_[globalIdx].phasePresence;
+//                 (*potential)[globalIdx]      = (volVars.pressure(wPhaseIdx)-1e5)
+//                         /volVars.fluidState().density(wPhaseIdx)
+//                         /9.81
+//                         - (zmax - globalPos[dim-1]);
+// 
+// 
+//                 for (int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
+//                 {
+//                     (*saturationIdx[sPhaseIdx])[globalIdx]   = volVars.saturationIdx(sPhaseIdx + numPhases);
+//                 }
+
+
+                for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+                    for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                    {
+                        (*massFraction[phaseIdx][compIdx])[globalIdx]= volVars.fluidState().massFraction(phaseIdx,compIdx);
+
+                        Valgrind::CheckDefined((*massFraction[phaseIdx][compIdx])[globalIdx]);
+
+                    }
+                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                    (*molarity[compIdx])[globalIdx] = (volVars.fluidState().molarity(wPhaseIdx, compIdx));
+
+                Tensor K = this->perm_(this->problem_().spatialParams().intrinsicPermeability(*elemIt, fvGeometry, i));
+
+                for (int j = 0; j<dim; ++j)
+                    (*Perm[j])[globalIdx] = K[j][j] * volVars.permFactor();
+            };
+
+            // velocity output
+            if(velocityOutput.enableOutput()){
+                velocityOutput.calculateVelocity(*velocityW, elemVolVars, fvGeometry, *elemIt, wPhaseIdx);
+                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, *elemIt, nPhaseIdx);
+            }
+        }  // loop over element
+
+        writer.attachVertexData(*Sg, "Sg");
+        writer.attachVertexData(*Sl, "Sl");
+        writer.attachVertexData(*pg, "pg");
+        writer.attachVertexData(*pl, "pl");
+        writer.attachVertexData(*pc, "pc");
+        writer.attachVertexData(*rhoL, "rhoL");
+        writer.attachVertexData(*rhoG, "rhoG");
+        writer.attachVertexData(*mobL, "mobL");
+        writer.attachVertexData(*mobG, "mobG");
+        writer.attachVertexData(*poro, "porosity");
+        writer.attachVertexData(*permFactor, "permFactor");
+        writer.attachVertexData(*temperature, "temperature");
+        writer.attachVertexData(*phasePresence, "phase presence");
+//         writer.attachVertexData(*potential, "potential");
+        writer.attachVertexData(*boxVolume, "boxVolume");
+        
+    
+        for (int i = 0; i < numSPhases; ++i)
+        {
+            std::ostringstream oss;
+            oss << "precipitateVolumeFraction_"
+                << FluidSystem::phaseName(numPhases + i);
+            writer.attachDofData(*precipitateVolumeFraction[i], oss.str().c_str(), isBox);
+        }
+
+//         for (int i = 0; i < numSPhases; ++i)
+//         {
+//             std::ostringstream oss;
+//             oss << "saturationIndex_"
+//                 << FluidSystem::phaseName(numPhases + i);
+//             writer.attachDofData(*saturationIdx[i], oss.str().c_str(), isBox);
+//         }
+
+        writer.attachVertexData(*Perm[0], "Kxx");
+        if (dim >= 2)
+            writer.attachVertexData(*Perm[1], "Kyy");
+        if (dim == 3)
+            writer.attachVertexData(*Perm[2], "Kzz");
+
+        for (int i = 0; i < numPhases; ++i)
+        {
+            for (int j = 0; j < numComponents; ++j)
+            {
+                std::ostringstream oss;
+                oss << "X^"
+                << FluidSystem::phaseName(i)
+                << "_"
+                << FluidSystem::componentName(j);
+                writer.attachVertexData(*massFraction[i][j], oss.str().c_str());
+            }
+        }
+
+        for (int j = 0; j < numComponents; ++j)
+        {
+            std::ostringstream oss;
+            oss << "m^w_"
+                << FluidSystem::componentName(j);
+            writer.attachVertexData(*molarity[j], oss.str().c_str());
+        }
+
+        if (velocityOutput.enableOutput()) // check if velocity output is demanded
+        {
+            writer.attachDofData(*velocityW,  "velocityW", isBox, dim);
+            writer.attachDofData(*velocityN,  "velocityN", 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)
+    {
+        bool wasSwitched = false;
+
+        for (unsigned i = 0; i < this->staticDat_.size(); ++i)
+            this->staticDat_[i].visited = false;
+
+        FVElementGeometry fvGeometry;
+        static VolumeVariables volVars;
+        ElementIterator it = this->gridView_().template begin<0> ();
+        const ElementIterator &endit = this->gridView_().template end<0> ();
+        for (; it != endit; ++it)
+        {
+            fvGeometry.update(this->gridView_(), *it);
+            for (int i = 0; i < fvGeometry.numScv; ++i)
+            {
+                int globalIdx = this->vertexMapper().map(*it, i, dim);
+
+                if (this->staticDat_[globalIdx].visited)
+                    continue;
+
+                this->staticDat_[globalIdx].visited = true;
+                volVars.update(curGlobalSol[globalIdx],
+                               this->problem_(),
+                               *it,
+                               fvGeometry,
+                               i,
+                               false);
+                const GlobalPosition &global = it->geometry().corner(i);
+                if (primaryVarSwitch_(curGlobalSol,
+                                      volVars,
+                                      globalIdx,
+                                      global))
+                { wasSwitched = true;
+                std::cout<<"Switch works :) "<<std::endl;
+                }
+            }
+        }
+
+        // make sure that if there was a variable switch in an
+        // other partition we will also set the switch flag
+        // for our partition.
+        if (this->gridView_().comm().size() > 1)
+        wasSwitched = this->gridView_().comm().max(wasSwitched);
+
+        setSwitched_(wasSwitched);
+    } 
+protected:
+	 
+    /*!
+     * \brief Set whether there was a primary variable switch after in
+     *        the last timestep.
+     */
+    void setSwitched_(bool yesno)
+    {
+        switchFlag_ = yesno;
+    }
+    
+    /*!
+     * \copydoc 2pnc::primaryVarSwitch_
+     */
+    bool primaryVarSwitch_(SolutionVector &globalSol,
+                           const VolumeVariables &volVars, int globalIdx,
+                           const GlobalPosition &globalPos)
+    {
+
+            // evaluate primary variable switch
+            bool wouldSwitch = false;
+            int phasePresence = this->staticDat_[globalIdx].phasePresence;
+            int newPhasePresence = phasePresence;
+
+            //check if a primary variable switch is necessary
+            if (phasePresence == bothPhases)
+            {
+                Scalar Smin = 0.0; //saturation threshold
+                if (this->staticDat_[globalIdx].wasSwitched)
+                    Smin = -0.01;
+
+                //if saturation of liquid phase is smaller 0 switch
+                if (volVars.saturation(wPhaseIdx) <= Smin)
+                {
+                    wouldSwitch = true;
+                    //liquid phase has to disappear
+                    std::cout << "Liquid Phase disappears at vertex " << globalIdx
+                                << ", coordinated: " << globalPos << ", Sl: "
+                                << volVars.saturation(wPhaseIdx) << std::endl;
+                    newPhasePresence = nPhaseOnly;
+
+                    //switch not depending on formulation
+                    //switch "Sl" to "xgH20"
+                    globalSol[globalIdx][switchIdx]
+                            = volVars.fluidState().moleFraction(nPhaseIdx, wCompIdx /*H2O*/);
+                    //Here unlike 2pnc model we do not switch all components to to mole fraction in gas phase
+                }
+                //if saturation of gas phase is smaller than 0 switch
+                else if (volVars.saturation(nPhaseIdx) <= Smin)
+                {
+                    wouldSwitch = true;
+                    //gas phase has to disappear
+                    std::cout << "Gas Phase disappears at vertex " << globalIdx
+                                << ", coordinated: " << globalPos << ", Sg: "
+                                << volVars.saturation(nPhaseIdx) << std::endl;
+                    newPhasePresence = wPhaseOnly;
+
+                    //switch "Sl" to "xlN2"
+                    globalSol[globalIdx][switchIdx]
+                            = volVars.fluidState().moleFraction(wPhaseIdx, nCompIdx /*N2*/);
+                }
+            }
+            else if (phasePresence == nPhaseOnly)
+            {
+            Scalar sumxl = 0;
+            //Calculate sum of mole fractions (water and air) in the hypothetical liquid phase
+            //WARNING: Here numComponents is replaced by numMajorComponents as the solutes 
+            //are only present in the liquid phase and cannot condense as the liquid (water).
+            for (int compIdx = 0; compIdx < numMajorComponents; compIdx++)
+                {
+                    sumxl += volVars.fluidState().moleFraction(wPhaseIdx, compIdx);
+                }
+                    Scalar xlmax = 1.0;
+                    if (sumxl > xlmax)
+                wouldSwitch = true;
+                    if (this->staticDat_[globalIdx].wasSwitched)
+                xlmax *=1.02;
+
+            //if the sum of the mole fractions would be larger than
+            //1, wetting phase appears
+                    if (sumxl/*sum of mole fractions*/ > xlmax/*1*/)
+                    {
+                        // liquid phase appears
+                        std::cout << "Liquid Phase appears at vertex " << globalIdx
+                                << ", coordinated: " << globalPos << ", sumxl: "
+                                << sumxl << std::endl;
+                        newPhasePresence = bothPhases;
+                        if (formulation == pgSl)
+                            globalSol[globalIdx][switchIdx] = 0.0;
+                        else if (formulation == plSg)
+                            globalSol[globalIdx][switchIdx] = 1.0;
+                    //Here unlike 2pnc model we do not switch all components to to mole fraction in gas phase
+                    }
+            }
+            else if (phasePresence == wPhaseOnly)
+            {
+                Scalar xgmax = 1;
+                Scalar sumxg = 0;
+                //Calculate sum of mole fractions in the hypothetical liquid phase
+                for (int compIdx = 0; compIdx < numMajorComponents; compIdx++)
+                {
+                    sumxg += volVars.fluidState().moleFraction(nPhaseIdx, compIdx);
+                }
+                if (sumxg > xgmax)
+                    wouldSwitch = true;
+                if (this->staticDat_[globalIdx].wasSwitched)
+                    xgmax *=1.02;
+                //liquid phase appears if sum is larger than one
+                if (sumxg > xgmax)
+                {
+                    std::cout << "Gas Phase appears at vertex " << globalIdx
+                            << ", coordinated: " << globalPos << ", sumxg: "
+                            << sumxg << std::endl;
+                    newPhasePresence = bothPhases;
+                    //saturation of the liquid phase set to 0.9999 (if formulation pgSl and vice versa)
+                    if (formulation == pgSl)
+                        globalSol[globalIdx][switchIdx] = 0.999;
+                    else if (formulation == plSg)
+                        globalSol[globalIdx][switchIdx] = 0.001;
+
+                }
+            }
+            this->staticDat_[globalIdx].phasePresence = newPhasePresence;
+            this->staticDat_[globalIdx].wasSwitched = wouldSwitch;
+            return phasePresence != newPhasePresence;
+        }
+        // parameters given in constructor
+        bool switchFlag_;
+};
+
+}
+
+#include "2pncminpropertydefaults.hh"
+
+#endif
diff --git a/dumux/implicit/2pncmin/2pncminproperties.hh b/dumux/implicit/2pncmin/2pncminproperties.hh
new file mode 100644
index 0000000000..18e6c866e6
--- /dev/null
+++ b/dumux/implicit/2pncmin/2pncminproperties.hh
@@ -0,0 +1,63 @@
+// -*- 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 TwoPNCMinModel
+ *
+ * \file
+ *
+ * \brief Defines the properties required for the two-phase n-component mineralization
+ *        fully implicit model.
+ */
+#ifndef DUMUX_2PNCMIN_PROPERTIES_HH
+#define DUMUX_2PNCMIN_PROPERTIES_HH
+
+#include <dumux/implicit/2pnc/2pncproperties.hh>
+
+namespace Dumux
+{
+
+namespace Properties
+{
+//////////////////////////////////////////////////////////////////
+// Type tags
+//////////////////////////////////////////////////////////////////
+
+//! The type tag for the isothermal two phase n component mineralisation problems
+NEW_TYPE_TAG(BoxTwoPNCMin, INHERITS_FROM(BoxTwoPNC));
+
+//////////////////////////////////////////////////////////////////
+// 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(TwoPNCMinIndices); //!< Enumerations for the 2pncMin models
+NEW_PROP_TAG(useSalinity); //!< Determines if salinity is used
+NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
+
+}
+}
+
+#endif
diff --git a/dumux/implicit/2pncmin/2pncminpropertydefaults.hh b/dumux/implicit/2pncmin/2pncminpropertydefaults.hh
new file mode 100644
index 0000000000..516ee45bc6
--- /dev/null
+++ b/dumux/implicit/2pncmin/2pncminpropertydefaults.hh
@@ -0,0 +1,129 @@
+// -*- 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 TwoPNCMinModel
+ * \file
+ *
+ * \brief Defines default values for most properties required by the
+ *        two-phase n-component mineralization fully implicit model.
+ */
+#ifndef DUMUX_2PNCMIN_PROPERTY_DEFAULTS_HH
+#define DUMUX_2PNCMIN_PROPERTY_DEFAULTS_HH
+
+#include "2pncminindices.hh"
+#include "2pncminmodel.hh"
+#include "2pncminindices.hh"
+#include "2pncminfluxvariables.hh"
+#include "2pncminvolumevariables.hh"
+#include "2pncminproperties.hh"
+
+#include <dumux/implicit/2pnc/2pncnewtoncontroller.hh>
+#include <dumux/implicit/common/implicitdarcyfluxvariables.hh>
+#include <dumux/material/spatialparams/implicitspatialparams.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(BoxTwoPNCMin, NumSecComponents)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numSecComponents;
+
+};
+/*!
+ * \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(BoxTwoPNCMin, 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(BoxTwoPNCMin, NumEq)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numComponents + FluidSystem::numSPhases;
+};
+
+//! Use the 2pncmin local residual operator
+SET_TYPE_PROP(BoxTwoPNCMin,
+              LocalResidual,
+              TwoPNCMinLocalResidual<TypeTag>);
+
+//! the Model property
+SET_TYPE_PROP(BoxTwoPNCMin, Model, TwoPNCMinModel<TypeTag>);
+
+//! the VolumeVariables property
+SET_TYPE_PROP(BoxTwoPNCMin, VolumeVariables, TwoPNCMinVolumeVariables<TypeTag>);
+
+//! the FluxVariables property
+SET_TYPE_PROP(BoxTwoPNCMin, FluxVariables, TwoPNCMinFluxVariables<TypeTag>);
+
+//! The indices required by the isothermal 2pNcMin model
+SET_TYPE_PROP(BoxTwoPNCMin, Indices, TwoPNCMinIndices <TypeTag, /*PVOffset=*/0>);
+
+//! disable useSalinity for the calculation of osmotic pressure by default
+SET_BOOL_PROP(BoxTwoPNCMin, useSalinity, false);
+
+
+//! 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(BoxModel, SpatialParamsForchCoeff, 0.55);
+
+}
+
+}
+
+#endif
diff --git a/dumux/implicit/2pncmin/2pncminvolumevariables.hh b/dumux/implicit/2pncmin/2pncminvolumevariables.hh
new file mode 100644
index 0000000000..e3b5883083
--- /dev/null
+++ b/dumux/implicit/2pncmin/2pncminvolumevariables.hh
@@ -0,0 +1,554 @@
+// -*- 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_2PNCMin_VOLUME_VARIABLES_HH
+#define DUMUX_2PNCMin_VOLUME_VARIABLES_HH
+
+#include <dumux/implicit/common/implicitmodel.hh>
+#include <dumux/material/fluidstates/compositionalfluidstate.hh>
+#include <dumux/common/math.hh>
+#include <dune/common/collectivecommunication.hh>
+#include <vector>
+#include <iostream>
+
+#include "2pncminproperties.hh"
+#include "2pncminindices.hh"
+#include <dumux/material/constraintsolvers/computefromreferencephase2pnc.hh>
+#include <dumux/material/constraintsolvers/miscible2pnccomposition.hh>
+#include <dumux/implicit/2pnc/2pncvolumevariables.hh>
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup TwoPNCMinModel
+ * \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 TwoPNCMinVolumeVariables : public TwoPNCVolumeVariables<TypeTag>
+{
+    typedef TwoPNCVolumeVariables<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+//     typedef typename GET_PROP_TYPE(TypeTag, Chemistry) Chemistry;
+
+    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),
+        numMajorComponents = GET_PROP_VALUE(TypeTag, NumMajorComponents),
+
+        // formulations
+        formulation = GET_PROP_VALUE(TypeTag, Formulation),
+        plSg = TwoPNCFormulation::plSg,
+        pgSl = TwoPNCFormulation::pgSl,
+
+        // phase indices
+        wPhaseIdx = FluidSystem::wPhaseIdx,
+        nPhaseIdx = FluidSystem::nPhaseIdx,
+
+        // component indices
+        wCompIdx = FluidSystem::wCompIdx,
+        nCompIdx = FluidSystem::nCompIdx,
+
+        // phase presence enums
+        nPhaseOnly = Indices::nPhaseOnly,
+        wPhaseOnly = Indices::wPhaseOnly,
+        bothPhases = Indices::bothPhases,
+
+        // primary variable indices
+        pressureIdx = Indices::pressureIdx,
+        switchIdx = Indices::switchIdx,
+
+        useSalinity = GET_PROP_VALUE(TypeTag, useSalinity)
+    };
+
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+    typedef typename Grid::ctype CoordScalar;
+    typedef Dumux::Miscible2pNcComposition<Scalar, FluidSystem> Miscible2pNcComposition;
+    typedef Dumux::ComputeFromReferencePhase2pNc<Scalar, FluidSystem> ComputeFromReferencePhase2pNc;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+public:
+  
+      //! The type of the object returned by the fluidState() method
+      typedef CompositionalFluidState<Scalar, FluidSystem> FluidState;
+    /*!
+     * \copydoc ImplicitVolumeVariables::update
+     */
+    void update(const PrimaryVariables &priVars,
+                const Problem &problem,
+                const Element &element,
+                const FVElementGeometry &fvGeometry,
+                int scvIdx,
+                bool isOldSol)
+    {
+        ParentType::update(priVars,
+                           problem,
+                           element,
+                           fvGeometry,
+                           scvIdx,
+                           isOldSol);
+
+        completeFluidState(priVars, problem, element, fvGeometry, scvIdx, this->fluidState_, isOldSol);
+
+    /////////////
+        // calculate the remaining quantities
+        /////////////
+
+    // porosity evaluation
+    initialPorosity_ = problem.spatialParams().porosity(element, fvGeometry, scvIdx);
+
+    sumPrecipitates_ = 0.0;
+    for(int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
+    {
+       precipitateVolumeFraction_[sPhaseIdx] = priVars[numComponents + sPhaseIdx];
+       sumPrecipitates_+= precipitateVolumeFraction_[sPhaseIdx];
+    }
+    
+//         for(int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
+//     {
+//         Chemistry chemistry; // the non static functions can not be called without abject 
+//         saturationIdx_[sPhaseIdx] = chemistry.omega(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_ = initialPorosity_ - sumPrecipitates_;
+
+   this->porosity_ = std::max(0.1, std::max(0.0, initialPorosity_ - sumPrecipitates_));
+
+   salinity_= 0.0;
+   moleFractionSalinity_ = 0.0;
+   for (int compIdx = numMajorComponents; compIdx< numComponents; compIdx++)	//sum of the mass fraction of the components
+   {
+       if(this->fluidState_.moleFraction(wPhaseIdx, compIdx)> 0)
+       {
+          salinity_+= this->fluidState_.massFraction(wPhaseIdx, compIdx);
+          moleFractionSalinity_ += this->fluidState_.moleFraction(wPhaseIdx, compIdx);
+       }
+    }
+
+// TODO/FIXME: Different relations for the porosoty-permeability changes are given here. We have to fins a way
+//    so that one can select the relation form the input file.
+
+    // kozeny-Carman relation
+    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_(priVars, problem,element, fvGeometry, scvIdx, isOldSol);
+    }
+
+   /*!
+    * \copydoc ImplicitModel::completeFluidState
+    * \param isOldSol Specifies whether this is the previous solution or the current one
+    */
+  static void completeFluidState(const PrimaryVariables& priVars,
+                                 const Problem& problem,
+                                 const Element& element,
+                                 const FVElementGeometry& fvGeometry,
+                                 int scvIdx,
+                                 FluidState& fluidState,
+                                 bool isOldSol = false)
+
+    {
+        Scalar t = Implementation::temperature_(priVars, problem, element,fvGeometry, scvIdx);
+        fluidState.setTemperature(t);
+
+#if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
+        int dofIdxGlobal = problem.model().dofMapper().subIndex(element, scvIdx, dofCodim);
+#else
+        int dofIdxGlobal = problem.model().dofMapper().map(element, scvIdx, dofCodim);
+#endif   
+        int phasePresence = problem.model().phasePresence(dofIdxGlobal, isOldSol);
+
+        /////////////
+        // set the saturations
+        /////////////
+
+        Scalar Sg;
+        if (phasePresence == nPhaseOnly)
+            Sg = 1.0;
+        else if (phasePresence == wPhaseOnly) {
+            Sg = 0.0;
+        }
+        else if (phasePresence == bothPhases) {
+            if (formulation == plSg)
+                Sg = priVars[switchIdx];
+            else if (formulation == pgSl)
+                Sg = 1.0 - priVars[switchIdx];
+            else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
+        }
+        else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid.");
+        fluidState.setSaturation(nPhaseIdx, Sg);
+        fluidState.setSaturation(wPhaseIdx, 1.0 - Sg);
+
+        /////////////
+        // set the pressures of the fluid phases
+        /////////////
+
+        // calculate capillary pressure
+        const MaterialLawParams &materialParams = problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
+        Scalar pc = MaterialLaw::pc(materialParams, 1 - Sg);
+
+        // extract the pressures
+        if (formulation == plSg) {
+            fluidState.setPressure(wPhaseIdx, priVars[pressureIdx]);
+            fluidState.setPressure(nPhaseIdx, priVars[pressureIdx] + pc);
+        }
+        else if (formulation == pgSl) {
+            fluidState.setPressure(nPhaseIdx, priVars[pressureIdx]);
+            fluidState.setPressure(wPhaseIdx, priVars[pressureIdx] - pc);
+        }
+        else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
+
+        /////////////
+        // calculate the phase compositions
+        /////////////
+
+    typename FluidSystem::ParameterCache paramCache;
+
+        // now comes the tricky part: calculate phase composition
+        if (phasePresence == bothPhases) {
+            // both phases are present, phase composition results from
+            // the gas <-> liquid equilibrium. This is
+            // the job of the "MiscibleMultiPhaseComposition"
+            // constraint solver
+
+            // set the known mole fractions in the fluidState so that they
+            // can be used by the Miscible2pNcComposition constraint solver
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+            	fluidState.setMoleFraction(wPhaseIdx, compIdx, priVars[compIdx]);
+            }
+
+            Miscible2pNcComposition::solve(fluidState,
+                                            paramCache,
+                                            wPhaseIdx,	//known phaseIdx
+                                            /*setViscosity=*/true,
+                                            /*setInternalEnergy=*/false);
+        }
+        else if (phasePresence == nPhaseOnly){
+
+            Dune::FieldVector<Scalar, numComponents> moleFrac;
+            Dune::FieldVector<Scalar, numComponents> fugCoeffL;
+            Dune::FieldVector<Scalar, numComponents> fugCoeffG;
+
+            for (int compIdx=0; compIdx<numComponents; ++compIdx)
+            {
+                fugCoeffL[compIdx] = FluidSystem::fugacityCoefficient(fluidState,
+                                        paramCache,
+                                        wPhaseIdx,
+                                        compIdx);
+                fugCoeffG[compIdx] = FluidSystem::fugacityCoefficient(fluidState,
+                                        paramCache,
+                                        nPhaseIdx,
+                                        compIdx);
+            }
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+                moleFrac[compIdx] = (priVars[compIdx]*fugCoeffL[compIdx]*fluidState.pressure(wPhaseIdx))
+                /(fugCoeffG[compIdx]*fluidState.pressure(nPhaseIdx));
+            
+            moleFrac[wCompIdx] =  priVars[switchIdx];
+            Scalar sumMoleFracNotGas = 0;
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+            		sumMoleFracNotGas+=moleFrac[compIdx];
+            }
+            sumMoleFracNotGas += moleFrac[wCompIdx];
+            moleFrac[nCompIdx] = 1 - sumMoleFracNotGas;
+
+//          typedef Dune::FieldMatrix<Scalar, numComponents, numComponents> Matrix;
+//          typedef Dune::FieldVector<Scalar, numComponents> Vector;
+
+
+            // Set fluid state mole fractions
+            for (int compIdx=0; compIdx<numComponents; ++compIdx)
+            {
+            	fluidState.setMoleFraction(nPhaseIdx, compIdx, moleFrac[compIdx]);
+            }
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). this is the job
+            // of the "ComputeFromReferencePhase2pNc" constraint solver
+            ComputeFromReferencePhase2pNc::solve(fluidState,
+                                             paramCache,
+                                             nPhaseIdx,
+                                             /*setViscosity=*/true,
+                                             /*setInternalEnergy=*/false);
+
+            }
+        else if (phasePresence == wPhaseOnly){
+        
+        // only the liquid phase is present, i.e. liquid phase
+        // composition is stored explicitly.
+        // extract _mass_ fractions in the gas phase
+            Dune::FieldVector<Scalar, numComponents> moleFrac;
+
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+            	moleFrac[compIdx] = priVars[compIdx];
+            }
+            moleFrac[nCompIdx] = priVars[switchIdx];
+            Scalar sumMoleFracNotWater = 0;
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+            		sumMoleFracNotWater+=moleFrac[compIdx];
+            }
+            sumMoleFracNotWater += moleFrac[nCompIdx];
+            moleFrac[wCompIdx] = 1 -sumMoleFracNotWater;
+
+//             convert mass to mole fractions and set the fluid state
+            for (int compIdx=0; compIdx<numComponents; ++compIdx)
+            {
+                fluidState.setMoleFraction(wPhaseIdx, compIdx, moleFrac[compIdx]);
+            }
+
+//             calculate the composition of the remaining phases (as
+//             well as the densities of all phases). this is the job
+//             of the "ComputeFromReferencePhase2pNc" constraint solver
+            ComputeFromReferencePhase2pNc::solve(fluidState,
+                                             paramCache,
+                                             wPhaseIdx,
+                                             /*setViscosity=*/true,
+                                             /*setInternalEnergy=*/false);
+        }
+        paramCache.updateAll(fluidState);
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            Scalar h = Implementation::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 permFactor() const
+    { return permeabilityFactor_; }
+    
+    /*!
+     * \brief Returns the mole fraction of a component in the phase
+     * 
+     * \param phaseIdx the index of the fluid phase
+     * \param compIdx the index of the component
+     */ 
+    Scalar moleFraction(int phaseIdx, int compIdx) const
+    {
+       return this->fluidState_.moleFraction(phaseIdx, compIdx);
+    }
+    
+    /*!
+     * \brief Returns the mole fraction of the salinity in the liquid phase
+     */
+    Scalar moleFracSalinity() const
+    {
+    	return moleFractionSalinity_;
+    }
+    
+    /*!
+     * \brief Returns the salinity (mass fraction) in the liquid phase
+     */
+    Scalar salinity() const
+    {
+        return salinity_;
+    }
+    
+    /*!
+     * \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);
+#if SALINIZATION
+        else if (phaseIdx >= numPhases)
+        return FluidSystem::precipitateDensity(phaseIdx);
+#endif
+        else
+            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
+    }
+    /*!
+        * \brief Returns the liquid vapor pressure within the control volume.
+        */
+#if SALINIZATION
+    Scalar vaporPressure() const
+    { return FluidSystem::vaporPressure(this->fluidState_.temperature(/*phaseIdx=*/0),this->fluidState_.moleFraction(wPhaseIdx, FluidSystem::NaClIdx)); }
+#endif
+
+    /*!
+     * \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 < numPhases)
+            return this->fluidState_.molarDensity(phaseIdx);
+#if SALINIZATION
+        else if (phaseIdx >= numPhases)
+            return FluidSystem::precipitateMolarDensity(phaseIdx);
+#endif
+        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
+     */ 
+     Scalar molality(int phaseIdx, int compIdx) const // [moles/Kg]
+    { return this->fluidState_.moleFraction(phaseIdx, compIdx)/FluidSystem::molarMass(compIdx);}
+
+protected:
+    friend class TwoPNCVolumeVariables<TypeTag>;
+    static Scalar temperature_(const PrimaryVariables &priVars,
+                                const Problem& problem,
+                                const Element &element,
+                                const FVElementGeometry &fvGeometry,
+                                int scvIdx)
+    {
+        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
+    }
+    
+    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 PrimaryVariables &priVars,
+                           const Problem &problem,
+                           const Element &element,
+                           const FVElementGeometry &fvGeometry,
+                           const int scvIdx,
+                           bool isOldSol)
+        { };
+
+    Scalar precipitateVolumeFraction_[numSPhases];
+//     Scalar saturationIdx_[numSPhases];
+    Scalar permeabilityFactor_;
+    Scalar initialPorosity_;
+    Scalar InitialPermeability_;
+    Scalar sumPrecipitates_;
+    Scalar salinity_;
+    Scalar moleFractionSalinity_;
+
+private:
+    Implementation &asImp_()
+    { return *static_cast<Implementation*>(this); }
+
+    const Implementation &asImp_() const
+    { return *static_cast<const Implementation*>(this); }
+};
+
+} // end namespace
+
+#endif
-- 
GitLab