25#ifndef DUMUX_MULTIDOMAIN_BOUNDARY_FREEFLOWPORENETWORK_FFMASSPORENETWORK_COUPLINGMANAGER_HH
26#define DUMUX_MULTIDOMAIN_BOUNDARY_FREEFLOWPORENETWORK_FFMASSPORENETWORK_COUPLINGMANAGER_HH
31#include <dune/common/float_cmp.hh>
32#include <dune/common/exceptions.hh>
44template<
class MDTraits>
48 using Scalar =
typename MDTraits::Scalar;
52 static constexpr auto freeFlowMassIndex =
typename MDTraits::template SubDomain<0>::Index();
53 static constexpr auto poreNetworkIndex =
typename MDTraits::template SubDomain<1>::Index();
59 using FreeFlowMassTypeTag =
typename MDTraits::template SubDomain<freeFlowMassIndex>::TypeTag;
60 using PoreNetworkTypeTag =
typename MDTraits::template SubDomain<poreNetworkIndex>::TypeTag;
62 using CouplingStencils = std::unordered_map<std::size_t, std::vector<std::size_t> >;
63 using CouplingStencil = CouplingStencils::mapped_type;
66 template<std::
size_t id>
67 using SubDomainTypeTag =
typename MDTraits::template SubDomain<id>::TypeTag;
75 template<std::
size_t id>
using FVElementGeometry =
typename GridGeometry<id>::LocalView;
77 template<std::
size_t id>
using Element =
typename GridView<id>::template Codim<0>::Entity;
79 template<std::
size_t id>
using SubControlVolumeFace =
typename FVElementGeometry<id>::SubControlVolumeFace;
80 template<std::
size_t id>
using SubControlVolume =
typename FVElementGeometry<id>::SubControlVolume;
82 using VelocityVector =
typename Element<freeFlowMassIndex>::Geometry::GlobalCoordinate;
84 struct FreeFlowMassCouplingContext
86 SubControlVolume<poreNetworkIndex> scv;
87 VolumeVariables<poreNetworkIndex> volVars;
88 mutable VelocityVector velocity;
91 struct PoreNetworkCouplingContext
93 SubControlVolume<freeFlowMassIndex> scv;
94 SubControlVolumeFace<freeFlowMassIndex> scvf;
95 VolumeVariables<freeFlowMassIndex> volVars;
96 mutable VelocityVector velocity;
99 using CouplingMapper = StaggeredFreeFlowPoreNetworkCouplingMapper;
109 void init(std::shared_ptr<Problem<freeFlowMassIndex>> freeFlowMassProblem,
110 std::shared_ptr<Problem<poreNetworkIndex>> pnmProblem,
111 std::shared_ptr<CouplingMapper> couplingMapper,
114 couplingMapper_ = couplingMapper;
115 this->
setSubProblems(std::make_tuple(freeFlowMassProblem, pnmProblem));
129 template<std::
size_t i,
class Assembler>
130 void bindCouplingContext(Dune::index_constant<i> domainI,
const Element<i>& element,
const Assembler& assembler)
const
132 bindCouplingContext_(domainI, element);
138 template<std::
size_t i, std::
size_t j,
class LocalAssemblerI>
140 const LocalAssemblerI& localAssemblerI,
141 Dune::index_constant<j> domainJ,
142 std::size_t dofIdxGlobalJ,
143 const PrimaryVariables<j>& priVarsJ,
146 this->
curSol(domainJ)[dofIdxGlobalJ][pvIdxJ] = priVarsJ[pvIdxJ];
153 auto& context = std::get<1-j>(couplingContext_);
154 for (
auto& c : context)
156 if (c.scv.dofIndex() == dofIdxGlobalJ)
159 const auto& element =
problem.gridGeometry().element(c.scv.elementIndex());
161 c.volVars.update(elemSol,
problem, element, c.scv);
172 const FVElementGeometry<freeFlowMassIndex>& fvGeometry,
173 const SubControlVolumeFace<freeFlowMassIndex> scvf)
const
175 auto& contexts = std::get<freeFlowMassIndex>(couplingContext_);
176 const auto eIdx = scvf.insideScvIdx();
178 if (contexts.empty() || couplingContextBoundForElement_[
freeFlowMassIndex] != eIdx)
189 const FVElementGeometry<poreNetworkIndex>& fvGeometry,
190 const SubControlVolume<poreNetworkIndex> scv)
const
192 auto& contexts = std::get<poreNetworkIndex>(couplingContext_);
193 const auto eIdx = fvGeometry.gridGeometry().elementMapper().index(fvGeometry.element());
195 if (contexts.empty() || couplingContextBoundForElement_[
poreNetworkIndex] != eIdx)
209 template<std::
size_t i, std::
size_t j>
211 const Element<i>& element,
212 Dune::index_constant<j> domainJ)
const
214 const auto eIdx = this->
problem(domainI).gridGeometry().elementMapper().index(element);
216 return couplingMapper_->freeFlowMassToPoreNetworkCouplingStencil(eIdx);
218 return couplingMapper_->poreNetworkToFreeFlowMassCouplingStencil(eIdx);
226 bool isCoupled(Dune::index_constant<freeFlowMassIndex> domainI,
227 const SubControlVolumeFace<freeFlowMassIndex>& scvf)
const
228 {
return couplingMapper_->isCoupledFreeFlowMassScvf(scvf.index()); }
235 bool isCoupled(Dune::index_constant<poreNetworkIndex> domainI,
236 const SubControlVolume<poreNetworkIndex>& scv)
const
237 {
return couplingMapper_->isCoupledPoreNetworkDof(scv.dofIndex()); }
243 template<std::
size_t i>
244 bool isCoupledElement_(Dune::index_constant<i> domainI, std::size_t eIdx)
const
247 return couplingMapper_->isCoupledFreeFlowElement(eIdx);
249 return couplingMapper_->isCoupledPoreNetworkElement(eIdx);
253 template<std::
size_t i>
254 VolumeVariables<i> volVars_(Dune::index_constant<i> domainI,
255 const Element<i>& element,
256 const SubControlVolume<i>& scv)
const
258 VolumeVariables<i> volVars;
260 element, this->
curSol(domainI), this->
problem(domainI).gridGeometry()
262 volVars.update(elemSol, this->
problem(domainI), element, scv);
269 template<std::
size_t i>
270 void bindCouplingContext_(Dune::index_constant<i> domainI,
const Element<i>& element)
const
272 const auto fvGeometry =
localView(this->
problem(domainI).gridGeometry()).bindElement(element);
273 bindCouplingContext_(domainI, fvGeometry);
279 void bindCouplingContext_(Dune::index_constant<poreNetworkIndex> domainI,
const FVElementGeometry<poreNetworkIndex>& fvGeometry)
const
281 auto& context = std::get<domainI>(couplingContext_);
282 const auto eIdx = fvGeometry.gridGeometry().elementMapper().index(fvGeometry.element());
285 if ((!context.empty() && couplingContextBoundForElement_[domainI] == eIdx) || !isCoupledElement_(domainI, eIdx))
289 couplingContextBoundForElement_[domainI] = eIdx;
292 const auto& freeFlowElements = couplingMapper_->pnmElementToFreeFlowElementsMap().at(eIdx);
295 for (
const auto ffElementIdx : freeFlowElements)
298 ffFVGeometry.bindElement(ffElement);
300 for (
const auto& scvf : scvfs(ffFVGeometry))
302 if (couplingMapper_->isCoupledFreeFlowMassScvf(scvf.index()))
304 const auto& scv = ffFVGeometry.scv(scvf.insideScvIdx());
305 const auto dofIdx = scv.dofIndex();
306 if (std::any_of(stencil.begin(), stencil.end(), [&](
const auto x){ return dofIdx == x; } ))
308 context.push_back({scv,
322 void bindCouplingContext_(Dune::index_constant<freeFlowMassIndex> domainI,
const FVElementGeometry<freeFlowMassIndex>& fvGeometry)
const
324 auto& context = std::get<domainI>(couplingContext_);
325 const auto eIdx = fvGeometry.gridGeometry().elementMapper().index(fvGeometry.element());
328 if ((!context.empty() && couplingContextBoundForElement_[domainI] == eIdx) || !isCoupledElement_(domainI, eIdx))
332 couplingContextBoundForElement_[domainI] = eIdx;
336 const auto poreNetworkElemIdx = couplingMapper_->freeFlowElementToPNMElementMap().at(eIdx);
338 poreNetworkFVGeometry.bindElement(poreNetworkElement);
340 auto poreNetworkScv = [&]
342 SubControlVolume<poreNetworkIndex> result;
343 std::size_t counter = 0;
344 for (
auto&& scv : scvs(poreNetworkFVGeometry))
346 if (couplingMapper_->isCoupledPoreNetworkDof(scv.dofIndex()))
354 DUNE_THROW(Dune::InvalidStateException,
"Only one pore per throat may be coupled");
359 auto volVars = volVars_(
poreNetworkIndex, poreNetworkElement, poreNetworkScv);
361 context.push_back({std::move(poreNetworkScv),
367 mutable std::tuple<std::vector<FreeFlowMassCouplingContext>, std::vector<PoreNetworkCouplingContext>> couplingContext_;
368 mutable std::array<std::size_t, 2> couplingContextBoundForElement_;
370 std::shared_ptr<CouplingMapper> couplingMapper_;
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
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:150
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:57
Definition: common/properties.hh:102
The type for a global container for the volume variables.
Definition: common/properties.hh:109
The grid variables object managing variable data on the grid (volvars/fluxvars cache)
Definition: common/properties.hh:123
Coupling manager for free-flow mass and pore-network models.
Definition: multidomain/boundary/freeflowporenetwork/ffmassporenetwork/couplingmanager.hh:47
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/ffmassporenetwork/couplingmanager.hh:235
static constexpr auto poreNetworkIndex
Definition: multidomain/boundary/freeflowporenetwork/ffmassporenetwork/couplingmanager.hh:53
typename ParentType::SolutionVectorStorage SolutionVectorStorage
Definition: multidomain/boundary/freeflowporenetwork/ffmassporenetwork/couplingmanager.hh:55
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/ffmassporenetwork/couplingmanager.hh:130
void init(std::shared_ptr< Problem< freeFlowMassIndex > > freeFlowMassProblem, std::shared_ptr< Problem< poreNetworkIndex > > pnmProblem, std::shared_ptr< CouplingMapper > couplingMapper, SolutionVectorStorage &curSol)
Methods to be accessed by main.
Definition: multidomain/boundary/freeflowporenetwork/ffmassporenetwork/couplingmanager.hh:109
const auto & couplingContext(Dune::index_constant< poreNetworkIndex > domainI, const FVElementGeometry< poreNetworkIndex > &fvGeometry, const SubControlVolume< poreNetworkIndex > scv) const
Access the coupling context needed for the PNM domain.
Definition: multidomain/boundary/freeflowporenetwork/ffmassporenetwork/couplingmanager.hh:188
const auto & couplingContext(Dune::index_constant< freeFlowMassIndex > domainI, const FVElementGeometry< freeFlowMassIndex > &fvGeometry, const SubControlVolumeFace< freeFlowMassIndex > scvf) const
Access the coupling context needed for the Stokes domain.
Definition: multidomain/boundary/freeflowporenetwork/ffmassporenetwork/couplingmanager.hh:171
static constexpr auto freeFlowMassIndex
Definition: multidomain/boundary/freeflowporenetwork/ffmassporenetwork/couplingmanager.hh:52
const CouplingStencil & couplingStencil(Dune::index_constant< i > domainI, const Element< i > &element, Dune::index_constant< j > domainJ) const
The coupling stencils.
Definition: multidomain/boundary/freeflowporenetwork/ffmassporenetwork/couplingmanager.hh:210
bool isCoupled(Dune::index_constant< freeFlowMassIndex > domainI, const SubControlVolumeFace< freeFlowMassIndex > &scvf) const
Returns whether a given scvf is coupled to the other domain.
Definition: multidomain/boundary/freeflowporenetwork/ffmassporenetwork/couplingmanager.hh:226
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/ffmassporenetwork/couplingmanager.hh:139
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
decltype(auto) curSol()
the solution vector of the coupled problem
Definition: multidomain/couplingmanager.hh:370
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
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.