GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/multidomain/embedded/couplingmanager1d3d_average.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 123 130 94.6%
Functions: 51 95 53.7%
Branches: 206 386 53.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 EmbeddedCoupling
10 * \brief Coupling manager for low-dimensional domains embedded in the bulk domain.
11 */
12
13 #ifndef DUMUX_MULTIDOMAIN_EMBEDDED_COUPLINGMANAGER_1D3D_AVERAGE_HH
14 #define DUMUX_MULTIDOMAIN_EMBEDDED_COUPLINGMANAGER_1D3D_AVERAGE_HH
15
16 #include <vector>
17
18 #include <dune/common/timer.hh>
19 #include <dune/geometry/quadraturerules.hh>
20
21 #include <dumux/common/tag.hh>
22 #include <dumux/common/properties.hh>
23 #include <dumux/common/indextraits.hh>
24
25 #include <dumux/geometry/distance.hh>
26
27 #include <dumux/multidomain/embedded/couplingmanagerbase.hh>
28 #include <dumux/multidomain/embedded/circlepoints.hh>
29 #include <dumux/multidomain/embedded/extendedsourcestencil.hh>
30 #include <dumux/multidomain/embedded/circleaveragepointsourcetraits.hh>
31
32 namespace Dumux {
33
34 namespace Embedded1d3dCouplingMode {
35 struct Average : public Utility::Tag<Average> {
36 static std::string name() { return "average"; }
37 };
38
39 inline constexpr Average average{};
40 } // end namespace Embedded1d3dCouplingMode
41
42 // forward declaration
43 template<class MDTraits, class CouplingMode>
44 class Embedded1d3dCouplingManager;
45
46 /*!
47 * \ingroup EmbeddedCoupling
48 * \brief Manages the coupling between bulk elements and lower dimensional elements
49 * Point sources on each integration point are computed by an AABB tree.
50 * \note Specialization for coupling method using line sources with 3d quantities averaged on the cylinder surface
51 */
52 template<class MDTraits>
53 class Embedded1d3dCouplingManager<MDTraits, Embedded1d3dCouplingMode::Average>
54 : public EmbeddedCouplingManagerBase<MDTraits, Embedded1d3dCouplingManager<MDTraits, Embedded1d3dCouplingMode::Average>,
55 CircleAveragePointSourceTraits<MDTraits>>
56 {
57 using ThisType = Embedded1d3dCouplingManager<MDTraits, Embedded1d3dCouplingMode::Average>;
58 using ParentType = EmbeddedCouplingManagerBase<MDTraits, ThisType, CircleAveragePointSourceTraits<MDTraits>>;
59 using Scalar = typename MDTraits::Scalar;
60 using SolutionVector = typename MDTraits::SolutionVector;
61 using PointSourceData = typename ParentType::PointSourceTraits::PointSourceData;
62
63 static constexpr auto bulkIdx = typename MDTraits::template SubDomain<0>::Index();
64 static constexpr auto lowDimIdx = typename MDTraits::template SubDomain<1>::Index();
65
66 // the sub domain type aliases
67 template<std::size_t id> using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
68 template<std::size_t id> using Problem = GetPropType<SubDomainTypeTag<id>, Properties::Problem>;
69 template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
70 template<std::size_t id> using GridView = typename GridGeometry<id>::GridView;
71 template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity;
72 template<std::size_t id> using GridIndex = typename IndexTraits<GridView<id>>::GridIndex;
73
74 using GlobalPosition = typename Element<bulkIdx>::Geometry::GlobalCoordinate;
75
76 template<std::size_t id>
77 static constexpr bool isBox()
78 { return GridGeometry<id>::discMethod == DiscretizationMethods::box; }
79
80
81 public:
82 enum {
83 bulkDim = GridView<bulkIdx>::dimension,
84 lowDimDim = GridView<lowDimIdx>::dimension,
85 dimWorld = GridView<bulkIdx>::dimensionworld
86 };
87
88 static constexpr Embedded1d3dCouplingMode::Average couplingMode{};
89
90
4/8
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
12 using ParentType::ParentType;
91
92 12 void init(std::shared_ptr<Problem<bulkIdx>> bulkProblem,
93 std::shared_ptr<Problem<lowDimIdx>> lowDimProblem,
94 const SolutionVector& curSol)
95 {
96
3/10
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
24 ParentType::init(bulkProblem, lowDimProblem, curSol);
97 12 computeLowDimVolumeFractions();
98 12 }
99
100 /*!
101 * \brief extend the jacobian pattern of the diagonal block of domain i
102 * by those entries that are not already in the uncoupled pattern
103 * \note Such additional dependencies can arise from the coupling, e.g. if a coupling source
104 * term depends on a non-local average of a quantity of the same domain
105 */
106 template<std::size_t id, class JacobianPattern>
107 void extendJacobianPattern(Dune::index_constant<id> domainI, JacobianPattern& pattern) const
108 {
109 extendedSourceStencil_.extendJacobianPattern(*this, domainI, pattern);
110 }
111
112 /*!
113 * \brief evaluate additional derivatives of the element residual of a domain with respect
114 * to dofs in the same domain that are not in the regular stencil (per default this is not the case)
115 * \note Such additional dependencies can arise from the coupling, e.g. if a coupling source
116 * term depends on a non-local average of a quantity of the same domain
117 * \note This is the same for box and cc
118 */
119 template<std::size_t i, class LocalAssemblerI, class JacobianMatrixDiagBlock, class GridVariables>
120 void evalAdditionalDomainDerivatives(Dune::index_constant<i> domainI,
121 const LocalAssemblerI& localAssemblerI,
122 const typename LocalAssemblerI::LocalResidual::ElementResidualVector&,
123 JacobianMatrixDiagBlock& A,
124 GridVariables& gridVariables)
125 {
126 694028 extendedSourceStencil_.evalAdditionalDomainDerivatives(*this, domainI, localAssemblerI, A, gridVariables);
127 }
128
129 /* \brief Compute integration point point sources and associated data
130 *
131 * This method uses grid glue to intersect the given grids. Over each intersection
132 * we later need to integrate a source term. This method places point sources
133 * at each quadrature point and provides the point source with the necessary
134 * information to compute integrals (quadrature weight and integration element)
135 * \param order The order of the quadrature rule for integration of sources over an intersection
136 * \param verbose If the point source computation is verbose
137 */
138 12 void computePointSourceData(std::size_t order = 1, bool verbose = false)
139 {
140 // Initialize the bulk bounding box tree
141
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 const auto& bulkGridGeometry = this->problem(bulkIdx).gridGeometry();
142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 const auto& lowDimGridGeometry = this->problem(lowDimIdx).gridGeometry();
143 12 const auto& bulkTree = bulkGridGeometry.boundingBoxTree();
144
145 // initialize the maps
146 // do some logging and profiling
147 12 Dune::Timer watch;
148 24 std::cout << "Initializing the point sources..." << std::endl;
149
150 // clear all internal members like pointsource vectors and stencils
151 // initializes the point source id counter
152 12 this->clear();
153 12 extendedSourceStencil_.clear();
154
155 // precompute the vertex indices for efficiency
156 12 this->precomputeVertexIndices(bulkIdx);
157 12 this->precomputeVertexIndices(lowDimIdx);
158
159 // intersect the bounding box trees
160 12 this->glueGrids();
161
162 // iterate over all intersection and add point sources
163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 const auto& lowDimProblem = this->problem(lowDimIdx);
164
4/4
✓ Branch 0 taken 9429 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 9429 times.
✓ Branch 3 taken 12 times.
9465 for (const auto& is : intersections(this->glue()))
165 {
166 // all inside elements are identical...
167 9429 const auto& lowDimElement = is.targetEntity(0);
168 18858 const auto lowDimElementIdx = lowDimGridGeometry.elementMapper().index(lowDimElement);
169
170 // get the intersection geometry
171 9429 const auto intersectionGeometry = is.geometry();
172 // get the Gaussian quadrature rule for the local intersection
173 9429 const auto& quad = Dune::QuadratureRules<Scalar, lowDimDim>::rule(intersectionGeometry.type(), order);
174
175 // apply the Gaussian quadrature rule and define point sources at each quadrature point
176 // note that the approximation is not optimal if
177 // (a) the one-dimensional elements are too large,
178 // (b) whenever a one-dimensional element is split between two or more elements,
179 // (c) when gradients of important quantities in the three-dimensional domain are large.
180
181 // iterate over all quadrature points
182
4/4
✓ Branch 0 taken 9620 times.
✓ Branch 1 taken 9429 times.
✓ Branch 2 taken 9620 times.
✓ Branch 3 taken 9429 times.
37907 for (auto&& qp : quad)
183 {
184 // global position of the quadrature point
185 19240 const auto globalPos = intersectionGeometry.global(qp.position());
186
187
1/4
✓ Branch 1 taken 9620 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
19240 const auto bulkElementIndices = intersectingEntities(globalPos, bulkTree);
188
189 // do not add a point source if the qp is outside of the 3d grid
190 // this is equivalent to having a source of zero for that qp
191
2/4
✓ Branch 0 taken 9620 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9620 times.
✗ Branch 3 not taken.
19240 if (bulkElementIndices.empty())
192 continue;
193
194 //////////////////////////////////////////////////////////
195 // get circle average connectivity and interpolation data
196 //////////////////////////////////////////////////////////
197
198
4/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9608 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
9620 static const auto numIp = getParam<int>("MixedDimension.NumCircleSegments");
199 18858 const auto radius = lowDimProblem.spatialParams().radius(lowDimElementIdx);
200 28860 const auto normal = intersectionGeometry.corner(1)-intersectionGeometry.corner(0);
201 9620 const auto circleAvgWeight = 2*M_PI*radius/numIp;
202
1/2
✓ Branch 1 taken 9620 times.
✗ Branch 2 not taken.
9620 const auto integrationElement = intersectionGeometry.integrationElement(qp.position());
203 9620 const auto qpweight = qp.weight();
204
205
2/6
✓ Branch 1 taken 9620 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9620 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
19240 const auto circlePoints = EmbeddedCoupling::circlePoints(globalPos, normal, radius, numIp);
206
4/10
✓ Branch 1 taken 9620 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9620 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9620 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 9620 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
38480 std::vector<Scalar> circleIpWeight; circleIpWeight.reserve(circlePoints.size());
207
4/10
✓ Branch 1 taken 9620 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9620 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9620 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 9620 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
38480 std::vector<GridIndex<bulkIdx>> circleStencil; circleStencil.reserve(circlePoints.size());
208
209 // for box
210
1/4
✓ Branch 0 taken 9620 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19240 std::vector<const std::vector<GridIndex<bulkIdx>>*> circleCornerIndices;
211 using ShapeValues = std::vector<Dune::FieldVector<Scalar, 1> >;
212
1/2
✓ Branch 1 taken 9620 times.
✗ Branch 2 not taken.
19240 std::vector<ShapeValues> circleShapeValues;
213
214 // go over all points of the average operator
215 9620 int insideCirclePoints = 0;
216
4/4
✓ Branch 0 taken 218902 times.
✓ Branch 1 taken 9620 times.
✓ Branch 2 taken 218902 times.
✓ Branch 3 taken 9620 times.
228522 for (int k = 0; k < circlePoints.size(); ++k)
217 {
218
3/6
✓ Branch 1 taken 218902 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 218902 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 217475 times.
✗ Branch 7 not taken.
872754 const auto circleBulkElementIndices = intersectingEntities(circlePoints[k], bulkTree);
219
4/4
✓ Branch 0 taken 1427 times.
✓ Branch 1 taken 217475 times.
✓ Branch 2 taken 1427 times.
✓ Branch 3 taken 217475 times.
437804 if (circleBulkElementIndices.empty())
220
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1427 times.
1427 continue;
221
222 217475 ++insideCirclePoints;
223 217475 const auto localCircleAvgWeight = circleAvgWeight / circleBulkElementIndices.size();
224
4/4
✓ Branch 0 taken 217477 times.
✓ Branch 1 taken 217475 times.
✓ Branch 2 taken 217477 times.
✓ Branch 3 taken 217475 times.
929699 for (const auto bulkElementIdx : circleBulkElementIndices)
225 {
226
1/4
✓ Branch 1 taken 217477 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
217477 circleStencil.push_back(bulkElementIdx);
227
1/2
✓ Branch 1 taken 217477 times.
✗ Branch 2 not taken.
217477 circleIpWeight.push_back(localCircleAvgWeight);
228
229 // precompute interpolation data for box scheme for each cut bulk element
230 if constexpr (isBox<bulkIdx>())
231 {
232
1/2
✓ Branch 1 taken 59797 times.
✗ Branch 2 not taken.
59797 const auto bulkElement = bulkGridGeometry.element(bulkElementIdx);
233
2/6
✓ Branch 1 taken 59797 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 59797 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
119594 circleCornerIndices.push_back(&(this->vertexIndices(bulkIdx, bulkElementIdx)));
234
235 // evaluate shape functions at the integration point
236 59797 const auto bulkGeometry = bulkElement.geometry();
237
2/6
✓ Branch 1 taken 59797 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 59797 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
119594 ShapeValues shapeValues;
238
2/4
✓ Branch 1 taken 59797 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 59797 times.
✗ Branch 5 not taken.
119594 this->getShapeValues(bulkIdx, bulkGridGeometry, bulkGeometry, circlePoints[k], shapeValues);
239
1/2
✓ Branch 1 taken 59797 times.
✗ Branch 2 not taken.
59797 circleShapeValues.emplace_back(std::move(shapeValues));
240 }
241 }
242 }
243
244 // if the circle stencil is empty (that is the circle is entirely outside the domain)
245 // we do not add a (zero) point source
246
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9620 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9620 times.
19240 if (circleStencil.empty())
247 continue;
248
249 // export low dim circle stencil
250 if constexpr (isBox<bulkIdx>())
251 {
252 // we insert all vertices and make it unique later
253
4/4
✓ Branch 0 taken 59797 times.
✓ Branch 1 taken 2242 times.
✓ Branch 2 taken 59797 times.
✓ Branch 3 taken 2242 times.
126320 for (const auto& vertices : circleCornerIndices)
254 {
255
9/18
✓ Branch 1 taken 59797 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 59797 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 59797 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 59797 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 59797 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 59797 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 59797 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 59797 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 59797 times.
✗ Branch 26 not taken.
119594 this->couplingStencils(lowDimIdx)[lowDimElementIdx].insert(this->couplingStencils(lowDimIdx)[lowDimElementIdx].end(),
256 vertices->begin(), vertices->end());
257
258 }
259 }
260 else
261 {
262
9/18
✓ Branch 1 taken 7378 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7378 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7378 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7378 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7378 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7378 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 7378 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 7378 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 7378 times.
✗ Branch 26 not taken.
14756 this->couplingStencils(lowDimIdx)[lowDimElementIdx].insert(this->couplingStencils(lowDimIdx)[lowDimElementIdx].end(),
263 circleStencil.begin(), circleStencil.end());
264 }
265
266 // surface fraction that is inside the domain (only different than 1.0 on the boundary)
267 9620 const auto surfaceFraction = Scalar(insideCirclePoints)/Scalar(circlePoints.size());
268
269 // loop over the bulk elements at the integration points (usually one except when it is on a face or edge or vertex)
270
4/4
✓ Branch 0 taken 10310 times.
✓ Branch 1 taken 9620 times.
✓ Branch 2 taken 10310 times.
✓ Branch 3 taken 9620 times.
39170 for (auto bulkElementIdx : bulkElementIndices)
271 {
272 10310 const auto id = this->idCounter_++;
273
274
2/4
✓ Branch 1 taken 10310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10310 times.
✗ Branch 5 not taken.
20620 this->pointSources(bulkIdx).emplace_back(globalPos, id, qpweight, integrationElement*surfaceFraction, bulkElementIdx);
275
4/8
✓ Branch 1 taken 10310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10310 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10310 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 10310 times.
✗ Branch 11 not taken.
41240 this->pointSources(bulkIdx).back().setEmbeddings(bulkElementIndices.size());
276
2/4
✓ Branch 1 taken 10310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10310 times.
✗ Branch 5 not taken.
20620 this->pointSources(lowDimIdx).emplace_back(globalPos, id, qpweight, integrationElement*surfaceFraction, lowDimElementIdx);
277
4/8
✓ Branch 1 taken 10310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10310 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10310 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 10310 times.
✗ Branch 11 not taken.
41240 this->pointSources(lowDimIdx).back().setEmbeddings(bulkElementIndices.size());
278
279 // pre compute additional data used for the evaluation of
280 // the actual solution dependent source term
281
1/2
✓ Branch 1 taken 10310 times.
✗ Branch 2 not taken.
12552 PointSourceData psData;
282
283 if constexpr (isBox<lowDimIdx>())
284 {
285
1/4
✓ Branch 1 taken 236 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
236 ShapeValues shapeValues;
286
1/2
✓ Branch 1 taken 236 times.
✗ Branch 2 not taken.
236 this->getShapeValues(lowDimIdx, lowDimGridGeometry, intersectionGeometry, globalPos, shapeValues);
287
3/6
✓ Branch 1 taken 236 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 236 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 236 times.
✗ Branch 7 not taken.
708 psData.addLowDimInterpolation(shapeValues, this->vertexIndices(lowDimIdx, lowDimElementIdx), lowDimElementIdx);
288 }
289 else
290 {
291
1/2
✓ Branch 1 taken 10074 times.
✗ Branch 2 not taken.
10074 psData.addLowDimInterpolation(lowDimElementIdx);
292 }
293
294 // add data needed to compute integral over the circle
295 if constexpr (isBox<bulkIdx>())
296 {
297
1/2
✓ Branch 1 taken 2242 times.
✗ Branch 2 not taken.
2242 psData.addCircleInterpolation(circleCornerIndices, circleShapeValues, circleIpWeight, circleStencil);
298
299
1/2
✓ Branch 1 taken 2242 times.
✗ Branch 2 not taken.
2242 const auto bulkGeometry = bulkGridGeometry.element(bulkElementIdx).geometry();
300
1/4
✓ Branch 1 taken 2242 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2242 ShapeValues shapeValues;
301
1/2
✓ Branch 1 taken 2242 times.
✗ Branch 2 not taken.
2242 this->getShapeValues(bulkIdx, bulkGridGeometry, bulkGeometry, globalPos, shapeValues);
302
3/6
✓ Branch 1 taken 2242 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2242 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2242 times.
✗ Branch 7 not taken.
6726 psData.addBulkInterpolation(shapeValues, this->vertexIndices(bulkIdx, bulkElementIdx), bulkElementIdx);
303 }
304 else
305 {
306
1/2
✓ Branch 1 taken 8068 times.
✗ Branch 2 not taken.
8068 psData.addCircleInterpolation(circleIpWeight, circleStencil);
307
1/2
✓ Branch 1 taken 8068 times.
✗ Branch 2 not taken.
8068 psData.addBulkInterpolation(bulkElementIdx);
308 }
309
310 // publish point source data in the global vector
311
2/4
✓ Branch 1 taken 10310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10310 times.
✗ Branch 5 not taken.
20620 this->pointSourceData().emplace_back(std::move(psData));
312
313 // mean distance to outside element for source correction schemes
314
2/4
✓ Branch 1 taken 10310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2185 times.
✗ Branch 5 not taken.
10310 const auto outsideGeometry = bulkGridGeometry.element(bulkElementIdx).geometry();
315
3/6
✓ Branch 1 taken 10310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10310 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10310 times.
✗ Branch 8 not taken.
20620 this->averageDistanceToBulkCell().push_back(averageDistancePointGeometry(globalPos, outsideGeometry));
316
317 // export the bulk coupling stencil
318 if constexpr (isBox<lowDimIdx>())
319 {
320
7/14
✓ Branch 1 taken 236 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 236 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 236 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 236 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 236 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 236 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 236 times.
✗ Branch 20 not taken.
472 this->couplingStencils(bulkIdx)[bulkElementIdx].insert(this->couplingStencils(bulkIdx)[bulkElementIdx].end(),
321
2/4
✓ Branch 1 taken 236 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 236 times.
✗ Branch 5 not taken.
472 this->vertexIndices(lowDimIdx, lowDimElementIdx).begin(),
322
2/4
✓ Branch 1 taken 236 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 236 times.
✗ Branch 5 not taken.
472 this->vertexIndices(lowDimIdx, lowDimElementIdx).end());
323
324 }
325 else
326 {
327
3/6
✓ Branch 1 taken 10074 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10074 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10074 times.
✗ Branch 8 not taken.
20148 this->couplingStencils(bulkIdx)[bulkElementIdx].push_back(lowDimElementIdx);
328 }
329
330 // export bulk circle stencil
331 if constexpr (isBox<bulkIdx>())
332 {
333 // we insert all vertices and make it unique later
334
4/4
✓ Branch 0 taken 59797 times.
✓ Branch 1 taken 2242 times.
✓ Branch 2 taken 59797 times.
✓ Branch 3 taken 2242 times.
126320 for (const auto& vertices : circleCornerIndices)
335 {
336
9/18
✓ Branch 1 taken 59797 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 59797 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 59797 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 59797 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 59797 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 59797 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 59797 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 59797 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 59797 times.
✗ Branch 26 not taken.
119594 extendedSourceStencil_.stencil()[bulkElementIdx].insert(extendedSourceStencil_.stencil()[bulkElementIdx].end(),
337 vertices->begin(), vertices->end());
338
339 }
340 }
341 else
342 {
343
9/18
✓ Branch 1 taken 8068 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8068 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8068 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8068 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 8068 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 8068 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 8068 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 8068 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 8068 times.
✗ Branch 26 not taken.
16136 extendedSourceStencil_.stencil()[bulkElementIdx].insert(extendedSourceStencil_.stencil()[bulkElementIdx].end(),
344 circleStencil.begin(), circleStencil.end());
345 }
346 }
347 }
348 }
349
350 // make the circle stencil unique (for source derivatives)
351
2/2
✓ Branch 0 taken 2384 times.
✓ Branch 1 taken 12 times.
2432 for (auto&& stencil : extendedSourceStencil_.stencil())
352 {
353 7152 std::sort(stencil.second.begin(), stencil.second.end());
354 11920 stencil.second.erase(std::unique(stencil.second.begin(), stencil.second.end()), stencil.second.end());
355
356 // remove the vertices element (box)
357 if constexpr (isBox<bulkIdx>())
358 {
359 283 const auto& indices = this->vertexIndices(bulkIdx, stencil.first);
360 1415 stencil.second.erase(std::remove_if(stencil.second.begin(), stencil.second.end(),
361 30728 [&](auto i){ return std::find(indices.begin(), indices.end(), i) != indices.end(); }),
362 stencil.second.end());
363 }
364 // remove the own element (cell-centered)
365 else
366 {
367 10505 stencil.second.erase(std::remove_if(stencil.second.begin(), stencil.second.end(),
368
8/10
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 2802 times.
✓ Branch 2 taken 107 times.
✓ Branch 3 taken 257 times.
✓ Branch 4 taken 410 times.
✓ Branch 5 taken 337 times.
✓ Branch 6 taken 478 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1968 times.
✗ Branch 9 not taken.
6505 [&](auto i){ return i == stencil.first; }),
369 stencil.second.end());
370 }
371 }
372
373 // make stencils unique
374 using namespace Dune::Hybrid;
375 108 forEach(integralRange(Dune::index_constant<2>{}), [&](const auto domainIdx)
376 {
377
4/4
✓ Branch 0 taken 7104 times.
✓ Branch 1 taken 12 times.
✓ Branch 3 taken 2384 times.
✓ Branch 4 taken 12 times.
9584 for (auto&& stencil : this->couplingStencils(domainIdx))
378 {
379 28464 std::sort(stencil.second.begin(), stencil.second.end());
380 47440 stencil.second.erase(std::unique(stencil.second.begin(), stencil.second.end()), stencil.second.end());
381 }
382 });
383
384 36 std::cout << "took " << watch.elapsed() << " seconds." << std::endl;
385 12 }
386
387 //! Compute the low dim volume fraction in the bulk domain cells
388 12 void computeLowDimVolumeFractions()
389 {
390 // resize the storage vector
391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 lowDimVolumeInBulkElement_.resize(this->gridView(bulkIdx).size(0));
392 // get references to the grid geometries
393
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 const auto& lowDimGridGeometry = this->problem(lowDimIdx).gridGeometry();
394
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 const auto& bulkGridGeometry = this->problem(bulkIdx).gridGeometry();
395
396 // compute the low dim volume fractions
397
4/4
✓ Branch 0 taken 9429 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 9429 times.
✓ Branch 3 taken 12 times.
9465 for (const auto& is : intersections(this->glue()))
398 {
399 // all inside elements are identical...
400 9429 const auto& inside = is.targetEntity(0);
401 9429 const auto intersectionGeometry = is.geometry();
402
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2873 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2873 times.
18858 const auto lowDimElementIdx = lowDimGridGeometry.elementMapper().index(inside);
403
404 // compute the volume the low-dim domain occupies in the bulk domain if it were full-dimensional
405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9429 times.
9429 const auto radius = this->problem(lowDimIdx).spatialParams().radius(lowDimElementIdx);
406
4/4
✓ Branch 0 taken 9774 times.
✓ Branch 1 taken 9429 times.
✓ Branch 2 taken 9774 times.
✓ Branch 3 taken 9429 times.
28977 for (int outsideIdx = 0; outsideIdx < is.numDomainNeighbors(); ++outsideIdx)
407 {
408 9774 const auto& outside = is.domainEntity(outsideIdx);
409 19548 const auto bulkElementIdx = bulkGridGeometry.elementMapper().index(outside);
410 29322 lowDimVolumeInBulkElement_[bulkElementIdx] += intersectionGeometry.volume()*M_PI*radius*radius;
411 }
412 }
413 12 }
414
415 /*!
416 * \brief Methods to be accessed by the subproblems
417 */
418 // \{
419
420 //! Return a reference to the bulk problem
421 5520620 Scalar radius(std::size_t id) const
422 {
423
6/12
✗ Branch 0 not taken.
✓ Branch 1 taken 5520620 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5520620 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 81980 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 81980 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 91576 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 91576 times.
11388352 const auto& data = this->pointSourceData()[id];
424
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 5520620 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81980 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 91576 times.
5694176 return this->problem(lowDimIdx).spatialParams().radius(data.lowDimElementIdx());
425 }
426
427 //! The volume the lower dimensional domain occupies in the bulk domain element
428 // For one-dimensional low dim domain we assume radial tubes
429 Scalar lowDimVolume(const Element<bulkIdx>& element) const
430 {
431 const auto eIdx = this->problem(bulkIdx).gridGeometry().elementMapper().index(element);
432 return lowDimVolumeInBulkElement_[eIdx];
433 }
434
435 //! The volume fraction the lower dimensional domain occupies in the bulk domain element
436 // For one-dimensional low dim domain we assume radial tubes
437 Scalar lowDimVolumeFraction(const Element<bulkIdx>& element) const
438 {
439 const auto totalVolume = element.geometry().volume();
440 return lowDimVolume(element) / totalVolume;
441 }
442
443 // \}
444
445 /*!
446 * \brief Extended source stencil (for the bulk domain)
447 */
448 const typename ParentType::template CouplingStencils<bulkIdx>::mapped_type&
449 673744 extendedSourceStencil(std::size_t eIdx) const
450 {
451 673744 const auto& sourceStencils = extendedSourceStencil_.stencil();
452
4/4
✓ Branch 1 taken 4768 times.
✓ Branch 2 taken 668976 times.
✓ Branch 3 taken 4768 times.
✓ Branch 4 taken 668976 times.
2021232 if (auto stencil = sourceStencils.find(eIdx); stencil != sourceStencils.end())
453 9536 return stencil->second;
454
455 1337952 return this->emptyStencil(bulkIdx);
456 }
457
458 private:
459 //! the extended source stencil object
460 EmbeddedCoupling::ExtendedSourceStencil<ThisType> extendedSourceStencil_;
461
462 //! vector for the volume fraction of the lowdim domain in the bulk domain cells
463 std::vector<Scalar> lowDimVolumeInBulkElement_;
464 };
465
466 //! we support multithreaded assembly
467 template<class MDTraits>
468 struct CouplingManagerSupportsMultithreadedAssembly<Embedded1d3dCouplingManager<MDTraits, Embedded1d3dCouplingMode::Average>>
469 : public std::true_type {};
470
471 } // end namespace Dumux
472
473 #endif
474