version 3.10-dev
boundary/darcydarcy/couplingmapper.hh
Go to the documentation of this file.
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//
13#ifndef DUMUX_MULTIDOMAIN_DARCYDARCY_BOUNDARY_COUPLINGMAPPER_HH
14#define DUMUX_MULTIDOMAIN_DARCYDARCY_BOUNDARY_COUPLINGMAPPER_HH
15
16#include <iostream>
17#include <unordered_map>
18#include <tuple>
19#include <vector>
20
21#include <dune/common/timer.hh>
22#include <dune/common/exceptions.hh>
23#include <dune/common/indices.hh>
24
27
28namespace Dumux {
29
35template<class MDTraits>
37{
38 using Scalar = typename MDTraits::Scalar;
39
40 template<std::size_t i> using GridGeometry = typename MDTraits::template SubDomain<i>::GridGeometry;
41 template<std::size_t i> using SubControlVolumeFace = typename GridGeometry<i>::SubControlVolumeFace;
42 template<std::size_t i> using GridView = typename GridGeometry<i>::GridView;
43 template<std::size_t i> using Element = typename GridView<i>::template Codim<0>::Entity;
44
45 template<std::size_t i>
46 static constexpr auto domainIdx()
47 { return typename MDTraits::template SubDomain<i>::Index{}; }
48
49 template<std::size_t i>
50 static constexpr bool isCCTpfa()
51 { return GridGeometry<i>::discMethod == DiscretizationMethods::cctpfa; }
52
53 struct ScvfInfo
54 {
55 std::size_t eIdxOutside;
56 std::size_t flipScvfIdx;
57 };
58
59 using FlipScvfMapType = std::unordered_map<std::size_t, ScvfInfo>;
60 using MapType = std::unordered_map<std::size_t, std::vector<std::size_t>>;
61
62 static constexpr std::size_t numSD = MDTraits::numSubDomains;
63
64public:
68 template<class CouplingManager>
69 void update(const CouplingManager& couplingManager)
70 {
71 // TODO: Box and multiple domains
72 static_assert(numSD == 2, "More than two subdomains not implemented!");
73 static_assert(isCCTpfa<0>() && isCCTpfa<1>(), "Only cctpfa implemented!");
74
75 Dune::Timer watch;
76 std::cout << "Initializing the coupling map..." << std::endl;
77
78 for (std::size_t domIdx = 0; domIdx < numSD; ++domIdx)
79 {
80 stencils_[domIdx].clear();
81 scvfInfo_[domIdx].clear();
82 }
83
84 const auto& problem0 = couplingManager.problem(domainIdx<0>());
85 const auto& problem1 = couplingManager.problem(domainIdx<1>());
86 const auto& gg0 = problem0.gridGeometry();
87 const auto& gg1 = problem1.gridGeometry();
88
89 isCoupledScvf_[0].resize(gg0.numScvf(), false);
90 isCoupledScvf_[1].resize(gg1.numScvf(), false);
91
92 for (const auto& element0 : elements(gg0.gridView()))
93 {
94 auto fvGeometry0 = localView(gg0);
95 fvGeometry0.bindElement(element0);
96
97 for (const auto& scvf0 : scvfs(fvGeometry0))
98 {
99 // skip all non-boundaries
100 if (!scvf0.boundary())
101 continue;
102
103 // get elements intersecting with the scvf center
104 // for robustness add epsilon in unit outer normal direction
105 const auto eps = (scvf0.ipGlobal() - element0.geometry().corner(0)).two_norm()*1e-8;
106 auto globalPos = scvf0.ipGlobal(); globalPos.axpy(eps, scvf0.unitOuterNormal());
107 const auto indices = intersectingEntities(globalPos, gg1.boundingBoxTree());
108
109 // skip if no intersection was found
110 if (indices.empty())
111 continue;
112
113 // sanity check
114 if (indices.size() > 1)
115 DUNE_THROW(Dune::InvalidStateException, "Are you sure your grids is conforming at the boundary?");
116
117 // add the pair to the multimap
118 const auto eIdx0 = gg0.elementMapper().index(element0);
119 const auto eIdx1 = indices[0];
120 stencils_[0][eIdx0].push_back(eIdx1);
121
122 // mark the scvf and find and mark the flip scvf
123 isCoupledScvf_[0][scvf0.index()] = true;
124 const auto& element1 = gg1.element(eIdx1);
125 auto fvGeometry1 = localView(gg1);
126 fvGeometry1.bindElement(element1);
127
128 using std::abs;
129 for (const auto& scvf1 : scvfs(fvGeometry1))
130 if (scvf1.boundary())
131 if (abs(scvf1.unitOuterNormal()*scvf0.unitOuterNormal() + 1) < eps)
132 {
133 isCoupledScvf_[1][scvf1.index()] = true;
134 scvfInfo_[0][scvf0.index()] = ScvfInfo{eIdx1, scvf1.index()};
135 scvfInfo_[1][scvf1.index()] = ScvfInfo{eIdx0, scvf0.index()};
136 }
137 }
138 }
139
140 // create the inverse map for efficient access
141 for (const auto& entry : stencils_[0])
142 for (const auto idx : entry.second)
143 stencils_[1][idx].push_back(entry.first);
144
145 std::cout << "took " << watch.elapsed() << " seconds." << std::endl;
146 }
147
162 template<std::size_t i, std::size_t j>
163 const std::vector<std::size_t>& couplingStencil(Dune::index_constant<i> domainI,
164 const std::size_t eIdxI,
165 Dune::index_constant<j> domainJ) const
166 {
167 static_assert(i != j, "A domain cannot be coupled to itself!");
168 if (isCoupledElement(domainI, eIdxI))
169 return stencils_[i].at(eIdxI);
170 else
171 return emptyStencil_;
172 }
173
177 template<std::size_t i>
178 bool isCoupledElement(Dune::index_constant<i>, std::size_t eIdx) const
179 { return static_cast<bool>(stencils_[i].count(eIdx)); }
180
186 template<std::size_t i>
187 bool isCoupled(Dune::index_constant<i> domainI,
188 const SubControlVolumeFace<i>& scvf) const
189 {
190 return isCoupledScvf_[i].at(scvf.index());
191 }
192
198 template<std::size_t i>
199 std::size_t flipScvfIndex(Dune::index_constant<i> domainI,
200 const SubControlVolumeFace<i>& scvf) const
201 {
202 return scvfInfo_[i].at(scvf.index()).flipScvfIdx;
203 }
204
210 template<std::size_t i>
211 std::size_t outsideElementIndex(Dune::index_constant<i> domainI,
212 const SubControlVolumeFace<i>& scvf) const
213 {
214 return scvfInfo_[i].at(scvf.index()).eIdxOutside;
215 }
216
217private:
218 std::array<MapType, numSD> stencils_;
219 std::vector<std::size_t> emptyStencil_;
220 std::array<std::vector<bool>, numSD> isCoupledScvf_;
221 std::array<FlipScvfMapType, numSD> scvfInfo_;
222};
223
224} // end namespace Dumux
225
226#endif
The interface of the coupling manager for multi domain problems.
Definition: multidomain/couplingmanager.hh:37
const Problem< i > & problem(Dune::index_constant< i > domainIdx) const
Return a reference to the sub problem.
Definition: multidomain/couplingmanager.hh:298
the default mapper for conforming equal dimension boundary coupling between two domains (box or cc)
Definition: boundary/darcydarcy/couplingmapper.hh:37
bool isCoupledElement(Dune::index_constant< i >, std::size_t eIdx) const
Return if an element residual with index eIdx of domain i is coupled to domain j.
Definition: boundary/darcydarcy/couplingmapper.hh:178
void update(const CouplingManager &couplingManager)
Main update routine.
Definition: boundary/darcydarcy/couplingmapper.hh:69
const std::vector< std::size_t > & couplingStencil(Dune::index_constant< i > domainI, const std::size_t eIdxI, Dune::index_constant< j > domainJ) const
returns an iterable container of all indices of degrees of freedom of domain j that couple with / inf...
Definition: boundary/darcydarcy/couplingmapper.hh:163
std::size_t outsideElementIndex(Dune::index_constant< i > domainI, const SubControlVolumeFace< i > &scvf) const
Return the outside element index (the element index of the other domain)
Definition: boundary/darcydarcy/couplingmapper.hh:211
bool isCoupled(Dune::index_constant< i > domainI, const SubControlVolumeFace< i > &scvf) const
If the boundary entity is on a coupling boundary.
Definition: boundary/darcydarcy/couplingmapper.hh:187
std::size_t flipScvfIndex(Dune::index_constant< i > domainI, const SubControlVolumeFace< i > &scvf) const
Return the scvf index of the flipped scvf in the other domain.
Definition: boundary/darcydarcy/couplingmapper.hh:199
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:26
std::vector< std::size_t > intersectingEntities(const Dune::FieldVector< ctype, dimworld > &point, const BoundingBoxTree< EntitySet > &tree, bool isCartesianGrid=false)
Compute all intersections between entities and a point.
Definition: intersectingentities.hh:102
Algorithms that finds which geometric entities intersect.
The available discretization methods in Dumux.
constexpr CCTpfa cctpfa
Definition: method.hh:145
Definition: adapt.hh:17