From 03ab43dbd607b8270ec37baeee4a129fed4b4d1b Mon Sep 17 00:00:00 2001
From: Katharina Heck <katharina.heck@iws.uni-stuttgart.de>
Date: Fri, 3 Nov 2017 16:50:11 +0100
Subject: [PATCH] [3p][test] add exact temperature calculation for ni tests

---
 .../3p/implicit/3pniconductionproblem.hh      | 46 +++++++++++--------
 .../3p/implicit/3pniconvectionproblem.hh      | 41 ++++++++++++-----
 .../3p/implicit/test_box3pniconduction.cc     | 19 ++++----
 .../3p/implicit/test_box3pniconvection.cc     |  5 ++
 .../3p/implicit/test_cc3pniconduction.cc      | 13 +++++-
 .../3p/implicit/test_cc3pniconvection.cc      | 13 +++++-
 .../3p/implicit/test_cc3pniconvection.input   |  3 ++
 7 files changed, 97 insertions(+), 43 deletions(-)

diff --git a/test/porousmediumflow/3p/implicit/3pniconductionproblem.hh b/test/porousmediumflow/3p/implicit/3pniconductionproblem.hh
index f1a20768da..b237e14d31 100644
--- a/test/porousmediumflow/3p/implicit/3pniconductionproblem.hh
+++ b/test/porousmediumflow/3p/implicit/3pniconductionproblem.hh
@@ -112,6 +112,8 @@ class ThreePNIConductionProblem : public PorousMediumFlowProblem<TypeTag>
     using ThermalConductivityModel = typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector);
+    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
     using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
     using IapwsH2O = H2O<Scalar>;
     using NeumannFluxes = typename GET_PROP_TYPE(TypeTag, NumEqVector);
@@ -151,7 +153,8 @@ public:
         outputInterval_ = getParam<int>("Problem.OutputInterval");
         temperatureHigh_ = 300.0;
         time_ = 0.0;
-    }
+        temperatureExact_.resize(this->fvGridGeometry().gridView().size(GridView::dimension));
+   }
 
     // get time from the mainfile timeloop
     void setTime(Scalar time)
@@ -160,15 +163,24 @@ public:
      /*!
      * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write.
      */
-    const std::vector<Scalar>& getExactTemperature() const
+    /*!
+     * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write.
+     */
+    const std::vector<Scalar>& getExactTemperature()
+    {
+        return temperatureExact_;
+    }
+
+    void updateExactTemperature(const SolutionVector& curSol)
     {
         const auto someElement = *(elements(this->fvGridGeometry().gridView()).begin());
-        const auto someElemSol = this->model().elementSolution(someElement, this->model().curSol());
+
+        ElementSolutionVector someElemSol(someElement, curSol, this->fvGridGeometry());
         const auto someInitSol = initialAtPos(someElement.geometry().center());
 
-        auto someFvGeometry = localView(this->model().fvGridGeometry());
-        someFvGeometry.bindElement(someElement);
-        const auto someScv = *(scvs(someFvGeometry).begin());
+        auto fvGeometry = localView(this->fvGridGeometry());
+        fvGeometry.bindElement(someElement);
+        const auto someScv = *(scvs(fvGeometry).begin());
 
         VolumeVariables volVars;
         volVars.update(someElemSol, *this, someElement, someScv);
@@ -180,25 +192,23 @@ public:
         const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol);
         const auto storage = densityW*heatCapacityW*porosity + densityS*heatCapacityS*(1 - porosity);
         const auto effectiveThermalConductivity = ThermalConductivityModel::effectiveThermalConductivity(volVars, this->spatialParams(),
-                                                                                                         someElement, someFvGeometry, someScv);
-        using std::max;
-
-        for (const auto& element : elements(this->gridView()))
+                                                                                                         someElement, fvGeometry, someScv);
+        for (const auto& element : elements(this->fvGridGeometry().gridView()))
         {
-            auto fvGeometry = localView(this->model().fvGridGeometry());
+            auto fvGeometry = localView(this->fvGridGeometry());
             fvGeometry.bindElement(element);
 
             for (auto&& scv : scvs(fvGeometry))
             {
-                auto globalIdx = scv.dofIndex();
-                const auto& globalPos = scv.dofPosition();
-                using std::erf;
-                using std::sqrt;
-                temperatureExact_[globalIdx] = temperatureHigh_ + (someInitSol[temperatureIdx] - temperatureHigh_)
+               auto globalIdx = scv.dofIndex();
+               const auto& globalPos = scv.dofPosition();
+               using std::erf;
+               using std::sqrt;
+               temperatureExact_[globalIdx] = temperatureHigh_ + (someInitSol[temperatureIdx] - temperatureHigh_)
                                               *erf(0.5*sqrt(globalPos[0]*globalPos[0]*storage/time_/effectiveThermalConductivity));
+
             }
         }
