13#ifndef DUMUX_POROMECHANICS_COUPLING_MANAGER_HH 
   14#define DUMUX_POROMECHANICS_COUPLING_MANAGER_HH 
   19#include <dune/common/std/type_traits.hh> 
   38template< 
class MDTraits,
 
   39          std::size_t PMFlowId = 0,
 
   40          std::size_t PoroMechId = PMFlowId+1 >
 
   46    template<std::
size_t id> 
using SubDomainTypeTag = 
typename MDTraits::template SubDomain<id>::TypeTag;
 
   52    template<std::
size_t id> 
using PrimaryVariables = 
typename GridVariables<id>::PrimaryVariables;
 
   53    template<std::
size_t id> 
using GridVolumeVariables = 
typename GridVariables<id>::GridVolumeVariables;
 
   54    template<std::
size_t id> 
using ElementVolumeVariables = 
typename GridVolumeVariables<id>::LocalView;
 
   55    template<std::
size_t id> 
using VolumeVariables = 
typename GridVolumeVariables<id>::VolumeVariables;
 
   56    template<std::
size_t id> 
using GridGeometry = 
typename GridVariables<id>::GridGeometry;
 
   57    template<std::
size_t id> 
using FVElementGeometry = 
typename GridGeometry<id>::LocalView;
 
   58    template<std::
size_t id> 
using GridView = 
typename GridGeometry<id>::GridView;
 
   59    template<std::
size_t id> 
using GridIndexType = 
typename GridView<id>::IndexSet::IndexType;
 
   60    template<std::
size_t id> 
using Element = 
typename GridView<id>::template Codim<0>::Entity;
 
   61    template<std::
size_t id> 
using GlobalPosition = 
typename Element<id>::Geometry::GlobalCoordinate;
 
   64    static_assert(std::is_same< GridView<PMFlowId>, GridView<PoroMechId> >::value,
 
   65                  "The grid types of the two sub-problems have to be equal!");
 
   69                  "Poro-mechanical problem must be discretized with the box scheme for this coupling manager!");
 
   73                  "Porous medium flow problem must be discretized with a cell-centered scheme for this coupling manager!");
 
   77                  "Poromechanics framework does not yet work for enabled grid volume variables caching");
 
   80    template<std::
size_t id>
 
   81    using CouplingIndexType = 
typename std::conditional< 
id == PMFlowId,
 
   82                                                         GridIndexType<PoroMechId>,
 
   83                                                         GridIndexType<PMFlowId> >::type;
 
   90    struct PoroMechanicsCouplingContext
 
   93        Element<PMFlowId> pmFlowElement;
 
   94        std::unique_ptr< FVElementGeometry<PMFlowId> > pmFlowFvGeometry;
 
   95        std::unique_ptr< ElementVolumeVariables<PMFlowId> > pmFlowElemVolVars;
 
   99    using Storage = 
decltype(std::declval<T>().localResidual().evalStorage(
 
  100        std::declval<T>().fvGeometry(),
 
  101        std::declval<T>().curElemVolVars()
 
  104    template<
typename LA>
 
  105    static constexpr bool hasExperimentalEvalStorage = Dune::Std::is_detected_v<Storage, LA>;
 
  110    static constexpr auto pmFlowId = Dune::index_constant<PMFlowId>();
 
  111    static constexpr auto poroMechId = Dune::index_constant<PoroMechId>();
 
  118    template<std::
size_t i, std::
size_t j = (i == PMFlowId) ? PoroMechId : PMFlowId>
 
  120                                                           std::vector< CouplingIndexType<i> >,
 
  121                                                           std::array< CouplingIndexType<i>, 1> >::type;
 
  133    void init(std::shared_ptr< Problem<PMFlowId> > pmFlowProblem,
 
  134              std::shared_ptr< Problem<PoroMechId> > poroMechanicalProblem,
 
  144        initializeCouplingMap_();
 
 
  151                                                         const Element<PMFlowId>& element,
 
  152                                                         Dune::index_constant<PoroMechId> poroMechDomainId)
 const 
  154        return pmFlowCouplingMap_[ this->
problem(
pmFlowId).gridGeometry().elementMapper().index(element) ];
 
 
  161                                                          const Element<PoroMechId>& element,
 
  162                                                          Dune::index_constant<PMFlowId> pmFlowDomainId)
 const 
  164        const auto eIdx = this->
problem(
pmFlowId).gridGeometry().elementMapper().index(element);
 
 
  175    template< 
class Assembler >
 
  177                             const Element<PoroMechId>& element,
 
  178                             const Assembler& assembler)
 
  181        poroMechCouplingContext_.pmFlowFvGeometry.reset(
nullptr);
 
  182        poroMechCouplingContext_.pmFlowElemVolVars.reset(
nullptr);
 
  187        const auto elemVolVars = 
