*[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,

*[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.

@@ -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.

<imgsrc="img/setup.png"width="500">

![](./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

```

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:

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.

The 1p-model calculated a stationary pressure distribution. It is shown in the following figure:

<imgsrc="img/pressure.png"width="300">

![](./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.

// 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 <dumux/common/properties.hh>

// 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 <dumux/common/parameters.hh>

// 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 <dumux/common/dumuxmessage.hh>

// The following file contains the class, which defines the sequential linear solver backends.

...

...

@@ -95,7 +95,7 @@ int main(int argc, char** argv) try

// 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::Timertimer;

Dune::TimerassemblyTimer;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.

usingLinearSolver=UMFPackBackend;

Dune::TimersolverTimer;std::cout<<"Solving linear system ..."<<std::flush;

@@ -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.

// 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.

@@ -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

// 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 <random>

// In the file properties.hh all properties are declared.

// In the file `properties.hh` all properties are declared.

#include <dumux/porousmediumflow/properties.hh>

// We include the spatial parameters for single-phase, finite volumes from which we will inherit.

...

...

@@ -32,14 +32,14 @@

namespaceDumux{

// 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<classFVGridGeometry,classScalar>

classOnePTestSpatialParams

:publicFVSpatialParamsOneP<FVGridGeometry,Scalar,

OnePTestSpatialParams<FVGridGeometry,Scalar>>

{

// 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.

// 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_`.

// 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 <dumux/porousmediumflow/properties.hh>

// 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 <dumux/material/spatialparams/fv1p.hh>

// We enter the namespace Dumux

namespaceDumux{

// 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`.

// 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<classElementSolution>

Scalardispersivity(constElement&element,

constSubControlVolume&scv,

...

...

@@ -67,7 +67,7 @@ public:

{return0;}

// ### 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}`$.

@@ -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

namespaceDumux{

```

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<classFVGridGeometry,classScalar>

...

...

@@ -96,7 +96,7 @@ we get the position of the lens from the params.input file. The lens is defined

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

@@ -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 <config.h>

...

...

@@ -553,7 +551,7 @@ Dumux is based on DUNE, the Distributed and Unified Numerics Environment, which

#include <dune/grid/io/file/vtk.hh>

#include <dune/istl/io.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.

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 <dumux/common/properties.hh>

```

...

...

@@ -570,11 +568,11 @@ we include the linear solver to be used to solve the linear system

```cpp

#include <dumux/linear/amgbackend.hh>

```

we include the nonlinear newtons method

we include the nonlinear Newton's method

```cpp

#include <dumux/nonlinear/newtonsolver.hh>

```

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 <dumux/assembly/fvassembler.hh>

```

...

...

@@ -594,7 +592,7 @@ The gridmanager constructs a grid from the information in the input or grid file

```cpp

#include <dumux/io/grid/gridmanager.hh>

```

we include several files which are needed for the adaptive grid

We include several files which are needed for the adaptive grid

```cpp

#include <dumux/adaptive/adapt.hh>

#include <dumux/adaptive/markelements.hh>

...

...

@@ -602,7 +600,7 @@ we include several files which are needed for the adaptive grid

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.

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.

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.

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.

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.

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.