-        return temperatureExact_;
     }
     /*!
      * \name Problem parameters
@@ -319,7 +329,7 @@ private:
     static constexpr Scalar eps_ = 1e-6;
     std::string name_;
     int outputInterval_;
-    std::vector<Scalar> temperatureExact_;
+    std::vector<double> temperatureExact_;
     Scalar time_;
 
 };
diff --git a/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh b/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh
index ce2e4bdc70..2bc1f5f254 100644
--- a/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh
+++ b/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh
@@ -109,6 +109,8 @@ class ThreePNIConvectionProblem : public PorousMediumFlowProblem<TypeTag>
     using ThermalConductivityModel = typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector);
+    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
     using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
     using IapwsH2O = H2O<Scalar>;
 
@@ -155,24 +157,37 @@ public:
         pressureHigh_ = 2e5;
         pressureLow_ = 1e5;
 
+        time_ = 0.0;
+        temperatureExact_.resize(this->fvGridGeometry().gridView().size(GridView::dimension));
+
 
     }
 
+    // get time from the mainfile timeloop
+    void setTime(Scalar time)
+    { time_ = time; }
+
+     /*!
+     * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write.
+     */
     /*!
      * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write.
      */
-    template <class VtkOutputModule>
-    void addVtkOutputFields(VtkOutputModule& outputModule) const
+    const std::vector<Scalar>& getExactTemperature()
+    {
+        return temperatureExact_;
+    }
+
+ void updateExactTemperature(const SolutionVector& curSol)
     {
-        auto& temperatureExact = outputModule.createScalarField("temperatureExact", dofCodim);
+        const auto someElement = *(elements(this->fvGridGeometry().gridView()).begin());
 
-        const auto someElement = *(elements(this->gridView()).begin());
-        const auto someElemSol = this->model().elementSolution(someElement, this->model().curSol());
+        ElementSolutionVector someElemSol(someElement, curSol, this->fvGridGeometry());
         const auto someInitSol = initialAtPos(someElement.geometry().center());
 
-        auto someFvGeometry = localView(this->model().fvGridGeometry());
-        someFvGeometry.bindElement(someElement);
-        const auto someScv = *(scvs(someFvGeometry).begin());
+        auto fvGeometry = localView(this->fvGridGeometry());
+        fvGeometry.bindElement(someElement);
+        const auto someScv = *(scvs(fvGeometry).begin());
 
         VolumeVariables volVars;
         volVars.update(someElemSol, *this, someElement, someScv);
@@ -187,19 +202,19 @@ public:
         std::cout << "storage: " << storageTotal << '\n';
 
         using std::max;
-        const Scalar time = max(this->timeManager().time() + this->timeManager().timeStepSize(), 1e-10);
+        const Scalar time = max(time_, 1e-10);
         const Scalar retardedFrontVelocity = darcyVelocity_*storageW/storageTotal/porosity;
         std::cout << "retarded velocity: " << retardedFrontVelocity << '\n';
 
-        for (const auto& element : elements(this->gridView()))
+        for (const auto& element : elements(this->fvGridGeometry().gridView()))
         {
-            auto fvGeometry = localView(this->model().fvGridGeometry());
+            auto fvGeometry = localView(this->fvGridGeometry());
             fvGeometry.bindElement(element);
             for (auto&& scv : scvs(fvGeometry))
             {
                 auto dofIdxGlobal = scv.dofIndex();
                 auto dofPosition = scv.dofPosition();
-                temperatureExact[dofIdxGlobal] = (dofPosition[0] < retardedFrontVelocity*time) ? temperatureHigh_ : temperatureLow_;
+                temperatureExact_[dofIdxGlobal] = (dofPosition[0] < retardedFrontVelocity*time) ? temperatureHigh_ : temperatureLow_;
             }
         }
     }
