From b88a16179c76b1405f4c528e12062dcb485f80d3 Mon Sep 17 00:00:00 2001
From: Timo Koch <timo.koch@iws.uni-stuttgart.de>
Date: Mon, 26 Nov 2018 10:00:46 +0100
Subject: [PATCH] [cleanup] Simplify or shorten privarswitch code

---
 dumux/multidomain/newtonsolver.hh | 48 +++++++++++++++++--------------
 dumux/nonlinear/newtonsolver.hh   | 47 +++++++++++++++++-------------
 2 files changed, 53 insertions(+), 42 deletions(-)

diff --git a/dumux/multidomain/newtonsolver.hh b/dumux/multidomain/newtonsolver.hh
index 0028df82bc..e63fb4fd77 100644
--- a/dumux/multidomain/newtonsolver.hh
+++ b/dumux/multidomain/newtonsolver.hh
@@ -29,19 +29,15 @@
 #include <dumux/nonlinear/newtonsolver.hh>
 
 namespace Dumux {
+namespace Detail {
 
-namespace MDDetail {
-
-template<class Assembler, class IdType>
-using GridVariables = std::decay_t<decltype(std::declval<Assembler>().gridVariables(IdType()))>;
-
-template<class Assembler, class IdType>
-using GetPVSwitch = typename GridVariables<Assembler, IdType>::VolumeVariables::PrimaryVariableSwitch;
+template<class Assembler, class Index>
+using DetectPVSwitchMultiDomain = typename Assembler::template GridVariables<Index::value>::VolumeVariables::PrimaryVariableSwitch;
 
 template<class Assembler, std::size_t i>
-using PrimaryVariableSwitch = Dune::Std::detected_or<int, GetPVSwitch, Assembler, Dune::index_constant<i>>;
+using GetPVSwitchMultiDomain = Dune::Std::detected_or<int, DetectPVSwitchMultiDomain, Assembler, Dune::index_constant<i>>;
 
-}
+} // end namespace Detail
 
 /*!
  * \ingroup Nonlinear
@@ -57,15 +53,14 @@ class MultiDomainNewtonSolver: public NewtonSolver<Assembler, LinearSolver, Reas
     using SolutionVector = typename Assembler::ResidualType;
 
     template<std::size_t i>
-    using PrimaryVariableSwitch = typename MDDetail::PrimaryVariableSwitch<Assembler, i>::type;
+    using PrimaryVariableSwitch = typename Detail::GetPVSwitchMultiDomain<Assembler, i>::type;
 
     template<std::size_t i>
-    using PrivarSwitchPtr = std::unique_ptr<PrimaryVariableSwitch<i>>;
-
-    using PriVarSwitchPtrTuple = typename Assembler::Traits::template MakeTuple<PrivarSwitchPtr>;
+    using HasPriVarsSwitch = typename Detail::GetPVSwitchMultiDomain<Assembler, i>::value_t; // std::true_type or std::false_type
 
     template<std::size_t i>
-    using HasPriVarsSwitch = typename MDDetail::PrimaryVariableSwitch<Assembler, i>::value_t;
+    using PrivarSwitchPtr = std::unique_ptr<PrimaryVariableSwitch<i>>;
+    using PriVarSwitchPtrTuple = typename Assembler::Traits::template MakeTuple<PrivarSwitchPtr>;
 
 public:
 
@@ -114,7 +109,7 @@ public:
         using namespace Dune::Hybrid;
         forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](auto&& id)
         {
-            resetPriVarSwitch_(u[id].size(), id, HasPriVarsSwitch<id>());
+            resetPriVarSwitch_(u[id].size(), id, HasPriVarsSwitch<id>{});
         });
     }
 
@@ -143,7 +138,7 @@ public:
         using namespace Dune::Hybrid;
         forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](auto&& id)
         {
-            invokePriVarSwitch_(uCurrentIter[id], id, HasPriVarsSwitch<id>());
+            invokePriVarSwitch_(uCurrentIter[id], id, HasPriVarsSwitch<id>{});
         });
 
         ParentType::newtonEndStep(uCurrentIter, uLastIter);
@@ -152,11 +147,15 @@ public:
 
 private:
 
-
+    /*!
+     * \brief Reset the privar switch state, noop if there is no priVarSwitch
+     */
     template<std::size_t i>
-    void resetPriVarSwitch_(const std::size_t numDofs, Dune::index_constant<i> id, std::false_type)
-    {}
+    void resetPriVarSwitch_(const std::size_t numDofs, Dune::index_constant<i> id, std::false_type) {}
 
+    /*!
+     * \brief Switch primary variables if necessary
+     */
     template<std::size_t i>
     void resetPriVarSwitch_(const std::size_t numDofs, Dune::index_constant<i> id, std::true_type)
     {
@@ -165,10 +164,15 @@ private:
         priVarsSwitchedInLastIteration_[i] = false;
     }
 
+    /*!
+     * \brief Switch primary variables if necessary, noop if there is no priVarSwitch
+     */
     template<class SubSol, std::size_t i>
-    void invokePriVarSwitch_(SubSol&, Dune::index_constant<i> id, std::false_type)
-    {}
+    void invokePriVarSwitch_(SubSol&, Dune::index_constant<i> id, std::false_type) {}
 
+    /*!
+     * \brief Switch primary variables if necessary
+     */
     template<class SubSol, std::size_t i>
     void invokePriVarSwitch_(SubSol& uCurrentIter, Dune::index_constant<i> id, std::true_type)
     {
@@ -198,7 +202,7 @@ private:
         }
     }
 
