From 239af28c82549a30d1324822d806bd7611de45cc Mon Sep 17 00:00:00 2001 From: Edward 'Ned' Coltman <edward.coltman@iws.uni-stuttgart.de> Date: Wed, 26 Apr 2023 12:06:12 +0200 Subject: [PATCH] [test][navierstokesnc] Port channel test --- .../navierstokesnc/channel/CMakeLists.txt | 15 +- test/freeflow/navierstokesnc/channel/main.cc | 83 ++++-- .../navierstokesnc/channel/problem.hh | 278 ++++++++++-------- .../navierstokesnc/channel/properties.hh | 17 +- .../navierstokesnc/maxwellstefan/main.cc | 4 +- .../navierstokesnc/maxwellstefan/problem.hh | 10 +- .../maxwellstefan/properties.hh | 33 ++- 7 files changed, 262 insertions(+), 178 deletions(-) diff --git a/test/freeflow/navierstokesnc/channel/CMakeLists.txt b/test/freeflow/navierstokesnc/channel/CMakeLists.txt index 0e68ff1588..34318acecc 100644 --- a/test/freeflow/navierstokesnc/channel/CMakeLists.txt +++ b/test/freeflow/navierstokesnc/channel/CMakeLists.txt @@ -4,11 +4,11 @@ dune_symlink_to_source_files(FILES "params_advection.input" "params_diffusion.input" "params_advectionni.input" "params_diffusionni.input") add_executable(test_ff_stokes2c_mass EXCLUDE_FROM_ALL main.cc) -target_compile_definitions(test_ff_stokes2c_mass PUBLIC "USE_MASS=1") +target_compile_definitions(test_ff_stokes2c_mass PUBLIC "USE_MOLES=0") dumux_add_test(NAME test_ff_stokes2c_diffusion_mass TARGET test_ff_stokes2c_mass - LABELS freeflow navierstokes + LABELS freeflow navierstokes navierstokesnc CMAKE_GUARD HAVE_UMFPACK COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py CMD_ARGS --script fuzzy @@ -19,10 +19,11 @@ dumux_add_test(NAME test_ff_stokes2c_diffusion_mass --zeroThreshold {"velocity_liq \(m/s\)":1e-22}) add_executable(test_ff_stokes2c EXCLUDE_FROM_ALL main.cc) +target_compile_definitions(test_ff_stokes2c PUBLIC "USE_MOLES=1") dumux_add_test(NAME test_ff_stokes2c_diffusion_mole TARGET test_ff_stokes2c - LABELS freeflow navierstokes + LABELS freeflow navierstokes navierstokesnc CMAKE_GUARD HAVE_UMFPACK COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py CMD_ARGS --script fuzzy @@ -34,7 +35,7 @@ dumux_add_test(NAME test_ff_stokes2c_diffusion_mole dumux_add_test(NAME test_ff_stokes2c_advection TARGET test_ff_stokes2c - LABELS freeflow navierstokes + LABELS freeflow navierstokes navierstokesnc CMAKE_GUARD HAVE_UMFPACK COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py CMD_ARGS --script fuzzy @@ -45,7 +46,7 @@ dumux_add_test(NAME test_ff_stokes2c_advection dumux_add_test(NAME test_ff_stokes2c_advection_nocaching SOURCES main.cc - LABELS freeflow navierstokes + LABELS freeflow navierstokes navierstokesnc CMAKE_GUARD HAVE_UMFPACK COMPILE_DEFINITIONS ENABLECACHING=0 COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py @@ -60,7 +61,7 @@ target_compile_definitions(test_ff_stokes2cni PUBLIC "NONISOTHERMAL=1") dumux_add_test(NAME test_ff_stokes2cni_advection TARGET test_ff_stokes2cni - LABELS freeflow navierstokes + LABELS freeflow navierstokes navierstokesnc CMAKE_GUARD HAVE_UMFPACK COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py CMD_ARGS --script fuzzy @@ -71,7 +72,7 @@ dumux_add_test(NAME test_ff_stokes2cni_advection dumux_add_test(NAME test_ff_stokes2cni_diffusion TARGET test_ff_stokes2cni - LABELS freeflow navierstokes + LABELS freeflow navierstokes navierstokesnc CMAKE_GUARD HAVE_UMFPACK COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py CMD_ARGS --script fuzzy diff --git a/test/freeflow/navierstokesnc/channel/main.cc b/test/freeflow/navierstokesnc/channel/main.cc index 066e4e4a15..f313120b59 100644 --- a/test/freeflow/navierstokesnc/channel/main.cc +++ b/test/freeflow/navierstokesnc/channel/main.cc @@ -17,11 +17,12 @@ #include <dune/common/parallel/mpihelper.hh> #include <dune/common/timer.hh> - #include <dumux/common/initialize.hh> #include <dumux/common/dumuxmessage.hh> #include <dumux/common/parameters.hh> #include <dumux/common/properties.hh> + +#include <dumux/io/vtkoutputmodule.hh> #include <dumux/io/grid/gridmanager_yasp.hh> #include <dumux/linear/istlsolvers.hh> #include <dumux/linear/linearsolvertraits.hh> @@ -34,6 +35,11 @@ #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" int main(int argc, char** argv) @@ -41,7 +47,8 @@ int main(int argc, char** argv) using namespace Dumux; // define the type tag for this problem - using TypeTag = Properties::TTag::ChannelNCTest; + using MomentumTypeTag = Properties::TTag::ChannelNCTestMomentum; + using MassTypeTag = Properties::TTag::ChannelNCTestMass; // maybe initialize MPI and/or multithreading backend initialize(argc, argv); @@ -55,7 +62,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<MassTypeTag, Properties::Grid>> gridManager; + GridManager<GetPropType<MomentumTypeTag, Properties::Grid>> gridManager; gridManager.init(); //////////////////////////////////////////////////////////// @@ -66,8 +73,10 @@ 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>; @@ -80,15 +89,13 @@ int main(int argc, char** argv) auto massProblem = std::make_shared<MassProblem>(massGridGeometry, couplingManager); // 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<CheckPointTimeLoop<Scalar>>(0, dt, tEnd); - timeLoop->setMaxTimeStepSize(maxDt); - problem->setTimeLoop(timeLoop); + // check if we are about to restart a previously interrupted simulation + Scalar restartTime = getParam<Scalar>("Restart.Time", 0); // the solution vector constexpr auto momentumIdx = CouplingManager::freeFlowMomentumIndex; @@ -96,34 +103,51 @@ int main(int argc, char** argv) 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->getDeltaP(), "deltaP"); - 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.pressure() - 1.1e5; }, "deltaP"); + 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 @@ -133,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->calculateDeltaP(*gridVariables, x); - // write vtk output vtkWriter.write(timeLoop->time()); diff --git a/test/freeflow/navierstokesnc/channel/problem.hh b/test/freeflow/navierstokesnc/channel/problem.hh index 06c4699b3f..53638e84bb 100644 --- a/test/freeflow/navierstokesnc/channel/problem.hh +++ b/test/freeflow/navierstokesnc/channel/problem.hh @@ -13,8 +13,8 @@ #ifndef DUMUX_CHANNEL_NC_TEST_PROBLEM_HH #define DUMUX_CHANNEL_NC_TEST_PROBLEM_HH -#include <dumux/common/properties.hh> #include <dumux/common/parameters.hh> +#include <dumux/common/properties.hh> #include <dumux/freeflow/navierstokes/boundarytypes.hh> @@ -32,202 +32,250 @@ namespace Dumux { * a fixed value on the right boundary. The top and bottom boundaries * represent solid walls with no-slip/no-flow conditions. */ -template <class TypeTag> -class ChannelNCTestProblem : public NavierStokesStaggeredProblem<TypeTag> +template <class TypeTag, class BaseProblem> +class ChannelNCTestProblem : public BaseProblem { - using ParentType = NavierStokesStaggeredProblem<TypeTag>; - - using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; - using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>; + using ParentType = BaseProblem; + using BoundaryTypes = typename ParentType::BoundaryTypes; 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>; + using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>; static constexpr auto dimWorld = GridGeometry::GridView::dimensionworld; - using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>; + using Element = typename GridGeometry::GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; + + using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>; using TimeLoopPtr = std::shared_ptr<CheckPointTimeLoop<Scalar>>; + static constexpr bool useMoles = ModelTraits::useMoles(); + static constexpr bool isNonisothermal = ModelTraits::enableEnergyBalance(); static constexpr auto compIdx = 1; - static constexpr auto transportCompIdx = Indices::conti0EqIdx + compIdx; - static constexpr auto transportEqIdx = Indices::conti0EqIdx + compIdx; public: - ChannelNCTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) - : ParentType(gridGeometry), eps_(1e-6) + ChannelNCTestProblem(std::shared_ptr<const GridGeometry> gridGeometry, + std::shared_ptr<CouplingManager> couplingManager) + : ParentType(gridGeometry, couplingManager) + , eps_(1e-6) { - inletVelocity_ = getParam<Scalar>("Problem.InletVelocity"); FluidSystem::init(); - deltaP_.resize(this->gridGeometry().numCellCenterDofs()); + inletVelocity_ = getParam<Scalar>("Problem.InletVelocity"); } - /*! - * \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 do 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; - if(isInlet_(globalPos)) + if constexpr (ParentType::isMomentumProblem()) { values.setDirichlet(Indices::velocityXIdx); values.setDirichlet(Indices::velocityYIdx); - values.setDirichlet(transportCompIdx); -#if NONISOTHERMAL - values.setDirichlet(Indices::temperatureIdx); -#endif - } - else if(isOutlet_(globalPos)) - { - values.setDirichlet(Indices::pressureIdx); - values.setOutflow(transportEqIdx); -#if NONISOTHERMAL - values.setOutflow(Indices::energyEqIdx); -#endif + + if (isOutlet_(globalPos)) + values.setAllNeumann(); } else { - // set Dirichlet values for the velocity everywhere - values.setDirichlet(Indices::velocityXIdx); - values.setDirichlet(Indices::velocityYIdx); - values.setNeumann(Indices::conti0EqIdx); - values.setNeumann(transportEqIdx); -#if NONISOTHERMAL - values.setNeumann(Indices::energyEqIdx); -#endif + values.setAllNeumann(); + + if (isInlet_(globalPos)) + { + values.setDirichlet(Indices::pressureIdx); + values.setDirichlet(Indices::conti0EqIdx + compIdx); + if constexpr (isNonisothermal) + values.setDirichlet(Indices::temperatureIdx); + } } return values; } - /*! + /*! * \brief Evaluates the boundary conditions for a Dirichlet control volume. * * \param globalPos The center of the finite volume which ought to be set. */ - PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const + DirichletValues dirichlet(const Element& element, const SubControlVolumeFace& scvf) const { - PrimaryVariables values = initialAtPos(globalPos); + const auto& globalPos = scvf.ipGlobal(); + DirichletValues values = initialAtPos(globalPos); - // give the system some time so that the pressure can equilibrate, then start the injection of the tracer - if(isInlet_(globalPos)) + if constexpr (!ParentType::isMomentumProblem()) { - if(time() >= 10.0 || inletVelocity_ < eps_) + // give the system some time so that the pressure can equilibrate, then start the injection of the tracer + if (isInlet_(globalPos)) { - Scalar moleFracTransportedComp = 1e-3; -#if USE_MASS - Scalar averageMolarMassPhase = moleFracTransportedComp * FluidSystem::molarMass(compIdx) - + (1. - moleFracTransportedComp) * FluidSystem::molarMass(1-compIdx); - values[transportCompIdx] = moleFracTransportedComp * FluidSystem::molarMass(compIdx) - / averageMolarMassPhase; -#else - values[transportCompIdx] = moleFracTransportedComp; -#endif -#if NONISOTHERMAL - values[Indices::temperatureIdx] = 293.15; -#endif + values[Indices::pressureIdx] = this->couplingManager().cellPressure(element, scvf); + + if (time() >= 10.0 || inletVelocity_ < eps_) + { + Scalar moleFracTransportedComp = 1e-3; + if constexpr (useMoles) + values[Indices::conti0EqIdx+compIdx] = moleFracTransportedComp; + else + { + Scalar averageMolarMassPhase = moleFracTransportedComp * FluidSystem::molarMass(compIdx) + + (1. - moleFracTransportedComp) * FluidSystem::molarMass(1-compIdx); + values[Indices::conti0EqIdx+compIdx] = moleFracTransportedComp * FluidSystem::molarMass(compIdx) + / averageMolarMassPhase; + } + + if constexpr (isNonisothermal) + values[Indices::temperatureIdx] = 293.15; + } } } return values; } - // \} - - /*! - * \name Volume terms - */ - // \{ - - /*! - * \brief Evaluates the initial value for a control volume. + /*! + * \brief Evaluates the boundary conditions for a Neumann control volume. * - * \param globalPos The global position + * \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 initialAtPos(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; - values[Indices::pressureIdx] = 1.1e+5; - values[transportCompIdx] = 0.0; -#if NONISOTHERMAL - values[Indices::temperatureIdx] = 283.15; -#endif + BoundaryFluxes values(0.0); - // parabolic velocity profile - values[Indices::velocityXIdx] = inletVelocity_*(globalPos[1] - this->gridGeometry().bBoxMin()[1])*(this->gridGeometry().bBoxMax()[1] - globalPos[1]) - / (0.25*(this->gridGeometry().bBoxMax()[1] - this->gridGeometry().bBoxMin()[1])*(this->gridGeometry().bBoxMax()[1] - this->gridGeometry().bBoxMin()[1])); + if constexpr (ParentType::isMomentumProblem()) + { + using FluxHelper = NavierStokesMomentumBoundaryFluxHelper; + values = FluxHelper::fixedPressureMomentumFlux(*this, fvGeometry, scvf, + elemVolVars, elemFluxVarsCache, + referencePressure(element, fvGeometry, scvf), true /*zeroNormalVelocityGradient*/); + } + else + { + const auto insideDensity = elemVolVars[scvf.insideScvIdx()].density(); + values[Indices::conti0EqIdx] = this->faceVelocity(element, fvGeometry, scvf) * insideDensity * scvf.unitOuterNormal(); - values[Indices::velocityYIdx] = 0.0; + using FluxHelper = NavierStokesScalarBoundaryFluxHelper<AdvectiveFlux<ModelTraits>>; + if (isOutlet_(scvf.ipGlobal())) + values = FluxHelper::scalarOutflowFlux( *this, element, fvGeometry, scvf, elemVolVars); + } return values; } - /*! - * \brief Adds additional VTK output data to the VTKWriter. - * - * Function is called by the output module on every write. + /*! + * \brief Evaluates the initial value for a control volume. * - * \param gridVariables The grid variables - * \param sol The solution vector + * \param globalPos The global position */ - template<class GridVariables, class SolutionVector> - void calculateDeltaP(const GridVariables& gridVariables, const SolutionVector& sol) + InitialValues initialAtPos(const GlobalPosition& globalPos) const { - auto fvGeometry = localView(this->gridGeometry()); - auto elemVolVars = localView(gridVariables.curGridVolVars()); - for (const auto& element : elements(this->gridGeometry().gridView())) + InitialValues values(0.0); + + if constexpr (ParentType::isMomentumProblem()) { - fvGeometry.bindElement(element); - elemVolVars.bindElement(element, fvGeometry, sol); - for (auto&& scv : scvs(fvGeometry)) - { - const auto ccDofIdx = scv.dofIndex(); - deltaP_[ccDofIdx] = elemVolVars[scv].pressure() - 1.1e5; - } + // parabolic velocity profile + values[Indices::velocityXIdx] = parabolicProfile(globalPos[1], inletVelocity_); + } + else + { + values[Indices::pressureIdx] = 1.1e+5; + if constexpr (isNonisothermal) + values[Indices::temperatureIdx] = 283.15; } - } - - auto& getDeltaP() const - { return deltaP_; } - // \} + return values; + } - void setTimeLoop(TimeLoopPtr timeLoop) + /*! + * \brief A parabolic velocity profile. + * + * \param y The position where the velocity is evaluated. + * \param vMax The profile's maximum velocity. + */ + Scalar parabolicProfile(const Scalar y, const Scalar vMax) const { - timeLoop_ = timeLoop; + const Scalar yMin = this->gridGeometry().bBoxMin()[1]; + const Scalar yMax = this->gridGeometry().bBoxMax()[1]; + return vMax * (y - yMin)*(yMax - y) / (0.25*(yMax - yMin)*(yMax - yMin)); } + 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 element The finite element + * \param scv The sub-control volume + */ + std::bitset<DirichletValues::dimension> hasInternalDirichletConstraint(const Element& element, const SubControlVolume& scv) const { - return timeLoop_->time(); + std::bitset<DirichletValues::dimension> values; + return values; } -private: + /*! + * \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_; - } + { return globalPos[0] < eps_; } bool isOutlet_(const GlobalPosition& globalPos) const - { - return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; - } + { return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; } const Scalar eps_; Scalar inletVelocity_; TimeLoopPtr timeLoop_; - std::vector<Scalar> deltaP_; }; } // end namespace Dumux diff --git a/test/freeflow/navierstokesnc/channel/properties.hh b/test/freeflow/navierstokesnc/channel/properties.hh index 68f02f994e..60e537702e 100644 --- a/test/freeflow/navierstokesnc/channel/properties.hh +++ b/test/freeflow/navierstokesnc/channel/properties.hh @@ -16,6 +16,10 @@ #define ENABLECACHING 1 #endif +#ifndef USEMOLES +#define USEMOLES 1 +#endif + #include <dune/grid/yaspgrid.hh> #include <dumux/discretization/cctpfa.hh> @@ -40,10 +44,12 @@ namespace Dumux::Properties { // Create new type tags namespace TTag { +struct ChannelNCTest {}; +struct ChannelNCTestMomentum { using InheritsFrom = std::tuple<ChannelNCTest, NavierStokesMomentum, FaceCenteredStaggeredModel>; }; #if !NONISOTHERMAL -struct ChannelNCTest { using InheritsFrom = std::tuple<NavierStokesNC, StaggeredFreeFlowModel>; }; +struct ChannelNCTestMass { using InheritsFrom = std::tuple<ChannelNCTest, NavierStokesMassOnePNC, CCTpfaModel>; }; #else -struct ChannelNCTest { using InheritsFrom = std::tuple<NavierStokesNCNI, StaggeredFreeFlowModel>; }; +struct ChannelNCTestMass { using InheritsFrom = std::tuple<ChannelNCTest, NavierStokesMassOnePNCNI, CCTpfaModel>; }; #endif } // end namespace TTag @@ -84,13 +90,8 @@ template<class TypeTag> struct EnableGridFaceVariablesCache<TypeTag, TTag::ChannelNCTest> { static constexpr bool value = ENABLECACHING; }; // Use mole fraction formulation -#if USE_MASS template<class TypeTag> -struct UseMoles<TypeTag, TTag::ChannelNCTest> { static constexpr bool value = false; }; -#else -template<class TypeTag> -struct UseMoles<TypeTag, TTag::ChannelNCTest> { static constexpr bool value = true; }; -#endif +struct UseMoles<TypeTag, TTag::ChannelNCTest> { static constexpr bool value = USEMOLES; }; // Set the problem property template<class TypeTag> diff --git a/test/freeflow/navierstokesnc/maxwellstefan/main.cc b/test/freeflow/navierstokesnc/maxwellstefan/main.cc index 21ceac603c..cbcbfc8e27 100644 --- a/test/freeflow/navierstokesnc/maxwellstefan/main.cc +++ b/test/freeflow/navierstokesnc/maxwellstefan/main.cc @@ -199,8 +199,7 @@ int main(int argc, char** argv) auto massGridGeometry = std::make_shared<MassGridGeometry>(leafGridView); // the coupling manager - using Traits = MultiDomainTraits<MomentumTypeTag, MassTypeTag>; - using CouplingManager = StaggeredFreeFlowCouplingManager<Traits>; + using CouplingManager = GetPropType<MomentumTypeTag, Properties::CouplingManager>; auto couplingManager = std::make_shared<CouplingManager>(); // the problem (boundary conditions) @@ -210,6 +209,7 @@ int main(int argc, char** argv) auto massProblem = std::make_shared<MassProblem>(massGridGeometry, couplingManager); // get some time loop parameters + using Traits = MultiDomainTraits<MomentumTypeTag, MassTypeTag>; using Scalar = typename Traits::Scalar; const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); diff --git a/test/freeflow/navierstokesnc/maxwellstefan/problem.hh b/test/freeflow/navierstokesnc/maxwellstefan/problem.hh index f1bdfd7f54..8b2f320472 100644 --- a/test/freeflow/navierstokesnc/maxwellstefan/problem.hh +++ b/test/freeflow/navierstokesnc/maxwellstefan/problem.hh @@ -16,10 +16,10 @@ #include <dumux/common/parameters.hh> #include <dumux/common/properties.hh> +#include <dumux/freeflow/navierstokes/boundarytypes.hh> + #include <dumux/freeflow/navierstokes/momentum/fluxhelper.hh> #include <dumux/freeflow/navierstokes/scalarfluxhelper.hh> -#include <dumux/freeflow/navierstokes/boundarytypes.hh> -#include <dumux/freeflow/navierstokes/staggered/problem.hh> namespace Dumux { @@ -27,10 +27,10 @@ namespace Dumux { * \ingroup NavierStokesNCTests * \brief Test problem for the Maxwell-Stefan model */ -template <class TypeTag> -class MaxwellStefanNCTestProblem : public NavierStokesStaggeredProblem<TypeTag> +template <class TypeTag, class BaseProblem> +class MaxwellStefanNCTestProblem : public BaseProblem { - using ParentType = NavierStokesStaggeredProblem<TypeTag>; + using ParentType = BaseProblem; using BoundaryTypes = typename ParentType::BoundaryTypes; using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; diff --git a/test/freeflow/navierstokesnc/maxwellstefan/properties.hh b/test/freeflow/navierstokesnc/maxwellstefan/properties.hh index 35b5f5a734..55469cf76c 100644 --- a/test/freeflow/navierstokesnc/maxwellstefan/properties.hh +++ b/test/freeflow/navierstokesnc/maxwellstefan/properties.hh @@ -14,8 +14,11 @@ #include <dune/grid/yaspgrid.hh> -#include <dumux/freeflow/navierstokes/momentum/model.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/flux/maxwellstefanslaw.hh> #include <dumux/material/fluidsystems/base.hh> @@ -23,7 +26,8 @@ #include <dumux/discretization/fcstaggered.hh> #include <dumux/discretization/cctpfa.hh> -#include <dumux/multidomain/staggeredfreeflow/couplingmanager.hh> +#include <dumux/multidomain/traits.hh> +#include <dumux/multidomain/freeflow/couplingmanager.hh> #include "problem.hh" @@ -41,11 +45,17 @@ struct ReplaceCompEqIdx<TypeTag, TTag::MaxwellStefanNCTest> { static constexpr i // Set the grid type template<class TypeTag> -struct Grid<TypeTag, TTag::MaxwellStefanNCTest> { using type = Dune::YaspGrid<2>; }; +struct Grid<TypeTag, TTag::MaxwellStefanNCTest> +{ using type = Dune::YaspGrid<2>; }; // Set the problem property template<class TypeTag> -struct Problem<TypeTag, TTag::MaxwellStefanNCTest> { using type = Dumux::MaxwellStefanNCTestProblem<TypeTag> ; }; +struct Problem<TypeTag, TTag::MaxwellStefanTestMomentum> +{ using type = MaxwellStefanNCTestProblem<TypeTag, Dumux::NavierStokesMomentumProblem<TypeTag>>; }; + +template<class TypeTag> +struct Problem<TypeTag, TTag::MaxwellStefanTestMass> +{ using type = MaxwellStefanNCTestProblem<TypeTag, Dumux::NavierStokesMassProblem<TypeTag>>; }; template<class TypeTag> struct EnableGridGeometryCache<TypeTag, TTag::MaxwellStefanNCTest> { static constexpr bool value = true; }; @@ -61,13 +71,6 @@ struct UseMoles<TypeTag, TTag::MaxwellStefanNCTest> { static constexpr bool valu template<class TypeTag> struct MolecularDiffusionType<TypeTag, TTag::MaxwellStefanNCTest> { using type = MaxwellStefansLaw<TypeTag>; }; -template<class TypeTag> -struct CouplingManager<TypeTag, TTag::MaxwellStefanNCTest> -{ - using Traits = MultiDomainTraits<TTag::MaxwellStefanTestMomentum, TTag::MaxwellStefanTestMass>; - using type = StaggeredFreeFlowCouplingManager<Traits>; -}; - /*! * \ingroup NavierStokesNCTests * \brief A simple fluid system with three components for testing the multi-component diffusion with the Maxwell-Stefan formulation. @@ -194,6 +197,14 @@ public: template<class TypeTag> struct FluidSystem<TypeTag, TTag::MaxwellStefanNCTest> { using type = MaxwellStefanFluidSystem<TypeTag>; }; +template<class TypeTag> +struct CouplingManager<TypeTag, TTag::MaxwellStefanNCTest> +{ + using Traits = MultiDomainTraits<TTag::MaxwellStefanTestMomentum, TTag::MaxwellStefanTestMass>; + using type = FreeFlowCouplingManager<Traits>; +}; + + } // end namespace Dumux::Properties #endif -- GitLab