GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/test/multidomain/boundary/freeflowporousmedium/1p_1p/convergence/problem_darcy.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 54 60 90.0%
Functions: 5 6 83.3%
Branches: 52 144 36.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 BoundaryTests
10 * \brief The Darcy sub-problem of coupled Stokes-Darcy convergence test
11 */
12
13 #ifndef DUMUX_DARCY_SUBPROBLEM_HH
14 #define DUMUX_DARCY_SUBPROBLEM_HH
15
16 #include <dumux/common/boundarytypes.hh>
17 #include <dumux/common/numeqvector.hh>
18 #include <dumux/common/properties.hh>
19 #include <dumux/common/parameters.hh>
20
21 #include <dumux/porousmediumflow/problem.hh>
22
23 #include "testcase.hh"
24 #include "analyticalsolutions.hh"
25
26 namespace Dumux {
27
28 /*!
29 * \ingroup BoundaryTests
30 * \brief The Darcy sub-problem of coupled Stokes-Darcy convergence test
31 */
32 template <class TypeTag>
33 class DarcySubProblem : public PorousMediumFlowProblem<TypeTag>
34 {
35 using ParentType = PorousMediumFlowProblem<TypeTag>;
36 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
37 using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
38 using NumEqVector = Dumux::NumEqVector<PrimaryVariables>;
39 using BoundaryTypes = Dumux::BoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>;
40 using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>;
41 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
42 using GridView = typename GridGeometry::GridView;
43 using FVElementGeometry = typename GridGeometry::LocalView;
44 using SubControlVolume = typename GridGeometry::SubControlVolume;
45 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
46 using Element = typename GridView::template Codim<0>::Entity;
47 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
48
49 using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>;
50
51 enum class BC {
52 dirichlet, neumann, mixed
53 };
54
55 public:
56 //! export the Indices
57 using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
58
59 12 DarcySubProblem(std::shared_ptr<const GridGeometry> gridGeometry,
60 std::shared_ptr<CouplingManager> couplingManager,
61 std::shared_ptr<typename ParentType::SpatialParams> spatialParams,
62 const DarcyStokesTestCase testCase,
63 const std::string& name)
64 : ParentType(gridGeometry, spatialParams, "Darcy")
65 , couplingManager_(couplingManager)
66
7/22
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 12 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 12 times.
✓ Branch 20 taken 12 times.
✗ Branch 21 not taken.
✗ 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 30 not taken.
✗ Branch 31 not taken.
48 , testCase_(testCase)
67 {
68
5/16
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 12 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
12 problemName_ = name + "_"
69
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
24 + getParamFromGroup<std::string>(this->paramGroup(), "Problem.Name");
70
71
1/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
12 auto bc = getParamFromGroup<std::string>(this->paramGroup(), "Problem.BoundaryConditions", "Dirichlet");
72
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 9 times.
12 if (bc == "Dirichlet")
73 3 boundaryConditions_ = BC::dirichlet;
74
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 6 times.
9 else if (bc == "Neumann")
75 3 boundaryConditions_ = BC::neumann;
76
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 else if (bc == "Mixed")
77 6 boundaryConditions_ = BC::mixed;
78 else
79 DUNE_THROW(Dune::Exception, "Wrong BC type choose: Dirichlet, Neumann or Mixed");
80
81
3/6
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 12 times.
36 std::cout << "Porous medium domain: Using " << bc << " boundary conditions" << std::endl;
82 12 }
83
84 const std::string& name() const
85
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
24 { return problemName_; }
86
87 /*!
88 * \name Boundary conditions
89 */
90 // \{
91
92 /*!
93 * \brief Specifies which kind of boundary condition should be
94 * used for which equation on a given boundary control volume.
95 *
96 * \param element The element
97 * \param scvf The boundary sub control volume face
98 */
99 76424 BoundaryTypes boundaryTypes(const Element &element, const SubControlVolumeFace &scvf) const
100 {
101 76424 BoundaryTypes values;
102
103
2/2
✓ Branch 0 taken 48144 times.
✓ Branch 1 taken 28280 times.
76424 if (couplingManager().isCoupled(CouplingManager::porousMediumIndex, CouplingManager::freeFlowMassIndex, scvf))
104 values.setAllCouplingNeumann();
105 else
106 {
107
2/2
✓ Branch 0 taken 38016 times.
✓ Branch 1 taken 10128 times.
48144 if (boundaryConditions_ == BC::dirichlet)
108 values.setAllDirichlet();
109
2/2
✓ Branch 0 taken 27888 times.
✓ Branch 1 taken 10128 times.
38016 else if (boundaryConditions_ == BC::neumann)
110 values.setAllNeumann();
111 else
112 {
113
2/2
✓ Branch 0 taken 9324 times.
✓ Branch 1 taken 18564 times.
27888 if (onLeftBoundary_(scvf.center()))
114 values.setAllNeumann();
115 else
116 values.setAllDirichlet();
117 }
118 }
119
120 76424 return values;
121 }
122
123 /*!
124 * \brief Evaluates the boundary conditions for a Dirichlet control volume.
125 *
126 * \param element The element for which the Dirichlet boundary condition is set
127 * \param scvf The boundary sub-control-volume-face
128 */
129 PrimaryVariables dirichlet(const Element &element, const SubControlVolumeFace &scvf) const
130 {
131
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19040 const auto p = fullAnalyticalSolution(scvf.center())[2];
132 9520 return PrimaryVariables(p);
133 }
134
135 /*!
136 * \brief Evaluates the boundary conditions for a Neumann control volume.
137 *
138 * \param element The element for which the Neumann boundary condition is set
139 * \param fvGeometry The fvGeometry
140 * \param elemVolVars The element volume variables
141 * \param elemFluxVarsCache Flux variables caches for all faces in stencil
142 * \param scvf The boundary sub control volume face
143 */
144 template<class ElementVolumeVariables, class ElementFluxVarsCache>
145 30932 NumEqVector neumann(const Element& element,
146 const FVElementGeometry& fvGeometry,
147 const ElementVolumeVariables& elemVolVars,
148 const ElementFluxVarsCache& elemFluxVarsCache,
149 const SubControlVolumeFace& scvf) const
150 {
151 30932 NumEqVector values(0.0);
152
153
2/2
✓ Branch 0 taken 20720 times.
✓ Branch 1 taken 10212 times.
30932 if (couplingManager().isCoupled(CouplingManager::porousMediumIndex, CouplingManager::freeFlowMassIndex, scvf))
154 41440 values[Indices::conti0EqIdx] = couplingManager().massCouplingCondition(
155 CouplingManager::porousMediumIndex, CouplingManager::freeFlowMassIndex,
156 fvGeometry, scvf, elemVolVars
157 );
158
159 else
160 {
161 20424 const auto sol = fullAnalyticalSolution(scvf.center());
162 10212 const auto n = scvf.unitOuterNormal();
163 40848 auto v = n; v[0] = sol[0]; v[1] = sol[1];
164 20424 values[Indices::conti0EqIdx] = v*n;
165 }
166
167 30932 return values;
168 }
169
170 // \}
171
172 /*!
173 * \name Volume terms
174 */
175 // \{
176 /*!
177 * \brief Evaluates the source term for all phases within a given
178 * sub control volume.
179 * \param globalPos The global position
180 */
181 751520 NumEqVector sourceAtPos(const GlobalPosition& globalPos) const
182 {
183 using namespace Solution::DarcyStokes;
184
4/5
✓ Branch 0 taken 136640 times.
✓ Branch 1 taken 136640 times.
✓ Branch 2 taken 136640 times.
✓ Branch 3 taken 341600 times.
✗ Branch 4 not taken.
751520 switch (testCase_)
185 {
186 136640 case DarcyStokesTestCase::ShiueExampleOne:
187 136640 return ShiueOne::darcyRHS(globalPos);
188 136640 case DarcyStokesTestCase::ShiueExampleTwo:
189 136640 return ShiueTwo::darcyRHS(globalPos);
190 136640 case DarcyStokesTestCase::Rybak:
191 136640 return Rybak::darcyRHS(globalPos);
192 341600 case DarcyStokesTestCase::Schneider:
193 341600 return Schneider::darcyRHS(globalPos);
194 default:
195 DUNE_THROW(Dune::InvalidStateException, "Invalid test case");
196 }
197 }
198
199 // \}
200
201 /*!
202 * \brief Evaluates the initial value for a control volume.
203 * \param element The element
204 */
205 PrimaryVariables initial(const Element &element) const
206 { return PrimaryVariables(0.0); }
207
208 /*!
209 * \brief Returns the analytical solution of the problem at a given position.
210 * \param globalPos The global position
211 * Returns vector with entries: (velocity-x | velocity-y | pressure)
212 */
213 288532 Dune::FieldVector<Scalar, 3> fullAnalyticalSolution(const GlobalPosition& globalPos) const
214 {
215 using namespace Solution::DarcyStokes;
216
4/5
✓ Branch 0 taken 70560 times.
✓ Branch 1 taken 71144 times.
✓ Branch 2 taken 72288 times.
✓ Branch 3 taken 74540 times.
✗ Branch 4 not taken.
288532 switch (testCase_)
217 {
218 70560 case DarcyStokesTestCase::ShiueExampleOne:
219 70560 return ShiueOne::darcy(globalPos);
220 71144 case DarcyStokesTestCase::ShiueExampleTwo:
221 71144 return ShiueTwo::darcy(globalPos);
222 72288 case DarcyStokesTestCase::Rybak:
223 72288 return Rybak::darcy(globalPos);
224 74540 case DarcyStokesTestCase::Schneider:
225 74540 return Schneider::darcy(globalPos);
226 default:
227 DUNE_THROW(Dune::InvalidStateException, "Invalid test case");
228 }
229 }
230
231 // \}
232
233 //! Get the coupling manager
234 const CouplingManager& couplingManager() const
235 256152 { return *couplingManager_; }
236
237 private:
238 bool onLeftBoundary_(const GlobalPosition& globalPos) const
239
10/10
✓ Branch 0 taken 9324 times.
✓ Branch 1 taken 18564 times.
✓ Branch 2 taken 9324 times.
✓ Branch 3 taken 18564 times.
✓ Branch 4 taken 9324 times.
✓ Branch 5 taken 18564 times.
✓ Branch 6 taken 9324 times.
✓ Branch 7 taken 18564 times.
✓ Branch 8 taken 9324 times.
✓ Branch 9 taken 18564 times.
139440 { return globalPos[0] < this->gridGeometry().bBoxMin()[0] + eps_; }
240
241 static constexpr Scalar eps_ = 1e-7;
242 std::shared_ptr<CouplingManager> couplingManager_;
243 std::string problemName_;
244 DarcyStokesTestCase testCase_;
245 BC boundaryConditions_;
246 };
247
248 } // end namespace Dumux
249
250 #endif
251