-
+    //! the coupling manager
     std::shared_ptr<CouplingManager> couplingManager_;
 
     //! the class handling the primary variable switch
diff --git a/dumux/nonlinear/newtonsolver.hh b/dumux/nonlinear/newtonsolver.hh
index f81f878570..50b1242113 100644
--- a/dumux/nonlinear/newtonsolver.hh
+++ b/dumux/nonlinear/newtonsolver.hh
@@ -29,6 +29,7 @@
 #include <cmath>
 #include <memory>
 #include <iostream>
+#include <type_traits>
 
 #include <dune/common/timer.hh>
 #include <dune/common/exceptions.hh>
@@ -49,8 +50,8 @@
 #include "newtonconvergencewriter.hh"
 
 namespace Dumux {
-
 namespace Detail {
+
 //! helper struct detecting if an assembler supports partial reassembly
 struct supportsPartialReassembly
 {
@@ -63,13 +64,12 @@ struct supportsPartialReassembly
 
 //! helper aliases to extract a primary variable switch from the VolumeVariables (if defined, yields int otherwise)
 template<class Assembler>
-using GetPVSwitch = typename Assembler::GridVariables::VolumeVariables::PrimaryVariableSwitch;
+using DetectPVSwitch = typename Assembler::GridVariables::VolumeVariables::PrimaryVariableSwitch;
 
 template<class Assembler>
-using PrimaryVariableSwitch = Dune::Std::detected_or<int, GetPVSwitch, Assembler>;
-
-}
+using GetPVSwitch = Dune::Std::detected_or<int, DetectPVSwitch, Assembler>;
 
+} // end namespace Detail
 
 /*!
  * \ingroup Nonlinear
@@ -91,8 +91,9 @@ class NewtonSolver
     using SolutionVector = typename Assembler::ResidualType;
     using ConvergenceWriter = ConvergenceWriterInterface<SolutionVector>;
 
-    using PrimaryVariableSwitch = typename Detail::PrimaryVariableSwitch<Assembler>::type;
-    static constexpr bool hasPriVarsSwitch = Detail::PrimaryVariableSwitch<Assembler>::value_t::value;
+    using PrimaryVariableSwitch = typename Detail::GetPVSwitch<Assembler>::type;
+    using HasPriVarsSwitch = typename Detail::GetPVSwitch<Assembler>::value_t; // std::true_type or std::false_type
+    static constexpr bool hasPriVarsSwitch() { return HasPriVarsSwitch::value; };
 
 public:
 
@@ -124,7 +125,7 @@ public:
         if (enablePartialReassembly_)
             partialReassembler_ = std::make_unique<Reassembler>(*assembler_);
 
-        if (hasPriVarsSwitch)
+        if (hasPriVarsSwitch())
         {
             const int priVarSwitchVerbosity = getParamFromGroup<int>(paramGroup, "PrimaryVariableSwitch.Verbosity", 1);
             priVarSwitch_ = std::make_unique<PrimaryVariableSwitch>(priVarSwitchVerbosity);
@@ -254,7 +255,7 @@ public:
     virtual void newtonBegin(const SolutionVector& u)
     {
         numSteps_ = 0;
-        resetPriVarSwitch_(u.size());
+        resetPriVarSwitch_(u.size(), HasPriVarsSwitch{});
     }
 
     /*!
@@ -467,7 +468,7 @@ public:
     virtual void newtonEndStep(SolutionVector &uCurrentIter,
                                const SolutionVector &uLastIter)
     {
-        invokePriVarSwitch_(uCurrentIter);
+        invokePriVarSwitch_(uCurrentIter, HasPriVarsSwitch{});
 
         ++numSteps_;
 
@@ -650,23 +651,29 @@ protected:
     Assembler& assembler()
     { return *assembler_; }
 
-    template<bool enable = hasPriVarsSwitch, std::enable_if_t<!enable, int> = 0>
-    void resetPriVarSwitch_(const std::size_t numDofs)
-    {}
+    /*!
+     * \brief Reset the privar switch state, noop if there is no priVarSwitch
+     */
+    void resetPriVarSwitch_(const std::size_t numDofs, std::false_type) {}
 
-    template<bool enable = hasPriVarsSwitch, std::enable_if_t<enable, int> = 0>
-    void resetPriVarSwitch_(const std::size_t numDofs)
+    /*!
+     * \brief Reset the privar switch state
+     */
+    void resetPriVarSwitch_(const std::size_t numDofs, std::true_type)
     {
         priVarSwitch_->reset(numDofs);
         priVarsSwitchedInLastIteration_ = false;
     }
 
-    template<bool enable = hasPriVarsSwitch, std::enable_if_t<!enable, int> = 0>
-    void invokePriVarSwitch_(SolutionVector&)
-    {}
+    /*!
+     * \brief Switch primary variables if necessary, noop if there is no priVarSwitch
+     */
+    void invokePriVarSwitch_(SolutionVector&, std::false_type) {}
 
-    template<bool enable = hasPriVarsSwitch, std::enable_if_t<enable, int> = 0>
-    void invokePriVarSwitch_(SolutionVector& uCurrentIter)
+    /*!
+     * \brief Switch primary variables if necessary
+     */
+    void invokePriVarSwitch_(SolutionVector& uCurrentIter, std::true_type)
     {
         // update the variable switch (returns true if the pri vars at at least one dof were switched)
         // for disabled grid variable caching
-- 
GitLab