diff --git a/dumux/multidomain/boundary/stokesdarcy/couplingdata.hh b/dumux/multidomain/boundary/stokesdarcy/couplingdata.hh index e2d204d4b0a4879590ca1e388f214c81cc475026..5846529cb7ae160a9c37a9cce145de35f5b81382 100644 --- a/dumux/multidomain/boundary/stokesdarcy/couplingdata.hh +++ b/dumux/multidomain/boundary/stokesdarcy/couplingdata.hh @@ -76,43 +76,110 @@ struct StokesDarcyCouplingOptions * \ingroup BoundaryCoupling * \ingroup StokesDarcyCoupling * \brief This structs helps to check if the two sub models use the same fluidsystem. - * \tparam FSFF The free-flow fluidsystem - * \tparam FSFF The porous-medium flow fluidsystem - * \tparam numPhasesPM The number of phases used in the porous-medium flow model. + * Specialization for the case of using an adapter only for the free-flow model. + * \tparam FFFS The free-flow fluidsystem + * \tparam PMFS The porous-medium flow fluidsystem */ -template<class FSFF, class FSPM, int numPhasesPM> -struct IsSameFluidSystem; +template<class FFFS, class PMFS> +struct IsSameFluidSystem +{ + static_assert(FFFS::numPhases == 1, "Only single-phase fluidsystems may be used for free flow."); + static constexpr bool value = std::is_same<typename FFFS::MultiPhaseFluidSystem, PMFS>::value; +}; /*! * \ingroup MultiDomain * \ingroup BoundaryCoupling * \ingroup StokesDarcyCoupling * \brief This structs helps to check if the two sub models use the same fluidsystem. - * Specialization for single-phase porous-medium models. - * \tparam FSFF The free-flow fluidsystem - * \tparam FSFF The porous-medium flow fluidsystem + * \tparam FS The fluidsystem */ -template<class FSFF, class FSPM> -struct IsSameFluidSystem<FSFF, FSPM, 1> +template<class FS> +struct IsSameFluidSystem<FS, FS> { - static constexpr bool value = std::is_same<FSFF, FSPM>::value; + static_assert(FS::numPhases == 1, "Only single-phase fluidsystems may be used for free flow."); + static constexpr bool value = std::is_same<FS, FS>::value; // always true }; /*! * \ingroup MultiDomain * \ingroup BoundaryCoupling * \ingroup StokesDarcyCoupling - * \brief This structs helps to check if the two sub models use the same fluidsystem. - * Specialization for two-phase porous-medium models. - * \tparam FSFF The free-flow fluidsystem - * \tparam FSFF The porous-medium flow fluidsystem + * \brief Helper struct to choose the correct index for phases and components. This is need if the porous-medium-flow model + features more fluid phases than the free-flow model. + * \tparam stokesIdx The domain index of the free-flow model. + * \tparam darcyIdx The domain index of the porous-medium-flow model. + * \tparam FFFS The free-flow fluidsystem. + * \tparam hasAdapter Specifies whether an adapter class for the fluidsystem is used. + */ +template<std::size_t stokesIdx, std::size_t darcyIdx, class FFFS, bool hasAdapter> +struct IndexHelper; + +/*! + * \ingroup MultiDomain + * \ingroup BoundaryCoupling + * \ingroup StokesDarcyCoupling + * \brief Helper struct to choose the correct index for phases and components. This is need if the porous-medium-flow model + features more fluid phases than the free-flow model. Specialization for the case that no adapter is used. + * \tparam stokesIdx The domain index of the free-flow model. + * \tparam darcyIdx The domain index of the porous-medium-flow model. + * \tparam FFFS The free-flow fluidsystem. */ -template<class FSFF, class FSPM> -struct IsSameFluidSystem<FSFF, FSPM, 2> +template<std::size_t stokesIdx, std::size_t darcyIdx, class FFFS> +struct IndexHelper<stokesIdx, darcyIdx, FFFS, false> { - static constexpr bool value = std::is_same<typename FSFF::MultiPhaseFluidSystem, FSPM>::value; + /*! + * \brief No adapter is used, just return the input index. + */ + template<std::size_t i> + static constexpr auto couplingPhaseIdx(Dune::index_constant<i>, int coupledPhaseIdx = 0) + { return coupledPhaseIdx; } + + /*! + * \brief No adapter is used, just return the input index. + */ + template<std::size_t i> + static constexpr auto couplingCompIdx(Dune::index_constant<i>, int coupledCompdIdx) + { return coupledCompdIdx; } }; +/*! + * \ingroup MultiDomain + * \ingroup BoundaryCoupling + * \ingroup StokesDarcyCoupling + * \brief Helper struct to choose the correct index for phases and components. This is need if the porous-medium-flow model + features more fluid phases than the free-flow model. Specialization for the case that a adapter is used. + * \tparam stokesIdx The domain index of the free-flow model. + * \tparam darcyIdx The domain index of the porous-medium-flow model. + * \tparam FFFS The free-flow fluidsystem. + */ +template<std::size_t stokesIdx, std::size_t darcyIdx, class FFFS> +struct IndexHelper<stokesIdx, darcyIdx, FFFS, true> +{ + /*! + * \brief The free-flow model always uses phase index 0. + */ + static constexpr auto couplingPhaseIdx(Dune::index_constant<stokesIdx>, int coupledPhaseIdx = 0) + { return 0; } + + /*! + * \brief The phase index of the porous-medium-flow model is given by the adapter fluidsytem (i.e., user input). + */ + static constexpr auto couplingPhaseIdx(Dune::index_constant<darcyIdx>, int coupledPhaseIdx = 0) + { return FFFS::multiphaseFluidsystemPhaseIdx; } + + /*! + * \brief The free-flow model does not need any change of the component index. + */ + static constexpr auto couplingCompIdx(Dune::index_constant<stokesIdx>, int coupledCompdIdx) + { return coupledCompdIdx; } + + /*! + * \brief The component index of the porous-medium-flow model is mapped by the adapter fluidsytem. + */ + static constexpr auto couplingCompIdx(Dune::index_constant<darcyIdx>, int coupledCompdIdx) + { return FFFS::compIdx(coupledCompdIdx); } +}; template<class MDTraits, class CouplingManager, bool enableEnergyBalance, bool isCompositional> class StokesDarcyCouplingDataImplementation; @@ -154,20 +221,15 @@ class StokesDarcyCouplingDataImplementationBase static constexpr auto stokesIdx = CouplingManager::stokesIdx; static constexpr auto darcyIdx = CouplingManager::darcyIdx; - - - - - + static constexpr bool adapterUsed = ModelTraits<darcyIdx>::numPhases() > 1; + using IndexHelper = Dumux::IndexHelper<stokesIdx, darcyIdx, FluidSystem<stokesIdx>, adapterUsed>; static constexpr int enableEnergyBalance = GET_PROP_TYPE(SubDomainTypeTag<stokesIdx>, ModelTraits)::enableEnergyBalance(); static_assert(GET_PROP_TYPE(SubDomainTypeTag<darcyIdx>, ModelTraits)::enableEnergyBalance() == enableEnergyBalance, "All submodels must both be either isothermal or non-isothermal"); static_assert(IsSameFluidSystem<FluidSystem<stokesIdx>, - FluidSystem<darcyIdx>, - GET_PROP_TYPE(SubDomainTypeTag<darcyIdx>, ModelTraits)::numPhases() - >::value, + FluidSystem<darcyIdx>>::value, "All submodels must use the same fluid system"); using DiffusionCoefficientAveragingType = typename StokesDarcyCouplingOptions::DiffusionCoefficientAveragingType; @@ -175,32 +237,19 @@ class StokesDarcyCouplingDataImplementationBase public: StokesDarcyCouplingDataImplementationBase(const CouplingManager& couplingmanager): couplingManager_(couplingmanager) {} - template<std::size_t i, bool hasAdapter = (ModelTraits<darcyIdx>::numPhases() > 1), std::enable_if_t<!hasAdapter, int> = 0> - static constexpr auto couplingPhaseIdx(Dune::index_constant<i>, int coupledPhaseIdx = 0) - { return 0; } - - template<bool hasAdapter = (ModelTraits<darcyIdx>::numPhases() > 1), std::enable_if_t<hasAdapter, int> = 0> - static constexpr auto couplingPhaseIdx(Dune::index_constant<stokesIdx>, int coupledPhaseIdx = 0) - { return 0; } - - template<bool hasAdapter = (ModelTraits<darcyIdx>::numPhases() > 1), std::enable_if_t<hasAdapter, int> = 0> - static constexpr auto couplingPhaseIdx(Dune::index_constant<darcyIdx>, int coupledPhaseIdx = 0) - { return FluidSystem<stokesIdx>::multiphaseFluidsystemPhaseIdx; } - - - - - template<std::size_t i, bool hasAdapter = (ModelTraits<darcyIdx>::numPhases() > 1), std::enable_if_t<!hasAdapter, int> = 0> - static constexpr auto couplingCompIdx(Dune::index_constant<i>, int coupledCompdIdx) - { return coupledCompdIdx; } - - template<bool hasAdapter = (ModelTraits<darcyIdx>::numPhases() > 1), std::enable_if_t<hasAdapter, int> = 0> - static constexpr auto couplingCompIdx(Dune::index_constant<stokesIdx>, int coupledCompdIdx) - { return coupledCompdIdx; } + /*! + * \brief Returns the corresponding phase index needed for coupling. + */ + template<std::size_t i> + static constexpr auto couplingPhaseIdx(Dune::index_constant<i> id, int coupledPhaseIdx = 0) + { return IndexHelper::couplingPhaseIdx(id, coupledPhaseIdx); } - template<bool hasAdapter = (ModelTraits<darcyIdx>::numPhases() > 1), std::enable_if_t<hasAdapter, int> = 0> - static constexpr auto couplingCompIdx(Dune::index_constant<darcyIdx>, int coupledCompdIdx) - { return FluidSystem<stokesIdx>::compIdx(coupledCompdIdx); } + /*! + * \brief Returns the corresponding component index needed for coupling. + */ + template<std::size_t i> + static constexpr auto couplingCompIdx(Dune::index_constant<i> id, int coupledCompdIdx) + { return IndexHelper::couplingCompIdx(id, coupledCompdIdx); } /*! * \brief Returns a reference to the coupling manager. diff --git a/test/multidomain/boundary/stokesdarcy/1p_2p/darcyproblem.hh b/test/multidomain/boundary/stokesdarcy/1p_2p/darcyproblem.hh index 47bfba7e6a277b3bc41f2f134c7d4f6e9d3e9f78..234c34f6b136c0eeebe1333da29b0c34b056d024 100644 --- a/test/multidomain/boundary/stokesdarcy/1p_2p/darcyproblem.hh +++ b/test/multidomain/boundary/stokesdarcy/1p_2p/darcyproblem.hh @@ -33,13 +33,6 @@ #include "spatialparams.hh" -#include <dumux/material/fluidsystems/2pimmiscible.hh> -#include <dumux/material/fluidsystems/1pliquid.hh> -#include <dumux/material/fluidsystems/1pgas.hh> -#include <dumux/material/components/air.hh> -#include <dumux/material/components/simpleh2o.hh> -#include <dumux/material/components/tabulatedcomponent.hh> - namespace Dumux { template <class TypeTag> @@ -52,17 +45,6 @@ NEW_TYPE_TAG(DarcyTwoPTypeTag, INHERITS_FROM(CCTpfaModel, TwoP)); // Set the problem property SET_TYPE_PROP(DarcyTwoPTypeTag, Problem, Dumux::DarcySubProblem<TypeTag>); -// the fluid system -SET_PROP(DarcyTwoPTypeTag, FluidSystem) -{ - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using H2OType = Dumux::Components::SimpleH2O<Scalar>; - using H2OPhase = Dumux::FluidSystems::OnePLiquid<Scalar, H2OType>; - using AirType = Dumux::Components::TabulatedComponent<Components::Air<Scalar>, false >; - using AirPhase = Dumux::FluidSystems::OnePGas<Scalar, AirType>; - using type = FluidSystems::TwoPImmiscible<Scalar, H2OPhase, AirPhase> ; -}; - // Set the grid type #if ENABLE_3D SET_TYPE_PROP(DarcyTwoPTypeTag, Grid, Dune::YaspGrid<3>); diff --git a/test/multidomain/boundary/stokesdarcy/1p_2p/stokesproblem.hh b/test/multidomain/boundary/stokesdarcy/1p_2p/stokesproblem.hh index f4264647660c22e656d054b04be3066b15125d62..48c5129c3d77c1c99dbef98ee6189bbd9f3e0ae3 100644 --- a/test/multidomain/boundary/stokesdarcy/1p_2p/stokesproblem.hh +++ b/test/multidomain/boundary/stokesdarcy/1p_2p/stokesproblem.hh @@ -26,14 +26,6 @@ #include <dune/grid/yaspgrid.hh> -#include <dumux/material/fluidsystems/1padapter.hh> -#include <dumux/material/fluidsystems/2pimmiscible.hh> -#include <dumux/material/fluidsystems/1pliquid.hh> -#include <dumux/material/fluidsystems/1pgas.hh> -#include <dumux/material/components/air.hh> -#include <dumux/material/components/simpleh2o.hh> -#include <dumux/material/components/tabulatedcomponent.hh> - #include <dumux/freeflow/navierstokes/problem.hh> #include <dumux/discretization/staggered/freeflow/properties.hh> #include <dumux/freeflow/navierstokes/model.hh> @@ -50,20 +42,6 @@ NEW_TYPE_TAG(StokesOnePTypeTag, INHERITS_FROM(StaggeredFreeFlowModel, NavierStok // Set the grid type SET_TYPE_PROP(StokesOnePTypeTag, Grid, Dune::YaspGrid<2, Dune::EquidistantOffsetCoordinates<typename GET_PROP_TYPE(TypeTag, Scalar), 2> >); -// the fluid system -SET_PROP(StokesOnePTypeTag, FluidSystem) -{ - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using H2OType = Components::SimpleH2O<Scalar>; - using H2OPhase = FluidSystems::OnePLiquid<Scalar, H2OType>; - using AirType = Components::TabulatedComponent<Components::Air<Scalar>, false >; - using AirPhase = FluidSystems::OnePGas<Scalar, AirType>; - using TwoPFluidSystem = FluidSystems::TwoPImmiscible<Scalar, H2OPhase, AirPhase> ; - - static constexpr auto phaseIdx = 1; // simulate the air phase - using type = FluidSystems::OnePAdapter<TwoPFluidSystem, phaseIdx>; -}; - // Set the problem property SET_TYPE_PROP(StokesOnePTypeTag, Problem, Dumux::StokesSubProblem<TypeTag> ); diff --git a/test/multidomain/boundary/stokesdarcy/1p_2p/test_stokes1pdarcy2pvertical.cc b/test/multidomain/boundary/stokesdarcy/1p_2p/test_stokes1pdarcy2pvertical.cc index 35d4dc9ccc04a076ca7e788009f15786608a193a..dd9742849d991305d2978cddfe98b4c574bc1bca 100644 --- a/test/multidomain/boundary/stokesdarcy/1p_2p/test_stokes1pdarcy2pvertical.cc +++ b/test/multidomain/boundary/stokesdarcy/1p_2p/test_stokes1pdarcy2pvertical.cc @@ -49,6 +49,14 @@ #include <dumux/multidomain/boundary/stokesdarcy/couplingmanager.hh> +#include <dumux/material/fluidsystems/2pimmiscible.hh> +#include <dumux/material/fluidsystems/1pliquid.hh> +#include <dumux/material/fluidsystems/1pgas.hh> +#include <dumux/material/components/air.hh> +#include <dumux/material/components/simpleh2o.hh> +#include <dumux/material/components/tabulatedcomponent.hh> +#include <dumux/material/fluidsystems/1padapter.hh> + #include "darcyproblem.hh" #include "stokesproblem.hh" @@ -67,6 +75,30 @@ SET_PROP(DarcyTwoPTypeTag, CouplingManager) using type = Dumux::StokesDarcyCouplingManager<Traits>; }; +template<class TypeTag> +struct CouplingFluidSystem +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using H2OType = Dumux::Components::SimpleH2O<Scalar>; + using H2OPhase = Dumux::FluidSystems::OnePLiquid<Scalar, H2OType>; + using AirType = Dumux::Components::TabulatedComponent<Components::Air<Scalar>, false >; + using AirPhase = Dumux::FluidSystems::OnePGas<Scalar, AirType>; + using type = FluidSystems::TwoPImmiscible<Scalar, H2OPhase, AirPhase> ; +}; + +// the fluid system for the free-flow model +SET_PROP(StokesOnePTypeTag, FluidSystem) +{ + static constexpr auto phaseIdx = 1; // simulate the air phase + using type = FluidSystems::OnePAdapter<typename CouplingFluidSystem<TypeTag>::type, phaseIdx>; +}; + +// the fluid system for the Darcy model +SET_PROP(DarcyTwoPTypeTag, FluidSystem) +{ + using type = typename CouplingFluidSystem<TypeTag>::type; +}; + } // end namespace Properties } // end namespace Dumux