Commit 7b29f2bd by Farid Mohammadi Committed by Katharina Heck

image
parent 35cf0e4d
 ... ... @@ -25,6 +25,7 @@ The following resources are useful to get started with DuMux: * [Handbook](https://dumux.org/handbook), a detailed DuMux manual, * [DuMux course materials](https://git.iws.uni-stuttgart.de/dumux-repositories/dumux-course/tree/master), * [Examples](https://git.iws.uni-stuttgart.de/dumux-repositories/dumux/tree/feature/documented-tutorials/examples), with detailed description of code and results, * [Class documentation](https://dumux.org/classdocumentation) generated from the source code, * [Mailing list](https://listserv.uni-stuttgart.de/mailman/listinfo/dumux), * [Changelog](https://git.iws.uni-stuttgart.de/dumux-repositories/dumux/blob/master/CHANGELOG.md), where all changes between different release versions are listed and explained. ... ...
This diff is collapsed.
 ... ... @@ -5,8 +5,8 @@ This tutorial was copied from dumux/test/porousmediumflow/tracer/1ptracer. ## Problem set-up This example contains a contaminant transported by a base groundwater flow in a randomly distributed permeability field. The figure below shows the simulation set-up. The permeability values range between 6.12e-15 and 1.5 e-7 $m^2$. A pressure gradient between the top an the bottom boundary leads to a groundwater flux from the bottom to the top. Neumann no-flow boundaries are assigned to the left and right boundary. Initially, there is a contaminant concentration at the bottom of the domain. ![](./img/setup.png) ## Model description Two different models are applied to simulate the system: In a first step, the groundwater velocity is evaluated under stationary conditions. Therefore the single phase model is applied. In a second step, the contaminant gets transported based on the groundwater velocity field. It is assumed, that the dissolved contaminant does not affect density and viscosity of the groundwater and thus, it is handled as a tracer by the tracer model. The tracer model is then solved instationarily. ... ... @@ -14,30 +14,36 @@ In a second step, the contaminant gets transported based on the groundwater velo ### 1p Model The single phase model uses Darcy's law as the equation for the momentum conservation: $ \textbf v = - \frac{\textbf K}{\mu} \left(\textbf{grad}\, p - \varrho {\textbf g} \right) $ math \textbf v = - \frac{\textbf K}{\mu} \left(\textbf{grad}\, p - \varrho {\textbf g} \right)  With the darcy velocity $ \textbf v $, the permeability $ \textbf K$, the dynamic viscosity $ \mu$, the pressure $p$, the density $\rho$ and the gravity $\textbf g$. Darcy's law is inserted into the continuity equation: $ \phi \frac{\partial \varrho}{\partial t} + \text{div} \textbf v = 0$ math \phi \frac{\partial \varrho}{\partial t} + \text{div} \textbf v = 0  with porosity $\phi$. The equation is discretized using a cell-centered finite volume scheme as spatial discretization for the pressure as primary variable. For details on the discretization scheme, have a look at the dumux handbook. The equation is discretized using a cell-centered finite volume scheme as spatial discretization for the pressure as primary variable. For details on the discretization scheme, have a look at the dumux [handbook](https://dumux.org/handbook). ### Tracer Model The transport of the contaminant component $\kappa$ is based on the previously evaluated velocity field $\textbf v$ with the help the following mass balance equation: $ \phi \frac{ \partial X^\kappa}{\partial t} - \text{div} \left\lbrace X^\kappa {\textbf v}+ D^\kappa_\text{pm} \frac{M^\kappa}{M_\alpha} \textbf{grad} x^\kappa \right\rbrace = 0 $ math \phi \frac{ \partial X^\kappa}{\partial t} - \text{div} \left\lbrace X^\kappa {\textbf v}+ D^\kappa_\text{pm} \frac{M^\kappa}{M_\alpha} \textbf{grad} x^\kappa \right\rbrace = 0  With the porosity $\phi$, the mass fraction of the contaminant component $\kappa$: $X^\kappa$, the binary diffusion coefficient in the porous medium $ D^\kappa_\text{pm} $, the molar masses of the component $ M^\kappa $, the average molar mass of the phase $M_\alpha$ and the mole fraction $x$. With the porosity $\phi$, the mass fraction of the contaminant component $\kappa$: $X^\kappa$, the porous medium diffusivity $ D^\kappa_\text{pm} $, the molar masses of the component $ M^\kappa $, the average molar mass of the phase $M_\alpha$ and the mole fraction $x$. The porous medium diffusivity is yield out of the diffusion coefficient of the component, the porosity $\phi $ and the porous medium tortuosity $\tau$ by the following equation: The porous medium diffusivity is a function of the diffusion coefficient of the component $D^\kappa$, the porosity $\phi$ and the porous medium tortuosity $\tau$ by the following equation: $ math D^\kappa_\text{pm}= \phi \tau D^\kappa $  The primary variable of this model is the mass fraction $X^\kappa$. We apply the same spatial discretization as in the single pahse model and use the implicit Euler method for time discretization. For more information, have a look at the dumux handbook. ... ...
 ## Results The 1p-model calculated a stationary pressure distribution. It is shown in the following figure: ![](./img/pressure.png) The random permeability distribution generates the velocity profile shown in the left plot of the next figure. The image in the middle illustrates the tracer distribution after 2500s and the image on the right after 5000s. ... ...
This diff is collapsed.
 ... ... @@ -21,11 +21,11 @@ // ### Includes #include // We include both problems in the main file, the problem_1p.hh and the problem_tracer.hh. // We include both problems in the main file, the problem_1p.hh and the problem_tracer.hh. #include "problem_1p.hh" #include "problem_tracer.hh" // Further we include a standard header file for C++, to get time and date information // Further, we include a standard header file for C++, to get time and date information #include // and another one for in- and output. #include ... ... @@ -36,11 +36,11 @@ #include #include // In Dumux a property system is used to specify the model. For this, different properties are defined containing type definitions, values and methods. All properties are declared in the file properties.hh. // In Dumux, a property system is used to specify the model. For this, different properties are defined containing type definitions, values and methods. All properties are declared in the file properties.hh. #include // The following file contains the parameter class, which manages the definition of input parameters by a default value, the inputfile or the command line. #include // The file dumuxmessage.hh contains the class defining the start and end message of the simulation. // The file dumuxmessage.hh contains the class defining the start and end message of the simulation. #include // The following file contains the class, which defines the sequential linear solver backends. ... ... @@ -95,7 +95,7 @@ int main(int argc, char** argv) try using OnePProblem = GetPropType; auto problemOneP = std::make_shared(fvGridGeometry); // The jacobian matrix A, the solution vector p and the residual r are parts of the linear system. // The jacobian matrix (A), the solution vector (p) and the residual (r) are parts of the linear system. using JacobianMatrix = GetPropType; using SolutionVector = GetPropType; SolutionVector p(leafGridView.size(0)); ... ... @@ -114,17 +114,17 @@ int main(int argc, char** argv) try auto assemblerOneP = std::make_shared(problemOneP, fvGridGeometry, onePGridVariables); assemblerOneP->setLinearSystem(A, r); // We assemble the local jacobian and the residual and stop the time needed, which is displayed in the terminal output, using the assemblyTimer. Further, we start the timer to evaluate the total time of the assembly, solving and updating. // We assemble the local jacobian and the residual and stop the time needed, which is displayed in the terminal output, using the assemblyTimer. Further, we start the timer to evaluate the total time of the assembly, solving and updating. Dune::Timer timer; Dune::Timer assemblyTimer; std::cout << "Assembling linear system ..." << std::flush; assemblerOneP->assembleJacobianAndResidual(p); assemblyTimer.stop(); std::cout << " took " << assemblyTimer.elapsed() << " seconds." << std::endl; // We want to solve Ax = -r. // We want to solve Ax = -r. (*r) *= -1.0; // #### Solution // We set the linear solver "UMFPack" as the linear solver. Afterwards we solve the linear system. The time needed to solve the system is recorded by the solverTimer and displayed in the terminal output. // We set the linear solver "UMFPack" as the linear solver. Afterwards we solve the linear system. The time needed to solve the system is recorded by the solverTimer and displayed in the terminal output. using LinearSolver = UMFPackBackend; Dune::Timer solverTimer; std::cout << "Solving linear system ..." << std::flush; auto linearSolver = std::make_shared(); ... ... @@ -138,7 +138,7 @@ int main(int argc, char** argv) try updateTimer.elapsed(); std::cout << " took " << updateTimer.elapsed() << std::endl; // We initialize the vtkoutput. Each model has a predefined model specific output with relevant parameters for that model. We add the pressure data from the solution vector p and the permeability field as output data. // We initialize the vtkoutput. Each model has a predefined model specific output with relevant parameters for that model. We add the pressure data from the solution vector (p) and the permeability field as output data. using GridView = GetPropType; Dune::VTKWriter onepWriter(leafGridView); onepWriter.addCellData(p, "p"); ... ... @@ -221,7 +221,7 @@ int main(int argc, char** argv) try auto gridVariables = std::make_shared(tracerProblem, fvGridGeometry); gridVariables->init(x); // We read in some time loop parameters from the input file. The parameter tEnd defines the duration of the simulation, dt the initial time step size and maxDt the maximal time step size. // We read in some time loop parameters from the input file. The parameter tEnd defines the duration of the simulation, dt the initial time step size and maxDt the maximal time step size. const auto tEnd = getParam("TimeLoop.TEnd"); auto dt = getParam("TimeLoop.DtInitial"); const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); ... ... @@ -248,7 +248,7 @@ int main(int argc, char** argv) try timeLoop->setPeriodicCheckPoint(tEnd/10.0); // #### The time loop // We start the time loop and calculate a new time step as long as tEnd is not reached. In every single time step the problem is assembled and solved. // We start the time loop and calculate a new time step as long as tEnd is not reached. In every single time step, the problem is assembled and solved. timeLoop->start(); do { // First we define the old solution as the solution of the previous time step for storage evaluations. ... ... @@ -259,7 +259,7 @@ int main(int argc, char** argv) try assembler->assembleJacobianAndResidual(x); assembleTimer.stop(); // We solve the linear system A(xOld-xNew) = r. // We solve the linear system A(xOld-xNew) = r. Dune::Timer solveTimer; SolutionVector xDelta(x); linearSolver->solve(*A, xDelta, *r); ... ...
 ... ... @@ -54,8 +54,7 @@ class OnePTestProblem; // We enter the namespace Properties, which is a sub-namespace of the namespace Dumux: namespace Properties { // A TypeTag for our simulation is created which inherits from the one-phase flow model and the // cell centered, two-point-flux discretization scheme. // A TypeTag for our simulation is created which inherits from the one-phase flow model and the cell centered, two-point-flux discretization scheme. namespace TTag { struct IncompressibleTest { using InheritsFrom = std::tuple; }; } ... ... @@ -72,10 +71,10 @@ struct Problem { using type = OnePTestProblem template struct SpatialParams { // We define convenient shortcuts to the properties FVGridGeometry and Scalar: // We define convenient shortcuts to the properties FVGridGeometry and Scalar: using FVGridGeometry = GetPropType; using Scalar = GetPropType; // Finally we set the spatial parameters: // Finally, we set the spatial parameters: using type = OnePTestSpatialParams; }; ... ... @@ -94,10 +93,10 @@ struct FluidSystem using type = FluidSystems::OnePLiquid >; }; // We enable caching for the grid volume variables // We enable caching for the grid volume variables. template struct EnableGridVolumeVariablesCache { static constexpr bool value = true; }; // We enable caching for the grid flux variables // We enable caching for the grid flux variables. template struct EnableGridFluxVariablesCache { static constexpr bool value = true; }; // We enable caching for the FV grid geometry ... ... @@ -109,7 +108,7 @@ struct EnableFVGridGeometryCache { static con // ### The problem class // We enter the problem class where all necessary boundary conditions and initial conditions are set for our simulation. // As this is a porous medium problem, we inherit from the basic PorousMediumFlowProblem. // As this is a porous medium problem, we inherit from the basic PorousMediumFlowProblem. template class OnePTestProblem : public PorousMediumFlowProblem { ... ...
 ... ... @@ -23,7 +23,7 @@ //Before we enter the problem class containing initial and boundary conditions, we include necessary files and introduce properties. // ### Include files // Again, we have to include the dune grid interphase: // Again, we have to include the dune grid interface: #include // and the cell centered, two-point-flux discretization. #include ... ... @@ -46,7 +46,7 @@ class TracerTestProblem; // We enter the namespace Properties, namespace Properties { // A TypeTag for our simulation is created which inherits from the tracer model and the // A TypeTag for our simulation is created which inherits from the tracer model and the // cell centered, two-point-flux discretization scheme. namespace TTag { struct TracerTest { using InheritsFrom = std::tuple; }; ... ... @@ -81,17 +81,17 @@ struct SpatialParams // We define that mass fractions are used to define the concentrations template struct UseMoles { static constexpr bool value = false; }; // We don't use a solution dependent molecular diffusion coefficient: // We do not use a solution dependent molecular diffusion coefficient: template struct SolutionDependentMolecularDiffusion { static constexpr bool value = false; }; // In the following we create a new tracer fluid system and derive it from the base fluid system. // In the following, we create a new tracer fluid system and derive it from the base fluid system. template class TracerFluidSystem : public FluidSystems::Base, TracerFluidSystem> { // We define convenient shortcuts to the properties Scalar, Problem, GridView, // Element, FVElementGeometry and SubControlVolume: // We define convenient shortcuts to the properties Scalar, Problem, GridView, // Element, FVElementGeometry and SubControlVolume: using Scalar = GetPropType; using Problem = GetPropType; using GridView = GetPropType; ... ... @@ -111,19 +111,19 @@ public: // and the number of components static constexpr int numComponents = 1; // We set the component name for the component index (compIdx) for the vtk output: // We set the component name for the component index (compIdx) for the vtk output: static std::string componentName(int compIdx) { return "tracer_" + std::to_string(compIdx); } //We set the phase name for the phase index (phaseIdx) for velocity vtk output: //We set the phase name for the phase index (phaseIdx) for velocity vtk output: static std::string phaseName(int phaseIdx = 0) { return "Groundwater"; } // We set the molar mass of the tracer component with index compIdx // We set the molar mass of the tracer component with index compIdx. static Scalar molarMass(unsigned int compIdx) { return 0.300; } // And we set the value for the binary diffusion coefficient. This // We set the value for the binary diffusion coefficient. This // might depend on spatial parameters like pressure / temperature. But for our case it is 0.0: static Scalar binaryDiffusionCoefficient(unsigned int compIdx, const Problem& problem, ... ... @@ -142,7 +142,7 @@ struct FluidSystem { using type = TracerFluidSystem class TracerTestProblem : public PorousMediumFlowProblem { ... ...
 ... ... @@ -21,10 +21,10 @@ #ifndef DUMUX_INCOMPRESSIBLE_ONEP_TEST_SPATIAL_PARAMS_HH #define DUMUX_INCOMPRESSIBLE_ONEP_TEST_SPATIAL_PARAMS_HH // In this file we generate the random permeability field in the constructor of the OnePTestSpatialParams class. Thereafter spatial properties of the porous medium like permeability and porosity are defined in various functions for the 1p problem. // We want to generate a random permeability field. For this we use a random number generation of the C++ standard library. // In this file, we generate the random permeability field in the constructor of the OnePTestSpatialParams class. Thereafter, spatial properties of the porous medium such as the permeability and the porosity are defined in various functions for the 1p problem. // We want to generate a random permeability field. For this, we use a random number generation of the C++ standard library. #include // In the file properties.hh all properties are declared. // In the file properties.hh all properties are declared. #include // We include the spatial parameters for single-phase, finite volumes from which we will inherit. ... ... @@ -32,14 +32,14 @@ namespace Dumux { // In the OnePTestSpatialParams class, we define all functions needed to describe the porous matrix, e.g. define porosity and permeability for the 1p_problem. // In the OnePTestSpatialParams class, we define all functions needed to describe the porous matrix, e.g. porosity and permeability for the 1p_problem. template class OnePTestSpatialParams : public FVSpatialParamsOneP> { // We introduce using declarations that are derived from the property system which we need in this class. // We introduce using declarations that are derived from the property system, which we need in this class. using GridView = typename FVGridGeometry::GridView; using FVElementGeometry = typename FVGridGeometry::LocalView; using SubControlVolume = typename FVElementGeometry::SubControlVolume; ... ... @@ -56,7 +56,7 @@ public: : ParentType(fvGridGeometry), K_(fvGridGeometry->gridView().size(0), 0.0) { // ### Generation of the random permeability field // We get the permeability of the domain and the lens from the params.input file. // We get the permeability of the domain and the lens from the params.input file. permeability_ = getParam("SpatialParams.Permeability"); permeabilityLens_ = getParam("SpatialParams.PermeabilityLens"); ... ... @@ -64,7 +64,7 @@ public: lensLowerLeft_ = getParam("SpatialParams.LensLowerLeft"); lensUpperRight_ =getParam("SpatialParams.LensUpperRight"); // We generate random fields for the permeability using a lognormal distribution, with the permeability_ as mean value and 10 % of it as standard deviation. A seperate distribution is used for the lens using permeabilityLens_. // We generate random fields for the permeability using a lognormal distribution, with the permeability_ as mean value and 10 % of it as standard deviation. A seperate distribution is used for the lens using permeabilityLens_. std::mt19937 rand(0); std::lognormal_distribution K(std::log(permeability_), std::log(permeability_)*0.1); std::lognormal_distribution KLens(std::log(permeabilityLens_), std::log(permeabilityLens_)*0.1); ... ... @@ -96,7 +96,7 @@ public: { return K_; } private: // We have a convenience definition of the position of the lens. // We have a convenient definition of the position of the lens. bool isInLens_(const GlobalPosition &globalPos) const { for (int i = 0; i < dimWorld; ++i) { ... ...
 ... ... @@ -23,15 +23,15 @@ #ifndef DUMUX_TRACER_TEST_SPATIAL_PARAMS_HH #define DUMUX_TRACER_TEST_SPATIAL_PARAMS_HH // In this file we define spatial properties of the porous medium like permeability and porosity in various functions for the tracer problem. Further spatial dependent properties of the tracer fluid system are defined and in the end two functions handel the calculated volume fluxes from the solution of the 1p problem. // In the file properties.hh all properties are declared. // In this file, we define spatial properties of the porous medium such as the permeability and the porosity in various functions for the tracer problem. Further, spatial dependent properties of the tracer fluid system are defined and in the end two functions handel the calculated volume fluxes from the solution of the 1p problem. // In the file properties.hh, all properties are declared. #include // As in the 1p spatialparams we inherit from the spatial parameters for single-phase, finite volumes, which we include here. // As in the 1p spatialparams, we inherit from the spatial parameters for single-phase, finite volumes, which we include here. #include // We enter the namespace Dumux namespace Dumux { // In the TracerTestSpatialParams class, we define all functions needed to describe spatially dependent parameters for the tracer_problem. // In the TracerTestSpatialParams class, we define all functions needed to describe spatially dependent parameters for the tracer_problem. template class TracerTestSpatialParams ... ... @@ -59,7 +59,7 @@ public: Scalar porosityAtPos(const GlobalPosition& globalPos) const { return 0.2; } // We don't consider dispersivity for the tracer transport. So we set the dispersivity coefficient to zero. // We do not consider dispersivity for the tracer transport. So we set the dispersivity coefficient to zero. template Scalar dispersivity(const Element &element, const SubControlVolume& scv, ... ... @@ -67,7 +67,7 @@ public: { return 0; } // ### Properties of the fluid system // In the following we define fluid properties that are spatial parameters in the tracer model. They can possible vary with space but are usually constants. Further spatially constant values of the fluid system are defined in the TracerFluidSystem class in problem.hh. // In the following, we define fluid properties that are spatial parameters in the tracer model. They can possible vary with space but are usually constants. Further spatially constant values of the fluid system are defined in the TracerFluidSystem class in problem.hh. // We define the fluid density to a constant value of 1000 $\frac{kg}{m^3}$. Scalar fluidDensity(const Element &element, const SubControlVolume& scv) const ... ...
 ... ... @@ -13,7 +13,7 @@ To describe that problem we use a two phase model of two immiscible fluids with \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} {\textbf g} \right)  If we insert this into the conservation equations for each phase $$\alpha$$ that leads to: If we insert this into the conservation equations for each phase $\alpha$ that leads to: math \phi \frac{\partial \varrho_\alpha S_\alpha}{\partial t} ... ... @@ -38,7 +38,7 @@ DNAPL enters the model domain at the upper boundary between 1.75m ≤ x ≤ 2m w In addition, the DNAPL is injected at a point source at x = 0.502 and y = 3.02 with a rate of 0.1 kg/s. ## Discretization We descritize the equations with a cell-centered finete volume TPFA scheme in space and an implicit Euler scheme in time. We use Newton's method to solve the system of nonlinear equations. For more information about the discretization please have a look at the handbook. We discretize the equations with a cell-centered finite volume TPFA scheme in space and an implicit Euler scheme in time. We use Newton's method to solve the system of nonlinear equations. For more information about the discretization please have a look at the [handbook](https://dumux.org/handbook). ## Adaptive grid The grid is adapitvely refined around the injection. The adaptive behaviour can be changed with input parameters in the params.input file. ... ... @@ -60,7 +60,7 @@ we include all laws which are needed to define the interaction between the solid namespace Dumux {  In the TwoPTestSpatialParams class we define all functions needed to describe the porous matrix, e.g. defines porosity and permeability In the TwoPTestSpatialParams class we define all functions needed to describe the porous matrix, e.g. porosity and permeability cpp template ... ... @@ -96,7 +96,7 @@ we get the position of the lens from the params.input file. The lens is defined lensLowerLeft_ = getParam("SpatialParams.LensLowerLeft"); lensUpperRight_ = getParam("SpatialParams.LensUpperRight");  we set the parameters for the material law (here Van-Genuchten Law). First we set the residual saturations for the wetting phase and the non-wetting phase. lensMaterialParams_ are the material parameters define the material parameters for the lens while outerMaterialParams_ define material marams for the rest of the domain we set the parameters for the material law (here Van-Genuchten Law). First we set the residual saturations for the wetting phase and the non-wetting phase. lensMaterialParams_ define the material parameters for the lens while outerMaterialParams_ define material params for the rest of the domain. cpp lensMaterialParams_.setSwr(0.18); lensMaterialParams_.setSnr(0.0); ... ... @@ -116,7 +116,7 @@ here we get the permeabilities from the params.input file. In case that no param outerK_ = getParam("SpatialParams.outerK", 4.6e-10); }  We define the (intrinsic) permeability \f$[m^2]\f$. In this test, we use element-wise distributed permeabilities. We define the (intrinsic) permeability $[m^2]$. In this test, we use element-wise distributed permeabilities. cpp template PermeabilityType permeability(const Element& element, ... ... @@ -128,7 +128,7 @@ We define the (intrinsic) permeability \f$[m^2]\f$. In this test, we use element return outerK_; }  We set the porosity \f$[-]\f$ depending on the position We set the porosity $[-]$ depending on the position cpp Scalar porosityAtPos(const GlobalPosition& globalPos) const { ... ... @@ -429,7 +429,7 @@ The saturation of the DNAPL Trichlorethene is zero on our Dirichlet boundary:  Third, we specify the values for the Neumann boundaries. In our case, we need to specify mass fluxes for our two liquid phases. Inflow is denoted by a negative sign, outflow by a positive sign. The inflow is denoted by a negative sign, and the outflow by a positive sign. cpp NumEqVector neumannAtPos(const GlobalPosition &globalPos) const { ... ... @@ -439,7 +439,7 @@ We initialize the fluxes with zero: NumEqVector values(0.0);  At the inlet, we specify an inflow for our DNAPL Trichlorethene. The units are kg/(m^2 s). The units are $kg/(m^2 s)$. cpp if (onInlet_(globalPos)) values[contiDNAPLEqIdx] = -0.04; ... ... @@ -447,7 +447,7 @@ The units are kg/(m^2 s). return values; }  Last, we specify the initial conditions. The initial condition need to be set for all primary variables. Last, we specify the initial conditions. The initial condition needs to be set for all primary variables. Here, we take the data from the file that we read in previously. cpp PrimaryVariables initial(const Element& element) const ... ... @@ -475,7 +475,7 @@ Fluid properties that depend on temperature will be calculated with this value.  Additionally, we set a point source. The point source can be solution dependent. It is specified in form of a vector that contains source values for alle phases and positions in space. The first entry is a tupel containing the position in space, the second entry contains a tupel with the source (unit kg/s) The first entry is a tuple containing the position in space, the second entry contains a tuple with the source (with the unit of $kg/s$) for the phases (first phase is the water phase, the second phase is the DNAPL Trichlorethene phase). cpp void addPointSources(std::vector& pointSources) const ... ... @@ -529,9 +529,7 @@ We leave the namespace Dumux here, too. ## The file main.cc ## The main file This is the main file for the 2pinfiltration example. Here we can see the programme sequence and how the system is solved using newton's method cpp  This is the main file for the 2pinfiltration example. Here we can see the programme sequence and how the system is solved using Newton's method ### Includes cpp #include ... ... @@ -553,7 +551,7 @@ Dumux is based on DUNE, the Distributed and Unified Numerics Environment, which #include #include  In Dumux a property system is used to specify the model. For this, different properties are defined containing type definitions, values and methods. All properties are declared in the file properties.hh. In Dumux, a property system is used to specify the model. For this, different properties are defined containing type definitions, values and methods. All properties are declared in the file properties.hh. cpp #include  ... ... @@ -570,11 +568,11 @@ we include the linear solver to be used to solve the linear system cpp #include  we include the nonlinear newtons method we include the nonlinear Newton's method cpp #include  Further we include assembler, which assembles the linear systems for finite volume schemes (box-scheme, tpfa-approximation, mpfa-approximation). Further, we include assembler, which assembles the linear systems for finite volume schemes (box-scheme, tpfa-approximation, mpfa-approximation). cpp #include  ... ... @@ -594,7 +592,7 @@ The gridmanager constructs a grid from the information in the input or grid file cpp #include  we include several files which are needed for the adaptive grid We include several files which are needed for the adaptive grid cpp #include #include ... ... @@ -602,7 +600,7 @@ we include several files which are needed for the adaptive grid #include #include  we include the problem file which defines initial and boundary conditions to describe our example problem We include the problem file which defines initial and boundary conditions to describe our example problem cpp #include "problem.hh"  ... ... @@ -630,29 +628,22 @@ We parse command line arguments and input file Parameters::init(argc, argv);  ### Create the grid cpp  A gridmanager tries to create the grid either from a grid file or the input file. cpp GridManager> gridManager; gridManager.init();  ////////////////////////////////////////////////////////// run instationary non-linear problem on this grid ////////////////////////////////////////////////////////// cpp  The instationary non-linear problem is run on this grid. we compute on the leaf grid view cpp const auto& leafGridView = gridManager.grid().leafGridView();  ### Setup and solving of the problem cpp  #### Setup We create and initialize the finite volume grid geometry, the problem, the linear system, including the jacobian matrix, the residual and the solution vector and the gridvariables. cpp  We need the finite volume geometry to build up the subcontrolvolumes (scv) and subcontrolvolume faces (scvf) for each element of the grid partition. cpp using FVGridGeometry = GetPropType; ... ... @@ -664,42 +655,42 @@ In the problem, we define the boundary and initial conditions. using Problem = GetPropType; auto problem = std::make_shared(fvGridGeometry);  We call the computePointSourceMap method to compute the point sources. The computePointSourceMap method is inherited from the fvproblem and therefore specified in the dumux/common/fvproblem.hh. It calls the addPointSources method specified in the problem.hh file We call the computePointSourceMap method to compute the point sources. The computePointSourceMap method is inherited from the fvproblem and therefore specified in the dumux/common/fvproblem.hh. It calls the addPointSources method specified in the problem.hh file. cpp problem->computePointSourceMap();  we initialize the solution vector We initialize the solution vector, cpp using SolutionVector = GetPropType; SolutionVector x(fvGridGeometry->numDofs()); problem->applyInitialSolution(x); auto xOld = x;  and then use the solutionvector to intialize the gridVariables and then use the solution vector to intialize the gridVariables. cpp using GridVariables = GetPropType; auto gridVariables = std::make_shared(problem, fvGridGeometry); gridVariables->init(x);  we instantiate the indicator for grid adaption & the data transfer, we read some parameters for indicator from the input file We instantiate the indicator for grid adaption & the data transfer, we read some parameters for indicator from the input file. cpp using Scalar = GetPropType; const Scalar refineTol = getParam("Adaptive.RefineTolerance"); const Scalar coarsenTol = getParam("Adaptive.CoarsenTolerance");  We use an indicator for a two-phase flow problem that is saturation-dependent and defined in the file dumux/porousmediumflow/2p/gridadaptindicator.hh. It allows to set the minimum and maximum allowed refinement levels via the input parameters We use an indicator for a two-phase flow problem that is saturation-dependent and defined in the file dumux/porousmediumflow/2p/gridadaptindicator.hh. It allows to set the minimum and maximum allowed refinement levels via the input parameters. cpp TwoPGridAdaptIndicator indicator(fvGridGeometry);  The data transfer performs the transfer of data on a grid from before to after adaptation and is defined in the file dumux/porousmediumflow/2p/griddatatransfer.hh. Its main functions are to store and reconstruct the primary variables. The data transfer performs the transfer of data on a grid from before to after adaptation and is defined in the file dumux/porousmediumflow/2p/griddatatransfer.hh. Its main functions are to store and reconstruct the primary variables. cpp TwoPGridDataTransfer dataTransfer(problem, fvGridGeometry, gridVariables, x);  we do an initial refinement around sources/BCs. We use the GridAdaptInitializationIndicator defined in dumux/adaptive/initializationindicator.hh for that. We do an initial refinement around sources/BCs. We use the GridAdaptInitializationIndicator defined in dumux/adaptive/initializationindicator.hh for that. cpp GridAdaptInitializationIndicator initIndicator(problem, fvGridGeometry, gridVariables);  we refine up to the maximum level. For every level, the indicator used for the refinement/coarsening is calculated. If any grid cells have to be adapted, the gridvariables and the pointsourcemap are updated. We refine up to the maximum level. For every level, the indicator used for the refinement/coarsening is calculated. If any grid cells have to be adapted, the gridvariables and the pointsourcemap are updated. cpp const auto maxLevel = getParam("Adaptive.MaxLevel", 0); for (std::size_t i = 0; i < maxLevel; ++i) ... ... @@ -709,7 +700,7 @@ we calculate the initial indicator for adaption for each grid cell using the ini cpp initIndicator.calculate(x);  we mark the elements that were adapted and then we mark the elements that were adapted. cpp bool wasAdapted = false; if (markElements(gridManager.grid(), initIndicator)) ... ... @@ -762,14 +753,14 @@ Update the point source map problem->computePointSourceMap(); }  we get some time loop parameters from the input file params.input We get some time loop parameters from the input file params.input `cpp