@@ -338,6 +353,8 @@ private:
     static constexpr Scalar eps_ = 1e-6;
     std::string name_;
     int outputInterval_;
+    std::vector<double> temperatureExact_;
+    Scalar time_;
 };
 
 } //end namespace
diff --git a/test/porousmediumflow/3p/implicit/test_box3pniconduction.cc b/test/porousmediumflow/3p/implicit/test_box3pniconduction.cc
index 2f964ae900..1271393c21 100644
--- a/test/porousmediumflow/3p/implicit/test_box3pniconduction.cc
+++ b/test/porousmediumflow/3p/implicit/test_box3pniconduction.cc
@@ -146,8 +146,11 @@ int main(int argc, char** argv) try
     using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields);
     VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name());
     VtkOutputFields::init(vtkWriter); //! Add model specific output fields
+    //add specific output
+     vtkWriter.addField(problem->getExactTemperature(), "temperatureExact");
      //! Add model specific output fields
     vtkWriter.write(0.0);
+     //add specific output
     const auto outputInterval = getParam<int>("Problem.OutputInterval");
 
     // instantiate time loop
@@ -200,22 +203,20 @@ int main(int argc, char** argv) try
         // advance to the time loop to the next step
         timeLoop->advanceTimeStep();
 
-        // write vtk output
-        vtkWriter.write(
-            timeLoop->timeStepIndex()==0 ||
-            timeLoop->timeStepIndex() % outputInterval == 0 ||
-            timeLoop->willBeFinished());
-
+        problem->setTime(timeLoop->time()+timeLoop->timeStepSize());
+        problem->updateExactTemperature(x);
 
         // report statistics of this time step
         timeLoop->reportTimeStep();
 
         // set new dt as suggested by newton controller
         timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize()));
-        problem->setTime(timeLoop->time()+timeLoop->timeStepSize());
 
-        //add specific output
-//         vtkWriter.addField(problem->getExactTemperature(), "exactTemperature");
+        // write vtk output
+        vtkWriter.write(timeLoop->timeStepIndex()==0 ||
+                        timeLoop->timeStepIndex() % outputInterval == 0 ||
+                        timeLoop->willBeFinished());
+
 
     } while (!timeLoop->finished());
 
diff --git a/test/porousmediumflow/3p/implicit/test_box3pniconvection.cc b/test/porousmediumflow/3p/implicit/test_box3pniconvection.cc
index d6c2206c46..a180deac45 100644
--- a/test/porousmediumflow/3p/implicit/test_box3pniconvection.cc
+++ b/test/porousmediumflow/3p/implicit/test_box3pniconvection.cc
@@ -146,6 +146,8 @@ int main(int argc, char** argv) try
     using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields);
     VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name());
     VtkOutputFields::init(vtkWriter); //! Add model specific output fields
+    //add specific output
+    vtkWriter.addField(problem->getExactTemperature(), "temperatureExact");
     vtkWriter.write(0.0);
     const auto outputInterval = getParam<int>("Problem.OutputInterval");
 
@@ -199,6 +201,9 @@ int main(int argc, char** argv) try
         // advance to the time loop to the next step
         timeLoop->advanceTimeStep();
 
+        problem->setTime(timeLoop->time()+timeLoop->timeStepSize());
+        problem->updateExactTemperature(x);
+
         // write vtk output
         vtkWriter.write(
             timeLoop->timeStepIndex()==0 ||
diff --git a/test/porousmediumflow/3p/implicit/test_cc3pniconduction.cc b/test/porousmediumflow/3p/implicit/test_cc3pniconduction.cc
index ced7b6eb03..c7f1f7b690 100644
--- a/test/porousmediumflow/3p/implicit/test_cc3pniconduction.cc
+++ b/test/porousmediumflow/3p/implicit/test_cc3pniconduction.cc
@@ -147,7 +147,11 @@ int main(int argc, char** argv) try
     using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields);
     VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name());
     VtkOutputFields::init(vtkWriter); //! Add model specific output fields
