diff --git a/test/freeflow/navierstokesnc/densitydrivenflow/CMakeLists.txt b/test/freeflow/navierstokesnc/densitydrivenflow/CMakeLists.txt index d439f49b32ac3f06e6199fd101ad8481a8654b81..acbf3779a135144f21b51a6a00a384aeb2b3d6f3 100644 --- a/test/freeflow/navierstokesnc/densitydrivenflow/CMakeLists.txt +++ b/test/freeflow/navierstokesnc/densitydrivenflow/CMakeLists.txt @@ -1,9 +1,10 @@ # SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder # SPDX-License-Identifier: GPL-3.0-or-later +dune_symlink_to_source_files(FILES "params.input") dumux_add_test(NAME test_ff_stokes2c_densitydrivenflow - LABELS freeflow navierstokes + LABELS freeflow navierstokesnc navierstokes SOURCES main.cc CMAKE_GUARD HAVE_UMFPACK COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py @@ -11,10 +12,4 @@ dumux_add_test(NAME test_ff_stokes2c_densitydrivenflow --files ${CMAKE_SOURCE_DIR}/test/references/test_ff_stokes2c_densitydrivenflow-reference.vtu ${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokes2c_densitydrivenflow-00021.vtu --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokes2c_densitydrivenflow params.input - -Problem.Name test_ff_stokes2c_densitydrivenflow" - --zeroThreshold {"X^Air_liq":1e-12} - --zeroThreshold {"x^Air_liq":1e-12} - --zeroThreshold {"velocity_liq \(m/s\)":1e-10} - --zeroThreshold {"deltaRho":1e-7}) - -dune_symlink_to_source_files(FILES "params.input") + -Problem.Name test_ff_stokes2c_densitydrivenflow") diff --git a/test/freeflow/navierstokesnc/densitydrivenflow/main.cc b/test/freeflow/navierstokesnc/densitydrivenflow/main.cc index 14f759c687d05bea6e5a2bb1bf7aa20991236409..1ae94100474fc9cfee97bc53685ed586f0ac0e96 100644 --- a/test/freeflow/navierstokesnc/densitydrivenflow/main.cc +++ b/test/freeflow/navierstokesnc/densitydrivenflow/main.cc @@ -7,7 +7,7 @@ /*! * \file * \ingroup NavierStokesNCTests - * \brief Test for the staggered grid multi-component (Navier-)Stokes model. + * \brief Density Driven Test for the staggered grid multi-component (Navier-)Stokes model */ #include <config.h> @@ -17,21 +17,25 @@ #include <dune/common/parallel/mpihelper.hh> #include <dune/common/timer.hh> -#include <dune/grid/io/file/vtk.hh> #include <dune/istl/io.hh> -#include <dumux/assembly/staggeredfvassembler.hh> #include <dumux/assembly/diffmethod.hh> #include <dumux/common/initialize.hh> #include <dumux/common/dumuxmessage.hh> #include <dumux/common/parameters.hh> #include <dumux/common/properties.hh> + #include <dumux/io/grid/gridmanager_yasp.hh> -#include <dumux/io/staggeredvtkoutputmodule.hh> #include <dumux/linear/istlsolvers.hh> #include <dumux/linear/linearsolvertraits.hh> #include <dumux/linear/linearalgebratraits.hh> #include <dumux/nonlinear/newtonsolver.hh> +#include <dumux/io/vtkoutputmodule.hh> +#include <dumux/freeflow/navierstokes/velocityoutput.hh> + +#include <dumux/multidomain/fvassembler.hh> +#include <dumux/multidomain/traits.hh> +#include <dumux/multidomain/newtonsolver.hh> #include "properties.hh" @@ -40,7 +44,8 @@ int main(int argc, char** argv) using namespace Dumux; // define the type tag for this problem - using TypeTag = Properties::TTag::DensityDrivenFlow; + using MomentumTypeTag = Properties::TTag::DensityDrivenFlowMomentum; + using MassTypeTag = Properties::TTag::DensityDrivenFlowMass; // maybe initialize MPI and/or multithreading backend initialize(argc, argv); @@ -54,7 +59,7 @@ int main(int argc, char** argv) Parameters::init(argc, argv); // try to create a grid (from the given grid file or the input file) - GridManager<GetPropType<TypeTag, Properties::Grid>> gridManager; + GridManager<GetPropType<MomentumTypeTag, Properties::Grid>> gridManager; gridManager.init(); //////////////////////////////////////////////////////////// @@ -65,54 +70,84 @@ int main(int argc, char** argv) const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); + using MomentumGridGeometry = GetPropType<MomentumTypeTag, Properties::GridGeometry>; + auto momentumGridGeometry = std::make_shared<MomentumGridGeometry>(leafGridView); + using MassGridGeometry = GetPropType<MassTypeTag, Properties::GridGeometry>; + auto massGridGeometry = std::make_shared<MassGridGeometry>(leafGridView); + + // the coupling manager + using CouplingManager = GetPropType<MomentumTypeTag, Properties::CouplingManager>; + auto couplingManager = std::make_shared<CouplingManager>(); + + // the problem (boundary conditions) + using MomentumProblem = GetPropType<MomentumTypeTag, Properties::Problem>; + auto momentumProblem = std::make_shared<MomentumProblem>(momentumGridGeometry, couplingManager); + using MassProblem = GetPropType<MassTypeTag, Properties::Problem>; + auto massProblem = std::make_shared<MassProblem>(massGridGeometry, couplingManager); - // the problem (initial and boundary conditions) - using Problem = GetPropType<TypeTag, Properties::Problem>; - auto problem = std::make_shared<Problem>(gridGeometry); + // Initialize the fluid system + GetPropType<MassTypeTag, Properties::FluidSystem>::init(); // get some time loop parameters - using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using Scalar = GetPropType<MomentumTypeTag, Properties::Scalar>; const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); - // instantiate time loop - auto timeLoop = std::make_shared<TimeLoop<Scalar>>(0, dt, tEnd); - timeLoop->setMaxTimeStepSize(maxDt); + // check if we are about to restart a previously interrupted simulation + Scalar restartTime = getParam<Scalar>("Restart.Time", 0); // the solution vector - using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + constexpr auto momentumIdx = CouplingManager::freeFlowMomentumIndex; + constexpr auto massIdx = CouplingManager::freeFlowMassIndex; + using Traits = MultiDomainTraits<MomentumTypeTag, MassTypeTag>; + using SolutionVector = typename Traits::SolutionVector; SolutionVector x; - x[GridGeometry::cellCenterIdx()].resize(gridGeometry->numCellCenterDofs()); - x[GridGeometry::faceIdx()].resize(gridGeometry->numFaceDofs()); - problem->applyInitialSolution(x); + x[momentumIdx].resize(momentumGridGeometry->numDofs()); + x[massIdx].resize(massGridGeometry->numDofs()); + momentumProblem->applyInitialSolution(x[momentumIdx]); + massProblem->applyInitialSolution(x[massIdx]); auto xOld = x; + // instantiate time loop + auto timeLoop = std::make_shared<CheckPointTimeLoop<Scalar>>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + massProblem->setTimeLoop(timeLoop); + momentumProblem->setTimeLoop(timeLoop); + // the grid variables - using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; - auto gridVariables = std::make_shared<GridVariables>(problem, gridGeometry); - gridVariables->init(x); + using MomentumGridVariables = GetPropType<MomentumTypeTag, Properties::GridVariables>; + auto momentumGridVariables = std::make_shared<MomentumGridVariables>(momentumProblem, momentumGridGeometry); - // initialize the vtk output module - using IOFields = GetPropType<TypeTag, Properties::IOFields>; - StaggeredVtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); - IOFields::initOutputModule(vtkWriter); // Add model specific output fields - vtkWriter.addField(problem->getDeltaRho(), "deltaRho"); - vtkWriter.write(0.0); + using MassGridVariables = GetPropType<MassTypeTag, Properties::GridVariables>; + auto massGridVariables = std::make_shared<MassGridVariables>(massProblem, massGridGeometry); - // the assembler with time loop for instationary problem - using Assembler = StaggeredFVAssembler<TypeTag, DiffMethod::numeric>; - auto assembler = std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); + couplingManager->init(momentumProblem, massProblem, std::make_tuple(momentumGridVariables, massGridVariables), x, xOld); + momentumGridVariables->init(x[momentumIdx]); + massGridVariables->init(x[massIdx]); + // initialize the vtk output module + using IOFields = GetPropType<MassTypeTag, Properties::IOFields>; + VtkOutputModule vtkWriter(*massGridVariables, x[massIdx], massProblem->name()); + IOFields::initOutputModule(vtkWriter); // Add model specific output fields + vtkWriter.addVelocityOutput(std::make_shared<NavierStokesVelocityOutput<MassGridVariables>>()); + vtkWriter.addVolumeVariable([](const auto& volVars){ return volVars.density() - 999.694; }, "deltaRho"); + vtkWriter.write(0); + + using Assembler = MultiDomainFVAssembler<Traits, CouplingManager, DiffMethod::numeric>; + auto assembler = std::make_shared<Assembler>(std::make_tuple(momentumProblem, massProblem), + std::make_tuple(momentumGridGeometry, massGridGeometry), + std::make_tuple(momentumGridVariables, massGridVariables), + couplingManager, + timeLoop, xOld); // the linear solver using LinearSolver = Dumux::UMFPackIstlSolver<SeqLinearSolverTraits, LinearAlgebraTraitsFromAssembler<Assembler>>; auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; - NewtonSolver nonLinearSolver(assembler, linearSolver); + using NewtonSolver = MultiDomainNewtonSolver<Assembler, LinearSolver, CouplingManager>; + NewtonSolver nonLinearSolver(assembler, linearSolver, couplingManager); // time loop timeLoop->start(); do @@ -122,13 +157,12 @@ int main(int argc, char** argv) // make the new solution the old solution xOld = x; - gridVariables->advanceTimeStep(); + momentumGridVariables->advanceTimeStep(); + massGridVariables->advanceTimeStep(); // advance to the time loop to the next step timeLoop->advanceTimeStep(); - problem->calculateDeltaRho(*gridVariables, x); - // write vtk output vtkWriter.write(timeLoop->time()); diff --git a/test/freeflow/navierstokesnc/densitydrivenflow/problem.hh b/test/freeflow/navierstokesnc/densitydrivenflow/problem.hh index b900d90f4a7efef7d671d9c55bd6e5d1e8c1b157..e11b64e63926986e7082a1c2919a529a17a20e4a 100644 --- a/test/freeflow/navierstokesnc/densitydrivenflow/problem.hh +++ b/test/freeflow/navierstokesnc/densitydrivenflow/problem.hh @@ -7,195 +7,224 @@ /*! * \file * \ingroup NavierStokesNCTests - * \brief Test for the compositional staggered grid (Navier-)Stokes model. + * \brief Density driven flow test for the multi-component staggered grid (Navier-)Stokes model. */ -#ifndef DUMUX_DENSITY_FLOW_NC_TEST_PROBLEM_HH -#define DUMUX_DENSITY_FLOW_NC_TEST_PROBLEM_HH +#ifndef DUMUX_DENSITY_DRIVEN_NC_TEST_PROBLEM_HH +#define DUMUX_DENSITY_DRIVEN_NC_TEST_PROBLEM_HH #include <dumux/common/parameters.hh> #include <dumux/common/properties.hh> -#include <dumux/common/numeqvector.hh> #include <dumux/freeflow/navierstokes/boundarytypes.hh> -#include <dumux/freeflow/navierstokes/staggered/problem.hh> + +#include <dumux/freeflow/navierstokes/momentum/fluxhelper.hh> +#include <dumux/freeflow/navierstokes/scalarfluxhelper.hh> namespace Dumux { /*! * \ingroup NavierStokesNCTests - * \brief Test problem for the one-phase model. + * \brief Test problem for the one-phase (Navier-)Stokes model. * - * Here, a quadratic two-dimensional domain with closed and non-moving walls at - * all sides is considered. Initially, the domain is filled with pure water. - * At the top, a fixed concentration of the air component is set. - * The air slowly dissolves in the water which leads to a local increase of density. - * Due to the influence of gravity and - * small numerical instabilities, fingers of denser water will form and sink downwards. + * Density driven flow test for the multi-component staggered grid (Navier-)Stokes model. */ -template <class TypeTag> -class DensityDrivenFlowProblem : public NavierStokesStaggeredProblem<TypeTag> +template <class TypeTag, class BaseProblem> +class DensityDrivenFlowProblem : public BaseProblem { - using ParentType = NavierStokesStaggeredProblem<TypeTag>; - - using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; + using ParentType = BaseProblem; + using BoundaryTypes = typename ParentType::BoundaryTypes; using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>; using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using FVElementGeometry = typename GridGeometry::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; - using NumEqVector = Dumux::NumEqVector<PrimaryVariables>; + using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; + using InitialValues = typename ParentType::InitialValues; + using Sources = typename ParentType::Sources; + using DirichletValues = typename ParentType::DirichletValues; + using BoundaryFluxes = typename ParentType::BoundaryFluxes; using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + static constexpr auto dimWorld = GridGeometry::GridView::dimensionworld; using Element = typename GridGeometry::GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; - static constexpr auto dimWorld = GridGeometry::GridView::dimensionworld; + using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>; - static constexpr auto transportCompIdx = Indices::conti0EqIdx + 1; - static constexpr auto transportEqIdx = Indices::conti0EqIdx + 1; + using TimeLoopPtr = std::shared_ptr<CheckPointTimeLoop<Scalar>>; + + static constexpr auto compIdx = 1; public: - DensityDrivenFlowProblem(std::shared_ptr<const GridGeometry> gridGeometry) - : ParentType(gridGeometry), eps_(1e-6) + DensityDrivenFlowProblem(std::shared_ptr<const GridGeometry> gridGeometry, + std::shared_ptr<CouplingManager> couplingManager) + : ParentType(gridGeometry, couplingManager) + , eps_(1e-6) { useWholeLength_ = getParam<bool>("Problem.UseWholeLength"); - FluidSystem::init(); - deltaRho_.resize(this->gridGeometry().numCellCenterDofs()); } - /*! - * \name Boundary conditions + /*! + * \brief Returns a reference pressure at a given sub control volume face. + * This pressure is subtracted from the actual pressure for the momentum balance + * which potentially helps to improve numerical accuracy by avoiding issues related to floating point arithmetic. */ - // \{ + Scalar referencePressure(const Element& element, + const FVElementGeometry& fvGeometry, + const SubControlVolumeFace& scvf) const + { return 1.1e5; } - /*! + /*! * \brief Specifies which kind of boundary condition should be * used for which equation on a given boundary control volume. * * \param globalPos The position of the center of the finite volume */ - BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const + BoundaryTypes boundaryTypesAtPos(const GlobalPosition& globalPos) const { BoundaryTypes values; - // set Dirichlet values for the velocity everywhere - values.setDirichlet(Indices::velocityXIdx); - values.setDirichlet(Indices::velocityYIdx); - values.setNeumann(Indices::conti0EqIdx); - values.setNeumann(transportEqIdx); - - if(globalPos[1] > this->gridGeometry().bBoxMax()[1] - eps_) + if constexpr (ParentType::isMomentumProblem()) + values.setAllDirichlet(); + else { - if(useWholeLength_) - values.setDirichlet(transportCompIdx); - else - if(globalPos[0] > 0.4 && globalPos[0] < 0.6) - values.setDirichlet(transportCompIdx); + values.setAllNeumann(); + if (globalPos[1] > this->gridGeometry().bBoxMax()[1] - eps_) + { + if (useWholeLength_ || (globalPos[0] > 0.4 && globalPos[0] < 0.6)) + values.setAllDirichlet(); + } + } return values; } /*! - * \brief Returns whether a fixed Dirichlet value shall be used at a given cell. + * \brief Evaluates the boundary conditions for a Dirichlet control volume. * - * \param element The finite element - * \param fvGeometry The finite-volume geometry - * \param scv The sub control volume - * \param pvIdx The primary variable index in the solution vector + * \param globalPos The center of the finite volume which ought to be set. */ - template<class FVElementGeometry, class SubControlVolume> - bool isDirichletCell(const Element& element, - const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx) const + DirichletValues dirichlet(const Element& element, const SubControlVolumeFace& scvf) const { - // set a fixed pressure in one cell - return (isLowerLeftCell_(scv) && pvIdx == Indices::pressureIdx); + const auto& globalPos = scvf.ipGlobal(); + DirichletValues values(0.0); + + if constexpr (!ParentType::isMomentumProblem()) + { + values[Indices::pressureIdx] = 1.1e+5; + if (useWholeLength_ || (globalPos[0] > 0.4 && globalPos[0] < 0.6)) + values[Indices::conti0EqIdx + compIdx] = 1e-3; + } + + return values; } - /*! - * \brief Evaluates the boundary conditions for a Dirichlet control volume. + /*! + * \brief Evaluates the boundary conditions for a Neumann control volume. * - * \param globalPos The center of the finite volume which ought to be set. + * \param element The element for which the Neumann boundary condition is set + * \param fvGeometry The fvGeometry + * \param elemVolVars The element volume variables + * \param elemFaceVars The element face variables + * \param scvf The boundary sub control volume face */ - PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const + template<class ElementVolumeVariables, class ElementFluxVariablesCache> + BoundaryFluxes neumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFluxVariablesCache& elemFluxVarsCache, + const SubControlVolumeFace& scvf) const { - PrimaryVariables values; + BoundaryFluxes values(0.0); - values[Indices::pressureIdx] = 1.1e+5; - values[transportCompIdx] = 1e-3; - values[Indices::velocityXIdx] = 0.0; - values[Indices::velocityYIdx] = 0.0; + if constexpr (!ParentType::isMomentumProblem()) + { + const auto insideDensity = elemVolVars[scvf.insideScvIdx()].density(); + + // The resulting flux over the boundary is zero anyway (velocity is zero), but this will add some non-zero derivatives to the + // Jacobian and makes the BC more general. + values[Indices::conti0EqIdx] = this->faceVelocity(element, fvGeometry, scvf) * insideDensity * scvf.unitOuterNormal(); + } return values; } - // \} - - /*! - * \name Volume terms - */ - // \{ - - /*! + /*! * \brief Evaluates the initial value for a control volume. * * \param globalPos The global position */ - PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const + InitialValues initialAtPos(const GlobalPosition& globalPos) const { - PrimaryVariables values; - values[Indices::pressureIdx] = 1.1e+5; - values[transportCompIdx] = 0.0; - values[Indices::velocityXIdx] = 0.0; - values[Indices::velocityYIdx] = 0.0; + InitialValues values(0.0); + + if constexpr (!ParentType::isMomentumProblem()) + values[Indices::pressureIdx] = 1.1e5; return values; } - /*! - * \brief Adds additional VTK output data to the VTKWriter. - * - * Function is called by the output module on every write. + void setTimeLoop(TimeLoopPtr timeLoop) + { timeLoop_ = timeLoop; } + + Scalar time() const + { return timeLoop_->time(); } + + //! Enable internal Dirichlet constraints + static constexpr bool enableInternalDirichletConstraints() + { return !ParentType::isMomentumProblem(); } + + /*! + * \brief Tag a degree of freedom to carry internal Dirichlet constraints. + * If true is returned for a dof, the equation for this dof is replaced + * by the constraint that its primary variable values must match the + * user-defined values obtained from the function internalDirichlet(), + * which must be defined in the problem. * - * \param gridVariables The grid variables - * \param sol The solution vector + * \param element The finite element + * \param scv The sub-control volume */ - template<class GridVariables, class SolutionVector> - void calculateDeltaRho(const GridVariables& gridVariables, const SolutionVector& sol) + std::bitset<DirichletValues::dimension> hasInternalDirichletConstraint(const Element& element, const SubControlVolume& scv) const { - auto fvGeometry = localView(this->gridGeometry()); - auto elemVolVars = localView(gridVariables.curGridVolVars()); - for (const auto& element : elements(this->gridGeometry().gridView())) - { - fvGeometry.bindElement(element); - elemVolVars.bind(element, fvGeometry, sol); - for (auto&& scv : scvs(fvGeometry)) - { - const auto ccDofIdx = scv.dofIndex(); - deltaRho_[ccDofIdx] = elemVolVars[scv].density() - 999.694; - } - } - } + std::bitset<DirichletValues::dimension> values; - const std::vector<Scalar>& getDeltaRho() const - { return deltaRho_; } + // the pure Neumann problem is only defined up to a constant + // we create a well-posed problem by fixing the pressure at one dof + if constexpr (!ParentType::isMomentumProblem()) + { + const bool isLowerLeftCell = (scv.dofIndex() == 0); + if (isLowerLeftCell) + values.set(0); + } + return values; + } - // \} + /*! + * \brief Define the values of internal Dirichlet constraints for a degree of freedom. + * \param element The finite element + * \param scv The sub-control volume + */ + DirichletValues internalDirichlet(const Element& element, const SubControlVolume& scv) const + { return DirichletValues(1.1e5); } private: + bool isInlet_(const GlobalPosition& globalPos) const + { return globalPos[0] < eps_; } - template<class SubControlVolume> - bool isLowerLeftCell_(const SubControlVolume& scv) const - { return scv.dofIndex() == 0; } + bool isOutlet_(const GlobalPosition& globalPos) const + { return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; } const Scalar eps_; bool useWholeLength_; - std::vector<Scalar> deltaRho_; + TimeLoopPtr timeLoop_; }; -} // end namespace Dumux +} // end namespace Dumux #endif diff --git a/test/freeflow/navierstokesnc/densitydrivenflow/properties.hh b/test/freeflow/navierstokesnc/densitydrivenflow/properties.hh index bb9cd4eacb02e0337f2eb785cb7dcec475d939f4..b0122004017c90fcfe606cbdace49fedaa39d9e6 100644 --- a/test/freeflow/navierstokesnc/densitydrivenflow/properties.hh +++ b/test/freeflow/navierstokesnc/densitydrivenflow/properties.hh @@ -14,25 +14,40 @@ #include <dune/grid/yaspgrid.hh> -#include <dumux/discretization/staggered/freeflow/properties.hh> +#include <dumux/discretization/fcstaggered.hh> +#include <dumux/discretization/cctpfa.hh> + +#include <dumux/freeflow/navierstokes/mass/1pnc/model.hh> +#include <dumux/freeflow/navierstokes/mass/problem.hh> + +#include <dumux/freeflow/navierstokes/momentum/problem.hh> +#include <dumux/freeflow/navierstokes/momentum/model.hh> -#include <dumux/freeflow/compositional/navierstokesncmodel.hh> #include <dumux/material/components/simpleh2o.hh> #include <dumux/material/fluidsystems/1padapter.hh> #include <dumux/material/fluidsystems/h2oair.hh> +#include <dumux/multidomain/traits.hh> +#include <dumux/multidomain/freeflow/couplingmanager.hh> + #include "problem.hh" namespace Dumux::Properties { // Create new type tags namespace TTag { -struct DensityDrivenFlow { using InheritsFrom = std::tuple<NavierStokesNC, StaggeredFreeFlowModel>; }; +struct DensityDrivenFlowTest {}; +struct DensityDrivenFlowMomentum { using InheritsFrom = std::tuple<DensityDrivenFlowTest, NavierStokesMomentum, FaceCenteredStaggeredModel>; }; +#if !NONISOTHERMAL +struct DensityDrivenFlowMass { using InheritsFrom = std::tuple<DensityDrivenFlowTest, NavierStokesMassOnePNC, CCTpfaModel>; }; +#else +struct DensityDrivenFlowMass { using InheritsFrom = std::tuple<DensityDrivenFlowTest, NavierStokesMassOnePNCNI, CCTpfaModel>; }; +#endif } // end namespace TTag // Select the fluid system template<class TypeTag> -struct FluidSystem<TypeTag, TTag::DensityDrivenFlow> +struct FluidSystem<TypeTag, TTag::DensityDrivenFlowTest> { using H2OAir = FluidSystems::H2OAir<GetPropType<TypeTag, Properties::Scalar>>; static constexpr int phaseIdx = H2OAir::liquidPhaseIdx; @@ -40,25 +55,40 @@ struct FluidSystem<TypeTag, TTag::DensityDrivenFlow> }; template<class TypeTag> -struct ReplaceCompEqIdx<TypeTag, TTag::DensityDrivenFlow> { static constexpr int value = 0; }; +struct ReplaceCompEqIdx<TypeTag, TTag::DensityDrivenFlowTest> { static constexpr int value = 0; }; // Set the grid type template<class TypeTag> -struct Grid<TypeTag, TTag::DensityDrivenFlow> { using type = Dune::YaspGrid<2>; }; +struct Grid<TypeTag, TTag::DensityDrivenFlowTest> { using type = Dune::YaspGrid<2>; }; // Set the problem property template<class TypeTag> -struct Problem<TypeTag, TTag::DensityDrivenFlow> { using type = Dumux::DensityDrivenFlowProblem<TypeTag> ; }; +struct Problem<TypeTag, TTag::DensityDrivenFlowMomentum> +{ using type = DensityDrivenFlowProblem<TypeTag, Dumux::NavierStokesMomentumProblem<TypeTag>>; }; + +template<class TypeTag> +struct Problem<TypeTag, TTag::DensityDrivenFlowMass> +{ using type = DensityDrivenFlowProblem<TypeTag, Dumux::NavierStokesMassProblem<TypeTag>>; }; template<class TypeTag> -struct EnableGridGeometryCache<TypeTag, TTag::DensityDrivenFlow> { static constexpr bool value = true; }; +struct EnableGridGeometryCache<TypeTag, TTag::DensityDrivenFlowTest> { static constexpr bool value = true; }; +template<class TypeTag> +struct EnableGridFluxVariablesCache<TypeTag, TTag::DensityDrivenFlowTest> { static constexpr bool value = true; }; template<class TypeTag> -struct EnableGridFluxVariablesCache<TypeTag, TTag::DensityDrivenFlow> { static constexpr bool value = true; }; +struct EnableGridVolumeVariablesCache<TypeTag, TTag::DensityDrivenFlowTest> { static constexpr bool value = true; }; + template<class TypeTag> -struct EnableGridVolumeVariablesCache<TypeTag, TTag::DensityDrivenFlow> { static constexpr bool value = true; }; +struct UseMoles<TypeTag, TTag::DensityDrivenFlowTest> { static constexpr bool value = true; }; +// Set the coupling manager template<class TypeTag> -struct UseMoles<TypeTag, TTag::DensityDrivenFlow> { static constexpr bool value = true; }; +struct CouplingManager<TypeTag, TTag::DensityDrivenFlowTest> +{ +private: + using Traits = MultiDomainTraits<TTag::DensityDrivenFlowMomentum, TTag::DensityDrivenFlowMass>; +public: + using type = FreeFlowCouplingManager<Traits>; +}; } // end namespace Dumux::Properties