diff --git a/dumux/multidomain/subdomaincclocalassembler.hh b/dumux/multidomain/subdomaincclocalassembler.hh index 8137710c5052d0c78a5836fa6ded044290388601..6647c2d1ff282aa22f58977ed9edd16f98491425 100644 --- a/dumux/multidomain/subdomaincclocalassembler.hh +++ b/dumux/multidomain/subdomaincclocalassembler.hh @@ -151,6 +151,7 @@ public: res[globalI] = this->asImp_().assembleResidualImpl(); // forward to the internal implementation } + //! evaluates the local source term for an element and element volume variables ElementResidualVector evalLocalSourceResidual(const Element& element, const ElementVolumeVariables& elemVolVars) const { // initialize the residual vector for all scvs in this element @@ -169,6 +170,10 @@ public: return residual; } + //! evaluates the local source term depending on time discretization scheme + ElementResidualVector evalLocalSourceResidual(const Element& neighbor) const + { return this->evalLocalSourceResidual(neighbor, implicit ? this->curElemVolVars() : this->prevElemVolVars()); } + LocalResidualValues evalLocalStorageResidual() const { return this->localResidual().evalStorage(this->element(), this->fvGeometry(), this->prevElemVolVars(), this->curElemVolVars())[0]; @@ -180,49 +185,10 @@ public: return this->localResidual().evalFlux(problem(), neighbor, this->fvGeometry(), this->curElemVolVars(), this->elemFluxVarsCache(), scvf); } - const Problem& problem() const - { return this->assembler().problem(domainId); } - - CouplingManager& couplingManager() - { return couplingManager_; } - -private: - CouplingManager& couplingManager_; //!< the coupling manager -}; - -/*! - * \ingroup Assembly - * \ingroup CCDiscretization - * \ingroup MultiDomain - * \brief A base class for all implicit multidomain local assemblers - * \tparam id the id of the sub domain - * \tparam TypeTag the TypeTag - * \tparam Assembler the assembler type - * \tparam Implementation the actual assembler implementation - */ -template<std::size_t id, class TypeTag, class Assembler, class Implementation> -class SubDomainCCLocalAssemblerImplicitBase : public SubDomainCCLocalAssemblerBase<id, TypeTag, Assembler, Implementation, true> -{ - using ParentType = SubDomainCCLocalAssemblerBase<id, TypeTag, Assembler, Implementation, true>; - - using LocalResidualValues = typename GET_PROP_TYPE(TypeTag, NumEqVector); - using ElementResidualVector = typename ParentType::LocalResidual::ElementResidualVector; - using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); - using SubControlVolume = typename FVGridGeometry::SubControlVolume; - using GridView = typename FVGridGeometry::GridView; - using Element = typename GridView::template Codim<0>::Entity; - -public: - //! export the domain id of this sub-domain - static constexpr auto domainId = Dune::index_constant<id>(); - //! pull up constructor of parent class - using ParentType::ParentType; - //! prepares all necessary local views void bindLocalViews() { // get some references for convenience - auto& couplingManager = this->couplingManager(); const auto& element = this->element(); const auto& curSol = this->curSol()[domainId]; auto&& fvGeometry = this->fvGeometry(); @@ -230,24 +196,42 @@ public: auto&& elemFluxVarsCache = this->elemFluxVarsCache(); // bind the caches - couplingManager.bindCouplingContext(domainId, element, this->assembler()); + couplingManager_.bindCouplingContext(domainId, element, this->assembler()); fvGeometry.bind(element); - curElemVolVars.bind(element, fvGeometry, curSol); - elemFluxVarsCache.bind(element, fvGeometry, curElemVolVars); - if (!this->assembler().isStationaryProblem()) - this->prevElemVolVars().bindElement(element, fvGeometry, this->assembler().prevSol()[domainId]); - } - using ParentType::evalLocalSourceResidual; - ElementResidualVector evalLocalSourceResidual(const Element& neighbor) const - { return this->evalLocalSourceResidual(neighbor, this->curElemVolVars()); } + if (implicit) + { + curElemVolVars.bind(element, fvGeometry, curSol); + elemFluxVarsCache.bind(element, fvGeometry, curElemVolVars); + if (!this->assembler().isStationaryProblem()) + this->prevElemVolVars().bindElement(element, fvGeometry, this->assembler().prevSol()[domainId]); + } + else + { + auto& prevElemVolVars = this->prevElemVolVars(); + const auto& prevSol = this->assembler().prevSol()[domainId]; + + curElemVolVars.bindElement(element, fvGeometry, curSol); + prevElemVolVars.bind(element, fvGeometry, prevSol); + elemFluxVarsCache.bind(element, fvGeometry, prevElemVolVars); + } + } /*! * \brief Computes the residual * \return The element residual at the current solution. */ LocalResidualValues assembleResidualImpl() - { return this->elementIsGhost() ? LocalResidualValues(0.0) : this->evalLocalResidual()[0]; } + { return this->evalLocalResidual()[0]; } + + const Problem& problem() const + { return this->assembler().problem(domainId); } + + CouplingManager& couplingManager() + { return couplingManager_; } + +private: + CouplingManager& couplingManager_; //!< the coupling manager }; /*! @@ -272,11 +256,11 @@ class SubDomainCCLocalAssembler; */ template<std::size_t id, class TypeTag, class Assembler> class SubDomainCCLocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, /*implicit=*/true> -: public SubDomainCCLocalAssemblerImplicitBase<id, TypeTag, Assembler, - SubDomainCCLocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, true> > +: public SubDomainCCLocalAssemblerBase<id, TypeTag, Assembler, + SubDomainCCLocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, true>, true> { using ThisType = SubDomainCCLocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, /*implicit=*/true>; - using ParentType = SubDomainCCLocalAssemblerImplicitBase<id, TypeTag, Assembler, ThisType>; + using ParentType = SubDomainCCLocalAssemblerBase<id, TypeTag, Assembler, ThisType, /*implicit=*/true>; using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using LocalResidualValues = typename GET_PROP_TYPE(TypeTag, NumEqVector); @@ -550,11 +534,11 @@ public: */ template<std::size_t id, class TypeTag, class Assembler> class SubDomainCCLocalAssembler<id, TypeTag, Assembler, DiffMethod::analytic, /*implicit=*/true> -: public SubDomainCCLocalAssemblerImplicitBase<id, TypeTag, Assembler, - SubDomainCCLocalAssembler<id, TypeTag, Assembler, DiffMethod::analytic, true> > +: public SubDomainCCLocalAssemblerBase<id, TypeTag, Assembler, + SubDomainCCLocalAssembler<id, TypeTag, Assembler, DiffMethod::analytic, true>, true> { using ThisType = SubDomainCCLocalAssembler<id, TypeTag, Assembler, DiffMethod::analytic, /*implicit=*/true>; - using ParentType = SubDomainCCLocalAssemblerImplicitBase<id, TypeTag, Assembler, ThisType>; + using ParentType = SubDomainCCLocalAssemblerBase<id, TypeTag, Assembler, ThisType, /*implicit=*/true>; using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using LocalResidualValues = typename GET_PROP_TYPE(TypeTag, NumEqVector); using GridView = typename GET_PROP_TYPE(TypeTag, GridView);