diff --git a/dumux/discretization/staggered/freeflow/facevariables.hh b/dumux/discretization/staggered/freeflow/facevariables.hh
index 5cadb11af6f3537d9bb8a10cde4d4e59627ff248..b84abd27c42d494478df2c7a86fb5ad9d8f82809 100644
--- a/dumux/discretization/staggered/freeflow/facevariables.hh
+++ b/dumux/discretization/staggered/freeflow/facevariables.hh
@@ -86,24 +86,6 @@ public:
         velocitySelf_ = faceSol[scvf.dofIndex()];
         velocityOpposite_ = faceSol[scvf.dofIndexOpposingFace()];
 
-        // lambda to conveniently create a ghost face which is outside the domain, parallel to the scvf of interest
-        auto makeGhostFace = [](const auto& pos)
-        {
-            return SubControlVolumeFace(pos, std::vector<unsigned int>{0,0});
-        };
-
-        // lambda to check whether there is a parallel face neighbor
-        auto hasParallelNeighbor = [](const auto& subFaceData)
-        {
-            return subFaceData.outerParallelFaceDofIdx >= 0;
-        };
-
-        // lambda to check whether there is a normal face neighbor
-        auto hasNormalNeighbor = [](const auto& subFaceData)
-        {
-            return subFaceData.normalPair.second >= 0;
-        };
-
         // handle all sub faces
         for(int i = 0; i < scvf.pairData().size(); ++i)
         {
@@ -112,21 +94,12 @@ public:
             // treat the velocities normal to the face
             velocityNormalInside_[i] = faceSol[subFaceData.normalPair.first];
 
-            if(hasNormalNeighbor(subFaceData))
-            {
+            if(scvf.hasFrontalNeighbor(i))
                 velocityNormalOutside_[i] = faceSol[subFaceData.normalPair.second];
-            }
-            else
-            {
-                const auto& normalFace = fvGeometry.scvf(scvf.insideScvIdx(), subFaceData.localNormalFaceIdx);
-                const auto normalDirIdx = normalFace.directionIndex();
-                velocityNormalOutside_[i] = problem.dirichlet(element, makeGhostFace(subFaceData.virtualOuterNormalFaceDofPos))[Indices::velocity(normalDirIdx)];
-            }
 
             // treat the velocity parallel to the face
-            velocityParallel_[i] = hasParallelNeighbor(subFaceData) ?
-                                   velocityParallel_[i] = faceSol[subFaceData.outerParallelFaceDofIdx] :
-                                   problem.dirichlet(element, makeGhostFace(subFaceData.virtualOuterParallelFaceDofPos))[Indices::velocity(scvf.directionIndex())];
+            if(scvf.hasParallelNeighbor(i))
+                velocityParallel_[i] = faceSol[subFaceData.outerParallelFaceDofIdx];
         }
     }
 
diff --git a/dumux/discretization/staggered/freeflow/subcontrolvolumeface.hh b/dumux/discretization/staggered/freeflow/subcontrolvolumeface.hh
index be10af48e93e590ec2d76bd46bd4576e4626da73..426657563cfc9ce92f8fac15456551a3391028f9 100644
--- a/dumux/discretization/staggered/freeflow/subcontrolvolumeface.hh
+++ b/dumux/discretization/staggered/freeflow/subcontrolvolumeface.hh
@@ -31,7 +31,6 @@
 #include <dumux/discretization/staggered/subcontrolvolumeface.hh>
 #include <dumux/discretization/staggered/freeflow/staggeredgeometryhelper.hh>
 #include <dumux/common/properties.hh>
-#include <dumux/common/optional.hh>
 
 #include <typeinfo>
 
@@ -82,34 +81,32 @@ public:
       unitOuterNormal_(is.centerUnitOuterNormal()),
       scvfIndex_(scvfIndex),
       scvIndices_(scvIndices),
-      boundary_(is.boundary())
+      boundary_(is.boundary()),
+      dofIdx_(geometryHelper.dofIndex()),
+      dofIdxOpposingFace_(geometryHelper.dofIndexOpposingFace()),
+      selfToOppositeDistance_(geometryHelper.selfToOppositeDistance()),
+      pairData_(geometryHelper.pairData()),
+      localFaceIdx_(geometryHelper.localFaceIndex()),
+      dirIdx_(geometryHelper.directionIndex()),
+      normalInPosCoordDir_(unitOuterNormal_[directionIndex()] > 0.0),
+      outerNormalScalar_(unitOuterNormal_[directionIndex()]),
+      isGhostFace_(false)
       {
           corners_.resize(isGeometry.corners());
           for (int i = 0; i < isGeometry.corners(); ++i)
               corners_[i] = isGeometry.corner(i);
-
-          dofIdx_ = geometryHelper.dofIndex();
-          oppositeIdx_ = geometryHelper.dofIndexOpposingFace();
-          selfToOppositeDistance_ = geometryHelper.selfToOppositeDistance();
-
-          pairData_ = geometryHelper.pairData();
-          localFaceIdx_ = geometryHelper.localFaceIndex();
-          dirIdx_ = geometryHelper.directionIndex();
-          normalInPosCoordDir_ = unitOuterNormal()[directionIndex()] > 0.0;
-          outerNormalScalar_ = unitOuterNormal()[directionIndex()];
-          isGhostFace_ = false;
       }
 
