diff --git a/.patches/exercise-basic/exercise-basic.patch b/.patches/exercise-basic/exercise-basic.patch index 7e0ee9a827d59e0d4dc4282ac65782bfed3c1e37..43e320fbdf6e6245526b91e26def9cf46879a7aa 100644 --- a/.patches/exercise-basic/exercise-basic.patch +++ b/.patches/exercise-basic/exercise-basic.patch @@ -1,163 +1,5 @@ -diff -ruN exercises/exercise-basic/2p2cmain.cc exercises/solution/exercise-basic/2p2cmain.cc ---- exercises/exercise-basic/2p2cmain.cc 2024-07-08 09:06:59.581159992 +0200 -+++ exercises/solution/exercise-basic/2p2cmain.cc 1970-01-01 01:00:00.000000000 +0100 -@@ -1,154 +0,0 @@ --// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- --// vi: set et ts=4 sw=4 sts=4: --/***************************************************************************** -- * See the file COPYING for full copying permissions. * -- * * -- * This program is free software: you can redistribute it and/or modify * -- * it under the terms of the GNU General Public License as published by * -- * the Free Software Foundation, either version 3 of the License, or * -- * (at your option) any later version. * -- * * -- * This program is distributed in the hope that it will be useful, * -- * but WITHOUT ANY WARRANTY; without even the implied warranty of * -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -- * GNU General Public License for more details. * -- * * -- * You should have received a copy of the GNU General Public License * -- * along with this program. If not, see <http://www.gnu.org/licenses/>. * -- *****************************************************************************/ --/*! -- * \file -- * \brief The main file for the 2p2c porousmediumflow problem in exercise-basic -- */ --#include <config.h> -- --#include <iostream> -- --#include <dumux/common/initialize.hh> --#include <dumux/common/properties.hh> --#include <dumux/common/parameters.hh> -- --#include <dumux/linear/istlsolvers.hh> --#include <dumux/linear/linearsolvertraits.hh> --#include <dumux/linear/linearalgebratraits.hh> --#include <dumux/nonlinear/newtonsolver.hh> -- --#include <dumux/assembly/fvassembler.hh> --#include <dumux/assembly/diffmethod.hh> -- --#include <dumux/io/vtkoutputmodule.hh> --#include <dumux/io/grid/gridmanager_yasp.hh> -- --// The properties file, where the compile time options are defined --#include "properties2p2c.hh" -- --//////////////////////// --// the main function --//////////////////////// --int main(int argc, char** argv) --{ -- using namespace Dumux; -- -- // define the type tag for this problem -- using TypeTag = Properties::TTag::Injection2p2cCC; -- -- // initialize MPI+X, finalize is done automatically on exit -- Dumux::initialize(argc, argv); -- -- // parse command line arguments and input file -- 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.init(); -- -- //////////////////////////////////////////////////////////// -- // run instationary non-linear problem on this grid -- //////////////////////////////////////////////////////////// -- -- // we compute on the leaf grid view -- 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); -- -- // the solution vector -- using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; -- SolutionVector x; -- problem->applyInitialSolution(x); -- auto xOld = x; -- -- // the grid variables -- using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; -- auto gridVariables = std::make_shared<GridVariables>(problem, gridGeometry); -- gridVariables->init(x); -- -- // initialize the vtk output module -- using IOFields = GetPropType<TypeTag, Properties::IOFields>; -- VtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); -- using VelocityOutput = GetPropType<TypeTag, Properties::VelocityOutput>; -- vtkWriter.addVelocityOutput(std::make_shared<VelocityOutput>(*gridVariables)); -- IOFields::initOutputModule(vtkWriter); //!< Add model specific output fields -- vtkWriter.write(0.0); -- -- // instantiate time loop -- using Scalar = GetPropType<TypeTag, Properties::Scalar>; -- const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); -- const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); -- const auto dt = getParam<Scalar>("TimeLoop.DtInitial"); -- auto timeLoop = std::make_shared<TimeLoop<Scalar>>(0.0, dt, tEnd); -- timeLoop->setMaxTimeStepSize(maxDt); -- -- // the assembler with time loop for instationary problem -- using Assembler = FVAssembler<TypeTag, DiffMethod::numeric>; -- auto assembler = std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); -- -- // the linear solver -- using LinearSolver = AMGBiCGSTABIstlSolver<LinearSolverTraits<GridGeometry>, LinearAlgebraTraitsFromAssembler<Assembler>>; -- auto linearSolver = std::make_shared<LinearSolver>(gridGeometry->gridView(), gridGeometry->dofMapper()); -- -- // the non-linear solver --// using PrimaryVariableSwitch = GetPropType<TypeTag, Properties::PrimaryVariableSwitch>; -- using NewtonSolver = NewtonSolver<Assembler, LinearSolver>; -- NewtonSolver nonLinearSolver(assembler, linearSolver); -- -- // time loop -- timeLoop->start(); -- while (!timeLoop->finished()) -- { -- //set time in problem (is used in time-dependent Neumann boundary condition) -- problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); -- -- // solve the non-linear system with time step control -- nonLinearSolver.solve(x, *timeLoop); -- -- // make the new solution the old solution -- xOld = x; -- gridVariables->advanceTimeStep(); -- -- // advance to the time loop to the next step -- timeLoop->advanceTimeStep(); -- -- // report statistics of this time step -- timeLoop->reportTimeStep(); -- -- // set new dt as suggested by the newton solver -- timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); -- -- // output to vtk -- vtkWriter.write(timeLoop->time()); -- } -- -- timeLoop->finalize(leafGridView.comm()); -- -- // print parameter report -- if (leafGridView.comm().rank() == 0) -- Parameters::print(); -- -- return 0; --} // end main diff -ruN exercises/exercise-basic/2pmain.cc exercises/solution/exercise-basic/2pmain.cc ---- exercises/exercise-basic/2pmain.cc 2024-07-08 09:06:59.581159992 +0200 +--- exercises/exercise-basic/2pmain.cc 2023-03-31 13:48:56.158686713 +0200 +++ exercises/solution/exercise-basic/2pmain.cc 1970-01-01 01:00:00.000000000 +0100 @@ -1,157 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- @@ -319,7 +161,7 @@ diff -ruN exercises/exercise-basic/2pmain.cc exercises/solution/exercise-basic/2 -} // end main diff -ruN exercises/exercise-basic/2pnimain.cc exercises/solution/exercise-basic/2pnimain.cc --- exercises/exercise-basic/2pnimain.cc 1970-01-01 01:00:00.000000000 +0100 -+++ exercises/solution/exercise-basic/2pnimain.cc 2024-07-08 09:06:59.613159864 +0200 ++++ exercises/solution/exercise-basic/2pnimain.cc 2023-03-31 13:48:56.182686617 +0200 @@ -0,0 +1,150 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: @@ -472,17 +314,13 @@ diff -ruN exercises/exercise-basic/2pnimain.cc exercises/solution/exercise-basic + return 0; +} // end main diff -ruN exercises/exercise-basic/CMakeLists.txt exercises/solution/exercise-basic/CMakeLists.txt ---- exercises/exercise-basic/CMakeLists.txt 2024-07-08 09:06:59.581159992 +0200 -+++ exercises/solution/exercise-basic/CMakeLists.txt 2024-07-08 09:06:59.613159864 +0200 -@@ -1,13 +1,6 @@ +--- exercises/exercise-basic/CMakeLists.txt 2024-07-16 17:38:07.971854664 +0200 ++++ exercises/solution/exercise-basic/CMakeLists.txt 2023-03-31 13:48:56.182686617 +0200 +@@ -1,9 +1,6 @@ -# the immiscible two-phase simulation program -dumux_add_test(NAME exercise_basic_2p - SOURCES 2pmain.cc) - --# the compositional two-phase two-component simulation program --dumux_add_test(NAME exercise_basic_2p2c -- SOURCES 2p2cmain.cc) -- -# here, add the two-phase non-isothermal simulation program - +# the two-phase non-isothermal simulation program @@ -490,243 +328,12 @@ diff -ruN exercises/exercise-basic/CMakeLists.txt exercises/solution/exercise-ba + SOURCES 2pnimain.cc) # add a symlink for each input file - add_input_file_links() -diff -ruN exercises/exercise-basic/injection2p2cproblem.hh exercises/solution/exercise-basic/injection2p2cproblem.hh ---- exercises/exercise-basic/injection2p2cproblem.hh 2024-07-08 09:06:59.581159992 +0200 -+++ exercises/solution/exercise-basic/injection2p2cproblem.hh 1970-01-01 01:00:00.000000000 +0100 -@@ -1,229 +0,0 @@ --// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- --// vi: set et ts=4 sw=4 sts=4: --/***************************************************************************** -- * See the file COPYING for full copying permissions. * -- * * -- * This program is free software: you can redistribute it and/or modify * -- * it under the terms of the GNU General Public License as published by * -- * the Free Software Foundation, either version 3 of the License, or * -- * (at your option) any later version. * -- * * -- * This program is distributed in the hope that it will be useful, * -- * but WITHOUT ANY WARRANTY; without even the implied warranty of * -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -- * GNU General Public License for more details. * -- * * -- * You should have received a copy of the GNU General Public License * -- * along with this program. If not, see <http://www.gnu.org/licenses/>. * -- *****************************************************************************/ --/*! -- * \file -- * -- * \brief The two-phase porousmediumflow problem for exercise-basic -- */ -- --#ifndef DUMUX_EX_BASIC_PROBLEM_2P2C_HH --#define DUMUX_EX_BASIC_PROBLEM_2P2C_HH -- --#include <dumux/common/properties.hh> --#include <dumux/common/boundarytypes.hh> --#include <dumux/common/numeqvector.hh> --#include <dumux/porousmediumflow/problem.hh> --#include <dumux/material/binarycoefficients/h2o_n2.hh> -- --namespace Dumux { -- --/*! -- * \ingroup TwoPTwoCModel -- * \ingroup ImplicitTestProblems -- * \brief Gas injection problem where a gas (here nitrogen) is injected into a fully -- * water saturated medium. During buoyancy driven upward migration the gas -- * passes a high temperature area. -- * -- * The domain is sized 60 m times 40 m. -- * -- * For the mass conservation equation Neumann boundary conditions are used on -- * the top, on the bottom and on the right of the domain, while Dirichlet conditions -- * apply on the left boundary. -- * -- * Gas is injected at the right boundary from 7 m to 15 m at a rate of -- * 0.001 kg/(s m), the remaining Neumann boundaries are no-flow -- * boundaries. -- * -- * At the Dirichlet boundaries a hydrostatic pressure and a gas saturation of zero a -- * -- * This problem uses the \ref TwoPModel model. -- */ --template<class TypeTag> --class Injection2p2cProblem : public PorousMediumFlowProblem<TypeTag> --{ -- using ParentType = PorousMediumFlowProblem<TypeTag>; -- using Scalar = GetPropType<TypeTag, Properties::Scalar>; -- using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; -- using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; -- using BoundaryTypes = Dumux::BoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; -- using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; -- using FVElementGeometry = typename GridGeometry::LocalView; -- using GridView = typename GridGeometry::GridView; -- using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>; -- using NumEqVector = Dumux::NumEqVector<PrimaryVariables>; -- -- static constexpr int dimWorld = GridView::dimensionworld; -- using Element = typename GridView::template Codim<0>::Entity; -- using GlobalPosition = typename Element::Geometry::GlobalCoordinate; -- --public: -- Injection2p2cProblem(std::shared_ptr<const GridGeometry> gridGeometry) -- : ParentType(gridGeometry) -- { -- // initialize the tables of the fluid system -- FluidSystem::init(/*tempMin=*/273.15, -- /*tempMax=*/423.15, -- /*numTemp=*/50, -- /*pMin=*/0.0, -- /*pMax=*/30e6, -- /*numP=*/300); -- -- // name of the problem and output file -- // getParam<TYPE>("GROUPNAME.PARAMNAME") reads and sets parameter PARAMNAME -- // of type TYPE given in the group GROUPNAME from the input file -- name_ = getParam<std::string>("Problem.Name"); -- // depth of the aquifer, units: m -- aquiferDepth_ = getParam<Scalar>("Problem.AquiferDepth"); -- // the duration of the injection, units: second -- injectionDuration_ = getParam<Scalar>("Problem.InjectionDuration"); -- } -- -- /*! -- * \brief Returns the problem name -- * -- * This is used as a prefix for files generated by the simulation. -- */ -- std::string name() const -- { return name_+"-2p2c"; } -- -- /*! -- * \brief Specifies which kind of boundary condition should be -- * used for which equation on a given boundary segment. -- * -- * \param globalPos The position for which the bc type should be evaluated -- */ -- BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const -- { -- BoundaryTypes bcTypes; -- if (globalPos[0] < eps_) -- bcTypes.setAllDirichlet(); -- else -- bcTypes.setAllNeumann(); -- -- return bcTypes; -- } -- -- /*! -- * \brief Evaluates the boundary conditions for a Dirichlet -- * boundary segment -- * -- * \param globalPos The global position -- */ -- PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const -- { -- return initialAtPos(globalPos); -- } -- -- /*! -- * \brief Evaluate the boundary conditions for a Neumann -- * boundary segment. -- * -- * \param globalPos The position of the integration point of the boundary segment. -- */ -- NumEqVector neumannAtPos(const GlobalPosition &globalPos) const -- { -- // initialize values to zero, i.e. no-flow Neumann boundary conditions -- NumEqVector values(0.0); -- -- // if we are inside the injection zone set inflow Neumann boundary conditions -- if (injectionActive() && onInjectionBoundary(globalPos)) -- { -- // TODO: dumux-course-task -- //instead of setting -1e-4 here directly use totalAreaSpecificInflow_ in the computation -- -- // inject nitrogen. negative values mean injection -- // convert from units kg/(s*m^2) to mole/(s*m^2) -- values[Indices::conti0EqIdx + FluidSystem::N2Idx] = -1e-4/FluidSystem::molarMass(FluidSystem::N2Idx); -- values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0.0; -- } -- -- return values; -- } -- -- /*! -- * \brief Evaluate the source term for all phases within a given -- * sub-control-volume. -- * -- * \param globalPos The position for which the source term should be evaluated -- */ -- NumEqVector sourceAtPos(const GlobalPosition &globalPos) const -- { -- return NumEqVector(0.0); -- } -- -- /*! -- * \brief Evaluate the initial value for a control volume. -- * -- * \param globalPos The position for which the initial condition should be evaluated -- */ -- PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const -- { -- PrimaryVariables values(0.0); -- values.setState(Indices::firstPhaseOnly); -- // get the water density at atmospheric conditions -- const Scalar densityW = FluidSystem::H2O::liquidDensity(this->spatialParams().temperatureAtPos(globalPos), 1.0e5); -- -- // assume an initially hydrostatic liquid pressure profile -- // note: we subtract rho_w*g*h because g is defined negative -- const Scalar pw = 1.0e5 - densityW*this->spatialParams().gravity(globalPos)[dimWorld-1]*(aquiferDepth_ - globalPos[dimWorld-1]); -- -- // initially we have some nitrogen dissolved -- // saturation mole fraction would be -- // moleFracLiquidN2 = (pw + pc + p_vap^sat)/henry; -- const Scalar moleFracLiquidN2 = pw*0.95/BinaryCoeff::H2O_N2::henry(this->spatialParams().temperatureAtPos(globalPos)); -- -- // note that because we start with a single phase system the primary variables -- // are pl and x^w_N2. This will switch as soon after we start injecting to a two -- // phase system so the primary variables will be pl and Sn (nonwetting saturation). -- values[Indices::pressureIdx] = pw; -- values[Indices::switchIdx] = moleFracLiquidN2; -- -- return values; -- } -- -- //! set the time for the time dependent boundary conditions (called from main) -- void setTime(Scalar time) -- { time_ = time; } -- -- //! Return true if the injection is currently active -- bool injectionActive() const -- { return time_ < injectionDuration_; } -- -- //! Return true if the given position is in the injection boundary region -- bool onInjectionBoundary(const GlobalPosition& globalPos) const -- { -- return globalPos[1] < 15. + eps_ -- && globalPos[1] > 7. - eps_ -- && globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; -- } -- --private: -- static constexpr Scalar eps_ = 1e-6; -- std::string name_; //! Problem name -- Scalar aquiferDepth_; //! Depth of the aquifer in m -- Scalar injectionDuration_; //! Duration of the injection in seconds -- Scalar time_; -- //TODO: dumux-course-task -- //define the Scalar totalAreaSpecificInflow_ here -- --}; -- --} //end namespace Dumux -- --#endif +-add_input_file_links() +\ No newline at end of file ++add_input_file_links() diff -ruN exercises/exercise-basic/injection2pniproblem.hh exercises/solution/exercise-basic/injection2pniproblem.hh ---- exercises/exercise-basic/injection2pniproblem.hh 2024-07-16 16:55:12.734099365 +0200 -+++ exercises/solution/exercise-basic/injection2pniproblem.hh 2024-07-16 16:55:12.738099338 +0200 +--- exercises/exercise-basic/injection2pniproblem.hh 2024-07-16 17:38:07.971854664 +0200 ++++ exercises/solution/exercise-basic/injection2pniproblem.hh 2024-07-16 17:38:07.971854664 +0200 @@ -19,7 +19,7 @@ /*! * \file @@ -774,102 +381,100 @@ diff -ruN exercises/exercise-basic/injection2pniproblem.hh exercises/solution/ex static constexpr int dimWorld = GridView::dimensionworld; using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; -@@ -115,14 +116,6 @@ +@@ -83,13 +84,13 @@ + /*pMax=*/30e6, + /*numP=*/300); + +- // name of the problem and output file ++ // Name of the problem and output file + // getParam<TYPE>("GROUPNAME.PARAMNAME") reads and sets parameter PARAMNAME + // of type TYPE given in the group GROUPNAME from the input file + name_ = getParam<std::string>("Problem.Name"); +- // depth of the aquifer, unit: m ++ // Depth of the aquifer, unit: m + aquiferDepth_ = getParam<Scalar>("Problem.AquiferDepth"); +- // the duration of the injection, unit: seconds ++ // The duration of the injection, unit: seconds + injectionDuration_ = getParam<Scalar>("Problem.InjectionDuration"); + } + +@@ -115,13 +116,6 @@ else bcTypes.setAllNeumann(); - /*! -- * TODO:dumux-course-task: -- * dumux-course-task: -- * set Dirichlet conditions for the energy equation on the left boundary -- * and Neumann everywhere else -- * think about: is there anything necessary to do here? +- * TODO:dumux-course-task 4: +- * Set Dirichlet conditions for the energy equation on the left boundary +- * and Neumann everywhere else. +- * Think about: is there anything necessary to do here? - */ - return bcTypes; } -@@ -135,13 +128,6 @@ +@@ -134,12 +128,6 @@ PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { return initialAtPos(globalPos); - - /*! -- * TODO:dumux-course-task: -- * dumux-course-task: -- * set Dirichlet conditions for the energy equation on the left boundary -- * think about: is there anything necessary to do here? +- * TODO:dumux-course-task 4: +- * Set Dirichlet conditions for the energy equation on the left boundary. +- * Think about: is there anything necessary to do here? - */ } /*! -@@ -156,19 +142,17 @@ +@@ -154,19 +142,20 @@ NumEqVector values(0.0); // if we are inside the injection zone set inflow Neumann boundary conditions - if (injectionActive() && onInjectionBoundary(globalPos)) + if (injectionActive() && onInjectionBoundary(globalPos)) { -+ - // inject nitrogen. negative values mean injection - // units kg/(s*m^2) - values[Indices::conti0EqIdx + FluidSystem::N2Idx] = -1e-4; +- // inject nitrogen. negative values mean injection ++ const Scalar injectionRate = -1e-4; ++ ++ // inject nitrogen. Negative values mean injection + // unit: kg/(s*m^2) +- values[Indices::conti0EqIdx + FluidSystem::N2Idx] = -1e-4; ++ values[Indices::conti0EqIdx + FluidSystem::N2Idx] = injectionRate; values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0.0; - /*! -- * TODO:dumux-course-task: +- * TODO:dumux-course-task 4: - * Set Neumann noflow conditions for the energy equation everywhere else except the left boundary. -- * Additionally, consider the energy flux at the injection point which is equal to the product of the respective mass flux and the matching enthalpy. Use the function `gasEnthalpy(...)` from the N2 component to access the necessary enthalpy. +- * Additionally, consider the energy flux at the injection point which is equal to the product of the respective mass flux and the matching enthalpy. Use the function `gasEnthalpy(temperature,pressure)` from the N2 component to access the necessary enthalpy. - * hint: use `Indices::energyEqIdx` to access the entry belonging to the energy flux. - */ + // energy fluxes are always mass specific -+ //units W/(m^2) -+ values[Indices::energyEqIdx] = -1e-4 /*kg/(m^2 s)*/ *N2::gasEnthalpy(injectionTemperature(), 1e5 /*Pa*/)/*J/kg*/; ++ // unit: W/(m^2) ++ const Scalar temperatureAtInjection = initialAtPos(globalPos)[Indices::temperatureIdx];/*K*/ ++ const Scalar pressureAtInjection = initialAtPos(globalPos)[Indices::pressureIdx];/*Pa*/ ++ values[Indices::energyEqIdx] = injectionRate /*kg/(m^2 s)*/ *N2::gasEnthalpy(temperatureAtInjection, pressureAtInjection)/*J/kg*/; } return values; -@@ -204,20 +188,17 @@ +@@ -202,13 +191,10 @@ values[Indices::pressureIdx] = pw; values[Indices::saturationIdx] = 0.0; - /*! -- * TODO:dumux-course-task: -- * set a temperature gradient of 0.03 K per m beginning at 283 K here. -- * Hint: you can use aquiferDepth_ and the globalPos similar to the pressure gradient -- * use globalPos[0] and globalPos[1] to implement the high temperature lens with 380 K +- * TODO:dumux-course-task 4: +- * Set a temperature gradient of 0.03 K per m beginning at 283 K here. +- * Hint: you can use aquiferDepth_ and the globalPos similar to the pressure gradient. +- * Use globalPos[0] and globalPos[1] to implement the high temperature lens with 380 K - * Hint : use Indices::temperatureIdx to address the initial values for temperature - */ + values[Indices::temperatureIdx] = 283.0 + (aquiferDepth_ - globalPos[1])*0.03; + if (globalPos[0] > 20 - eps_ && globalPos[0] < 30 + eps_ && globalPos[1] > 5 - eps_ && globalPos[1] < 35 + eps_) -+ values[Indices::temperatureIdx] = injectionTemperature(); ++ values[Indices::temperatureIdx] = 380.0; + return values; } -- //! set the time for the time dependent boundary conditions (called from main) -+ //! Set the time for the time dependent boundary conditions (called from main) - void setTime(Scalar time) - { time_ = time; } -- -+ - //! Return true if the injection is currently active - bool injectionActive() const - { return time_ < injectionDuration_; } -@@ -230,6 +211,12 @@ - && globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; - } - -+ //! Set injection temperature for the domain -+ Scalar injectionTemperature() const -+ { -+ return 380.0; -+ } -+ - private: - static constexpr Scalar eps_ = 1e-6; - std::string name_; //! Problem name diff -ruN exercises/exercise-basic/injection2pproblem.hh exercises/solution/exercise-basic/injection2pproblem.hh ---- exercises/exercise-basic/injection2pproblem.hh 2024-07-08 09:06:59.581159992 +0200 +--- exercises/exercise-basic/injection2pproblem.hh 2024-07-16 17:38:07.971854664 +0200 +++ exercises/solution/exercise-basic/injection2pproblem.hh 1970-01-01 01:00:00.000000000 +0100 @@ -1,223 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- @@ -949,7 +554,7 @@ diff -ruN exercises/exercise-basic/injection2pproblem.hh exercises/solution/exer - Injection2PProblem(std::shared_ptr<const GridGeometry> gridGeometry) - : ParentType(gridGeometry) - { -- // initialize the tables of the fluid system +- // Initialize the tables of the fluid system - FluidSystem::init(/*tempMin=*/273.15, - /*tempMax=*/423.15, - /*numTemp=*/50, @@ -957,13 +562,13 @@ diff -ruN exercises/exercise-basic/injection2pproblem.hh exercises/solution/exer - /*pMax=*/30e6, - /*numP=*/300); - -- // name of the problem and output file +- // Name of the problem and output file - // getParam<TYPE>("GROUPNAME.PARAMNAME") reads and sets parameter PARAMNAME - // of type TYPE given in the group GROUPNAME from the input file - name_ = getParam<std::string>("Problem.Name"); -- // depth of the aquifer, units: m +- // Depth of the aquifer, unit: m - aquiferDepth_ = getParam<Scalar>("Problem.AquiferDepth"); -- // the duration of the injection, units: second +- // The duration of the injection, unit: seconds - injectionDuration_ = getParam<Scalar>("Problem.InjectionDuration"); - } - @@ -1023,8 +628,8 @@ diff -ruN exercises/exercise-basic/injection2pproblem.hh exercises/solution/exer - // than using <= or >= as it is robust with regard to imprecision introduced by rounding errors. - if (injectionActive() && onInjectionBoundary(globalPos)) - { -- // inject nitrogen. negative values mean injection -- // units kg/(s*m^2) +- // Inject nitrogen. Negative values mean injection +- // unit: kg/(s*m^2) - values[Indices::conti0EqIdx + FluidSystem::N2Idx] = -1e-4; - values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0.0; - } @@ -1068,7 +673,7 @@ diff -ruN exercises/exercise-basic/injection2pproblem.hh exercises/solution/exer - - // \} - -- //! set the time for the time dependent boundary conditions (called from main) +- //! Set the time for the time dependent boundary conditions (called from main) - void setTime(Scalar time) - { time_ = time; } - @@ -1096,8 +701,8 @@ diff -ruN exercises/exercise-basic/injection2pproblem.hh exercises/solution/exer - -#endif diff -ruN exercises/exercise-basic/params.input exercises/solution/exercise-basic/params.input ---- exercises/exercise-basic/params.input 2024-07-08 09:06:59.581159992 +0200 -+++ exercises/solution/exercise-basic/params.input 2024-07-08 09:06:59.613159864 +0200 +--- exercises/exercise-basic/params.input 2023-03-31 13:48:56.158686713 +0200 ++++ exercises/solution/exercise-basic/params.input 2024-07-08 11:41:07.994134860 +0200 @@ -1,6 +1,6 @@ [TimeLoop] DtInitial = 3600 # in seconds @@ -1118,90 +723,8 @@ diff -ruN exercises/exercise-basic/params.input exercises/solution/exercise-basi +SolidDensity = 2700 # solid density of granite +SolidThermalConductivity = 2.8 # solid thermal conducitivity of granite +SolidHeatCapacity = 790 # solid heat capacity of granite -diff -ruN exercises/exercise-basic/properties2p2c.hh exercises/solution/exercise-basic/properties2p2c.hh ---- exercises/exercise-basic/properties2p2c.hh 2024-07-08 09:06:59.581159992 +0200 -+++ exercises/solution/exercise-basic/properties2p2c.hh 1970-01-01 01:00:00.000000000 +0100 -@@ -1,78 +0,0 @@ --// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- --// vi: set et ts=4 sw=4 sts=4: --/***************************************************************************** -- * See the file COPYING for full copying permissions. * -- * * -- * This program is free software: you can redistribute it and/or modify * -- * it under the terms of the GNU General Public License as published by * -- * the Free Software Foundation, either version 3 of the License, or * -- * (at your option) any later version. * -- * * -- * This program is distributed in the hope that it will be useful, * -- * but WITHOUT ANY WARRANTY; without even the implied warranty of * -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -- * GNU General Public License for more details. * -- * * -- * You should have received a copy of the GNU General Public License * -- * along with this program. If not, see <http://www.gnu.org/licenses/>. * -- *****************************************************************************/ --/*! -- * \file -- * -- * \brief The two-phase two-component porousmediumflow properties file for exercise-basic -- */ -- --#ifndef DUMUX_EX_BASIC_PROPERTIES_2P2C_HH --#define DUMUX_EX_BASIC_PROPERTIES_2P2C_HH -- --#include <dune/grid/yaspgrid.hh> -- --#include <dumux/discretization/cctpfa.hh> --#include <dumux/porousmediumflow/2p2c/model.hh> --#include <dumux/material/fluidsystems/h2on2.hh> -- --#include "injection2p2cproblem.hh" --#include "injection2pspatialparams.hh" -- --namespace Dumux::Properties { -- --// Create new type tags --namespace TTag { --struct Injection2p2c { using InheritsFrom = std::tuple<TwoPTwoC>; }; --struct Injection2p2cCC { using InheritsFrom = std::tuple<Injection2p2c, CCTpfaModel>; }; --} // end namespace TTag -- --// Set the grid type --template<class TypeTag> --struct Grid<TypeTag, TTag::Injection2p2c> { using type = Dune::YaspGrid<2>; }; -- --// Set the problem property --template<class TypeTag> --struct Problem<TypeTag, TTag::Injection2p2c> { using type = Injection2p2cProblem<TypeTag>; }; -- --// Set the spatial parameters --template<class TypeTag> --struct SpatialParams<TypeTag, TTag::Injection2p2c> --{ --private: -- using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; -- using Scalar = GetPropType<TypeTag, Properties::Scalar>; --public: -- using type = InjectionSpatialParams<GridGeometry, Scalar>; --}; -- --// Set fluid configuration --template<class TypeTag> --struct FluidSystem<TypeTag, TTag::Injection2p2c> --{ -- using type = FluidSystems::H2ON2< GetPropType<TypeTag, Properties::Scalar>, -- FluidSystems::H2ON2DefaultPolicy</*fastButSimplifiedRelations=*/ true> >; --}; -- --// Define whether mole (true) or mass (false) fractions are used --template<class TypeTag> --struct UseMoles<TypeTag, TTag::Injection2p2c> { static constexpr bool value = true; }; -- --} // end namespace Dumux::Properties -- --#endif diff -ruN exercises/exercise-basic/properties2p.hh exercises/solution/exercise-basic/properties2p.hh ---- exercises/exercise-basic/properties2p.hh 2024-07-08 09:06:59.581159992 +0200 +--- exercises/exercise-basic/properties2p.hh 2024-07-08 11:41:07.986134888 +0200 +++ exercises/solution/exercise-basic/properties2p.hh 1970-01-01 01:00:00.000000000 +0100 @@ -1,75 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- @@ -1280,8 +803,8 @@ diff -ruN exercises/exercise-basic/properties2p.hh exercises/solution/exercise-b - -#endif diff -ruN exercises/exercise-basic/properties2pni.hh exercises/solution/exercise-basic/properties2pni.hh ---- exercises/exercise-basic/properties2pni.hh 2024-07-08 09:06:59.581159992 +0200 -+++ exercises/solution/exercise-basic/properties2pni.hh 2024-07-08 09:06:59.613159864 +0200 +--- exercises/exercise-basic/properties2pni.hh 2024-07-08 11:41:07.986134888 +0200 ++++ exercises/solution/exercise-basic/properties2pni.hh 2024-07-08 11:41:07.994134860 +0200 @@ -31,18 +31,14 @@ #include <dumux/porousmediumflow/2p/model.hh> #include <dumux/material/fluidsystems/h2on2.hh> @@ -1315,9 +838,9 @@ diff -ruN exercises/exercise-basic/properties2pni.hh exercises/solution/exercise } // end namespace Dumux::Properties diff -ruN exercises/exercise-basic/README.md exercises/solution/exercise-basic/README.md ---- exercises/exercise-basic/README.md 2024-07-16 16:55:12.734099365 +0200 +--- exercises/exercise-basic/README.md 2024-07-16 17:38:07.971854664 +0200 +++ exercises/solution/exercise-basic/README.md 1970-01-01 01:00:00.000000000 +0100 -@@ -1,105 +0,0 @@ +@@ -1,103 +0,0 @@ -# Exercise Basics (DuMuX course) -<br> - @@ -1332,7 +855,7 @@ diff -ruN exercises/exercise-basic/README.md exercises/solution/exercise-basic/R - -* Navigate to the directory `dumux-course/exercises/exercise-basic` - --This exercise deals with two problems: a two-phase immiscible problem (__2p__) and a two-phase compositional problem (__2p2c__). They both set up the same scenario with the difference that the 2p2c assumes a miscible fluid state for the two fluids (water and gaseous N$_2$) and the 2p model assumes an immiscible fluid state. +-This exercise deals with two problems: a two-phase immiscible problem (__2p__) and a two-phase non-isothermal problem (__2pni__). They both set up the same scenario with the difference that the 2pni model introduces an extra energy equation. - -<br><br> -### Task 1: Getting familiar with the code @@ -1340,11 +863,10 @@ diff -ruN exercises/exercise-basic/README.md exercises/solution/exercise-basic/R - -Locate all the files you will need for this exercise -* The __main file__ for the __2p__ problem : `2pmain.cc` --* The __main file__ for the __2p2c__ problem : `2p2cmain.cc` -* The __problem file__ for the __2p__ problem: `injection2pproblem.hh` --* The __problem file__ for the __2p2c__ problem: `injection2p2cproblem.hh` +-* The __problem file__ for the __2pni__ problem: `injection2pniproblem.hh` -* The __properties file__ for the __2p__ problem: `properties2p.hh` --* The __properties file__ for the __2p2c__ problem: `properties2p2c.hh` +-* The __properties file__ for the __2pni__ problem: `properties2pni.hh` -* The shared __spatial parameters file__: `injection2pspatialparams.hh` -* The shared __input file__: `params.input` - @@ -1358,23 +880,22 @@ diff -ruN exercises/exercise-basic/README.md exercises/solution/exercise-basic/R -cd ../../build-cmake/exercises/exercise-basic -``` - --* Compile both executables `exercise_basic_2p` and `exercise_basic_2p2c` +-* Compile the executable `exercise_basic_2p` - -```bash --make exercise_basic_2p exercise_basic_2p2c +-make exercise_basic_2p -``` - --* Execute the two problems and inspect the result +-* Execute the problem and inspect the result - -```bash -./exercise_basic_2p params.input --./exercise_basic_2p2c params.input -``` - -* you can look at the results with paraview - -```bash --paraview injection-2p2c.pvd +-paraview injection-2p.pvd -``` - -<br><br> @@ -1392,7 +913,7 @@ diff -ruN exercises/exercise-basic/README.md exercises/solution/exercise-basic/R - SOURCES 2pnimain.cc) -``` - --* Test that everything compiles without error +-* In the respective build-cmake folder, test that everything compiles without error - -```bash -make # should rerun cmake @@ -1413,14 +934,14 @@ diff -ruN exercises/exercise-basic/README.md exercises/solution/exercise-basic/R - -* The following set-up should be realized: - -- __Boundary conditions:__ Dirichlet conditions at the left boundary. For the primary variable __temperature__ use a varying temperature of <br/> +- __Initial conditions:__ For the primary variable __temperature__ use a varying temperature of <br/> -$`\displaystyle T(y) = 283~\text{K} + 0.03~\frac{\text{K}}{\text{m}} \cdot \left( d_\text{aquifer} - y \right)`$, <br/> -with the aquifer depth --$\displaystyle d_\text{aquifer}=2700~\text{m}$. Add an energy flux at the injection point of N$_2$. Assign Neumann no-flow for the energy balance to the rest of the boundaries. +-$\displaystyle d_\text{aquifer}=2700~\text{m}$. Additionally, add a subdomain (20 < x < 30, 5 < y < 35), where you assign a constant initial temperature of 380 K. - -- __Initial conditions:__ The same temperature gradient as in the boundary conditions with an exception in the subdomain (20 < x < 30, 5 < y < 35), where you assign a constant initial temperature of 380 K. +- __Boundary conditions:__ Dirichlet boundary conditions at the left boundary with the same temperature gradient as in the initial conditions. For the Neumann conditions, assign an energy flux at the injection point of N$_2$ and no-flow conditions for the energy balance to the rest of the boundaries. - -<img src="https://git.iws.uni-stuttgart.de/dumux-repositories/dumux-course/raw/master/exercises/extradoc/exercise1_nonisothermal.png" width="800"> - -The non-isothermal model requires additional parameters like the thermal conductivity of the solid component. They are already implemented and set in `params.input`, you just need to _uncomment_ them. -\ Kein Zeilenumbruch am Dateiende. +\ No newline at end of file