12#ifndef DUMUX_STAGGERED_NAVIERSTOKES_LOCAL_RESIDUAL_HH
13#define DUMUX_STAGGERED_NAVIERSTOKES_LOCAL_RESIDUAL_HH
17#include <dune/common/hybridutilities.hh>
29static constexpr bool isRotationalExtrusion =
false;
31template<
int radialAxis>
41template<
class TypeTag,
class DiscretizationMethod>
44template<
class TypeTag>
53 using GridVolumeVariables =
typename GridVariables::GridVolumeVariables;
54 using ElementVolumeVariables =
typename GridVolumeVariables::LocalView;
55 using VolumeVariables =
typename GridVolumeVariables::VolumeVariables;
57 using GridFluxVariablesCache =
typename GridVariables::GridFluxVariablesCache;
58 using ElementFluxVariablesCache =
typename GridFluxVariablesCache::LocalView;
60 using GridFaceVariables =
typename GridVariables::GridFaceVariables;
61 using ElementFaceVariables =
typename GridFaceVariables::LocalView;
67 using FVElementGeometry =
typename GridGeometry::LocalView;
68 using GridView =
typename GridGeometry::GridView;
69 using Element =
typename GridView::template Codim<0>::Entity;
70 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
71 using SubControlVolumeFace =
typename FVElementGeometry::SubControlVolumeFace;
81 using CellCenterResidual = CellCenterPrimaryVariables;
82 using FaceResidual = FacePrimaryVariables;
90 static constexpr auto cellCenterOffset = ModelTraits::numEq() - CellCenterPrimaryVariables::dimension;
91 static_assert(
cellCenterOffset == ModelTraits::dim(),
"cellCenterOffset must equal dim for staggered NavierStokes");
94 using ParentType::ParentType;
98 const Element &element,
99 const FVElementGeometry& fvGeometry,
100 const ElementVolumeVariables& elemVolVars,
101 const ElementFaceVariables& elemFaceVars,
102 const SubControlVolumeFace &scvf,
103 const ElementFluxVariablesCache& elemFluxVarsCache)
const
105 FluxVariables fluxVars;
106 CellCenterPrimaryVariables flux = fluxVars.computeMassFlux(
problem, element, fvGeometry, elemVolVars,
107 elemFaceVars, scvf, elemFluxVarsCache[scvf]);
109 EnergyLocalResidual::heatFlux(flux,
problem, element, fvGeometry, elemVolVars, elemFaceVars, scvf);
116 const Element &element,
117 const FVElementGeometry& fvGeometry,
118 const ElementVolumeVariables& elemVolVars,
119 const ElementFaceVariables& elemFaceVars,
120 const SubControlVolume &scv)
const
122 CellCenterPrimaryVariables result(0.0);
125 const auto sourceValues =
problem.source(element, fvGeometry, elemVolVars, elemFaceVars, scv);
128 for (
int i = 0; i < result.size(); ++i)
137 const SubControlVolume& scv,
138 const VolumeVariables& volVars)
const
140 CellCenterPrimaryVariables storage;
141 storage[Indices::conti0EqIdx - ModelTraits::dim()] = volVars.density();
143 EnergyLocalResidual::fluidPhaseStorage(storage, volVars);
150 const SubControlVolumeFace& scvf,
151 const VolumeVariables& volVars,
152 const ElementFaceVariables& elemFaceVars)
const
154 FacePrimaryVariables storage(0.0);
155 const Scalar velocity = elemFaceVars[scvf].velocitySelf();
156 storage[0] = volVars.density() * velocity;
162 const Element& element,
163 const FVElementGeometry& fvGeometry,
164 const SubControlVolumeFace& scvf,
165 const ElementVolumeVariables& elemVolVars,
166 const ElementFaceVariables& elemFaceVars)
const
168 FacePrimaryVariables source(0.0);
169 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
170 source +=
problem.gravity()[scvf.directionIndex()] * insideVolVars.density();
171 source +=
problem.source(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[Indices::velocity(scvf.directionIndex())];
176 if constexpr (ModelTraits::dim() == 2 && Impl::isRotationalExtrusion<Extrusion>)
178 if (scvf.directionIndex() == Extrusion::radialAxis)
181 const auto r = scvf.center()[scvf.directionIndex()];
182 source -= -2.0*insideVolVars.effectiveViscosity() * elemFaceVars[scvf].velocitySelf() / (r*r);
187 const Scalar pressure =
188 normalizePressure ? insideVolVars.pressure() -
problem.initial(scvf)[Indices::pressureIdx]
189 : insideVolVars.pressure();
191 source += pressure/r;
200 const Element& element,
201 const SubControlVolumeFace& scvf,
202 const FVElementGeometry& fvGeometry,
203 const ElementVolumeVariables& elemVolVars,
204 const ElementFaceVariables& elemFaceVars,
205 const ElementFluxVariablesCache& elemFluxVarsCache)
const
207 FluxVariables fluxVars;
208 return fluxVars.computeMomentumFlux(
problem, element, scvf, fvGeometry, elemVolVars, elemFaceVars, elemFluxVarsCache.gridFluxVarsCache());
215 const Element& element,
216 const FVElementGeometry& fvGeometry,
217 const SubControlVolumeFace& scvf,
218 const ElementVolumeVariables& elemVolVars,
219 const ElementFaceVariables& elemFaceVars,
220 const ElementBoundaryTypes& elemBcTypes,
221 const ElementFluxVariablesCache& elemFluxVarsCache)
const
223 CellCenterResidual result(0.0);
227 const auto bcTypes =
problem.boundaryTypes(element, scvf);
230 if (bcTypes.isSymmetry())
237 static constexpr auto numEqCellCenter = CellCenterResidual::dimension;
238 if (bcTypes.hasNeumann())
240 const auto extrusionFactor = elemVolVars[scvf.insideScvIdx()].extrusionFactor();
241 const auto neumannFluxes =
problem.neumann(element, fvGeometry, elemVolVars, elemFaceVars, scvf);
243 for (
int eqIdx = 0; eqIdx < numEqCellCenter; ++eqIdx)
246 result[eqIdx] = neumannFluxes[eqIdx +
cellCenterOffset] * extrusionFactor * Extrusion::area(fvGeometry, scvf);
251 incorporateWallFunction_(result,
problem, element, fvGeometry, scvf, elemVolVars, elemFaceVars);
261 const Element& element,
262 const FVElementGeometry& fvGeometry,
263 const SubControlVolumeFace& scvf,
264 const ElementVolumeVariables& elemVolVars,
265 const ElementFaceVariables& elemFaceVars,
266 const ElementBoundaryTypes& elemBcTypes,
267 const ElementFluxVariablesCache& elemFluxVarsCache)
const
272 const auto bcTypes =
problem.boundaryTypes(element, scvf);
274 if(bcTypes.isDirichlet(Indices::velocity(scvf.directionIndex())))
277 const Scalar velocity = elemFaceVars[scvf].velocitySelf();
278 const Scalar dirichletValue =
problem.dirichlet(element, scvf)[Indices::velocity(scvf.directionIndex())];
279 residual = velocity - dirichletValue;
281 else if(bcTypes.isSymmetry())
285 const Scalar velocity = elemFaceVars[scvf].velocitySelf();
286 const Scalar fixedValue = 0.0;
287 residual = velocity - fixedValue;
296 const Element& element,
297 const FVElementGeometry& fvGeometry,
298 const SubControlVolumeFace& scvf,
299 const ElementVolumeVariables& elemVolVars,
300 const ElementFaceVariables& elemFaceVars,
301 const ElementBoundaryTypes& elemBcTypes,
302 const ElementFluxVariablesCache& elemFluxVarsCache)
const
304 FaceResidual result(0.0);
308 FluxVariables fluxVars;
311 const auto bcTypes =
problem.boundaryTypes(element, scvf);
312 if (bcTypes.isNeumann(Indices::velocity(scvf.directionIndex())))
316 const auto extrusionFactor = elemVolVars[scvf.insideScvIdx()].extrusionFactor();
317 result =
problem.neumann(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[Indices::velocity(scvf.directionIndex())]
318 * extrusionFactor * Extrusion::area(fvGeometry, scvf);
321 result += fluxVars.computeMomentumFlux(
problem, element, scvf, fvGeometry, elemVolVars, elemFaceVars, elemFluxVarsCache.gridFluxVarsCache());
323 else if(bcTypes.isDirichlet(Indices::pressureIdx))
327 result = fluxVars.computeMomentumFlux(
problem, element, scvf, fvGeometry, elemVolVars, elemFaceVars, elemFluxVarsCache.gridFluxVarsCache());
330 result += fluxVars.inflowOutflowBoundaryFlux(
problem, scvf, fvGeometry, elemVolVars, elemFaceVars);
339 template<
class ...Args,
bool turbulenceModel = ModelTraits::usesTurbulenceModel(), std::enable_if_t<!turbulenceModel, int> = 0>
340 void incorporateWallFunction_(Args&&... args)
const
344 template<
bool turbulenceModel = ModelTraits::usesTurbulenceModel(), std::enable_if_t<turbulenceModel,
int> = 0>
345 void incorporateWallFunction_(CellCenterResidual& boundaryFlux,
346 const Problem& problem,
347 const Element& element,
348 const FVElementGeometry& fvGeometry,
349 const SubControlVolumeFace& scvf,
350 const ElementVolumeVariables& elemVolVars,
351 const ElementFaceVariables& elemFaceVars)
const
353 static constexpr auto numEqCellCenter = CellCenterResidual::dimension;
354 const auto extrusionFactor = elemVolVars[scvf.insideScvIdx()].extrusionFactor();
357 for(
int eqIdx = 0; eqIdx < numEqCellCenter; ++eqIdx)
360 if(problem.useWallFunction(element, scvf, eqIdx + cellCenterOffset))
362 boundaryFlux[eqIdx] = problem.wallFunction(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[eqIdx]
363 * extrusionFactor * Extrusion::area(fvGeometry, scvf);
FacePrimaryVariables computeFluxForFace(const Problem &problem, const Element &element, const SubControlVolumeFace &scvf, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluate the momentum flux for the face control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:199
void evalDirichletBoundariesForFace(FaceResidual &residual, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const ElementBoundaryTypes &elemBcTypes, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluate Dirichlet (fixed value) boundary conditions for a face dof.
Definition freeflow/navierstokes/staggered/localresidual.hh:259
FacePrimaryVariables computeStorageForFace(const Problem &problem, const SubControlVolumeFace &scvf, const VolumeVariables &volVars, const ElementFaceVariables &elemFaceVars) const
Evaluate the storage term for the face control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:149
FacePrimaryVariables computeSourceForFace(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars) const
Evaluate the source term for the face control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:161
FreeFlowEnergyLocalResidual< GridGeometry, FluxVariables, ModelTraits::enableEnergyBalance(),(ModelTraits::numFluidComponents() > 1)> EnergyLocalResidual
Definition freeflow/navierstokes/staggered/localresidual.hh:87
FaceResidual computeBoundaryFluxForFace(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const ElementBoundaryTypes &elemBcTypes, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluate boundary fluxes for a face dof.
Definition freeflow/navierstokes/staggered/localresidual.hh:295
CellCenterResidual computeBoundaryFluxForCellCenter(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const ElementBoundaryTypes &elemBcTypes, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluate boundary conditions for a cell center dof.
Definition freeflow/navierstokes/staggered/localresidual.hh:214
CellCenterPrimaryVariables computeFluxForCellCenter(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const SubControlVolumeFace &scvf, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluate fluxes entering or leaving the cell center control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:97
CellCenterPrimaryVariables computeStorageForCellCenter(const Problem &problem, const SubControlVolume &scv, const VolumeVariables &volVars) const
Evaluate the storage term for the cell center control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:136
CellCenterPrimaryVariables computeSourceForCellCenter(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const SubControlVolume &scv) const
Evaluate the source term for the cell center control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:115
static constexpr auto cellCenterOffset
Definition freeflow/navierstokes/staggered/localresidual.hh:90
Element-wise calculation of the Navier-Stokes residual for models using the staggered discretization.
Definition freeflow/navierstokes/localresidual.hh:23
const Problem & problem() const
the problem
Definition staggeredlocalresidual.hh:294
StaggeredLocalResidual(const Problem *problem, const TimeLoop *timeLoop=nullptr)
the constructor
Definition staggeredlocalresidual.hh:59
Defines all properties used in Dumux.
Helper classes to compute the integration elements.
Element-wise calculation of the local residual for non-isothermal free-flow models.
FreeFlowEnergyLocalResidualImplementation< GridGeometry, FluxVariables, typename GridGeometry::DiscretizationMethod, enableEneryBalance, isCompositional > FreeFlowEnergyLocalResidual
Element-wise calculation of the local residual for non-isothermal free-flow models.
Definition freeflow/nonisothermal/localresidual.hh:32
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:310
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
The available discretization methods in Dumux.
constexpr bool isRotationalExtrusion
Convenience trait to check whether the extrusion is rotational.
Definition extrusion.hh:172
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:166
Calculates the element-wise residual for the staggered FV scheme.