diff --git a/dumux/discretization/staggered/gridfluxvariablescache.hh b/dumux/discretization/staggered/gridfluxvariablescache.hh
index ff6d9273bc49518076e6d7be1e3cf76b1e55d459..b78cbe750302a58f66f18bc8dc4d04d6afeff516 100644
--- a/dumux/discretization/staggered/gridfluxvariablescache.hh
+++ b/dumux/discretization/staggered/gridfluxvariablescache.hh
@@ -91,11 +91,17 @@ public:
     //! export the type of the local view
     using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
 
-    StaggeredGridFluxVariablesCache(const Problem& problem, const std::string& paramGroup = "")
+    [[deprecated("Will be removed after 3.2. Use StaggeredGridFluxVariablesCache(problem) instead.")]]
+    StaggeredGridFluxVariablesCache(const Problem& problem, const std::string& paramGroup)
     : problemPtr_(&problem)
     , staggeredUpwindMethods_(paramGroup)
     {}
 
+    StaggeredGridFluxVariablesCache(const Problem& problem)
+    : problemPtr_(&problem)
+    , staggeredUpwindMethods_(problem.paramGroup())
+    {}
+
     // When global caching is enabled, precompute transmissibilities and stencils for all the scv faces
     template<class GridGeometry, class GridVolumeVariables, class SolutionVector>
     void update(const GridGeometry& gridGeometry,
@@ -181,9 +187,9 @@ public:
     //! export the type of the local view
     using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
 
-    StaggeredGridFluxVariablesCache(const Problem& problem, const std::string& paramGroup = "")
+    StaggeredGridFluxVariablesCache(const Problem& problem)
     : problemPtr_(&problem)
-    , staggeredUpwindMethods_(paramGroup)
+    , staggeredUpwindMethods_(problem.paramGroup())
       {}
 
     // When global caching is enabled, precompute transmissibilities and stencils for all the scv faces
diff --git a/dumux/freeflow/navierstokes/staggered/staggeredupwindfluxvariables.hh b/dumux/freeflow/navierstokes/staggered/staggeredupwindfluxvariables.hh
index d1d011a4692cccef56896de7ae53934440789492..0566c7e6e567ba15418fa25836e862a05c5c44f8 100644
--- a/dumux/freeflow/navierstokes/staggered/staggeredupwindfluxvariables.hh
+++ b/dumux/freeflow/navierstokes/staggered/staggeredupwindfluxvariables.hh
@@ -412,9 +412,9 @@ private:
             if (ownScvf.hasParallelNeighbor(oppositeSubFaceIdx, 0))
                 momenta[2] = faceVars.velocityParallel(oppositeSubFaceIdx, 0) * insideVolVars.density();
             else
-                momenta[2] = getParallelVelocityFromOtherBoundary_(problem, fvGeometry, ownScvf,
-                                                                   oppositeSubFaceIdx, element,
-                                                                   (momenta[1]/insideVolVars.density())) * insideVolVars.density();
+                momenta[2] = getParallelVelocityFromOppositeBoundary_(problem, element, fvGeometry, ownScvf,
+                                                                      faceVars, currentScvfBoundaryTypes,
+                                                                      oppositeSubFaceIdx) * insideVolVars.density();
         }
         else
         {
@@ -428,9 +428,10 @@ private:
             {
                 const Element& elementParallel = fvGeometry.gridGeometry().element(lateralFace.outsideScvIdx());
                 const SubControlVolumeFace& firstParallelScvf = fvGeometry.scvf(lateralFace.outsideScvIdx(), ownScvf.localFaceIdx());
-                momenta[2] = getParallelVelocityFromOtherBoundary_(problem, fvGeometry, firstParallelScvf,
-                                                                   localSubFaceIdx, elementParallel,
-                                                                   (momenta[1]/outsideVolVars.density())) * outsideVolVars.density();
+
+                momenta[2] = getParallelVelocityFromOppositeBoundary_(problem, elementParallel, fvGeometry, firstParallelScvf,
+                                                                      faceVars, problem.boundaryTypes(elementParallel, firstParallelScvf),
+                                                                      localSubFaceIdx) * outsideVolVars.density();
             }
         }
 