localView(assembler.gridVariables(Dune::index_constant<PMFlowId>()).curGridVolVars()).bindElement(element,
 
  189                                                                                                                             this->
curSol(Dune::index_constant<PMFlowId>()));
 
  191        poroMechCouplingContext_.pmFlowElement = element;
 
  192        poroMechCouplingContext_.pmFlowFvGeometry = std::make_unique< FVElementGeometry<PMFlowId> >(fvGeometry);
 
  193        poroMechCouplingContext_.pmFlowElemVolVars = std::make_unique< ElementVolumeVariables<PMFlowId> >(elemVolVars);
 
 
  201    template< 
class PoroMechLocalAssembler >
 
  203                               const PoroMechLocalAssembler& poroMechLocalAssembler,
 
  204                               Dune::index_constant<PMFlowId> pmFlowDomainId,
 
  205                               GridIndexType<PMFlowId> dofIdxGlobalJ,
 
  206                               const PrimaryVariables<PMFlowId>& priVarsJ,
 
  213        const auto& element = poroMechCouplingContext_.pmFlowElement;
 
  214        const auto& fvGeometry = *poroMechCouplingContext_.pmFlowFvGeometry;
 
  215        poroMechCouplingContext_.pmFlowElemVolVars->bindElement(element, fvGeometry, this->
curSol(pmFlowDomainId));
 
 
  224    template< 
class PoroMechLocalAssembler >
 
  226                               const PoroMechLocalAssembler& poroMechLocalAssembler,
 
  227                               Dune::index_constant<PoroMechId> poroMechDomainIdJ,
 
  228                               GridIndexType<PoroMechId> dofIdxGlobalJ,
 
  229                               const PrimaryVariables<PoroMechId>& priVarsJ,
 
  236        (*poroMechCouplingContext_.pmFlowElemVolVars).bindElement(poroMechCouplingContext_.pmFlowElement,
 
  237                                                                  *poroMechCouplingContext_.pmFlowFvGeometry,
 
  238                                                                  this->curSol(Dune::index_constant<PMFlowId>()));
 
 
  245    template< std::
size_t j, 
class PMFlowLocalAssembler >
 
  247                               const PMFlowLocalAssembler& pmFlowLocalAssembler,
 
  248                               Dune::index_constant<j> domainIdJ,
 
  249                               GridIndexType<j> dofIdxGlobalJ,
 
  250                               const PrimaryVariables<j>& priVarsJ,
 
 
  265    template< 
