GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/test/freeflow/navierstokes/channel/pipe/momentum/problem.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 55 55 100.0%
Functions: 6 6 100.0%
Branches: 48 62 77.4%

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-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7
8 #ifndef DUMUX_TEST_FREEFLOW_PIPE_PROBLEM_HH
9 #define DUMUX_TEST_FREEFLOW_PIPE_PROBLEM_HH
10
11 #include <dumux/common/parameters.hh>
12 #include <dumux/common/properties.hh>
13
14 namespace Dumux {
15 /*!
16 * \ingroup NavierStokesTests
17 * \brief Freeflow problem for pipe flow
18 * Simulation of a radially-symmetric pipe flow with circular cross-section
19 */
20 template <class TypeTag, class BaseProblem>
21 6 class FreeFlowPipeProblem : public BaseProblem
22 {
23 using ParentType = BaseProblem;
24 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
25 using FVElementGeometry = typename GridGeometry::LocalView;
26 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
27 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
28 using GridView = typename GridGeometry::GridView;
29 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
30 using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
31 using Element = typename GridView::template Codim<0>::Entity;
32 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
33 using InitialValues = typename ParentType::InitialValues;
34 using Sources = typename ParentType::Sources;
35 using DirichletValues = typename ParentType::DirichletValues;
36 using BoundaryFluxes = typename ParentType::BoundaryFluxes;
37 using BoundaryTypes = typename ParentType::BoundaryTypes;
38
39 public:
40 using Indices = typename ModelTraits::Indices;
41
42 6 FreeFlowPipeProblem(std::shared_ptr<const GridGeometry> gridGeometry)
43
2/4
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
18 : ParentType(gridGeometry)
44 {
45
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 name_ = getParamFromGroup<std::string>(this->paramGroup(), "Problem.Name");
46
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 meanInletVelocity_ = getParamFromGroup<Scalar>(this->paramGroup(), "Problem.MeanInletVelocity");
47
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 const Scalar nu = getParam<Scalar>("Component.LiquidKinematicViscosity");
48
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 rho_ = getParam<Scalar>("Component.LiquidDensity");
49 6 mu_ = nu*rho_;
50
51
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 pipeRadius_ = this->gridGeometry().bBoxMax()[0] - this->gridGeometry().bBoxMin()[0];
52 6 pipeLength_ = this->gridGeometry().bBoxMax()[1] - this->gridGeometry().bBoxMin()[1];
53
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 eps_ = 1e-7*pipeRadius_;
54
55
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 std::cout << "-- Reynolds number: " << 2*pipeRadius_*meanInletVelocity_/nu << std::endl;
56 6 }
57
58 12 const std::string& name() const
59 {
60
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 return name_;
61 }
62
63 /*!
64 * \brief Specifies which kind of boundary condition should be
65 * used for which equation on a given boundary segment.
66 */
67 9216 BoundaryTypes boundaryTypesAtPos(const GlobalPosition& globalPos) const
68 {
69 9216 BoundaryTypes values;
70
71 if constexpr (ParentType::isMomentumProblem())
72 {
73
4/4
✓ Branch 0 taken 8796 times.
✓ Branch 1 taken 420 times.
✓ Branch 2 taken 4194 times.
✓ Branch 3 taken 4602 times.
9216 if (onLowerBoundary_(globalPos) || onOuterBoundary_(globalPos))
74 9216 values.setAllDirichlet();
75
2/2
✓ Branch 0 taken 408 times.
✓ Branch 1 taken 4194 times.
4602 else if (onInnerBoundary_(globalPos))
76 {
77 4194 values.setDirichlet(Indices::velocityXIdx);
78 4194 values.setNeumann(Indices::momentumYBalanceIdx);
79 }
80 else
81 9216 values.setAllNeumann();
82 }
83 else
84 values.setAllNeumann();
85
86 9216 return values;
87 }
88
89 /*!
90 * \brief Evaluates the boundary conditions for a Neumann control volume.
91 *
92 * \param element The element for which the Neumann boundary condition is set
93 * \param fvGeometry The fvGeometry
94 * \param elemVolVars The element volume variables
95 * \param elemFaceVars The element face variables
96 * \param scvf The boundary sub control volume face
97 */
98 template<class ElementVolumeVariables, class ElementFluxVariablesCache>
99 47608 BoundaryFluxes neumann(const Element& element,
100 const FVElementGeometry& fvGeometry,
101 const ElementVolumeVariables& elemVolVars,
102 const ElementFluxVariablesCache& elemFluxVarsCache,
103 const SubControlVolumeFace& scvf) const
104 {
105
2/2
✓ Branch 0 taken 43334 times.
✓ Branch 1 taken 4274 times.
47608 BoundaryFluxes values(0.0);
106 47608 const auto& globalPos = scvf.ipGlobal();
107
108 if constexpr (ParentType::isMomentumProblem())
109 {
110
2/2
✓ Branch 0 taken 43334 times.
✓ Branch 1 taken 4274 times.
47608 if (onInnerBoundary_(globalPos))
111 values = 0.0; // zero shear stress at symmetry axis
112
1/2
✓ Branch 0 taken 4274 times.
✗ Branch 1 not taken.
4274 else if (onUpperBoundary_(globalPos))
113 4274 values.axpy(analyticalPressure(globalPos), scvf.unitOuterNormal());
114 }
115 else
116 {
117 const auto insideDensity = elemVolVars[scvf.insideScvIdx()].density();
118 values[Indices::conti0EqIdx] = this->faceVelocity(element, fvGeometry, scvf) * insideDensity * scvf.unitOuterNormal();
119 }
120
121 47608 return values;
122 }
123
124 8808 DirichletValues dirichletAtPos(const GlobalPosition& globalPos) const
125 8808 { return analyticalSolution(globalPos); }
126
127 344808 DirichletValues analyticalSolution(const GlobalPosition& globalPos, Scalar time = 0.0) const
128 {
129
2/2
✓ Branch 0 taken 5132 times.
✓ Branch 1 taken 330868 times.
344808 DirichletValues values(0.0);
130
131 // paraboloid velocity profile
132 if constexpr (ParentType::isMomentumProblem())
133 {
134
2/2
✓ Branch 0 taken 5132 times.
✓ Branch 1 taken 330868 times.
344808 const auto r = globalPos[0] - this->gridGeometry().bBoxMin()[0];
135 344808 values[Indices::velocityXIdx] = 0.0;
136
2/2
✓ Branch 0 taken 5132 times.
✓ Branch 1 taken 330868 times.
344808 values[Indices::velocityYIdx] = 2.0*meanInletVelocity_*(1.0 - r*r/(pipeRadius_*pipeRadius_));
137 }
138 else
139 values[Indices::pressureIdx] = analyticalPressure(globalPos);
140
141 return values;
142 }
143
144 3822000 Scalar densityAtPos(const GlobalPosition& globalPos) const
145 3822000 { return rho_; }
146
147 9030000 Scalar effectiveViscosityAtPos(const GlobalPosition& globalPos) const
148
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 5207990 times.
5208000 { return mu_; }
149
150 9030000 Scalar pressureAtPos(const GlobalPosition& globalPos) const
151 9030000 { return analyticalPressure(globalPos); }
152
153 5254274 Scalar analyticalPressure(const GlobalPosition& globalPos) const
154 {
155 9076274 const auto y = globalPos[1];
156 5254274 return (pipeLength_-y)*meanInletVelocity_*8.0*mu_/(pipeRadius_*pipeRadius_);
157 }
158
159 Scalar analyticalMassFlux() const
160 {
161 return meanInletVelocity_ * M_PI * pipeRadius_*pipeRadius_ * rho_;
162 }
163
164 private:
165
4/4
✓ Branch 0 taken 43334 times.
✓ Branch 1 taken 4274 times.
✓ Branch 2 taken 408 times.
✓ Branch 3 taken 4194 times.
52210 bool onInnerBoundary_(const GlobalPosition &globalPos) const
166
4/4
✓ Branch 0 taken 43334 times.
✓ Branch 1 taken 4274 times.
✓ Branch 2 taken 408 times.
✓ Branch 3 taken 4194 times.
52210 { return globalPos[0] < this->gridGeometry().bBoxMin()[0] + eps_; }
167
168
2/2
✓ Branch 0 taken 4194 times.
✓ Branch 1 taken 4602 times.
8796 bool onOuterBoundary_(const GlobalPosition &globalPos) const
169
2/2
✓ Branch 0 taken 4194 times.
✓ Branch 1 taken 4602 times.
8796 { return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; }
170
171
2/2
✓ Branch 0 taken 8796 times.
✓ Branch 1 taken 420 times.
9216 bool onLowerBoundary_(const GlobalPosition &globalPos) const
172
2/2
✓ Branch 0 taken 8796 times.
✓ Branch 1 taken 420 times.
9216 { return globalPos[1] < this->gridGeometry().bBoxMin()[1] + eps_; }
173
174
1/2
✓ Branch 0 taken 4274 times.
✗ Branch 1 not taken.
4274 bool onUpperBoundary_(const GlobalPosition &globalPos) const
175
1/2
✓ Branch 0 taken 4274 times.
✗ Branch 1 not taken.
4274 { return globalPos[1] > this->gridGeometry().bBoxMax()[1] - eps_; }
176
177 std::string name_;
178 Scalar initialPressure_;
179 Scalar meanInletVelocity_;
180 Scalar mu_;
181 Scalar rho_;
182 Scalar pipeRadius_, pipeLength_;
183 Scalar eps_;
184 };
185
186 } // end namespace Dumux
187
188 #endif
189