@@ -579,26 +580,22 @@ private:
                                                    const int localSubFaceIdx)
     {
         // Find out what boundary type is set on the lateral face
-        const bool lateralFaceHasDirichletPressure = lateralFaceBoundaryTypes && lateralFaceBoundaryTypes->isDirichlet(Indices::pressureIdx);
+        const bool useZeroGradient = lateralFaceBoundaryTypes && (lateralFaceBoundaryTypes->isSymmetry()
+                                                                  || lateralFaceBoundaryTypes->isDirichlet(Indices::pressureIdx));
         const bool lateralFaceHasBJS = lateralFaceBoundaryTypes && lateralFaceBoundaryTypes->isBJS(Indices::velocity(scvf.directionIndex()));
+        const bool lateralFaceHasDirichletVelocity = lateralFaceBoundaryTypes && lateralFaceBoundaryTypes->isDirichlet(Indices::velocity(scvf.directionIndex()));
         const Scalar velocitySelf = faceVars.velocitySelf();
 
         // If there is a Dirichlet condition for the pressure we assume zero gradient for the velocity,
         // so the velocity at the boundary equal to that on the scvf.
-        if (lateralFaceHasDirichletPressure)
+        if (useZeroGradient)
             return velocitySelf;
 
         if (lateralFaceHasBJS)
-        {
-            const auto eIdx = scvf.insideScvIdx();
-            const auto& lateralFace = fvGeometry.scvf(eIdx, scvf.pairData(localSubFaceIdx).localLateralFaceIdx);
-            const Scalar velocityGrad_ji = VelocityGradients::velocityGradJI(problem, element, fvGeometry, scvf, faceVars,
-                                                                             currentScvfBoundaryTypes, lateralFaceBoundaryTypes, localSubFaceIdx);
+            return VelocityGradients::beaversJosephVelocityAtLateralScvf(problem, element, fvGeometry, scvf,  faceVars,
+                                                                         currentScvfBoundaryTypes, lateralFaceBoundaryTypes, localSubFaceIdx);
 
-            const SubControlVolume& scv = fvGeometry.scv(scvf.insideScvIdx());
-            return problem.beaversJosephVelocity(element, scv, lateralFace, velocitySelf, velocityGrad_ji);
-        }
-        else
+        else if(lateralFaceHasDirichletVelocity)
         {
             //     ________________
             //     ---------------o                 || frontal face of staggered half-control-volume
@@ -612,6 +609,11 @@ private:
             const auto ghostFace = makeParallelGhostFace_(scvf, localSubFaceIdx);
             return problem.dirichlet(element, ghostFace)[Indices::velocity(scvf.directionIndex())];
         }
+        else
+        {
+            // Neumann conditions are not well implemented
+            DUNE_THROW(Dune::InvalidStateException, "Something went wrong with the boundary conditions for the momentum equations at global position " << fvGeometry.scvf(scvf.insideScvIdx(), scvf.pairData(localSubFaceIdx).localLateralFaceIdx).center());
+        }
     }
 
     /*!
@@ -623,60 +625,36 @@ private:
      * \param boundaryElement The element that is on the boundary
      * \param parallelVelocity The velocity over scvf
      */