-      //! Constructor for a ghost face outside of the domain. Only needed to retrieve the center and scvIndices
-      FreeFlowStaggeredSubControlVolumeFace(const GlobalPosition& dofPosition,
-                                    const std::vector<GridIndexType>& scvIndices)
-      {
-          isGhostFace_ = true;
-          center_ = dofPosition;
-          scvIndices_ = scvIndices;
-          scvfIndex_ = -1;
-          dofIdx_ = -1;
-      }
+    //! Constructor for a ghost face outside of the domain. Only needed to retrieve the center and scvIndices
+    FreeFlowStaggeredSubControlVolumeFace(const GlobalPosition& dofPosition,
+                                          const std::vector<GridIndexType>& scvIndices,
+                                          const int dofIdx = -1)
+    : center_(dofPosition),
+      scvfIndex_(-1),
+      scvIndices_(scvIndices),
+      dofIdx_(dofIdx),
+      isGhostFace_(true)
+    {}
 
     //! The center of the sub control volume face
     const GlobalPosition& center() const
@@ -189,7 +186,7 @@ public:
     //! The global index of the dof living on the opposing face
     GridIndexType dofIndexOpposingFace() const
     {
-        return oppositeIdx_;
+        return dofIdxOpposingFace_;
     }
 
     //! The local index of this sub control volume face
@@ -234,6 +231,21 @@ public:
         return pairData_;
     }
 
+    bool isGhostFace() const
+    {
+        return isGhostFace_;
+    }
+
+    bool hasParallelNeighbor(const int localFaceIdx) const
+    {
+        return pairData_[localFaceIdx].outerParallelFaceDofIdx >= 0;
+    }
+
+    bool hasFrontalNeighbor(const int localFaceIdx) const
+    {
+        return pairData_[localFaceIdx].normalPair.second >= 0;
+    }
+
 private:
     Dune::GeometryType geomType_;
     std::vector<GlobalPosition> corners_;
@@ -245,7 +257,7 @@ private:
     bool boundary_;
 
     int dofIdx_;
-    int oppositeIdx_;
+    int dofIdxOpposingFace_;
     Scalar selfToOppositeDistance_;
     std::array<PairData<Scalar, GlobalPosition>, numPairs> pairData_;
     int localFaceIdx_;
diff --git a/dumux/freeflow/navierstokes/staggered/fluxvariables.hh b/dumux/freeflow/navierstokes/staggered/fluxvariables.hh
index 4df4442acc2c92ef19e51ce82970e715c33e0bb4..d693511e762366607c143f7e234c5637f92d2afe 100644
--- a/dumux/freeflow/navierstokes/staggered/fluxvariables.hh
+++ b/dumux/freeflow/navierstokes/staggered/fluxvariables.hh
@@ -283,16 +283,10 @@ public:
             const auto& normalFace = fvGeometry.scvf(eIdx, scvf.pairData()[localSubFaceIdx].localNormalFaceIdx);
 
             // Check if we have a symmetry boundary condition. If yes, the tangental part of the momentum flux can be neglected.
-            if(scvf.pairData()[localSubFaceIdx].outerParallelFaceDofIdx < 0)
+            if(!scvf.hasParallelNeighbor(localSubFaceIdx))
             {
-                // Lambda to conveniently create a ghost face which is outside the domain, parallel to the scvf of interest.
-                auto makeGhostFace = [eIdx] (const GlobalPosition& pos)
-                {
-                    return SubControlVolumeFace(pos, std::vector<unsigned int>{eIdx,eIdx});
-                };
-
                 // Use the ghost face to check if there is a symmetry boundary condition and skip any further steps if yes.
-                const auto bcTypes = problem.boundaryTypes(element, makeGhostFace(scvf.pairData()[localSubFaceIdx].virtualOuterParallelFaceDofPos));
+                const auto bcTypes = problem.boundaryTypes(element, makeParallelGhostFace_(scvf, localSubFaceIdx));
                 if(bcTypes.isSymmetry())
                     continue;
             }
@@ -346,7 +340,18 @@ private:
 
         // Get the velocities at the current (own) scvf and at the parallel one at the neighboring scvf.
         const Scalar velocitySelf = faceVars.velocitySelf();
