version 3.11-dev
Loading...
Searching...
No Matches
couplingmanager_binary_cvfe.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-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12
13#ifndef DUMUX_MULTIDOMAIN_BOUNDARY_COUPLINGMANAGER_BINARY_CVFE_HH
14#define DUMUX_MULTIDOMAIN_BOUNDARY_COUPLINGMANAGER_BINARY_CVFE_HH
15
16#include <utility>
17#include <memory>
18#include <tuple>
19#include <vector>
20#include <unordered_map>
21#include <cassert>
22
23#include <dune/common/exceptions.hh>
24#include <dumux/common/concepts/localdofs_.hh>
25#include <dumux/common/concepts/variables_.hh>
30#include <dumux/common/typetraits/localdofs_.hh>
33
35
36namespace Dumux {
37
42template<class MDTraits>
44: public CouplingManager<MDTraits>
45{
46 using ParentType = CouplingManager<MDTraits>;
47
48public:
50private:
51 static_assert(MDTraits::numSubDomains == 2, "CouplingManagerBinaryCvfe requires exactly two subdomains");
52
53 template<std::size_t i>
54 static constexpr auto domainIdx()
55 { return typename MDTraits::template SubDomain<i>::Index{}; }
56
57 // the sub domain type tags
58 template<std::size_t id>
59 using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
60
61 template<std::size_t id> using GridView = typename GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>::GridView;
62 template<std::size_t id> using Problem = GetPropType<SubDomainTypeTag<id>, Properties::Problem>;
63 template<std::size_t id> using GridDiscretization = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
64
65 static_assert(DiscretizationMethods::isCVFE<std::decay_t<decltype(GridDiscretization<0>::discMethod)>>,
66 "CouplingManagerBinaryCvfe requires subdomain 0 to be discretized with a CVFE scheme");
67 static_assert(DiscretizationMethods::isCVFE<std::decay_t<decltype(GridDiscretization<1>::discMethod)>>,
68 "CouplingManagerBinaryCvfe requires subdomain 1 to be discretized with a CVFE scheme");
69
70 template<std::size_t id> using ElementDiscretization = typename GridDiscretization<id>::LocalView;
71 template<std::size_t id> using GridVariables = GetPropType<SubDomainTypeTag<id>, Properties::GridVariables>;
72 template<std::size_t id> using GridVariablesCache = Concept::GridVariablesCache_t<GridVariables<id>>;
73 template<std::size_t id> using Variables = Concept::Variables_t<GridVariables<id>>;
74 template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity;
75 template<std::size_t id> using PrimaryVariables = GetPropType<SubDomainTypeTag<id>, Properties::PrimaryVariables>;
76
77 using GridVariablesTuple = typename MDTraits::template TupleOfSharedPtr<GridVariables>;
78
80 using CouplingStencil = typename CouplingMapper::CouplingStencil;
81
82 template<class ElementSolution, std::size_t domainIdx, std::size_t coupledDomainIdx>
83 struct CouplingContext
84 {
85 ElementDiscretization<coupledDomainIdx> elemDisc;
86 const Problem<coupledDomainIdx>& problem;
87 ElementSolution elemSol;
88
89 template<class ScvOrLocalDof>
90 auto vars(const ScvOrLocalDof& scvOrLocalDof) const
91 {
92 Variables<coupledDomainIdx> variables;
93 if constexpr (Concept::FVGridVariables<GridVariables<coupledDomainIdx>>)
94 {
95 // the variables are still defined per sub-control volume
96 if constexpr (Concept::LocalDof<ScvOrLocalDof>)
97 variables.update(elemSol, problem, elemDisc.element(), elemDisc.scv(scvOrLocalDof.index()));
98 else
99 variables.update(elemSol, problem, elemDisc.element(), scvOrLocalDof);
100 }
101 else
102 variables.update(elemSol, problem, elemDisc, ipData(elemDisc, scvOrLocalDof));
103 return variables;
104 }
105
106 template<class ScvOrLocalDof>
107 auto operator[](const ScvOrLocalDof& scvOrLocalDof) const
108 {
109 return vars(scvOrLocalDof);
110 }
111 };
112
113public:
114
118 // \{
119
121 void init(std::shared_ptr<Problem<domainIdx<0>()>> domain0Problem,
122 std::shared_ptr<Problem<domainIdx<1>()>> domain1Problem,
123 GridVariablesTuple&& gridVariables,
125 {
126 this->setSubProblems(std::make_tuple(domain0Problem, domain1Problem));
127 gridVariables_ = std::move(gridVariables);
128 this->attachSolution(curSol);
129 couplingMapper_.update(*this);
130 }
131
132 // \}
133
134
138 // \{
139
143 template<std::size_t i, class Assembler>
144 void bindCouplingContext(Dune::index_constant<i> domainI, const Element<i>& element, const Assembler& assembler) const
145 {}
146
150 template<std::size_t i, std::size_t j, class LocalAssemblerI>
151 void updateCouplingContext(Dune::index_constant<i> domainI,
152 const LocalAssemblerI& localAssemblerI,
153 Dune::index_constant<j> domainJ,
154 std::size_t dofIdxGlobalJ,
155 const PrimaryVariables<j>& priVarsJ,
156 int pvIdxJ)
157 {
158 this->curSol(domainJ)[dofIdxGlobalJ][pvIdxJ] = priVarsJ[pvIdxJ];
159 // couplingContext() recomputes variables on-the-fly via makeCouplingContext_
160 // using the correct element from the coupling mapper, so no cache update needed here.
161 }
162
163 // \}
164
168 template<std::size_t i, class FaceIpData>
169 auto couplingContext(Dune::index_constant<i> domainI,
170 const ElementDiscretization<i>& elemDisc,
171 const FaceIpData& faceIpData) const
172 { return makeCouplingContext_(domainI, elemDisc, faceIpData); }
173
177 // \{
178
182 template<std::size_t i, std::size_t j>
183 const CouplingStencil& couplingStencil(Dune::index_constant<i> domainI,
184 const Element<i>& element,
185 Dune::index_constant<j> domainJ) const
186 {
187 const auto eIdx = Dumux::gridDiscretization(this->problem(domainI)).elementMapper().index(element);
188 return couplingMapper_.couplingStencil(domainI, eIdx, domainJ);
189 }
190
191 // \}
192
199 template<std::size_t i>
200 bool isCoupled(Dune::index_constant<i> domainI,
201 const ElementDiscretization<i>& elemDisc,
202 const typename ElementDiscretization<i>::SubControlVolumeFace& scvf) const
203 {
204 return isCoupled(domainI, elemDisc, elemDisc.intersectionIndex(scvf));
205 }
206
212 template<std::size_t i>
213 bool isCoupled(Dune::index_constant<i> domainI,
214 const typename ElementDiscretization<i>::SubControlVolume& scv) const
215 { return couplingMapper_.isCoupledDof(domainI, scv.dofIndex()); }
216
223 template<std::size_t i>
224 bool isCoupled(Dune::index_constant<i> domainI,
225 const ElementDiscretization<i>& elemDisc,
226 std::size_t iIdx) const
227 {
228 const auto eIdx = Dumux::gridDiscretization(this->problem(domainI)).elementMapper().index(elemDisc.element());
229 return couplingMapper_.isCoupled(domainI, eIdx, iIdx);
230 }
231
237 template<std::size_t i>
238 bool isCoupled(Dune::index_constant<i> domainI,
239 std::size_t dofIdx) const
240 { return couplingMapper_.isCoupledDof(domainI, dofIdx); }
241
242private:
243 template<class ElementDiscretization, class FaceIpData>
244 std::size_t intersectionIndex_(const ElementDiscretization& elemDisc,
245 const FaceIpData& faceIpData) const
246 {
247 if constexpr (requires { faceIpData.scvfIndex(); })
248 {
249 const auto& scvf = elemDisc.scvf(faceIpData.scvfIndex());
250 return elemDisc.intersectionIndex(scvf);
251 }
252 else if constexpr (requires { faceIpData.boundaryFaceIndex(); })
253 return elemDisc.boundaryFace(faceIpData.boundaryFaceIndex()).intersectionIndex();
254 else
255 DUNE_THROW(Dune::InvalidStateException, "FaceIpData must provide either scvfIndex() or boundaryFaceIndex()");
256 }
257
258 template<std::size_t i, class FaceIpData>
259 auto makeCouplingContext_(Dune::index_constant<i> domainI,
260 const ElementDiscretization<i>& elemDisc,
261 const FaceIpData& faceIpData) const
262 {
263 const auto eIdx = Dumux::gridDiscretization(this->problem(domainI)).elementMapper().index(elemDisc.element());
264 const auto iIdx = intersectionIndex_(elemDisc, faceIpData);
265
266 if (!couplingMapper_.isCoupled(domainI, eIdx, iIdx))
267 DUNE_THROW(Dune::InvalidStateException, "No coupling context found at element " << eIdx << " with intersection index " << iIdx);
268
269 const auto otherElementIdx = couplingMapper_.outsideElementIndex(domainI, eIdx, iIdx);
270 constexpr auto domainJ = Dune::index_constant<1-i>();
271 const auto& otherGridDiscretization = Dumux::gridDiscretization(this->problem(domainJ));
272 const auto& otherElement = otherGridDiscretization.element(otherElementIdx);
273 auto otherElemDisc = localView(otherGridDiscretization).bind(otherElement);
274 const auto elemSol = elementSolution(otherElement, this->curSol(domainJ), otherGridDiscretization);
275 return CouplingContext<decltype(elemSol), i, 1-i>{ std::move(otherElemDisc), this->problem(domainJ), std::move(elemSol) };
276 }
277
278 CouplingMapper couplingMapper_;
279 GridVariablesTuple gridVariables_;
280};
281
282} // end namespace Dumux
283
284#endif
Coupling manager for coupling two domains both discretized with CVFE schemes.
Definition couplingmanager_binary_cvfe.hh:45
auto couplingContext(Dune::index_constant< i > domainI, const ElementDiscretization< i > &elemDisc, const FaceIpData &faceIpData) const
Access the coupling context for domain i.
Definition couplingmanager_binary_cvfe.hh:169
void bindCouplingContext(Dune::index_constant< i > domainI, const Element< i > &element, const Assembler &assembler) const
Methods to be accessed by the assembly.
Definition couplingmanager_binary_cvfe.hh:144
void updateCouplingContext(Dune::index_constant< i > domainI, const LocalAssemblerI &localAssemblerI, Dune::index_constant< j > domainJ, std::size_t dofIdxGlobalJ, const PrimaryVariables< j > &priVarsJ, int pvIdxJ)
Update the coupling context.
Definition couplingmanager_binary_cvfe.hh:151
typename ParentType::SolutionVectorStorage SolutionVectorStorage
Definition couplingmanager_binary_cvfe.hh:49
bool isCoupled(Dune::index_constant< i > domainI, const typename ElementDiscretization< i >::SubControlVolume &scv) const
If the boundary entity is on a coupling boundary.
Definition couplingmanager_binary_cvfe.hh:213
const CouplingStencil & couplingStencil(Dune::index_constant< i > domainI, const Element< i > &element, Dune::index_constant< j > domainJ) const
The coupling stencils.
Definition couplingmanager_binary_cvfe.hh:183
bool isCoupled(Dune::index_constant< i > domainI, const ElementDiscretization< i > &elemDisc, std::size_t iIdx) const
If the boundary entity is on a coupling boundary.
Definition couplingmanager_binary_cvfe.hh:224
bool isCoupled(Dune::index_constant< i > domainI, std::size_t dofIdx) const
If the boundary entity is on a coupling boundary.
Definition couplingmanager_binary_cvfe.hh:238
bool isCoupled(Dune::index_constant< i > domainI, const ElementDiscretization< i > &elemDisc, const typename ElementDiscretization< i >::SubControlVolumeFace &scvf) const
If the boundary entity is on a coupling boundary.
Definition couplingmanager_binary_cvfe.hh:200
void init(std::shared_ptr< Problem< domainIdx< 0 >()> > domain0Problem, std::shared_ptr< Problem< domainIdx< 1 >()> > domain1Problem, GridVariablesTuple &&gridVariables, const SolutionVectorStorage &curSol)
Methods to be accessed by main.
Definition couplingmanager_binary_cvfe.hh:121
void attachSolution(const SolutionVectorStorage &curSol)
Definition multidomain/couplingmanager.hh:331
void setSubProblems(const std::tuple< std::shared_ptr< SubProblems >... > &problems)
Definition multidomain/couplingmanager.hh:296
const Problem< i > & problem(Dune::index_constant< i > domainIdx) const
Definition multidomain/couplingmanager.hh:318
SubSolutionVector< i > & curSol(Dune::index_constant< i > domainIdx)
Definition multidomain/couplingmanager.hh:347
CouplingManager()
Definition multidomain/couplingmanager.hh:70
typename MDTraits::template TupleOfSharedPtr< SubSolutionVector > SolutionVectorStorage
Definition multidomain/couplingmanager.hh:59
Mapper for the boundary coupling of two domains of equal dimension using the boundary faces for coupl...
Definition couplingmapper_boundaryfaces.hh:40
std::vector< std::size_t > CouplingStencil
Definition couplingmapper_boundaryfaces.hh:60
Defines all properties used in Dumux.
Mapper for the boundary coupling of two domains of equal dimension using the boundary faces for coupl...
Classes representing interpolation point data for control-volume finite element schemes.
Element solution classes and factory functions.
Type traits for classes providing a grid discretization.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethods::cctpfa||GridGeometry::discMethod==DiscretizationMethods::ccmpfa, CCElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for cell-centered schemes.
Definition cellcentered/elementsolution.hh:101
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
decltype(auto) gridDiscretization(const T &t, Args &&... args)
The grid discretization.
Definition griddiscretization.hh:65
The available discretization methods in Dumux.
The interface of the coupling manager for multi domain problems.
constexpr bool isCVFE
Definition method.hh:67
Definition adapt.hh:17