From 4d9a6535e6e3bf0753554544d46f06ca95510f1a Mon Sep 17 00:00:00 2001
From: Gabriele Seitz <gabriele.seitz@iws.uni-stuttgart.de>
Date: Mon, 26 Jun 2017 17:17:38 +0200
Subject: [PATCH] [1pncmin] add problem

not running yet
---
 test/porousmediumflow/1pncmin/CMakeLists.txt  |   1 +
 .../1pncmin/implicit/CMakeLists.txt           |  50 ++
 .../1pncmin/implicit/test_2pnc.input          |  71 +++
 .../1pncmin/implicit/test_box2pnc.cc          |  55 ++
 .../1pncmin/implicit/thermochemproblem.hh     | 571 ++++++++++++++++++
 .../implicit/thermochemspatialparams.hh       | 283 +++++++++
 test/porousmediumflow/CMakeLists.txt          |   1 +
 7 files changed, 1032 insertions(+)
 create mode 100644 test/porousmediumflow/1pncmin/CMakeLists.txt
 create mode 100644 test/porousmediumflow/1pncmin/implicit/CMakeLists.txt
 create mode 100644 test/porousmediumflow/1pncmin/implicit/test_2pnc.input
 create mode 100644 test/porousmediumflow/1pncmin/implicit/test_box2pnc.cc
 create mode 100644 test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh
 create mode 100644 test/porousmediumflow/1pncmin/implicit/thermochemspatialparams.hh

