From dd180043ef55c183ee3ec053eeae67bf30af75a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= <dennis.glaeser@iws.uni-stuttgart.de>
Date: Mon, 25 Sep 2023 19:32:50 +0200
Subject: [PATCH] [assembly][multidomain] add sd-specific view on assembler

---
 dumux/multidomain/assemblerview.hh | 66 ++++++++++++++++++++++++++++++
 dumux/multidomain/fvassembler.hh   | 20 +++++----
 2 files changed, 79 insertions(+), 7 deletions(-)
 create mode 100644 dumux/multidomain/assemblerview.hh

diff --git a/dumux/multidomain/assemblerview.hh b/dumux/multidomain/assemblerview.hh
new file mode 100644
index 0000000000..c6ff03bbda
--- /dev/null
+++ b/dumux/multidomain/assemblerview.hh
@@ -0,0 +1,66 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+//
+// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+/*!
+ * \file
+ * \ingroup MultiDomain
+ * \ingroup Assembly
+ * \brief Subdomain-specific views on multidomain assemblers.
+ */
+#ifndef DUMUX_MULTIDOMAIN_ASSEMBLER_VIEW_HH
+#define DUMUX_MULTIDOMAIN_ASSEMBLER_VIEW_HH
+
+namespace Dumux {
+
+/*!
+ * \ingroup MultiDomain
+ * \ingroup Assembly
+ * \brief Subdomain-specific view on a multidomain assembler.
+ *        Allows retrieval of sub-domain specific objects w/o passing a domain id.
+ * \todo This is not necessarily fv-specifiv (could be in other header).
+ * \todo Can we get rid of some of the interfaces?
+ */
+template<typename MDAssembler, std::size_t domainId>
+class MultiDomainAssemblerSubDomainView
+{
+    static constexpr Dune::index_constant<domainId> myId{};
+
+public:
+    using CouplingManager = typename MDAssembler::CouplingManager;
+    using SolutionVector = typename MDAssembler::SolutionVector;
+
+    MultiDomainAssemblerSubDomainView(MDAssembler& assembler, Dune::index_constant<domainId>)
+    : assembler_{assembler}
+    {}
+
+    template<std::size_t i>
+    auto localResidual(Dune::index_constant<i> id) const { return assembler_.localResidual(id); }
+    auto localResidual() const { return assembler_.localResidual(myId); }
+
+    template<std::size_t i>
+    const auto& problem(Dune::index_constant<i> id) const { return assembler_.problem(id); }
+    const auto& problem() const { return assembler_.problem(myId); }
+
+    template<std::size_t i>
+    const auto& gridGeometry(Dune::index_constant<i> id) const { return assembler_.gridGeometry(id); }
+    const auto& gridGeometry() const { return assembler_.gridGeometry(myId); }
+
+    template<std::size_t i>
+    const auto& gridVariables(Dune::index_constant<i> id) const { return assembler_.gridVariables(id); }
+    const auto& gridVariables() const { return assembler_.gridVariables(myId); }
+
+    const auto& prevSol() const { return assembler_.prevSol(); }
+    bool isStationaryProblem() const { return assembler_.isStationaryProblem(); }
+
+    static constexpr bool isImplicit() { return MDAssembler::isImplicit(); }
+
+private:
+    MDAssembler& assembler_;
+};
+
+} // end namespace Dumux
+
+#endif
diff --git a/dumux/multidomain/fvassembler.hh b/dumux/multidomain/fvassembler.hh
index 95b0800280..d619eba11f 100644
--- a/dumux/multidomain/fvassembler.hh
+++ b/dumux/multidomain/fvassembler.hh
@@ -36,6 +36,7 @@
 #include "subdomaincvfelocalassembler.hh"
 #include "subdomainstaggeredlocalassembler.hh"
 #include "subdomainfclocalassembler.hh"
+#include "assemblerview.hh"
 
 #include <dumux/discretization/method.hh>
 
@@ -124,37 +125,40 @@ private:
     using TimeLoop = TimeLoopBase<Scalar>;
     using ThisType = MultiDomainFVAssembler<MDTraits, CouplingManager, diffMethod, isImplicit()>;
 
+    template<std::size_t id>
+    using SubDomainAssemblerView = MultiDomainAssemblerSubDomainView<ThisType, id>;
+
     template<class DiscretizationMethod, std::size_t id>
     struct SubDomainAssemblerType;
 
     template<std::size_t id>
     struct SubDomainAssemblerType<DiscretizationMethods::CCTpfa, id>
     {
-        using type = SubDomainCCLocalAssembler<id, SubDomainTypeTag<id>, ThisType, diffMethod, isImplicit()>;
+        using type = SubDomainCCLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
     };
 
     template<std::size_t id>
     struct SubDomainAssemblerType<DiscretizationMethods::CCMpfa, id>
     {
-        using type = SubDomainCCLocalAssembler<id, SubDomainTypeTag<id>, ThisType, diffMethod, isImplicit()>;
+        using type = SubDomainCCLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
     };
 
     template<std::size_t id, class DM>
     struct SubDomainAssemblerType<DiscretizationMethods::CVFE<DM>, id>
     {
-        using type = SubDomainCVFELocalAssembler<id, SubDomainTypeTag<id>, ThisType, diffMethod, isImplicit()>;
+        using type = SubDomainCVFELocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
     };
 
     template<std::size_t id>
     struct SubDomainAssemblerType<DiscretizationMethods::Staggered, id>
     {
-        using type = SubDomainStaggeredLocalAssembler<id, SubDomainTypeTag<id>, ThisType, diffMethod, isImplicit()>;
+        using type = SubDomainStaggeredLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
     };
 
     template<std::size_t id>
     struct SubDomainAssemblerType<DiscretizationMethods::FCStaggered, id>
     {
-        using type = SubDomainFaceCenteredLocalAssembler<id, SubDomainTypeTag<id>, ThisType, diffMethod, isImplicit()>;
+        using type = SubDomainFaceCenteredLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
     };
 
     template<std::size_t id>
@@ -501,7 +505,8 @@ private:
     {
         assemble_(domainId, [&](const auto& element)
         {
-            SubDomainAssembler<i> subDomainAssembler(*this, element, curSol, *couplingManager_);
+            MultiDomainAssemblerSubDomainView view{*this, domainId};
+            SubDomainAssembler<i> subDomainAssembler(view, element, curSol, *couplingManager_);
             subDomainAssembler.assembleJacobianAndResidual(jacRow, subRes, gridVariablesTuple_);
         });
     }
@@ -512,7 +517,8 @@ private:
     {
         assemble_(domainId, [&](const auto& element)
         {
-            SubDomainAssembler<i> subDomainAssembler(*this, element, curSol, *couplingManager_);
+            MultiDomainAssemblerSubDomainView view{*this, domainId};
+            SubDomainAssembler<i> subDomainAssembler(view, element, curSol, *couplingManager_);
             subDomainAssembler.assembleResidual(subRes);
         });
     }
-- 
GitLab