Line | Branch | Exec | Source |
---|---|---|---|
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-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder | ||
5 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
6 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup NavierStokesModel | ||
10 | * \copydoc Dumux::NavierStokesResidualImpl | ||
11 | */ | ||
12 | #ifndef DUMUX_STAGGERED_NAVIERSTOKES_LOCAL_RESIDUAL_HH | ||
13 | #define DUMUX_STAGGERED_NAVIERSTOKES_LOCAL_RESIDUAL_HH | ||
14 | |||
15 | #include <dune/common/hybridutilities.hh> | ||
16 | |||
17 | #include <dumux/common/properties.hh> | ||
18 | #include <dumux/discretization/method.hh> | ||
19 | #include <dumux/discretization/extrusion.hh> | ||
20 | #include <dumux/assembly/staggeredlocalresidual.hh> | ||
21 | #include <dumux/freeflow/nonisothermal/localresidual.hh> | ||
22 | |||
23 | namespace Dumux { | ||
24 | |||
25 | namespace Impl { | ||
26 | template<class T> | ||
27 | static constexpr bool isRotationalExtrusion = false; | ||
28 | |||
29 | template<int radialAxis> | ||
30 | static constexpr bool isRotationalExtrusion<RotationalExtrusion<radialAxis>> = true; | ||
31 | } // end namespace Impl | ||
32 | |||
33 | /*! | ||
34 | * \ingroup NavierStokesModel | ||
35 | * \brief Element-wise calculation of the Navier-Stokes residual for models using the staggered discretization | ||
36 | */ | ||
37 | |||
38 | // forward declaration | ||
39 | template<class TypeTag, class DiscretizationMethod> | ||
40 | class NavierStokesResidualImpl; | ||
41 | |||
42 | template<class TypeTag> | ||
43 | class NavierStokesResidualImpl<TypeTag, DiscretizationMethods::Staggered> | ||
44 | : public StaggeredLocalResidual<TypeTag> | ||
45 | { | ||
46 | using ParentType = StaggeredLocalResidual<TypeTag>; | ||
47 | friend class StaggeredLocalResidual<TypeTag>; | ||
48 | |||
49 | using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; | ||
50 | |||
51 | using GridVolumeVariables = typename GridVariables::GridVolumeVariables; | ||
52 | using ElementVolumeVariables = typename GridVolumeVariables::LocalView; | ||
53 | using VolumeVariables = typename GridVolumeVariables::VolumeVariables; | ||
54 | |||
55 | using GridFluxVariablesCache = typename GridVariables::GridFluxVariablesCache; | ||
56 | using ElementFluxVariablesCache = typename GridFluxVariablesCache::LocalView; | ||
57 | |||
58 | using GridFaceVariables = typename GridVariables::GridFaceVariables; | ||
59 | using ElementFaceVariables = typename GridFaceVariables::LocalView; | ||
60 | |||
61 | using Scalar = GetPropType<TypeTag, Properties::Scalar>; | ||
62 | using Implementation = GetPropType<TypeTag, Properties::LocalResidual>; | ||
63 | using Problem = GetPropType<TypeTag, Properties::Problem>; | ||
64 | using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; | ||
65 | using FVElementGeometry = typename GridGeometry::LocalView; | ||
66 | using GridView = typename GridGeometry::GridView; | ||
67 | using Element = typename GridView::template Codim<0>::Entity; | ||
68 | using SubControlVolume = typename FVElementGeometry::SubControlVolume; | ||
69 | using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; | ||
70 | using Extrusion = Extrusion_t<GridGeometry>; | ||
71 | using ElementBoundaryTypes = GetPropType<TypeTag, Properties::ElementBoundaryTypes>; | ||
72 | using CellCenterPrimaryVariables = GetPropType<TypeTag, Properties::CellCenterPrimaryVariables>; | ||
73 | using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; | ||
74 | using FluxVariables = GetPropType<TypeTag, Properties::FluxVariables>; | ||
75 | using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; | ||
76 | |||
77 | static constexpr bool normalizePressure = getPropValue<TypeTag, Properties::NormalizePressure>(); | ||
78 | |||
79 | using CellCenterResidual = CellCenterPrimaryVariables; | ||
80 | using FaceResidual = FacePrimaryVariables; | ||
81 | |||
82 | using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; | ||
83 | |||
84 | public: | ||
85 | using EnergyLocalResidual = FreeFlowEnergyLocalResidual<GridGeometry, FluxVariables, ModelTraits::enableEnergyBalance(), (ModelTraits::numFluidComponents() > 1)>; | ||
86 | |||
87 | // account for the offset of the cell center privars within the PrimaryVariables container | ||
88 | static constexpr auto cellCenterOffset = ModelTraits::numEq() - CellCenterPrimaryVariables::dimension; | ||
89 | static_assert(cellCenterOffset == ModelTraits::dim(), "cellCenterOffset must equal dim for staggered NavierStokes"); | ||
90 | |||
91 | //! Use the parent type's constructor | ||
92 |
6/8✓ Branch 1 taken 1355444 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1355444 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2578 times.
✓ Branch 7 taken 50 times.
✓ Branch 8 taken 2578 times.
✓ Branch 9 taken 50 times.
|
2716144 | using ParentType::ParentType; |
93 | |||
94 | //! Evaluate fluxes entering or leaving the cell center control volume. | ||
95 | ✗ | CellCenterPrimaryVariables computeFluxForCellCenter(const Problem& problem, | |
96 | const Element &element, | ||
97 | const FVElementGeometry& fvGeometry, | ||
98 | const ElementVolumeVariables& elemVolVars, | ||
99 | const ElementFaceVariables& elemFaceVars, | ||
100 | const SubControlVolumeFace &scvf, | ||
101 | const ElementFluxVariablesCache& elemFluxVarsCache) const | ||
102 | { | ||
103 | FluxVariables fluxVars; | ||
104 | 118805706 | CellCenterPrimaryVariables flux = fluxVars.computeMassFlux(problem, element, fvGeometry, elemVolVars, | |
105 |
1/8✓ Branch 1 taken 138882 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
202698350 | elemFaceVars, scvf, elemFluxVarsCache[scvf]); |
106 | |||
107 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
99555458 | EnergyLocalResidual::heatFlux(flux, problem, element, fvGeometry, elemVolVars, elemFaceVars, scvf); |
108 | |||
109 | 11358064 | return flux; | |
110 | } | ||
111 | |||
112 | //! Evaluate the source term for the cell center control volume. | ||
113 | ✗ | CellCenterPrimaryVariables computeSourceForCellCenter(const Problem& problem, | |
114 | const Element &element, | ||
115 | const FVElementGeometry& fvGeometry, | ||
116 | const ElementVolumeVariables& elemVolVars, | ||
117 | const ElementFaceVariables& elemFaceVars, | ||
118 | const SubControlVolume &scv) const | ||
119 | { | ||
120 |
0/4✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
37620788 | CellCenterPrimaryVariables result(0.0); |
121 | |||
122 | // get the values from the problem | ||
123 |
0/4✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
37620788 | const auto sourceValues = problem.source(element, fvGeometry, elemVolVars, elemFaceVars, scv); |
124 | |||
125 | // copy the respective cell center related values to the result | ||
126 |
2/4✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 131014696 times.
✓ Branch 3 taken 37620788 times.
|
168635484 | for (int i = 0; i < result.size(); ++i) |
127 | 393044088 | result[i] = sourceValues[i + cellCenterOffset]; | |
128 | |||
129 | 3746088 | return result; | |
130 | } | ||
131 | |||
132 | |||
133 | //! Evaluate the storage term for the cell center control volume. | ||
134 | ✗ | CellCenterPrimaryVariables computeStorageForCellCenter(const Problem& problem, | |
135 | const SubControlVolume& scv, | ||
136 | const VolumeVariables& volVars) const | ||
137 | { | ||
138 | 5070312 | CellCenterPrimaryVariables storage; | |
139 | 93959880 | storage[Indices::conti0EqIdx - ModelTraits::dim()] = volVars.density(); | |
140 | |||
141 | 65777128 | EnergyLocalResidual::fluidPhaseStorage(storage, volVars); | |
142 | |||
143 | ✗ | return storage; | |
144 | } | ||
145 | |||
146 | //! Evaluate the storage term for the face control volume. | ||
147 | ✗ | FacePrimaryVariables computeStorageForFace(const Problem& problem, | |
148 | const SubControlVolumeFace& scvf, | ||
149 | const VolumeVariables& volVars, | ||
150 | const ElementFaceVariables& elemFaceVars) const | ||
151 | { | ||
152 | 135806428 | FacePrimaryVariables storage(0.0); | |
153 | 135806428 | const Scalar velocity = elemFaceVars[scvf].velocitySelf(); | |
154 | 271612856 | storage[0] = volVars.density() * velocity; | |
155 | ✗ | return storage; | |
156 | } | ||
157 | |||
158 | //! Evaluate the source term for the face control volume. | ||
159 | 150537748 | FacePrimaryVariables computeSourceForFace(const Problem& problem, | |
160 | const Element& element, | ||
161 | const FVElementGeometry& fvGeometry, | ||
162 | const SubControlVolumeFace& scvf, | ||
163 | const ElementVolumeVariables& elemVolVars, | ||
164 | const ElementFaceVariables& elemFaceVars) const | ||
165 | { | ||
166 | 150537748 | FacePrimaryVariables source(0.0); | |
167 | 301075496 | const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()]; | |
168 | 602150992 | source += problem.gravity()[scvf.directionIndex()] * insideVolVars.density(); | |
169 | 150537748 | source += problem.source(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[Indices::velocity(scvf.directionIndex())]; | |
170 | |||
171 | // Axisymmetric problems in 2D feature an extra source terms arising from the transformation to cylindrical coordinates. | ||
172 | // See Ferziger/Peric: Computational methods for fluid dynamics chapter 8. | ||
173 | // https://doi.org/10.1007/978-3-540-68228-8 (page 301) | ||
174 | if constexpr (ModelTraits::dim() == 2 && Impl::isRotationalExtrusion<Extrusion>) | ||
175 | { | ||
176 | if (scvf.directionIndex() == Extrusion::radialAxis) | ||
177 | { | ||
178 | // Velocity term | ||
179 | const auto r = scvf.center()[scvf.directionIndex()]; | ||
180 | source -= -2.0*insideVolVars.effectiveViscosity() * elemFaceVars[scvf].velocitySelf() / (r*r); | ||
181 | |||
182 | // Pressure term (needed because we incorporate pressure in terms of a surface integral). | ||
183 | // grad(p) becomes div(pI) + (p/r)*n_r in cylindrical coordinates. The second term | ||
184 | // is new with respect to Cartesian coordinates and handled below as a source term. | ||
185 | const Scalar pressure = | ||
186 | normalizePressure ? insideVolVars.pressure() - problem.initial(scvf)[Indices::pressureIdx] | ||
187 | : insideVolVars.pressure(); | ||
188 | |||
189 | source += pressure/r; | ||
190 | } | ||
191 | } | ||
192 | |||
193 | 150537748 | return source; | |
194 | } | ||
195 | |||
196 | //! Evaluate the momentum flux for the face control volume. | ||
197 | ✗ | FacePrimaryVariables computeFluxForFace(const Problem& problem, | |
198 | const Element& element, | ||
199 | const SubControlVolumeFace& scvf, | ||
200 | const FVElementGeometry& fvGeometry, | ||
201 | const ElementVolumeVariables& elemVolVars, | ||
202 | const ElementFaceVariables& elemFaceVars, | ||
203 | const ElementFluxVariablesCache& elemFluxVarsCache) const | ||
204 | { | ||
205 | FluxVariables fluxVars; | ||
206 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
141926782 | return fluxVars.computeMomentumFlux(problem, element, scvf, fvGeometry, elemVolVars, elemFaceVars, elemFluxVarsCache.gridFluxVarsCache()); |
207 | } | ||
208 | |||
209 | /*! | ||
210 | * \brief Evaluate boundary conditions for a cell center dof | ||
211 | */ | ||
212 | 9358728 | CellCenterResidual computeBoundaryFluxForCellCenter(const Problem& problem, | |
213 | const Element& element, | ||
214 | const FVElementGeometry& fvGeometry, | ||
215 | const SubControlVolumeFace& scvf, | ||
216 | const ElementVolumeVariables& elemVolVars, | ||
217 | const ElementFaceVariables& elemFaceVars, | ||
218 | const ElementBoundaryTypes& elemBcTypes, | ||
219 | const ElementFluxVariablesCache& elemFluxVarsCache) const | ||
220 | { | ||
221 |
1/2✓ Branch 0 taken 287554 times.
✗ Branch 1 not taken.
|
9358728 | CellCenterResidual result(0.0); |
222 | |||
223 |
1/2✓ Branch 0 taken 9358728 times.
✗ Branch 1 not taken.
|
9358728 | if (scvf.boundary()) |
224 | { | ||
225 | 9358728 | const auto bcTypes = problem.boundaryTypes(element, scvf); | |
226 | |||
227 | // no fluxes occur over symmetry boundaries | ||
228 |
4/4✓ Branch 0 taken 7676456 times.
✓ Branch 1 taken 1682272 times.
✓ Branch 2 taken 7676456 times.
✓ Branch 3 taken 1682272 times.
|
18717456 | if (bcTypes.isSymmetry()) |
229 | 551970 | return result; | |
230 | |||
231 | // treat Dirichlet and outflow BCs | ||
232 |
1/2✓ Branch 1 taken 138882 times.
✗ Branch 2 not taken.
|
8806758 | result = computeFluxForCellCenter(problem, element, fvGeometry, elemVolVars, elemFaceVars, scvf, elemFluxVarsCache); |
233 | |||
234 | // treat Neumann BCs, i.e. overwrite certain fluxes by user-specified values | ||
235 | static constexpr auto numEqCellCenter = CellCenterResidual::dimension; | ||
236 |
4/4✓ Branch 0 taken 929888 times.
✓ Branch 1 taken 7876870 times.
✓ Branch 2 taken 929888 times.
✓ Branch 3 taken 7876870 times.
|
17613516 | if (bcTypes.hasNeumann()) |
237 | { | ||
238 | 1859776 | const auto extrusionFactor = elemVolVars[scvf.insideScvIdx()].extrusionFactor(); | |
239 |
1/2✓ Branch 1 taken 41192 times.
✗ Branch 2 not taken.
|
929888 | const auto neumannFluxes = problem.neumann(element, fvGeometry, elemVolVars, elemFaceVars, scvf); |
240 | |||
241 |
2/2✓ Branch 0 taken 3159654 times.
✓ Branch 1 taken 929888 times.
|
4089542 | for (int eqIdx = 0; eqIdx < numEqCellCenter; ++eqIdx) |
242 | { | ||
243 |
2/2✓ Branch 0 taken 1766956 times.
✓ Branch 1 taken 1392698 times.
|
3159654 | if (bcTypes.isNeumann(eqIdx + cellCenterOffset)) |
244 | 5529600 | result[eqIdx] = neumannFluxes[eqIdx + cellCenterOffset] * extrusionFactor * Extrusion::area(fvGeometry, scvf); | |
245 | } | ||
246 | } | ||
247 | |||
248 | // account for wall functions, if used | ||
249 | 14593054 | incorporateWallFunction_(result, problem, element, fvGeometry, scvf, elemVolVars, elemFaceVars); | |
250 | } | ||
251 | 1150388 | return result; | |
252 | } | ||
253 | |||
254 | /*! | ||
255 | * \brief Evaluate Dirichlet (fixed value) boundary conditions for a face dof | ||
256 | */ | ||
257 | 150537748 | void evalDirichletBoundariesForFace(FaceResidual& residual, | |
258 | const Problem& problem, | ||
259 | const Element& element, | ||
260 | const FVElementGeometry& fvGeometry, | ||
261 | const SubControlVolumeFace& scvf, | ||
262 | const ElementVolumeVariables& elemVolVars, | ||
263 | const ElementFaceVariables& elemFaceVars, | ||
264 | const ElementBoundaryTypes& elemBcTypes, | ||
265 | const ElementFluxVariablesCache& elemFluxVarsCache) const | ||
266 | { | ||
267 |
2/2✓ Branch 0 taken 8610966 times.
✓ Branch 1 taken 141926782 times.
|
150537748 | if (scvf.boundary()) |
268 | { | ||
269 | // handle the actual boundary conditions: | ||
270 | 8610966 | const auto bcTypes = problem.boundaryTypes(element, scvf); | |
271 | |||
272 |
2/2✓ Branch 0 taken 3277000 times.
✓ Branch 1 taken 5333966 times.
|
8610966 | if(bcTypes.isDirichlet(Indices::velocity(scvf.directionIndex()))) |
273 | { | ||
274 | // set a fixed value for the velocity for Dirichlet boundary conditions | ||
275 |
2/2✓ Branch 0 taken 5976 times.
✓ Branch 1 taken 1488 times.
|
5333966 | const Scalar velocity = elemFaceVars[scvf].velocitySelf(); |
276 |
2/2✓ Branch 0 taken 5976 times.
✓ Branch 1 taken 1488 times.
|
5441614 | const Scalar dirichletValue = problem.dirichlet(element, scvf)[Indices::velocity(scvf.directionIndex())]; |
277 | 10667932 | residual = velocity - dirichletValue; | |
278 | } | ||
279 |
4/4✓ Branch 0 taken 489258 times.
✓ Branch 1 taken 2787742 times.
✓ Branch 2 taken 489258 times.
✓ Branch 3 taken 2787742 times.
|
6554000 | else if(bcTypes.isSymmetry()) |
280 | { | ||
281 | // for symmetry boundary conditions, there is no flow across the boundary and | ||
282 | // we therefore treat it like a Dirichlet boundary conditions with zero velocity | ||
283 | 489258 | const Scalar velocity = elemFaceVars[scvf].velocitySelf(); | |
284 | 489258 | const Scalar fixedValue = 0.0; | |
285 | 978516 | residual = velocity - fixedValue; | |
286 | } | ||
287 | } | ||
288 | 150537748 | } | |
289 | |||
290 | /*! | ||
291 | * \brief Evaluate boundary fluxes for a face dof | ||
292 | */ | ||
293 | 8610966 | FaceResidual computeBoundaryFluxForFace(const Problem& problem, | |
294 | const Element& element, | ||
295 | const FVElementGeometry& fvGeometry, | ||
296 | const SubControlVolumeFace& scvf, | ||
297 | const ElementVolumeVariables& elemVolVars, | ||
298 | const ElementFaceVariables& elemFaceVars, | ||
299 | const ElementBoundaryTypes& elemBcTypes, | ||
300 | const ElementFluxVariablesCache& elemFluxVarsCache) const | ||
301 | { | ||
302 |
1/2✓ Branch 0 taken 8610966 times.
✗ Branch 1 not taken.
|
8610966 | FaceResidual result(0.0); |
303 | |||
304 |
1/2✓ Branch 0 taken 8610966 times.
✗ Branch 1 not taken.
|
8610966 | if (scvf.boundary()) |
305 | { | ||
306 | FluxVariables fluxVars; | ||
307 | |||
308 | // handle the actual boundary conditions: | ||
309 | 8610966 | const auto bcTypes = problem.boundaryTypes(element, scvf); | |
310 |
2/2✓ Branch 0 taken 8437702 times.
✓ Branch 1 taken 173264 times.
|
8610966 | if (bcTypes.isNeumann(Indices::velocity(scvf.directionIndex()))) |
311 | { | ||
312 | // the source term has already been accounted for, here we | ||
313 | // add a given Neumann flux for the face on the boundary itself ... | ||
314 | 346528 | const auto extrusionFactor = elemVolVars[scvf.insideScvIdx()].extrusionFactor(); | |
315 |
2/4✓ Branch 1 taken 173264 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 173264 times.
✗ Branch 5 not taken.
|
173264 | result = problem.neumann(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[Indices::velocity(scvf.directionIndex())] |
316 |
2/4✓ Branch 1 taken 173264 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 173264 times.
✗ Branch 5 not taken.
|
346528 | * extrusionFactor * Extrusion::area(fvGeometry, scvf); |
317 | |||
318 | // ... and treat the fluxes of the remaining (frontal and lateral) faces of the staggered control volume | ||
319 |
1/2✓ Branch 1 taken 173264 times.
✗ Branch 2 not taken.
|
173264 | result += fluxVars.computeMomentumFlux(problem, element, scvf, fvGeometry, elemVolVars, elemFaceVars, elemFluxVarsCache.gridFluxVarsCache()); |
320 | } | ||
321 |
2/2✓ Branch 0 taken 5823224 times.
✓ Branch 1 taken 2614478 times.
|
8437702 | else if(bcTypes.isDirichlet(Indices::pressureIdx)) |
322 | { | ||
323 | // we are at an "fixed pressure" boundary for which the resdiual of the momentum balance needs to be assembled | ||
324 | // as if it where inside the domain and not on the boundary (source term has already been acounted for) | ||
325 |
1/2✓ Branch 1 taken 2614478 times.
✗ Branch 2 not taken.
|
2614478 | result = fluxVars.computeMomentumFlux(problem, element, scvf, fvGeometry, elemVolVars, elemFaceVars, elemFluxVarsCache.gridFluxVarsCache()); |
326 | |||
327 | // incorporate the inflow or outflow contribution | ||
328 |
1/2✓ Branch 1 taken 79436 times.
✗ Branch 2 not taken.
|
2614478 | result += fluxVars.inflowOutflowBoundaryFlux(problem, scvf, fvGeometry, elemVolVars, elemFaceVars); |
329 | } | ||
330 | } | ||
331 | 8610966 | return result; | |
332 | } | ||
333 | |||
334 | private: | ||
335 | |||
336 | //! do nothing if no turbulence model is used | ||
337 | template<class ...Args, bool turbulenceModel = ModelTraits::usesTurbulenceModel(), std::enable_if_t<!turbulenceModel, int> = 0> | ||
338 | ✗ | void incorporateWallFunction_(Args&&... args) const | |
339 | ✗ | {} | |
340 | |||
341 | //! if a turbulence model is used, ask the problem is a wall function shall be employed and get the flux accordingly | ||
342 | template<bool turbulenceModel = ModelTraits::usesTurbulenceModel(), std::enable_if_t<turbulenceModel, int> = 0> | ||
343 | 2306480 | void incorporateWallFunction_(CellCenterResidual& boundaryFlux, | |
344 | const Problem& problem, | ||
345 | const Element& element, | ||
346 | const FVElementGeometry& fvGeometry, | ||
347 | const SubControlVolumeFace& scvf, | ||
348 | const ElementVolumeVariables& elemVolVars, | ||
349 | const ElementFaceVariables& elemFaceVars) const | ||
350 | { | ||
351 | static constexpr auto numEqCellCenter = CellCenterResidual::dimension; | ||
352 | 16185552 | const auto extrusionFactor = elemVolVars[scvf.insideScvIdx()].extrusionFactor(); | |
353 | |||
354 | // account for wall functions, if used | ||
355 |
2/2✓ Branch 0 taken 8304774 times.
✓ Branch 1 taken 2306480 times.
|
16397550 | for(int eqIdx = 0; eqIdx < numEqCellCenter; ++eqIdx) |
356 | { | ||
357 | // use a wall function | ||
358 |
2/2✓ Branch 1 taken 662108 times.
✓ Branch 2 taken 7642666 times.
|
8304774 | if(problem.useWallFunction(element, scvf, eqIdx + cellCenterOffset)) |
359 | { | ||
360 | 1748276 | boundaryFlux[eqIdx] = problem.wallFunction(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[eqIdx] | |
361 | 1324216 | * extrusionFactor * Extrusion::area(fvGeometry, scvf); | |
362 | } | ||
363 | } | ||
364 | 2306480 | } | |
365 | |||
366 | //! Returns the implementation of the problem (i.e. static polymorphism) | ||
367 | Implementation &asImp_() | ||
368 | { return *static_cast<Implementation *>(this); } | ||
369 | |||
370 | //! \copydoc asImp_() | ||
371 | const Implementation &asImp_() const | ||
372 | { return *static_cast<const Implementation *>(this); } | ||
373 | }; | ||
374 | |||
375 | } // end namespace Dumux | ||
376 | |||
377 | #endif | ||
378 |