diff --git a/test/porousmediumflow/1pncmin/CMakeLists.txt b/test/porousmediumflow/1pncmin/CMakeLists.txt
new file mode 100644
index 0000000000..ba8341c614
--- /dev/null
+++ b/test/porousmediumflow/1pncmin/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory("implicit")
diff --git a/test/porousmediumflow/1pncmin/implicit/CMakeLists.txt b/test/porousmediumflow/1pncmin/implicit/CMakeLists.txt
new file mode 100644
index 0000000000..941775ea72
--- /dev/null
+++ b/test/porousmediumflow/1pncmin/implicit/CMakeLists.txt
@@ -0,0 +1,50 @@
+# isothermal tests
+
+add_input_file_links()
+
+add_executable(test_box2pnc test_box2pnc.cc)
+
+#add_executable_all(test_box1p2c test_box1p2c.cc)
+#
+# add_executable_all(test_cc1p2c test_cc1p2c.cc)
+
+# dune_symlink_to_source_files(FILES test_2pnc.input)
+# # dune_symlink_to_source_files(FILES test_box2pnc.input)
+# dune_symlink_to_source_files(FILES test_box1p2c.input)
+# dune_symlink_to_source_files(FILES test_cc1p2c.input)
+
+# set(BUILD_TYPE Debug)
+
+#install sources
+# install(FILES
+# thermochemproblem.hh
+# thermochemspatialparams.hh
+# test_box2pnc.cc
+# test_cc2pnc.cc
+# DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux-devel/appl/thermochemistry)
+
+
+# # isothermal tests
+# add_dumux_test(test_box2pnc test_box2pnc test_box2pnc.cc
+#                python ${dumux_INCLUDE_DIRS}/bin/testing/runtest.py
+#                  --script fuzzy
+#                  --files ${CMAKE_SOURCE_DIR}/test/references/fuelcell2pncbox-reference.vtu
+#                          ${CMAKE_CURRENT_BINARY_DIR}/fuelcell-box-00016.vtu
+#                  --command "${CMAKE_CURRENT_BINARY_DIR}/test_box2pnc -ParameterFile test_2pnc.input -Problem.Name fuelcell-box")
+#
+# add_dumux_test(test_cc2pnc test_cc2pnc test_cc2pnc.cc
+#                python ${dumux_INCLUDE_DIRS}/bin/testing/runtest.py
+#                  --script fuzzy
+#                  --files ${CMAKE_SOURCE_DIR}/test/references/fuelcell2pnccc-reference.vtu
+#                          ${CMAKE_CURRENT_BINARY_DIR}/fuelcell-cc-00016.vtu
+#                  --command "${CMAKE_CURRENT_BINARY_DIR}/test_cc2pnc -ParameterFile test_2pnc.input -Problem.Name fuelcell-cc")
+#
+# dune_symlink_to_source_files(FILES test_2pnc.input)
+#
+# #install sources
+# install(FILES
+# thermochemproblem.hh
+# thermochemspatialparams.hh
+# test_box2pnc.cc
+# test_cc2pnc.cc
+# DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/test/implicit/2pnc)
diff --git a/test/porousmediumflow/1pncmin/implicit/test_2pnc.input b/test/porousmediumflow/1pncmin/implicit/test_2pnc.input
new file mode 100644
index 0000000000..51c2ebb610
--- /dev/null
+++ b/test/porousmediumflow/1pncmin/implicit/test_2pnc.input
@@ -0,0 +1,71 @@
+# Parameter file for test case 2pnc.
+# Everything behind a '#' is a comment.
+# Type "./test_2pnc --help" for more information.
+
+[TimeManager]
+DtInitial = 1                      # [s] initial time step size
+MaxTimeStepSize = 50               # [s] maximum time step size
+TEnd= 5000                        # [s] duration of the simulation
+FreqOutput          = 10           # frequency of VTK output
+WriteRestartFile    = 1            # Boolean. Should restart files be written? (1) Yes (0) No
+
+[Grid]
+UpperRight = 0.08 0.01 #20 10 #     # [m] upper right corner coordinates
+Cells =  40 2 # 21 6                # [-] number of cells in x,y-direction
+
+[FluidSystem]
+NTemperature = 10                   # [-] number of tabularization entries
+NPressure = 100                     # [-] number of tabularization entries
+PressureLow = 1E5                   # [Pa]low end for tabularization of fluid properties
+PressureHigh = 1E6                  # [Pa]high end for tabularization of fluid properties
+TemperatureLow = 373.15             # [Pa]low end for tabularization of fluid properties
+TemperatureHigh = 873.15            # [Pa]high end for tabularization of fluid properties
+
+[Problem]
+Name = thermochem
+IsCharge = 0                       # Bool: 1: charge; 0: discharge
+
+[Charge]
+PressureInitial = 1E5              # [Pa] Initial reservoir pressure
+TemperatureInitial = 773.15        # [K]  reservoir temperature
+VaporInitial = 0.01                # [-]  initial mole fraction of water
+CaOInitial = 0.0                   # [-]  molefraction in the solid phase;  0 dehydration/charge, 1  hydration/discharge
+CaO2H2Initial = 0.3960             # [-]  molefraction in the solid phase;  0 dehydration/charge, 1  hydration/discharge
+PressureIn = 1.02e5                # [Pa] Inlet pressure; charge
+PressureOut = 1e5                  # [Pa] outlet pressure
+TemperatureIn = 773.15             # [K] inlet temperature: // Shao 500 °C
+TemperatureOut = 773.15            # [K] outlet temperature: // Shao noflow
+InFlow = 5                         # [mol/s] Inflow of HTF // Shao 0.309 g/s (Area (0.015)^2pi m^2) --> here 1.55 mol/s
+VaporIn = 0.01                     # [] molefraction // Shao 0.01 [g/g]
+
+[Discharge]
+PressureInitial = 1E5              # [Pa] Initial reservoir pressure
+TemperatureInitial = 573.15        # [K]  reservoir temperature
+VaporInitial = 0.35                # [-]  initial mole fraction of water
+CaOInitial = 0.2                   # [-]  molefraction in the solid phase;  0 dehydration/charge, 1  hydration/discharge
+CaO2H2Initial = 0.0
+PressureIn = 1.05e5                # [Pa] Inlet pressure; charge
+PressureOut = 1e5                  # [Pa] outlet pressure
+TemperatureIn = 573.15             # [K] inlet temperature: charge: 873 K ; discharge: 473K
+TemperatureOut = 573.15            # [K] outlet temperature: charge:  573; discharge: outflow
+InFlow = 5                         # 0.277[mol/s] Inflow of HTF
+VaporIn = 0.36                     # [] molefraction
+
+[Vtk]
+AddVelocity         = 1            # Add extra information
+VtuWritingFreq      = 1            # 1: write a vtu file at every timestep, 2: write a vtu file every second timestep ...
+
+[LinearSolver]
+ResidualReduction = 1e-6
+
+[Newton]
+MaxRelativeShift = 1e-6
+2WriteConvergence = 1
+
+[Output]
+#Frequency of restart file, flux and VTK output
+FreqRestart = 1000                 # how often restart files are written out
+FreqOutput = 50                    # frequency of VTK output
+FreqMassOutput = 2                 # frequency of mass and evaporation rate output (Darcy)
+FreqFluxOutput = 1000              # frequency of detailed flux output
+FreqVaporFluxOutput = 2            # frequency of summarized flux output
\ No newline at end of file
diff --git a/test/porousmediumflow/1pncmin/implicit/test_box2pnc.cc b/test/porousmediumflow/1pncmin/implicit/test_box2pnc.cc
new file mode 100644
index 0000000000..fc844ca2b9
--- /dev/null
+++ b/test/porousmediumflow/1pncmin/implicit/test_box2pnc.cc
@@ -0,0 +1,55 @@
+// -*- 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 Test for the 2pnc box model used for water management in PEM fuel cells.
+ */
+#include <config.h>
+#include "thermochemproblem.hh"
+#include <dumux/common/start.hh>
+
+/*!
+ * \brief Provides an interface for customizing error messages associated with
+ *        reading in parameters.
+ *
+ * \param progName  The name of the program, that was tried to be started.
+ * \param errorMsg  The error message that was issued by the start function.
+ *                  Comprises the thing that went wrong and a general help message.
+ */
+void usage(const char *progName, const std::string &errorMsg)
+{
+    if (errorMsg.size() > 0) {
+        std::string errorMessageOut = "\nUsage: ";
+                    errorMessageOut += progName;
+                    errorMessageOut += " [options]\n";
+                    errorMessageOut += errorMsg;
+                    errorMessageOut += "\n\nThe list of mandatory options for this program is:\n"
+                                        "\t-ParameterFile Parameter file (Input file) \n";
+
+        std::cout << errorMessageOut
+                  << "\n";
+    }
+}
+
+int main(int argc, char** argv)
+{
+    typedef TTAG(ThermoChemBoxProblem) ProblemTypeTag;
+    return Dumux::start<ProblemTypeTag>(argc, argv, usage);
+}
diff --git a/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh b/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh
new file mode 100644
index 0000000000..585a6df933
--- /dev/null
+++ b/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh
@@ -0,0 +1,571 @@
+// -*- 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 Definition of a problem for water management in PEM fuel cells.
+ */
+#ifndef DUMUX_THERMOCHEM_PROBLEM_HH
+#define DUMUX_THERMOCHEM_PROBLEM_HH
+
+#include <dumux/porousmediumflow/1pncmin/implicit/model.hh>
+#include <dumux/porousmediumflow/implicit/problem.hh>
+#include <dumux/material/fluidsystems/simplesteamaircao2h2.hh>
+#include <dumux/material/fluidmatrixinteractions/1p/thermalconductivityaverage.hh>
+
+#include "thermochemspatialparams.hh"
+
+#define NONISOTHERMAL 1
+
+
+namespace Dumux
+{
+
+template <class TypeTag>
+class ThermoChemProblem;
+
+namespace Properties
+{
+#if NONISOTHERMAL
+NEW_TYPE_TAG(ThermoChemProblem, INHERITS_FROM(OnePNCMinNI, ThermoChemSpatialParams));
+NEW_TYPE_TAG(ThermoChemBoxProblem, INHERITS_FROM(BoxModel, ThermoChemProblem));
+NEW_TYPE_TAG(ThermoChemCCProblem, INHERITS_FROM(CCModel, ThermoChemProblem));
+#else
+NEW_TYPE_TAG(ThermoChemProblem, INHERITS_FROM(OnePNCMin, ThermoChemSpatialParams));
+NEW_TYPE_TAG(ThermoChemBoxProblem, INHERITS_FROM(BoxModel, ThermoChemProblem));
+NEW_TYPE_TAG(ThermoChemCCProblem, INHERITS_FROM(CCModel, ThermoChemProblem));
+#endif
+// Set the grid type
+SET_TYPE_PROP(ThermoChemProblem, Grid, Dune::YaspGrid<2>);
+// Set the problem property
+SET_TYPE_PROP(ThermoChemProblem, Problem, ThermoChemProblem<TypeTag>);
+// Set fluid configuration
+SET_PROP(ThermoChemProblem, FluidSystem)
+{ /*private:*/
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using type = FluidSystems::SteamAirCaO2H2<Scalar>;
+};
+
+// Set the transport equation that is replaced by the total mass balance
+// SET_INT_PROP(ThermoChemProblem, ReplaceCompEqIdx, 1 /*3*/ /*1*/);
+
+SET_TYPE_PROP(ThermoChemProblem, LinearSolver, UMFPackBackend<TypeTag>);
+
+}
+
+// Set the spatial parameters
+SET_TYPE_PROP(ThermoChemProblem, SpatialParams, ThermoChemSpatialparams<TypeTag>);
+
+/*!
+ * \ingroup OnePNCModel
+ * \ingroup ImplicitTestProblems
+ * \brief Problem or water management in PEM fuel cells.
+ *
+ * To run the simulation execute the following line in shell:
+ * <tt>./test_box2pnc</tt>
+ */
+template <class TypeTag>
+class ThermoChemProblem : public ImplicitPorousMediaProblem<TypeTag>
+{
+    using ParentType = ImplicitPorousMediaProblem<TypeTag>;
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+
+    enum { dim = GridView::dimension };
+    enum { dimWorld = GridView::dimensionworld };
+
+    enum
+    {
+        replaceCompEqIdx = GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx),
+
+        numComponents = FluidSystem::numComponents,
+        numSComponents = FluidSystem::numSComponents,
+
+        // Indices of the primary variables
+        pressureIdx = Indices::pressureIdx, //gas-phase pressure
+        firstMoleFracIdx = Indices::firstMoleFracIdx, // mole fraction water
+
+        CaOIdx = FluidSystem::numComponents,
+        CaO2H2Idx = FluidSystem::numComponents+1,
+
+        //Equation Indices
+        conti0EqIdx = Indices::conti0EqIdx,
+        firstTransportEqIdx = Indices::firstTransportEqIdx,
+        solidEqIdx = Indices::conti0EqIdx + FluidSystem::numComponents,
+
+        // Phase Indices
+        phaseIdx = FluidSystem::gPhaseIdx,
+        cPhaseIdx = FluidSystem::cPhaseIdx,
+        hPhaseIdx = FluidSystem::hPhaseIdx,
+
+#if NONISOTHERMAL
+        temperatureIdx = Indices::temperatureIdx,
+        energyEqIdx = Indices::energyEqIdx
+#endif
+    };
+
+    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
+    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
+    using TimeManager = typename GET_PROP_TYPE(TypeTag, TimeManager);
+    using Element = typename GridView::template Codim<0>::Entity;
+    using Vertex = typename GridView::template Codim<dim>::Entity;
+    using Intersection = typename GridView::Intersection;
+    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
+    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
+
+    using GridCreator = typename GET_PROP_TYPE(TypeTag, GridCreator);
+    using DimVector = Dune::FieldVector<Scalar, dim> ;
+
+
+    // Select the electrochemistry method
+//     typedef typename Dumux::ElectroChemistry<TypeTag, Dumux::ElectroChemistryModel::Ochs> ElectroChemistry;
+//     typedef Dumux::Constants<Scalar> Constant;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+public:
+    /*!
+     * \brief The constructor
+     *
+     * \param timeManager The time manager
+     * \param gridView The grid view
+     */
+    ThermoChemProblem(TimeManager &timeManager, const GridView &gridView)
+        : ParentType(timeManager, gridView)
+    {
+        nTemperature_           = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, int, FluidSystem, NTemperature);
+        nPressure_              = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, int, FluidSystem, NPressure);
+        pressureLow_            = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, FluidSystem, PressureLow);
+        pressureHigh_           = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, FluidSystem, PressureHigh);
+        temperatureLow_         = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, FluidSystem, TemperatureLow);
+        temperatureHigh_        = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, FluidSystem, TemperatureHigh);
+        name_                   = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::string, Problem, Name);
+
+
+        FluidSystem::init(/*Tmin=*/temperatureLow_,
+                          /*Tmax=*/temperatureHigh_,
+                          /*nT=*/nTemperature_,
+                          /*pmin=*/pressureLow_,
+                          /*pmax=*/pressureHigh_,
+                          /*np=*/nPressure_);
+    }
+
+    /*!
+     * \name Problem parameters
+     */
+
+    /*!
+     * \brief The problem name.
+     *
+     * This is used as a prefix for files generated by the simulation.
+     */
+    const std::string name() const
+    { return name_; }
+
+    /*!
+     * \brief Returns the temperature within the domain.
+     *
+     * This problem assumes a temperature of 10 degrees Celsius.
+     */
+    Scalar temperature() const
+    { return temperature_; }
+
+    /*!
+     * \name Boundary conditions
+     */
+    // \{
+
+    /*!
+     * \brief Specifies which kind of boundary condition should be
+     *        used for which equation on a given boundary segment
+     *
+     * \param globalPos The global position
+     */
+    BoundaryTypes boundaryTypesAtPos( const GlobalPosition &globalPos) const
+    {
+        BoundaryTypes values;
+
+        values.setAllNeumann();
+
+        if(globalPos[0] < eps_ )
+        {
+//             values.setDirichlet(pressureIdx);
+            values.setDirichlet(firstMoleFracIdx);
+            values.setDirichlet(temperatureIdx);
+        }
+
+        if (globalPos[0] > this->bBoxMax()[0] - eps_){
+            values.setDirichlet(pressureIdx);
+//             values.setDirichlet(firstMoleFracIdx);
+//             values.setDirichlet(temperatureIdx);
+            values.setOutflow(temperatureIdx);
+            values.setOutflow(firstMoleFracIdx);
+//             values.setDirichlet(firstMoleFracIdx);
+        }
+        return values;
+    }
+
+    /*!
+     * \brief Evaluates the boundary conditions for a Dirichlet
+     *        boundary segment
+     *
+     * \param values Stores the Dirichlet values for the conservation equations in
+     *               \f$ [ \textnormal{unit of primary variable} ] \f$
+     * \param globalPos The global position
+     */
+    PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
+    {
+      PrimaryVariables priVars(0.0);
+
+      //input parameters
+      Scalar pIn;
+      Scalar pOut;
+      Scalar tIn;
+      Scalar tOut;
+      Scalar vapor;
+
+      // read input parameters
+      if (GET_PARAM_FROM_GROUP(TypeTag, bool, Problem, IsCharge)){
+      pIn = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, PressureIn);
+      pOut = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, PressureOut);
+      tIn = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, TemperatureIn);
+      tOut = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, TemperatureOut);
+      vapor = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, VaporIn);
+
+      }
+      else{
+      pIn = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, PressureIn);
+      pOut = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, PressureOut);
+      tIn = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, TemperatureIn);
+      tOut = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, TemperatureOut);
+      vapor = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, VaporIn);
+      }
+
+        if(globalPos[0] < eps_)
+        {
+//           priVars[pressureIdx]   = pIn;
+            priVars[firstMoleFracIdx]     = vapor; // Saturation outer boundary
+            priVars[temperatureIdx] = tIn;
+        }
+        if(globalPos[0] > this->bBoxMax()[0] - eps_)
+        {
+            priVars[pressureIdx] = pOut;
+//             priVars[firstMoleFracIdx] = 0.01; // Saturation inner boundary
+//             priVars[temperatureIdx] = tOut;
+//             priVars[firstMoleFracIdx]     = 0;
+        }
+        return priVars;
+    }
+
+    /*!
+     * \brief Evaluates the boundary conditions for a Neumann
+     *        boundary segment in dependency on the current solution.
+     *
+     * \param values Stores the Neumann values for the conservation equations in
+     *               \f$ [ \textnormal{unit of conserved quantity} / (m^(dim-1) \cdot s )] \f$
+     * \param element The finite element
+     * \param fvGeometry The finite volume geometry of the element
+     * \param intersection The intersection between element and boundary
+     * \param scvIdx The local index of the sub-control volume
+     * \param boundaryFaceIdx The index of the boundary face
+     * \param elemVolVars All volume variables for the element
+     *
+     * This method is used for cases, when the Neumann condition depends on the
+     * solution and requires some quantities that are specific to the fully-implicit method.
+     * The \a values store the mass flux of each phase normal to the boundary.
+     * Negative values indicate an inflow.
+     */
+
+        PrimaryVariables neumannAtPos(const GlobalPosition& globalPos) const
+    {
+        PrimaryVariables priVars(0.0);
+
+        if(globalPos[0] < eps_)
+        {
+        //if(isCharge == true){
+        if (GET_PARAM_FROM_GROUP(TypeTag, bool, Problem, IsCharge)){
+            priVars[pressureIdx] = -GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, InFlow); //[mol/s] gas inflow; negative sign: inflow
+        }
+        else
+        priVars[pressureIdx] = -GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, InFlow); //[mol/s] gas inflow
+        }
+
+        return priVars;
+    }
+
+    /*!
+     * \name Volume terms
+     */
+
+    /*!
+     * \brief Evaluates the initial values for a control volume
+     *
+     * \param values Stores the initial values for the conservation equations in
+     *               \f$ [ \textnormal{unit of primary variables} ] \f$
+     * \param globalPos The global position
+     */
+    PrimaryVariables initialAtPos(const GlobalPosition& globalPos) const
+    {
+        PrimaryVariables priVars(0.0);
+
+        Scalar pInit;
+        Scalar tInit;
+        Scalar h2oInit;
+        Scalar CaOInit;
+        Scalar CaO2H2Init;
+
+        //if(isCharge == true){
+        if (GET_PARAM_FROM_GROUP(TypeTag, bool, Problem, IsCharge)){
+        std::cout << "true " << "\n";
+        pInit = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, PressureInitial);
+        tInit = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, TemperatureInitial);
+        h2oInit = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, VaporInitial);
+        CaOInit = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, CaOInitial);
+        CaO2H2Init = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, CaO2H2Initial);
+        }
+
+        else {
+        std::cout << "false " << "\n";
+        pInit = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, PressureInitial);
+        tInit = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, TemperatureInitial);
+        h2oInit = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, VaporInitial);
+        CaOInit = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, CaOInitial);
+        CaO2H2Init = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, CaO2H2Initial);
+        }
+
+        priVars[pressureIdx] = pInit;
+        priVars[firstMoleFracIdx]   = h2oInit;
+#if NONISOTHERMAL
+        priVars[temperatureIdx] = tInit;
+#endif
+        priVars[CaOIdx] = CaOInit;
+        priVars[CaO2H2Idx]   = CaO2H2Init;
+
+        return priVars;
+    }
+
+    /*!
+     * \brief Return the initial phase state inside a sub control volume.
+     *
+     * \param element The element of the sub control volume
+     * \param fvGeometry The finite volume geometry
+     * \param scvIdx The sub control volume index
+     */
+    PrimaryVariables solDependentSource(const Element &element,
+                            const FVElementGeometry& fvGeometry,
+                            const ElementVolumeVariables& elemVolVars,
+                            const SubControlVolume &scv) const
+    {
+
+        PrimaryVariables source(0.0);
+        const auto& volVars = elemVolVars[scv];
+
+        Scalar Initial_Precipitate_Volume;
+        Scalar maxPrecipitateVolumeCaO;
+        Scalar maxPrecipitateVolumeCaO2H2;
+
+        //if(isCharge == true){
+        if (GET_PARAM_FROM_GROUP(TypeTag, bool, Problem, IsCharge)){
+        Initial_Precipitate_Volume = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Charge, CaO2H2Initial);
+        maxPrecipitateVolumeCaO =  0.3960;
+        maxPrecipitateVolumeCaO2H2 = Initial_Precipitate_Volume;
+        }
+        else {
+        Initial_Precipitate_Volume = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Discharge, CaOInitial);
+        maxPrecipitateVolumeCaO = Initial_Precipitate_Volume;
+        maxPrecipitateVolumeCaO2H2 = 0.3960;
+        }
+
+        Scalar T= volVars.temperature();
+        Scalar Teq = 0;
+
+        Scalar moleFractionVapor = 1e-3;
+
+        if(volVars.moleFraction(firstMoleFracIdx) > 1e-3)
+            moleFractionVapor = volVars.moleFraction(firstMoleFracIdx) ;
+        if(volVars.moleFraction(firstMoleFracIdx) >= 1.0){
+            moleFractionVapor = 1;
+//           std::cout << " test vapor = " << "\n";
+        }
+        Scalar vaporPressure = volVars.pressure(phaseIdx) *moleFractionVapor ;
+        vaporPressure *= 1.0e-5;
+        Scalar pFactor = log(vaporPressure);
+
+        Teq = -12845;
+        Teq /= (pFactor - 16.508);        //the equilibrium temperature
+
+//         if(isCharge == false) {
+//             if (Teq < 573.15) {
+//                 std::cout << "Teq = " << Teq<< "\n";
+//                 // Teq=573.15;
+//             }
+//         }
+
+        Scalar moleFracH2O_fPhase = volVars.moleFraction(firstMoleFracIdx);
+
+        Scalar moleFracCaO_sPhase = volVars.precipitateVolumeFraction(cPhaseIdx)*volVars.molarDensity(cPhaseIdx)
+                                     /(volVars.precipitateVolumeFraction(hPhaseIdx)*volVars.molarDensity(hPhaseIdx)
+                                        + volVars.precipitateVolumeFraction(cPhaseIdx)*volVars.molarDensity(cPhaseIdx));
+
+        Scalar moleFracCaO2H2_sPhase = volVars.precipitateVolumeFraction(hPhaseIdx)*volVars.molarDensity(hPhaseIdx)
+                                       /(volVars.precipitateVolumeFraction(hPhaseIdx)*volVars.molarDensity(hPhaseIdx)
+                                          + volVars.precipitateVolumeFraction(cPhaseIdx)*volVars.molarDensity(cPhaseIdx));
+
+        Scalar deltaH = 112e3; // J/mol
+
+        Scalar solidDensityAverage = moleFracCaO_sPhase*volVars.molarDensity(cPhaseIdx)
+                                     + moleFracCaO2H2_sPhase* volVars.molarDensity(hPhaseIdx);
+
+//         //discharge or hydration
+        if (T < Teq){
+
+            Scalar krh =0.08;  //0.006
+
+            Scalar rHydration = - moleFracH2O_fPhase* (volVars.molarDensity(hPhaseIdx)- solidDensityAverage)
+                                                     * krh * (T-Teq)/ Teq;
+
+            Scalar q = - rHydration ;
+
+            // make sure not more CaO reacts than present
+
+            if (- q*this->timeManager().timeStepSize() + moleFracCaO_sPhase* volVars.molarDensity(cPhaseIdx) < 0 + eps_){
+                q = moleFracCaO_sPhase/this->timeManager().timeStepSize();
+//                 std::cout << "q_discharge = " << q << "\n";
+            }
+
+            source[conti0EqIdx+CaO2H2Idx] = q;
+
+            source[conti0EqIdx+CaOIdx] = -q;
+
+            source[conti0EqIdx+firstMoleFracIdx] = -q;
+
+#if NONISOTHERMAL
+            source[energyEqIdx] = q * deltaH;
+#endif
+        }
+
+        // charge or dehydration
+        else if(T > Teq){
+
+            Scalar krd = 0.03; //0.05;
+
+            Scalar rDehydration = (volVars.molarDensity(cPhaseIdx)- solidDensityAverage)
+                                                     * krd * (Teq-T)/ Teq;
+
+            Scalar q =  -rDehydration;
+
+            if (- q*this->timeManager().timeStepSize() + moleFracCaO2H2_sPhase*volVars.molarDensity(hPhaseIdx) < 0){
+                q = moleFracCaO2H2_sPhase/this->timeManager().timeStepSize();
+            // std::cout << "q_charge " << q << "\n";
+            }
+
+            source[conti0EqIdx+CaO2H2Idx] = -q;
+
+            source[conti0EqIdx+CaOIdx] = q;
+
+            source[conti0EqIdx+firstMoleFracIdx] = q;
+#if NONISOTHERMAL
+            source[energyEqIdx] = -q * deltaH;
+
+#endif
+        }
+
+        else
+        source = 0.0;
+
+        return source;
+    }
+
+
+    /*!
+     * \brief Add problem specific vtk output for the electrochemistry
+     */
+//     void addOutputVtkFields()
+//     {
+//         // add the output field specific to the electrochemistry
+//         typedef Dune::BlockVector<Dune::FieldVector<Scalar, 1> > ScalarField;
+//
+//         // get the number of degrees of freedom
+// //         auto numDofs = this->model().numDofs();
+//
+//         for (const auto& element : elements(this->gridView()))
+//         {
+//             FVElementGeometry fvGeometry;
+//             fvGeometry.update(this->gridView(), element);
+//
+//             ElementVolumeVariables elemVolVars;
+//             elemVolVars.update(*this,
+//                                element,
+//                                fvGeometry,
+//                                false /* oldSol? */);
+//
+// //             for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+// //             {
+// //                 const auto& globalPos = isBox ? element.geometry().corner(scvIdx)
+// //                                               : element.geometry().center();
+// //
+// //                 auto dofIdxGlobal = this->model().dofMapper().subIndex(element, scvIdx, dofCodim);
+// //             }
+//         }
+//     }
+
+private:
+
+        static Scalar massTomoleFrac_(Scalar XlNaCl)
+    {
+       const Scalar Mw = 18.015e-3; /* molecular weight of water [kg/mol] */
+       const Scalar Ms = 58.44e-3; /* molecular weight of NaCl  [kg/mol] */
+
+       const Scalar X_NaCl = XlNaCl;
+       /* XlNaCl: conversion from mass fraction to mol fraction */
+       auto xlNaCl = -Mw * X_NaCl / ((Ms - Mw) * X_NaCl - Ms);
+       return xlNaCl;
+    }
+
+    int nTemperature_;
+    int nPressure_;
+
+//     PrimaryVariables storageLastTimestep_;
+
+    std::string name_;
+
+    Scalar pressureLow_, pressureHigh_;
+    Scalar temperatureLow_, temperatureHigh_;
+    Scalar reservoirPressure_;
+    Scalar innerPressure_;
+    Scalar outerPressure_;
+    Scalar temperature_;
+
+    static constexpr Scalar eps_ = 1e-6;
+    Scalar reservoirSaturation_;
+    std::ofstream outfile;
+
+//     bool isCharge_ ;
+
+};
+
+} //end namespace
+
+#endif
diff --git a/test/porousmediumflow/1pncmin/implicit/thermochemspatialparams.hh b/test/porousmediumflow/1pncmin/implicit/thermochemspatialparams.hh
new file mode 100644
index 0000000000..c9098f281d
--- /dev/null
+++ b/test/porousmediumflow/1pncmin/implicit/thermochemspatialparams.hh
@@ -0,0 +1,283 @@
+// -*- 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 Definition of the spatial parameters for the fuel cell
+ *        problem which uses the isothermal/non-insothermal 2pnc box model
+ */
+
+#ifndef DUMUX_THERMOCHEM_SPATIAL_PARAMS_HH
+#define DUMUX_THERMOCHEM_SPATIAL_PARAMS_HH
+
+#include <dumux/material/spatialparams/implicit1p.hh>
+#include <dumux/porousmediumflow/1pncmin/implicit/indices.hh>
+// #include <dumux/material/fluidmatrixinteractions/2p/linearmaterial.hh>
+// #include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh>
+// #include <dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchten.hh>
+// #include <dumux/material/fluidmatrixinteractions/2p/philtophoblaw.hh>
+#include <dumux/material/fluidmatrixinteractions/porosityreactivebed.hh>
+#include <dumux/material/fluidmatrixinteractions/permeabilitykozenycarman.hh>
+
+namespace Dumux
+{
+
+//forward declaration
+template<class TypeTag>
+class ThermoChemSpatialParams;
+
+namespace Properties
+{
+// The spatial parameters TypeTag
+NEW_TYPE_TAG(ThermoChemSpatialParams);
+
+// Set the spatial parameters
+SET_TYPE_PROP(ThermoChemSpatialParams, SpatialParams, Dumux::ThermoChemSpatialParams<TypeTag>);
+
+} // end namespace Properties
+
+/*!
+ * \ingroup TwoPTwoCModel
+ * \ingroup BoxTestProblems
+ * \brief Definition of the spatial parameters for the FuelCell
+ *        problem which uses the isothermal 2p2c box model
+ */
+template<class TypeTag>
+class ThermoChemSpatialParams : public ImplicitSpatialParamsOneP<TypeTag>
+{
+    using ThisType = ThermoChemSpatialParams<TypeTag>;
+    using ParentType = ImplicitSpatialParamsOneP<TypeTag>;
+//     typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using CoordScalar = typename GridView::ctype;
+    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+
+    using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector);
+
+    enum {
+        dim=GridView::dimension,
+        dimWorld=GridView::dimensionworld,
+
+//         wPhaseIdx = FluidSystem::wPhaseIdx
+    };
+
+    using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
+//     typedef Dune::FieldVector<CoordScalar,dim> DimVector;
+//     typedef Dune::FieldMatrix<CoordScalar,dim,dim> DimMatrix;
+    using Tensor = Dune::FieldMatrix<CoordScalar, dimWorld, dimWorld>;
+    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
+//     typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using Element = typename GridView::template Codim<0>::Entity;
+
+    using PorosityLaw = PorosityReactiveBed<TypeTag>;
+    using PermeabilityLaw = PermeabilityKozenyCarman<TypeTag>;
+
+public:
+    // type used for the permeability (i.e. tensor or scalar)
+    using PermeabilityType = Scalar;
+    /*!
+     * \brief The constructor
+     *
+     * \param gridView The grid view
+     */
+    ThermoChemSpatialParams(const Problem& problem, const GridView &gridView)
+    : ParentType(problem, gridView)
+    {
+        // intrinsic permeabilities
+//         K_[0][0] = 5e-12;
+//         K_[1][1] = 5e-12;
+//         K_[0][0] = 2.23e-14;
+//         K_[1][1] = 2.23e-14;
+
+        //thermal conductivity of CaO
+        lambdaSolid_ = 0.4; //[W/(m*K)] Nagel et al [2013b]
+
+        eps_ = 1e-6;
+    }
+
+    ~ThermoChemSpatialParams()
+    {}
+
+    /*!
+     * \brief Called by the Problem to initialize the spatial params.
+     */
+    void init()
+    {
+        //! Intitialize the parameter laws
+        poroLaw_.init(*this);
+        permLaw_.init(*this);
+    }
+
+    /*! Old
+     * \brief Apply the intrinsic permeability tensor to a pressure
+     *        potential gradient.
+     *
+     * \param element The current finite element
+     * \param fvGeometry The current finite volume geometry of the element
+     * \param scvIdx The index of the sub-control volume
+     */
+//     const DimMatrix intrinsicPermeability(const Element &element,
+//                                        const FVElementGeometry &fvGeometry,
+//                                        const int scvIdx) const
+//     { return K_; }
+//
+    /*!
+     *  \brief Define the initial permeability \f$[m^2]\f$ distribution
+     *
+     *  \param element The finite element
+     *  \param scv The sub-control volume
+     */
+    Scalar initialPermeability(const Element& element, const SubControlVolume &scv) const
+    { return 5e-12; }
+
+    /*!
+     * \brief Define the porosity \f$[-]\f$ of the spatial parameters
+     *
+     * \param element The finite element
+     * \param fvGeometry The finite volume geometry
+     * \param scvIdx The local index of the sub-control volume where
+     *                    the porosity needs to be defined
+     */
+//     Scalar porosity(const Element &element,
+//                     const FVElementGeometry &fvGeometry,
+//                     const int scvIdx) const
+//     {
+//         const GlobalPosition &globalPos = fvGeometry.subContVol[scvIdx].global;
+//
+//         if (globalPos[1]<eps_)
+//             return porosity_;
+//         else
+//             return 0.2;
+//
+//     }
+
+
+    /*!
+     *  \brief Define the initial porosity \f$[-]\f$ distribution
+     *
+     *  \param element The finite element
+     *  \param scv The sub-control volume
+     */
+    Scalar initialPorosity(const Element& element, const SubControlVolume &scv) const
+    {
+         Scalar phi;
+
+         if(isCharge_==true)
+         phi = 0.8;  //direct charging acc. to Nagel et al 2014
+//              phi = 0.887; //indirect charging acc. to Schmitt 2016
+         else
+          phi = 0.604;  //direct charging acc. to Nagel et al 2014
+//             phi = 0.772;  //indirect charging acc. to Schmitt 2016
+
+         return phi;
+    }
+
+
+    /*!
+     *  \brief Define the minimum porosity \f$[-]\f$ distribution
+     *
+     *  \param element The finite element
+     *  \param scv The sub-control volume
+     */
+    Scalar minPorosity(const Element& element, const SubControlVolume &scv) const
+    { return 0.604; //intrinsic porosity of CaO2H2 (see Nagel et al. 2014)
+        //        return 0.772;  //indirect charging acc. to Schmitt 2016
+    }
+
+    /*!
+     *  \brief Define the minimum porosity \f$[-]\f$ after clogging caused by mineralization
+     *
+     *  \param element The finite element
+     *  \param scv The sub-control volume
+     */
+    Scalar porosity(const Element& element,
+                    const SubControlVolume& scv,
+                    const ElementSolutionVector& elemSol) const
+    { return poroLaw_.evaluatePorosity(element, scv, elemSol); }
+
+
+
+    Scalar solidity(const SubControlVolume &scv) const
+    { return 1.0 - porosityAtPos(scv.center()); }
+
+    /*!
+     * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix.
+     *
+     * This is only required for non-isothermal models.
+     *
+     * \param element The element
+     * \param scv The sub control volume
+     * \param elemSol The element solution vector
+     */
+    Scalar solidHeatCapacity(const Element &element,
+                             const SubControlVolume& scv,
+                             const ElementSolutionVector& elemSol) const
+    {
+        return 790;
+//             42 // specific heat capacity of CaO [J / (kg K)]
+//             * 3370 // density of CaO [kg/m^3]
+//             * (1 - porosity(element, fvGeometry, scvIdx));  // for CaO only!!
+    }
+
+    /*!
+     * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix.
+     *
+     * This is only required for non-isothermal models.
+     *
+     * \param element The element
+     * \param scv The sub control volume
+     * \param elemSol The element solution vector
+     */
+    Scalar solidDensity(const Element &element,
+                        const SubControlVolume& scv,
+                        const ElementSolutionVector& elemSol) const
+    {
+//      return 3370; // density of CaO [kg/m^3]
+        return 2600;
+    }
+
+    /*!
+     * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material.
+     *
+     * \param element The element
+     * \param scv The sub control volume
+     * \param elemSol The element solution vector
+     */
+    Scalar solidThermalConductivity(const Element &element,
+                                    const SubControlVolume& scv,
+                                    const ElementSolutionVector& elemSol) const
+    { return lambdaSolid_; }
+
+private:
+//     DimMatrix K_;
+//     Scalar porosity_;
+    Scalar eps_;
+//     MaterialLawParams materialParams_;
+    Scalar lambdaSolid_;
+   bool isCharge_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, bool, Problem, isCharge);
+   PorosityLaw poroLaw_;
+   PermeabilityLaw permLaw_;
+};
+
+}//end namespace
+
+#endif
diff --git a/test/porousmediumflow/CMakeLists.txt b/test/porousmediumflow/CMakeLists.txt
index 9d36688958..3072fc0b28 100644
--- a/test/porousmediumflow/CMakeLists.txt
+++ b/test/porousmediumflow/CMakeLists.txt
@@ -1,6 +1,7 @@
 add_subdirectory("1p")
 add_subdirectory("1p2c")
 add_subdirectory("1pnc")
+add_subdirectory("1pncmin")
 add_subdirectory("2p")
 add_subdirectory("2p1c")
 add_subdirectory("2p2c")
-- 
GitLab