12#ifndef DUMUX_NAVIERSTOKES_STAGGERED_VELOCITYGRADIENTS_HH
13#define DUMUX_NAVIERSTOKES_STAGGERED_VELOCITYGRADIENTS_HH
25template<
class Scalar,
class Gr
idGeometry,
class BoundaryTypes,
class Indices>
26class StaggeredVelocityGradients
28 using FVElementGeometry =
typename GridGeometry::LocalView;
29 using GridView =
typename GridGeometry::GridView;
30 using Element =
typename GridView::template Codim<0>::Entity;
31 using SubControlVolumeFace =
typename FVElementGeometry::SubControlVolumeFace;
32 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
51 template<
class FaceVariables>
53 const FaceVariables& faceVars)
56 const Scalar velocitySelf = faceVars.velocitySelf();
57 const Scalar velocityOpposite = faceVars.velocityOpposite();
59 return ((velocityOpposite - velocitySelf) / scvf.selfToOppositeDistance()) * scvf.directionSign();
105 template<
class Problem,
class FaceVariables>
107 const Element& element,
108 const FVElementGeometry& fvGeometry,
109 const SubControlVolumeFace& scvf,
110 const FaceVariables& faceVars,
111 const std::optional<BoundaryTypes>& currentScvfBoundaryTypes,
112 const std::optional<BoundaryTypes>& lateralFaceBoundaryTypes,
113 const std::size_t localSubFaceIdx)
115 const auto eIdx = scvf.insideScvIdx();
116 const auto& lateralScvf = fvGeometry.scvf(eIdx, scvf.pairData(localSubFaceIdx).localLateralFaceIdx);
120 const Scalar innerParallelVelocity = faceVars.velocitySelf();
122 const auto outerParallelVelocity = [&]()
124 if (!lateralScvf.boundary())
125 return faceVars.velocityParallel(localSubFaceIdx, 0);
126 else if (lateralFaceBoundaryTypes->isDirichlet(Indices::velocity(scvf.directionIndex())))
129 const auto& lateralBoundaryFacePos = lateralStaggeredFaceCenter_(scvf, localSubFaceIdx);
131 return problem.dirichlet(element, lateralBoundaryFace)[Indices::velocity(scvf.directionIndex())];
133 else if (lateralFaceBoundaryTypes->isBeaversJoseph(Indices::velocity(scvf.directionIndex())))
136 currentScvfBoundaryTypes, lateralFaceBoundaryTypes, localSubFaceIdx);
139 DUNE_THROW(Dune::InvalidStateException,
"Invalid lateral boundary type at " << lateralScvf.center());
145 return (outerParallelVelocity - innerParallelVelocity)
146 / scvf.parallelDofsDistance(localSubFaceIdx, 0) * lateralScvf.directionSign();
180 template<
class Problem,
class FaceVariables>
182 const Element& element,
183 const FVElementGeometry& fvGeometry,
184 const SubControlVolumeFace& scvf,
185 const FaceVariables& faceVars,
186 const std::optional<BoundaryTypes>& currentScvfBoundaryTypes,
187 const std::optional<BoundaryTypes>& lateralFaceBoundaryTypes,
188 const std::size_t localSubFaceIdx)
190 const auto eIdx = scvf.insideScvIdx();
191 const auto& lateralScvf = fvGeometry.scvf(eIdx, scvf.pairData(localSubFaceIdx).localLateralFaceIdx);
194 if (currentScvfBoundaryTypes && currentScvfBoundaryTypes->isDirichlet(Indices::pressureIdx))
201 const Scalar innerLateralVelocity = faceVars.velocityLateralInside(localSubFaceIdx);
202 const Scalar outerLateralVelocity = [&]()
204 if (!scvf.boundary())
205 return faceVars.velocityLateralOutside(localSubFaceIdx);
206 else if (currentScvfBoundaryTypes->isDirichlet(Indices::velocity(lateralScvf.directionIndex())))
209 const auto& lateralBoundaryFacePos = lateralStaggeredFaceCenter_(scvf, localSubFaceIdx);
211 return problem.dirichlet(element, lateralBoundaryFace)[Indices::velocity(lateralScvf.directionIndex())];
213 else if (currentScvfBoundaryTypes->isBeaversJoseph(Indices::velocity(lateralScvf.directionIndex())))
216 currentScvfBoundaryTypes, lateralFaceBoundaryTypes, localSubFaceIdx);
219 DUNE_THROW(Dune::InvalidStateException,
"Invalid lateral boundary types at " << lateralScvf.center());
223 const Scalar lateralDeltaV = scvf.normalInPosCoordDir()
224 ? (outerLateralVelocity - innerLateralVelocity)
225 : (innerLateralVelocity - outerLateralVelocity);
227 return lateralDeltaV / scvf.pairData(localSubFaceIdx).lateralDistance;
250 template<
class Problem,
class FaceVariables>
252 const Element& element,
253 const FVElementGeometry& fvGeometry,
254 const SubControlVolumeFace& scvf,
255 const FaceVariables& faceVars,
256 const std::optional<BoundaryTypes>& currentScvfBoundaryTypes,
257 const std::optional<BoundaryTypes>& lateralFaceBoundaryTypes,
258 const std::size_t localSubFaceIdx)
260 const auto eIdx = scvf.insideScvIdx();
261 const auto& lateralScvf = fvGeometry.scvf(eIdx, scvf.pairData(localSubFaceIdx).localLateralFaceIdx);
262 const Scalar innerLateralVelocity = faceVars.velocityLateralInside(localSubFaceIdx);
264 const auto tangentialVelocityGradient = [&]()
269 static const bool unsymmetrizedGradientForBJ = getParamFromGroup<bool>(problem.paramGroup(),
270 "FreeFlow.EnableUnsymmetrizedVelocityGradientForBeaversJoseph",
false);
272 if (unsymmetrizedGradientForBJ)
275 if (lateralScvf.boundary())
277 if (lateralFaceBoundaryTypes->isDirichlet(Indices::pressureIdx) ||
278 lateralFaceBoundaryTypes->isBeaversJoseph(Indices::velocity(scvf.directionIndex())))
282 return velocityGradIJ(problem, element, fvGeometry, scvf, faceVars, currentScvfBoundaryTypes, lateralFaceBoundaryTypes, localSubFaceIdx);
285 return problem.beaversJosephVelocity(element,
286 fvGeometry.scv(scvf.insideScvIdx()),
289 innerLateralVelocity,
290 tangentialVelocityGradient);
310 template<
class Problem,
class FaceVariables>
312 const Element& element,
313 const FVElementGeometry& fvGeometry,
314 const SubControlVolumeFace& scvf,
315 const FaceVariables& faceVars,
316 const std::optional<BoundaryTypes>& currentScvfBoundaryTypes,
317 const std::optional<BoundaryTypes>& lateralFaceBoundaryTypes,
318 const std::size_t localSubFaceIdx)
320 const auto eIdx = scvf.insideScvIdx();
321 const auto& lateralScvf = fvGeometry.scvf(eIdx, scvf.pairData(localSubFaceIdx).localLateralFaceIdx);
322 const Scalar innerParallelVelocity = faceVars.velocitySelf();
324 const auto tangentialVelocityGradient = [&]()
329 static const bool unsymmetrizedGradientForBJ = getParamFromGroup<bool>(problem.paramGroup(),
330 "FreeFlow.EnableUnsymmetrizedVelocityGradientForBeaversJoseph",
false);
332 if (unsymmetrizedGradientForBJ)
337 if (currentScvfBoundaryTypes->isDirichlet(Indices::pressureIdx) ||
338 currentScvfBoundaryTypes->isBeaversJoseph(Indices::velocity(lateralScvf.directionIndex())))
342 return velocityGradJI(problem, element, fvGeometry, scvf, faceVars, currentScvfBoundaryTypes, lateralFaceBoundaryTypes, localSubFaceIdx);
345 return problem.beaversJosephVelocity(element,
346 fvGeometry.scv(scvf.insideScvIdx()),
349 innerParallelVelocity,
350 tangentialVelocityGradient);
369 static const GlobalPosition& lateralStaggeredFaceCenter_(
const SubControlVolumeFace& scvf,
const int localSubFaceIdx)
371 return scvf.pairData(localSubFaceIdx).lateralStaggeredFaceCenter;
static Scalar velocityGradIJ(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const FaceVariables &faceVars, const std::optional< BoundaryTypes > ¤tScvfBoundaryTypes, const std::optional< BoundaryTypes > &lateralFaceBoundaryTypes, const std::size_t localSubFaceIdx)
Returns the velocity gradient perpendicular to the orientation of our current scvf.
Definition: staggered/velocitygradients.hh:106
static Scalar beaversJosephVelocityAtLateralScvf(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const FaceVariables &faceVars, const std::optional< BoundaryTypes > ¤tScvfBoundaryTypes, const std::optional< BoundaryTypes > &lateralFaceBoundaryTypes, const std::size_t localSubFaceIdx)
Returns the Beavers-Jospeh slip velocity for a lateral scvf which lies on the boundary.
Definition: staggered/velocitygradients.hh:311
static Scalar velocityGradII(const SubControlVolumeFace &scvf, const FaceVariables &faceVars)
Returns the in-axis velocity gradient.
Definition: staggered/velocitygradients.hh:52
static auto velocityGradJI(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolumeFace &scvf, const ElemVolVars &elemVolVars)
Returns the velocity gradient in line with our current scvf.
Definition: momentum/velocitygradients.hh:222
static Scalar velocityGradJI(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const FaceVariables &faceVars, const std::optional< BoundaryTypes > ¤tScvfBoundaryTypes, const std::optional< BoundaryTypes > &lateralFaceBoundaryTypes, const std::size_t localSubFaceIdx)
Returns the velocity gradient in line with our current scvf.
Definition: staggered/velocitygradients.hh:181
static Scalar beaversJosephVelocityAtCurrentScvf(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const FaceVariables &faceVars, const std::optional< BoundaryTypes > ¤tScvfBoundaryTypes, const std::optional< BoundaryTypes > &lateralFaceBoundaryTypes, const std::size_t localSubFaceIdx)
Returns the Beavers-Jospeh slip velocity for a scvf which lies on the boundary itself.
Definition: staggered/velocitygradients.hh:251
static auto velocityGradIJ(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolumeFace &scvf, const ElemVolVars &elemVolVars)
Returns the velocity gradient perpendicular to the orientation of our current scvf.
Definition: momentum/velocitygradients.hh:181
Some exceptions thrown in DuMux
SubControlVolumeFace makeStaggeredBoundaryFace(const SubControlVolumeFace &scvf, const typename SubControlVolumeFace::GlobalPosition &newCenter)
Helper function to turn a given cell scvface into a fake boundary face.
Definition: discretization/staggered/freeflow/subcontrolvolumeface.hh:62
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.