From 2885681ef1cd137934db1ec3213f1d949a5255fc Mon Sep 17 00:00:00 2001
From: Bernd Flemisch <bernd@iws.uni-stuttgart.de>
Date: Wed, 5 Dec 2012 12:49:09 +0000
Subject: [PATCH] implicit branch: add cell-centered treatment to the Richards
 model, unify the test.

git-svn-id: svn://svn.iws.uni-stuttgart.de/DUMUX/dumux/branches/implicit@9782 2fb0f335-1f38-0410-981e-8018bf24f1b0
---
 dumux/implicit/richards/richardsmodel.hh      | 85 ++++++++++++-------
 .../richards/richardsnewtoncontroller.hh      | 21 +++--
 test/implicit/richards/Makefile.am            |  5 +-
 test/implicit/richards/richardslensproblem.hh | 11 ++-
 test/implicit/richards/test_boxrichards.cc    | 58 +++++++++++++
 test/implicit/richards/test_boxrichards.input | 31 +++++++
 .../{test_richards.cc => test_ccrichards.cc}  |  2 +-
 ...t_richards.input => test_ccrichards.input} |  3 +
 8 files changed, 173 insertions(+), 43 deletions(-)
 create mode 100644 test/implicit/richards/test_boxrichards.cc
 create mode 100644 test/implicit/richards/test_boxrichards.input
 rename test/implicit/richards/{test_richards.cc => test_ccrichards.cc} (98%)
 rename test/implicit/richards/{test_richards.input => test_ccrichards.input} (96%)

