Skip to content
Snippets Groups Projects
model.md 6.91 KiB
Newer Older
---
title: Models in DuMux
---

# Implementing a new DuMu<sup>X</sup> model

## What is a DuMu<sup>X</sup> model
A DuMu<sup>X</sup> model is an implementation of a **mathematical model**, generally given by partial differential equations, by using **discretization** schemes.

## What is a DuMu<sup>X</sup> model
Mathematical model (PDE):
$\begin{equation*}
\small
\frac{\partial S(u)}{\partial t} + \nabla \cdot \mathbf{F}(u) = q, \quad \forall (t,\mathbf{x}) \in (0,T] \times \Omega
\end{equation*}$

<img src=img/model_domain_discretization.png width="100%">

Discrete model, e.g. using finite volumes:
$\begin{equation*}
\small
|B| \frac{S_h(\mathbf{u}^{n+1}_h) - S_h(\mathbf{u}^{n}_h)}{\Delta t}  + \sum_{\sigma \in \Sigma_B} F_{B,\sigma}(\mathbf{u}^{n+1}_h) = \int_{B}  q^{n+1} \, dx, \quad \forall t_{n+1}\leq T, \; \forall B
\end{equation*}$

## What is a DuMu<sup>X</sup> model
Discrete model, e.g. using finite volumes:
$\begin{equation*}
\small
|B| \frac{S_h(\mathbf{u}^{n+1}_h) - S_h(\mathbf{u}^{n}_h)}{\Delta t}  + \sum_{\sigma \in \Sigma_B} F_{B,\sigma}(\mathbf{u}^{n+1}_h) = \int_{B}  q \, dx, \quad \forall t_{n+1}\leq T, \; \forall B
\end{equation*}$

* $S_h$: storage calculation
* $F_{B,\sigma}$: flux over sub control volume face
* $q$ source term

How to implement these terms in DuMu<sup>X</sup>?

**local residual**

# Local Residual

## Local Residual

Implements these terms within

* `computeStorage(...)`
* `computeFlux(...)`
* `computeSource(...)`


## Example: Diffusion equation
Mathematical model (PDE):

$\begin{equation}
\frac{\partial c}{\partial t} - \nabla \cdot (D \nabla c) = 0 \:\: \mathrm{in}\; \Omega \times (0,T] \\
\end{equation}$

with

$\begin{aligned}
    c: &\:\text{concentration} \\
    D: &\:\text{constant diffusion coefficient} \\
    \Omega: &\:\text{spatial domain} \\
    T: &\:\text{end time}
\end{aligned}$

## Example: Diffusion equation
Discrete model using the Box discretization:

$\begin{equation}
\vert B \vert \frac{c_B^{n+1}-c_B^{n}}{\Delta t} - \sum_{\sigma \in \Sigma_{B}} \left[ D \nabla c_h^{n+1} \cdot \boldsymbol{n}_{B,\sigma} \vert \sigma \vert \right] = 0,
\end{equation}$

with

$\begin{aligned}
    c_B^n: &\:\text{concentration at time $t_n$ and control volume $B$} \\
    c_h: &\:\text{global discrete solution, interpolation using \textbf{basis functions}} \\
    \mathbf{n}: &\:\text{unit outer normal vector} \\
    \sigma: &\:\text{sub control volume face} \\
\end{aligned}$


## Local residual
The local residual of the diffusion model:
```cpp
namespace Dumux {
template<class TypeTag>
class DiffusionModelLocalResidual
: public GetPropType<TypeTag, Properties::BaseLocalResidual>
{
```

## Local residual
```cpp
namespace Dumux {
template<class TypeTag>
class DiffusionModelLocalResidual
: public GetPropType<TypeTag, Properties::BaseLocalResidual>
{
```
Our class inherits from the class `BaseLocalResidual`, which has to be chosen depending on the discretization scheme, here *Box scheme*.

