25#ifndef DUMUX_MULTIDOMAIN_BOUNDARY_FFPM_FFMASSPM_COUPLINGMANAGER_HH
26#define DUMUX_MULTIDOMAIN_BOUNDARY_FFPM_FFMASSPM_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 porousMediumIndex =
typename MDTraits::template SubDomain<1>::Index();
59 using FreeFlowMassTypeTag =
typename MDTraits::template SubDomain<freeFlowMassIndex>::TypeTag;
60 using PorousMediumTypeTag =
typename MDTraits::template SubDomain<porousMediumIndex>::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 Element<porousMediumIndex> element;
87 VolumeVariables<porousMediumIndex> volVars;
88 FVElementGeometry<porousMediumIndex> fvGeometry;
90 std::size_t freeFlowMassScvfIdx;
91 std::size_t porousMediumScvfIdx;
92 mutable VelocityVector velocity;
95 struct PorousMediumCouplingContext
97 Element<freeFlowMassIndex> element;
98 VolumeVariables<freeFlowMassIndex> volVars;
99 FVElementGeometry<freeFlowMassIndex> fvGeometry;
101 std::size_t porousMediumScvfIdx;
102 std::size_t freeFlowMassScvfIdx;
103 mutable VelocityVector velocity;
106 using CouplingMapper = DarcyDarcyBoundaryCouplingMapper<MDTraits>;
116 void init(std::shared_ptr<Problem<freeFlowMassIndex>> freeFlowMassProblem,
117 std::shared_ptr<Problem<porousMediumIndex>> darcyProblem,
120 this->
setSubProblems(std::make_tuple(freeFlowMassProblem, darcyProblem));
123 couplingMapper_.update(*
this);
136 template<std::
size_t i,
class Assembler>
137 void bindCouplingContext(Dune::index_constant<i> domainI,
const Element<i>& element,
const Assembler& assembler)
const
139 bindCouplingContext_(domainI, element);
145 template<std::
size_t i, std::
size_t j,
class LocalAssemblerI>
147 const LocalAssemblerI& localAssemblerI,
148 Dune::index_constant<j> domainJ,
149 std::size_t dofIdxGlobalJ,
150 const PrimaryVariables<j>& priVarsJ,
153 this->
curSol(domainJ)[dofIdxGlobalJ][pvIdxJ] = priVarsJ[pvIdxJ];
160 auto& context = std::get<1-j>(couplingContext_);
161 for (
auto& c : context)
163 if (c.dofIdx == dofIdxGlobalJ)
165 const auto elemSol =
elementSolution(c.element, this->curSol(domainJ), this->problem(domainJ).gridGeometry());
166 const auto& scv = *scvs(c.fvGeometry).begin();
167 c.volVars.update(elemSol, this->
problem(domainJ), c.element, scv);
177 template<std::
size_t i>
179 const FVElementGeometry<i>& fvGeometry,
180 const SubControlVolumeFace<i> scvf)
const
182 auto& contexts = std::get<i>(couplingContext_);
184 if (contexts.empty() || couplingContextBoundForElement_[i] != scvf.insideScvIdx())
185 bindCouplingContext_(domainI, fvGeometry);
187 for (
const auto& context : contexts)
189 const auto expectedScvfIdx = domainI ==
freeFlowMassIndex ? context.freeFlowMassScvfIdx : context.porousMediumScvfIdx;
190 if (scvf.index() == expectedScvfIdx)
194 DUNE_THROW(Dune::InvalidStateException,
"No coupling context found at scvf " << scvf.center());
205 template<std::
size_t i, std::
size_t j>
207 const Element<i>& element,
208 Dune::index_constant<j> domainJ)
const
210 const auto eIdx = this->
problem(domainI).gridGeometry().elementMapper().index(element);
211 return couplingMapper_.couplingStencil(domainI, eIdx, domainJ);
219 template<std::
size_t i>
220 bool isCoupled(Dune::index_constant<i> domainI,
const SubControlVolumeFace<i>& scvf)
const
221 {
return couplingMapper_.isCoupled(domainI, scvf); }
227 template<std::
size_t i>
228 bool isCoupledElement_(Dune::index_constant<i> domainI, std::size_t eIdx)
const
232 template<std::
size_t i>
233 VolumeVariables<i> volVars_(Dune::index_constant<i> domainI,
234 const Element<i>& element,
235 const SubControlVolume<i>& scv)
const
237 VolumeVariables<i> volVars;
239 element, this->
curSol(domainI), this->
problem(domainI).gridGeometry()
241 volVars.update(elemSol, this->
problem(domainI), element, scv);
248 template<std::
size_t i>
249 void bindCouplingContext_(Dune::index_constant<i> domainI,
const Element<i>& element)
const
251 const auto fvGeometry =
localView(this->
problem(domainI).gridGeometry()).bindElement(element);
252 bindCouplingContext_(domainI, fvGeometry);
258 template<std::
size_t i>
259 void bindCouplingContext_(Dune::index_constant<i> domainI,
const FVElementGeometry<i>& fvGeometry)
const
261 auto& context = std::get<domainI>(couplingContext_);
264 const auto eIdx = this->
problem(domainI).gridGeometry().elementMapper().index(fvGeometry.element());
267 if (!isCoupledElement_(domainI, eIdx))
270 couplingContextBoundForElement_[domainI] = eIdx;
272 for (
const auto& scvf : scvfs(fvGeometry))
276 const auto otherElementIdx = couplingMapper_.outsideElementIndex(domainI, scvf);
277 constexpr auto domainJ = Dune::index_constant<1-domainI>();
278 const auto& otherGridGeometry = this->
problem(domainJ).gridGeometry();
279 const auto& otherElement = otherGridGeometry.element(otherElementIdx);
280 auto otherFvGeometry =
localView(otherGridGeometry).bindElement(otherElement);
285 volVars_(domainJ, otherElement, *std::begin(scvs(otherFvGeometry))),
286 std::move(otherFvGeometry),
289 couplingMapper_.flipScvfIndex(domainI, scvf),
296 mutable std::tuple<std::vector<FreeFlowMassCouplingContext>, std::vector<PorousMediumCouplingContext>> couplingContext_;
297 mutable std::array<std::size_t, 2> couplingContextBoundForElement_;
299 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
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:190
Coupling manager for Stokes and Darcy domains with equal dimension.
Definition multidomain/boundary/freeflowporousmedium/ffmasspm/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/freeflowporousmedium/ffmasspm/couplingmanager.hh:137
void init(std::shared_ptr< Problem< freeFlowMassIndex > > freeFlowMassProblem, std::shared_ptr< Problem< porousMediumIndex > > darcyProblem, SolutionVectorStorage &curSol)
Methods to be accessed by main.
Definition multidomain/boundary/freeflowporousmedium/ffmasspm/couplingmanager.hh:116
static constexpr auto porousMediumIndex
Definition multidomain/boundary/freeflowporousmedium/ffmasspm/couplingmanager.hh:53
const CouplingStencil & couplingStencil(Dune::index_constant< i > domainI, const Element< i > &element, Dune::index_constant< j > domainJ) const
The coupling stencils.
Definition multidomain/boundary/freeflowporousmedium/ffmasspm/couplingmanager.hh:206
bool isCoupled(Dune::index_constant< i > domainI, const SubControlVolumeFace< i > &scvf) const
Returns whether a given scvf is coupled to the other domain.
Definition multidomain/boundary/freeflowporousmedium/ffmasspm/couplingmanager.hh:220
static constexpr auto freeFlowMassIndex
Definition multidomain/boundary/freeflowporousmedium/ffmasspm/couplingmanager.hh:52
const auto & couplingContext(Dune::index_constant< i > domainI, const FVElementGeometry< i > &fvGeometry, const SubControlVolumeFace< i > scvf) const
Access the coupling context needed for the Stokes domain.
Definition multidomain/boundary/freeflowporousmedium/ffmasspm/couplingmanager.hh:178
typename ParentType::SolutionVectorStorage SolutionVectorStorage
Definition multidomain/boundary/freeflowporousmedium/ffmasspm/couplingmanager.hh:55
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/freeflowporousmedium/ffmasspm/couplingmanager.hh:146
void attachSolution(SolutionVectorStorage &curSol)
Definition multidomain/couplingmanager.hh:333
decltype(auto) curSol()
Definition multidomain/couplingmanager.hh:369
void setSubProblems(const std::tuple< std::shared_ptr< SubProblems >... > &problems)
Definition multidomain/couplingmanager.hh:298
const Problem< i > & problem(Dune::index_constant< i > domainIdx) const
Definition multidomain/couplingmanager.hh:320
SubSolutionVector< i > & curSol(Dune::index_constant< i > domainIdx)
Definition multidomain/couplingmanager.hh:349
CouplingManager()
Definition multidomain/couplingmanager.hh:93
typename Traits::template TupleOfSharedPtr< SubSolutionVector > SolutionVectorStorage
the type in which the solution vector is stored in the manager
Definition multidomain/couplingmanager.hh:82
The local element solution class for staggered methods.
The interface of the coupling manager for multi domain problems.
the default mapper for conforming equal dimension boundary coupling between two domains (box or cc)
Declares all properties used in Dumux.