diff --git a/dumux/implicit/richards/richardsmodel.hh b/dumux/implicit/richards/richardsmodel.hh
index ff71be4f6f..8ed12767a9 100644
--- a/dumux/implicit/richards/richardsmodel.hh
+++ b/dumux/implicit/richards/richardsmodel.hh
@@ -119,6 +119,8 @@ class RichardsModel : public GET_PROP_TYPE(TypeTag, BaseModel)
     typedef typename GridView::template Codim<0>::Iterator ElementIterator;
     enum { dim = GridView::dimension };
 
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+
 public:
     /*!
      * \brief All relevant primary and secondary of a given
@@ -132,25 +134,27 @@ public:
     {
         typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
 
+        // get the number of degrees of freedom
+        unsigned numDofs = this->numDofs();
+
         // create the required scalar fields
-        unsigned numVertices = this->problem_().gridView().size(dim);
-        ScalarField *pW = writer.allocateManagedBuffer(numVertices);
-        ScalarField *pN = writer.allocateManagedBuffer(numVertices);
-        ScalarField *pC = writer.allocateManagedBuffer(numVertices);
-        ScalarField *Sw = writer.allocateManagedBuffer(numVertices);
-        ScalarField *Sn = writer.allocateManagedBuffer(numVertices);
-        ScalarField *rhoW = writer.allocateManagedBuffer(numVertices);
-        ScalarField *rhoN = writer.allocateManagedBuffer(numVertices);
-        ScalarField *mobW = writer.allocateManagedBuffer(numVertices);
-        ScalarField *mobN = writer.allocateManagedBuffer(numVertices);
-        ScalarField *poro = writer.allocateManagedBuffer(numVertices);
-        ScalarField *Te = writer.allocateManagedBuffer(numVertices);
+        ScalarField *pW = writer.allocateManagedBuffer(numDofs);
+        ScalarField *pN = writer.allocateManagedBuffer(numDofs);
+        ScalarField *pC = writer.allocateManagedBuffer(numDofs);
+        ScalarField *Sw = writer.allocateManagedBuffer(numDofs);
+        ScalarField *Sn = writer.allocateManagedBuffer(numDofs);
+        ScalarField *rhoW = writer.allocateManagedBuffer(numDofs);
+        ScalarField *rhoN = writer.allocateManagedBuffer(numDofs);
+        ScalarField *mobW = writer.allocateManagedBuffer(numDofs);
+        ScalarField *mobN = writer.allocateManagedBuffer(numDofs);
+        ScalarField *poro = writer.allocateManagedBuffer(numDofs);
+        ScalarField *Te = writer.allocateManagedBuffer(numDofs);
 
         unsigned numElements = this->gridView_().size(0);
         ScalarField *rank =
                 writer.allocateManagedBuffer (numElements);
 
-        FVElementGeometry fvElemGeom;
+        FVElementGeometry fvGeometry;
         VolumeVariables volVars;
 
         ElementIterator elemIt = this->gridView_().template begin<0>();
@@ -160,17 +164,21 @@ public:
             int idx = this->problem_().model().elementMapper().map(*elemIt);
             (*rank)[idx] = this->gridView_().comm().rank();
 
-            fvElemGeom.update(this->gridView_(), *elemIt);
+            fvGeometry.update(this->gridView_(), *elemIt);
 
-            int numVerts = elemIt->template count<dim> ();
-            for (int i = 0; i < numVerts; ++i)
+            for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx)
             {
-                int globalIdx = this->vertexMapper().map(*elemIt, i, dim);
+                int globalIdx;
+                if (isBox)
+                    globalIdx = this->vertexMapper().map(*elemIt, scvIdx, dim);
+                else 
+                    globalIdx = this->elementMapper().map(*elemIt);
+
                 volVars.update(sol[globalIdx],
                                this->problem_(),
                                *elemIt,
-                               fvElemGeom,
-                               i,
+                               fvGeometry,
+                               scvIdx,
                                false);
 
                 (*pW)[globalIdx] = volVars.pressure(wPhaseIdx);
@@ -187,17 +195,34 @@ public:
             }
         }
 
-        writer.attachVertexData(*Sn, "Sn");
-        writer.attachVertexData(*Sw, "Sw");
-        writer.attachVertexData(*pN, "pn");
-        writer.attachVertexData(*pW, "pw");
-        writer.attachVertexData(*pC, "pc");
-        writer.attachVertexData(*rhoW, "rhoW");
-        writer.attachVertexData(*rhoN, "rhoN");
-        writer.attachVertexData(*mobW, "mobW");
-        writer.attachVertexData(*mobN, "mobN");
-        writer.attachVertexData(*poro, "porosity");
-        writer.attachVertexData(*Te, "temperature");
+        if (isBox) // vertex data
+        {
+            writer.attachVertexData(*Sn, "Sn");
+            writer.attachVertexData(*Sw, "Sw");
+            writer.attachVertexData(*pN, "pn");
+            writer.attachVertexData(*pW, "pw");
+            writer.attachVertexData(*pC, "pc");
+            writer.attachVertexData(*rhoW, "rhoW");
+            writer.attachVertexData(*rhoN, "rhoN");
+            writer.attachVertexData(*mobW, "mobW");
+            writer.attachVertexData(*mobN, "mobN");
+            writer.attachVertexData(*poro, "porosity");
+            writer.attachVertexData(*Te, "temperature");
+        }
+        else // cell data
+        {
+            writer.attachCellData(*Sn, "Sn");
+            writer.attachCellData(*Sw, "Sw");
+            writer.attachCellData(*pN, "pn");
+            writer.attachCellData(*pW, "pw");
+            writer.attachCellData(*pC, "pc");
+            writer.attachCellData(*rhoW, "rhoW");
+            writer.attachCellData(*rhoN, "rhoN");
+            writer.attachCellData(*mobW, "mobW");
+            writer.attachCellData(*mobN, "mobN");
+            writer.attachCellData(*poro, "porosity");
+            writer.attachCellData(*Te, "temperature");
+        }
         writer.attachCellData(*rank, "process rank");
     }
 };
diff --git a/dumux/implicit/richards/richardsnewtoncontroller.hh b/dumux/implicit/richards/richardsnewtoncontroller.hh
index 635f6a6288..2f0b035d6d 100644
--- a/dumux/implicit/richards/richardsnewtoncontroller.hh
+++ b/dumux/implicit/richards/richardsnewtoncontroller.hh
@@ -54,6 +54,8 @@ class RichardsNewtonController : public NewtonController<TypeTag>
     typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
     typedef typename GridView::template Codim<0>::Iterator ElementIterator;
     enum { dim = GridView::dimension };
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+
 public:
     /*!
      * \brief Constructor
@@ -92,15 +94,20 @@ public:
             const ElementIterator elemEndIt = gridView.template end<0>();
             for (; elemIt != elemEndIt; ++elemIt) {
                 fvGeometry.update(gridView, *elemIt);
-                for (int i = 0; i < fvGeometry.numSCV; ++i) {
-                    int globI = this->problem_().vertexMapper().map(*elemIt, i, dim);
+                for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx)
+                {
+                    int globalIdx;
+                    if (isBox)
+                        globalIdx = this->problem_().vertexMapper().map(*elemIt, scvIdx, dim);
+                    else 
+                        globalIdx = this->problem_().elementMapper().map(*elemIt);
 
                     // calculate the old wetting phase saturation
                     const SpatialParams &spatialParams = this->problem_().spatialParams();
-                    const MaterialLawParams &mp = spatialParams.materialLawParams(*elemIt, fvGeometry, i);
+                    const MaterialLawParams &mp = spatialParams.materialLawParams(*elemIt, fvGeometry, scvIdx);
                     Scalar pcMin = MaterialLaw::pC(mp, 1.0);
-                    Scalar pW = uLastIter[globI][pwIdx];
-                    Scalar pN = std::max(this->problem_().referencePressure(*elemIt, fvGeometry, i),
+                    Scalar pW = uLastIter[globalIdx][pwIdx];
+                    Scalar pN = std::max(this->problem_().referencePressure(*elemIt, fvGeometry, scvIdx),
                                          pW + pcMin);
                     Scalar pcOld = pN - pW;
                     Scalar SwOld = std::max<Scalar>(0.0, MaterialLaw::Sw(mp, pcOld));
@@ -111,9 +118,9 @@ public:
                     Scalar pwMax = pN - MaterialLaw::pC(mp, SwOld + 0.2);
 
                     // clamp the result
-                    pW = uCurrentIter[globI][pwIdx];
+                    pW = uCurrentIter[globalIdx][pwIdx];
                     pW = std::max(pwMin, std::min(pW, pwMax));
-                    uCurrentIter[globI][pwIdx] = pW;
+                    uCurrentIter[globalIdx][pwIdx] = pW;
 
                 }
             }
diff --git a/test/implicit/richards/Makefile.am b/test/implicit/richards/Makefile.am
index 4f821cef5b..596324d827 100644
--- a/test/implicit/richards/Makefile.am
+++ b/test/implicit/richards/Makefile.am
@@ -1,8 +1,9 @@
-check_PROGRAMS = test_richards
+check_PROGRAMS = test_boxrichards test_ccrichards
 
 noinst_HEADERS = *.hh
 EXTRA_DIST=*reference*.vtu *.input grids/*.dgf CMakeLists.txt
 
-test_richards_SOURCES = test_richards.cc 
+test_boxrichards_SOURCES = test_boxrichards.cc 
+test_ccrichards_SOURCES = test_ccrichards.cc 
 
 include $(top_srcdir)/am/global-rules
diff --git a/test/implicit/richards/richardslensproblem.hh b/test/implicit/richards/richardslensproblem.hh
index a33345db67..fb2f68d0da 100644
--- a/test/implicit/richards/richardslensproblem.hh
+++ b/test/implicit/richards/richardslensproblem.hh
@@ -45,7 +45,9 @@ class RichardsLensProblem;
 //////////
 namespace Properties
 {
-NEW_TYPE_TAG(RichardsLensProblem, INHERITS_FROM(BoxRichards, RichardsLensSpatialParams));
+NEW_TYPE_TAG(RichardsLensProblem, INHERITS_FROM(Richards, RichardsLensSpatialParams));
+NEW_TYPE_TAG(RichardsLensBoxProblem, INHERITS_FROM(BoxModel, RichardsLensProblem));
+NEW_TYPE_TAG(RichardsLensCCProblem, INHERITS_FROM(CCModel, RichardsLensProblem));
 
 // Use 2d YaspGrid
 SET_TYPE_PROP(RichardsLensProblem, Grid, Dune::YaspGrid<2>);
@@ -156,6 +158,8 @@ public:
         lensUpperRight_[1] = 3.0;
 
         this->spatialParams().setLensCoords(lensLowerLeft_, lensUpperRight_);
+        
+        name_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::string, Problem, Name);
     }
 
     /*!
@@ -168,8 +172,8 @@ public:
      *
      * This is used as a prefix for files generated by the simulation.
      */
