12#ifndef DUMUX_BOX_FACETCOUPLING_MANAGER_HH 
   13#define DUMUX_BOX_FACETCOUPLING_MANAGER_HH 
   38template<
class MDTraits, 
class CouplingMapper, std::
size_t bulkDomainId, std::
size_t lowDimDomainId>
 
   45    using BulkIdType = 
typename MDTraits::template SubDomain<bulkDomainId>::Index;
 
   46    using LowDimIdType = 
typename MDTraits::template SubDomain<lowDimDomainId>::Index;
 
   47    static constexpr auto bulkId = BulkIdType();
 
   48    static constexpr auto lowDimId = LowDimIdType();
 
   51    template<std::
size_t id> 
using SubDomainTypeTag = 
typename MDTraits::template SubDomain<id>::TypeTag;
 
   58    template<std::
size_t id> 
using LocalResidual = 
typename MDTraits::template SubDomain<id>::LocalResidual;
 
   61    template<std::
size_t id> 
using FVElementGeometry = 
typename GridGeometry<id>::LocalView;
 
   62    template<std::
size_t id> 
using SubControlVolume = 
typename GridGeometry<id>::SubControlVolume;
 
   63    template<std::
size_t id> 
using SubControlVolumeFace = 
typename GridGeometry<id>::SubControlVolumeFace;
 
   64    template<std::
size_t id> 
using GridView = 
typename GridGeometry<id>::GridView;
 
   65    template<std::
size_t id> 
using Element = 
typename GridView<id>::template Codim<0>::Entity;
 
   66    template<std::
size_t id> 
using GridIndexType = 
typename GridView<id>::IndexSet::IndexType;
 
   69    template<std::
size_t id> 
using GridVolumeVariables = 
typename GridVariables<id>::GridVolumeVariables;
 
   70    template<std::
size_t id> 
using ElementVolumeVariables = 
typename GridVolumeVariables<id>::LocalView;
 
   71    template<std::
size_t id> 
using VolumeVariables = 
typename ElementVolumeVariables<id>::VolumeVariables;
 
   72    template<std::
size_t id> 
using GridFluxVariablesCache = 
typename GridVariables<id>::GridFluxVariablesCache;
 
   73    template<std::
size_t id> 
using ElementFluxVariablesCache = 
typename GridFluxVariablesCache<id>::LocalView;
 
   76    static constexpr int bulkDim = GridView<bulkDomainId>::dimension;
 
   77    static constexpr int lowDimDim = GridView<lowDimDomainId>::dimension;
 
   78    static constexpr auto bulkGridId = CouplingMapper::template gridId<bulkDim>();
 
   79    static constexpr auto lowDimGridId = CouplingMapper::template gridId<lowDimDim>();
 
   89    struct BulkCouplingContext
 
   92        GridIndexType< bulkId > elementIdx;
 
   93        std::vector< FVElementGeometry<lowDimId> > lowDimFvGeometries;
 
   94        std::vector< std::vector<VolumeVariables<lowDimId>> > lowDimElemVolVars;
 
   98            lowDimFvGeometries.clear();
 
   99            lowDimElemVolVars.clear();
 
  114    struct LowDimCouplingContext
 
  120        static constexpr int bulkDimWorld = GridView<bulkId>::dimensionworld;
 
  121        static constexpr bool bulkIsSurfaceGrid = bulkDim != bulkDimWorld;
 
  124        using ContainerType = 
typename std::conditional< bulkIsSurfaceGrid,
 
  126                                                         std::array< T, 2 > >::type;
 
  130        GridIndexType< lowDimId > elementIdx;
 
  131        ContainerType< std::unique_ptr<FVElementGeometry<bulkId>> > bulkFvGeometries;
 
  132        ContainerType< std::unique_ptr<ElementVolumeVariables<bulkId>> > bulkElemVolVars;
 
  133        ContainerType< std::unique_ptr<ElementFluxVariablesCache<bulkId>> > bulkElemFluxVarsCache;
 
  134        std::unique_ptr< LocalResidual<bulkId> > bulkLocalResidual;
 
  135        ContainerType< ElementBoundaryTypes<bulkId> > bulkElemBcTypes;
 
  140            auto resetPtr = [&] (
auto&& uniquePtr) { uniquePtr.reset(); };
 
  141            std::for_each(bulkFvGeometries.begin(), bulkFvGeometries.end(), resetPtr);
 
  142            std::for_each(bulkElemVolVars.begin(), bulkElemVolVars.end(), resetPtr);
 
  143            std::for_each(bulkElemFluxVarsCache.begin(), bulkElemFluxVarsCache.end(), resetPtr);
 
  144            bulkLocalResidual.reset();
 
  148        template<
