From 96855f6c07bb35b173edf72cc924e258b420b41e Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de> Date: Thu, 17 Dec 2020 16:09:13 +0100 Subject: [PATCH] [test][navierstokesnc] Port 1pnc MaxwellStefan test --- .../navierstokes/mass/1pnc/CMakeLists.txt | 3 + .../navierstokes/mass/1pnc/localresidual.hh | 3 +- .../freeflow/navierstokes/mass/1pnc/model.hh | 11 +- test/freeflow/navierstokes/angeli/main.cc | 1 - test/freeflow/navierstokesnc/channel/main.cc | 32 ++- .../navierstokesnc/channel/problem.hh | 6 +- .../navierstokesnc/channel/properties.hh | 40 ++- .../maxwellstefan/CMakeLists.txt | 10 +- .../navierstokesnc/maxwellstefan/main.cc | 215 +++++++++++--- .../navierstokesnc/maxwellstefan/params.input | 3 +- .../navierstokesnc/maxwellstefan/problem.hh | 265 +++++++----------- .../maxwellstefan/properties.hh | 28 +- 12 files changed, 378 insertions(+), 239 deletions(-) create mode 100644 dumux/freeflow/navierstokes/mass/1pnc/CMakeLists.txt diff --git a/dumux/freeflow/navierstokes/mass/1pnc/CMakeLists.txt b/dumux/freeflow/navierstokes/mass/1pnc/CMakeLists.txt new file mode 100644 index 0000000000..80a3545121 --- /dev/null +++ b/dumux/freeflow/navierstokes/mass/1pnc/CMakeLists.txt @@ -0,0 +1,3 @@ +file(GLOB DUMUX_FREEFLOW_NAVIERSTOKES_MASS_1PNC_HEADERS *.hh *.inc) +install(FILES ${DUMUX_FREEFLOW_NAVIERSTOKES_MASS_1PNC_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/freeflow/navierstokes/mass/1pnc) diff --git a/dumux/freeflow/navierstokes/mass/1pnc/localresidual.hh b/dumux/freeflow/navierstokes/mass/1pnc/localresidual.hh index 5878df9c16..eea71d29d8 100644 --- a/dumux/freeflow/navierstokes/mass/1pnc/localresidual.hh +++ b/dumux/freeflow/navierstokes/mass/1pnc/localresidual.hh @@ -26,6 +26,7 @@ #include <dumux/common/numeqvector.hh> #include <dumux/common/properties.hh> +#include <dumux/discretization/method.hh> namespace Dumux { @@ -58,7 +59,7 @@ class NavierStokesMassOnePNCLocalResidual : public GetPropType<TypeTag, Properti using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; - static_assert(GridGeometry::discMethod == DiscretizationMethod::cctpfa); + static_assert(GridGeometry::discMethod == DiscretizationMethods::cctpfa, ""); static constexpr bool useMoles = ModelTraits::useMoles(); static constexpr auto numComponents = ModelTraits::numFluidComponents(); diff --git a/dumux/freeflow/navierstokes/mass/1pnc/model.hh b/dumux/freeflow/navierstokes/mass/1pnc/model.hh index 73fb1d51a9..34eb915401 100644 --- a/dumux/freeflow/navierstokes/mass/1pnc/model.hh +++ b/dumux/freeflow/navierstokes/mass/1pnc/model.hh @@ -53,17 +53,8 @@ #include "volumevariables.hh" #include "fluxvariables.hh" #include "indices.hh" -#include "./../../iofields.hh" #include "iofields.hh" -#include <dumux/flux/cctpfa/fourierslaw.hh> - -#include <dumux/discretization/method.hh> -#include <dumux/freeflow/navierstokes/energy/model.hh> -#include <dumux/flux/fickslaw.hh> -#include <dumux/freeflow/navierstokes/scalarfluxvariablescachefiller.hh> - - namespace Dumux { /*! @@ -360,7 +351,7 @@ struct ThermalConductivityModel<TypeTag, TTag::NavierStokesMassOnePNCNI> template<class TypeTag> struct HeatConductionType<TypeTag, TTag::NavierStokesMassOnePNCNI> -{ using type = FouriersLawImplementation<TypeTag, DiscretizationMethod::cctpfa>; }; +{ using type = FouriersLaw<TypeTag>; }; //! The flux variables template<class TypeTag> diff --git a/test/freeflow/navierstokes/angeli/main.cc b/test/freeflow/navierstokes/angeli/main.cc index 02013dc541..81208a3d97 100644 --- a/test/freeflow/navierstokes/angeli/main.cc +++ b/test/freeflow/navierstokes/angeli/main.cc @@ -147,7 +147,6 @@ int main(int argc, char** argv) using LinearSolver = Dumux::UMFPackIstlSolver<SeqLinearSolverTraits, LinearAlgebraTraitsFromAssembler<Assembler>>; auto linearSolver = std::make_shared<LinearSolver>(); - // the non-linear solver // the non-linear solver using NewtonSolver = Dumux::MultiDomainNewtonSolver<Assembler, LinearSolver, CouplingManager>; NewtonSolver nonLinearSolver(assembler, linearSolver, couplingManager); diff --git a/test/freeflow/navierstokesnc/channel/main.cc b/test/freeflow/navierstokesnc/channel/main.cc index f51db75508..066e4e4a15 100644 --- a/test/freeflow/navierstokesnc/channel/main.cc +++ b/test/freeflow/navierstokesnc/channel/main.cc @@ -17,21 +17,22 @@ #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/multidomain/newtonsolver.hh> +#include <dumux/multidomain/fvassembler.hh> +#include <dumux/multidomain/traits.hh> + +#include <dumux/io/vtkoutputmodule.hh> +#include <dumux/freeflow/navierstokes/velocityoutput.hh> #include "properties.hh" @@ -54,7 +55,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<MassTypeTag, Properties::Grid>> gridManager; gridManager.init(); //////////////////////////////////////////////////////////// @@ -68,9 +69,15 @@ int main(int argc, char** argv) using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); - // the problem (initial and boundary conditions) - using Problem = GetPropType<TypeTag, Properties::Problem>; - auto problem = std::make_shared<Problem>(gridGeometry); + // 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); // get some time loop parameters using Scalar = GetPropType<TypeTag, Properties::Scalar>; @@ -84,7 +91,10 @@ int main(int argc, char** argv) problem->setTimeLoop(timeLoop); // 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()); diff --git a/test/freeflow/navierstokesnc/channel/problem.hh b/test/freeflow/navierstokesnc/channel/problem.hh index 851a90ea4e..06c4699b3f 100644 --- a/test/freeflow/navierstokesnc/channel/problem.hh +++ b/test/freeflow/navierstokesnc/channel/problem.hh @@ -15,11 +15,11 @@ #include <dumux/common/properties.hh> #include <dumux/common/parameters.hh> -#include <dumux/common/timeloop.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 { diff --git a/test/freeflow/navierstokesnc/channel/properties.hh b/test/freeflow/navierstokesnc/channel/properties.hh index a2657253a5..68f02f994e 100644 --- a/test/freeflow/navierstokesnc/channel/properties.hh +++ b/test/freeflow/navierstokesnc/channel/properties.hh @@ -18,13 +18,22 @@ #include <dune/grid/yaspgrid.hh> -#include <dumux/discretization/staggered/freeflow/properties.hh> +#include <dumux/discretization/cctpfa.hh> +#include <dumux/discretization/fcstaggered.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 { @@ -38,6 +47,15 @@ struct ChannelNCTest { using InheritsFrom = std::tuple<NavierStokesNCNI, Stagger #endif } // end namespace TTag +// Set the problem property +template<class TypeTag> +struct Problem<TypeTag, TTag::ChannelNCTestMomentum> +{ using type = ChannelNCTestProblem<TypeTag, Dumux::NavierStokesMomentumProblem<TypeTag>>; }; + +template<class TypeTag> +struct Problem<TypeTag, TTag::ChannelNCTestMass> +{ using type = ChannelNCTestProblem<TypeTag, Dumux::NavierStokesMassProblem<TypeTag>>; }; + // Select the fluid system template<class TypeTag> struct FluidSystem<TypeTag, TTag::ChannelNCTest> @@ -48,15 +66,13 @@ struct FluidSystem<TypeTag, TTag::ChannelNCTest> }; template<class TypeTag> -struct ReplaceCompEqIdx<TypeTag, TTag::ChannelNCTest> { static constexpr int value = 0; }; +struct ReplaceCompEqIdx<TypeTag, TTag::ChannelNCTest> +{ static constexpr int value = 0; }; // Set the grid type template<class TypeTag> -struct Grid<TypeTag, TTag::ChannelNCTest> { using type = Dune::YaspGrid<2>; }; - -// Set the problem property -template<class TypeTag> -struct Problem<TypeTag, TTag::ChannelNCTest> { using type = Dumux::ChannelNCTestProblem<TypeTag> ; }; +struct Grid<TypeTag, TTag::ChannelNCTest> +{ using type = Dune::YaspGrid<2>; }; template<class TypeTag> struct EnableGridGeometryCache<TypeTag, TTag::ChannelNCTest> { static constexpr bool value = ENABLECACHING; }; @@ -76,6 +92,14 @@ template<class TypeTag> struct UseMoles<TypeTag, TTag::ChannelNCTest> { static constexpr bool value = true; }; #endif +// Set the problem property +template<class TypeTag> +struct CouplingManager<TypeTag, TTag::ChannelNCTest> +{ + using Traits = MultiDomainTraits<TTag::ChannelNCTestMomentum, TTag::ChannelNCTestMass>; + using type = FreeFlowCouplingManager<Traits>; +}; + } // end namespace Dumux::Properties #endif diff --git a/test/freeflow/navierstokesnc/maxwellstefan/CMakeLists.txt b/test/freeflow/navierstokesnc/maxwellstefan/CMakeLists.txt index da04883876..23a5ef924b 100644 --- a/test/freeflow/navierstokesnc/maxwellstefan/CMakeLists.txt +++ b/test/freeflow/navierstokesnc/maxwellstefan/CMakeLists.txt @@ -1,8 +1,11 @@ + # 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_maxwellstefan - LABELS freeflow navierstokes + LABELS freeflow navierstokesnc navierstokes SOURCES main.cc CMAKE_GUARD HAVE_UMFPACK COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py @@ -10,6 +13,5 @@ dumux_add_test(NAME test_ff_stokes2c_maxwellstefan --files ${CMAKE_SOURCE_DIR}/test/references/test_ff_stokes2c_maxwellstefan-reference.vtu ${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokes2c_maxwellstefan-00005.vtu --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokes2c_maxwellstefan params.input - -Problem.Name test_ff_stokes2c_maxwellstefan") - -dune_symlink_to_source_files(FILES "params.input") + -Problem.Name test_ff_stokes2c_maxwellstefan + -Problem.PlotOutput false") diff --git a/test/freeflow/navierstokesnc/maxwellstefan/main.cc b/test/freeflow/navierstokesnc/maxwellstefan/main.cc index a0fc14d160..21ceac603c 100644 --- a/test/freeflow/navierstokesnc/maxwellstefan/main.cc +++ b/test/freeflow/navierstokesnc/maxwellstefan/main.cc @@ -14,33 +14,161 @@ #include <ctime> #include <iostream> +#include <type_traits> +#include <tuple> #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/io/vtkoutputmodule.hh> +#include <dumux/io/gnuplotinterface.hh> +#include <dumux/freeflow/navierstokes/velocityoutput.hh> + #include <dumux/linear/istlsolvers.hh> #include <dumux/linear/linearsolvertraits.hh> #include <dumux/linear/linearalgebratraits.hh> #include <dumux/nonlinear/newtonsolver.hh> +#include <dumux/assembly/diffmethod.hh> +#include <dumux/multidomain/fvassembler.hh> +#include <dumux/multidomain/traits.hh> +#include <dumux/multidomain/newtonsolver.hh> + #include "properties.hh" +namespace Dumux { + +template<class Scalar> +class PlotConcentration +{ +public: + /*! + * \brief Writes out the diffusion rates from left to right + * + * Called after every time step + * + * \param curSol Vector containing the current solution + * \param gridVariables The grid variables + * \param time The time + */ + template<class SolutionVector, class GridVariables> + void plotComponentsOverTime(const SolutionVector& curSol, + const GridVariables& gridVariables, + const Scalar time) + { + using FluidSystem = typename GridVariables::VolumeVariables::FluidSystem; + const auto& gridGeometry = gridVariables.curGridVolVars().problem().gridGeometry(); + Scalar x_co2_left = 0.0; + Scalar x_n2_left = 0.0; + Scalar x_co2_right = 0.0; + Scalar x_n2_right = 0.0; + Scalar x_h2_left = 0.0; + Scalar x_h2_right = 0.0; + Scalar i = 0.0; + Scalar j = 0.0; + for (const auto& element : elements(gridGeometry.gridView())) + { + auto fvGeometry = localView(gridGeometry); + fvGeometry.bindElement(element); + + auto elemVolVars = localView(gridVariables.curGridVolVars()); + elemVolVars.bind(element, fvGeometry, curSol); + for (auto&& scv : scvs(fvGeometry)) + { + const auto globalPos = scv.dofPosition(); + + if (globalPos[0] < 0.5) + { + x_co2_left += elemVolVars[scv].moleFraction(FluidSystem::CO2Idx); + x_n2_left += elemVolVars[scv].moleFraction(FluidSystem::N2Idx); + x_h2_left += elemVolVars[scv].moleFraction(FluidSystem::H2Idx); + i +=1; + } + else + { + x_co2_right += elemVolVars[scv].moleFraction(FluidSystem::CO2Idx); + x_n2_right += elemVolVars[scv].moleFraction(FluidSystem::N2Idx); + x_h2_right += elemVolVars[scv].moleFraction(FluidSystem::H2Idx); + j +=1; + } + } + } + x_co2_left /= i; + x_n2_left /= i; + x_h2_left /= i; + x_co2_right /= j; + x_n2_right /= j; + x_h2_right /= j; + + //do a gnuplot + x_.push_back(time); // in seconds + y1_.push_back(x_n2_left); + y2_.push_back(x_n2_right); + y3_.push_back(x_co2_left); + y4_.push_back(x_co2_right); + y5_.push_back(x_h2_left); + y6_.push_back(x_h2_right); + + gnuplot_.resetPlot(); + gnuplot_.setXRange(0, std::max(time, 72000.0)); + gnuplot_.setYRange(0.4, 0.6); + gnuplot_.setXlabel("time [s]"); + gnuplot_.setYlabel("mole fraction mol/mol"); + gnuplot_.addDataSetToPlot(x_, y1_, "N2_left.dat", "w l t 'N_2 left'"); + gnuplot_.addDataSetToPlot(x_, y2_, "N2_right.dat", "w l t 'N_2 right'"); + gnuplot_.plot("mole_fraction_N2"); + + gnuplot2_.resetPlot(); + gnuplot2_.setXRange(0, std::max(time, 72000.0)); + gnuplot2_.setYRange(0.0, 0.6); + gnuplot2_.setXlabel("time [s]"); + gnuplot2_.setYlabel("mole fraction mol/mol"); + gnuplot2_.addDataSetToPlot(x_, y3_, "CO2_left.dat", "w l t 'CO_2 left'"); + gnuplot2_.addDataSetToPlot(x_, y4_, "CO2_right.dat", "w l t 'CO_2 right'"); + gnuplot2_.plot("mole_fraction_C02"); + + gnuplot3_.resetPlot(); + gnuplot3_.setXRange(0, std::max(time, 72000.0)); + gnuplot3_.setYRange(0.0, 0.6); + gnuplot3_.setXlabel("time [s]"); + gnuplot3_.setYlabel("mole fraction mol/mol"); + gnuplot3_.addDataSetToPlot(x_, y5_, "H2_left.dat", "w l t 'H_2 left'"); + gnuplot3_.addDataSetToPlot(x_, y6_, "H2_right.dat", "w l t 'H_2 right'"); + gnuplot3_.plot("mole_fraction_H2"); + } + +private: + GnuplotInterface<Scalar> gnuplot_; + GnuplotInterface<Scalar> gnuplot2_; + GnuplotInterface<Scalar> gnuplot3_; + + std::vector<Scalar> x_; + std::vector<Scalar> y1_; + std::vector<Scalar> y2_; + std::vector<Scalar> y3_; + std::vector<Scalar> y4_; + std::vector<Scalar> y5_; + std::vector<Scalar> y6_; +}; + +} + + + + int main(int argc, char** argv) { using namespace Dumux; // define the type tag for this problem - using TypeTag = Properties::TTag::MaxwellStefanNCTest; + using MomentumTypeTag = Properties::TTag::MaxwellStefanTestMomentum; + using MassTypeTag = Properties::TTag::MaxwellStefanTestMass; // maybe initialize MPI and/or multithreading backend initialize(argc, argv); @@ -54,7 +182,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,15 +193,24 @@ 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); - - // the problem (initial and boundary conditions) - using Problem = GetPropType<TypeTag, Properties::Problem>; - auto problem = std::make_shared<Problem>(gridGeometry); + 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 Traits = MultiDomainTraits<MomentumTypeTag, MassTypeTag>; + using CouplingManager = StaggeredFreeFlowCouplingManager<Traits>; + 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); // get some time loop parameters - using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using Scalar = typename Traits::Scalar; const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); @@ -83,39 +220,49 @@ int main(int argc, char** argv) timeLoop->setMaxTimeStepSize(maxDt); // the solution vector - using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + constexpr auto momentumIdx = CouplingManager::freeFlowMomentumIndex; + constexpr auto massIdx = CouplingManager::freeFlowMassIndex; + using SolutionVector = typename Traits::SolutionVector; SolutionVector x; - x[GridGeometry::cellCenterIdx()].resize(gridGeometry->numCellCenterDofs()); - x[GridGeometry::faceIdx()].resize(gridGeometry->numFaceDofs()); - problem->applyInitialSolution(x); + momentumProblem->applyInitialSolution(x[momentumIdx]); + massProblem->applyInitialSolution(x[massIdx]); auto xOld = x; // 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); + using MassGridVariables = GetPropType<MassTypeTag, Properties::GridVariables>; + auto massGridVariables = std::make_shared<MassGridVariables>(massProblem, massGridGeometry); + + 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<TypeTag, Properties::IOFields>; - StaggeredVtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); - IOFields::initOutputModule(vtkWriter); //! Add model specific output fields + 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.write(0.0); - // 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); - + 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 = Dumux::MultiDomainNewtonSolver<Assembler, LinearSolver, CouplingManager>; + NewtonSolver nonLinearSolver(assembler, linearSolver, couplingManager); //! set some check points for the time loop timeLoop->setPeriodicCheckPoint(tEnd/5.0); + PlotConcentration<Scalar> plotConcentration; + // time loop timeLoop->start(); do { @@ -124,8 +271,12 @@ int main(int argc, char** argv) // make the new solution the old solution xOld = x; - gridVariables->advanceTimeStep(); - problem->plotComponentsOverTime(x, *gridVariables,timeLoop->time()+timeLoop->timeStepSize()); + momentumGridVariables->advanceTimeStep(); + massGridVariables->advanceTimeStep(); + + static const bool plotOutput = getParam<bool>("Problem.PlotOutput"); + if (plotOutput) + plotConcentration.plotComponentsOverTime(x[massIdx], *massGridVariables, timeLoop->time()+timeLoop->timeStepSize()); // advance to the time loop to the next step timeLoop->advanceTimeStep(); diff --git a/test/freeflow/navierstokesnc/maxwellstefan/params.input b/test/freeflow/navierstokesnc/maxwellstefan/params.input index 3bc552f490..f406f1b138 100644 --- a/test/freeflow/navierstokesnc/maxwellstefan/params.input +++ b/test/freeflow/navierstokesnc/maxwellstefan/params.input @@ -11,9 +11,10 @@ Cells = 30 30 Name = test_msfreeflow EnableGravity = false EnableInertiaTerms = false +PlotOutput = true [Assembly] -NumericDifference.BaseEpsilon = 1e-8 +NumericDifference.BaseEpsilon = 1e-4 [Vtk] WriteFaceData = false diff --git a/test/freeflow/navierstokesnc/maxwellstefan/problem.hh b/test/freeflow/navierstokesnc/maxwellstefan/problem.hh index ef12f3bebf..f1bdfd7f54 100644 --- a/test/freeflow/navierstokesnc/maxwellstefan/problem.hh +++ b/test/freeflow/navierstokesnc/maxwellstefan/problem.hh @@ -15,13 +15,12 @@ #include <dumux/common/parameters.hh> #include <dumux/common/properties.hh> -#include <dumux/common/numeqvector.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> -#include <dumux/io/gnuplotinterface.hh> - namespace Dumux { /*! @@ -33,211 +32,151 @@ class MaxwellStefanNCTestProblem : public NavierStokesStaggeredProblem<TypeTag> { using ParentType = NavierStokesStaggeredProblem<TypeTag>; - using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; - using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>; + using BoundaryTypes = typename ParentType::BoundaryTypes; using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; - using NumEqVector = Dumux::NumEqVector<PrimaryVariables>; + 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 SubControlVolume = typename GridGeometry::SubControlVolume; + using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; + using FVElementGeometry = typename GridGeometry::LocalView; - using Element = typename GridGeometry::GridView::template Codim<0>::Entity; + static constexpr auto dimWorld = GridGeometry::GridView::dimensionworld; + using Element = typename FVElementGeometry::Element; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - static constexpr auto compOneIdx = Indices::conti0EqIdx; - static constexpr auto compTwoIdx = Indices::conti0EqIdx + FluidSystem::N2Idx; - static constexpr auto compThreeIdx = Indices::conti0EqIdx + FluidSystem::CO2Idx; + using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>; + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; -public: - MaxwellStefanNCTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) - : ParentType(gridGeometry) - { - plotOutput_ = getParam<bool>("Problem.PlotOutput", false); - } + using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>; + using TimeLoopPtr = std::shared_ptr<CheckPointTimeLoop<Scalar>>; - /*! - * \name Problem parameters - */ - // \{ +public: + MaxwellStefanNCTestProblem(std::shared_ptr<const GridGeometry> gridGeometry, + std::shared_ptr<CouplingManager> couplingManager) + : ParentType(gridGeometry, couplingManager) + {} /*! - * \brief Writes out the diffusion rates from left to right - * - * Called after every time step + * \brief Specifies which kind of boundary condition should be + * used for which equation on a given boundary control volume. * - * \param curSol Vector containing the current solution - * \param gridVariables The grid variables - * \param time The time + * \param globalPos The position of the center of the finite volume */ - template<class SolutionVector, class GridVariables> - void plotComponentsOverTime(const SolutionVector& curSol, - const GridVariables& gridVariables, - const Scalar time) + BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const { - if (plotOutput_) + BoundaryTypes values; + + if constexpr (ParentType::isMomentumProblem()) { - Scalar x_co2_left = 0.0; - Scalar x_n2_left = 0.0; - Scalar x_co2_right = 0.0; - Scalar x_n2_right = 0.0; - Scalar x_h2_left = 0.0; - Scalar x_h2_right = 0.0; - Scalar i = 0.0; - Scalar j = 0.0; - 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, curSol); - for (auto&& scv : scvs(fvGeometry)) - { - const auto globalPos = scv.dofPosition(); - - if (globalPos[0] < 0.5) - { - x_co2_left += elemVolVars[scv].moleFraction(FluidSystem::CO2Idx); - x_n2_left += elemVolVars[scv].moleFraction(FluidSystem::N2Idx); - x_h2_left += elemVolVars[scv].moleFraction(FluidSystem::H2Idx); - i +=1; - } - else - { - x_co2_right += elemVolVars[scv].moleFraction(FluidSystem::CO2Idx); - x_n2_right += elemVolVars[scv].moleFraction(FluidSystem::N2Idx); - x_h2_right += elemVolVars[scv].moleFraction(FluidSystem::H2Idx); - j +=1; - } - } - } - x_co2_left /= i; - x_n2_left /= i; - x_h2_left /= i; - x_co2_right /= j; - x_n2_right /= j; - x_h2_right /= j; - - //do a gnuplot - x_.push_back(time); // in seconds - y1_.push_back(x_n2_left); - y2_.push_back(x_n2_right); - y3_.push_back(x_co2_left); - y4_.push_back(x_co2_right); - y5_.push_back(x_h2_left); - y6_.push_back(x_h2_right); - - gnuplot_.resetPlot(); - gnuplot_.setXRange(0, std::max(time, 72000.0)); - gnuplot_.setYRange(0.4, 0.6); - gnuplot_.setXlabel("time [s]"); - gnuplot_.setYlabel("mole fraction mol/mol"); - gnuplot_.addDataSetToPlot(x_, y1_, "N2_left.dat", "w l t 'N_2 left'"); - gnuplot_.addDataSetToPlot(x_, y2_, "N2_right.dat", "w l t 'N_2 right'"); - gnuplot_.plot("mole_fraction_N2"); - - gnuplot2_.resetPlot(); - gnuplot2_.setXRange(0, std::max(time, 72000.0)); - gnuplot2_.setYRange(0.0, 0.6); - gnuplot2_.setXlabel("time [s]"); - gnuplot2_.setYlabel("mole fraction mol/mol"); - gnuplot2_.addDataSetToPlot(x_, y3_, "CO2_left.dat", "w l t 'CO_2 left'"); - gnuplot2_.addDataSetToPlot(x_, y4_, "CO2_right.dat", "w l t 'CO_2 right'"); - gnuplot2_.plot("mole_fraction_C02"); - - gnuplot3_.resetPlot(); - gnuplot3_.setXRange(0, std::max(time, 72000.0)); - gnuplot3_.setYRange(0.0, 0.6); - gnuplot3_.setXlabel("time [s]"); - gnuplot3_.setYlabel("mole fraction mol/mol"); - gnuplot3_.addDataSetToPlot(x_, y5_, "H2_left.dat", "w l t 'H_2 left'"); - gnuplot3_.addDataSetToPlot(x_, y6_, "H2_right.dat", "w l t 'H_2 right'"); - gnuplot3_.plot("mole_fraction_H2"); + values.setDirichlet(Indices::velocityXIdx); + values.setDirichlet(Indices::velocityYIdx); } + else + values.setAllNeumann(); + + return values; } - // \} + //! Enable internal Dirichlet constraints + static constexpr bool enableInternalDirichletConstraints() + { return !ParentType::isMomentumProblem(); } /*! - * \name Boundary conditions - */ - // \{ - - /*! - * \brief Specifies which kind of boundary condition should be - * used for which equation on a given boundary control volume. + * \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 globalPos The position of the center of the finite volume + * \param element The finite element + * \param scv The sub-control volume */ - BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const + std::bitset<DirichletValues::dimension> hasInternalDirichletConstraint(const Element& element, const SubControlVolume& scv) const { - BoundaryTypes values; - // Set no-flow/no-slip everywhere. Neumann defaults to zero. - values.setDirichlet(Indices::velocityXIdx); - values.setDirichlet(Indices::velocityYIdx); - values.setNeumann(compOneIdx); - values.setNeumann(compTwoIdx); - values.setNeumann(compThreeIdx); + std::bitset<DirichletValues::dimension> values; + + // 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 (scv.dofIndex() == 0) + values.set(0); + return values; } - /*! - * \brief Evaluates the boundary conditions for a Dirichlet control volume. + /*! + * \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); } + + /*! + * \brief Returns Dirichlet boundary values at a given position. * - * \param globalPos The center of the finite volume which ought to be set. + * \param globalPos The global position */ - PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const - { - return initialAtPos(globalPos); - } + DirichletValues dirichletAtPos(const GlobalPosition &globalPos) const + { return initialAtPos(globalPos); } - /*! - * \name Volume terms + /*! + * \brief Evaluates the boundary conditions for a Neumann control volume. + * + * \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 */ - // \{ + template<class ElementVolumeVariables, class ElementFluxVariablesCache> + BoundaryFluxes neumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFluxVariablesCache& elemFluxVarsCache, + const SubControlVolumeFace& scvf) const + { return BoundaryFluxes(0.0); } - /*! + /*! * \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 initialValues(0.0); - if (globalPos[0] < 0.5) + InitialValues initialValues(0.0); + + if constexpr (!ParentType::isMomentumProblem()) { - initialValues[compTwoIdx] = 0.50086; - initialValues[compThreeIdx] = 0.49914; + static constexpr auto compTwoIdx = Indices::conti0EqIdx + FluidSystem::N2Idx; + static constexpr auto compThreeIdx = Indices::conti0EqIdx + FluidSystem::CO2Idx; + + initialValues[Indices::pressureIdx] = 1.1e+5; + if (globalPos[0] < 0.5) + { + initialValues[compTwoIdx] = 0.50086; + initialValues[compThreeIdx] = 0.49914; + } + else + { + initialValues[compTwoIdx] = 0.49879; + initialValues[compThreeIdx] = 0.0; + } } else { - initialValues[compTwoIdx] = 0.49879; - initialValues[compThreeIdx] = 0.0; + initialValues[Indices::velocityXIdx] = 0.0; + initialValues[Indices::velocityYIdx] = 0.0; } - initialValues[Indices::pressureIdx] = 1.1e+5; - initialValues[Indices::velocityXIdx] = 0.0; - initialValues[Indices::velocityYIdx] = 0.0; - return initialValues; } -private: - - bool plotOutput_; +private: const Scalar eps_{1e-6}; - - Dumux::GnuplotInterface<Scalar> gnuplot_; - Dumux::GnuplotInterface<Scalar> gnuplot2_; - Dumux::GnuplotInterface<Scalar> gnuplot3_; - - std::vector<Scalar> x_; - std::vector<Scalar> y1_; - std::vector<Scalar> y2_; - std::vector<Scalar> y3_; - std::vector<Scalar> y4_; - std::vector<Scalar> y5_; - std::vector<Scalar> y6_; }; } // end namespace Dumux diff --git a/test/freeflow/navierstokesnc/maxwellstefan/properties.hh b/test/freeflow/navierstokesnc/maxwellstefan/properties.hh index 63980d3202..35b5f5a734 100644 --- a/test/freeflow/navierstokesnc/maxwellstefan/properties.hh +++ b/test/freeflow/navierstokesnc/maxwellstefan/properties.hh @@ -14,13 +14,16 @@ #include <dune/grid/yaspgrid.hh> -#include <dumux/discretization/staggered/freeflow/properties.hh> +#include <dumux/freeflow/navierstokes/momentum/model.hh> +#include <dumux/freeflow/navierstokes/mass/1pnc/model.hh> #include <dumux/flux/maxwellstefanslaw.hh> +#include <dumux/material/fluidsystems/base.hh> -#include <dumux/freeflow/compositional/navierstokesncmodel.hh> -#include <dumux/material/components/simpleh2o.hh> -#include <dumux/material/fluidsystems/h2oair.hh> +#include <dumux/discretization/fcstaggered.hh> +#include <dumux/discretization/cctpfa.hh> + +#include <dumux/multidomain/staggeredfreeflow/couplingmanager.hh> #include "problem.hh" @@ -28,7 +31,9 @@ namespace Dumux::Properties { // Create new type tags namespace TTag { -struct MaxwellStefanNCTest { using InheritsFrom = std::tuple<NavierStokesNC, StaggeredFreeFlowModel>; }; +struct MaxwellStefanNCTest {}; +struct MaxwellStefanTestMomentum { using InheritsFrom = std::tuple<MaxwellStefanNCTest, NavierStokesMomentum, FaceCenteredStaggeredModel>; }; +struct MaxwellStefanTestMass { using InheritsFrom = std::tuple<MaxwellStefanNCTest, NavierStokesMassOnePNC, CCTpfaModel>; }; } // end namespace TTag template<class TypeTag> @@ -56,6 +61,12 @@ 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 @@ -91,6 +102,13 @@ public: static Scalar molarMass(unsigned int compIdx) { return 0.02896; } + //! Returns whether the fluids are miscible + static constexpr bool isMiscible() + { return false; } + + //! Returns whether the fluids are compressible + static constexpr bool isCompressible(int phaseIdx = 0) + { return false; } using Base::binaryDiffusionCoefficient; /*! -- GitLab