GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/test/freeflow/navierstokes/channel/3d/problem.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 33 40 82.5%
Functions: 8 29 27.6%
Branches: 44 115 38.3%

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 NavierStokesTests
10 * \brief Channel flow test for the staggered grid (Navier-)Stokes model.
11 *
12 * The channel is either modeled in 3D or in 2D, using an additional wall friction term
13 * to mimic the 3D behavior of the flow.
14 */
15
16 #ifndef DUMUX_TEST_FREEFLOW_NAVIERSTOKES_3D_CHANNEL_PROBLEM_HH
17 #define DUMUX_TEST_FREEFLOW_NAVIERSTOKES_3D_CHANNEL_PROBLEM_HH
18
19 #include <dune/common/float_cmp.hh>
20
21 #include <dumux/common/properties.hh>
22 #include <dumux/common/parameters.hh>
23
24 #include <dumux/freeflow/navierstokes/momentum/fluxhelper.hh>
25 #include <dumux/freeflow/navierstokes/scalarfluxhelper.hh>
26 #include <dumux/freeflow/navierstokes/mass/1p/advectiveflux.hh>
27
28 namespace Dumux {
29
30 /*!
31 * \brief Test problem for the one-phase (Navier-) Stokes model in a 3D or pseudo 3D channel.
32 *
33 * Flow from left to right in a three-dimensional channel is considered. At the inlet (left)
34 * and outlet (right) fixed values for pressure are set.
35 * The channel is confined by solid walls at all other sides of the domain which corresponds
36 * to no-slip/no-flow conditions.
37 * The value of an analytical solution for the given flow configuration is furthermore provided.
38 * For sake of efficiency, the 3D problem can be reduced to a two-dimensional one by including
39 * an additional wall friction term to the momentum balance (Flekkoy et al., 1995 \cite flekkoy1995a).
40 */
41 template <class TypeTag, class BaseProblem>
42 8 class ThreeDChannelTestProblem : public BaseProblem
43 {
44 using ParentType = BaseProblem;
45
46 using BoundaryTypes = typename ParentType::BoundaryTypes;
47 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
48 using FVElementGeometry = typename GridGeometry::LocalView;
49 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
50 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
51 using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
52 using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
53 using InitialValues = typename ParentType::InitialValues;
54 using Sources = typename ParentType::Sources;
55 using DirichletValues = typename ParentType::DirichletValues;
56 using BoundaryFluxes = typename ParentType::BoundaryFluxes;
57 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
58 using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
59
60 static constexpr auto dimWorld = GridGeometry::GridView::dimensionworld;
61 using Element = typename GridGeometry::GridView::template Codim<0>::Entity;
62 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
63 using VelocityVector = Dune::FieldVector<Scalar, dimWorld>;
64
65 using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>;
66 static constexpr int dim = GridGeometry::GridView::dimension;
67 static constexpr bool enablePseudoThreeDWallFriction = dim != 3;
68
69 public:
70 16 ThreeDChannelTestProblem(std::shared_ptr<const GridGeometry> gridGeometry, std::shared_ptr<CouplingManager> couplingManager)
71
7/20
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✓ Branch 18 taken 8 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
64 : ParentType(gridGeometry, couplingManager)
72 {
73
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 deltaP_ = getParam<Scalar>("Problem.DeltaP");
74
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 rho_ = getParam<Scalar>("Component.LiquidDensity");
75
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 nu_ = getParam<Scalar>("Component.LiquidKinematicViscosity");
76
77
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 height_ = getParam<Scalar>("Problem.Height");
78
5/10
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
48 if(dim == 3 && !Dune::FloatCmp::eq(height_, this->gridGeometry().bBoxMax()[2]))
79 DUNE_THROW(Dune::InvalidStateException, "z-dimension must equal height");
80 16 }
81
82 /*!
83 * \name Problem parameters
84 */
85 // \{
86
87 /*!
88 * \brief Evaluates the source term for all phases within a given
89 * sub-control volume
90 */
91 template<class ElementVolumeVariables>
92 14736 Sources source(const Element& element,
93 const FVElementGeometry& fvGeometry,
94 const ElementVolumeVariables& elemVolVars,
95 const SubControlVolume& scv) const
96 {
97
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
139520 auto source = Sources(0.0);
98
99 if constexpr (ParentType::isMomentumProblem() && enablePseudoThreeDWallFriction)
100 {
101
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7367 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
14736 static const Scalar height = getParam<Scalar>("Problem.Height");
102
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7367 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
14736 static const Scalar factor = getParam<Scalar>("Problem.PseudoWallFractionFactor", 8.0);
103 14736 source[scv.dofAxis()] = this->pseudo3DWallFriction(element, fvGeometry, elemVolVars, scv, height, factor);
104 }
105
106 14736 return source;
107 }
108
109 // \}
110
111 /*!
112 * \name Boundary conditions
113 */
114 // \{
115
116 /*!
117 * \brief Specifies which kind of boundary condition should be
118 * used for which equation on a given boundary control volume.
119 *
120 * \param globalPos The position of the center of the finite volume
121 */
122 824596 BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
123 {
124
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 72474 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13806 times.
910876 BoundaryTypes values;
125
126 if constexpr (ParentType::isMomentumProblem())
127 {
128 824596 values.setAllDirichlet();
129 2656064 if (isOutlet_(globalPos) || isInlet_(globalPos))
130 values.setAllNeumann();
131 }
132 else
133
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 72474 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 72474 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13806 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13806 times.
172560 values.setNeumann(Indices::conti0EqIdx);
134
135 824596 return values;
136 }
137
138 /*!
139 * \brief Evaluates the boundary conditions for a Dirichlet control volume.
140 *
141 * \param globalPos The center of the finite volume which ought to be set.
142 */
143 DirichletValues dirichletAtPos(const GlobalPosition &globalPos) const
144 {
145 // no-flow/no-slip
146
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
266512 return DirichletValues(0.0);
147 }
148
149 /*!
150 * \brief Evaluates the boundary conditions for a Neumann control volume.
151 *
152 * \param element The element for which the Neumann boundary condition is set
153 * \param fvGeometry The fvGeometry
154 * \param elemVolVars The element volume variables
155 * \param elemFaceVars The element face variables
156 * \param scvf The boundary sub control volume face
157 */
158 template<class ElementVolumeVariables, class ElementFluxVariablesCache>
159 BoundaryFluxes neumann(const Element& element,
160 const FVElementGeometry& fvGeometry,
161 const ElementVolumeVariables& elemVolVars,
162 const ElementFluxVariablesCache& elemFluxVarsCache,
163 const SubControlVolumeFace& scvf) const
164 {
165
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
72474 BoundaryFluxes values(0.0);
166
0/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
72474 const auto& globalPos = scvf.ipGlobal();
167
168 if constexpr (ParentType::isMomentumProblem())
169 {
170 const auto p = isInlet_(globalPos) ? 1e5 + deltaP_ : 1e5;
171 values = NavierStokesMomentumBoundaryFluxHelper::fixedPressureMomentumFlux(
172 *this, fvGeometry, scvf, elemVolVars, elemFluxVarsCache, p
173 );
174 }
175 else
176 {
177
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
72474 values = NavierStokesScalarBoundaryFluxHelper<AdvectiveFlux<ModelTraits>>::scalarOutflowFlux(
178 *this, element, fvGeometry, scvf, elemVolVars
179 );
180 }
181
182 return values;
183 }
184
185 // \}
186
187 //! Returns the analytical solution for the flux through the rectangular channel
188 4 Scalar analyticalFlux() const
189 {
190 4 const Scalar h = height_;
191 16 const Scalar w = this->gridGeometry().bBoxMax()[1];
192 16 const Scalar L = this->gridGeometry().bBoxMax()[0];
193
194 4 const Scalar mu = nu_*rho_;
195
196 4 return h*h*h * w * deltaP_ / (12*mu*L) * (1.0 - 0.630 * h/w);
197 }
198
199 private:
200
201 bool isInlet_(const GlobalPosition& globalPos) const
202
4/8
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 199332 times.
✓ Branch 5 taken 52386 times.
✓ Branch 6 taken 199332 times.
✓ Branch 7 taken 52386 times.
503436 { return globalPos[0] < eps_; }
203
204 bool isOutlet_(const GlobalPosition& globalPos) const
205
10/10
✓ Branch 0 taken 251718 times.
✓ Branch 1 taken 160580 times.
✓ Branch 2 taken 251718 times.
✓ Branch 3 taken 160580 times.
✓ Branch 4 taken 251718 times.
✓ Branch 5 taken 160580 times.
✓ Branch 6 taken 251718 times.
✓ Branch 7 taken 160580 times.
✓ Branch 8 taken 251718 times.
✓ Branch 9 taken 160580 times.
2061490 { return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; }
206
207 static constexpr Scalar eps_=1e-6;
208 Scalar deltaP_;
209 Scalar height_;
210 Scalar rho_;
211 Scalar nu_;
212 };
213
214 } // end namespace Dumux
215
216 #endif
217