From 8c58db99f7db4f9b6d43f848e37ea7a17187cae8 Mon Sep 17 00:00:00 2001
From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de>
Date: Thu, 6 Sep 2018 18:13:42 +0200
Subject: [PATCH] [freeflow][iofields] Add createStaggeredFVNameFunction as
 free function

* takes a multitypeblockvector and an index constant to automatically
  figure out the pv names for cellcenter and face privars
---
 dumux/freeflow/navierstokes/iofields.hh | 40 +++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/dumux/freeflow/navierstokes/iofields.hh b/dumux/freeflow/navierstokes/iofields.hh
index fae9c6fa83..704541c2ae 100644
--- a/dumux/freeflow/navierstokes/iofields.hh
+++ b/dumux/freeflow/navierstokes/iofields.hh
@@ -26,6 +26,8 @@
 
 #include <dune/common/fvector.hh>
 #include <dune/common/deprecated.hh>
+#include <dune/common/indices.hh>
+#include <dune/istl/multitypeblockvector.hh> // TODO: needed? or is forward declare enough?
 
 #include <dumux/common/parameters.hh>
 #include <dumux/discretization/methods.hh>
@@ -34,6 +36,44 @@
 namespace Dumux
 {
 
+/*!
+ * \ingroup InputOutput
+ * \ingroup NavierStokesModel
+ * \brief helper function to determine the names of cell-centered primary variables of a model with staggered grid discretization
+ * \note use this as input for the load solution function
+ */
+template<class ModelTraits, class IOFields, class FluidSystem, std::size_t cellCenterIdx = 0, class ...Args, std::size_t i>
+std::function<std::string(int,int)> createStaggeredPVNameFunction(const Dune::MultiTypeBlockVector<Args...>&,
+                                                                  Dune::index_constant<i> idx,
+                                                                  const std::string& paramGroup = "")
+{
+    using CellCenterPriVarsType = typename std::tuple_element_t<cellCenterIdx, std::tuple<Args...>>::block_type;
+    static constexpr auto offset = ModelTraits::numEq() - CellCenterPriVarsType::dimension;
+
+    if (i == cellCenterIdx) // cell center
+    {
+        if (hasParamInGroup(paramGroup, "LoadSolution.CellCenterPriVarNames"))
+        {
+            const auto pvName = getParamFromGroup<std::vector<std::string>>(paramGroup, "LoadSolution.CellCenterPriVarNames");
+            return [n = std::move(pvName)](int pvIdx, int state = 0){ return n[pvIdx]; };
+        }
+        else
+        // add an offset to the pvIdx so that the velocities are skipped
+        return [](int pvIdx, int state = 0){ return IOFields::template primaryVariableName<ModelTraits ,FluidSystem>(pvIdx + offset, state); };
+    }
+    else // face
+    {
+            if (hasParamInGroup(paramGroup, "LoadSolution.FacePriVarNames"))
+            {
+                const auto pvName = getParamFromGroup<std::vector<std::string>>(paramGroup, "LoadSolution.FacePriVarNames");
+                return [n = std::move(pvName)](int pvIdx, int state = 0){ return n[pvIdx]; };
+            }
+            else
+                // there is only one scalar-type primary variable called "v" living on the faces
+                return [](int pvIdx, int state = 0){ return IOFields::template primaryVariableName<ModelTraits, FluidSystem>(pvIdx , state); };
+    }
+}
+
 /*!
  * \ingroup NavierStokesModel
  * \brief Adds I/O fields for the Navier-Stokes model
-- 
GitLab