From 942e5c6b7e82d24385888b7258d69a635f4200d3 Mon Sep 17 00:00:00 2001
From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de>
Date: Wed, 3 Nov 2021 22:12:33 +0100
Subject: [PATCH] [staggered] Adapt coupling manager to handle twisted grids

---
 .../staggeredfreeflow/couplingmanager.hh      | 44 ++++++++++++++++---
 1 file changed, 37 insertions(+), 7 deletions(-)

diff --git a/dumux/multidomain/staggeredfreeflow/couplingmanager.hh b/dumux/multidomain/staggeredfreeflow/couplingmanager.hh
index 08fc15548a..adefb3a790 100644
--- a/dumux/multidomain/staggeredfreeflow/couplingmanager.hh
+++ b/dumux/multidomain/staggeredfreeflow/couplingmanager.hh
@@ -36,6 +36,7 @@
 #include <dumux/common/properties.hh>
 #include <dumux/common/typetraits/typetraits.hh>
 #include <dumux/multidomain/couplingmanager.hh>
+#include <dumux/discretization/facecentered/staggered/consistentlyorientedgrid.hh>
 
 namespace Dumux {
 
@@ -93,6 +94,11 @@ private:
 
     struct MassAndEnergyCouplingContext
     {
+        MassAndEnergyCouplingContext(FVElementGeometry<freeFlowMomentumIndex>&& f, const std::size_t i)
+        : fvGeometry(std::move(f))
+        , eIdx(i)
+        {}
+
         FVElementGeometry<freeFlowMomentumIndex> fvGeometry;
         std::size_t eIdx;
     };
@@ -328,12 +334,14 @@ public:
     {
         // TODO: rethink this! Maybe we only need scvJ.dofIndex()
         bindCouplingContext_(Dune::index_constant<freeFlowMassIndex>(), element, scvf.insideScvIdx()/*eIdx*/);
-        const auto& scvJ = massAndEnergyCouplingContext_[0].fvGeometry.scv(scvf.index()/*corresponds to scvIdx of staggered*/);
+
+        // the TPFA scvf index corresponds to the staggered scv index (might need mapping)
+        const auto localMomentumScvIdx = massScvfToMomentumScvIdx_(scvf, massAndEnergyCouplingContext_[0].fvGeometry);
+        const auto& scvJ = massAndEnergyCouplingContext_[0].fvGeometry.scv(localMomentumScvIdx);
 
         // create a unit normal vector oriented in positive coordinate direction
-        auto velocity = scvf.unitOuterNormal();
-        using std::abs;
-        std::for_each(velocity.begin(), velocity.end(), [](auto& v){ v = abs(v); });
+        typename SubControlVolumeFace<freeFlowMassIndex>::GlobalPosition velocity;
+        velocity[scvJ.dofAxis()] = 1.0;
 
         // create the actual velocity vector
         velocity *= this->curSol(freeFlowMomentumIndex)[scvJ.dofIndex()];
@@ -505,10 +513,10 @@ private:
     {
         if (massAndEnergyCouplingContext_.empty())
         {
-            auto fvGeometry = localView(this->problem(freeFlowMomentumIndex).gridGeometry());
+            const auto& gridGeometry = this->problem(freeFlowMomentumIndex).gridGeometry();
+            auto fvGeometry = localView(gridGeometry);
             fvGeometry.bindElement(elementI);
-
-            massAndEnergyCouplingContext_.emplace_back(MassAndEnergyCouplingContext{std::move(fvGeometry), eIdx});
+            massAndEnergyCouplingContext_.emplace_back(std::move(fvGeometry), eIdx);
         }
         else if (eIdx != massAndEnergyCouplingContext_[0].eIdx)
         {
@@ -581,6 +589,28 @@ private:
         }
     }
 
+    std::size_t massScvfToMomentumScvIdx_(const SubControlVolumeFace<freeFlowMassIndex>& massScvf,
+                                          [[maybe_unused]] const FVElementGeometry<freeFlowMomentumIndex>& momentumFVGeometry) const
+    {
+        if constexpr (ConsistentlyOrientedGrid<typename GridView<freeFlowMomentumIndex>::Grid>{})
+            return massScvf.index();
+        else
+        {
+            static const bool makeConsistentlyOriented = getParam<bool>("Grid.MakeConsistentlyOriented", true);
+            if (!makeConsistentlyOriented)
+                return massScvf.index();
+
+            for (const auto& momentumScv : scvs(momentumFVGeometry))
+            {
+                typename SubControlVolumeFace<freeFlowMassIndex>::GlobalPosition momentumUnitOuterNormal(0.0);
+                momentumUnitOuterNormal[momentumScv.dofAxis()] = momentumScv.directionSign();
+                if (Dune::FloatCmp::eq<typename GridView<freeFlowMomentumIndex>::ctype>(massScvf.unitOuterNormal()*momentumUnitOuterNormal, 1.0))
+                    return momentumScv.index();
+            }
+            DUNE_THROW(Dune::InvalidStateException, "No Momentum SCV found");
+        }
+    }
+
     CouplingStencilType emptyStencil_;
     std::vector<CouplingStencilType> momentumToMassAndEnergyStencils_;
     std::vector<CouplingStencilType> massAndEnergyToMomentumStencils_;
-- 
GitLab