24#ifndef DUMUX_ZEROEQ_PROBLEM_HH
25#define DUMUX_ZEROEQ_PROBLEM_HH
48template<
class TypeTag>
54 using Grid =
typename GridView::Grid;
59 using SubControlVolumeFace =
typename FVElementGeometry::SubControlVolumeFace;
67 dim = Grid::dimension,
69 using DimVector = Dune::FieldVector<Scalar, dim>;
70 using DimMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
78 RANSProblemImpl(std::shared_ptr<const GridGeometry> gridGeometry,
const std::string& paramGroup =
"")
79 : ParentType(gridGeometry, paramGroup)
81 eddyViscosityModel_ = getParamFromGroup<std::string>(paramGroup,
"RANS.EddyViscosityModel",
"vanDriest");
89 ParentType::updateStaticWallProperties();
92 kinematicEddyViscosity_.resize(this->gridGeometry().elementMapper().size(), 0.0);
93 additionalRoughnessLength_.resize(this->gridGeometry().elementMapper().size(), 0.0);
105 ParentType::updateDynamicWallProperties(curSol);
108 bool printedRangeWarning =
false;
109 for (
const auto& element : elements(this->gridGeometry().gridView()))
111 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
113 auto fvGeometry =
localView(this->gridGeometry());
114 fvGeometry.bindElement(element);
115 for (
auto&& scv : scvs(fvGeometry))
120 const int dofIdx = scv.dofIndex();
123 const auto& cellCenterPriVars = curSol[GridGeometry::cellCenterIdx()][dofIdx];
124 PrimaryVariables priVars = makePriVarsFromCellCenterPriVars<PrimaryVariables>(cellCenterPriVars);
125 auto elemSol = elementSolution<typename GridGeometry::LocalView>(std::move(priVars));
127 VolumeVariables volVars;
128 volVars.update(elemSol, asImp_(), element, scv);
130 Scalar ksPlus = this->sandGrainRoughness_[elementIdx] * volVars.uStar() / volVars.kinematicViscosity();
131 if (ksPlus > 0 && eddyViscosityModel_.compare(
"baldwinLomax") == 0)
133 DUNE_THROW(Dune::NotImplemented,
"Roughness is not implemented for the Baldwin-Lomax model.");
137 std::cout <<
"info: equivalent sand grain roughness ks+=" << ksPlus <<
" at " << this->cellCenter_[this->wallElementIdx_[elementIdx]]
138 <<
" is not in the valid range (ksPlus < 2000),"
139 <<
" for high ksPlus values the roughness function reaches a turning point."<< std::endl;
140 DUNE_THROW(Dune::InvalidStateException,
"Unphysical roughness behavior.");
142 else if (ksPlus > 0.0 && ksPlus < 4.535 && !printedRangeWarning)
144 Dune::dinfo <<
"info: equivalent sand grain roughness ks+=" << ksPlus <<
" at " << this->cellCenter_[this->wallElementIdx_[elementIdx]]
145 <<
" is not in the valid range (ksPlus > 4.535) and now set to 0.0"<< std::endl;
147 printedRangeWarning =
true;
149 additionalRoughnessLength_[elementIdx] = 0.9 / (volVars.uStar() / volVars.kinematicViscosity())
150 * (sqrt(ksPlus) - ksPlus * exp(-ksPlus / 6.0));
155 if (eddyViscosityModel_.compare(
"baldwinLomax") == 0)
156 updateBaldwinLomaxProperties();
164 std::vector<Scalar> kinematicEddyViscosityInner(this->gridGeometry().elementMapper().size(), 0.0);
165 std::vector<Scalar> kinematicEddyViscosityOuter(this->gridGeometry().elementMapper().size(), 0.0);
166 std::vector<Scalar> kinematicEddyViscosityDifference(this->gridGeometry().elementMapper().size(), 0.0);
167 std::vector<Scalar> switchingPosition(this->gridGeometry().elementMapper().size(), std::numeric_limits<Scalar>::max());
174 const Scalar aPlus = 26.0;
175 const Scalar k = 0.0168;
176 const Scalar cCP = 1.6;
177 const Scalar cWake = 0.25;
178 const Scalar cKleb = 0.3;
180 std::vector<Scalar> storedFMax;
181 std::vector<Scalar> storedYFMax;
182 storedFMax.resize(this->gridGeometry().elementMapper().size(), 0.0);
183 storedYFMax.resize(this->gridGeometry().elementMapper().size(), 0.0);
186 for (
const auto& element : elements(this->gridGeometry().gridView()))
188 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
189 unsigned int wallElementIdx = this->wallElementIdx_[elementIdx];
190 Scalar wallDistance = this->wallDistance_[elementIdx] + additionalRoughnessLength_[elementIdx];
191 unsigned int flowNormalAxis = this->flowNormalAxis_[elementIdx];
192 unsigned int wallNormalAxis = this->wallNormalAxis_[elementIdx];
194 Scalar omegaAbs = abs(this->velocityGradients_[elementIdx][flowNormalAxis][wallNormalAxis]
195 - this->velocityGradients_[elementIdx][wallNormalAxis][flowNormalAxis]);
196 Scalar uStar = sqrt(this->kinematicViscosity_[wallElementIdx]
197 * abs(this->velocityGradients_[wallElementIdx][flowNormalAxis][wallNormalAxis]));
198 Scalar yPlus = wallDistance * uStar / this->kinematicViscosity_[elementIdx];
199 Scalar mixingLength = this->karmanConstant() * wallDistance * (1.0 - exp(-yPlus / aPlus));
200 kinematicEddyViscosityInner[elementIdx] = mixingLength * mixingLength * omegaAbs;
202 Scalar f = wallDistance * omegaAbs * (1.0 - exp(-yPlus / aPlus));
203 if (f > storedFMax[wallElementIdx])
205 storedFMax[wallElementIdx] = f;
206 storedYFMax[wallElementIdx] = wallDistance;
211 for (
const auto& element : elements(this->gridGeometry().gridView()))
213 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
214 unsigned int wallElementIdx = this->wallElementIdx_[elementIdx];
215 Scalar wallDistance = this->wallDistance_[elementIdx] + additionalRoughnessLength_[elementIdx];
217 Scalar maxVelocityNorm = 0.0;
218 Scalar minVelocityNorm = 0.0;
219 for (
unsigned dimIdx = 0; dimIdx < dim; ++dimIdx)
221 maxVelocityNorm += this->velocityMaximum_[wallElementIdx][dimIdx]
222 * this->velocityMaximum_[wallElementIdx][dimIdx];
223 minVelocityNorm += this->velocityMinimum_[wallElementIdx][dimIdx]
224 * this->velocityMinimum_[wallElementIdx][dimIdx];
226 Scalar deltaU = sqrt(maxVelocityNorm) - sqrt(minVelocityNorm);
227 Scalar yFMax = storedYFMax[wallElementIdx];
228 Scalar fMax = storedFMax[wallElementIdx];
229 Scalar fWake = min(yFMax * fMax, cWake * yFMax * deltaU * deltaU / fMax);
230 Scalar fKleb = 1.0 / (1.0 + 5.5 * pow(cKleb * wallDistance / yFMax, 6.0));
231 kinematicEddyViscosityOuter[elementIdx] = k * cCP * fWake * fKleb;
233 kinematicEddyViscosityDifference[elementIdx]
234 = kinematicEddyViscosityInner[elementIdx] - kinematicEddyViscosityOuter[elementIdx];
238 for (
const auto& element : elements(this->gridGeometry().gridView()))
240 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
241 unsigned int wallElementIdx = this->wallElementIdx_[elementIdx];
242 Scalar wallDistance = this->wallDistance_[elementIdx] + additionalRoughnessLength_[elementIdx];
245 Scalar check = kinematicEddyViscosityDifference[wallElementIdx] * kinematicEddyViscosityDifference[elementIdx];
247 && switchingPosition[wallElementIdx] > wallDistance)
249 switchingPosition[wallElementIdx] = wallDistance;
254 for (
const auto& element : elements(this->gridGeometry().gridView()))
256 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
257 unsigned int wallElementIdx = this->wallElementIdx_[elementIdx];
258 Scalar wallDistance = this->wallDistance_[elementIdx] + additionalRoughnessLength_[elementIdx];
260 kinematicEddyViscosity_[elementIdx] = kinematicEddyViscosityInner[elementIdx];
261 if (wallDistance >= switchingPosition[wallElementIdx])
263 kinematicEddyViscosity_[elementIdx] = kinematicEddyViscosityOuter[elementIdx];
275 Implementation &asImp_()
276 {
return *
static_cast<Implementation *
>(
this); }
279 const Implementation &asImp_()
const
280 {
return *
static_cast<const Implementation *
>(
this); }
Free function to get the local view of a grid cache object.
The available discretization methods in Dumux.
The available free flow turbulence models in Dumux.
Base class for all staggered fv problems.
TurbulenceModel
The available free flow turbulence models in Dumux.
Definition: turbulencemodel.hh:37
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
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
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< Scalar > additionalRoughnessLength_
Definition: dumux/freeflow/rans/zeroeq/problem.hh:271
RANSProblemImpl(std::shared_ptr< const GridGeometry > gridGeometry, const std::string ¶mGroup="")
The constructor.
Definition: dumux/freeflow/rans/zeroeq/problem.hh:78
std::string eddyViscosityModel_
Definition: dumux/freeflow/rans/zeroeq/problem.hh:269
void updateStaticWallProperties()
Correct size of the static (solution independent) wall variables.
Definition: dumux/freeflow/rans/zeroeq/problem.hh:87
std::vector< Scalar > kinematicEddyViscosity_
Definition: dumux/freeflow/rans/zeroeq/problem.hh:270
void updateDynamicWallProperties(const SolutionVector &curSol)
Update the dynamic (solution dependent) relations to the walls.
Definition: dumux/freeflow/rans/zeroeq/problem.hh:103
void updateBaldwinLomaxProperties()
Update the relations and coefficients for the Baldwin-Lomax turbulence model.
Definition: dumux/freeflow/rans/zeroeq/problem.hh:162
The local element solution class for staggered methods.
Declares all properties used in Dumux.
Adaption of the fully implicit scheme to the tracer transport model.