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_LINE_HH | ||
14 | #define DUMUX_MULTIDOMAIN_EMBEDDED_COUPLINGMANAGER_1D3D_LINE_HH | ||
15 | |||
16 | #include <vector> | ||
17 | |||
18 | #include <dumux/common/tag.hh> | ||
19 | #include <dumux/common/properties.hh> | ||
20 | #include <dumux/common/indextraits.hh> | ||
21 | |||
22 | #include <dumux/multidomain/embedded/couplingmanagerbase.hh> | ||
23 | |||
24 | namespace Dumux { | ||
25 | |||
26 | namespace Embedded1d3dCouplingMode { | ||
27 | struct Line : public Utility::Tag<Line> { | ||
28 | static std::string name() { return "line"; } | ||
29 | }; | ||
30 | |||
31 | inline constexpr Line line{}; | ||
32 | } // end namespace Embedded1d3dCouplingMode | ||
33 | |||
34 | // forward declaration | ||
35 | template<class MDTraits, class CouplingMode> | ||
36 | class Embedded1d3dCouplingManager; | ||
37 | |||
38 | /*! | ||
39 | * \ingroup EmbeddedCoupling | ||
40 | * \brief Manages the coupling between bulk elements and lower dimensional elements | ||
41 | * Point sources on each integration point are computed by an AABB tree. | ||
42 | * \note Specialization for coupling method using line sources with 3d quantities evaluated on the line | ||
43 | * \note This is the simplest method but it mathematically not well defined as the 3d quantity is evaluated | ||
44 | * where the solution to the continuous problem has a singularity | ||
45 | */ | ||
46 | template<class MDTraits> | ||
47 | class Embedded1d3dCouplingManager<MDTraits, Embedded1d3dCouplingMode::Line> | ||
48 | : public EmbeddedCouplingManagerBase<MDTraits, Embedded1d3dCouplingManager<MDTraits, Embedded1d3dCouplingMode::Line>> | ||
49 | { | ||
50 | using ThisType = Embedded1d3dCouplingManager<MDTraits, Embedded1d3dCouplingMode::Line>; | ||
51 | using ParentType = EmbeddedCouplingManagerBase<MDTraits, ThisType>; | ||
52 | |||
53 | using Scalar = typename MDTraits::Scalar; | ||
54 | using SolutionVector = typename MDTraits::SolutionVector; | ||
55 | |||
56 | static constexpr auto bulkIdx = typename MDTraits::template SubDomain<0>::Index(); | ||
57 | static constexpr auto lowDimIdx = typename MDTraits::template SubDomain<1>::Index(); | ||
58 | |||
59 | // the sub domain type aliases | ||
60 | template<std::size_t id> using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag; | ||
61 | template<std::size_t id> using Problem = GetPropType<SubDomainTypeTag<id>, Properties::Problem>; | ||
62 | template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>; | ||
63 | template<std::size_t id> using GridView = typename GridGeometry<id>::GridView; | ||
64 | template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity; | ||
65 | template<std::size_t id> using GridIndex = typename IndexTraits<GridView<id>>::GridIndex; | ||
66 | |||
67 | public: | ||
68 | static constexpr Embedded1d3dCouplingMode::Line couplingMode{}; | ||
69 | |||
70 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | using ParentType::ParentType; |
71 | |||
72 | 1 | void init(std::shared_ptr<Problem<bulkIdx>> bulkProblem, | |
73 | std::shared_ptr<Problem<lowDimIdx>> lowDimProblem, | ||
74 | const SolutionVector& curSol) | ||
75 | { | ||
76 |
3/10✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
|
2 | ParentType::init(bulkProblem, lowDimProblem, curSol); |
77 | 1 | computeLowDimVolumeFractions(); | |
78 | 1 | } | |
79 | |||
80 | //! Compute the low dim volume fraction in the bulk domain cells | ||
81 | 1 | void computeLowDimVolumeFractions() | |
82 | { | ||
83 | // resize the storage vector | ||
84 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | lowDimVolumeInBulkElement_.resize(this->gridView(bulkIdx).size(0)); |
85 | // get references to the grid geometries | ||
86 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | const auto& lowDimGridGeometry = this->problem(lowDimIdx).gridGeometry(); |
87 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | const auto& bulkGridGeometry = this->problem(bulkIdx).gridGeometry(); |
88 | |||
89 | // compute the low dim volume fractions | ||
90 |
4/4✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 1 times.
|
23 | for (const auto& is : intersections(this->glue())) |
91 | { | ||
92 | // all inside elements are identical... | ||
93 | 20 | const auto& inside = is.targetEntity(0); | |
94 | 20 | const auto intersectionGeometry = is.geometry(); | |
95 | 40 | const auto lowDimElementIdx = lowDimGridGeometry.elementMapper().index(inside); | |
96 | |||
97 | // compute the volume the low-dim domain occupies in the bulk domain if it were full-dimensional | ||
98 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | const auto radius = this->problem(lowDimIdx).spatialParams().radius(lowDimElementIdx); |
99 |
4/4✓ Branch 0 taken 80 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 20 times.
|
180 | for (int outsideIdx = 0; outsideIdx < is.numDomainNeighbors(); ++outsideIdx) |
100 | { | ||
101 | 80 | const auto& outside = is.domainEntity(outsideIdx); | |
102 | 160 | const auto bulkElementIdx = bulkGridGeometry.elementMapper().index(outside); | |
103 | 240 | lowDimVolumeInBulkElement_[bulkElementIdx] += intersectionGeometry.volume()*M_PI*radius*radius; | |
104 | } | ||
105 | } | ||
106 | 1 | } | |
107 | |||
108 | /*! | ||
109 | * \brief Methods to be accessed by the subproblems | ||
110 | */ | ||
111 | // \{ | ||
112 | |||
113 | //! Return a reference to the bulk problem | ||
114 | ✗ | Scalar radius(std::size_t id) const | |
115 | { | ||
116 |
4/12✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1760 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1760 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 800 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 800 times.
|
5120 | const auto& data = this->pointSourceData()[id]; |
117 |
2/6✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1760 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 800 times.
|
2560 | return this->problem(lowDimIdx).spatialParams().radius(data.lowDimElementIdx()); |
118 | } | ||
119 | |||
120 | //! The volume the lower dimensional domain occupies in the bulk domain element | ||
121 | // For one-dimensional low dim domain we assume radial tubes | ||
122 | Scalar lowDimVolume(const Element<bulkIdx>& element) const | ||
123 | { | ||
124 | const auto eIdx = this->problem(bulkIdx).gridGeometry().elementMapper().index(element); | ||
125 | return lowDimVolumeInBulkElement_[eIdx]; | ||
126 | } | ||
127 | |||
128 | //! The volume fraction the lower dimensional domain occupies in the bulk domain element | ||
129 | // For one-dimensional low dim domain we assume radial tubes | ||
130 | Scalar lowDimVolumeFraction(const Element<bulkIdx>& element) const | ||
131 | { | ||
132 | const auto totalVolume = element.geometry().volume(); | ||
133 | return lowDimVolume(element) / totalVolume; | ||
134 | } | ||
135 | |||
136 | // \} | ||
137 | |||
138 | private: | ||
139 | //! vector for the volume fraction of the lowdim domain in the bulk domain cells | ||
140 | std::vector<Scalar> lowDimVolumeInBulkElement_; | ||
141 | }; | ||
142 | |||
143 | //! we support multithreaded assembly | ||
144 | template<class MDTraits> | ||
145 | struct CouplingManagerSupportsMultithreadedAssembly<Embedded1d3dCouplingManager<MDTraits, Embedded1d3dCouplingMode::Line>> | ||
146 | : public std::true_type {}; | ||
147 | |||
148 | } // end namespace Dumux | ||
149 | |||
150 | #endif | ||
151 |