version 3.11-dev
Loading...
Searching...
No Matches
freeflow/navierstokes/momentum/cvfe/localresidual.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_NAVIERSTOKES_MOMENTUM_CVFE_LOCAL_RESIDUAL_HH
13#define DUMUX_NAVIERSTOKES_MOMENTUM_CVFE_LOCAL_RESIDUAL_HH
14
15#include <dune/common/hybridutilities.hh>
16#include <dune/geometry/quadraturerules.hh>
17
20#include <dumux/common/concepts/variables_.hh>
21#include <dumux/common/typetraits/localdofs_.hh>
24
31
34
35namespace Dumux {
36
37namespace Detail {
38
40template<class P, class FVG, class EV, class IPD>
42 std::declval<P>().source(std::declval<FVG>(), std::declval<EV>(), std::declval<IPD>())
43);
44
45template<class P, class FVG, class EV, class IPD>
47{ return Dune::Std::is_detected<SourceWithIpDataInterface, P, FVG, EV, IPD>::value; }
48
49} // end namespace Detail
50
55template<class TypeTag>
58{
60
62
63 using GridVariablesCache = Concept::GridVariablesCache_t<GridVariables>;
64 using ElementVariables = typename GridVariablesCache::LocalView;
65 using Variables = Concept::Variables_t<GridVariables>;
66
70 using ElementDiscretization = typename GridGeometry::LocalView;
71 using SubControlVolume = typename ElementDiscretization::SubControlVolume;
72 using SubControlVolumeFace = typename ElementDiscretization::SubControlVolumeFace;
73 using GridView = typename GridGeometry::GridView;
74 using Element = typename GridView::template Codim<0>::Entity;
78 using NumEqVector = Dumux::NumEqVector<PrimaryVariables>;
79
80 using Extrusion = Extrusion_t<GridGeometry>;
81
83
84 static constexpr auto dim = GridView::dimension;
85
86 using LocalBasis = typename GridGeometry::FeCache::FiniteElementType::Traits::LocalBasisType;
87 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
91
93
94public:
96 using ElementResidualVector = typename ParentType::ElementResidualVector;
97 using ParentType::ParentType;
98
109 NumEqVector computeStorage(const Problem& problem,
110 const ElementDiscretization& elemDisc,
111 const SubControlVolume& scv,
112 const Variables& vars,
113 const bool isPreviousStorage) const
114 {
115 return problem.density(elemDisc.element(), elemDisc, ipData(elemDisc, scv), isPreviousStorage) * vars.velocity();
116 }
117
127 NumEqVector storageIntegral(const ElementDiscretization& elemDisc,
128 const ElementVariables& elemVars,
129 const SubControlVolume& scv,
130 bool isPreviousTimeLevel) const
131 {
132 const auto& vars = elemVars[scv];
133 // We apply mass lumping
134 NumEqVector storage = this->asImp().problem().density(elemDisc.element(), elemDisc, ipData(elemDisc, scv), isPreviousTimeLevel)
135 * vars.velocity();
136
137 storage *= Extrusion::volume(elemDisc, scv) * vars.extrusionFactor();
138
139 return storage;
140 }
141
153 NumEqVector computeSource(const Problem& problem,
154 const Element& element,
155 const ElementDiscretization& elemDisc,
156 const ElementVariables& elemVars,
157 const SubControlVolume& scv) const
158 {
159 NumEqVector source;
160
162 {
163 source = problem.source(elemDisc, elemVars, ipData(elemDisc, scv.center()));
164
165 // ToDo: point source data with ipData
166 // add contribution from possible point sources
167 if (!problem.pointSourceMap().empty())
168 source += problem.scvPointSources(element, elemDisc, elemVars, scv);
169 }
170 else
171 source = ParentType::computeSource(problem, element, elemDisc, elemVars, scv);
172
173
174 // add rho*g (note that gravity might be zero in case it's disabled in the problem)
175 const auto& data = ipData(elemDisc, scv);
176 source += problem.density(element, elemDisc, data) * problem.gravity();
177
178 // Axisymmetric problems in 2D feature an extra source term arising from the transformation to cylindrical coordinates.
179 // See Ferziger/Peric: Computational methods for Fluid Dynamics (2020)
180 // https://doi.org/10.1007/978-3-319-99693-6
181 // Chapter 9.9 and Eq. (9.81) and comment on finite volume methods
182 if constexpr (dim == 2 && isRotationalExtrusion<Extrusion>)
183 {
184 // the radius with respect to the rotation axis
185 const auto& gridDiscretization = Dumux::gridDiscretization(elemDisc);
186 const auto r = scv.center()[Extrusion::radialAxis] - gridDiscretization.bBoxMin()[Extrusion::radialAxis];
187
188 // The velocity term is new with respect to Cartesian coordinates and handled below as a source term
189 // It only enters the balance of the momentum balance in radial direction
190 source[Extrusion::radialAxis] += -2.0*problem.effectiveViscosity(element, elemDisc, data)
191 * elemVars[scv].velocity(Extrusion::radialAxis) / (r*r);
192
193 // Pressure term (needed because we incorporate pressure in terms of a surface integral).
194 // grad(p) becomes div(pI) + (p/r)*n_r in cylindrical coordinates. The second term
195 // is new with respect to Cartesian coordinates and handled below as a source term.
196 source[Extrusion::radialAxis] += problem.pressure(element, elemDisc, data)/r;
197 }
198
199 return source;
200 }
201
210 NumEqVector sourceIntegral(const ElementDiscretization& elemDisc,
211 const ElementVariables& elemVars,
212 const SubControlVolume& scv) const
213 {
214 static_assert(!(dim == 2 && isRotationalExtrusion<Extrusion>), "Rotational extrusion source terms are not implemented for integral interface.");
215
216 const auto& problem = this->asImp().problem();
217
218 NumEqVector source(0.0);
219 for (const auto& qpData : CVFE::quadratureRule(elemDisc, scv))
220 {
221 source += qpData.weight() * (problem.source(elemDisc, elemVars, qpData.ipData())
222 + problem.density(elemDisc.element(), elemDisc, qpData.ipData()) * problem.gravity());
223 }
224
225 source *= elemVars[scv].extrusionFactor();
226
227 // add contribution from possible point sources
228 const auto& pointSources = problem.pointSources();
229 if (!pointSources.empty())
230 for (const auto& context : pointSources.contexts(elemDisc, scv))
231 {
232 auto psValues = pointSources.eval(elemDisc, elemVars, context);
233 source += psValues;
234 }
235
236 return source;
237 }
238
249 template<class ElementFluxVariablesCache>
250 NumEqVector computeFlux(const Problem& problem,
251 const Element& element,
252 const ElementDiscretization& elemDisc,
253 const ElementVariables& elemVars,
254 const SubControlVolumeFace& scvf,
255 const ElementFluxVariablesCache& elemFluxVarsCache) const
256 {
258 FluxContext context(problem, elemDisc, elemVars, elemFluxVarsCache, scvf);
259 FluxHelper fluxHelper;
260
261 NumEqVector flux(0.0);
262 flux += fluxHelper.advectiveMomentumFlux(context);
263 flux += fluxHelper.diffusiveMomentumFlux(context);
264 flux += fluxHelper.pressureContribution(context);
265 return flux;
266 }
267
276 NumEqVector fluxIntegral(const ElementDiscretization& elemDisc,
277 const ElementVariables& elemVars,
278 const SubControlVolumeFace& scvf) const
279 {
280 const auto& problem = this->asImp().problem();
281
282 NumEqVector flux(0.0);
283 GlobalPosition velIntegral(0.0);
284 FluxFunctionHelper fluxFunctionHelper;
286
287 for (const auto& qpData : CVFE::quadratureRule(elemDisc, scvf))
288 {
289 const auto& ipCache = cache(elemVars, qpData.ipData());
290 FluxFunctionContext context(this->problem(), elemDisc, elemVars, ipCache);
291
292 velIntegral += context.velocity() * qpData.weight();
293 flux += qpData.weight() * ( fluxFunctionHelper.diffusiveMomentumFluxIntegrand(context, qpData.ipData())
294 + fluxFunctionHelper.pressureFluxIntegrand(context, qpData.ipData()) );
295 }
296 flux += fluxFunctionHelper.advectiveMomentumFluxIntegral(problem, elemDisc, elemVars, scvf, velIntegral);
297
298 flux *= elemVars[elemDisc.scv(scvf.insideScvIdx())].extrusionFactor();
299
300 return flux;
301 }
302
304 const Problem& problem,
305 const Element& element,
306 const ElementDiscretization& elemDisc,
307 const ElementVariables& prevElemVars,
308 const ElementVariables& curElemVars) const
309 {
311 residual, problem, elemDisc, prevElemVars, curElemVars, this->timeLoop().timeStepSize()
312 );
313 }
314
316 const Problem& problem,
317 const Element& element,
318 const ElementDiscretization& elemDisc,
319 const ElementVariables& elemVars) const
320 {
322 residual, problem, elemDisc, elemVars
323 );
324 }
325
326};
327
328} // end namespace Dumux
329
330#endif
Boundary flag to store e.g. in sub control volume faces.
An interpolation point related to an element that includes global and local positions.
Definition cvfe/interpolationpointdata.hh:31
Element-wise calculation of the Navier-Stokes residual for models using CVFE discretizations.
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:58
NumEqVector computeSource(const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolume &scv) const
Calculate the source term of the equation.
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:153
NumEqVector computeStorage(const Problem &problem, const ElementDiscretization &elemDisc, const SubControlVolume &scv, const Variables &vars, const bool isPreviousStorage) const
Calculate the storage term of the equation.
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:109
NumEqVector sourceIntegral(const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolume &scv) const
Calculate the source integral.
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:210
NumEqVector computeFlux(const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolumeFace &scvf, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluates the mass flux over a face of a sub control volume.
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:250
typename ParentType::ElementResidualVector ElementResidualVector
Use the parent type's constructor.
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:96
NumEqVector storageIntegral(const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolume &scv, bool isPreviousTimeLevel) const
Calculate the storage integral.
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:127
NumEqVector fluxIntegral(const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolumeFace &scvf) const
Calculates the flux integral over a sub control volume face.
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:276
void addToElementFluxAndSourceResidual(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars) const
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:315
void addToElementStorageResidual(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &prevElemVars, const ElementVariables &curElemVars) const
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:303
Helper class for evaluating FE-based local residuals.
Definition felocalresidual.hh:31
static void addFluxAndSourceTerms(ResidualVector &residual, const Problem &problem, const ElementDiscretization &elemDisc, const ElementVariables &elemVars)
Add flux and source residual contribution for non-CV local dofs.
Definition felocalresidual.hh:106
static void addStorageTerms(ResidualVector &residual, const Problem &problem, const ElementDiscretization &elemDisc, const ElementVariables &prevElemVars, const ElementVariables &curElemVars, const Scalar timeStepSize)
Add storage residual contribution for non-CV local dofs.
Definition felocalresidual.hh:46
The flux variables class for the Navier-Stokes model using control-volume finite element schemes.
Definition flux.hh:178
NumEqVector advectiveMomentumFlux(const Context &context) const
Returns the advective momentum flux.
Definition flux.hh:196
NumEqVector diffusiveMomentumFlux(const Context &context) const
Returns the diffusive momentum flux due to viscous forces.
Definition flux.hh:230
NumEqVector pressureContribution(const Context &context) const
Definition flux.hh:269
Context for computing fluxes.
Definition flux.hh:39
The flux function class for the Navier-Stokes model using control-volume finite element schemes.
Definition flux.hh:299
NumEqVector pressureFluxIntegrand(const Context &context, const IpData &ipData) const
Definition flux.hh:372
NumEqVector diffusiveMomentumFluxIntegrand(const Context &context, const IpData &ipData) const
Returns the diffusive momentum flux due to viscous forces.
Definition flux.hh:345
NumEqVector advectiveMomentumFluxIntegral(const Problem &problem, const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolumeFace &scvf, const VelocityVector &integratedVelocity) const
Returns the advective momentum flux contribution for a given integrated velocity at the face.
Definition flux.hh:318
Context for interpolating data on interpolation points.
Definition flux.hh:99
Defines all properties used in Dumux.
Classes representing interpolation point data for control-volume finite element schemes.
The default local operator than can be specialized for each discretization scheme.
Helper classes to compute the integration elements.
Helper functions for assembling FE-based local residuals.
Shape functions and gradients at an interpolation point.
The flux variables class for the Navier-Stokes model using control-volume finite element schemes.
Type traits for classes providing a grid discretization.
typename NumEqVectorTraits< PrimaryVariables >::type NumEqVector
A vector with the same size as numbers of equations This is the default implementation and has to be ...
Definition numeqvector.hh:34
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
decltype(auto) gridDiscretization(const T &t, Args &&... args)
The grid discretization.
Definition griddiscretization.hh:65
The available discretization methods in Dumux.
auto quadratureRule(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolume &scv, QuadratureRules::MidpointQuadrature)
Midpoint quadrature for scv.
Definition quadraturerules.hh:159
Definition cvfelocalresidual.hh:25
decltype( std::declval< P >().source(std::declval< FVG >(), std::declval< EV >(), std::declval< IPD >())) SourceWithIpDataInterface
helper struct detecting if a problem has new source interface
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:41
constexpr bool hasProblemSourceWithIpDataInterface()
Definition freeflow/navierstokes/momentum/cvfe/localresidual.hh:46
Definition adapt.hh:17
constexpr bool isRotationalExtrusion
Convenience trait to check whether the extrusion is rotational.
Definition extrusion.hh:263
typename Detail::DiscretizationDefaultLocalOperator< TypeTag >::type DiscretizationDefaultLocalOperator
Definition defaultlocaloperator.hh:26
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:257
A helper to deduce a vector with the same size as numbers of equations.
Quadrature rules over sub-control volumes and sub-control volume faces.