bool s = bulkIsSurfaceGr
id, std::enable_if_t<s, 
int> = 0>
 
  149        void resize(std::size_t numEmbedments)
 
  151            bulkFvGeometries.resize(numEmbedments);
 
  152            bulkElemVolVars.resize(numEmbedments);
 
  153            bulkElemFluxVarsCache.resize(numEmbedments);
 
  154            bulkElemBcTypes.resize(numEmbedments);
 
  158        template<
bool s = bulkIsSurfaceGr
id, std::enable_if_t<!s, 
int> = 0>
 
  159        void resize(std::size_t numEmbedments)
 
  166    template<std::
size_t i, std::
size_t j = (i == bulkId) ? lowDimId : bulkId>
 
  167    using CouplingStencilType = 
typename CouplingMapper::template Stencil< CouplingMapper::template gridId<GridView<j>::dimension>() >;
 
  180    void init(std::shared_ptr< Problem<bulkId> > bulkProblem,
 
  181              std::shared_ptr< Problem<lowDimId> > lowDimProblem,
 
  182              std::shared_ptr< CouplingMapper > couplingMapper,
 
  185        couplingMapperPtr_ = couplingMapper;
 
  195        const auto& bulkMap = couplingMapperPtr_->couplingMap(bulkGridId, lowDimGridId);
 
  196        bulkElemIsCoupled_.assign(bulkProblem->gridGeometry().gridView().size(0), 
false);
 
  197        std::for_each( bulkMap.begin(),
 
  199                       [&] (
const auto& entry) { bulkElemIsCoupled_[entry.first] = true; });
 
 
  206                                                       const Element<bulkId>& element,
 
  207                                                       LowDimIdType domainJ)
 const 
  209        const auto eIdx = this->
problem(domainI).gridGeometry().elementMapper().index(element);
 
  211        if (bulkElemIsCoupled_[eIdx])
 
  213            const auto& map = couplingMapperPtr_->couplingMap(bulkGridId, lowDimGridId);
 
  214            auto it = map.find(eIdx);
 
  215            assert(it != map.end());
 
  216            return it->second.couplingStencil;
 
 
  226                                                         const Element<lowDimId>& element,
 
  227                                                         BulkIdType domainJ)
 const 
  229        const auto eIdx = this->
problem(lowDimId).gridGeometry().elementMapper().index(element);
 
  231        const auto& map = couplingMapperPtr_->couplingMap(lowDimGridId, bulkGridId);
 
  232        auto it = map.find(eIdx);
 
  233        if (it != map.end()) 
return it->second.couplingStencil;
 
 
  242                   const SubControlVolumeFace<bulkId>& scvf)
 const 
  243    { 
return scvf.interiorBoundary(); }
 
 
  250                              const SubControlVolumeFace<bulkId>& scvf)
 const 
 
  257                                                      const SubControlVolumeFace<bulkId>& scvf)
 const 
  259        const auto eIdx = this->
problem(bulkId).gridGeometry().elementMapper().index(element);
 
  260        assert(bulkContext_.isSet);
 
  261        assert(bulkElemIsCoupled_[eIdx]);
 
  263        const auto& map = couplingMapperPtr_->couplingMap(bulkGridId, lowDimGridId);
 
  264        const auto& couplingData = map.find(eIdx)->second;
 
  268        unsigned int coupledScvIdx;
 
  269        auto it = std::find_if( couplingData.elementToScvfMap.begin(),
 
  270                                couplingData.elementToScvfMap.end(),
 
  273                                    const auto& scvfList = dataPair.second;
 
  274                                    auto it = std::find(scvfList.begin(), scvfList.end(), scvf.index());
 
  275                                    coupledScvIdx = std::distance(scvfList.begin(), it);
 
  276                                    return it != scvfList.end();
 
  279        assert(it != couplingData.elementToScvfMap.end());
 
  280        const auto lowDimElemIdx = it->first;
 
  281        const auto& s = map.find(bulkContext_.elementIdx)->second.couplingElementStencil;
 
  282        const auto& idxInContext = std::distance( s.begin(), std::find(s.begin(), s.end(), lowDimElemIdx) );
 
  283        assert(std::find(s.begin(), s.end(), lowDimElemIdx) != s.end());
 
  286            return bulkContext_.lowDimElemVolVars[idxInContext][coupledScvIdx];
 
  288            return bulkContext_.lowDimElemVolVars[idxInContext][0];
 
 
  295                                             const SubControlVolumeFace<bulkId>& scvf)
 const 
  298        return this->
problem(lowDimId).gridGeometry().element(lowDimElemIdx);
 
 
  305                                                        const SubControlVolumeFace<bulkId>& scvf)
 const 
  307        const auto eIdx = this->
