GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/test/freeflow/navierstokesnc/densitydrivenflow/problem.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 29 38 76.3%
Functions: 4 13 30.8%
Branches: 48 84 57.1%

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 NavierStokesNCTests
10 * \brief Density driven flow test for the multi-component staggered grid (Navier-)Stokes model.
11 */
12
13 #ifndef DUMUX_DENSITY_DRIVEN_NC_TEST_PROBLEM_HH
14 #define DUMUX_DENSITY_DRIVEN_NC_TEST_PROBLEM_HH
15
16 #include <dumux/common/parameters.hh>
17 #include <dumux/common/properties.hh>
18 #include <dumux/common/timeloop.hh>
19
20 #include <dumux/freeflow/navierstokes/boundarytypes.hh>
21
22 #include <dumux/freeflow/navierstokes/momentum/fluxhelper.hh>
23 #include <dumux/freeflow/navierstokes/scalarfluxhelper.hh>
24
25 namespace Dumux {
26
27 /*!
28 * \ingroup NavierStokesNCTests
29 * \brief Test problem for the one-phase (Navier-)Stokes model.
30 *
31 * Density driven flow test for the multi-component staggered grid (Navier-)Stokes model.
32 */
33 template <class TypeTag, class BaseProblem>
34 class DensityDrivenFlowProblem : public BaseProblem
35 {
36 using ParentType = BaseProblem;
37 using BoundaryTypes = typename ParentType::BoundaryTypes;
38 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
39 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
40 using FVElementGeometry = typename GridGeometry::LocalView;
41 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
42 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
43 using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
44 using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
45 using InitialValues = typename ParentType::InitialValues;
46 using Sources = typename ParentType::Sources;
47 using DirichletValues = typename ParentType::DirichletValues;
48 using BoundaryFluxes = typename ParentType::BoundaryFluxes;
49 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
50 using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
51
52 static constexpr auto dimWorld = GridGeometry::GridView::dimensionworld;
53 using Element = typename GridGeometry::GridView::template Codim<0>::Entity;
54 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
55 using VelocityVector = Dune::FieldVector<Scalar, dimWorld>;
56
57 using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>;
58
59 using TimeLoopPtr = std::shared_ptr<CheckPointTimeLoop<Scalar>>;
60
61 static constexpr auto compIdx = 1;
62
63 public:
64 4 DensityDrivenFlowProblem(std::shared_ptr<const GridGeometry> gridGeometry,
65 std::shared_ptr<CouplingManager> couplingManager)
66 : ParentType(gridGeometry, couplingManager)
67
8/24
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 2 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
16 , eps_(1e-6)
68 {
69
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 useWholeLength_ = getParam<bool>("Problem.UseWholeLength");
70 4 }
71
72 /*!
73 * \brief Returns a reference pressure at a given sub control volume face.
74 * This pressure is subtracted from the actual pressure for the momentum balance
75 * which potentially helps to improve numerical accuracy by avoiding issues related to floating point arithmetic.
76 */
77 Scalar referencePressure(const Element& element,
78 const FVElementGeometry& fvGeometry,
79 const SubControlVolumeFace& scvf) const
80 { return 1.1e5; }
81
82 /*!
83 * \brief Specifies which kind of boundary condition should be
84 * used for which equation on a given boundary control volume.
85 *
86 * \param globalPos The position of the center of the finite volume
87 */
88 267200 BoundaryTypes boundaryTypesAtPos(const GlobalPosition& globalPos) const
89 {
90 267200 BoundaryTypes values;
91
92 if constexpr (ParentType::isMomentumProblem())
93 values.setAllDirichlet();
94 else
95 {
96 267200 values.setAllNeumann();
97
10/10
✓ Branch 0 taken 33400 times.
✓ Branch 1 taken 100200 times.
✓ Branch 2 taken 33400 times.
✓ Branch 3 taken 100200 times.
✓ Branch 4 taken 33400 times.
✓ Branch 5 taken 100200 times.
✓ Branch 6 taken 33400 times.
✓ Branch 7 taken 100200 times.
✓ Branch 8 taken 33400 times.
✓ Branch 9 taken 100200 times.
1336000 if (globalPos[1] > this->gridGeometry().bBoxMax()[1] - eps_)
98 {
99
9/10
✓ Branch 0 taken 33400 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20040 times.
✓ Branch 3 taken 13360 times.
✓ Branch 4 taken 20040 times.
✓ Branch 5 taken 13360 times.
✓ Branch 6 taken 6680 times.
✓ Branch 7 taken 13360 times.
✓ Branch 8 taken 6680 times.
✓ Branch 9 taken 13360 times.
66800 if (useWholeLength_ || (globalPos[0] > 0.4 && globalPos[0] < 0.6))
100 values.setAllDirichlet();
101 }
102
103 }
104
105 267200 return values;
106 }
107
108 /*!
109 * \brief Evaluates the boundary conditions for a Dirichlet control volume.
110 *
111 * \param globalPos The center of the finite volume which ought to be set.
112 */
113 DirichletValues dirichlet(const Element& element, const SubControlVolumeFace& scvf) const
114 {
115 29736 const auto& globalPos = scvf.ipGlobal();
116 29736 DirichletValues values(0.0);
117
118 if constexpr (!ParentType::isMomentumProblem())
119 {
120
1/2
✓ Branch 0 taken 1576 times.
✗ Branch 1 not taken.
1576 values[Indices::pressureIdx] = 1.1e+5;
121
5/10
✓ Branch 0 taken 1576 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1576 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1576 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1576 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1576 times.
✗ Branch 9 not taken.
1576 if (useWholeLength_ || (globalPos[0] > 0.4 && globalPos[0] < 0.6))
122 3152 values[Indices::conti0EqIdx + compIdx] = 1e-3;
123 }
124
125
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29736 return values;
126 }
127
128 /*!
129 * \brief Evaluates the boundary conditions for a Neumann control volume.
130 *
131 * \param element The element for which the Neumann boundary condition is set
132 * \param fvGeometry The fvGeometry
133 * \param elemVolVars The element volume variables
134 * \param elemFaceVars The element face variables
135 * \param scvf The boundary sub control volume face
136 */
137 template<class ElementVolumeVariables, class ElementFluxVariablesCache>
138 193952 BoundaryFluxes neumann(const Element& element,
139 const FVElementGeometry& fvGeometry,
140 const ElementVolumeVariables& elemVolVars,
141 const ElementFluxVariablesCache& elemFluxVarsCache,
142 const SubControlVolumeFace& scvf) const
143 {
144 193952 BoundaryFluxes values(0.0);
145
146 if constexpr (!ParentType::isMomentumProblem())
147 {
148 387904 const auto insideDensity = elemVolVars[scvf.insideScvIdx()].density();
149
150 // The resulting flux over the boundary is zero anyway (velocity is zero), but this will add some non-zero derivatives to the
151 // Jacobian and makes the BC more general.
152 581856 values[Indices::conti0EqIdx] = this->faceVelocity(element, fvGeometry, scvf) * insideDensity * scvf.unitOuterNormal();
153 }
154
155 193952 return values;
156 }
157
158 /*!
159 * \brief Evaluates the initial value for a control volume.
160 *
161 * \param globalPos The global position
162 */
163 InitialValues initialAtPos(const GlobalPosition& globalPos) const
164 {
165 3280 InitialValues values(0.0);
166
167 if constexpr (!ParentType::isMomentumProblem())
168 values[Indices::pressureIdx] = 1.1e5;
169
170 3280 return values;
171 }
172
173 void setTimeLoop(TimeLoopPtr timeLoop)
174
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 { timeLoop_ = timeLoop; }
175
176 Scalar time() const
177 { return timeLoop_->time(); }
178
179 //! Enable internal Dirichlet constraints
180 static constexpr bool enableInternalDirichletConstraints()
181 { return !ParentType::isMomentumProblem(); }
182
183 /*!
184 * \brief Tag a degree of freedom to carry internal Dirichlet constraints.
185 * If true is returned for a dof, the equation for this dof is replaced
186 * by the constraint that its primary variable values must match the
187 * user-defined values obtained from the function internalDirichlet(),
188 * which must be defined in the problem.
189 *
190 * \param element The finite element
191 * \param scv The sub-control volume
192 */
193 std::bitset<DirichletValues::dimension> hasInternalDirichletConstraint(const Element& element, const SubControlVolume& scv) const
194 {
195 1280640 std::bitset<DirichletValues::dimension> values;
196
197 // the pure Neumann problem is only defined up to a constant
198 // we create a well-posed problem by fixing the pressure at one dof
199
200 if constexpr (!ParentType::isMomentumProblem())
201 {
202
6/10
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 370968 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 116 times.
✓ Branch 5 taken 185484 times.
✓ Branch 6 taken 232 times.
✓ Branch 7 taken 723608 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
1280640 const bool isLowerLeftCell = (scv.dofIndex() == 0);
203
6/10
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 370968 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 116 times.
✓ Branch 5 taken 185484 times.
✓ Branch 6 taken 232 times.
✓ Branch 7 taken 723608 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
1280640 if (isLowerLeftCell)
204 580 values.set(0);
205 }
206
207 return values;
208 }
209
210 /*!
211 * \brief Define the values of internal Dirichlet constraints for a degree of freedom.
212 * \param element The finite element
213 * \param scv The sub-control volume
214 */
215 DirichletValues internalDirichlet(const Element& element, const SubControlVolume& scv) const
216 371200 { return DirichletValues(1.1e5); }
217
218 private:
219 bool isInlet_(const GlobalPosition& globalPos) const
220 { return globalPos[0] < eps_; }
221
222 bool isOutlet_(const GlobalPosition& globalPos) const
223 { return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; }
224
225 const Scalar eps_;
226 bool useWholeLength_;
227 TimeLoopPtr timeLoop_;
228 };
229
230 } // end namespace Dumux
231 #endif
232