GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/multidomain/boundary/freeflowporousmedium/couplingmanager_base.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 27 35 77.1%
Functions: 2 13 15.4%
Branches: 47 115 40.9%

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 FreeFlowPorousMediumCoupling
10 * \brief Base class for coupling freeflow and porous medium flow models.
11 */
12
13 #ifndef DUMUX_MULTIDOMAIN_BOUNDARY_FREEFLOW_POROUSMEDIUM_COUPLINGMANAGER_BASE_HH
14 #define DUMUX_MULTIDOMAIN_BOUNDARY_FREEFLOW_POROUSMEDIUM_COUPLINGMANAGER_BASE_HH
15
16 #include <utility>
17 #include <memory>
18
19 #include <dune/common/indices.hh>
20 #include <dumux/common/properties.hh>
21 #include <dumux/multidomain/boundary/freeflowporousmedium/ffmasspm/couplingmanager.hh>
22 #include <dumux/multidomain/boundary/freeflowporousmedium/ffmomentumpm/couplingmanager.hh>
23 #include <dumux/multidomain/freeflow/couplingmanager.hh>
24 #include <dumux/multidomain/multibinarycouplingmanager.hh>
25
26 namespace Dumux {
27
28 #ifndef DOXYGEN
29 namespace FreeFlowPorousMediumDetail {
30
31 // global subdomain indices
32 static constexpr auto freeFlowMomentumIndex = Dune::index_constant<0>();
33 static constexpr auto freeFlowMassIndex = Dune::index_constant<1>();
34 static constexpr auto porousMediumIndex = Dune::index_constant<2>();
35
36 // coupling indices
37 static constexpr auto freeFlowMassToFreeFlowMomentumIndex = Dune::index_constant<0>();
38 static constexpr auto freeFlowMomentumToPorousMediumIndex = Dune::index_constant<1>();
39 static constexpr auto freeFlowMassToPorousMediumIndex = Dune::index_constant<2>();
40 static constexpr auto noCouplingIdx = Dune::index_constant<99>();
41
42 constexpr auto makeCouplingManagerMap()
43 {
44 auto map = std::array<std::array<std::size_t, 3>, 3>{};
45
46 // free flow (momentum-mass)
47 map[freeFlowMomentumIndex][freeFlowMassIndex] = freeFlowMassToFreeFlowMomentumIndex;
48 map[freeFlowMassIndex][freeFlowMomentumIndex] = freeFlowMassToFreeFlowMomentumIndex;
49
50 // free flow momentum - porous medium
51 map[freeFlowMomentumIndex][porousMediumIndex] = freeFlowMomentumToPorousMediumIndex;
52 map[porousMediumIndex][freeFlowMomentumIndex] = freeFlowMomentumToPorousMediumIndex;
53
54 // free flow mass - porous medium
55 map[freeFlowMassIndex][porousMediumIndex] = freeFlowMassToPorousMediumIndex;
56 map[porousMediumIndex][freeFlowMassIndex] = freeFlowMassToPorousMediumIndex;
57
58 return map;
59 }
60
61 template<std::size_t i>
62 constexpr auto coupledDomains(Dune::index_constant<i> domainI)
63 {
64 if constexpr (i == freeFlowMomentumIndex)
65 27002800 return std::make_tuple(freeFlowMassIndex, porousMediumIndex);
66 else if constexpr (i == freeFlowMassIndex)
67 7065440 return std::make_tuple(freeFlowMomentumIndex, porousMediumIndex);
68 else // i == porousMediumIndex
69 1126240 return std::make_tuple(freeFlowMomentumIndex, freeFlowMassIndex);
70 }
71
72 template<std::size_t i, std::size_t j>
73 constexpr auto globalToLocalDomainIndices(Dune::index_constant<i>, Dune::index_constant<j>)
74 {
75 static_assert(i <= 2 && j <= 2);
76 static_assert(i != j);
77
78 if constexpr (i < j)
79 return std::pair<Dune::index_constant<0>, Dune::index_constant<1>>{};
80 else
81 return std::pair<Dune::index_constant<1>, Dune::index_constant<0>>{};
82 }
83
84 struct CouplingMaps
85 {
86 static constexpr auto managerMap()
87 {
88 return FreeFlowPorousMediumDetail::makeCouplingManagerMap();
89 }
90
91 template<std::size_t i, std::size_t j>
92 static constexpr auto globalToLocal(Dune::index_constant<i> domainI, Dune::index_constant<j> domainJ)
93 {
94 return FreeFlowPorousMediumDetail::globalToLocalDomainIndices(domainI, domainJ);
95 }
96
97 template<std::size_t i>
98 static constexpr auto coupledDomains(Dune::index_constant<i> domainI)
99 {
100
2/12
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 21 taken 371200 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 371200 times.
✗ Branch 26 not taken.
35194480 return FreeFlowPorousMediumDetail::coupledDomains(domainI);
101 }
102 };
103
104 template<class MDTraits>
105 struct CouplingManagers
106 {
107 template<std::size_t id>
108 using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
109
110 using FreeFlowTraits = MultiDomainTraits<
111 SubDomainTypeTag<freeFlowMomentumIndex>, SubDomainTypeTag<freeFlowMassIndex>
112 >;
113
114 using FreeFlowMomentumPorousMediumTraits = MultiDomainTraits<
115 SubDomainTypeTag<freeFlowMomentumIndex>, SubDomainTypeTag<porousMediumIndex>
116 >;
117
118 using FreeFlowMassPorousMediumTraits = MultiDomainTraits<
119 SubDomainTypeTag<freeFlowMassIndex>, SubDomainTypeTag<porousMediumIndex>
120 >;
121
122 using FreeFlowCouplingManager
123 = Dumux::FreeFlowCouplingManager<FreeFlowTraits>;
124 using FreeFlowMomentumPorousMediumCouplingManager
125 = Dumux::FreeFlowMomentumPorousMediumCouplingManager<FreeFlowMomentumPorousMediumTraits>;
126 using FreeFlowMassPorousMediumCouplingManager
127 = Dumux::FreeFlowMassPorousMediumCouplingManager<FreeFlowMassPorousMediumTraits>;
128 };
129
130 } // end namespace FreeFlowPorousMediumDetail
131 #endif // DOXYGEN
132
133 /*!
134 * \ingroup FreeFlowPorousMediumCoupling
135 * \brief Base coupling manager for coupling freeflow and porous medium flow models
136 */
137 template<class MDTraits>
138
1/4
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
28 class FreeFlowPorousMediumCouplingManagerBase
139 : public MultiBinaryCouplingManager<
140 MDTraits,
141 FreeFlowPorousMediumDetail::CouplingMaps,
142 typename FreeFlowPorousMediumDetail::CouplingManagers<MDTraits>::FreeFlowCouplingManager,
143 typename FreeFlowPorousMediumDetail::CouplingManagers<MDTraits>::FreeFlowMomentumPorousMediumCouplingManager,
144 typename FreeFlowPorousMediumDetail::CouplingManagers<MDTraits>::FreeFlowMassPorousMediumCouplingManager
145 >
146 {
147 using ParentType = MultiBinaryCouplingManager<
148 MDTraits,
149 FreeFlowPorousMediumDetail::CouplingMaps,
150 typename FreeFlowPorousMediumDetail::CouplingManagers<MDTraits>::FreeFlowCouplingManager,
151 typename FreeFlowPorousMediumDetail::CouplingManagers<MDTraits>::FreeFlowMomentumPorousMediumCouplingManager,
152 typename FreeFlowPorousMediumDetail::CouplingManagers<MDTraits>::FreeFlowMassPorousMediumCouplingManager
153 >;
154
155 using Scalar = typename MDTraits::Scalar;
156
157 // the sub domain type tags
158 template<std::size_t id>
159 using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
160
161 template<std::size_t id> using Problem = GetPropType<SubDomainTypeTag<id>, Properties::Problem>;
162 template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
163 template<std::size_t id> using FVElementGeometry = typename GridGeometry<id>::LocalView;
164 template<std::size_t id> using SubControlVolumeFace = typename FVElementGeometry<id>::SubControlVolumeFace;
165 template<std::size_t id> using SubControlVolume = typename FVElementGeometry<id>::SubControlVolume;
166 template<std::size_t id> using ElementVolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::LocalView;
167 template<std::size_t id> using NumEqVector = typename Problem<id>::Traits::NumEqVector;
168
169 template<std::size_t id> using GridView = typename GridGeometry<id>::GridView;
170 template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity;
171 using SolutionVector = typename MDTraits::SolutionVector;
172
173 public:
174
175 template<std::size_t i, std::size_t j>
176 using SubCouplingManager = typename ParentType::template SubCouplingManager<i, j>;
177
178 static constexpr auto freeFlowMomentumIndex = FreeFlowPorousMediumDetail::freeFlowMomentumIndex;
179 static constexpr auto freeFlowMassIndex = FreeFlowPorousMediumDetail::freeFlowMassIndex;
180 static constexpr auto porousMediumIndex = FreeFlowPorousMediumDetail::porousMediumIndex;
181
182 public:
183 using ParentType::ParentType;
184
185 template<class GridVarsTuple>
186 14 void init(std::shared_ptr<Problem<freeFlowMomentumIndex>> freeFlowMomentumProblem,
187 std::shared_ptr<Problem<freeFlowMassIndex>> freeFlowMassProblem,
188 std::shared_ptr<Problem<porousMediumIndex>> porousMediumProblem,
189 GridVarsTuple&& gridVarsTuple,
190 const SolutionVector& curSol)
191 {
192 14 this->updateSolution(curSol); // generic coupling manager stores tuple of shared_ptr
193
194 // initialize the binary sub coupling managers
195 42 typename SubCouplingManager<freeFlowMomentumIndex, freeFlowMassIndex>::SolutionVectorStorage ffSolVecTuple;
196 56 std::get<0>(ffSolVecTuple) = std::get<freeFlowMomentumIndex>(this->curSol());
197 56 std::get<1>(ffSolVecTuple) = std::get<freeFlowMassIndex>(this->curSol());
198
3/10
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
56 this->subCouplingManager(freeFlowMomentumIndex, freeFlowMassIndex).init(
199 freeFlowMomentumProblem, freeFlowMassProblem,
200 42 std::make_tuple(std::get<freeFlowMomentumIndex>(gridVarsTuple), std::get<freeFlowMassIndex>(gridVarsTuple)),
201 ffSolVecTuple
202 );
203
204 14 typename SubCouplingManager<freeFlowMassIndex, porousMediumIndex>::SolutionVectorStorage ffMassPmSolVecTuple;
205 56 std::get<0>(ffMassPmSolVecTuple) = std::get<freeFlowMassIndex>(this->curSol());
206 56 std::get<1>(ffMassPmSolVecTuple) = std::get<porousMediumIndex>(this->curSol());
207
3/10
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
42 this->subCouplingManager(freeFlowMassIndex, porousMediumIndex).init(
208 freeFlowMassProblem, porousMediumProblem, ffMassPmSolVecTuple
209 );
210
211 14 typename SubCouplingManager<freeFlowMomentumIndex, porousMediumIndex>::SolutionVectorStorage ffMomentumPmSolVecTuple;
212 56 std::get<0>(ffMomentumPmSolVecTuple) = std::get<freeFlowMomentumIndex>(this->curSol());
213 56 std::get<1>(ffMomentumPmSolVecTuple) = std::get<porousMediumIndex>(this->curSol());
214
3/10
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
56 this->subCouplingManager(freeFlowMomentumIndex, porousMediumIndex).init(
215 freeFlowMomentumProblem, porousMediumProblem, ffMomentumPmSolVecTuple
216 );
217 14 }
218
219 template<std::size_t i>
220 const Problem<i>& problem(Dune::index_constant<i> domainI) const
221 {
222 return this->subApply(domainI, [&](const auto& cm, auto&& ii) -> const auto& {
223
1/8
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 143704 times.
143704 return cm.problem(ii);
224
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 143704 times.
143704 });
225 }
226
227 template<std::size_t i, std::size_t j>
228 bool isCoupled(Dune::index_constant<i> domainI,
229 Dune::index_constant<j> domainJ,
230 const SubControlVolumeFace<i>& scvf) const
231 {
232 return this->subApply(domainI, domainJ, [&](const auto& cm, auto&& ii, auto&& jj){
233
10/22
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 20720 times.
✓ Branch 9 taken 10212 times.
✓ Branch 11 taken 37920 times.
✓ Branch 12 taken 94948 times.
✓ Branch 14 taken 48824 times.
✓ Branch 15 taken 29392 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 23 taken 600 times.
✓ Branch 24 taken 1568 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 600 times.
✓ Branch 27 taken 1568 times.
811692 return cm.isCoupled(ii, scvf);
234
19/25
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 4 taken 178640 times.
✓ Branch 5 taken 174388 times.
✓ Branch 7 taken 73128 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 66968 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 960 times.
✓ Branch 13 taken 23136 times.
✓ Branch 14 taken 10212 times.
✓ Branch 15 taken 680 times.
✓ Branch 16 taken 38072 times.
✓ Branch 17 taken 92532 times.
✓ Branch 18 taken 600 times.
✓ Branch 19 taken 49712 times.
✓ Branch 20 taken 28280 times.
✓ Branch 21 taken 600 times.
✓ Branch 22 taken 1568 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 726 times.
✓ Branch 25 taken 240 times.
✓ Branch 27 taken 17931 times.
✓ Branch 28 taken 53319 times.
811692 });
235 }
236
237 /*!
238 * \brief If the boundary entity is on a coupling boundary
239 * \param domainI the domain index of domain i for which to compute the flux
240 * \param domainJ the domain index of domain j for which to compute the flux
241 * \param scv the sub control volume
242 */
243 template<std::size_t i, std::size_t j>
244 bool isCoupled(Dune::index_constant<i> domainI,
245 Dune::index_constant<j> domainJ,
246 const SubControlVolume<i>& scv) const
247 {
248 return this->subApply(domainI, domainJ, [&](const auto& cm, auto&& ii, auto&& jj){
249 return cm.isCoupled(ii, scv);
250 });
251 }
252
253 using ParentType::couplingStencil;
254 /*!
255 * \brief returns an iterable container of all indices of degrees of freedom of domain j
256 * that couple with / influence the residual of the given sub-control volume of domain i
257 *
258 * \param domainI the domain index of domain i
259 * \param elementI the coupled element of domain í
260 * \param scvI the sub-control volume of domain i
261 * \param domainJ the domain index of domain j
262 */
263 template<std::size_t j>
264 const auto& couplingStencil(Dune::index_constant<freeFlowMomentumIndex> domainI,
265 const Element<freeFlowMomentumIndex>& elementI,
266 const SubControlVolume<freeFlowMomentumIndex>& scvI,
267 Dune::index_constant<j> domainJ) const
268 {
269 static_assert(freeFlowMomentumIndex != j);
270 return this->subApply(domainI, domainJ, [&](const auto& cm, auto&& ii, auto&& jj) -> const auto& {
271
2/6
✓ Branch 1 taken 1484800 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 540800 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
6076800 return cm.couplingStencil(ii, elementI, scvI, jj);
272
2/4
✓ Branch 1 taken 1484800 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 540800 times.
✗ Branch 5 not taken.
6076800 });
273 }
274 };
275
276 } // end namespace Dumux
277
278 #endif
279