From 1572df031abdfbee13ebf7f5a7367376cc9025a6 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de> Date: Fri, 9 Dec 2016 15:09:29 +0100 Subject: [PATCH] [staggeredGrid][localResidual] Add missing functions, clean-up * account for gravity * account for pressure * use scalar value of face normals --- .../staggered/subcontrolvolumeface.hh | 7 ++ dumux/freeflow/staggered/localresidual.hh | 99 ++++++++++++------- 2 files changed, 72 insertions(+), 34 deletions(-) diff --git a/dumux/discretization/staggered/subcontrolvolumeface.hh b/dumux/discretization/staggered/subcontrolvolumeface.hh index e17c75991c..32d1fc8101 100644 --- a/dumux/discretization/staggered/subcontrolvolumeface.hh +++ b/dumux/discretization/staggered/subcontrolvolumeface.hh @@ -106,6 +106,7 @@ public: localFaceIdx_ = is.indexInInside(); dirIdx_ = geometryHelper.directionIndex(); normalInPosCoordDir_ = unitOuterNormal()[directionIndex()] > 0.0; + outerNormalScalar_ = unitOuterNormal()[directionIndex()]; } /*//! The copy constrcutor @@ -229,6 +230,11 @@ public: return normalInPosCoordDir_; } + Scalar outerNormalScalar() const + { + return outerNormalScalar_; + } + auto pairData(const int idx) const { @@ -258,6 +264,7 @@ private: int localFaceIdx_; int dirIdx_; bool normalInPosCoordDir_; + Scalar outerNormalScalar_; }; diff --git a/dumux/freeflow/staggered/localresidual.hh b/dumux/freeflow/staggered/localresidual.hh index 899ec79f67..35b20e8e0e 100644 --- a/dumux/freeflow/staggered/localresidual.hh +++ b/dumux/freeflow/staggered/localresidual.hh @@ -104,21 +104,11 @@ public: CellCenterPrimaryVariables flux(0.0); - if(scvf.unitOuterNormal()[scvf.directionIndex()] > 0.0) // positive coordinate direction - { - if(velocity > 0.0) - flux[0] = insideVolVars.density(0) * velocity; - else - flux[0] = outsideVolVars.density(0) * velocity; - } - else // negative coordinate direction - { - if(velocity > 0.0) - flux[0] = outsideVolVars.density(0) * velocity; - else - flux[0] = insideVolVars.density(0) * velocity; - } - return flux * scvf.area(); + if(sign(scvf.outerNormalScalar()) == sign(velocity)) + flux[0] = insideVolVars.density() * velocity; + else + flux[0] = outsideVolVars.density() * velocity; + return flux * scvf.area() * sign(scvf.outerNormalScalar()); } CellCenterPrimaryVariables computeSourceForCellCenter(const Element &element, @@ -173,28 +163,40 @@ public: const ElementVolumeVariables& elemVolVars, const GlobalFaceVars& globalFaceVars) { - return FacePrimaryVariables(0.0); + FacePrimaryVariables gravityTerm(0.0); + gravityTerm += this->problem().gravity()[scvf.directionIndex()]; + return gravityTerm; } + /*! + * \brief Returns the complete momentum flux for a face + * \param scvf The sub control volume face + * \param fvGeometry The finite-volume geometry + * \param elemVolVars All volume variables for the element + * \param globalFaceVars The face variables + */ FacePrimaryVariables computeFluxForFace(const SubControlVolumeFace& scvf, const FVElementGeometry& fvGeometry, const ElementVolumeVariables& elemVolVars, const GlobalFaceVars& globalFaceVars) { FacePrimaryVariables flux(0.0); - - flux += computeNormalMomentumFlux(scvf, fvGeometry, elemVolVars, globalFaceVars); - - flux += computeTangetialMomentumFlux(scvf, fvGeometry, elemVolVars, globalFaceVars); - + flux += computeNormalMomentumFlux_(scvf, fvGeometry, elemVolVars, globalFaceVars); + flux += computeTangetialMomentumFlux_(scvf, fvGeometry, elemVolVars, globalFaceVars); + flux += computePressureTerm_(scvf, fvGeometry, elemVolVars, globalFaceVars); return flux; } + +private: /*! - * \brief Return the normal part of the momentum flux + * \brief Returns the normal part of the momentum flux * \param scvf The sub control volume face + * \param fvGeometry The finite-volume geometry + * \param elemVolVars All volume variables for the element + * \param globalFaceVars The face variables */ - FacePrimaryVariables computeNormalMomentumFlux(const SubControlVolumeFace& scvf, + FacePrimaryVariables computeNormalMomentumFlux_(const SubControlVolumeFace& scvf, const FVElementGeometry& fvGeometry, const ElementVolumeVariables& elemVolVars, const GlobalFaceVars& globalFaceVars) @@ -219,16 +221,19 @@ public: normalFlux -= insideVolVars.viscosity() * 2.0 * deltaV/deltaX; // account for the orientation of the face - const Scalar sign = scvf.normalInPosCoordDir() ? -1.0 : 1.0; + const Scalar sgn = -1.0 * sign(scvf.outerNormalScalar()); // std::cout << "normal flux (element: " << fvGeometry.globalFvGeometry().element(scvf.insideScvIdx()).geometry().center() <<") at face: " << scvf.center() << " , " << normalFlux*sign*scvf.area() << std::endl; - return normalFlux * sign * scvf.area(); + return normalFlux * sgn * scvf.area(); } /*! - * \brief Return the tangential part of the momentum flux + * \brief Returns the tangential part of the momentum flux * \param scvf The sub control volume face + * \param fvGeometry The finite-volume geometry + * \param elemVolVars All volume variables for the element + * \param globalFaceVars The face variables */ - auto computeTangetialMomentumFlux(const SubControlVolumeFace& scvf, + FacePrimaryVariables computeTangetialMomentumFlux_(const SubControlVolumeFace& scvf, const FVElementGeometry& fvGeometry, const ElementVolumeVariables& elemVolVars, const GlobalFaceVars& globalFaceVars) @@ -254,7 +259,6 @@ public: } -private: template<class SubFaceData, class VelocityHelper> FacePrimaryVariables computeAdvectivePartOfTangentialMomentumFlux_(const SubControlVolumeFace& scvf, const SubControlVolumeFace& normalFace, @@ -263,12 +267,10 @@ private: VelocityHelper velocity) { const Scalar transportingVelocity = velocity(subFaceData.normalPair.first); - const auto dirIdx = directionIndex(std::move(normalFace.unitOuterNormal())); - const auto insideScvIdx = normalFace.insideScvIdx(); const auto outsideScvIdx = normalFace.outsideScvIdx(); - const bool innerElementIsUpstream = ( sign(normalFace.unitOuterNormal()[dirIdx]) == sign(transportingVelocity) ); + const bool innerElementIsUpstream = ( sign(normalFace.outerNormalScalar()) == sign(transportingVelocity) ); const auto& upVolVars = innerElementIsUpstream ? elemVolVars[insideScvIdx] : elemVolVars[outsideScvIdx]; @@ -288,8 +290,8 @@ private: } } - const int sgn = innerElementIsUpstream ? 1.0 : -1.0; const Scalar momentum = upVolVars.density() * transportedVelocity; + const int sgn = sign(normalFace.outerNormalScalar()); return transportingVelocity * momentum * sgn * normalFace.area() * 0.5; } @@ -339,15 +341,44 @@ private: velocity(outerParallelFaceDofIdx) : this->problem().dirichletVelocityAtPos(subFaceData.virtualOuterParallelFaceDofPos)[scvf.directionIndex()]; - const Scalar parallelDeltaV = normalFace.unitOuterNormal()[normalDirIdx] > 0.0 ? + const Scalar parallelDeltaV = normalFace.normalInPosCoordDir() ? (outerParallelVelocity - innerParallelVelocity) : (innerParallelVelocity - outerParallelVelocity); const Scalar parallelDerivative = parallelDeltaV / subFaceData.parallelDistance; tangentialDiffusiveFlux -= muAvg * parallelDerivative; - return tangentialDiffusiveFlux; + const Scalar sgn = sign(normalFace.outerNormalScalar()); + return tangentialDiffusiveFlux * sgn * normalFace.area() * 0.5; } + + + /*! + * \brief Returns the pressure term + * \param scvf The sub control volume face + * \param fvGeometry The finite-volume geometry + * \param elemVolVars All volume variables for the element + * \param globalFaceVars The face variables + */ + FacePrimaryVariables computePressureTerm_(const SubControlVolumeFace& scvf, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const GlobalFaceVars& globalFaceVars) + { + const auto insideScvIdx = scvf.insideScvIdx(); + const auto& insideVolVars = elemVolVars[insideScvIdx]; + + Scalar result = insideVolVars.pressure() * scvf.area() * -1.0 * sign(scvf.outerNormalScalar()); + + if(scvf.boundary()) + { + const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()]; + result += outsideVolVars.pressure() * scvf.area() * sign(scvf.outerNormalScalar()); + } + + return result; + } + }; } -- GitLab