-        const Scalar velocityParallel = faceVars.velocityParallel(localSubFaceIdx);
+
+        // Lambda to conveniently get the outer parallel velocity for normal faces that are on the boundary
+        // and therefore have no neighbor. Calls the problem to retrieve a fixed value set on the boundary.
+        auto getParallelVelocityFromBoundary = [&]()
+        {
+            const auto ghostFace = makeParallelGhostFace_(scvf, localSubFaceIdx);
+            return problem.dirichlet(element, ghostFace)[Indices::velocity(scvf.directionIndex())];
+        };
+
+        const Scalar velocityParallel = scvf.hasParallelNeighbor(localSubFaceIdx) ?
+                                        faceVars.velocityParallel(localSubFaceIdx)
+                                      : getParallelVelocityFromBoundary();
 
         // Get the volume variables of the own and the neighboring element
         const auto& insideVolVars = elemVolVars[normalFace.insideScvIdx()];
@@ -420,7 +425,19 @@ private:
         // the outer one at the respective staggered face of the element on the other side of the
         // current scvf.
         const Scalar innerNormalVelocity = faceVars.velocityNormalInside(localSubFaceIdx);
-        const Scalar outerNormalVelocity = faceVars.velocityNormalOutside(localSubFaceIdx);
+
+        // Lambda to conveniently get the outer normal velocity for faces that are on the boundary
+        // and therefore have no neighbor. Calls the problem to retrieve a fixed value set on the boundary.
+        auto getNormalVelocityFromBoundary = [&]()
+        {
+            const auto ghostFace = makeNormalGhostFace_(scvf, localSubFaceIdx);
+            return problem.dirichlet(element, ghostFace)[Indices::velocity(normalFace.directionIndex())];
+        };
+
+        const Scalar outerNormalVelocity = scvf.hasFrontalNeighbor(localSubFaceIdx) ?
+                                           faceVars.velocityNormalOutside(localSubFaceIdx)
+                                         : getNormalVelocityFromBoundary();
+
 
         // Calculate the velocity gradient in positive coordinate direction.
         const Scalar normalDeltaV = scvf.normalInPosCoordDir() ?
@@ -435,7 +452,18 @@ private:
         // For the parallel derivative, get the velocities at the current (own) scvf
         // and at the parallel one at the neighboring scvf.
         const Scalar innerParallelVelocity = faceVars.velocitySelf();
-        const Scalar outerParallelVelocity = faceVars.velocityParallel(localSubFaceIdx);
+
+        // Lambda to conveniently get the outer parallel velocity for normal faces that are on the boundary
+        // and therefore have no neighbor. Calls the problem to retrieve a fixed value set on the boundary.
+        auto getParallelVelocityFromBoundary = [&]()
+        {
+            const auto ghostFace = makeParallelGhostFace_(scvf, localSubFaceIdx);
+            return problem.dirichlet(element, ghostFace)[Indices::velocity(scvf.directionIndex())];
+        };
+
+        const Scalar outerParallelVelocity = scvf.hasParallelNeighbor(localSubFaceIdx) ?
+                                             faceVars.velocityParallel(localSubFaceIdx)
+                                           : getParallelVelocityFromBoundary();
 
         // The velocity gradient already accounts for the orientation
         // of the staggered face's outer normal vector.
@@ -494,6 +522,27 @@ private:
         // Account for the orientation of the face at the boundary,
         return outflow * scvf.directionSign();
     }
+
+private:
+
+    //! helper functiuob to conveniently create a ghost face which is outside the domain, parallel to the scvf of interest
+    SubControlVolumeFace makeGhostFace_(const SubControlVolumeFace& ownScvf, const GlobalPosition& pos) const
+    {
+        return SubControlVolumeFace(pos, std::vector<unsigned int>{ownScvf.insideScvIdx(), ownScvf.outsideScvIdx()}, ownScvf.dofIndex());
+    };
+
+    //! helper functiuob to conveniently create a ghost face which is outside the domain, parallel to the scvf of interest
+    SubControlVolumeFace makeNormalGhostFace_(const SubControlVolumeFace& ownScvf, const int localSubFaceIdx) const
+    {
+        return makeGhostFace_(ownScvf, ownScvf.pairData(localSubFaceIdx).virtualOuterNormalFaceDofPos);
+    };
+
+    //! helper functiuob to conveniently create a ghost face which is outside the domain, parallel to the scvf of interest
+    SubControlVolumeFace makeParallelGhostFace_(const SubControlVolumeFace& ownScvf, const int localSubFaceIdx) const
+    {
+        return makeGhostFace_(ownScvf, ownScvf.pairData(localSubFaceIdx).virtualOuterParallelFaceDofPos);
+    };
+
 };
 
 } // end namespace