24#ifndef DUMUX_RANS_PROBLEM_HH
25#define DUMUX_RANS_PROBLEM_HH
27#include <dune/common/fmatrix.hh>
40template<
class TypeTag, TurbulenceModel turbulenceModel>
44template<
class TypeTag>
55template<
class TypeTag>
64 using FVElementGeometry =
typename GridGeometry::LocalView;
65 using GridView =
typename GridGeometry::GridView;
66 using Element =
typename GridView::template Codim<0>::Entity;
67 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
68 using SubControlVolumeFace =
typename FVElementGeometry::SubControlVolumeFace;
71 using PrimaryVariables =
typename VolumeVariables::PrimaryVariables;
76 using GlobalPosition =
typename SubControlVolumeFace::GlobalPosition;
78 static constexpr auto dim = GridView::dimension;
79 using DimVector = GlobalPosition;
80 using DimMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
88 RANSProblemBase(std::shared_ptr<const GridGeometry> gridGeometry,
const std::string& paramGroup =
"")
89 : ParentType(gridGeometry, paramGroup)
101 std::cout <<
"Update static wall properties. ";
106 wallDistance_.resize(this->gridGeometry().elementMapper().size(), std::numeric_limits<Scalar>::max());
107 neighborIdx_.resize(this->gridGeometry().elementMapper().size());
108 cellCenter_.resize(this->gridGeometry().elementMapper().size(), GlobalPosition(0.0));
109 velocity_.resize(this->gridGeometry().elementMapper().size(), DimVector(0.0));
110 velocityMaximum_.resize(this->gridGeometry().elementMapper().size(), DimVector(0.0));
111 velocityGradients_.resize(this->gridGeometry().elementMapper().size(), DimMatrix(0.0));
114 flowNormalAxis_.resize(this->gridGeometry().elementMapper().size(), 0);
115 wallNormalAxis_.resize(this->gridGeometry().elementMapper().size(), 1);
120 std::vector<unsigned int> wallElements;
121 std::vector<GlobalPosition> wallPositions;
122 std::vector<unsigned int> wallNormalAxisTemp;
124 const auto gridView = this->gridGeometry().gridView();
125 auto fvGeometry =
localView(this->gridGeometry());
127 for (
const auto& element : elements(gridView))
129 fvGeometry.bindElement(element);
130 for (
const auto& scvf : scvfs(fvGeometry))
133 if (!scvf.boundary())
138 wallElements.push_back(this->gridGeometry().elementMapper().index(element));
139 wallPositions.push_back(scvf.center());
140 wallNormalAxisTemp.push_back(scvf.directionIndex());
144 std::cout <<
"NumWallIntersections=" << wallPositions.size() << std::endl;
145 if (wallPositions.size() == 0)
146 DUNE_THROW(Dune::InvalidStateException,
147 "No wall intersections have been found. Make sure that the isOnWall(globalPos) is working properly.");
151 for (
const auto& element : elements(gridView))
153 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
154 cellCenter_[elementIdx] = element.geometry().center();
155 for (
unsigned int i = 0; i < wallPositions.size(); ++i)
157 static const int problemWallNormalAxis
158 = getParamFromGroup<int>(this->paramGroup(),
"RANS.WallNormalAxis", -1);
159 int searchAxis = problemWallNormalAxis;
162 if (problemWallNormalAxis < 0 || problemWallNormalAxis >= dim)
164 searchAxis = wallNormalAxisTemp[i];
167 GlobalPosition global = element.geometry().center();
168 global -= wallPositions[i];
171 && abs(global[searchAxis]) < global.two_norm() + 1e-8
172 && abs(global[searchAxis]) > global.two_norm() - 1e-8)
183 for (
const auto& element : elements(gridView))
185 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
186 for (
unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
192 for (
const auto& intersection :
intersections(gridView, element))
194 if (intersection.boundary())
197 unsigned int neighborIdx = this->gridGeometry().elementMapper().index(intersection.outside());
198 for (
unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
230 std::cout <<
"Update dynamic wall properties." << std::endl;
232 DUNE_THROW(Dune::InvalidStateException,
233 "You have to call updateStaticWallProperties() once before you call updateDynamicWallProperties().");
235 static const int flowNormalAxis
236 = getParamFromGroup<int>(this->paramGroup(),
"RANS.FlowNormalAxis", -1);
239 velocityMaximum_.assign(this->gridGeometry().elementMapper().size(), DimVector(1e-16));
240 velocityMinimum_.assign(this->gridGeometry().elementMapper().size(), DimVector(std::numeric_limits<Scalar>::max()));
243 for (
const auto& element : elements(this->gridGeometry().gridView()))
245 auto fvGeometry =
localView(this->gridGeometry());
246 fvGeometry.bindElement(element);
247 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
250 DimVector velocityTemp(0.0);
251 for (
auto&& scvf : scvfs(fvGeometry))
253 const int dofIdxFace = scvf.dofIndex();
254 const auto numericalSolutionFace = curSol[GridGeometry::faceIdx()][dofIdxFace][Indices::velocity(scvf.directionIndex())];
255 velocityTemp[scvf.directionIndex()] += numericalSolutionFace;
257 for (
unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
258 velocity_[elementIdx][dimIdx] = velocityTemp[dimIdx] * 0.5;
262 for (
const auto& element : elements(this->gridGeometry().gridView()))
264 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
267 Scalar maxVelocity = 0.0;
268 for (
unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
270 for (
unsigned int velIdx = 0; velIdx < dim; ++velIdx)
291 if (0 <= flowNormalAxis && flowNormalAxis < dim)
295 else if (abs(maxVelocity) < abs(
velocity_[elementIdx][dimIdx]))
297 maxVelocity = abs(
velocity_[elementIdx][dimIdx]);
302 auto fvGeometry =
localView(this->gridGeometry());
303 fvGeometry.bindElement(element);
304 for (
auto&& scvf : scvfs(fvGeometry))
307 unsigned int scvfNormDim = scvf.directionIndex();
310 for (
unsigned int velIdx = 0; velIdx < dim; ++velIdx)
312 if (!asImp_().boundaryTypes(element, scvf).isDirichlet(Indices::velocity(velIdx)))
315 Scalar dirichletVelocity = asImp_().dirichlet(element, scvf)[Indices::velocity(velIdx)];
317 unsigned int neighborIdx =
neighborIdx_[elementIdx][scvfNormDim][0];
318 if (scvf.center()[scvfNormDim] <
cellCenter_[elementIdx][scvfNormDim])
322 = (
velocity_[neighborIdx][velIdx] - dirichletVelocity)
323 / (
cellCenter_[neighborIdx][scvfNormDim] - scvf.center()[scvfNormDim]);
328 std::vector<int> bjsNumFaces(dim, 0);
329 std::vector<unsigned int> bjsNeighbor(dim, 0);
330 DimVector bjsVelocityAverage(0.0);
331 DimVector normalNormCoordinate(0.0);
332 unsigned int velIdx = Indices::velocity(scvfNormDim);
333 const int numSubFaces = scvf.pairData().size();
334 for(
int localSubFaceIdx = 0; localSubFaceIdx < numSubFaces; ++localSubFaceIdx)
336 const auto& lateralFace = fvGeometry.scvf(scvf.insideScvIdx(), scvf.pairData()[localSubFaceIdx].localLateralFaceIdx);
339 unsigned int normalNormDim = lateralFace.directionIndex();
340 if (lateralFace.boundary() && (asImp_().boundaryTypes(element, lateralFace).isBJS(Indices::velocity(velIdx))))
342 unsigned int neighborIdx =
neighborIdx_[elementIdx][normalNormDim][0];
343 if (lateralFace.center()[normalNormDim] <
cellCenter_[elementIdx][normalNormDim])
344 neighborIdx =
neighborIdx_[elementIdx][normalNormDim][1];
346 const SubControlVolume& scv = fvGeometry.scv(scvf.insideScvIdx());
348 if (bjsNumFaces[normalNormDim] > 0 && neighborIdx != bjsNeighbor[normalNormDim])
349 DUNE_THROW(Dune::InvalidStateException,
"Two different neighborIdx should not occur");
350 bjsNeighbor[normalNormDim] = neighborIdx;
351 normalNormCoordinate[normalNormDim] = lateralFace.center()[normalNormDim];
352 bjsNumFaces[normalNormDim]++;
355 for (
unsigned dirIdx = 0; dirIdx < dim; ++dirIdx)
357 if (bjsNumFaces[dirIdx] == 0)
360 unsigned int neighborIdx = bjsNeighbor[dirIdx];
361 bjsVelocityAverage[dirIdx] /= bjsNumFaces[dirIdx];
364 = (
velocity_[neighborIdx][velIdx] - bjsVelocityAverage[dirIdx])
365 / (
cellCenter_[neighborIdx][dirIdx] - normalNormCoordinate[dirIdx]);
372 for (
const auto& element : elements(this->gridGeometry().gridView()))
374 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
376 Dune::FieldMatrix<Scalar, GridView::dimension, GridView::dimension> stressTensor(0.0);
377 for (
unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
379 for (
unsigned int velIdx = 0; velIdx < dim; ++velIdx)
386 for (
unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
388 for (
unsigned int velIdx = 0; velIdx < dim; ++velIdx)
394 Dune::FieldMatrix<Scalar, GridView::dimension, GridView::dimension> vorticityTensor(0.0);
395 for (
unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
397 for (
unsigned int velIdx = 0; velIdx < dim; ++velIdx)
399 vorticityTensor[dimIdx][velIdx] = 0.5 *
velocityGradients_[elementIdx][dimIdx][velIdx]
404 for (
unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
406 for (
unsigned int velIdx = 0; velIdx < dim; ++velIdx)
412 auto fvGeometry =
localView(this->gridGeometry());
413 fvGeometry.bindElement(element);
414 for (
auto&& scv : scvs(fvGeometry))
416 const int dofIdx = scv.dofIndex();
419 const auto& cellCenterPriVars = curSol[GridGeometry::cellCenterIdx()][dofIdx];
420 PrimaryVariables priVars = makePriVarsFromCellCenterPriVars<PrimaryVariables>(cellCenterPriVars);
421 auto elemSol = elementSolution<typename GridGeometry::LocalView>(std::move(priVars));
423 VolumeVariables volVars;
424 volVars.update(elemSol, asImp_(), element, scv);
438 const SubControlVolumeFace& scvf,
439 const int& eqIdx)
const
445 template<
class ElementVolumeVariables,
class ElementFaceVariables>
447 const FVElementGeometry& fvGeometry,
448 const ElementVolumeVariables& elemVolVars,
449 const ElementFaceVariables& elemFaceVars,
450 const SubControlVolumeFace& scvf,
451 const SubControlVolumeFace& lateralBoundaryFace)
const
452 {
return FacePrimaryVariables(0.0); }
457 template<
class ElementVolumeVariables,
class ElementFaceVariables>
459 const FVElementGeometry& fvGeometry,
460 const ElementVolumeVariables& elemVolVars,
461 const ElementFaceVariables& elemFaceVars,
462 const SubControlVolumeFace& scvf)
const
463 {
return CellCenterPrimaryVariables(0.0); }
470 bool isOnWall(
const SubControlVolumeFace& scvf)
const
472 return asImp_().isOnWallAtPos(scvf.center());
483 DUNE_THROW(Dune::InvalidStateException,
484 "The problem does not provide an isOnWall() method.");
516 = getParamFromGroup<Scalar>(this->paramGroup(),
"RANS.TurbulentPrandtlNumber", 1.0);
527 = getParamFromGroup<Scalar>(this->paramGroup(),
"RANS.TurbulentSchmidtNumber", 1.0);
535 std::vector<std::array<std::array<unsigned int, 2>, dim>>
neighborIdx_;
550 Implementation &asImp_()
551 {
return *
static_cast<Implementation *
>(
this); }
554 const Implementation &asImp_()
const
555 {
return *
static_cast<const Implementation *
>(
this); }
Base class for all staggered fv problems.
Free function to get the local view of a grid cache object.
The available discretization methods in Dumux.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
Dune::IteratorRange< typename MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper >::Intersections::const_iterator > intersections(const MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper > &glue)
Range generator to iterate with range-based for loops over all intersections as follows: for (const a...
Definition: glue.hh:62
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:149
Navier-Stokes problem base class.
Definition: dumux/freeflow/navierstokes/problem.hh:63
const Scalar bjsVelocity(const Element &element, const SubControlVolume &scv, const SubControlVolumeFace &faceOnPorousBoundary, const Scalar velocitySelf) const
helper function to evaluate the slip velocity on the boundary when the Beavers-Joseph-Saffman conditi...
Definition: dumux/freeflow/navierstokes/problem.hh:229
forward declare
Definition: dumux/freeflow/rans/problem.hh:41
Reynolds-Averaged Navier-Stokes problem base class.
Definition: dumux/freeflow/rans/problem.hh:57
std::vector< std::array< std::array< unsigned int, 2 >, dim > > neighborIdx_
Definition: dumux/freeflow/rans/problem.hh:535
void updateDynamicWallProperties(const SolutionVector &curSol)
Update the dynamic (solution dependent) relations to the walls.
Definition: dumux/freeflow/rans/problem.hh:225
bool isOnWallAtPos(const GlobalPosition &globalPos) const
Returns whether a given point is on a wall.
Definition: dumux/freeflow/rans/problem.hh:480
std::vector< DimVector > velocityMinimum_
Definition: dumux/freeflow/rans/problem.hh:539
void updateStaticWallProperties()
Update the static (solution independent) relations to the walls.
Definition: dumux/freeflow/rans/problem.hh:98
FacePrimaryVariables wallFunction(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const SubControlVolumeFace &scvf, const SubControlVolumeFace &lateralBoundaryFace) const
Returns an additional wall function momentum flux.
Definition: dumux/freeflow/rans/problem.hh:446
std::vector< DimMatrix > velocityGradients_
Definition: dumux/freeflow/rans/problem.hh:540
const Scalar betaOmega() const
Returns the constant.
Definition: dumux/freeflow/rans/problem.hh:504
std::vector< GlobalPosition > cellCenter_
Definition: dumux/freeflow/rans/problem.hh:536
std::vector< Scalar > vorticityTensorScalarProduct_
Definition: dumux/freeflow/rans/problem.hh:542
std::vector< DimVector > velocityMaximum_
Definition: dumux/freeflow/rans/problem.hh:538
Scalar turbulentSchmidtNumber() const
Return the turbulent Schmidt number which is used to convert the eddy viscosity to an eddy diffusivi...
Definition: dumux/freeflow/rans/problem.hh:524
CellCenterPrimaryVariables wallFunction(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const SubControlVolumeFace &scvf) const
Returns an additional wall function flux for cell-centered quantities.
Definition: dumux/freeflow/rans/problem.hh:458
std::vector< Scalar > sandGrainRoughness_
Definition: dumux/freeflow/rans/problem.hh:546
std::vector< Scalar > kinematicViscosity_
Definition: dumux/freeflow/rans/problem.hh:545
Scalar turbulentPrandtlNumber() const
Return the turbulent Prandtl number which is used to convert the eddy viscosity to an eddy thermal c...
Definition: dumux/freeflow/rans/problem.hh:513
std::vector< unsigned int > wallNormalAxis_
Definition: dumux/freeflow/rans/problem.hh:543
std::vector< Scalar > stressTensorScalarProduct_
Definition: dumux/freeflow/rans/problem.hh:541
std::vector< Scalar > wallDistance_
Definition: dumux/freeflow/rans/problem.hh:534
RANSProblemBase(std::shared_ptr< const GridGeometry > gridGeometry, const std::string ¶mGroup="")
The constructor.
Definition: dumux/freeflow/rans/problem.hh:88
std::vector< DimVector > velocity_
Definition: dumux/freeflow/rans/problem.hh:537
bool calledUpdateStaticWallProperties
Definition: dumux/freeflow/rans/problem.hh:532
Scalar sandGrainRoughnessAtPos(const GlobalPosition &globalPos) const
Returns the sand-grain roughness at a given position.
Definition: dumux/freeflow/rans/problem.hh:492
bool useWallFunction(const Element &element, const SubControlVolumeFace &scvf, const int &eqIdx) const
Returns whether a wall function should be used at a given face.
Definition: dumux/freeflow/rans/problem.hh:437
const Scalar karmanConstant() const
Returns the Karman constant.
Definition: dumux/freeflow/rans/problem.hh:500
std::vector< unsigned int > wallElementIdx_
Definition: dumux/freeflow/rans/problem.hh:533
std::vector< unsigned int > flowNormalAxis_
Definition: dumux/freeflow/rans/problem.hh:544
bool isOnWall(const SubControlVolumeFace &scvf) const
Returns whether a given sub control volume face is on a wall.
Definition: dumux/freeflow/rans/problem.hh:470
Declares all properties used in Dumux.
Adaption of the fully implicit scheme to the tracer transport model.
The local element solution class for staggered methods.