problem(bulkId).gridGeometry().elementMapper().index(element);
 
  309        assert(bulkElemIsCoupled_[eIdx]);
 
  310        const auto& map = couplingMapperPtr_->couplingMap(bulkGridId, lowDimGridId);
 
  311        const auto& couplingData = map.at(eIdx);
 
  314        auto it = std::find_if( couplingData.elementToScvfMap.begin(),
 
  315                                couplingData.elementToScvfMap.end(),
 
  318                                    const auto& scvfList = dataPair.second;
 
  319                                    auto it = std::find(scvfList.begin(), scvfList.end(), scvf.index());
 
  320                                    return it != scvfList.end();
 
  323        assert(it != couplingData.elementToScvfMap.end());
 
 
  333    template< 
class BulkLocalAssembler >
 
  334    typename LocalResidual<bulkId>::ElementResidualVector
 
  336                         const BulkLocalAssembler& bulkLocalAssembler,
 
  338                         GridIndexType<lowDimId> dofIdxGlobalJ)
 
  340        const auto& map = couplingMapperPtr_->couplingMap(bulkGridId, lowDimGridId);
 
  342        assert(bulkContext_.isSet);
 
  343        assert(bulkElemIsCoupled_[bulkContext_.elementIdx]);
 
  344        assert(map.find(bulkContext_.elementIdx) != map.end());
 
  345        assert(bulkContext_.elementIdx == this->problem(bulkId).gridGeometry().elementMapper().index(bulkLocalAssembler.element()));
 
  347        const auto& fvGeometry = bulkLocalAssembler.fvGeometry();
 
  348        typename LocalResidual<bulkId>::ElementResidualVector res(fvGeometry.numScv());
 
  352        const auto& couplingScvfs = map.find(bulkContext_.elementIdx)->second.dofToCouplingScvfMap.at(dofIdxGlobalJ);
 
  353        for (
auto scvfIdx : couplingScvfs)
 
  355            const auto& scvf = fvGeometry.scvf(scvfIdx);
 
  356            const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
 
  357            res[insideScv.localDofIndex()] += evalBulkFluxes_( bulkLocalAssembler.element(),
 
  358                                                               bulkLocalAssembler.fvGeometry(),
 
  359                                                               bulkLocalAssembler.curElemVolVars(),
 
  360                                                               bulkLocalAssembler.elemBcTypes(),
 
  361                                                               bulkLocalAssembler.elemFluxVarsCache(),
 
  362                                                               bulkLocalAssembler.localResidual(),
 
  363                                                               std::array<GridIndexType<bulkId>, 1>({scvfIdx}) );
 
 
  375    template< 
