From d3be24fdad7f56645bf8b86e5108336d12336e9d Mon Sep 17 00:00:00 2001
From: Simon Scholz <simon.scholz@iws.uni-stuttgart.de>
Date: Thu, 7 Dec 2017 15:19:02 +0100
Subject: [PATCH] [min] introduce mineralization folder with localresidual,
 model (former properties), volVars and VTK output

---
 dumux/porousmediumflow/CMakeLists.txt         |   1 +
 .../mineralization/CMakeLists.txt             |   7 +
 .../mineralization/localresidual.hh           |  92 +++++++++++
 .../porousmediumflow/mineralization/model.hh  |  73 +++++++++
 .../mineralization/volumevariables.hh         | 152 ++++++++++++++++++
 .../mineralization/vtkoutputfields.hh         |  61 +++++++
 6 files changed, 386 insertions(+)
 create mode 100644 dumux/porousmediumflow/mineralization/CMakeLists.txt
 create mode 100644 dumux/porousmediumflow/mineralization/localresidual.hh
 create mode 100644 dumux/porousmediumflow/mineralization/model.hh
 create mode 100644 dumux/porousmediumflow/mineralization/volumevariables.hh
 create mode 100644 dumux/porousmediumflow/mineralization/vtkoutputfields.hh

diff --git a/dumux/porousmediumflow/CMakeLists.txt b/dumux/porousmediumflow/CMakeLists.txt
index 33c612c76a..602b161d2c 100644
--- a/dumux/porousmediumflow/CMakeLists.txt
+++ b/dumux/porousmediumflow/CMakeLists.txt
@@ -12,6 +12,7 @@ add_subdirectory("co2")
 add_subdirectory("compositional")
 add_subdirectory("immiscible")
 add_subdirectory("implicit")
+add_subdirectory("mineralization")
 add_subdirectory("mpnc")
 add_subdirectory("nonisothermal")
 add_subdirectory("richards")
