GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/multidomain/multibinarycouplingmanager.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 34 59 57.6%
Functions: 14 229 6.1%
Branches: 209 764 27.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-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 MultiDomain
10 * \copydoc Dumux::MultiBinaryCouplingManager
11 */
12
13 #ifndef DUMUX_MULTIDOMAIN_MULTIBINARY_COUPLINGMANAGER_HH
14 #define DUMUX_MULTIDOMAIN_MULTIBINARY_COUPLINGMANAGER_HH
15
16 #include <utility>
17 #include <memory>
18 #include <dune/common/hybridutilities.hh>
19 #include <dumux/common/properties.hh>
20 #include <dumux/multidomain/traits.hh>
21
22 namespace Dumux {
23
24 namespace Detail {
25
26 template <std::size_t, typename Tuple>
27 struct HasIndex;
28
29 template <std::size_t i, typename... Indices>
30 struct HasIndex<i, std::tuple<Indices...>>
31 : std::disjunction<std::is_same<Dune::index_constant<i>, Indices>...>
32 {};
33
34 } // end namespace Detail
35
36 /*!
37 * \ingroup MultiDomain
38 * \brief Coupling manager that combines an arbitrary number of binary coupling manager (coupling two domains each)
39 * \tparam MDTraits the multidomain traits
40 * \tparam CouplingMap a coupling policy class
41 * \tparam CouplingMgrs the binary sub-coupling manager types
42 *
43 * The coupling policy has to provide the interfaces
44 * - CouplingMap::coupledDomains(i): returns a tuple of Dune::index_constants with the coupled domains
45 * - CouplingMap::globalToLocal(i, j): maps the indices i, j to the local index pair of the responsible sub coupling manager
46 * - CouplingMap::managerMap(): returns a two-dimensional array mapping two indices to the coupling manager index
47 */
48 template<class MDTraits, class CouplingMap, class ...CouplingMgrs>
49 class MultiBinaryCouplingManager
50 {
51 // the sub domain type tags
52 template<std::size_t id>
53 using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
54
55 template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
56 template<std::size_t id> using GridView = typename GridGeometry<id>::GridView;
57 template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity;
58 template<std::size_t id> using FVElementGeometry = typename GridGeometry<id>::LocalView;
59 template<std::size_t id> using SubControlVolumeFace = typename FVElementGeometry<id>::SubControlVolumeFace;
60 template<std::size_t id> using SubControlVolume = typename FVElementGeometry<id>::SubControlVolume;
61 using CouplingStencil = std::vector<std::size_t>;
62
63 template<std::size_t id>
64 using SubCouplingManagerT = typename std::tuple_element_t<id, std::tuple<CouplingMgrs...>>;
65
66 using CMIndices = std::make_index_sequence<sizeof...(CouplingMgrs)>;
67 using CouplingManagers = typename Detail::MultiDomainTupleSharedPtr<SubCouplingManagerT, CMIndices>::type;
68
69 template<std::size_t id>
70 using SubSolutionVector = std::decay_t<decltype(std::declval<typename MDTraits::SolutionVector>()[Dune::index_constant<id>()])>;
71 using SolutionVectors = typename MDTraits::template TupleOfSharedPtr<SubSolutionVector>;
72
73 static constexpr auto couplingManagerMap_ = CouplingMap::managerMap();
74
75 //! Returns the local domain indices used within the binary sub coupling managers.
76 template<std::size_t i, std::size_t j>
77 static constexpr auto globalToLocal_(Dune::index_constant<i> domainI, Dune::index_constant<j> domainJ)
78 {
79 static_assert(i <= MDTraits::numSubDomains && j <= MDTraits::numSubDomains);
80 return CouplingMap::globalToLocal(domainI, domainJ);
81 }
82
83 //! If two domain are coupled
84 template<class Map, std::size_t i, std::size_t j>
85 static constexpr bool isCoupled_(Dune::index_constant<i> domainI, Dune::index_constant<j>)
86 { return Detail::HasIndex<j, std::decay_t<decltype(Map::coupledDomains(domainI))>>::value; }
87
88 //! Returns the coupling manager index for a given domain combination
89 template<std::size_t i, std::size_t j>
90 static constexpr auto subCouplingManagerIndex_(Dune::index_constant<i> domainI, Dune::index_constant<j> domainJ)
91 {
92 static_assert(
93 isCoupled_<CouplingMap>(domainI, domainJ),
94 "Sub-coupling manager only exists for coupled domains."
95 );
96 return couplingManagerMap_[i][j];
97 }
98
99 public:
100 template<std::size_t i, std::size_t j>
101 using SubCouplingManager = SubCouplingManagerT<couplingManagerMap_[i][j]>;
102
103 16 MultiBinaryCouplingManager()
104 48 {
105 using namespace Dune::Hybrid;
106
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
112 forEach(couplingManagers_, [&](auto&& couplingManager)
107 {
108
6/24
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 16 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 16 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 16 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
48 couplingManager = std::make_shared<typename std::decay_t<decltype(couplingManager)>::element_type>();
109 });
110
111
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
112 forEach(solutionVectors_, [&](auto&& solutionVector)
112 {
113
2/8
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
48 solutionVector = std::make_shared<typename std::decay_t<decltype(solutionVector)>::element_type>();
114 });
115 16 }
116
117 //! return the binary sub-coupling manager
118 template<std::size_t i, std::size_t j>
119 auto& subCouplingManager(Dune::index_constant<i> domainI,
120 Dune::index_constant<j> domainJ)
121 {
122 74998254 constexpr auto idx = subCouplingManagerIndex_(domainI, domainJ);
123
10/147
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 34 taken 3160 times.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✓ Branch 40 taken 1484833 times.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✓ Branch 44 taken 33 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 3193 times.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✓ Branch 50 taken 33 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 3193 times.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✓ Branch 60 taken 330 times.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✓ Branch 66 taken 3864 times.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✓ Branch 70 taken 3160 times.
✗ Branch 71 not taken.
✓ Branch 72 taken 33 times.
✗ Branch 73 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✗ Branch 148 not taken.
✗ Branch 149 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
71988498 return *std::get<idx>(couplingManagers_);
124 }
125
126 //! return the binary sub-coupling manager
127 template<std::size_t i, std::size_t j>
128 const auto& subCouplingManager(Dune::index_constant<i> domainI,
129 Dune::index_constant<j> domainJ) const
130 {
131 119454921 constexpr auto idx = subCouplingManagerIndex_(domainI, domainJ);
132
63/196
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 33 taken 3606 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 147310 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 3606 times.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 87 not taken.
✓ Branch 88 taken 33 times.
✓ Branch 90 taken 2 times.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✓ Branch 93 taken 33 times.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 99 not taken.
✓ Branch 100 taken 33 times.
✓ Branch 102 taken 2 times.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✓ Branch 105 taken 33 times.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✓ Branch 109 taken 1478400 times.
✗ Branch 110 not taken.
✓ Branch 111 taken 3864 times.
✓ Branch 112 taken 3080 times.
✗ Branch 113 not taken.
✓ Branch 114 taken 330 times.
✓ Branch 115 taken 6412 times.
✗ Branch 116 not taken.
✓ Branch 117 taken 2 times.
✓ Branch 118 taken 80 times.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✓ Branch 121 taken 2 times.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✓ Branch 125 taken 1478400 times.
✗ Branch 126 not taken.
✓ Branch 127 taken 3864 times.
✓ Branch 128 taken 12 times.
✗ Branch 129 not taken.
✓ Branch 130 taken 2 times.
✓ Branch 131 taken 6400 times.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✓ Branch 134 taken 2 times.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✓ Branch 139 taken 3080 times.
✗ Branch 140 not taken.
✗ Branch 141 not taken.
✓ Branch 142 taken 12 times.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✓ Branch 145 taken 80 times.
✗ Branch 146 not taken.
✓ Branch 147 taken 33 times.
✓ Branch 148 taken 2 times.
✗ Branch 149 not taken.
✓ Branch 150 taken 2 times.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✓ Branch 159 taken 3080 times.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✓ Branch 162 taken 12 times.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✓ Branch 165 taken 80 times.
✗ Branch 166 not taken.
✓ Branch 167 taken 3864 times.
✓ Branch 168 taken 2 times.
✗ Branch 169 not taken.
✓ Branch 170 taken 2 times.
✗ Branch 171 not taken.
✗ Branch 172 not taken.
✓ Branch 173 taken 3080 times.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✓ Branch 176 taken 12 times.
✗ Branch 177 not taken.
✓ Branch 179 taken 80 times.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✓ Branch 182 taken 2 times.
✗ Branch 183 not taken.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✓ Branch 189 taken 11 times.
✗ Branch 190 not taken.
✗ Branch 192 not taken.
✓ Branch 193 taken 1478400 times.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✓ Branch 196 taken 12 times.
✗ Branch 197 not taken.
✓ Branch 198 taken 11 times.
✓ Branch 199 taken 6400 times.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✓ Branch 202 taken 2 times.
✗ Branch 203 not taken.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✓ Branch 207 taken 408 times.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✓ Branch 212 taken 134400 times.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✗ Branch 215 not taken.
✗ Branch 216 not taken.
✓ Branch 218 taken 800 times.
✓ Branch 219 taken 1632 times.
✗ Branch 220 not taken.
✓ Branch 221 taken 134400 times.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✗ Branch 226 not taken.
✓ Branch 227 taken 800 times.
✗ Branch 228 not taken.
✓ Branch 230 taken 134400 times.
✗ Branch 231 not taken.
✗ Branch 233 not taken.
✗ Branch 234 not taken.
✓ Branch 236 taken 800 times.
✗ Branch 237 not taken.
✗ Branch 239 not taken.
✗ Branch 240 not taken.
✓ Branch 242 taken 537600 times.
✓ Branch 243 taken 168 times.
✓ Branch 244 taken 262 times.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✓ Branch 247 taken 168 times.
✓ Branch 248 taken 3200 times.
✓ Branch 249 taken 648 times.
✗ Branch 250 not taken.
✗ Branch 251 not taken.
✓ Branch 252 taken 648 times.
✗ Branch 253 not taken.
✗ Branch 254 not taken.
✓ Branch 255 taken 648 times.
✗ Branch 256 not taken.
✗ Branch 257 not taken.
✗ Branch 258 not taken.
✗ Branch 260 not taken.
✗ Branch 261 not taken.
✓ Branch 262 taken 14 times.
✓ Branch 263 taken 44 times.
✗ Branch 264 not taken.
✗ Branch 266 not taken.
✗ Branch 267 not taken.
331977399 return *std::get<idx>(couplingManagers_);
133 }
134
135 //! apply a function to the domainI-domainJ sub coupling manager using its local indices
136 template<std::size_t i, std::size_t j, class Apply>
137 decltype(auto) subApply(Dune::index_constant<i> domainI,
138 Dune::index_constant<j> domainJ,
139 Apply&& apply)
140 {
141 constexpr auto localIndices = globalToLocal_(domainI, domainJ);
142
8/36
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 19 taken 3160 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 33 times.
✓ Branch 23 taken 1484800 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 3160 times.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✓ Branch 31 taken 3490 times.
✗ Branch 32 not taken.
✓ Branch 35 taken 3864 times.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✓ Branch 39 taken 33 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 3160 times.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
5291838 return apply(subCouplingManager(domainI, domainJ), localIndices.first, localIndices.second);
143 }
144
145 //! apply a function to the domainI-domainJ sub coupling manager using its local indices
146 template<std::size_t i, std::size_t j, class Apply>
147 decltype(auto) subApply(Dune::index_constant<i> domainI,
148 Dune::index_constant<j> domainJ,
149 const Apply& apply) const
150 {
151 constexpr auto localIndices = globalToLocal_(domainI, domainJ);
152
48/72
✗ 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 taken 183131 times.
✓ Branch 7 taken 177449 times.
✓ Branch 9 taken 3864 times.
✓ Branch 10 taken 73128 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3864 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 66968 times.
✓ Branch 15 taken 1632 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 1632 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 24 taken 20720 times.
✓ Branch 25 taken 10212 times.
✓ Branch 27 taken 960 times.
✓ Branch 28 taken 2416 times.
✓ Branch 30 taken 405 times.
✓ Branch 31 taken 40111 times.
✓ Branch 32 taken 92532 times.
✓ Branch 34 taken 905 times.
✓ Branch 35 taken 2882 times.
✓ Branch 37 taken 6400 times.
✓ Branch 38 taken 48432 times.
✓ Branch 39 taken 30689 times.
✓ Branch 40 taken 6568 times.
✓ Branch 41 taken 1478662 times.
✓ Branch 42 taken 168 times.
✓ Branch 43 taken 3462 times.
✓ Branch 44 taken 1478568 times.
✓ Branch 45 taken 262 times.
✓ Branch 46 taken 3200 times.
✓ Branch 47 taken 537600 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 168 times.
✓ Branch 50 taken 537600 times.
✓ Branch 51 taken 168 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 168 times.
✓ Branch 54 taken 14 times.
✓ Branch 55 taken 44 times.
✓ Branch 56 taken 14 times.
✓ Branch 57 taken 44 times.
✓ Branch 58 taken 14 times.
✓ Branch 59 taken 44 times.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✓ Branch 64 taken 95 times.
✓ Branch 65 taken 865 times.
✗ Branch 66 not taken.
✓ Branch 68 taken 726 times.
✓ Branch 69 taken 2662 times.
✗ Branch 71 not taken.
✓ Branch 72 taken 600 times.
✓ Branch 73 taken 1568 times.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✓ Branch 76 taken 726 times.
✓ Branch 77 taken 240 times.
✓ Branch 80 taken 17931 times.
✓ Branch 81 taken 53319 times.
11934944 return apply(subCouplingManager(domainI, domainJ), localIndices.first, localIndices.second);
153 }
154
155 //! apply a function to a sub coupling manager containing this domain
156 template<std::size_t i, class Apply>
157 decltype(auto) subApply(Dune::index_constant<i> domainI, Apply&& apply)
158 {
159 constexpr auto dm = CouplingMap::coupledDomains(domainI);
160 static_assert(std::tuple_size_v<std::decay_t<decltype(dm)>> != 0, "subApply on uncoupled domain!");
161 constexpr auto domainJ = std::get<0>(dm);
162 constexpr auto localIndices = globalToLocal_(domainI, domainJ);
163 return apply(subCouplingManager(domainI, domainJ), localIndices.first);
164 }
165
166 //! apply a function to a sub coupling manager containing this domain
167 template<std::size_t i, class Apply>
168 decltype(auto) subApply(Dune::index_constant<i> domainI, const Apply& apply) const
169 {
170 constexpr auto dm = CouplingMap::coupledDomains(domainI);
171 static_assert(std::tuple_size_v<std::decay_t<decltype(dm)>> != 0, "subApply on uncoupled domain!");
172 constexpr auto domainJ = std::get<0>(dm);
173 constexpr auto localIndices = globalToLocal_(domainI, domainJ);
174
2/8
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 143704 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 143704 times.
287432 return apply(subCouplingManager(domainI, domainJ), localIndices.first);
175 }
176
177 //! Update the solution vector before assembly
178 void updateSolution(const typename MDTraits::SolutionVector& curSol)
179 {
180 using namespace Dune::Hybrid;
181 142 forEach(integralRange(Dune::Hybrid::size(solutionVectors_)), [&](const auto id)
182 {
183 *std::get<id>(solutionVectors_) = curSol[id];
184 });
185 }
186
187 /*!
188 * \brief extend the jacobian pattern of the diagonal block of domain i
189 * by those entries that are not already in the uncoupled pattern
190 * \note per default we do not add such additional dependencies
191 * \note Such additional dependencies can arise from the coupling, e.g. if a coupling source
192 * term depends on a non-local average of a quantity of the same domain
193 * \warning if you overload this also implement evalAdditionalDomainDerivatives
194 */
195 template<std::size_t id, class JacobianPattern>
196 void extendJacobianPattern(Dune::index_constant<id> domainI, JacobianPattern& pattern) const
197 {}
198
199 /*!
200 * \brief Return the coupling element stencil for a given bulk domain element
201 */
202 template<std::size_t i, class Entity, std::size_t j>
203 const auto& couplingStencil(Dune::index_constant<i> domainI,
204 const Entity& entity,
205 Dune::index_constant<j> domainJ) const
206 {
207 // if the domains are coupled according to the map, forward to sub-coupling manager
208 if constexpr (isCoupled_<CouplingMap>(domainI, domainJ))
209 return subApply(domainI, domainJ, [&](const auto& cm, auto&& ii, auto&& jj) -> const auto& {
210
3/14
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 5 taken 135211 times.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 11 taken 135211 times.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 17 taken 135608 times.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2028416 return cm.couplingStencil(ii, entity, jj);
211
5/11
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 135200 times.
✓ Branch 8 taken 11 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 135608 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 135200 times.
✗ Branch 16 not taken.
2028416 });
212 else
213 return emptyStencil_;
214 }
215
216 // ! evaluate coupling residual for the derivative low dim DOF with respect to bulk DOF
217 // ! we only need to evaluate the part of the residual that will be influence by the bulk DOF
218 template<std::size_t i, class LocalAssemblerI, std::size_t j>
219 decltype(auto) evalCouplingResidual(Dune::index_constant<i> domainI,
220 const SubControlVolumeFace<i>& scvfI,
221 const LocalAssemblerI& localAssemblerI,
222 Dune::index_constant<j> domainJ,
223 std::size_t dofIdxGlobalJ) const
224 {
225 if constexpr (i == j || isCoupled_<CouplingMap>(domainI, domainJ))
226 return subApply(domainI, domainJ, [&](const auto& cm, auto&& ii, auto&& jj) -> decltype(auto) {
227 return cm.evalCouplingResidual(ii, scvfI, localAssemblerI, jj, dofIdxGlobalJ);
228 });
229 else
230 {
231 DUNE_THROW(Dune::InvalidStateException,
232 "Calling evalCouplingResidual for uncoupled domains " << i << " and " << j
233 );
234 return localAssemblerI.evalLocalResidual();
235 }
236 }
237
238 //! evaluate coupling residual for the derivative low dim DOF with respect to bulk DOF
239 //! we only need to evaluate the part of the residual that will be influence by the bulk DOF
240 template<std::size_t i, class LocalAssemblerI, std::size_t j>
241 decltype(auto) evalCouplingResidual(Dune::index_constant<i> domainI,
242 const LocalAssemblerI& localAssemblerI,
243 Dune::index_constant<j> domainJ,
244 std::size_t dofIdxGlobalJ) const
245 {
246 if constexpr (i == j || isCoupled_<CouplingMap>(domainI, domainJ))
247 return subApply(domainI, domainJ, [&](const auto& cm, auto&& ii, auto&& jj) -> decltype(auto) {
248 return cm.evalCouplingResidual(ii, localAssemblerI, jj, dofIdxGlobalJ);
249
18/42
✗ Branch 0 not taken.
✓ Branch 1 taken 3193 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 3160 times.
✓ Branch 5 taken 33 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 33 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 33 times.
✓ Branch 12 taken 3160 times.
✓ Branch 13 taken 33 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 3193 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 33 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 33 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 3160 times.
✓ Branch 24 taken 33 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 3160 times.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 3864 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 1484800 times.
✓ Branch 35 taken 3864 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 1484800 times.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
5993038 });
250 else
251 {
252 DUNE_THROW(Dune::InvalidStateException,
253 "Calling evalCouplingResidual for uncoupled domains " << i << " and " << j
254 );
255 return localAssemblerI.evalLocalResidual();
256 }
257 }
258
259 //! evaluate coupling residual for the derivative low dim DOF with respect to bulk DOF
260 //! we only need to evaluate the part of the residual that will be influence by the bulk DOF
261 template<std::size_t i, class LocalAssemblerI, std::size_t j>
262 decltype(auto) evalCouplingResidual(Dune::index_constant<i> domainI,
263 const LocalAssemblerI& localAssemblerI,
264 const SubControlVolume<i>& scvI,
265 Dune::index_constant<j> domainJ,
266 std::size_t dofIdxGlobalJ) const
267 {
268 if constexpr (i == j || isCoupled_<CouplingMap>(domainI, domainJ))
269 return subApply(domainI, domainJ, [&](const auto& cm, auto&& ii, auto&& jj) -> decltype(auto) {
270
1/2
✓ Branch 1 taken 1488664 times.
✗ Branch 2 not taken.
2977328 return cm.evalCouplingResidual(ii, localAssemblerI, scvI, jj, dofIdxGlobalJ);
271
3/10
✓ Branch 1 taken 3490 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3490 times.
✗ Branch 5 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 12 taken 1488664 times.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2991288 });
272 else
273 {
274 DUNE_THROW(Dune::InvalidStateException,
275 "Calling evalCouplingResidual for uncoupled domains " << i << " and " << j
276 );
277 return localAssemblerI.evalLocalResidual();
278 }
279 }
280
281 /*!
282 * \brief Update the coupling context for the bulk face residual w.r.t to the lowDim dofs
283 */
284 template<std::size_t i, class LocalAssemblerI, std::size_t j, class PrimaryVariables>
285 void updateCouplingContext(Dune::index_constant<i> domainI,
286 const LocalAssemblerI& localAssemblerI,
287 Dune::index_constant<j> domainJ,
288 const std::size_t dofIdxGlobalJ,
289 const PrimaryVariables& priVars,
290 int pvIdxJ)
291 {
292 // only one other manager needs to take action if i != j
293 if constexpr (i != j)
294 {
295 if constexpr (isCoupled_<CouplingMap>(domainI, domainJ))
296
7/14
✓ Branch 1 taken 3193 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 33 times.
✓ Branch 6 taken 1484800 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 33 times.
✓ Branch 11 taken 3490 times.
✗ Branch 12 not taken.
✓ Branch 16 taken 7024 times.
✗ Branch 17 not taken.
✓ Branch 21 taken 3193 times.
✗ Branch 22 not taken.
8984260 subApply(domainI, domainJ, [&](auto& cm, auto&& ii, auto&& jj){
297 8958122 cm.updateCouplingContext(ii, localAssemblerI, jj, dofIdxGlobalJ, priVars, pvIdxJ);
298 });
299 }
300 else
301 {
302 // for i == j, we need to call all relevant managers where domainI is involved and make sure that the
303 // context is updated with respect to its own domain (I-I coupling context)
304 using namespace Dune::Hybrid;
305
6/11
✓ Branch 1 taken 371200 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 371200 times.
✓ Branch 5 taken 966 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 966 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 371200 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 371200 times.
✗ Branch 14 not taken.
81548204 forEach(CouplingMap::coupledDomains(domainI), [&](const auto domainJ){
306 static_assert(domainI != domainJ);
307 49599732 subApply(domainI, domainJ, [&](auto& cm, auto&& ii, auto&& jj){
308
0/20
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
99199464 cm.updateCouplingContext(ii, localAssemblerI, ii, dofIdxGlobalJ, priVars, pvIdxJ);
309 });
310 });
311 }
312 }
313
314 //! Bind the coupling context for a low dim element TODO remove Assembler
315 template<std::size_t i, class Assembler = int>
316 void bindCouplingContext(Dune::index_constant<i> domainI, const Element<i>& element, const Assembler& assembler = 0)
317 {
318 // for the coupling blocks
319 using namespace Dune::Hybrid;
320
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2231110 forEach(CouplingMap::coupledDomains(domainI), [&](const auto domainJ){
321 4465992 subApply(domainI, domainJ, [&](auto& cm, auto&& ii, auto&& jj) -> void {
322
0/87
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
2977328 cm.bindCouplingContext(ii, element, assembler);
323 });
324 });
325 }
326
327 /*!
328 * \brief return the numeric epsilon used for deflecting primary variables of coupled domain i.
329 * \note specialization for free-flow schemes
330 */
331 template<std::size_t i>
332 decltype(auto) numericEpsilon(Dune::index_constant<i> domainI,
333 const std::string& paramGroup) const
334 {
335 return subApply(domainI, [&](const auto& cm, auto&& ii) -> decltype(auto) {
336
7/18
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 14 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 16 times.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 22 taken 16 times.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
96 return cm.numericEpsilon(ii, paramGroup);
337
6/12
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 16 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 16 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 16 times.
✗ Branch 18 not taken.
✓ Branch 21 taken 16 times.
✗ Branch 22 not taken.
96 });
338 }
339
340 /*!
341 * \brief evaluate additional derivatives of the element residual of a domain with respect
342 * to dofs in the same domain that are not in the regular stencil (see CouplingManager::extendJacobianPattern)
343 * \note Such additional dependencies can arise from the coupling, e.g. if a coupling source
344 * term depends on a non-local average of a quantity of the same domain
345 */
346 template<std::size_t i, class LocalAssemblerI, class JacobianMatrixDiagBlock, class GridVariables>
347 void evalAdditionalDomainDerivatives(Dune::index_constant<i> domainI,
348 const LocalAssemblerI& localAssemblerI,
349 const typename LocalAssemblerI::LocalResidual::ElementResidualVector& origResiduals,
350 JacobianMatrixDiagBlock& A,
351 GridVariables& gridVariables)
352 {}
353
354 template<std::size_t i, class LocalAssemblerI, class UpdatableElementVolVars, class UpdatableFluxVarCache>
355 void updateCoupledVariables(Dune::index_constant<i> domainI,
356 const LocalAssemblerI& localAssemblerI,
357 UpdatableElementVolVars& elemVolVars,
358 UpdatableFluxVarCache& elemFluxVarsCache)
359 {
360 // for the coupling blocks
361 using namespace Dune::Hybrid;
362
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 33 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 33 times.
17929016 forEach(CouplingMap::coupledDomains(domainI), [&](const auto domainJ){
363 71716064 subApply(domainI, domainJ, [&](auto& cm, auto&& ii, auto&& jj){
364
8/16
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 33 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 33 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 33 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 33 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 33 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 33 times.
35858032 cm.updateCoupledVariables(ii, localAssemblerI, elemVolVars, elemFluxVarsCache);
365 });
366 });
367 }
368
369 protected:
370 SolutionVectors& curSol()
371 48 { return solutionVectors_; }
372
373 const SolutionVectors& curSol() const
374 { return solutionVectors_; }
375
376 private:
377 CouplingManagers couplingManagers_;
378 SolutionVectors solutionVectors_;
379
380 CouplingStencil emptyStencil_;
381 };
382
383 } // end namespace Dumux
384
385 #endif
386