class LowDimLocalAssembler >
 
  376    typename LocalResidual<lowDimId>::ElementResidualVector
 
  378                         const LowDimLocalAssembler& lowDimLocalAssembler,
 
  380                         GridIndexType<bulkId> dofIdxGlobalJ)
 
  383        assert(lowDimContext_.isSet);
 
  384        assert(this->
problem(lowDimId).gridGeometry().elementMapper().index(lowDimLocalAssembler.element()) == lowDimContext_.elementIdx);
 
  387        typename LocalResidual<lowDimId>::ElementResidualVector res(lowDimLocalAssembler.fvGeometry().numScv());
 
  389        for (
const auto& scv : scvs(lowDimLocalAssembler.fvGeometry()))
 
  391                                                            lowDimLocalAssembler.fvGeometry(),
 
  392                                                            lowDimLocalAssembler.curElemVolVars(),
 
 
  401                                              const FVElementGeometry<lowDimId>& fvGeometry,
 
  402                                              const ElementVolumeVariables<lowDimId>& elemVolVars,
 
  403                                              const SubControlVolume<lowDimId>& scv)
 const 
  406        assert(this->
problem(lowDimId).gridGeometry().elementMapper().index(element) == lowDimContext_.elementIdx);
 
  408        NumEqVector<lowDimId> sources(0.0);
 
  409        const auto& map = couplingMapperPtr_->couplingMap(lowDimGridId, bulkGridId);
 
  410        auto it = map.find(lowDimContext_.elementIdx);
 
  414        assert(lowDimContext_.isSet);
 
  415        for (
unsigned int i = 0; i < it->second.embedments.size(); ++i)
 
  417            const auto& embedment = it->second.embedments[i];
 
  422            const auto& coincidingScvfs = embedment.second;
 
  423            const auto& scvfList = lowDimUsesBox ? std::vector<GridIndexType<lowDimId>>{ coincidingScvfs[scv.localDofIndex()] }
 
  426            sources += evalBulkFluxes_(this->
problem(bulkId).gridGeometry().element(embedment.first),
 
  427                                       *(lowDimContext_.bulkFvGeometries[i]),
 
  428                                       *(lowDimContext_.bulkElemVolVars[i]),
 
  429                                       lowDimContext_.bulkElemBcTypes[i],
 
  430                                       *(lowDimContext_.bulkElemFluxVarsCache[i]),
 
  431                                       *lowDimContext_.bulkLocalResidual,
 
 
  443    template< 
class Assembler >
 
  447        bulkContext_.reset();
 
  450        const auto bulkElemIdx = this->
problem(bulkId).gridGeometry().elementMapper().index(element);
 
  451        bulkContext_.elementIdx = bulkElemIdx;
 
  454        if (bulkElemIsCoupled_[bulkElemIdx])
 
  456            const auto& map = couplingMapperPtr_->couplingMap(bulkGridId, lowDimGridId);
 
  458            auto it = map.find(bulkElemIdx); assert(it != map.end());
 
  459            const auto& elementStencil = it->second.couplingElementStencil;
 
  460            bulkContext_.lowDimFvGeometries.reserve(elementStencil.size());
 
  461            bulkContext_.lowDimElemVolVars.reserve(elementStencil.size());
 
  464            const auto bulkFvGeometry = 
localView(this->
problem(bulkId).gridGeometry()).bindElement(element);
 
  466            const auto& ldGridGeometry = this->
problem(lowDimId).gridGeometry();
 
  468            for (
const auto lowDimElemIdx : elementStencil)
 
  470                const auto& ldSol = assembler.isImplicit() ? this->
curSol(lowDimId) : assembler.prevSol()[lowDimId];
 
  471                const auto elemJ = ldGridGeometry.element(lowDimElemIdx);
 
  472                fvGeom.bindElement(elemJ);
 
  474                std::vector<VolumeVariables<lowDimId>> elemVolVars(fvGeom.numScv());
 
  475                const auto& coupledScvfIndices = it->second.elementToScvfMap.at(lowDimElemIdx);
 
  476                makeCoupledLowDimElemVolVars_(element, bulkFvGeometry, elemJ, fvGeom, ldSol, coupledScvfIndices, elemVolVars);
 
  478                bulkContext_.isSet = 
true;
 
  479                bulkContext_.lowDimFvGeometries.emplace_back( std::move(fvGeom) );
 
  480                bulkContext_.lowDimElemVolVars.emplace_back( std::move(elemVolVars) );
 
 
  494    template< 
class Assembler >
 
  498        bulkContext_.reset();
 
  499        lowDimContext_.reset();
 
  502        const auto lowDimElemIdx = this->
problem(lowDimId).gridGeometry().elementMapper().index(element);
 
  503        lowDimContext_.elementIdx = lowDimElemIdx;
 
  505        const auto& map = couplingMapperPtr_->couplingMap(lowDimGridId, bulkGridId);
 
  506        auto it = map.find(lowDimElemIdx);
 
  514            const auto& bulkGridGeom = this->
problem(bulkId).gridGeometry();
 
  515            const auto bulkElem = bulkGridGeom.element(it->second.embedments[0].first);
 
  519            const auto& embedments = it->second.embedments;
 
  520            const auto numEmbedments = embedments.size();
 
  521            lowDimContext_.resize(numEmbedments);
 
  523            auto bulkFvGeom = 
localView(bulkGridGeom);
 
  524            auto bulkElemVolVars = 
localView(assembler.gridVariables(bulkId).curGridVolVars());
 
  525            auto bulkElemFluxVarsCache = 
localView(assembler.gridVariables(bulkId).gridFluxVarsCache());
 
  527            for (
unsigned int i = 0; i < numEmbedments; ++i)
 
  529                const auto& bulkSol = assembler.isImplicit() ? this->
curSol(bulkId) : assembler.prevSol()[bulkId];
 
  530                const auto curBulkElem = bulkGridGeom.element(embedments[i].first);
 
  532                bulkFvGeom.bind(curBulkElem);
 
  533                bulkElemVolVars.bind(curBulkElem, bulkFvGeom, bulkSol);
 
  534                bulkElemFluxVarsCache.bind(curBulkElem, bulkFvGeom, bulkElemVolVars);
 
  536                lowDimContext_.isSet = 
true;
 
  537                lowDimContext_.bulkElemBcTypes[i].update(this->
problem(bulkId), curBulkElem, bulkFvGeom);
 
  538                lowDimContext_.bulkFvGeometries[i] = std::make_unique< FVElementGeometry<bulkId> >( std::move(bulkFvGeom) );
 
  539                lowDimContext_.bulkElemVolVars[i] = std::make_unique< ElementVolumeVariables<bulkId> >( std::move(bulkElemVolVars) );
 
  540                lowDimContext_.bulkElemFluxVarsCache[i] = std::make_unique< ElementFluxVariablesCache<bulkId> >( std::move(bulkElemFluxVarsCache) );
 
  544            lowDimContext_.bulkLocalResidual = std::make_unique< LocalResidual<bulkId> >(assembler.localResidual(bulkId));
 
 
  552    template< 
class BulkLocalAssembler >
 
  554                               const BulkLocalAssembler& bulkLocalAssembler,
 
  555                               LowDimIdType domainJ,
 
  556                               GridIndexType<lowDimId> dofIdxGlobalJ,
 
  557                               const PrimaryVariables<lowDimId>& priVarsJ,
 
  566        if (!bulkLocalAssembler.isImplicit())
 
  570        if (bulkContext_.isSet)
 
  572            const auto& map = couplingMapperPtr_->couplingMap(bulkGridId, lowDimGridId);
 
  573            const auto& couplingEntry = map.at(bulkContext_.elementIdx);
 
  574            const auto& couplingElemStencil = couplingEntry.couplingElementStencil;
 
  575            const auto& ldGridGeometry = this->
problem(lowDimId).gridGeometry();
 
  578            const auto couplingElements = [&] ()
 
  582                    std::vector< Element<lowDimId> > lowDimElems;
 
  583                    std::for_each( couplingElemStencil.begin(), couplingElemStencil.end(),
 
  584                                   [&] (
auto lowDimElemIdx)
 
  586                                       auto element = ldGridGeometry.element(lowDimElemIdx);
 
  587                                       for (unsigned int i = 0; i < element.geometry().corners(); ++i)
 
  589                                           const auto dofIdx = ldGridGeometry.vertexMapper().subIndex(element, i, lowDimDim);
 
  590                                           if (dofIdxGlobalJ == dofIdx) { lowDimElems.emplace_back( std::move(element) ); break; }
 
  597                    return std::vector<Element<lowDimId>>( {ldGridGeometry.element(dofIdxGlobalJ)} );
 
  601            for (
const auto& element : couplingElements)
 
  604                const auto eIdxGlobal = ldGridGeometry.elementMapper().index(element);
 
  605                auto it = std::find(couplingElemStencil.begin(), couplingElemStencil.end(), eIdxGlobal);
 
  606                const auto idxInContext = std::distance(couplingElemStencil.begin(), it);
 
  607                assert(it != couplingElemStencil.end());
 
  609                auto& elemVolVars = bulkContext_.lowDimElemVolVars[idxInContext];
 
  610                const auto& fvGeom = bulkContext_.lowDimFvGeometries[idxInContext];
 
  611                const auto& coupledScvfIndices = couplingEntry.elementToScvfMap.at(eIdxGlobal);
 
  612                makeCoupledLowDimElemVolVars_(bulkLocalAssembler.element(), bulkLocalAssembler.fvGeometry(),
 
  613                                              element, fvGeom, this->curSol(lowDimId), coupledScvfIndices, elemVolVars);
 
 
  622    template< 
class BulkLocalAssembler >
 
  624                               const BulkLocalAssembler& bulkLocalAssembler,
 
  626                               GridIndexType<bulkId> dofIdxGlobalJ,
 
  627                               const PrimaryVariables<bulkId>& priVarsJ,
 
 
  639    template< 
class LowDimLocalAssembler >
 
  641                               const LowDimLocalAssembler& lowDimLocalAssembler,
 
  643                               GridIndexType<bulkId> dofIdxGlobalJ,
 
  644                               const PrimaryVariables<bulkId>& priVarsJ,
 
  653        if (!lowDimLocalAssembler.isImplicit())
 
  657        if (lowDimContext_.isSet)
 
  659            assert(lowDimContext_.elementIdx == this->problem(lowDimId).gridGeometry().elementMapper().index(lowDimLocalAssembler.element()));
 
  661            const auto& map = couplingMapperPtr_->couplingMap(lowDimGridId, bulkGridId);
 
  662            auto it = map.find(lowDimContext_.elementIdx);
 
  664            assert(it != map.end());
 
  665            const auto& embedments = it->second.embedments;
 
  666            const auto& bulkGridGeometry = this->
problem(bulkId).gridGeometry();
 
  670            unsigned int embedmentIdx = 0;
 
  671            for (
const auto& embedment : embedments)
 
  673                const auto elementJ = bulkGridGeometry.element(embedment.first);
 
  675                for (
unsigned int i = 0; i < elementJ.subEntities(bulkDim); ++i)
 
  677                    const auto dofIdx = bulkGridGeometry.vertexMapper().subIndex(elementJ, i, bulkDim);
 
  678                    if (dofIdx == dofIdxGlobalJ)
 
  681                        const auto& fvGeom = *lowDimContext_.bulkFvGeometries[embedmentIdx];
 
  682                        (*lowDimContext_.bulkElemVolVars[embedmentIdx]).bindElement(elementJ, fvGeom, this->
curSol(bulkId));
 
 
  698    template< 
class LowDimLocalAssembler >
 
  700                               const LowDimLocalAssembler& lowDimLocalAssembler,
 
  701                               LowDimIdType domainJ,
 
  702                               GridIndexType<lowDimId> dofIdxGlobalJ,
 
  703                               const PrimaryVariables<lowDimId>& priVarsJ,
 
  712        if (!lowDimLocalAssembler.isImplicit())
 
  716        if (lowDimContext_.isSet)
 
  718            assert(bulkContext_.isSet);
 
  719            assert(lowDimContext_.elementIdx == this->problem(lowDimId).gridGeometry().elementMapper().index(lowDimLocalAssembler.element()));
 
  722            const auto& bulkMap = couplingMapperPtr_->couplingMap(bulkGridId, lowDimGridId);
 
  723            const auto& bulkCouplingEntry = bulkMap.at(bulkContext_.elementIdx);
 
  724            const auto& couplingElementStencil = bulkCouplingEntry.couplingElementStencil;
 
  725            auto it = std::find(couplingElementStencil.begin(), couplingElementStencil.end(), lowDimContext_.elementIdx);
 
  726            assert(it != couplingElementStencil.end());
 
  727            const auto idxInContext = std::distance(couplingElementStencil.begin(), it);
 
  730            const auto& bulkElement = this->
problem(bulkId).gridGeometry().element(bulkContext_.elementIdx);
 
  731            const auto& bulkFvGeometry = *lowDimContext_.bulkFvGeometries[0];
 
  733            auto& elemVolVars = bulkContext_.lowDimElemVolVars[idxInContext];
 
  734            const auto& fvGeom = bulkContext_.lowDimFvGeometries[idxInContext];
 
  735            const auto& element = lowDimLocalAssembler.element();
 
  736            const auto& scvfIndices = bulkCouplingEntry.elementToScvfMap.at(lowDimContext_.elementIdx);
 
  738            makeCoupledLowDimElemVolVars_(bulkElement, bulkFvGeometry, element, fvGeom,
 
  739                                          this->
curSol(lowDimId), scvfIndices, elemVolVars);
 
 
  744    template<std::
size_t id, std::enable_if_t<(
id == bulkId || 
id == lowDimId), 
int> = 0>
 
  745    const typename CouplingMapper::template Stencil<id>&
 
  747    { 
return std::get<(id == bulkId ? 0 : 1)>(emptyStencilTuple_); }
 
 
  755    template<
class LowDimSolution, 
class ScvfIdxStorage>
 
  756    void makeCoupledLowDimElemVolVars_(
const Element<bulkId>& bulkElement,
 
  757                                       const FVElementGeometry<bulkId>& bulkFvGeometry,
 
  758                                       const Element<lowDimId>& lowDimElement,
 
  759                                       const FVElementGeometry<lowDimId>& lowDimFvGeometry,
 
  760                                       const LowDimSolution& lowDimSol,
 
  761                                       const ScvfIdxStorage& coupledBulkScvfIndices,
 
  762                                       std::vector<VolumeVariables<lowDimId>>& elemVolVars)
 
  764        const auto lowDimElemSol = 
elementSolution(lowDimElement, lowDimSol, lowDimFvGeometry.gridGeometry());
 
  769            elemVolVars[0].update(lowDimElemSol, this->problem(lowDimId), lowDimElement, *scvs(lowDimFvGeometry).begin());
 
  777            for (
unsigned int i = 0; i < coupledBulkScvfIndices.size(); ++i)
 
  779                const auto& scvf = bulkFvGeometry.scvf(coupledBulkScvfIndices[i]);
 
  780                const auto bcTypes = this->problem(bulkId).interiorBoundaryTypes(bulkElement, scvf);
 
  781                if (bcTypes.hasOnlyNeumann())
 
  783                                                           lowDimFvGeometry, lowDimElement, lowDimElement.geometry(),
 
  786                    elemVolVars[i].update( lowDimElemSol, this->problem(lowDimId), lowDimElement, lowDimFvGeometry.scv(i) );
 
  792    template<
class BulkScvfIndices>
 
  794                                        const FVElementGeometry<bulkId>& fvGeometry,
 
  795                                        const ElementVolumeVariables<bulkId>& elemVolVars,
 
  796                                        const ElementBoundaryTypes<bulkId>& elemBcTypes,
 
  797                                        const ElementFluxVariablesCache<bulkId>& elemFluxVarsCache,
 
  798                                        const LocalResidual<bulkId>& localResidual,
 
  799                                        const BulkScvfIndices& scvfIndices)
 const 
  803        for (
const auto& scvfIdx : scvfIndices)
 
  804            coupledFluxes += localResidual.evalFlux(this->problem(bulkId),
 
  810                                                    fvGeometry.scvf(scvfIdx));
 
  811        return coupledFluxes;
 
  814    std::shared_ptr<CouplingMapper> couplingMapperPtr_;
 
  818    std::vector<bool> bulkElemIsCoupled_;
 
  821    using BulkStencil = 
typename CouplingMapper::template Stencil<bulkId>;
 
  822    using LowDimStencil = 
typename CouplingMapper::template Stencil<lowDimId>;
 
  823    std::tuple<BulkStencil, LowDimStencil> emptyStencilTuple_;
 
  826    BulkCouplingContext bulkContext_;
 
  827    LowDimCouplingContext lowDimContext_;
 
 
void setSubProblem(std::shared_ptr< SubProblem > problem, Dune::index_constant< i > domainIdx)
Definition multidomain/couplingmanager.hh:288
const Problem< i > & problem(Dune::index_constant< i > domainIdx) const
Definition multidomain/couplingmanager.hh:297
SubSolutionVector< i > & curSol(Dune::index_constant< i > domainIdx)
Definition multidomain/couplingmanager.hh:326
void updateSolution(const SolutionVector &curSol)
Definition multidomain/couplingmanager.hh:207
CouplingManager()
Definition multidomain/couplingmanager.hh:70
void bindCouplingContext(BulkIdType, const Element< bulkId > &element, const Assembler &assembler)
For the assembly of the element residual of a bulk domain element we need to prepare all variables of...
Definition multidomain/facet/box/couplingmanager.hh:444
void updateCouplingContext(BulkIdType domainI, const BulkLocalAssembler &bulkLocalAssembler, LowDimIdType domainJ, GridIndexType< lowDimId > dofIdxGlobalJ, const PrimaryVariables< lowDimId > &priVarsJ, unsigned int pvIdxJ)
After deflecting the solution of the lower-dimensional domain, we have to update the element volume v...
Definition multidomain/facet/box/couplingmanager.hh:553
void bindCouplingContext(LowDimIdType, const Element< lowDimId > &element, const Assembler &assembler)
For the assembly of the element residual of a bulk domain element we need to prepare the local views ...
Definition multidomain/facet/box/couplingmanager.hh:495
bool isOnInteriorBoundary(const Element< bulkId > &element, const SubControlVolumeFace< bulkId > &scvf) const
returns true if a bulk scvf coincides with a facet element.
Definition multidomain/facet/box/couplingmanager.hh:249
const CouplingMapper::template Stencil< id > & getEmptyStencil(Dune::index_constant< id >) const
Empty stencil to be returned for elements that aren't coupled.
Definition multidomain/facet/box/couplingmanager.hh:746
void init(std::shared_ptr< Problem< bulkId > > bulkProblem, std::shared_ptr< Problem< lowDimId > > lowDimProblem, std::shared_ptr< CouplingMapper > couplingMapper, const SolutionVector &curSol)
Initialize the coupling manager.
Definition multidomain/facet/box/couplingmanager.hh:180
const CouplingStencilType< lowDimId > & couplingStencil(LowDimIdType domainI, const Element< lowDimId > &element, BulkIdType domainJ) const
The coupling stencil of the lower-dimensional domain with the bulk domain.
Definition multidomain/facet/box/couplingmanager.hh:225
const GridIndexType< lowDimId > getLowDimElementIndex(const Element< bulkId > &element, const SubControlVolumeFace< bulkId > &scvf) const
returns the index of the lower-dimensional element coinciding with a bulk scvf.
Definition multidomain/facet/box/couplingmanager.hh:304
typename CouplingMapper::template Stencil< CouplingMapper::template gridId< GridView< j >::dimension >() > CouplingStencilType
types used for coupling stencils
Definition multidomain/facet/box/couplingmanager.hh:167
LocalResidual< bulkId >::ElementResidualVector evalCouplingResidual(BulkIdType, const BulkLocalAssembler &bulkLocalAssembler, LowDimIdType, GridIndexType< lowDimId > dofIdxGlobalJ)
Evaluates the coupling element residual of a bulk domain element with respect to a dof in the lower-d...
Definition multidomain/facet/box/couplingmanager.hh:335
const VolumeVariables< lowDimId > & getLowDimVolVars(const Element< bulkId > &element, const SubControlVolumeFace< bulkId > &scvf) const
returns the vol vars of a lower-dimensional element coinciding with a bulk scvf.
Definition multidomain/facet/box/couplingmanager.hh:256
NumEqVector< lowDimId > evalSourcesFromBulk(const Element< lowDimId > &element, const FVElementGeometry< lowDimId > &fvGeometry, const ElementVolumeVariables< lowDimId > &elemVolVars, const SubControlVolume< lowDimId > &scv) const
Computes the sources in a lower-dimensional element stemming from the bulk domain.
Definition multidomain/facet/box/couplingmanager.hh:400
void updateCouplingContext(BulkIdType domainI, const BulkLocalAssembler &bulkLocalAssembler, BulkIdType domainJ, GridIndexType< bulkId > dofIdxGlobalJ, const PrimaryVariables< bulkId > &priVarsJ, unsigned int pvIdxJ)
Update the coupling context for a derivative bulk -> bulk. Here, we simply have to update the solutio...
Definition multidomain/facet/box/couplingmanager.hh:623
void updateCouplingContext(LowDimIdType domainI, const LowDimLocalAssembler &lowDimLocalAssembler, BulkIdType domainJ, GridIndexType< bulkId > dofIdxGlobalJ, const PrimaryVariables< bulkId > &priVarsJ, unsigned int pvIdxJ)
After deflecting the solution of the bulk domain, we have to update the element volume variables of t...
Definition multidomain/facet/box/couplingmanager.hh:640
const Element< lowDimId > getLowDimElement(const Element< bulkId > &element, const SubControlVolumeFace< bulkId > &scvf) const
returns the lower-dimensional element coinciding with a bulk scvf.
Definition multidomain/facet/box/couplingmanager.hh:294
void updateCouplingContext(LowDimIdType domainI, const LowDimLocalAssembler &lowDimLocalAssembler, LowDimIdType domainJ, GridIndexType< lowDimId > dofIdxGlobalJ, const PrimaryVariables< lowDimId > &priVarsJ, unsigned int pvIdxJ)
After deflecting the solution of the lower-dimensional domain has been deflected during the assembly ...
Definition multidomain/facet/box/couplingmanager.hh:699
typename MDTraits::SolutionVector SolutionVector
the type of the solution vector
Definition multidomain/facet/box/couplingmanager.hh:170
LocalResidual< lowDimId >::ElementResidualVector evalCouplingResidual(LowDimIdType, const LowDimLocalAssembler &lowDimLocalAssembler, BulkIdType, GridIndexType< bulkId > dofIdxGlobalJ)
Evaluates the coupling element residual of a lower-dimensional domain element with respect to a dof i...
Definition multidomain/facet/box/couplingmanager.hh:377
bool isCoupled(const Element< bulkId > &element, const SubControlVolumeFace< bulkId > &scvf) const
returns true if a bulk scvf flux depends on data in the facet domain.
Definition multidomain/facet/box/couplingmanager.hh:241
const CouplingStencilType< bulkId > & couplingStencil(BulkIdType domainI, const Element< bulkId > &element, LowDimIdType domainJ) const
The coupling stencil of a given bulk domain element.
Definition multidomain/facet/box/couplingmanager.hh:205
Implementation for the coupling manager between two domains of dimension d and (d-1) for models consi...
Definition multidomain/facet/couplingmanager.hh:83
Defines all properties used in Dumux.
Element solution classes and factory functions.
typename NumEqVectorTraits< PrimaryVariables >::type NumEqVector
A vector with the same size as numbers of equations This is the default implementation and has to be ...
Definition numeqvector.hh:34
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
void makeInterpolatedVolVars(VolumeVariables &volVars, const Problem &problem, const SolutionVector &sol, const FVGeometry &fvGeometry, const typename FVGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const typename FVGeometry::GridGeometry::GridView::template Codim< 0 >::Entity::Geometry &elemGeom, const typename FVGeometry::GridGeometry::GridView::template Codim< 0 >::Entity::Geometry::GlobalCoordinate &pos)
Free function that allows the creation of a volume variables object interpolated to a given position ...
Definition multidomain/facet/couplingmanager.hh:40
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)
Definition multidomain/couplingmanager.hh:171
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
The available discretization methods in Dumux.
The interface of the coupling manager for multi domain problems.
Implementation for the coupling manager between two domains of dimension d and (d-1) for models consi...
constexpr Box box
Definition method.hh:147
A helper to deduce a vector with the same size as numbers of equations.