3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
25#ifndef DUMUX_MULTIDOMAIN_BOUNDARY_FFPM_FFMMOMENTUMPORENETWORK_COUPLINGMANAGER_HH
26#define DUMUX_MULTIDOMAIN_BOUNDARY_FFPM_FFMMOMENTUMPORENETWORK_COUPLINGMANAGER_HH
27
28#include <utility>
29#include <memory>
30
31#include <dune/common/float_cmp.hh>
32#include <dune/common/exceptions.hh>
37
38namespace Dumux {
39
44template<class MDTraits>
46: public CouplingManager<MDTraits>
47{
48 using Scalar = typename MDTraits::Scalar;
50
51public:
52 static constexpr auto freeFlowMomentumIndex = typename MDTraits::template SubDomain<0>::Index();
53 static constexpr auto poreNetworkIndex = typename MDTraits::template SubDomain<1>::Index();
54
56private:
57 // obtain the type tags of the sub problems
58 using FreeFlowMomentumTypeTag = typename MDTraits::template SubDomain<freeFlowMomentumIndex>::TypeTag;
59 using PoreNetworkTypeTag = typename MDTraits::template SubDomain<poreNetworkIndex>::TypeTag;
60
61 using CouplingStencils = std::unordered_map<std::size_t, std::vector<std::size_t> >;
62 using CouplingStencil = CouplingStencils::mapped_type;
63
64 // the sub domain type tags
65 template<std::size_t id>
66 using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
67
68 template<std::size_t id> using GridView = typename GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>::GridView;
69 template<std::size_t id> using Problem = GetPropType<SubDomainTypeTag<id>, Properties::Problem>;
70 template<std::size_t id> using ElementVolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::LocalView;
71 template<std::size_t id> using GridVolumeVariables = GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>;
72 template<std::size_t id> using VolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::VolumeVariables;
73 template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
74 template<std::size_t id> using FVElementGeometry = typename GridGeometry<id>::LocalView;
75 template<std::size_t id> using GridVariables = GetPropType<SubDomainTypeTag<id>, Properties::GridVariables>;
76 template<std::size_t id> using GridFluxVariablesCache = GetPropType<SubDomainTypeTag<id>, Properties::GridFluxVariablesCache>;
77 template<std::size_t id> using ElementFluxVariablesCache = typename GridFluxVariablesCache<id>::LocalView;
78 template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity;
79 template<std::size_t id> using PrimaryVariables = GetPropType<SubDomainTypeTag<id>, Properties::PrimaryVariables>;
80 template<std::size_t id> using SubControlVolumeFace = typename FVElementGeometry<id>::SubControlVolumeFace;
81 template<std::size_t id> using SubControlVolume = typename FVElementGeometry<id>::SubControlVolume;
82
83 using VelocityVector = typename Element<freeFlowMomentumIndex>::Geometry::GlobalCoordinate;
84
85 struct FreeFlowMomentumCouplingContext
86 {
87 FVElementGeometry<poreNetworkIndex> fvGeometry;
88 ElementVolumeVariables<poreNetworkIndex> elemVolVars;
89 ElementFluxVariablesCache<poreNetworkIndex> elemFluxVarsCache;
90 std::size_t poreNetworkDofIdx;
91 };
92
93 struct PoreNetworkCouplingContext
94 {
95 SubControlVolumeFace<freeFlowMomentumIndex> freeFlowMomentumScvf;
96 VelocityVector faceVelocity;
97 std::size_t freeFlowMomentumDofIdx;
98 };
99
100 using CouplingMapper = StaggeredFreeFlowPoreNetworkCouplingMapper;
101 using GridVariablesTuple = typename MDTraits::template TupleOfSharedPtr<GridVariables>;
102
103public:
104
108 // \{
109
111 void init(std::shared_ptr<Problem<freeFlowMomentumIndex>> freeFlowMomentumProblem,
112 std::shared_ptr<Problem<poreNetworkIndex>> porousMediumProblem,
113 GridVariablesTuple&& gridVariables,
114 std::shared_ptr<CouplingMapper> couplingMapper,
116 {
117 couplingMapper_ = couplingMapper;
118 gridVariables_ = gridVariables;
119 this->setSubProblems(std::make_tuple(freeFlowMomentumProblem, porousMediumProblem));
120 this->attachSolution(curSol);
121 }
122
123 // \}
124
125
129 // \{
130
134 template<std::size_t i, class Assembler>
135 void bindCouplingContext(Dune::index_constant<i> domainI, const Element<i>& element, const Assembler& assembler) const
136 {
137 bindCouplingContext_(domainI, element);
138 }
139
143 template<std::size_t i>
144 void bindCouplingContext(Dune::index_constant<i> domainI, const Element<i>& element) const
145 {
146 bindCouplingContext_(domainI, element);
147 }
148
152 template<std::size_t i, std::size_t j, class LocalAssemblerI>
153 void updateCouplingContext(Dune::index_constant<i> domainI,
154 const LocalAssemblerI& localAssemblerI,
155 Dune::index_constant<j> domainJ,
156 std::size_t dofIdxGlobalJ,
157 const PrimaryVariables<j>& priVarsJ,
158 int pvIdxJ)
159 {
160 this->curSol(domainJ)[dofIdxGlobalJ][pvIdxJ] = priVarsJ[pvIdxJ];
161
162 const auto eIdx = localAssemblerI.fvGeometry().gridGeometry().elementMapper().index(localAssemblerI.fvGeometry().element());
163 if (!isCoupledElement_(domainI, eIdx))
164 return;
165
166 // we need to update all solution-depenent components of the coupling context
167 // the dof of domain J has been deflected
168
169 // update the faceVelocity in the PoreNetworkCouplingContext
170 if constexpr (domainJ == freeFlowMomentumIndex)
171 {
172 // we only need to update if we are assembling the porous medium domain
173 // since the freeflow domain will not use the velocity from the context
174 if constexpr (domainI == poreNetworkIndex)
175 {
176 auto& context = std::get<poreNetworkIndex>(couplingContext_);
177 for (auto& c : context)
178 {
179 if (c.freeFlowMomentumDofIdx == dofIdxGlobalJ)
180 {
181 assert(c.freeFlowMomentumScvf.isFrontal() && c.freeFlowMomentumScvf.boundary());
182 c.faceVelocity = faceVelocity(c.freeFlowMomentumScvf, c.freeFlowMomentumDofIdx);
183 }
184 }
185 }
186 }
187
188 // update the elemVolVars and elemFluxVarsCache in the FreeFlowMomentumCouplingContext
189 else if constexpr (domainJ == poreNetworkIndex)
190 {
191 assert(couplingContextBoundForElement_[domainI] == localAssemblerI.fvGeometry().gridGeometry().elementMapper().index(localAssemblerI.fvGeometry().element()));
192 // there is only one context per coupled free-flow momentum dof
193 auto& context = std::get<freeFlowMomentumIndex>(couplingContext_)[0];
194 const auto& ggJ = context.fvGeometry.gridGeometry();
195 const auto& element = context.fvGeometry.element();
196 const auto elemSol = elementSolution(element, this->curSol(domainJ), ggJ);
197
198 for (const auto& scv : scvs(context.fvGeometry))
199 {
200 if (scv.dofIndex() == dofIdxGlobalJ)
201 {
202 if constexpr (ElementVolumeVariables<poreNetworkIndex>::GridVolumeVariables::cachingEnabled)
203 gridVars_(poreNetworkIndex).curGridVolVars().volVars(scv).update(std::move(elemSol), this->problem(domainJ), element, scv);
204 else
205 context.elemVolVars[scv].update(std::move(elemSol), this->problem(domainJ), element, scv);
206 }
207 }
208
209 const auto& scvf = context.fvGeometry.scvf(0);
210 if constexpr (ElementFluxVariablesCache<poreNetworkIndex>::GridFluxVariablesCache::cachingEnabled)
211 {
212 const auto eIdx = ggJ.elementMapper().index(element);
213 gridVars_(poreNetworkIndex).gridFluxVarsCache().cache(eIdx, scvf.index()).update(this->problem(domainJ), element, context.fvGeometry, context.elemVolVars, scvf);
214 }
215 else
216 context.elemFluxVarsCache[scvf].update(this->problem(domainJ), element, context.fvGeometry, context.elemVolVars, scvf);
217 }
218 }
219
220 // \}
221
225 const auto& couplingContext(const FVElementGeometry<freeFlowMomentumIndex>& fvGeometry,
226 const SubControlVolumeFace<freeFlowMomentumIndex> scvf) const
227 {
228 auto& contexts = std::get<freeFlowMomentumIndex>(couplingContext_);
229
230 if (contexts.empty() || couplingContextBoundForElement_[freeFlowMomentumIndex] != fvGeometry.elementIndex())
231 bindCouplingContext_(freeFlowMomentumIndex, fvGeometry);
232
233
234 return contexts[0];
235 }
236
240 const auto& couplingContext(const FVElementGeometry<poreNetworkIndex>& fvGeometry,
241 const SubControlVolume<poreNetworkIndex> scv) const
242 {
243 auto& contexts = std::get<poreNetworkIndex>(couplingContext_);
244
245 const auto eIdx = fvGeometry.gridGeometry().elementMapper().index(fvGeometry.element());
246 if (contexts.empty() || couplingContextBoundForElement_[poreNetworkIndex] != eIdx)
247 bindCouplingContext_(poreNetworkIndex, fvGeometry);
248
249 return contexts;
250 }
251
255 // \{
256
260 const CouplingStencil& couplingStencil(Dune::index_constant<poreNetworkIndex> domainI,
261 const Element<poreNetworkIndex>& element,
262 Dune::index_constant<freeFlowMomentumIndex> domainJ) const
263 {
264 const auto eIdx = this->problem(domainI).gridGeometry().elementMapper().index(element);
265 return couplingMapper_->poreNetworkToFreeFlowMomentumCouplingStencil(eIdx);
266 }
267
277 const CouplingStencil& couplingStencil(Dune::index_constant<freeFlowMomentumIndex> domainI,
278 const Element<freeFlowMomentumIndex>& elementI,
279 const SubControlVolume<freeFlowMomentumIndex>& scvI,
280 Dune::index_constant<poreNetworkIndex> domainJ) const
281 {
282 return couplingMapper_->freeFlowMomentumToPoreNetworkCouplingStencil(scvI.dofIndex());
283 }
284
286
291 template<class LocalAssemblerI, std::size_t j>
292 decltype(auto) evalCouplingResidual(Dune::index_constant<freeFlowMomentumIndex> domainI,
293 const LocalAssemblerI& localAssemblerI,
294 const SubControlVolume<freeFlowMomentumIndex>& scvI,
295 Dune::index_constant<j> domainJ,
296 std::size_t dofIdxGlobalJ) const
297 {
298 return localAssemblerI.evalLocalResidual();
299 }
300
301 // \}
302
306 bool isCoupledLateralScvf(Dune::index_constant<freeFlowMomentumIndex> domainI, const SubControlVolumeFace<freeFlowMomentumIndex>& scvf) const
307 { return couplingMapper_->isCoupledFreeFlowMomentumLateralScvf(scvf.index()); }
308
312 bool isCoupled(Dune::index_constant<freeFlowMomentumIndex> domainI, const SubControlVolumeFace<freeFlowMomentumIndex>& scvf) const
313 {
314 return couplingMapper_->isCoupledFreeFlowMomentumScvf(scvf.index()) || couplingMapper_->isCoupledFreeFlowMomentumLateralScvf(scvf.index());
315 }
316
322 bool isCoupled(Dune::index_constant<poreNetworkIndex> domainI,
323 const SubControlVolume<poreNetworkIndex>& scv) const
324 { return couplingMapper_->isCoupledPoreNetworkDof(scv.dofIndex()); }
325
329 auto faceVelocity(const SubControlVolumeFace<freeFlowMomentumIndex>& scvf,
330 std::size_t freeFlowMomentumDofIdx) const
331 {
332 // create a unit normal vector oriented in positive coordinate direction
333 auto velocity = scvf.unitOuterNormal();
334 using std::abs;
335 std::for_each(velocity.begin(), velocity.end(), [](auto& v){ v = abs(v); });
336
337 // create the actual velocity vector
338 velocity *= this->curSol(freeFlowMomentumIndex)[freeFlowMomentumDofIdx];
339
340 return velocity;
341 }
342
343private:
344
348 template<std::size_t i>
349 bool isCoupledElement_(Dune::index_constant<i> domainI, std::size_t eIdx) const
350 {
351 if constexpr (i == freeFlowMomentumIndex)
352 return couplingMapper_->isCoupledFreeFlowElement(eIdx);
353 else
354 return couplingMapper_->isCoupledPoreNetworkElement(eIdx);
355 }
356
360 template<std::size_t i>
361 void bindCouplingContext_(Dune::index_constant<i> domainI, const Element<i>& element) const
362 {
363 const auto fvGeometry = localView(this->problem(domainI).gridGeometry()).bindElement(element);
364 bindCouplingContext_(domainI, fvGeometry);
365 }
366
370 void bindCouplingContext_(Dune::index_constant<freeFlowMomentumIndex> domainI, const FVElementGeometry<freeFlowMomentumIndex>& fvGeometry) const
371 {
372 auto& context = std::get<domainI>(couplingContext_);
373 const auto eIdx = fvGeometry.elementIndex();
374
375 // do nothing if the element is already correctly bound
376 if ((!context.empty() && couplingContextBoundForElement_[domainI] == eIdx))
377 return;
378
379 bool bindElement = false;
380 std::size_t actuallyCoupledFreeFlowElementIndex;
381
382 // if the element is directly coupled to a lowDim dof,
383 // bind the element itself
384 if (couplingMapper_->isCoupledFreeFlowElement(eIdx))
385 {
386 bindElement = true;
387 actuallyCoupledFreeFlowElementIndex = eIdx;
388 }
389 else
390 {
391 // if we assemble another element that is not directly coupled to the lowDim dof
392 // but shares an intersection (and hence, a dof) with a neighbor element that does, bind that neighbor
393 for (const auto& intersection : intersections(fvGeometry.gridGeometry().gridView(), fvGeometry.element()))
394 {
395 const auto dofIdx = fvGeometry.gridGeometry().intersectionMapper().globalIntersectionIndex(fvGeometry.element(), intersection.indexInInside());
396 if (couplingMapper_->isCoupledFreeFlowMomentumDof(dofIdx))
397 {
398 bindElement = true;
399 actuallyCoupledFreeFlowElementIndex = fvGeometry.gridGeometry().elementMapper().index(intersection.outside());
400 }
401 }
402 }
403
404 // do nothing if the element is not coupled to the other domain
405 if (!bindElement)
406 return;
407
408 context.clear();
409 couplingContextBoundForElement_[domainI] = eIdx;
410
411 auto poreNetworkFVGeometry = localView(this->problem(poreNetworkIndex).gridGeometry());
412 auto poreNetworkElemVolVars = localView(gridVars_(poreNetworkIndex).curGridVolVars());
413 auto poreNetworkElemFluxVarsCache = localView(gridVars_(poreNetworkIndex).gridFluxVarsCache());
414
415 const auto poreNetworkElemIdx = couplingMapper_->freeFlowElementToPNMElementMap().at(actuallyCoupledFreeFlowElementIndex);
416 const auto& poreNetworkElement = this->problem(poreNetworkIndex).gridGeometry().element(poreNetworkElemIdx);
417
418 poreNetworkFVGeometry.bindElement(poreNetworkElement);
419 poreNetworkElemVolVars.bind(poreNetworkElement, poreNetworkFVGeometry, this->curSol(poreNetworkIndex));
420 poreNetworkElemFluxVarsCache.bind(poreNetworkElement, poreNetworkFVGeometry, poreNetworkElemVolVars);
421
422 const std::size_t poreNetworkDofIdx = [&]
423 {
424 std::size_t idx = 0;
425 std::size_t counter = 0;
426 for (const auto& scv : scvs(poreNetworkFVGeometry))
427 {
428 if (couplingMapper_->isCoupledPoreNetworkDof(scv.dofIndex()))
429 {
430 idx = scv.dofIndex();
431 ++counter;
432 }
433 }
434
435 if (counter != 1)
436 DUNE_THROW(Dune::InvalidStateException, "Exactly one pore per throat needs to be coupled with the FF domain");
437
438 return idx;
439 }();
440
441 context.push_back({std::move(poreNetworkFVGeometry),
442 std::move(poreNetworkElemVolVars),
443 std::move(poreNetworkElemFluxVarsCache),
444 poreNetworkDofIdx}
445 );
446 }
447
451 void bindCouplingContext_(Dune::index_constant<poreNetworkIndex> domainI, const FVElementGeometry<poreNetworkIndex>& fvGeometry) const
452 {
453 auto& context = std::get<domainI>(couplingContext_);
454 const auto eIdx = fvGeometry.gridGeometry().elementMapper().index(fvGeometry.element());
455
456 // do nothing if the element is already bound or not coupled to the other domain
457 if ((!context.empty() && couplingContextBoundForElement_[domainI] == eIdx) || !isCoupledElement_(domainI, eIdx))
458 return;
459
460 context.clear();
461 couplingContextBoundForElement_[domainI] = eIdx;
462
463 const auto& stencil = couplingStencil(poreNetworkIndex, fvGeometry.element(), freeFlowMomentumIndex);
464 const auto& freeFlowElements = couplingMapper_->pnmElementToFreeFlowElementsMap().at(eIdx);
465 auto ffFVGeometry = localView(this->problem(freeFlowMomentumIndex).gridGeometry());
466
467 for (const auto ffElementIdx : freeFlowElements)
468 {
469 const auto& ffElement = this->problem(freeFlowMomentumIndex).gridGeometry().element(ffElementIdx);
470 ffFVGeometry.bindElement(ffElement);
471 for (const auto& scv : scvs(ffFVGeometry))
472 {
473 if (couplingMapper_->isCoupledFreeFlowMomentumDof(scv.dofIndex()))
474 {
475 if (std::any_of(stencil.begin(), stencil.end(), [&](const auto x){ return scv.dofIndex() == x; } ))
476 {
477 const auto& coupledScvf = ffFVGeometry.frontalScvfOnBoundary(scv);
478 context.push_back({coupledScvf,
479 faceVelocity(coupledScvf, scv.dofIndex()),
480 scv.dofIndex()}
481 );
482 }
483 }
484 }
485 }
486 }
487
492 template<std::size_t i>
493 const GridVariables<i>& gridVars_(Dune::index_constant<i> domainIdx) const
494 {
495 if (std::get<i>(gridVariables_))
496 return *std::get<i>(gridVariables_);
497 else
498 DUNE_THROW(Dune::InvalidStateException, "The gridVariables pointer was not set. Use setGridVariables() before calling this function");
499 }
500
505 template<std::size_t i>
506 GridVariables<i>& gridVars_(Dune::index_constant<i> domainIdx)
507 {
508 if (std::get<i>(gridVariables_))
509 return *std::get<i>(gridVariables_);
510 else
511 DUNE_THROW(Dune::InvalidStateException, "The gridVariables pointer was not set. Use setGridVariables() before calling this function");
512 }
513
515 GridVariablesTuple gridVariables_;
516
517 mutable std::tuple<std::vector<FreeFlowMomentumCouplingContext>, std::vector<PoreNetworkCouplingContext>> couplingContext_;
518 mutable std::array<std::size_t, 2> couplingContextBoundForElement_;
519
520 std::shared_ptr<CouplingMapper> couplingMapper_;
521};
522
523} // end namespace Dumux
524
525#endif
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethods::box, BoxElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for box schemes.
Definition: box/elementsolution.hh:118
decltype(auto) evalCouplingResidual(Dune::index_constant< i > domainI, const LocalAssemblerI &localAssemblerI, Dune::index_constant< j > domainJ, std::size_t dofIdxGlobalJ) const
evaluates the element residual of a coupled element of domain i which depends on the variables at the...
Definition: multidomain/couplingmanager.hh:261
Adaption of the non-isothermal two-phase two-component flow model to problems with CO2.
Definition: adapt.hh:29
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:180
A vector of primary variables.
Definition: common/properties.hh:49
Property to specify the type of a problem which has to be solved.
Definition: common/properties.hh:55
Definition: common/properties.hh:100
The type for a global container for the volume variables.
Definition: common/properties.hh:107
The global vector of flux variable containers.
Definition: common/properties.hh:117
The grid variables object managing variable data on the grid (volvars/fluxvars cache)
Definition: common/properties.hh:121
Coupling manager for free-flow momentum and pore-network models.
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:47
void bindCouplingContext(Dune::index_constant< i > domainI, const Element< i > &element, const Assembler &assembler) const
Methods to be accessed by the assembly.
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:135
typename ParentType::SolutionVectorStorage SolutionVectorStorage
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:55
void bindCouplingContext(Dune::index_constant< i > domainI, const Element< i > &element) const
prepares all data and variables that are necessary to evaluate the residual (called from the local as...
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:144
bool isCoupledLateralScvf(Dune::index_constant< freeFlowMomentumIndex > domainI, const SubControlVolumeFace< freeFlowMomentumIndex > &scvf) const
Returns whether a given scvf is coupled to the other domain.
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:306
bool isCoupled(Dune::index_constant< poreNetworkIndex > domainI, const SubControlVolume< poreNetworkIndex > &scv) const
If the boundary entity is on a coupling boundary.
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:322
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: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:153
static constexpr auto poreNetworkIndex
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:53
const auto & couplingContext(const FVElementGeometry< poreNetworkIndex > &fvGeometry, const SubControlVolume< poreNetworkIndex > scv) const
Access the coupling context needed for the PNM domain.
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:240
static constexpr auto freeFlowMomentumIndex
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:52
const CouplingStencil & couplingStencil(Dune::index_constant< freeFlowMomentumIndex > domainI, const Element< freeFlowMomentumIndex > &elementI, const SubControlVolume< freeFlowMomentumIndex > &scvI, Dune::index_constant< poreNetworkIndex > domainJ) const
returns an iterable container of all indices of degrees of freedom of domain j that couple with / inf...
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:277
const auto & couplingContext(const FVElementGeometry< freeFlowMomentumIndex > &fvGeometry, const SubControlVolumeFace< freeFlowMomentumIndex > scvf) const
Access the coupling context needed for the Stokes domain.
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:225
void init(std::shared_ptr< Problem< freeFlowMomentumIndex > > freeFlowMomentumProblem, std::shared_ptr< Problem< poreNetworkIndex > > porousMediumProblem, GridVariablesTuple &&gridVariables, std::shared_ptr< CouplingMapper > couplingMapper, SolutionVectorStorage &curSol)
Methods to be accessed by main.
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:111
auto faceVelocity(const SubControlVolumeFace< freeFlowMomentumIndex > &scvf, std::size_t freeFlowMomentumDofIdx) const
Returns the velocity at a given sub control volume face.
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:329
const CouplingStencil & couplingStencil(Dune::index_constant< poreNetworkIndex > domainI, const Element< poreNetworkIndex > &element, Dune::index_constant< freeFlowMomentumIndex > domainJ) const
The coupling stencils.
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:260
decltype(auto) evalCouplingResidual(Dune::index_constant< freeFlowMomentumIndex > domainI, const LocalAssemblerI &localAssemblerI, const SubControlVolume< freeFlowMomentumIndex > &scvI, Dune::index_constant< j > domainJ, std::size_t dofIdxGlobalJ) const
evaluate the coupling residual special interface for fcstaggered methods
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:292
bool isCoupled(Dune::index_constant< freeFlowMomentumIndex > domainI, const SubControlVolumeFace< freeFlowMomentumIndex > &scvf) const
Returns whether a given scvf is coupled to the other domain.
Definition: multidomain/boundary/freeflowporenetwork/ffmomentumporenetwork/couplingmanager.hh:312
The interface of the coupling manager for multi domain problems.
Definition: multidomain/couplingmanager.hh:60
void attachSolution(SolutionVectorStorage &curSol)
Attach a solution vector stored outside of this class.
Definition: multidomain/couplingmanager.hh:334
void setSubProblems(const std::tuple< std::shared_ptr< SubProblems >... > &problems)
set the pointers to the sub problems
Definition: multidomain/couplingmanager.hh:299
const Problem< i > & problem(Dune::index_constant< i > domainIdx) const
Return a reference to the sub problem.
Definition: multidomain/couplingmanager.hh:321
SubSolutionVector< i > & curSol(Dune::index_constant< i > domainIdx)
the solution vector of the subproblem
Definition: multidomain/couplingmanager.hh:350
typename Traits::template TupleOfSharedPtr< SubSolutionVector > SolutionVectorStorage
the type in which the solution vector is stored in the manager
Definition: multidomain/couplingmanager.hh:83
Declares all properties used in Dumux.
The local element solution class for staggered methods.
The interface of the coupling manager for multi domain problems.