-    const char *name() const
-    { return "richardslens"; }
+    const std::string name() const
+    { return name_; }
 
     /*!
      * \brief Returns the temperature [K] within a finite volume
@@ -326,6 +330,7 @@ private:
 
     GlobalPosition lensLowerLeft_;
     GlobalPosition lensUpperRight_;
+    std::string name_;
 };
 } //end namespace
 
diff --git a/test/implicit/richards/test_boxrichards.cc b/test/implicit/richards/test_boxrichards.cc
new file mode 100644
index 0000000000..0e375eb705
--- /dev/null
+++ b/test/implicit/richards/test_boxrichards.cc
@@ -0,0 +1,58 @@
+// -*- 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 Richards box model.
+ */
+#include "config.h"
+#include "richardslensproblem.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-TimeManager.TEnd      End of the simulation [s] \n"
+                                        "\t-TimeManager.DtInitial Initial timestep size [s] \n"
+                                        "\t-Grid.File             Name of the file containing the grid \n"
+                                        "\t                       definition in DGF format\n";
+
+        std::cout << errorMessageOut
+                  << "\n";
+    }
+}
+
+int main(int argc, char** argv)
+{
+    typedef TTAG(RichardsLensBoxProblem) ProblemTypeTag;
+    return Dumux::start<ProblemTypeTag>(argc, argv, usage);
+}
diff --git a/test/implicit/richards/test_boxrichards.input b/test/implicit/richards/test_boxrichards.input
new file mode 100644
index 0000000000..30bc118eb5
--- /dev/null
+++ b/test/implicit/richards/test_boxrichards.input
@@ -0,0 +1,31 @@
+###############################################################
+# Parameter file for test_richards.
+# Everything behind a '#' is a comment.
+# Type "./test_richards --help" for more information.
+###############################################################
+
+###############################################################
+# Mandatory arguments
+###############################################################
+
+[TimeManager]
+DtInitial = 100 # [s]
+TEnd = 3000 # [s]
+
+[Grid]
+File = ./grids/richardslens-24x16.dgf
+
+[Problem]
+Name = richardslensbox
+
+###############################################################
+# Simulation restart
+#
+# DuMux simulations can be restarted from *.drs files
+# Set Restart to the value of a specific file, 
+# e.g.:  'Restart = 27184.1' for the restart file
+# name_time=27184.1_rank=0.drs
+# Please comment in the two lines below, if restart is desired.
+###############################################################
+# [TimeManager]
+# Restart = ... 
diff --git a/test/implicit/richards/test_richards.cc b/test/implicit/richards/test_ccrichards.cc
similarity index 98%
rename from test/implicit/richards/test_richards.cc
rename to test/implicit/richards/test_ccrichards.cc
index b033c62fa7..349edf3981 100644
--- a/test/implicit/richards/test_richards.cc
+++ b/test/implicit/richards/test_ccrichards.cc
@@ -53,6 +53,6 @@ void usage(const char *progName, const std::string &errorMsg)
 
 int main(int argc, char** argv)
 {
-    typedef TTAG(RichardsLensProblem) ProblemTypeTag;
+    typedef TTAG(RichardsLensCCProblem) ProblemTypeTag;
     return Dumux::start<ProblemTypeTag>(argc, argv, usage);
 }
diff --git a/test/implicit/richards/test_richards.input b/test/implicit/richards/test_ccrichards.input
similarity index 96%
rename from test/implicit/richards/test_richards.input
rename to test/implicit/richards/test_ccrichards.input
index 8507fe30b1..348df3bbb2 100644
--- a/test/implicit/richards/test_richards.input
+++ b/test/implicit/richards/test_ccrichards.input
@@ -15,6 +15,9 @@ TEnd = 3000 # [s]
 [Grid]
 File = ./grids/richardslens-24x16.dgf
 
+[Problem]
+Name = richardslenscc
+
 ###############################################################
 # Simulation restart
 #
-- 
GitLab