GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/multidomain/staggeredcouplingmanager.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 20 30 66.7%
Functions: 32 213 15.0%
Branches: 42 57 73.7%

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 * \ingroup StaggeredDiscretization
11 * \brief The interface of the coupling manager for multi domain problems
12 */
13
14 #ifndef DUMUX_STAGGERED_COUPLING_MANAGER_HH
15 #define DUMUX_STAGGERED_COUPLING_MANAGER_HH
16
17 #include <dumux/multidomain/couplingmanager.hh>
18 #include <dumux/assembly/numericepsilon.hh>
19 #include <dumux/common/indextraits.hh>
20 #include <dumux/discretization/method.hh>
21
22 namespace Dumux {
23
24 /*!
25 * \ingroup MultiDomain
26 * \ingroup StaggeredDiscretization
27 * \brief Base coupling manager for the staggered discretization.
28 */
29 template<class MDTraits>
30
1/4
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 8 taken 33 times.
✗ Branch 9 not taken.
66 class StaggeredCouplingManager: virtual public CouplingManager<MDTraits>
31 {
32 using ParentType = CouplingManager<MDTraits>;
33
34 template<std::size_t id> using GridGeometry = typename MDTraits::template SubDomain<id>::GridGeometry;
35 template<std::size_t id> using GridView = typename GridGeometry<id>::GridView;
36
37 using FVElementGeometry = typename GridGeometry<0>::LocalView;
38 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
39 using Element = typename GridView<0>::template Codim<0>::Entity;
40
41 using GridIndexType = typename IndexTraits< GridView<0> >::GridIndex;
42 using CouplingStencil = std::vector<GridIndexType>;
43
44 public:
45
46 using ParentType::evalCouplingResidual;
47
48 using Traits = MDTraits;
49
50 static constexpr auto cellCenterIdx = GridGeometry<0>::cellCenterIdx();
51 static constexpr auto faceIdx = GridGeometry<0>::faceIdx();
52
53 /*!
54 * \copydoc Dumux::CouplingManager::updateCouplingContext()
55 */
56 template<std::size_t i, std::size_t j, class LocalAssemblerI, class PriVarsJ>
57 void updateCouplingContext(Dune::index_constant<i> domainI,
58 const LocalAssemblerI& localAssemblerI,
59 Dune::index_constant<j> domainJ,
60 const std::size_t dofIdxGlobalJ,
61 const PriVarsJ& priVarsJ,
62 int pvIdxJ)
63 {
64
16/16
✓ Branch 0 taken 6980320 times.
✓ Branch 1 taken 34472732 times.
✓ Branch 2 taken 6980320 times.
✓ Branch 3 taken 68217264 times.
✓ Branch 4 taken 1651648 times.
✓ Branch 5 taken 3770128 times.
✓ Branch 6 taken 1651648 times.
✓ Branch 7 taken 7294256 times.
✓ Branch 8 taken 2892224 times.
✓ Branch 9 taken 28145556 times.
✓ Branch 10 taken 2892224 times.
✓ Branch 11 taken 14224078 times.
✓ Branch 12 taken 13012416 times.
✓ Branch 13 taken 56871744 times.
✓ Branch 14 taken 13012416 times.
✓ Branch 15 taken 29653672 times.
291722646 auto& curSol = this->curSol(domainJ);
65
66 // only proceed if the solution vector has actually been set in the base class
67 // (which is not the case if the staggered model is not coupled to another domain)
68
16/16
✓ Branch 0 taken 6980320 times.
✓ Branch 1 taken 34472732 times.
✓ Branch 2 taken 6980320 times.
✓ Branch 3 taken 68217264 times.
✓ Branch 4 taken 1651648 times.
✓ Branch 5 taken 3770128 times.
✓ Branch 6 taken 1651648 times.
✓ Branch 7 taken 7294256 times.
✓ Branch 8 taken 2892224 times.
✓ Branch 9 taken 28145556 times.
✓ Branch 10 taken 2892224 times.
✓ Branch 11 taken 14224078 times.
✓ Branch 12 taken 13012416 times.
✓ Branch 13 taken 56871744 times.
✓ Branch 14 taken 13012416 times.
✓ Branch 15 taken 29653672 times.
291722646 if (curSol.size() > 0)
69 119559168 curSol[dofIdxGlobalJ][pvIdxJ] = priVarsJ[pvIdxJ];
70 }
71
72 /*!
73 * \brief returns an iterable container of all indices of degrees of freedom of domain j
74 * that couple with / influence the element residual of the given element of domain i
75 *
76 * \param domainI the domain index of domain i
77 * \param elementI the coupled element of domain í
78 * \param domainJ the domain index of domain j
79
80 * \note this is a specialization for getting the indices of the coupled staggered face dofs
81 */
82 89392 const CouplingStencil& couplingStencil(Dune::index_constant<cellCenterIdx> domainI,
83 const Element& elementI,
84 Dune::index_constant<faceIdx> domainJ) const
85 {
86
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 89392 times.
89392 const auto& connectivityMap = this->problem(domainI).gridGeometry().connectivityMap();
87 357568 const auto eIdx = this->problem(domainI).gridGeometry().elementMapper().index(elementI);
88 178784 return connectivityMap(domainI, domainJ, eIdx);
89 }
90
91 /*!
92 * \brief returns an iterable container of all indices of degrees of freedom of domain j
93 * that couple with / influence the residual of the given subcontrolvolume face of domain i
94 *
95 * \param domainI the domain index of domain i
96 * \param scvfI the coupled subcontrolvolume face of domain í
97 * \param domainJ the domain index of domain j
98
99 * \note This function has to be implemented by all coupling managers for all combinations of i and j
100 */
101 template<std::size_t i, std::size_t j>
102 const CouplingStencil couplingStencil(Dune::index_constant<i> domainI,
103 const SubControlVolumeFace& scvfI,
104 Dune::index_constant<j> domainJ) const
105 {
106 static_assert(i != j, "Domain i cannot be coupled to itself!");
107 static_assert(AlwaysFalse<Dune::index_constant<i>>::value,
108 "The coupling manager does not implement the couplingStencil() function" );
109
110 return CouplingStencil(); // suppress compiler warning of function having no return statement
111 }
112
113 /*!
114 * \brief returns an iterable container of all indices of degrees of freedom of domain j
115 * that couple with / influence the residual of the given subcontrolvolume face of domain i
116 *
117 * \param domainI the domain index of domain i
118 * \param scvfI the coupled subcontrolvolume face of domain í
119 * \param domainJ the domain index of domain j
120
121 * \note this is a specialization for getting the indices of the coupled cellcentered dofs
122 */
123 const CouplingStencil& couplingStencil(Dune::index_constant<faceIdx> domainI,
124 const SubControlVolumeFace& scvfI,
125 Dune::index_constant<cellCenterIdx> domainJ) const
126 {
127 const auto& connectivityMap = this->problem(domainI).gridGeometry().connectivityMap();
128 return connectivityMap(domainI, domainJ, scvfI.index());
129 }
130
131 /*!
132 * \copydoc Dumux::CouplingManager::evalCouplingResidual()
133 *
134 * \note this is a specialization for calculating the coupled residual for cellcentered dofs
135 * w.r.t. staggered face dof changes
136 */
137 template<class LocalAssemblerI, std::size_t j>
138 decltype(auto) evalCouplingResidual(Dune::index_constant<cellCenterIdx> domainI,
139 const LocalAssemblerI& localAssemblerI,
140 Dune::index_constant<j> domainJ,
141 std::size_t dofIdxGlobalJ) const
142 {
143 static_assert(domainI != domainJ, "Domain i cannot be coupled to itself!");
144
3/6
✓ Branch 0 taken 3620 times.
✓ Branch 1 taken 7712 times.
✓ Branch 2 taken 5200 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
37848 return localAssemblerI.evalLocalResidualForCellCenter();
145 }
146
147 /*!
148 * \brief evaluates the face residual of a coupled face of domain i which depends on the variables
149 * at the degree of freedom with index dofIdxGlobalJ of domain j
150 *
151 * \param domainI the domain index of domain i
152 * \param scvfI the subcontrol volume face whose residual shall be evaluated of domain i
153 * \param localAssemblerI the local assembler assembling the element residual of an element of domain i
154 * \param domainJ the domain index of domain j
155 * \param dofIdxGlobalJ the index of the degree of freedom of domain j which has an influence on the element residual of domain i
156 *
157 * \note the default implementation evaluates the complete face residual
158 * if only certain terms of the residual of the residual are coupled
159 * to dof with index dofIdxGlobalJ the function can be overloaded in the coupling manager
160 * \return the face residual
161 */
162 template<class LocalAssemblerI, std::size_t j>
163 decltype(auto) evalCouplingResidual(Dune::index_constant<faceIdx> domainI,
164 const SubControlVolumeFace& scvfI,
165 const LocalAssemblerI& localAssemblerI,
166 Dune::index_constant<j> domainJ,
167 std::size_t dofIdxGlobalJ) const
168 {
169 static_assert(domainI != domainJ, "Domain i cannot be coupled to itself!");
170
2/6
✓ Branch 0 taken 11332 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22896 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
45560 return localAssemblerI.evalLocalResidualForFace(scvfI);
171 }
172
173 /*!
174 * \brief return the numeric epsilon used for deflecting primary variables of coupled domain i.
175 * \note specialization for non-staggered schemes
176 */
177 template<std::size_t i, typename std::enable_if_t<(GridGeometry<i>::discMethod != DiscretizationMethods::staggered), int> = 0>
178 decltype(auto) numericEpsilon(Dune::index_constant<i> id,
179 const std::string& paramGroup) const
180 {
181
3/5
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
34 return ParentType::numericEpsilon(id, paramGroup);
182 }
183
184 /*!
185 * \brief return the numeric epsilon used for deflecting primary variables of coupled domain i.
186 * \note specialization for non-staggered schemes
187 */
188 template<std::size_t i, typename std::enable_if_t<(GridGeometry<i>::discMethod == DiscretizationMethods::staggered), int> = 0>
189 234 decltype(auto) numericEpsilon(Dune::index_constant<i>,
190 const std::string& paramGroup) const
191 {
192 234 constexpr std::size_t numEqCellCenter = Traits::template SubDomain<cellCenterIdx>::PrimaryVariables::dimension;
193 234 constexpr std::size_t numEqFace = Traits::template SubDomain<faceIdx>::PrimaryVariables::dimension;
194 234 constexpr bool isCellCenter = GridGeometry<i>::isCellCenter();
195 234 constexpr std::size_t numEq = isCellCenter ? numEqCellCenter : numEqFace;
196 234 constexpr auto prefix = isCellCenter ? "CellCenter" : "Face";
197
198 try {
199 468 if(paramGroup.empty())
200 264 return NumericEpsilon<typename Traits::Scalar, numEq>(prefix);
201 else
202 153 return NumericEpsilon<typename Traits::Scalar, numEq>(paramGroup + "." + prefix);
203 }
204 catch (Dune::RangeError& e)
205 {
206 DUNE_THROW(Dumux::ParameterException, "For the staggered model, you can to specify \n\n"
207 " CellCenter.Assembly.NumericDifference.PriVarMagnitude = mCC\n"
208 " Face.Assembly.NumericDifference.PriVarMagnitude = mFace\n"
209 " CellCenter.Assembly.NumericDifference.BaseEpsilon = eCC_0 ... eCC_numEqCellCenter-1\n"
210 " Face.Assembly.NumericDifference.BaseEpsilon = eFace_0 ... eFace_numEqFace-1\n\n"
211 "Wrong number of values set for " << prefix << " (has " << numEq << " primary variable(s))\n\n" << e);
212 }
213
214 }
215
216 };
217
218 } //end namespace Dumux
219
220 #endif
221