class PMFlowLocalAssembler, 
class UpdatableFluxVarCache >
 
  267                                const PMFlowLocalAssembler& pmFlowLocalAssembler,
 
  268                                ElementVolumeVariables<PMFlowId>& elemVolVars,
 
  269                                UpdatableFluxVarCache& elemFluxVarsCache)
 
  272        elemVolVars.bind(pmFlowLocalAssembler.element(),
 
  273                         pmFlowLocalAssembler.fvGeometry(),
 
  274                         this->curSol(pmFlowDomainId));
 
  277        elemFluxVarsCache.update(pmFlowLocalAssembler.element(),
 
  278                                 pmFlowLocalAssembler.fvGeometry(),
 
 
  287    template< 
class PoroMechLocalAssembler, 
class UpdatableFluxVarCache >
 
  289                                const PoroMechLocalAssembler& poroMechLocalAssembler,
 
  290                                ElementVolumeVariables<PoroMechId>& elemVolVars,
 
  291                                UpdatableFluxVarCache& elemFluxVarsCache)
 
  293        elemVolVars.bind(poroMechLocalAssembler.element(),
 
  294                         poroMechLocalAssembler.fvGeometry(),
 
  295                         this->curSol(poroMechDomainId));
 
 
  304    template< 
class PMFlowLocalAssembler >
 
  306                              const PMFlowLocalAssembler& pmFlowLocalAssembler,
 
  307                              Dune::index_constant<PoroMechId> poroMechDomainId,
 
  308                              GridIndexType<PoroMechId> dofIdxGlobalJ)
 
  310        auto res = pmFlowLocalAssembler.localResidual().evalFluxAndSource(pmFlowLocalAssembler.element(),
 
  311                                                                          pmFlowLocalAssembler.fvGeometry(),
 
  312                                                                          pmFlowLocalAssembler.curElemVolVars(),
 
  313                                                                          pmFlowLocalAssembler.elemFluxVarsCache(),
 
  314                                                                          pmFlowLocalAssembler.elemBcTypes());
 
  317        if (!pmFlowLocalAssembler.localResidual().isStationary())
 
  319            if constexpr (hasExperimentalEvalStorage<PMFlowLocalAssembler>)
 
  320                res += pmFlowLocalAssembler.localResidual().evalStorage(pmFlowLocalAssembler.fvGeometry(),
 
  321                                                                        pmFlowLocalAssembler.curElemVolVars());
 
  323                res += pmFlowLocalAssembler.localResidual().evalStorage(pmFlowLocalAssembler.element(),
 
  324                                                                        pmFlowLocalAssembler.fvGeometry(),
 
  325                                                                        pmFlowLocalAssembler.prevElemVolVars(),
 
  326                                                                        pmFlowLocalAssembler.curElemVolVars());
 
 
  338    template< 
class PoroMechLocalAssembler >
 
  340                              const PoroMechLocalAssembler& poroMechLocalAssembler,
 
  341                              Dune::index_constant<PMFlowId> pmFlowDomainId,
 
  342                              GridIndexType<PMFlowId> dofIdxGlobalJ)
 
  344        return poroMechLocalAssembler.localResidual().evalFluxAndSource(poroMechLocalAssembler.element(),
 
  345                                                                        poroMechLocalAssembler.fvGeometry(),
 
  346                                                                        poroMechLocalAssembler.curElemVolVars(),
 
  347                                                                        poroMechLocalAssembler.elemFluxVarsCache(),
 
  348                                                                        poroMechLocalAssembler.elemBcTypes());
 
 
  352    const VolumeVariables<PMFlowId>& 
getPMFlowVolVars(
const Element<PoroMechId>& element)
 const 
  355        const auto eIdx = this->
problem(
poroMechId).gridGeometry().elementMapper().index(element);
 
  356        return (*poroMechCouplingContext_.pmFlowElemVolVars)[eIdx];
 
 
  364    template<std::
size_t i>
 
  365    const auto& 