diff --git a/dumux/porousmediumflow/mineralization/CMakeLists.txt b/dumux/porousmediumflow/mineralization/CMakeLists.txt
new file mode 100644
index 0000000000..783fba4a28
--- /dev/null
+++ b/dumux/porousmediumflow/mineralization/CMakeLists.txt
@@ -0,0 +1,7 @@
+#install headers
+install(FILES
+localresidual.hh
+model.hh
+volumevariables.hh
+vtkoutputfields.hh
+DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/porousmediumflow/mineralization)
\ No newline at end of file
diff --git a/dumux/porousmediumflow/mineralization/localresidual.hh b/dumux/porousmediumflow/mineralization/localresidual.hh
new file mode 100644
index 0000000000..af85e08c67
--- /dev/null
+++ b/dumux/porousmediumflow/mineralization/localresidual.hh
@@ -0,0 +1,92 @@
+// -*- 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 local residual for problems using a
+ *        compositional fully implicit model that also considers solid phases.
+ */
+#ifndef DUMUX_COMPOSITIONAL_MINERALIZATION_LOCAL_RESIDUAL_HH
+#define DUMUX_COMPOSITIONAL_MINERALIZATION_LOCAL_RESIDUAL_HH
+
+#include <dumux/porousmediumflow/compositional/localresidual.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup Mineralization
+ * \ingroup LocalResidual
+ * \brief Element-wise calculation of the local residual for problems
+ *        using a one/two-phase n-component mineralization fully implicit model.
+ */
+template<class TypeTag>
+class MineralizationLocalResidual: public CompositionalLocalResidual<TypeTag>
+{
+    using ParentType = CompositionalLocalResidual<TypeTag>;
+    using ResidualVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
+    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+
+    static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases);
+    static constexpr int numSPhases = GET_PROP_VALUE(TypeTag, NumSPhases);
+    static constexpr int numComponents = GET_PROP_VALUE(TypeTag, NumComponents);
+    static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
+
+    enum { conti0EqIdx = Indices::conti0EqIdx };
+
+public:
+    using ParentType::ParentType;
+
+    /*!
+     * \brief Evaluate the amount of 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)
+     *
+     *  \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
+     */
+    ResidualVector computeStorage(const Problem& problem,
+                                  const SubControlVolume& scv,
+                                  const VolumeVariables& volVars) const
+    {
+        auto storage = ParentType::computeStorage(problem, scv, volVars);
+
+        const auto massOrMoleDensity = [](const auto& volVars, const int phaseIdx)
+        { return useMoles ? volVars.molarDensity(phaseIdx) : volVars.density(phaseIdx); };
+
+        // compute storage term of all components within all fluid phases
+        for (int phaseIdx = numPhases; phaseIdx < numPhases + numSPhases; ++phaseIdx)
+        {
+            auto eqIdx = conti0EqIdx + numComponents-numPhases + phaseIdx;
+            storage[eqIdx] += volVars.precipitateVolumeFraction(phaseIdx)
+                             * massOrMoleDensity(volVars, phaseIdx);
+        }
+
+        return storage;
+    }
+};
+
+} // end namespace Dumux
+
+#endif
diff --git a/dumux/porousmediumflow/mineralization/model.hh b/dumux/porousmediumflow/mineralization/model.hh
new file mode 100644
index 0000000000..6ec7775ac4
--- /dev/null
+++ b/dumux/porousmediumflow/mineralization/model.hh
@@ -0,0 +1,73 @@
+// -*- 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 Mineralization
+ * \file
+ *
+ * \brief Defines the properties required for the
+ *        implicit mineralization models.
+ */
+
+#ifndef DUMUX_MINERALIZATION_MODEL_HH
+#define DUMUX_MINERALIZATION_MODEL_HH
+
+#include <dumux/common/properties.hh>
+#include "localresidual.hh"
+#include "volumevariables.hh"
+#include "vtkoutputfields.hh"
+
+namespace Dumux {
+namespace Properties {
+//////////////////////////////////////////////////////////////////
+// Type tags
+//////////////////////////////////////////////////////////////////
+NEW_TYPE_TAG(Mineralization);
+
+//! Set the general mineralization volume variables
+SET_TYPE_PROP(Mineralization, VolumeVariables, MineralizationVolumeVariables<TypeTag>);
+
+//! Set the general mineralization compositional local residual
+SET_TYPE_PROP(Mineralization, LocalResidual, MineralizationLocalResidual<TypeTag>);
+
+//! VTK outputs for mineralization models
+SET_TYPE_PROP(Mineralization, VtkOutputFields, MineralizationVtkOutputFields<TypeTag>);
+
+//! Set the property for the number of solid phases, excluding the non-reactive matrix.
+SET_PROP(Mineralization, NumSPhases)
+{
+private:
+    using FluidSystem = typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem));
+public:
+    static const int value = FluidSystem::numSPhases;
+};
+
+//! 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(Mineralization, NumEq)
+{
+private:
+    using FluidSystem = typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem));
+public:
+    static const int value = FluidSystem::numComponents + FluidSystem::numSPhases;
+};
+
+} // end namespace Properties
+} // end namespace Dumux
+
+#endif
diff --git a/dumux/porousmediumflow/mineralization/volumevariables.hh b/dumux/porousmediumflow/mineralization/volumevariables.hh
new file mode 100644
index 0000000000..adc516930a
--- /dev/null
+++ b/dumux/porousmediumflow/mineralization/volumevariables.hh
@@ -0,0 +1,152 @@
+// -**- 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_MINERALIZATION_VOLUME_VARIABLES_HH
+#define DUMUX_MINERALIZATION_VOLUME_VARIABLES_HH
+
+#include <dumux/common/math.hh>
+
+#include <dumux/material/fluidstates/compositional.hh>
+#include <dumux/discretization/volumevariables.hh>
+
+#include "model.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup Mineralization
+ * \ingroup ImplicitVolumeVariables
+ * \brief Contains the quantities which are are constant within a
+ *        finite volume in a mineralization n-component model.
+ */
+template <class TypeTag>
+class MineralizationVolumeVariables : public GET_PROP_TYPE(TypeTag, NonMineralizationVolumeVariables)
+{
+    using ParentType = typename GET_PROP_TYPE(TypeTag, NonMineralizationVolumeVariables);
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector);
+    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+    using MaterialLawParams = typename GET_PROP_TYPE(TypeTag, MaterialLaw)::Params;
+    using Element = typename GridView::template Codim<0>::Entity;
+
+    enum
+    {
+        dimWorld=GridView::dimensionworld,
+
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numSPhases =  GET_PROP_VALUE(TypeTag, NumSPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+    };
+
+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)
+    {
+        // Update parent type (also completes the fluid state)
+        ParentType::update(elemSol, problem, element, scv);
+
+        /////////////
+        // calculate the remaining quantities
+        /////////////
+        auto&& priVars = elemSol[scv.indexInElement()];
+
+        sumPrecipitates_ = 0.0;
+        for(int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
+        {
+           precipitateVolumeFraction_[sPhaseIdx] = priVars[numComponents + sPhaseIdx];
+           sumPrecipitates_+= precipitateVolumeFraction_[sPhaseIdx];
+        }
+    }
+
+    /*!
+     * \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 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
+            return FluidSystem::precipitateDensity(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 < numPhases)
+            return this->fluidState_.molarDensity(phaseIdx);
+        else
+            return FluidSystem::precipitateMolarDensity(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));
+    }
+
+protected:
+    Scalar precipitateVolumeFraction_[numSPhases];
+    Scalar sumPrecipitates_;
+};
+} // end namespace Dumux
+
+#endif
diff --git a/dumux/porousmediumflow/mineralization/vtkoutputfields.hh b/dumux/porousmediumflow/mineralization/vtkoutputfields.hh
new file mode 100644
index 0000000000..70e7a2acf5
--- /dev/null
+++ b/dumux/porousmediumflow/mineralization/vtkoutputfields.hh
@@ -0,0 +1,61 @@
+// -*- 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 Adds vtk output fields specific to the twop-nc-min model
+ */
+#ifndef DUMUX_MINERALIZATION_VTK_OUTPUT_FIELDS_HH
+#define DUMUX_MINERALIZATION_VTK_OUTPUT_FIELDS_HH
+
+#include <dumux/common/properties.hh>
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup Mineralization, InputOutput
+ * \brief Adds vtk output fields specific to the a NCMin model
+ */
+template<class TypeTag>
+class MineralizationVtkOutputFields
+{
+    using NonMineralizationVtkOutputFields = typename GET_PROP_TYPE(TypeTag, NonMineralizationVtkOutputFields);
+    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+
+    static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases);
+    static constexpr int numSPhases = GET_PROP_VALUE(TypeTag, NumSPhases);
+
+public:
+    template <class VtkOutputModule>
+    static void init(VtkOutputModule& vtk)
+    {
+        NonMineralizationVtkOutputFields::init(vtk);
+
+        //additional output
+        for (int i = 0; i < numSPhases; ++i)
+        {
+            vtk.addVolumeVariable([i](const VolumeVariables& v){ return v.precipitateVolumeFraction(numPhases + i); },"precipVolFrac_"+ FluidSystem::phaseName(numPhases + i));
+        }
+    }
+};
+
+} // end namespace Dumux
+
+#endif
-- 
GitLab