-    static Scalar getParallelVelocityFromOtherBoundary_(const Problem& problem,
-                                                        const FVElementGeometry& fvGeometry,
-                                                        const SubControlVolumeFace& scvf,
-                                                        const int localIdx,
-                                                        const Element& boundaryElement,
-                                                        const Scalar parallelVelocity)
+    static Scalar getParallelVelocityFromOppositeBoundary_(const Problem& problem,
+                                                           const Element& element,
+                                                           const FVElementGeometry& fvGeometry,
+                                                           const SubControlVolumeFace& scvf,
+                                                           const FaceVariables& faceVars,
+                                                           const Dune::Std::optional<BoundaryTypes>& currentScvfBoundaryTypes,
+                                                           const int localOppositeSubFaceIdx)
     {
         // A ghost subface at the boundary is created, featuring the location of the sub face's center
-        const SubControlVolumeFace& lateralScvf = fvGeometry.scvf(scvf.insideScvIdx(), scvf.pairData(localIdx).localLateralFaceIdx);
-        GlobalPosition lateralBoundaryFaceCenter = scvf.pairData(localIdx).lateralStaggeredFaceCenter + lateralScvf.center();
-        lateralBoundaryFaceCenter *= 0.5;
+        const SubControlVolumeFace& lateralOppositeScvf = fvGeometry.scvf(scvf.insideScvIdx(), scvf.pairData(localOppositeSubFaceIdx).localLateralFaceIdx);
+        GlobalPosition center = scvf.pairData(localOppositeSubFaceIdx).lateralStaggeredFaceCenter + lateralOppositeScvf.center();
+        center *= 0.5;
 
-        //    ________________
-        //    --------####o###                 || frontal face of staggered half-control-volume
-        //    |      ||      | current scvf    #  lateralBoundaryFace of interest, lies on lateral boundary
+        //          lateral face               #  lateralFace currently being assembled
+        //    --------########                 || frontal face of staggered half-control-volume
+        //    |      ||      | current scvf    %  lateralOppositeBoundaryFace of interest, lies on boundary
         //    |      ||      |                 x  dof position
         //    |      ||      x~~~~> vel.Self   -- element boundaries
         //    |      ||      |                 __ domain boundary
         //    |      ||      |                 o  position at which the boundary conditions will be evaluated
-        //    ----------------                    (lateralBoundaryFaceCenter)
+        //    --------%%%c%%%o
+        //    ________________                 c  center of opposite boundary face
 
-        const SubControlVolumeFace lateralBoundaryFace = lateralScvf.makeBoundaryFace(lateralBoundaryFaceCenter);
 
-        // The boundary condition is checked, in case of symmetry or Dirichlet for the pressure
-        // a gradient of zero is assumed in the direction normal to the bounadry, while if there is
-        // Dirichlet of BJS for the velocity the related values are exploited.
-        const auto bcTypes = problem.boundaryTypes(boundaryElement, lateralBoundaryFace);
+        // Get the boundary types of the lateral opposite boundary face
+        const auto lateralOppositeFaceBoundaryTypes = problem.boundaryTypes(element, lateralOppositeScvf.makeBoundaryFace(center));
 
-        if (bcTypes.isDirichlet(Indices::velocity(scvf.directionIndex())))
-        {
-            //    ________________
-            //    --------#######o                 || frontal face of staggered half-control-volume
-            //    |      ||      | current scvf    #  lateralBoundaryFace of interest, lies on lateral boundary
-            //    |      ||      |                 x  dof position
-            //    |      ||      x~~~~> vel.Self   -- element boundaries
-            //    |      ||      |                 __ domain boundary
-            //    |      ||      |                 o  position at which the boundary conditions will be evaluated
-            //    ----------------
-
-            const SubControlVolumeFace ghostFace = makeParallelGhostFace_(scvf, localIdx);
-            return problem.dirichlet(boundaryElement, ghostFace)[Indices::velocity(scvf.directionIndex())];
-        }
-        else if (bcTypes.isSymmetry() || bcTypes.isDirichlet(Indices::pressureIdx))
-            return parallelVelocity;
-        else if (bcTypes.isBJS(Indices::velocity(scvf.directionIndex())))
-        {
-            const SubControlVolume& scv = fvGeometry.scv(scvf.insideScvIdx());
-            return problem.beaversJosephVelocity(boundaryElement, scv, lateralScvf, parallelVelocity, 0.0);
-        }
-        else
-        {
-            // Neumann conditions are not well implemented
-            DUNE_THROW(Dune::InvalidStateException, "Something went wrong with the boundary conditions for the momentum equations at global position " << lateralBoundaryFaceCenter);
-        }
+        return getParallelVelocityFromBoundary_(problem, element, fvGeometry, scvf,
+                                                faceVars, currentScvfBoundaryTypes, lateralOppositeFaceBoundaryTypes,
+                                                localOppositeSubFaceIdx);
     }
 
     //! helper function to conveniently create a ghost face which is outside the domain, parallel to the scvf of interest