## Storage term
```cpp
NumEqVector computeStorage(const Problem& problem,
						   const SubControlVolume& scv,
						   const VolumeVariables& volVars) const
 {
	 NumEqVector storage;
     storage[Indices::massBalanceEqIdx]
        = volVars.priVar(Indices::concentrationIdx);
     return storage;
 }
```

## Flux term

$\begin{equation}
F_{B,\sigma} = -D \nabla c_h^{n+1} \cdot \boldsymbol{n}_{B,\sigma} \vert \sigma \vert
\end{equation}$

with

$\begin{aligned}
    c_h: &\:\text{discrete solution, interpolated using basis functions} \\
    \sigma: &\:\text{sub control volume face} \\
\end{aligned}$

## Flux term
Implementation takes place in the dedicated function `computeFlux`:
```cpp
 NumEqVector computeFlux(const Problem& problem,
                         const Element& element,
                         const FVElementGeometry& fvGeometry,
                         const ElementVolumeVariables& elemVolVars,
                         const SubControlVolumeFace& scvf,
                         const ElementFluxVariablesCache& elemFluxVarsCache) const
 {
    ...
```

## Flux term
Implementation takes place in the dedicated function `computeFlux`:
```cpp
 NumEqVector computeFlux(...) const
 {
	 // Compute ∇c
    const auto& fluxVarCache = elemFluxVarsCache[scvf];
    Dune::FieldVector<Scalar, dimWorld> gradConcentration(0.0);
    for (const auto& scv : scvs(fvGeometry))
    {
        const auto& volVars = elemVolVars[scv];
        gradConcentration.axpy(
            volVars.priVar(Indices::concentrationIdx),
            fluxVarCache.gradN(scv.indexInElement())
        );
    }
    ...
 }
```

## Flux term
Implementation takes place in the dedicated function `computeFlux`:
```cpp
 NumEqVector computeFlux(...) const
 {
    ...
    NumEqVector flux;

    // Compute the flux
    flux[Indices::massBalanceEqIdx] = -1.0*vtmv(
        scvf.unitOuterNormal(), problem.diffusionCoefficient(), gradConcentration
    )*scvf.area();

    return flux;

 }
```

## Local Residual

A *local residual* implements the discretized mathematical model.

For its implementation different model-specific properties have to be set

# Model properties

## Model type tag

The property tag is an empty struct with the respective name, e.g. `DiffusionModel`

```cpp
namespace Dumux::Properties::TTag {
//! The diffusion model tag that we can specialize properties for
struct DiffusionModel {};
} // end namespace Dumux::Properties::TTag
```
## Model properties
By specializing properties for the type tag `DiffusionModel`, every other class that knows about the type tag (this will be for example the assembler or the problem), can extract the type information that we specify here.

All properties are defined within the namespace `Dumux::Properties`
```cpp
namespace Dumux::Properties {
  //define all properties
} // end namespace Dumux::Properties
```

## Defining model properties
The type of the local residual is the class `DiffusionModelLocalResidual` defined from earlier
```cpp
template<class TypeTag>
struct LocalResidual<TypeTag, TTag::DiffusionModel>
{ using type = DiffusionModelLocalResidual<TypeTag>; };
```

## Defining model properties
The model traits specify information about the model:
```cpp
template<class TypeTag>
struct ModelTraits<TypeTag, TTag::DiffusionModel>
{
    struct type
    {
        struct Indices
        {
		    static constexpr int concentrationIdx = 0;
		    static constexpr int massBalanceEqIdx = 0;
        };
        static constexpr int numEq() { return 1; }
    };
};
```
## Defining model properties
Further model specific properties can be set accordingly by using the model property tag,
i.e. `TTag::DiffusionModel`

# Exercise: Model

## Exercise: Model
Implementation of a **nonlinear diffusion model**

<figure>
    <center>
        <img src="../exercises/extradoc/exercisemodel_mri_denoise.gif" alt="denoising"/>
        <figcaption> Denosing of MRI image using nonlinear diffusion model.</figcaption>
    </center>
</figure>

## Tasks

- Implement local residual
- Set model properties
- Use model in test case
- Customize volume variables