+    vtkWriter.addField(problem->getExactTemperature(), "temperatureExact");
+     //! Add model specific output fields
     vtkWriter.write(0.0);
+    //add specific output
+    const auto outputInterval = getParam<int>("Problem.OutputInterval");
 
     // instantiate time loop
     auto timeLoop = std::make_shared<TimeLoop<Scalar>>(restartTime, dt, tEnd);
@@ -199,8 +203,8 @@ int main(int argc, char** argv) try
         // advance to the time loop to the next step
         timeLoop->advanceTimeStep();
 
-        // write vtk output
-        vtkWriter.write(timeLoop->time());
+        problem->setTime(timeLoop->time()+timeLoop->timeStepSize());
+        problem->updateExactTemperature(x);
 
         // report statistics of this time step
         timeLoop->reportTimeStep();
@@ -208,6 +212,11 @@ int main(int argc, char** argv) try
         // set new dt as suggested by newton controller
         timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize()));
 
+         // write vtk output
+        vtkWriter.write(timeLoop->timeStepIndex()==0 ||
+                        timeLoop->timeStepIndex() % outputInterval == 0 ||
+                        timeLoop->willBeFinished());
+
     } while (!timeLoop->finished());
 
     timeLoop->finalize(leafGridView.comm());
diff --git a/test/porousmediumflow/3p/implicit/test_cc3pniconvection.cc b/test/porousmediumflow/3p/implicit/test_cc3pniconvection.cc
index 3ffb002a0b..5e905d2eef 100644
--- a/test/porousmediumflow/3p/implicit/test_cc3pniconvection.cc
+++ b/test/porousmediumflow/3p/implicit/test_cc3pniconvection.cc
@@ -147,7 +147,11 @@ int main(int argc, char** argv) try
     using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields);
     VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name());
     VtkOutputFields::init(vtkWriter); //! Add model specific output fields
+    vtkWriter.addField(problem->getExactTemperature(), "temperatureExact");
+     //! Add model specific output fields
     vtkWriter.write(0.0);
+    //add specific output
+    const auto outputInterval = getParam<int>("Problem.OutputInterval");
 
     // instantiate time loop
     auto timeLoop = std::make_shared<TimeLoop<Scalar>>(restartTime, dt, tEnd);
@@ -199,8 +203,8 @@ int main(int argc, char** argv) try
         // advance to the time loop to the next step
         timeLoop->advanceTimeStep();
 
-        // write vtk output
-        vtkWriter.write(timeLoop->time());
+        problem->setTime(timeLoop->time()+timeLoop->timeStepSize());
+        problem->updateExactTemperature(x);
 
         // report statistics of this time step
         timeLoop->reportTimeStep();
@@ -208,6 +212,11 @@ int main(int argc, char** argv) try
         // set new dt as suggested by newton controller
         timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize()));
 
+         // write vtk output
+        vtkWriter.write(timeLoop->timeStepIndex()==0 ||
+                        timeLoop->timeStepIndex() % outputInterval == 0 ||
+                        timeLoop->willBeFinished());
+
     } while (!timeLoop->finished());
 
     timeLoop->finalize(leafGridView.comm());
diff --git a/test/porousmediumflow/3p/implicit/test_cc3pniconvection.input b/test/porousmediumflow/3p/implicit/test_cc3pniconvection.input
index 8f4c56c4a4..e189a30b91 100644
--- a/test/porousmediumflow/3p/implicit/test_cc3pniconvection.input
+++ b/test/porousmediumflow/3p/implicit/test_cc3pniconvection.input
@@ -15,3 +15,6 @@ EnableGravity = 0 # disable gravity
 
 [Vtk]
 AddVelocity = 1 #Enable velocity output
+
+[Newton]
+EnableResidualCriterion = true
-- 
GitLab