curSol(Dune::index_constant<i> domainIdx)
 const 
 
  375    void initializeCouplingMap_()
 
  383        if (pmFlowGridGeom.gridView().size(0) != poroMechGridGeom.gridView().size(0))
 
  384            DUNE_THROW(Dune::InvalidStateException, 
"The two sub-problems are assumed to operate on the same mesh!");
 
  386        pmFlowCouplingMap_.resize(pmFlowGridGeom.gridView().size(0));
 
  387        static constexpr int dim = GridView<PMFlowId>::dimension;
 
  388        for (
const auto& element : elements(pmFlowGridGeom.gridView()))
 
  390            const auto eIdx = pmFlowGridGeom.elementMapper().index(element);
 
  393            for (
int i = 0; i < element.geometry().corners(); ++i)
 
  394                pmFlowCouplingMap_[eIdx].push_back( poroMechGridGeom.vertexMapper().subIndex(element, i , dim) );
 
  399            const auto& inverseConnectivity = pmFlowGridGeom.connectivityMap()[eIdx];
 
  400            for (
const auto& dataJ : inverseConnectivity)
 
  401                for (
int i = 0; i < element.geometry().corners(); ++i)
 
  402                    pmFlowCouplingMap_[dataJ.globalJ].push_back( poroMechGridGeom.vertexMapper().subIndex(element, i , dim) );
 
  406        for (
auto& stencil : pmFlowCouplingMap_)
 
  408            std::sort(stencil.begin(), stencil.end());
 
  409            stencil.erase(std::unique(stencil.begin(), stencil.end()), stencil.end());
 
  414    std::vector< CouplingStencilType<PMFlowId> > pmFlowCouplingMap_;
 
  417    PoroMechanicsCouplingContext poroMechCouplingContext_;
 
 
