GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/multidomain/subdomaincvfelocalassembler.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 93 105 88.6%
Functions: 131 444 29.5%
Branches: 172 382 45.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 Assembly
10 * \ingroup CVFEDiscretization
11 * \ingroup MultiDomain
12 * \brief An assembler for Jacobian and residual contribution per element (CVFE methods) for multidomain problems
13 */
14 #ifndef DUMUX_MULTIDOMAIN_SUBDOMAIN_CVFE_LOCAL_ASSEMBLER_HH
15 #define DUMUX_MULTIDOMAIN_SUBDOMAIN_CVFE_LOCAL_ASSEMBLER_HH
16
17 #include <type_traits>
18
19 #include <dune/common/reservedvector.hh>
20 #include <dune/common/indices.hh>
21 #include <dune/common/hybridutilities.hh>
22 #include <dune/grid/common/gridenums.hh> // for GhostEntity
23 #include <dune/istl/matrixindexset.hh>
24
25 #include <dumux/common/reservedblockvector.hh>
26 #include <dumux/common/properties.hh>
27 #include <dumux/common/parameters.hh>
28 #include <dumux/common/numericdifferentiation.hh>
29 #include <dumux/common/numeqvector.hh>
30 #include <dumux/assembly/numericepsilon.hh>
31 #include <dumux/assembly/diffmethod.hh>
32 #include <dumux/assembly/cvfelocalassembler.hh>
33 #include <dumux/discretization/extrusion.hh>
34
35 namespace Dumux {
36
37 /*!
38 * \ingroup Assembly
39 * \ingroup CVFEDiscretization
40 * \ingroup MultiDomain
41 * \brief A base class for all CVFE subdomain local assemblers
42 * \tparam id the id of the sub domain
43 * \tparam TypeTag the TypeTag
44 * \tparam Assembler the assembler type
45 * \tparam Implementation the actual implementation type
46 * \tparam implicit Specifies whether the time discretization is implicit or not not (i.e. explicit)
47 */
48 template<std::size_t id, class TypeTag, class Assembler, class Implementation, DiffMethod dm, bool implicit>
49 6616770 class SubDomainCVFELocalAssemblerBase : public CVFELocalAssembler<TypeTag, Assembler, dm, implicit, Implementation>
50 {
51 using ParentType = CVFELocalAssembler<TypeTag, Assembler, dm, implicit, Implementation>;
52
53 using Problem = GetPropType<TypeTag, Properties::Problem>;
54 using LocalResidualValues = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>;
55 using JacobianMatrix = GetPropType<TypeTag, Properties::JacobianMatrix>;
56 using SolutionVector = typename Assembler::SolutionVector;
57 using ElementBoundaryTypes = GetPropType<TypeTag, Properties::ElementBoundaryTypes>;
58
59 using GridVariables = GetPropType<TypeTag, Properties::GridVariables>;
60 using GridVolumeVariables = typename GridVariables::GridVolumeVariables;
61 using ElementVolumeVariables = typename GridVolumeVariables::LocalView;
62 using ElementFluxVariablesCache = typename GridVariables::GridFluxVariablesCache::LocalView;
63 using Scalar = typename GridVariables::Scalar;
64
65 using GridGeometry = typename GridVariables::GridGeometry;
66 using FVElementGeometry = typename GridGeometry::LocalView;
67 using SubControlVolume = typename GridGeometry::SubControlVolume;
68 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
69 using Extrusion = Extrusion_t<GridGeometry>;
70 using GridView = typename GridGeometry::GridView;
71 using Element = typename GridView::template Codim<0>::Entity;
72
73 using CouplingManager = typename Assembler::CouplingManager;
74
75 static constexpr auto numEq = GetPropType<TypeTag, Properties::ModelTraits>::numEq();
76
77 public:
78 //! export the domain id of this sub-domain
79 static constexpr auto domainId = typename Dune::index_constant<id>();
80 //! pull up constructor of parent class
81 using ParentType::ParentType;
82 //! export element residual vector type
83 using ElementResidualVector = typename ParentType::LocalResidual::ElementResidualVector;
84
85 // the constructor
86 5585931 explicit SubDomainCVFELocalAssemblerBase(
87 const Assembler& assembler,
88 const Element& element,
89 const SolutionVector& curSol,
90 CouplingManager& couplingManager
91 )
92 : ParentType(assembler,
93 element,
94 curSol,
95 localView(assembler.gridGeometry(domainId)),
96
2/4
✓ Branch 1 taken 1295090 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
12987915 localView(assembler.gridVariables(domainId).curGridVolVars()),
97
3/6
✓ Branch 1 taken 1295090 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 40 times.
✗ Branch 8 not taken.
13729075 localView(assembler.gridVariables(domainId).prevGridVolVars()),
98
4/8
✓ Branch 1 taken 1295090 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 40 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 40 times.
✗ Branch 11 not taken.
14470235 localView(assembler.gridVariables(domainId).gridFluxVarsCache()),
99 assembler.localResidual(domainId),
100 11035803 (element.partitionType() == Dune::GhostEntity))
101
26/44
✓ Branch 0 taken 1238886 times.
✓ Branch 1 taken 68041 times.
✓ Branch 2 taken 1239836 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 68041 times.
✓ Branch 5 taken 1239836 times.
✓ Branch 6 taken 712307 times.
✓ Branch 7 taken 55254 times.
✓ Branch 8 taken 1252623 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 55254 times.
✓ Branch 11 taken 1239836 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 55234 times.
✓ Branch 14 taken 1239816 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 55234 times.
✓ Branch 17 taken 1239816 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 55234 times.
✓ Branch 20 taken 1239816 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 55234 times.
✓ Branch 23 taken 1239816 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 55234 times.
✓ Branch 26 taken 1239816 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 55234 times.
✓ Branch 29 taken 1239816 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 55234 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 1239816 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 1295050 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 55234 times.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
6946241 , couplingManager_(couplingManager)
102 5585891 {}
103
104 /*!
105 * \brief Computes the derivatives with respect to the given element and adds them
106 * to the global matrix. The element residual is written into the right hand side.
107 */
108 template<class JacobianMatrixRow, class SubResidualVector, class GridVariablesTuple>
109 void assembleJacobianAndResidual(JacobianMatrixRow& jacRow, SubResidualVector& res, GridVariablesTuple& gridVariables)
110 {
111 4719964 auto assembleCouplingBlocks = [&](const auto& residual)
112 {
113 // assemble the coupling blocks
114 using namespace Dune::Hybrid;
115 1345982 forEach(integralRange(Dune::Hybrid::size(jacRow)), [&](auto&& i)
116 {
117 2359982 if constexpr (std::decay_t<decltype(i)>{} != id)
118
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
1337883 this->assembleJacobianCoupling(i, jacRow, residual, gridVariables);
119 });
120 };
121
122 // the coupled model does not support partial reassembly yet
123 2359982 const DefaultPartialReassembler* noReassembler = nullptr;
124
16/32
✓ Branch 1 taken 801611 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 801611 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 801611 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 801611 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 536663 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 536663 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 536663 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 536663 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 57708 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 57708 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 57708 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 57708 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 964000 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 964000 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 964000 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 964000 times.
✗ Branch 47 not taken.
9439928 ParentType::assembleJacobianAndResidual(jacRow[domainId], res, *std::get<domainId>(gridVariables), noReassembler, assembleCouplingBlocks);
125 }
126
127 /*!
128 * \brief Assemble the entries in a coupling block of the jacobian.
129 * There is no coupling block between a domain and itself.
130 */
131 template<std::size_t otherId, class JacRow, class GridVariables,
132 typename std::enable_if_t<(otherId == id), int> = 0>
133 void assembleJacobianCoupling(Dune::index_constant<otherId> domainJ, JacRow& jacRow,
134 const ElementResidualVector& res, GridVariables& gridVariables)
135 {}
136
137 /*!
138 * \brief Assemble the entries in a coupling block of the jacobian.
139 */
140 template<std::size_t otherId, class JacRow, class GridVariables,
141 typename std::enable_if_t<(otherId != id), int> = 0>
142 void assembleJacobianCoupling(Dune::index_constant<otherId> domainJ, JacRow& jacRow,
143 const ElementResidualVector& res, GridVariables& gridVariables)
144 {
145
0/79
✗ 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 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 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
9407532 this->asImp_().assembleJacobianCoupling(domainJ, jacRow[domainJ], res, *std::get<domainId>(gridVariables));
146 }
147
148 /*!
149 * \brief Evaluates the local source term for an element and given element volume variables
150 */
151 218701 ElementResidualVector evalLocalSourceResidual(const Element& element, const ElementVolumeVariables& elemVolVars) const
152 {
153 // initialize the residual vector for all scvs in this element
154 656103 ElementResidualVector residual(this->fvGeometry().numScv());
155
156 // evaluate the volume terms (storage + source terms)
157 // forward to the local residual specialized for the discretization methods
158
4/4
✓ Branch 0 taken 694440 times.
✓ Branch 1 taken 142542 times.
✓ Branch 2 taken 545808 times.
✓ Branch 3 taken 68226 times.
2074471 for (const auto& scv : scvs(this->fvGeometry()))
159 {
160
1/2
✓ Branch 0 taken 545808 times.
✗ Branch 1 not taken.
857816 const auto& curVolVars = elemVolVars[scv];
161
2/4
✓ Branch 0 taken 545808 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 545808 times.
✗ Branch 3 not taken.
1418368 auto source = this->localResidual().computeSource(problem(), element, this->fvGeometry(), elemVolVars, scv);
162 1715632 source *= -Extrusion::volume(this->fvGeometry(), scv)*curVolVars.extrusionFactor();
163 1715632 residual[scv.localDofIndex()] = std::move(source);
164 }
165
166 218701 return residual;
167 }
168
169 /*!
170 * \brief Evaluates the local source term depending on time discretization scheme
171 */
172 ElementResidualVector evalLocalSourceResidual(const Element& neighbor) const
173 285084 { return this->evalLocalSourceResidual(neighbor, implicit ? this->curElemVolVars() : this->prevElemVolVars()); }
174
175 /*!
176 * \brief Prepares all local views necessary for local assembly.
177 */
178 5592810 void bindLocalViews()
179 {
180 // get some references for convenience
181 5592810 const auto& element = this->element();
182 11185620 const auto& curSol = this->curSol(domainId);
183 11185620 auto&& fvGeometry = this->fvGeometry();
184 5592810 auto&& curElemVolVars = this->curElemVolVars();
185 5592810 auto&& elemFluxVarsCache = this->elemFluxVarsCache();
186
187 // bind the caches
188 5592810 couplingManager_.bindCouplingContext(domainId, element, this->assembler());
189 5592810 fvGeometry.bind(element);
190
191 if constexpr (implicit)
192 {
193 3564810 curElemVolVars.bind(element, fvGeometry, curSol);
194 3564810 elemFluxVarsCache.bind(element, fvGeometry, curElemVolVars);
195
4/4
✓ Branch 0 taken 873254 times.
✓ Branch 1 taken 1421131 times.
✓ Branch 2 taken 873254 times.
✓ Branch 3 taken 1421131 times.
7129620 if (!this->assembler().isStationaryProblem())
196 4160816 this->prevElemVolVars().bindElement(element, fvGeometry, this->assembler().prevSol()[domainId]);
197 }
198 else
199 {
200 2028000 auto& prevElemVolVars = this->prevElemVolVars();
201 4056000 const auto& prevSol = this->assembler().prevSol()[domainId];
202
203 2028000 curElemVolVars.bindElement(element, fvGeometry, curSol);
204 2028000 prevElemVolVars.bind(element, fvGeometry, prevSol);
205 2028000 elemFluxVarsCache.bind(element, fvGeometry, prevElemVolVars);
206 }
207
208 11185620 this->elemBcTypes().update(problem(), this->element(), this->fvGeometry());
209 5592810 }
210
211 //! return reference to the underlying problem
212 template<std::size_t i = domainId>
213 const Problem& problem(Dune::index_constant<i> dId = domainId) const
214
32/48
✓ Branch 0 taken 531064 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27418 times.
✓ Branch 3 taken 12745 times.
✓ Branch 4 taken 1318 times.
✓ Branch 5 taken 21 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 25 times.
✓ Branch 9 taken 10 times.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 23 times.
✓ Branch 12 taken 4 times.
✓ Branch 13 taken 5 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 22 times.
✓ Branch 16 taken 7 times.
✓ Branch 17 taken 1 times.
✓ Branch 18 taken 24 times.
✓ Branch 19 taken 7 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 22 times.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 4 times.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 1 times.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 35 taken 1 times.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 2 times.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✓ Branch 41 taken 2 times.
✗ Branch 42 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 1 times.
✗ Branch 50 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
17595775 { return this->assembler().problem(domainId); }
215
216 //! return reference to the underlying problem
217 template<std::size_t i = domainId>
218 const auto& curSol(Dune::index_constant<i> dId = domainId) const
219
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1795 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10531 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8736 times.
11336734 { return ParentType::curSol()[dId]; }
220
221 //! return reference to the coupling manager
222 CouplingManager& couplingManager()
223 { return couplingManager_; }
224
225 private:
226 CouplingManager& couplingManager_; //!< the coupling manager
227 };
228
229 /*!
230 * \ingroup Assembly
231 * \ingroup CVFEDiscretization
232 * \ingroup MultiDomain
233 * \brief The CVFE scheme multidomain local assembler
234 * \tparam id the id of the sub domain
235 * \tparam TypeTag the TypeTag
236 * \tparam Assembler the assembler type
237 * \tparam DM the numeric differentiation method
238 * \tparam implicit whether the assembler is explicit or implicit in time
239 */
240 template<std::size_t id, class TypeTag, class Assembler, DiffMethod DM = DiffMethod::numeric, bool implicit = true>
241 class SubDomainCVFELocalAssembler;
242
243 /*!
244 * \ingroup Assembly
245 * \ingroup CVFEDiscretization
246 * \ingroup MultiDomain
247 * \brief CVFE scheme multi domain local assembler using numeric differentiation and implicit time discretization
248 */
249 template<std::size_t id, class TypeTag, class Assembler>
250
4/16
✓ Branch 0 taken 442618 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 394194 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 232108 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 232108 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
3595413 class SubDomainCVFELocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, /*implicit=*/true>
251 : public SubDomainCVFELocalAssemblerBase<id, TypeTag, Assembler,
252 SubDomainCVFELocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, true>, DiffMethod::numeric, true >
253 {
254 using ThisType = SubDomainCVFELocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, /*implicit=*/true>;
255 using ParentType = SubDomainCVFELocalAssemblerBase<id, TypeTag, Assembler, ThisType, DiffMethod::numeric, /*implicit=*/true>;
256 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
257 using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>;
258
259 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
260 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
261 using FVElementGeometry = typename GridGeometry::LocalView;
262 using SubControlVolume = typename GridGeometry::SubControlVolume;
263 using GridView = typename GridGeometry::GridView;
264 using Element = typename GridView::template Codim<0>::Entity;
265 using Problem = GetPropType<TypeTag, Properties::Problem>;
266
267 static constexpr int numEq = GetPropType<TypeTag, Properties::ModelTraits>::numEq();
268 static constexpr int dim = GridView::dimension;
269
270 static constexpr bool enableGridFluxVarsCache = GetPropType<TypeTag, Properties::GridVariables>::GridFluxVariablesCache::cachingEnabled;
271 static constexpr bool enableGridVolVarsCache = GetPropType<TypeTag, Properties::GridVariables>::GridVolumeVariables::cachingEnabled;
272 static constexpr auto domainI = Dune::index_constant<id>();
273
274 public:
275
2/4
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
2294425 using ParentType::ParentType;
276 //! export element residual vector type
277 using ElementResidualVector = typename ParentType::LocalResidual::ElementResidualVector;
278
279 /*!
280 * \brief Update the coupling context for coupled models.
281 */
282 template<class ElemSol>
283 92 void maybeUpdateCouplingContext(const SubControlVolume& scv, ElemSol& elemSol, const int pvIdx)
284 {
285
6/10
✗ Branch 0 not taken.
✓ Branch 1 taken 37792 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
✓ Branch 4 taken 37712 times.
✓ Branch 5 taken 80 times.
✓ Branch 9 taken 18528 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 18528 times.
✗ Branch 13 not taken.
47944476 this->couplingManager().updateCouplingContext(domainI, *this, domainI, scv.dofIndex(), elemSol[scv.localDofIndex()], pvIdx);
286 92 }
287
288 /*!
289 * \brief Update the additional domain derivatives for coupled models.
290 */
291 template<class JacobianMatrixDiagBlock, class GridVariables>
292 void maybeEvalAdditionalDomainDerivatives(const ElementResidualVector& origResiduals, JacobianMatrixDiagBlock& A, GridVariables& gridVariables)
293 {
294 1345982 this->couplingManager().evalAdditionalDomainDerivatives(domainI, *this, origResiduals, A, gridVariables);
295 }
296
297 /*!
298 * \brief Computes the derivatives with respect to the given element and adds them
299 * to the global matrix.
300 */
301 template<std::size_t otherId, class JacobianBlock, class GridVariables>
302 2168412 void assembleJacobianCoupling(Dune::index_constant<otherId> domainJ, JacobianBlock& A,
303 const ElementResidualVector& res, GridVariables& gridVariables)
304 {
305 ////////////////////////////////////////////////////////////////////////////////////////////////////////
306 // Calculate derivatives of all dofs in the element with respect to all dofs in the coupling stencil. //
307 ////////////////////////////////////////////////////////////////////////////////////////////////////////
308
309 // get some aliases for convenience
310 2168412 const auto& element = this->element();
311 2168412 const auto& fvGeometry = this->fvGeometry();
312 2168412 auto&& curElemVolVars = this->curElemVolVars();
313 2168412 auto&& elemFluxVarsCache = this->elemFluxVarsCache();
314
315 // convenience lambda for call to update self
316 10616539 auto updateCoupledVariables = [&] ()
317 {
318 // Update ourself after the context has been modified. Depending on the
319 // type of caching, other objects might have to be updated. All ifs can be optimized away.
320 if constexpr (enableGridFluxVarsCache)
321 {
322 if constexpr (enableGridVolVarsCache)
323 7541069 this->couplingManager().updateCoupledVariables(domainI, *this, gridVariables.curGridVolVars(), gridVariables.gridFluxVarsCache());
324 else
325 this->couplingManager().updateCoupledVariables(domainI, *this, curElemVolVars, gridVariables.gridFluxVarsCache());
326 }
327 else
328 {
329 if constexpr (enableGridVolVarsCache)
330 this->couplingManager().updateCoupledVariables(domainI, *this, gridVariables.curGridVolVars(), elemFluxVarsCache);
331 else
332 907358 this->couplingManager().updateCoupledVariables(domainI, *this, curElemVolVars, elemFluxVarsCache);
333 }
334 };
335
336 // get element stencil information
337 2168412 const auto& stencil = this->couplingManager().couplingStencil(domainI, element, domainJ);
338 2168412 const auto& curSolJ = this->curSol(domainJ);
339
4/4
✓ Branch 0 taken 2485238 times.
✓ Branch 1 taken 1354081 times.
✓ Branch 2 taken 2484938 times.
✓ Branch 3 taken 1353781 times.
11654223 for (const auto globalJ : stencil)
340 {
341 // undeflected privars and privars to be deflected
342
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2485238 times.
✗ Branch 2 not taken.
4669271 const auto origPriVarsJ = curSolJ[globalJ];
343 4669271 auto priVarsJ = origPriVarsJ;
344
345 // the undeflected coupling residual
346
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2485238 times.
✗ Branch 2 not taken.
4669271 const auto origResidual = this->couplingManager().evalCouplingResidual(domainI, *this, domainJ, globalJ);
347
348
2/2
✓ Branch 0 taken 3779456 times.
✓ Branch 1 taken 2485238 times.
11926978 for (int pvIdx = 0; pvIdx < JacobianBlock::block_type::cols; ++pvIdx)
349 {
350 20019752 auto evalCouplingResidual = [&](Scalar priVar)
351 {
352 3202984 priVarsJ[pvIdx] = priVar;
353 3779456 this->couplingManager().updateCouplingContext(domainI, *this, domainJ, globalJ, priVarsJ, pvIdx);
354
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
3777152 updateCoupledVariables();
355
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
3779456 return this->couplingManager().evalCouplingResidual(domainI, *this, domainJ, globalJ);
356 };
357
358 // derive the residuals numerically
359
4/4
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 1509392 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 1509392 times.
14515414 ElementResidualVector partialDerivs(fvGeometry.numScv());
360
361
4/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 3779384 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 3779384 times.
14515414 const auto& paramGroup = this->assembler().problem(domainJ).paramGroup();
362
4/6
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 3779384 times.
✓ Branch 3 taken 72 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 72 times.
✗ Branch 7 not taken.
7257707 static const int numDiffMethod = getParamFromGroup<int>(paramGroup, "Assembly.NumericDifferenceMethod");
363
4/6
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 3779384 times.
✓ Branch 3 taken 72 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 72 times.
✗ Branch 7 not taken.
7257707 static const auto epsCoupl = this->couplingManager().numericEpsilon(domainJ, paramGroup);
364
365
2/4
✓ Branch 1 taken 3779456 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2547784 times.
✗ Branch 5 not taken.
12353275 NumericDifferentiation::partialDerivative(evalCouplingResidual, origPriVarsJ[pvIdx], partialDerivs, origResidual,
366 12353275 epsCoupl(origPriVarsJ[pvIdx], pvIdx), numDiffMethod);
367
368 // update the global stiffness matrix with the current partial derivatives
369
4/4
✓ Branch 0 taken 13468670 times.
✓ Branch 1 taken 3779456 times.
✓ Branch 2 taken 12858114 times.
✓ Branch 3 taken 3474178 times.
40147092 for (const auto& scv : scvs(fvGeometry))
370 {
371
2/2
✓ Branch 0 taken 18329838 times.
✓ Branch 1 taken 13468670 times.
60442076 for (int eqIdx = 0; eqIdx < numEq; eqIdx++)
372 {
373 // A[i][col][eqIdx][pvIdx] is the rate of change of
374 // the residual of equation 'eqIdx' at dof 'i'
375 // depending on the primary variable 'pvIdx' at dof
376 // 'col'.
377
9/13
✓ Branch 1 taken 18329838 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18329838 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 18329838 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 8730880 times.
✓ Branch 10 taken 9598958 times.
✓ Branch 11 taken 7845680 times.
✓ Branch 12 taken 802958 times.
✓ Branch 13 taken 8794160 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 648240 times.
122259688 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] += partialDerivs[scv.localDofIndex()][eqIdx];
378
379 // If the dof is coupled by a Dirichlet condition,
380 // set the derived value only once (i.e. overwrite existing values).
381
4/4
✓ Branch 0 taken 9367534 times.
✓ Branch 1 taken 8962304 times.
✓ Branch 2 taken 9367534 times.
✓ Branch 3 taken 8962304 times.
69620796 if (this->elemBcTypes().hasDirichlet())
382 {
383 2579468 const auto bcTypes = this->elemBcTypes().get(fvGeometry, scv);
384
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 689598 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 689598 times.
2580332 if (bcTypes.isCouplingDirichlet(eqIdx))
385 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = partialDerivs[scv.localDofIndex()][eqIdx];
386
2/2
✓ Branch 0 taken 293608 times.
✓ Branch 1 taken 395990 times.
1290166 else if (bcTypes.isDirichlet(eqIdx))
387
2/4
✓ Branch 1 taken 293608 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 293608 times.
✗ Branch 5 not taken.
1129744 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = 0.0;
388 }
389
390 // enforce internal Dirichlet constraints
391 if constexpr (Problem::enableInternalDirichletConstraints())
392 {
393
2/4
✓ Branch 1 taken 115200 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 115200 times.
✗ Branch 5 not taken.
460800 const auto internalDirichletConstraints = this->problem().hasInternalDirichletConstraint(this->element(), scv);
394
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 115200 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 115200 times.
460800 if (internalDirichletConstraints[eqIdx])
395 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = 0.0;
396 }
397
398 }
399 }
400
401 // restore the current element solution
402
2/4
✓ Branch 1 taken 340524 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340524 times.
✗ Branch 5 not taken.
12353275 priVarsJ[pvIdx] = origPriVarsJ[pvIdx];
403
404 // restore the undeflected state of the coupling context
405
1/2
✓ Branch 1 taken 1423644 times.
✗ Branch 2 not taken.
11823587 this->couplingManager().updateCouplingContext(domainI, *this, domainJ, globalJ, priVarsJ, pvIdx);
406 }
407
408 // Restore original state of the flux vars cache and/or vol vars.
409 // This has to be done in case they depend on variables of domainJ before
410 // we continue with the numeric derivative w.r.t the next globalJ. Otherwise,
411 // the next "origResidual" will be incorrect.
412
1/2
✓ Branch 1 taken 300 times.
✗ Branch 2 not taken.
4669271 updateCoupledVariables();
413 }
414 2168412 }
415 };
416
417 /*!
418 * \ingroup Assembly
419 * \ingroup CVFEDiscretization
420 * \ingroup MultiDomain
421 * \brief CVFE scheme multi domain local assembler using numeric differentiation and explicit time discretization
422 */
423 template<std::size_t id, class TypeTag, class Assembler>
424 1014000 class SubDomainCVFELocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, /*implicit=*/false>
425 : public SubDomainCVFELocalAssemblerBase<id, TypeTag, Assembler,
426 SubDomainCVFELocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, false>, DiffMethod::numeric, false >
427 {
428 using ThisType = SubDomainCVFELocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, /*implicit=*/false>;
429 using ParentType = SubDomainCVFELocalAssemblerBase<id, TypeTag, Assembler, ThisType, DiffMethod::numeric, /*implicit=*/false>;
430
431 public:
432 1014000 using ParentType::ParentType;
433 //! export element residual vector type
434 using ElementResidualVector = typename ParentType::LocalResidual::ElementResidualVector;
435
436 /*!
437 * \brief Computes the coupling derivatives with respect to the given element and adds them
438 * to the global matrix.
439 * \note Since the coupling can only enter sources or fluxes and these are evaluated on
440 * the old time level (explicit scheme), the coupling blocks are empty.
441 */
442 template<std::size_t otherId, class JacobianBlock, class GridVariables>
443 void assembleJacobianCoupling(Dune::index_constant<otherId> domainJ, JacobianBlock& A,
444 const ElementResidualVector& res, GridVariables& gridVariables)
445 {}
446 };
447
448 } // end namespace Dumux
449
450 #endif
451