GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/test/freeflow/shallowwater/roughchannel/limitednikuradse/problem.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 54 58 93.1%
Functions: 5 7 71.4%
Branches: 39 60 65.0%

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 ShallowWaterTests
10 * \brief A test for the Shallow water model in a rough channel with limited
11 * Nikuradse friction.
12 */
13 #ifndef DUMUX_ROUGH_CHANNEL_TEST_PROBLEM_HH
14 #define DUMUX_ROUGH_CHANNEL_TEST_PROBLEM_HH
15
16 #include <dumux/common/boundarytypes.hh>
17 #include <dumux/common/parameters.hh>
18 #include <dumux/common/properties.hh>
19 #include <dumux/common/numeqvector.hh>
20
21 #include <dumux/freeflow/shallowwater/problem.hh>
22 #include <dumux/freeflow/shallowwater/boundaryfluxes.hh>
23
24 namespace Dumux {
25
26 /*!
27 * \ingroup ShallowWaterTests
28 * \brief A simple flow in a rough channel with friction law after Nikuradse with
29 * limiting.
30 *
31 * This is a synthetic test to check if the limiting of friction laws works.
32 * Therefore a parameter RoughnessHeight is used to ensure that the maximum
33 * calculated shear stress of the friction law is limited. An artificial water
34 * depth is added to the actual water depth if the water depth is smaller than
35 * two times the RoughnessHeight to limit the shear stress.
36 *
37 * At the left border a discharge boundary condition is applied and at the right
38 * border a water depth boundary condition. All other boundaries are set to
39 * no-flow.
40 *
41 * This problem uses the \ref ShallowWaterModel
42 */
43 template <class TypeTag>
44 class RoughChannelProblem : public ShallowWaterProblem<TypeTag>
45 {
46 using ParentType = ShallowWaterProblem<TypeTag>;
47
48 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
49 using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
50 using NumEqVector = Dumux::NumEqVector<PrimaryVariables>;
51 using BoundaryTypes = Dumux::BoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>;
52 using NeumannFluxes = NumEqVector;
53 using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
54
55 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
56 using GridView = typename GridGeometry::GridView;
57 using Element = typename GridView::template Codim<0>::Entity;
58 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
59 using FVElementGeometry = typename GridGeometry::LocalView;
60 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
61 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
62
63 using GridVariables = GetPropType<TypeTag, Properties::GridVariables>;
64 using ElementFluxVariablesCache = typename GridVariables::GridFluxVariablesCache::LocalView;
65 using ElementVolumeVariables = typename GridVariables::GridVolumeVariables::LocalView;
66
67 public:
68 1 RoughChannelProblem(std::shared_ptr<const GridGeometry> gridGeometry)
69
7/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
3 : ParentType(gridGeometry)
70 {
71
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1 name_ = getParam<std::string>("Problem.Name");
72
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 bedSlope_ = getParam<Scalar>("Problem.BedSlope");
73
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 discharge_ = getParam<Scalar>("Problem.Discharge");
74
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 hBoundary_ = getParam<Scalar>("Problem.WaterDepthOutflow");
75 1 }
76
77 /*!
78 * \brief The problem name
79 *
80 * This is used as a prefix for files generated by the simulation.
81 */
82 const std::string& name() const
83 {
84
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 return name_;
85 }
86
87 /*!
88 * \brief Evaluate the source term for all balance equations within a given
89 * sub-control-volume.
90 *
91 * This is the method for the case where the source term is
92 * potentially solution dependent and requires some quantities that
93 * are specific to the fully-implicit method.
94 *
95 * \param element The finite element
96 * \param fvGeometry The finite-volume geometry
97 * \param elemVolVars All volume variables for the element
98 * \param scv The sub control volume
99 *
100 * For this method, the values parameter stores the conserved quantity rate
101 * generated or annihilate per volume unit. Positive values mean
102 * that the conserved quantity is created, negative ones mean that it vanishes.
103 * E.g. for the mass balance that would be a mass rate in \f$ [ kg / (m^3 \cdot s)] \f$.
104 */
105 1070877 NumEqVector source(const Element& element,
106 const FVElementGeometry& fvGeometry,
107 const ElementVolumeVariables& elemVolVars,
108 const SubControlVolume &scv) const
109 {
110
111 1070877 NumEqVector source (0.0);
112 1070877 source += bottomFrictionSource(element, fvGeometry, elemVolVars, scv);
113 1070877 return source;
114 }
115
116 /*!
117 * \brief Compute the source term due to bottom friction
118 */
119 1070877 NumEqVector bottomFrictionSource(const Element& element,
120 const FVElementGeometry& fvGeometry,
121 const ElementVolumeVariables& elemVolVars,
122 const SubControlVolume &scv) const
123 {
124 1070877 NumEqVector bottomFrictionSource(0.0);
125
126 1070877 const auto& volVars = elemVolVars[scv];
127 1070877 Dune::FieldVector<Scalar, 2> bottomShearStress =
128 3212631 this->spatialParams().frictionLaw(element, scv).bottomShearStress(volVars);
129
130 2141754 bottomFrictionSource[0] = 0.0;
131 4283508 bottomFrictionSource[1] = -bottomShearStress[0] / volVars.density();
132 4283508 bottomFrictionSource[2] = -bottomShearStress[1] / volVars.density();
133
134 1070877 return bottomFrictionSource;
135 }
136
137 /*!
138 * \brief Specifies which kind of boundary condition should be
139 * used for which equation on a given boundary segment.
140 *
141 * \param globalPos The position for which the boundary type is set
142 */
143 BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
144 {
145 544701 BoundaryTypes bcTypes;
146
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 112110 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 432591 times.
544701 bcTypes.setAllNeumann();
147 return bcTypes;
148 }
149
150 /*!
151 * \brief Specifies the Neumann boundary
152 *
153 * We need the Riemann invariants to compute the values depending of the boundary type.
154 * Since we use a weak imposition we do not have a Dirichlet value. We impose fluxes
155 * based on q, h, etc. computed with the Riemann invariants
156 */
157 432591 NeumannFluxes neumann(const Element& element,
158 const FVElementGeometry& fvGeometry,
159 const ElementVolumeVariables& elemVolVars,
160 const ElementFluxVariablesCache& elemFluxVarsCache,
161 const SubControlVolumeFace& scvf) const
162 {
163 432591 NeumannFluxes values(0.0);
164
165 865182 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
166 432591 const auto& insideVolVars = elemVolVars[insideScv];
167 432591 const auto& nxy = scvf.unitOuterNormal();
168 865182 const auto gravity = this->spatialParams().gravity(scvf.center());
169 432591 const auto boundaryStateVariables = [&]() -> std::array<Scalar, 3>
170 {
171 // impose discharge at the left side
172
10/10
✓ Branch 0 taken 2106 times.
✓ Branch 1 taken 430485 times.
✓ Branch 2 taken 2106 times.
✓ Branch 3 taken 430485 times.
✓ Branch 4 taken 2106 times.
✓ Branch 5 taken 430485 times.
✓ Branch 6 taken 2106 times.
✓ Branch 7 taken 430485 times.
✓ Branch 8 taken 2106 times.
✓ Branch 9 taken 430485 times.
2162955 if (scvf.center()[0] < this->gridGeometry().bBoxMin()[0] + eps_)
173 {
174 2106 return ShallowWater::fixedDischargeBoundary(discharge_,
175 4212 insideVolVars.waterDepth(), insideVolVars.velocity(0), insideVolVars.velocity(1),
176 2106 gravity, nxy
177 2106 );
178 }
179
180 // impose water depth at the right side
181
12/12
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 428325 times.
✓ Branch 2 taken 2160 times.
✓ Branch 3 taken 428325 times.
✓ Branch 4 taken 2160 times.
✓ Branch 5 taken 428325 times.
✓ Branch 6 taken 2160 times.
✓ Branch 7 taken 428325 times.
✓ Branch 8 taken 2160 times.
✓ Branch 9 taken 428325 times.
✓ Branch 10 taken 2160 times.
✓ Branch 11 taken 428325 times.
2582910 else if (scvf.center()[0] > this->gridGeometry().bBoxMax()[0] - eps_)
182 {
183 8640 return ShallowWater::fixedWaterDepthBoundary(hBoundary_,
184 insideVolVars.waterDepth(), insideVolVars.velocity(0), insideVolVars.velocity(1),
185 gravity, nxy
186 2160 );
187 }
188
189 // no flow boundary
190 else
191 {
192 return {{
193 insideVolVars.waterDepth(),
194 856650 -insideVolVars.velocity(0),
195 856650 -insideVolVars.velocity(1)
196 1713300 }};
197 }
198
2/2
✓ Branch 1 taken 2106 times.
✓ Branch 2 taken 430485 times.
865182 }();
199
200 432591 const auto riemannFlux = ShallowWater::riemannProblem(
201 865182 insideVolVars.waterDepth(), boundaryStateVariables[0],
202 865182 insideVolVars.velocity(0), boundaryStateVariables[1],
203 865182 insideVolVars.velocity(1), boundaryStateVariables[2],
204 insideVolVars.bedSurface(), insideVolVars.bedSurface(),
205 gravity, nxy
206 );
207
208 1297773 values[Indices::massBalanceIdx] = riemannFlux[0];
209 1297773 values[Indices::velocityXIdx] = riemannFlux[1];
210 1297773 values[Indices::velocityYIdx] = riemannFlux[2];
211
212 432591 return values;
213 }
214
215 /*!
216 * \brief Evaluate the initial values for a control volume
217 */
218 PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
219 {
220 2500 PrimaryVariables values(0.0);
221
222 5000 values[0] = hBoundary_;
223 7500 values[1] = abs(discharge_)/hBoundary_ *0.9;
224 5000 values[2] = 0.0;
225
226 return values;
227 };
228
229 private:
230 Scalar hBoundary_;
231 Scalar bedSlope_;
232 Scalar discharge_; // discharge at the inflow boundary
233 static constexpr Scalar eps_ = 1.0e-6;
234 std::string name_;
235 };
236
237 } // end namespace Dumux
238
239 #endif
240