void updateCoupledVariables(Dune::index_constant< i > domainI, const LocalAssemblerI &localAssemblerI, UpdatableElementVolVars &elemVolVars, UpdatableFluxVarCache &elemFluxVarsCache)
Definition multidomain/couplingmanager.hh:196
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
void bindCouplingContext(Dune::index_constant< i > domainI, const Element< i > &elementI, const Assembler &assembler)
Definition multidomain/couplingmanager.hh:145
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
Coupling manager for porous medium flow problems coupled to a poro-mechanical problem.
Definition poromechanics/poroelastic/couplingmanager.hh:42
void bindCouplingContext(Dune::index_constant< PoroMechId > poroMechDomainId, const Element< PoroMechId > &element, const Assembler &assembler)
For the assembly of the element residual of an element of the poro-mechanics domain,...
Definition poromechanics/poroelastic/couplingmanager.hh:176
auto evalCouplingResidual(Dune::index_constant< PMFlowId > pmFlowDomainId, const PMFlowLocalAssembler &pmFlowLocalAssembler, Dune::index_constant< PoroMechId > poroMechDomainId, GridIndexType< PoroMechId > dofIdxGlobalJ)
Evaluates the coupling element residual of the porous medium flow domain with respect to the poro-mec...
Definition poromechanics/poroelastic/couplingmanager.hh:305
void updateCoupledVariables(Dune::index_constant< PoroMechId > poroMechDomainId, const PoroMechLocalAssembler &poroMechLocalAssembler, ElementVolumeVariables< PoroMechId > &elemVolVars, UpdatableFluxVarCache &elemFluxVarsCache)
Update the poro-mechanics volume variables after the coupling context has been updated....
Definition poromechanics/poroelastic/couplingmanager.hh:288
void updateCoupledVariables(Dune::index_constant< PMFlowId > pmFlowDomainId, const PMFlowLocalAssembler &pmFlowLocalAssembler, ElementVolumeVariables< PMFlowId > &elemVolVars, UpdatableFluxVarCache &elemFluxVarsCache)
Update the porous medium flow domain volume variables and flux variables cache after the coupling con...
Definition poromechanics/poroelastic/couplingmanager.hh:266
const VolumeVariables< PMFlowId > & getPMFlowVolVars(const Element< PoroMechId > &element) const
Return the porous medium flow variables an element/scv of the poromech domain couples to.
Definition poromechanics/poroelastic/couplingmanager.hh:352
void updateCouplingContext(Dune::index_constant< PMFlowId > pmFlowDomainId, const PMFlowLocalAssembler &pmFlowLocalAssembler, Dune::index_constant< j > domainIdJ, GridIndexType< j > dofIdxGlobalJ, const PrimaryVariables< j > &priVarsJ, unsigned int pvIdxJ)
We need this overload to avoid ambiguity. However, for the porous medium flow domain weonly have to u...
Definition poromechanics/poroelastic/couplingmanager.hh:246
auto evalCouplingResidual(Dune::index_constant< PoroMechId > poroMechDomainId, const PoroMechLocalAssembler &poroMechLocalAssembler, Dune::index_constant< PMFlowId > pmFlowDomainId, GridIndexType< PMFlowId > dofIdxGlobalJ)
Evaluates the coupling element residual of the poromechanical domain with respect to the porous mediu...
Definition poromechanics/poroelastic/couplingmanager.hh:339
static constexpr auto pmFlowId
Definition poromechanics/poroelastic/couplingmanager.hh:110
void updateCouplingContext(Dune::index_constant< PoroMechId > poroMechDomainIdI, const PoroMechLocalAssembler &poroMechLocalAssembler, Dune::index_constant< PoroMechId > poroMechDomainIdJ, GridIndexType< PoroMechId > dofIdxGlobalJ, const PrimaryVariables< PoroMechId > &priVarsJ, unsigned int pvIdxJ)
After deflection of the solution in the poromechanics domain during element residual assembly in that...
Definition poromechanics/poroelastic/couplingmanager.hh:225
void updateCouplingContext(Dune::index_constant< PoroMechId > poroMechDomainId, const PoroMechLocalAssembler &poroMechLocalAssembler, Dune::index_constant< PMFlowId > pmFlowDomainId, GridIndexType< PMFlowId > dofIdxGlobalJ, const PrimaryVariables< PMFlowId > &priVarsJ, unsigned int pvIdxJ)
After deflection of the solution in the porous medium flow domain during element residual assembly in...
Definition poromechanics/poroelastic/couplingmanager.hh:202
typename std::conditional< i==PMFlowId, std::vector< CouplingIndexType< i > >, std::array< CouplingIndexType< i >, 1 > >::type CouplingStencilType
The types used for coupling stencils. An element of the poro-mechanical domain always only couples to...
Definition poromechanics/poroelastic/couplingmanager.hh:119
void init(std::shared_ptr< Problem< PMFlowId > > pmFlowProblem, std::shared_ptr< Problem< PoroMechId > > poroMechanicalProblem, const SolutionVector &curSol)
Initialize the coupling manager.
Definition poromechanics/poroelastic/couplingmanager.hh:133
const CouplingStencilType< PoroMechId > couplingStencil(Dune::index_constant< PoroMechId > poroMechDomainId, const Element< PoroMechId > &element, Dune::index_constant< PMFlowId > pmFlowDomainId) const
Return the coupling element stencil for a given poro-mechanical domain element.
Definition poromechanics/poroelastic/couplingmanager.hh:160
const auto & curSol(Dune::index_constant< i > domainIdx) const
the solution vector of the subproblem
Definition poromechanics/poroelastic/couplingmanager.hh:365
typename MDTraits::SolutionVector SolutionVector
the type of the solution vector
Definition poromechanics/poroelastic/couplingmanager.hh:124
static constexpr auto poroMechId
Definition poromechanics/poroelastic/couplingmanager.hh:111
const CouplingStencilType< PMFlowId > & couplingStencil(Dune::index_constant< PMFlowId > pmFlowDomainId, const Element< PMFlowId > &element, Dune::index_constant< PoroMechId > poroMechDomainId) const
Return the coupling stencil for a given porous medium flow domain element.
Definition poromechanics/poroelastic/couplingmanager.hh:150
Defines all properties used in Dumux.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
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.
constexpr CCMpfa ccmpfa
Definition method.hh:146
constexpr CCTpfa cctpfa
Definition method.hh:145
constexpr Box box
Definition method.hh:147