87
Handbook June 15, 2011 Lehrstuhl f¨ ur Hydromechanik und Hydrosystemmodellierung, Universit¨ at Stuttgart, Paffenwaldring 61, D-70569 Stuttgart, Germany http://dumux.org

Dumux Handbook

Embed Size (px)

Citation preview

Page 1: Dumux Handbook

Handbook

June 15, 2011

Lehrstuhl fur Hydromechanik und Hydrosystemmodellierung,

Universitat Stuttgart, Paffenwaldring 61, D-70569 Stuttgart, Germany

http://dumux.org

Page 2: Dumux Handbook
Page 3: Dumux Handbook

Contents

1 Introduction 5

2 Getting started 72.1 Installation of DuMux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.1.1 Preliminary remarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.1.2 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.1.3 Obtaining source code for DUNE and DuMux . . . . . . . . . . . . . . . . . . . . 82.1.4 Patching DUNE or external libraries . . . . . . . . . . . . . . . . . . . . . . . . . 112.1.5 Build of DUNE and DuMux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.1.6 Building doxygen documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.1.7 Building documentation of other DUNE modules . . . . . . . . . . . . . . . . . . 132.1.8 External libraries and modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.1.9 Hints for Users from IWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.2 Quick start guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.3 Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.4 Setup of a New Folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3 Design Patterns 193.1 C++ Template Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.2 Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203.3 Common Template Programming Related Problems . . . . . . . . . . . . . . . . . . . . 233.4 Traits Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

4 The DuMux Property System 264.1 Concepts and Features of the DuMux Property System . . . . . . . . . . . . . . . . . . . 264.2 DuMux Property System Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264.3 A Self-Contained Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

5 Tutorial 325.1 Box method - A short introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325.2 Fully-coupled model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

5.2.1 The main file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355.2.2 The problem class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375.2.3 Defining fluid properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425.2.4 The definition of the parameters that are dependent on space . . . . . . . . . . . 425.2.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

5.3 Decoupled model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495.3.1 The problem class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.3.2 The definition of the parameters that are dependent on space . . . . . . . . . . . 57

3

Page 4: Dumux Handbook

Contents

5.3.3 Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

6 Directory Structure 636.1 The directory dumux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 636.2 The directory test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

7 Models 667.1 Physical and mathematical description . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

7.1.1 Basic Definitions and Assumptions for the Compositional Model Concept . . . . 667.1.2 Balance Equations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

7.2 Available models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687.2.1 Fully coupled models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687.2.2 Decoupled models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

8 The flow of things in DuMux 738.1 Structure – by content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

8.1.1 Levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 748.2 Structure – by implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

9 Newton in a Nutshell 81

10 Tips & Tricks 83

4

Page 5: Dumux Handbook

1 Introduction

DuMux aims to be a generic framework for simulation of multiphase fluid flow and transport processesin porous media using contiuum mechanical approaches. At the same time, DuMux aims to delivertop-notch computational performance, high flexibility, a sound software architecture and the abilityto run on anything from single processor systems to highly parallel supercomputers with specializedhardware architectures.The means to achieve these somewhat contradictory goals are the thorough use of object oriented

design in conjunction with template programming. These requirements lead to C++ as the implemen-tation language.One of the more complex issues when dealing with parallel continuum models is managing the grids

used for the spatial discretization of the physical model. To date, no generic and efficient approachexists for all possible cases, so DuMux is build on top of DUNE, the Distributed and Unified NumericsEnvironment [12]. DUNE provides a generic interface to many existing grid management librariessuch as UG [23], ALBERTA [2], ALU-Grid [3] and a few more. DUNE also extensively uses templateprogramming in order to achieve minimal overhead when accessing the underlying grid libraries1.

Figure 1.1: A high-level overview on DUNE’s design as available on the project’s web site [12].

DUNE’s grid interface is independent of the spatial dimension of the underlying grid. For thispurpose, it uses the concept of co-dimensional entities. Roughly speaking, an entity of co-dimension0 constitutes a cell, co-dimension 1 entities are faces between cells, co-dimension 1 are edges, and soon until co-dimension n which are the cell’s vertices. The DUNE grid interface generally assumes

1In fact, the performance penalty resulting from the use of DUNE’s grid interface is usually negligible [8].

5

Page 6: Dumux Handbook

1 Introduction

that all entities are convex polytopes, which means that it must be possible to express each entityas the convex hull of a set of vertices. For efficiency, all entities are further expressed in terms ofso-called reference elements which are transformed to the actual spatial incarnation within the gridby a so-called geometry function2. Here, a reference element for an entity can be thought of as aprototype for the actual grid entity. For example, if we used a grid that used hexahedrons as cells, thereference element for each cell would be the unit cube [0, 1]3 and the geometry function would scaleand translate the cube so that it matches the grid’s cell. For a more thorough description of DUNE’sgrid definition, see [5].In addition to the grid interface, DUNE also provides quite a few additional modules, of which the

dune-pdelab, dune-localfunctions and dune-istl modules are the most relevant in the context ofthis handbook. dune-pdelab provides a toolbox for discretization and includes matrix assemblers fortranslating local stiffness matrices into a global linear system of equations and much more, while dune-localfunctions provides a set of generic finite element shape functions. dune-istl is the IterativeSolver Template Library and provides generic, highly optimized linear algebra routines for solving thegenerated systems.DuMux comes in form of an additional module dumux. It depends on the DUNE core modules dune-

common, dune-grid, dune-istl, dune-localfunctions, as well as from the discretization moduledune-pdelab. The main intention of DuMux is to provide a framework for easy and efficient imple-mentation of new physical models for porous media flow problems, ranging from problem formulation,the selection of spatial and temporal discretization schemes, as well as nonlinear solvers, up to generalconcepts for model coupling. Moreover, DuMux includes ready to use numerical models and a fewexample applications.

2The same approach is also used by dune-disc for finite element shape functions.

6

Page 7: Dumux Handbook

2 Getting started

First, we describe the prerequisites and the steps which are necessary for the installation of DuMux.Then a quick start guide for the first DuMux experience is provided. We conclude this chapter with acopy of the DUNE coding guidelines.

2.1 Installation of DuMux

2.1.1 Preliminary remarks

In this section about the installation of DuMux it is assumed that you work on a UNIX or Linuxcompatible operating system and that you are familiar with the use of a command line shell. Instal-lation means that you unpack DUNE together with DuMux in a certain directory. Then, you compileit in that directory tree where you do the further work, too. You also should know how to installnew software packages or you should have a person aside which can give you assistance with that. Insection 2.1.2 we list some prerequisites for running DUNE and DuMux. Please check this paragraphwhether you can fulfill them. In addition, section 2.1.8 provides some details on optional libraries andmodules.In a technical sense DuMux is a module of DUNE. Thus, the installation procedure of DuMux is

the same as that of DUNE. Details regarding the installation of DUNE are provided on the DUNEwebsite [17]. If you are interested in more details about the build system that is used, they can befound in the DUNE Buildsystem Howto [13].All DUNE modules including DuMux get extracted into a common directory, as it is done in a

usual DUNE installation. We refer to that directory abstractly as DUNE root directory or shortly asDUNE-Root. If it is used as directory’s path of a shell command it is typed as DUNE-Root. For thereal DUNE root directory on your file system any valid directory name can be chosen.Source code files for each DUNE module are contained in their own subdirectory within DUNE-Root.

We name this directory of a certain module “module root directory” or module-root-directory if it isa directory path, e.g. for the module dumux these names are “dumux root directory” respective dumux-root-directory. The real directory names for modules can be chosen arbitrarily, in this manual theyare the same as the module name or the module name extended by a version number suffix. Thename of each DUNE module is always defined in the file dune.module, which is in root directory ofthe respective module. This should not be changed by the user. It is allowed to have own files anddirectories in DUNE-Root, which are not related to DUNE’s needs.After installing source code for all relevant DUNE modules including DuMux, DUNE is being built

by the shell-command dunecontrol which is part of the DUNE build system. The DUNE build systemis a front-end of to the GNU build system adapted to the needs of DUNE.

7

Page 8: Dumux Handbook

2 Getting started

2.1.2 Prerequisites

The GNU tool chain of g++ and the tools of the GNU build system [24], also known as GNU autotools(autoconf, automake, autogen, libtool), as well as the GNU variant of make must be available ina recent version. For Ubuntu Linux, e.g., these are contained in the packages autoconf, automake,libtool and the C++ compiler g++ and make are contained in build-essential.At the time of writing this manual, it is expected that g++ of version > 4.4.1, automake of version> 1.11, autoconf of version > 2.65, autogen of version > 5.9.7, libtool of version > 2.2.6 andGNU make version > 3.81 should do their job for building DuMux. DuMux makes use of the boost

library in the version > 1.33.1, but optional external modules may require a more recent version. Itis thus necessary to install an appropriate developer package of boost which is sometimes also namedlibboost. The matching Ubuntu Linux package is libboost-dev.The building of included documentation like this handbook requires LATEX and auxiliary tools like

dvipdf and bibtex. One usually chooses a LATEX distribution like texlive for doing that. It is possibleto switch off the building of the documentation by setting the switch --disable-documentation inthe CONFIGURE FLAGS of the building options (see Chapter 2.1.5). Additional parts of documentationare contained within the source code files as special formatted comments. Extracting them can bedone with doxygen (version > 1.7.2 works). See for this optional step Section 2.1.6.Depending on whether you are going to use external libraries and modules for additional DUNE

features, additional software packages may be required. Some hints on that are given in Section 2.1.8.For the extraction of the content of tar-files, the GNU version of tar is used. The subversion (svn)

software repositories can be accessed with help of a subversion client. We recommend the ApacheSubversion command-line client svn contained in Apache Subversion of version > 1.6.0 [4].

2.1.3 Obtaining source code for DUNE and DuMux

As stated before, the DuMux release 2.0.2 is based on the DUNE release 2.1, comprising the coremodules dune-common, dune-grid, dune-istl, dune-localfunctions and the external dune moduledune-pdelab. Thus, for a proper DuMux installation these modules are required.Two possibilities exist to get the source code of DUNE and DuMux. Firstly, DUNE and DuMux can

be downloaded as tar-files from the respective DUNE and DuMux website. They have to be extractedas described in the next paragraph. Secondly, a method to obtain the most recent source code (or moregenerally any of its the previous revisions) by direct access via Internet to the software repositories ofthe revision control system is described in the subsequent part.However, if a user does not want to use the most recent version, certain version tags (i.e. special

names), version numbers and even software branches are means of the software revision control systemto provide access to different versions of the software.

Obtaining the software by installing tar-files The slightly old-fashioned named tape-archive-fileshortly named tar-file or tarball is a common file format for distributing collections of files containedwithin these archives. The extraction from the tar-files is done as follows: Download the tarballs fromthe respective DUNE (version 2.1) and DuMux websites to a certain folder in your file system. Createthe DUNE root directory, named DUMUX in the example below. Then extract the content of the tar-files, e.g. with the command-line program tar. This can be achieved by the following shell commands.

8

Page 9: Dumux Handbook

2 Getting started

Replace path to tarball with the directory name where the downloaded files are actually located.After extraction, the actual name of the dumux root directory is dumux-2.0.2.

$ mkdir DUMUX

$ cd DUMUX

$ tar xzvf path_to_tarball_of/dune -common -2.1.0. tar.gz

$ tar xzvf path_to_tarball_of/dune -grid -2.1.0. tar.gz

$ tar xzvf path_to_tarball_of/dune -istl -2.1.0. tar.gz

$ tar xzvf path_to_tarball_of/dune -localfunctions -2.1.0. tar.gz

$ tar xzvf path_to_tarball_of/dumux -2.0.2. tar.gz

Furthermore, if you wish to install the optional DUNE Grid-Howto which provides a tutorial on theDune grid interface:

$ tar xzvf path_to_tarball_of/dune -grid -howto -2.1. tar.gz

However, the required DUNE-module dune-pdelab is not available as tar-file. It can be installedfrom a software repository via svn. If svn is available in the command line, it can be done as follows:

$ svn co https :// svn.dune -project.org/svn/dune -pdelab/branches /2.1 snapshot

dune -pdelab

Obtaining DUNE and DuMux from software repositories Direct access to a software revision controlsystem for downloading code can be of later advantage for the user. It can be easier for him to keepup with code changes and to receive important bug fixes using the update command of the revisioncontrol system. DUNE and DuMux use Apache Subversion for their software repositories. To accessthem a certain program is needed which is referred here shortly as subversion client. In our description,we use the subversion client of the Apache Subversion software itself, which is a command-line toolnamed svn. It is available for most Linux and UNIX distributions as software package.In the technical speech of Apache Subversion “checking out a certain software version” means nothing

more then fetching a local copy from the software repository and laying it out in the file system.Additionally to the software some more files for the use of the software revision control system itselfare created. They are kept in directories named .svn and can be found in each subfolder that isunder version control. If you have developer access to DuMux, it is also possible to do the opposite,i.e. loading up a modified revision of software into the software repository. This is usually termed as“software commit”.The installation procedure is done as follows: Create a DUNE root directory, named DUMUX in

the lines below. Then, enter the previously created directory and check out the desired modules. Asyou see below, the check-out uses two different servers for getting the sources, one for DUNE and onefor DuMux. The DUNE modules of the stable 2.1 release are checked out as described on the DUNEwebsite [14]:

$ mkdir DUMUX

$ cd DUMUX

$ svn co https :// svn.dune -project.org/svn/dune -common/releases /2.1.0

dune -common

9

Page 10: Dumux Handbook

2 Getting started

$ svn co https :// svn.dune -project.org/svn/dune -grid/releases /2.1.0 dune -grid

$ svn co https :// svn.dune -project.org/svn/dune -istl/releases /2.1.0 dune -istl

$ svn co https :// svn.dune -project.org/svn/dune -localfunctions /releases /2.1.0

dune -localfunctions

$ svn co https :// svn.dune -project.org/svn/dune -pdelab/branches /2.1 snapshot

dune -pdelab

The newest (unstable) developments are also provided in these repositories, usually in a folder called“trunk”. Please check the DUNE website [14] for further information. However, the current DuMux

release is based on the stable 2.1 release and it probably will not compile without further adaptationsusing the the newest versions of DUNE.The additional module dune-grid-howto is a tutorial which provides information about the DUNE

grid interface. It may give you an idea how some abstractions in DUNE are done. The dune-grid-

howto is not required by DuMux, the installation is optional. It is done by:

$ svn co https :// svn.dune -project.org/svn/dune -grid -howto/releases /2.1.0

dune -grid -howto

The dumux module is checked out as described below (see also the DuMux website [11]). Its file treehas to be created in the DUNE-Root directory, where the DUNE modules are also have been checkedout to. Subsequently, the next command is executed there, too. The dumux root directory is calleddumux here.

$ # make su r e you are in DUNE−Root

$ svn co --username=anonymous --password=’’

svn :// svn.iws.uni -stuttgart.de/DUMUX/dumux/trunk dumux

Hints for DuMux-Developers If you also want to actively participate in the development of DuMux,you can apply either for full developer access or for developer access on certain parts of DuMux.Granted developer access means that you are allowed to commit own code and that you can access thedumux-devel module. This enhances dumux by providing (unstable) code from the developer group.A developer usually checks out non-anonymously the modules dumux and dumux-devel. Dumux-develitself makes use of the stable part dumux. Hence, the two parts have to be checked out together. Thisis done by the commands below. But joeuser needs to be replaced by the actual user name of thedeveloper for accessing the software repository. One can omit the --username option in the commandsabove, if the user name for the repository access is identical to the one for the system account.

$ svn co --username=joeuser svn :// svn.iws.uni -stuttgart.de/DUMUX/dumux/trunk

dumux

$ svn co --username=joeuser

svn :// svn.iws.uni -stuttgart.de/DUMUX/dune -mux/trunk dumux -devel

Please choose either not to store the password by subversion in an insecure way or choose to store itby subversion in a secure way, e.g. together with kwallet or gnomekeyring. Check the documentationof subversion, how this is being done. A leaked out password can be used by evil persons to abuse asoftware repository.

10

Page 11: Dumux Handbook

2 Getting started

checkout-dumux script The shell-script checkout-dumux facilitates setting up a DUNE/DuMux di-rectory tree. It is contained in the download section of the DuMux web page [11]. For example thesecond line below will check out the required DUNE modules and dumux, dumux-devel and the ex-

ternal folder, which contains some useful external software and libraries. Again, joeuser needs tobe replaced by the actual user name.

$ checkout -dumux -h # show he lp ,

$ checkout -dumux -gme -u joeuser -p password -d DUMUX

2.1.4 Patching DUNE or external libraries

Patching of DUNE modules in order to work together with DuMux can be necessary for several reasons.Software like a compiler or even a standard library changes at times. But, for example, a certain releaseof a software-component that we depend on, may not reflect that change and thus it has to be modified.In the dynamic developing process of software that depends on other modules it is not always feasibleto adapt everything to the most recent version of each module. Consequently, patches exist or they arebe brought into existence. They may fix problems with a certain module of a certain release withoutintroducing too much structural change. It can also happen that a release gets amendments (updates)and a formerly useful patch becomes obsolete.DuMux contains patches and documentation about their usage and application within the directory

dumux/patches. Please check the README file in that directory for recent information. In general, apatch can be applied as follows (the exact command or the used parameters may be slightly different).

$ # make su r e you are in DUNE−Root

$ cd dune -istl

$ patch -p1 < ../ dumux/patches/dune -istl -2.0. patch

It can be removed by

$ path -p1 -R < ../ dumux/patches/dune -istl -2.0. patch

The checkout-dumux script also applies patches, if not explicitly requested to do not so.

2.1.5 Build of DUNE and DuMux

Building of DUNE and DuMux is done by the command-line script dunecontrol as described in DUNEInstallation Notes [17] and in much more comprehensive form in the DUNE Buildsystem Howto [13].If something fails during the execution of dunecontrol feel free to report it to the DUNE or DuMux

developer mailing list, but also try to include error details.

It is possible to compile DuMux with nearly no explicit options to the build system. However,for the successful compilation of DUNE and DuMux, it is currently necessary to pass the the option-fno-strict-aliasing to the C++-compiler [25], which is done here via a command-line argumentto dunecontrol:

11

Page 12: Dumux Handbook

2 Getting started

$ # make su r e you are in t h e d i r e c t o r y DUNE−Root

$ ./dune -common/bin/dunecontrol

--configure -opts="CXXFLAGS=-fno -strict -aliasing" all

Too many options can make life hard, that’s why usually option-files are being used together withdunecontrol and its sub-tools. Larger sets of options are kept in them. If you are going to compilewith options suited for debugging of the code, the following can be a starting point:

$ # make su r e you are in t h e d i r e c t o r y DUNE−Root

$ cp dumux/debug.opts my -debug.opts # c r e a t e a p e r s o n a l v e r s i o n

$ gedit my -debug.opts # op t i o n a l e d i t i n g t h e o p t i o n s f i l e

$ ./dune -common/bin/dunecontrol --opts=my -debug.opts all

More optimized code, which is typically not usable for standard debugging tasks, can produced by

$ cp dumux/optim.opts my -optim.opts

$ ./dune -common/bin/dunecontrol --opts=my -optim.opts all

Sometimes it is necessary to have additional options which are specific to a package set of anoperating system or sometimes you have your own preferences. Feel free to work with your own set ofoptions, which may evolve over time. The option files above are more to be understood as a startingpoint for setting up an own customization than as something which is fixed. The use of externallibraries can make it necessary to add quite many options in an option-file. It can be helpful to giveyour customized option file its own name, as done above. One avoids to confused it with the optionfiles that came out of the distribution and that can be possibly updated by subversion later on.

2.1.6 Building doxygen documentation

Doxygen documentation is done by especially formatted comments integrated in the source code, whichcan get extracted by the program doxygen. Beside extracting these comments, doxygen builds up aweb-browsable code structure documentation like class hierarchy of code displayed as graphs, see [10].Building the doxygen documentation of a module is done as follows, provided the program doxygen

is installed: Set in building options the --enable-doxygen switch. This is either accomplished byadding it in dunecontrol options-file to CONFIGURE FLAGS, or by adding it to dunecontrol’s command-line-argument --configure-opts. After running dunecontrol enter in module’s root directory thesubdirectory doc/doxygen. You then run the command doxygen within that directory. Point your webbrowser to the file module-root-directory/doc/doxygen/html/index.html to read the generateddocumentation. All DUNE-modules that are used here except dune-grid-howto including also dumux

contain some doxygen documentation, which can be extracted as described in the following lines. Theexternal library UG has also a doc/doxygen directory for building its doxygen documentation.

$ # change b e f o r e nex t command your d i r e c t o r y t o DUNE−Root

$ cd dumux/doc/doxygen

$ doxygen

$ firefox html/index.html

12

Page 13: Dumux Handbook

2 Getting started

2.1.7 Building documentation of other DUNE modules

If the --enable-documentation switch has been set in the configure flags of dunecontrol, this doesnot necessarily mean that for every DUNE module the documentation is being build. However, atleast Makefiles for building the documentation are generated. Provided you run dunecontrol withthe option above, it should be possible to build documentation if available. Check in module-root-

directory/doc/Makefile.am which targets you can build. E.g., for the module dune-istl you canbuild the documentation istl.pdf by typing the following into the console, when you are in theDUNE-Root:

$ # change b e f o r e nex t command your d i r e c t o r y t o DUNE−Root

$ cd dune -istl/doc

$ make istl.pdf

Or for module dune-grid-howto the documentation can be build by:

$ # change b e f o r e nex t command your d i r e c t o r y t o DUNE−Root

$ cd dune -grid -howto/doc

$ make grid -howto.pdf

This applies for DuMux too. Rebuilding the handbook can be done as follows:

$ cd dumux/doc/handbook

$ make dumux -handbook.pdf

2.1.8 External libraries and modules

The libraries described in the sequel of this paragraph provide additional functionality but are notgenerally required to run DuMux. If you are going to use an external library check the informationprovided on the DUNE website [15]. If you are going to use an external DUNE module the website onexternal modules [16] can be helpful.

Installing an external library can require additional libraries which are also used by DUNE. Forsome libraries, such as BLAS or MPI, multiple versions can be installed on system. Make sure that ituses the same library as DUNE when configuring the external library.

In the following list, you can find some external modules and external libraries, and some morelibraries and tools which are prerequisites for their use.

• ALBERTA: External library for use as GRID. Adaptive multi Level finite element toolbox usingBisectioning refinement and Error control by Residual Techniques for scientific Applications.Building it requires a FORTRAN compiler gfortran. Download: http://www.alberta-fem.de.

• ALUGrid: External library for use as GRID. ALUGrid is build by a C++-compiler like g++.If you want to build a parallel version, you will need MPI. It was successfully run with openmpi.The parallel version needs also a graph partitioner, such as METIS. It was run successfully incombination with DUNE using METIS.Download: http://aam.mathematik.uni-freiburg.de/IAM/Research/alugrid

13

Page 14: Dumux Handbook

2 Getting started

• DUNE-multidomaingrid: External module. If you going to run on the same grid differentdomains or subdomains, this can be the package of choice. This is done by providing a metagrid. It can be useful for multi-physics approaches or domain decomposition methods. Download:http://gitorious.org/dune-multidomaingrid.

• PARDISO: External library for solving linear equations. The package PARDISO is a thread-safe, high-performance, robust, memory efficient and easy to use software for solving large sparsesymmetric and asymmetric linear systems of equations on shared memory multiprocessors. Theprecompiled binary can be downloaded after personal registration from the PARDISO website(http://www.pardiso-project.org).

• SuperLU: External library for solving linear equations. SuperLU is a general purpose libraryfor the direct solution of large, sparse, non-symmetric systems of linear equations.(http://crd.lbl.gov/~xiaoye/SuperLU).

• UG: External library for use as GRID. UG is a toolbox for Unstructured Grids: For DuMux ithas to be build by GNU buildsystem and a C++-compiler. That’s why DUNE specific patchesneed applied before use. Building it makes use of the tools lex/yacc or the GNU variantsflex/bison.

The following are dependencies of some of the used libraries. You will need them depending onwhich modules of DUNE and which external libraries you use.

• MPI: The parallel version of DUNE and also some of the external dependencies need MPI whenthey are going to be built for parallel computing. Openmpi version > 1.4.2 and MPICH in a recentversion have been reported to work.

• lex/yacc or flex/bison: These are quite common developing tools, code generators for lexicalanalyzers and parsers. This is a prerequisite for UG.

• BLAS: Alberta makes use of BLAS. Thus install GotoBLAS2, ATLAS, non-optimized BLAS orBLAS provided by a chip manufacturer. Take care that the installation scripts select the intendedversion of BLAS. See http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms.

• GotoBLAS2: This is an optimized version of BLAS. It covers not always available all processorsof the day, but quite a broad range. Its license is now very open. A FORTRAN compiler likegfortran is needed to compile it.Available by http://www.tacc.utexas.edu/tacc-projects/gotoblas2/.

• METIS: This is a dependency of ALUGrid, if you are going to run it parallel.

• Compilers: Beside g++ it has been reported that DUNE was successfully build with the IntelC++ compiler. C and FORTRAN compiler is needed for a some external libraries. As code ofdifferent compilers is linked together they have to be be compatible with each other. A goodchoice is the GNU compiler suite gcc,g++ and gfortran.

• libgomp: External libraries, such as ALUGrid, can make use of OpenMP when used togetherwith METIS. For that purpose it can be necessary to install the libgomp library.

14

Page 15: Dumux Handbook

2 Getting started

2.1.9 Hints for Users from IWS

We provide some features to make life a little bit easier for users from the Institute of HydraulicEngineering, University of Stuttgart.There exists internally a svn repository made for several external libraries. If you are allowed to

access it, go to the DUNE-Root, then do:

prepared external directory$ # Make su r e you are in DUNE−Root

$ svn checkout svn :// svn.iws.uni -stuttgart.de/DUMUX/external/trunk external

This directory external contains a script to install external libraries, such as ALBERTA, ALUGrid,UG, METIS and GotoBLAS2:

$ cd external

$ ./ installExternal.sh all

It is also possible to install only the actual needed external libraries:

$ ./ installExternal.sh -h # show , what o p t i o n s t h i s s c r i p t p r o v i d e

$ ./ installExternal.sh --parallel alu

The libraries are then compiled within that directory and are not installed in a different place. ADUNE build may need to know their location. Thus, one may have to refer to them as options fordunecontrol, for example via the options file my-debug.opts.

2.2 Quick start guide: The first run of a test application

The previous chapter showed, how to install and compile DuMux. This chapter shall give a very briefintroduction, how to run a first test application and how to visualize the first output files. Only therough steps will be described here. More detailed explanations can be found in the tutorials in thefollowing chapter.

1. Go to the directory /test. There, various test application folders can be found. Let us consideras example boxmodels/test 2p:

2. Enter the folder boxmodels/2p. If everything was compiled correctly, there should be an exe-cutable test 2p. Otherwise, type make test 2p in order to compile the application. To run thesimulation, type./test 2p 1e4 1e2

into the console. The parameters that are used here are the end time of the simulation and theinitial timestep size. The parameters that are required when calling the application are specifiedin the application file (here: test 2p.cc).

3. The simulation starts and produces some .vtu output files and also a .pvd file. The .pvd file canbe used to examine time series and summarizes the .vtu-files. It is possible to stop a runningapplication by pressing < ctrl >< c >.

15

Page 16: Dumux Handbook

2 Getting started

4. You can display the results using the visualization tool ParaView (or alternatively VisIt). Justtype paraview in the console and open the .pvd file. On the left hand side, you can choose thedesired parameter to be displayed.

2.3 Guidelines

This section quotes the DUNE coding guidelines found at [12]. These guidelines also should be followedby every DuMux developer and user.“In order to keep the code maintainable we have decided upon a set of coding rules. Some of themmay seem like splitting hairs to you, but they do make it much easier for everybody to work on codethat hasn’t been written by oneself.

• Naming:

– Variables: Names for variables should only consist of letters and digits. The first lettershould be a lower case one. If your variable names consists of several words, then the firstletter of each new word should be capital. As we decided on the only exception are thebegin and end methods.

– Private Data Variables: Names of private data variables end with an underscore.

– Typenames: For typenames, the same rules as for variables apply. The only difference isthat the first letter should be a capital one.

– Macros: The use of preprocessor macros is strongly discouraged. If you have to use themfor whatever reason, please use capital letters only.

– The Exlusive-Access Macro: Every header file traditionally begins with the definition of apreprocessor constant that is used to make sure that each header file is only included once.If your header file is called ’myheaderfile.hh’, this constant should be DUNE MYHEAD-ERFILE HH.

– Files: Filenames should consist of lower case letters exclusively. Header files get the suffix.hh, implementation files the suffix .cc

• Documentation: Dune, as any software project of similar complexity, will stand and fall with thequality of its documentation. Therefore it is of paramount importance that you document welleverything you do! We use the doxygen system to extract easily-readable documentation fromthe source code. Please use its syntax everywhere. In particular, please comment all

– Method Parameters

– Template Parameters

– Return Values

– Exceptions thrown by a method

Since we all know that writing documentation is not well-liked and is frequently defered to somevague ’next week’, we herewith proclaim the Doc-Me Dogma . It goes like this: Whatever you do,and in whatever hurry you happen to be, please document everything at least with a /**\todoPlease doc me! */. That way at least the absence of documentation is documented, and it iseasier to get rid of it systematically.

16

Page 17: Dumux Handbook

2 Getting started

• Exceptions: The use of exceptions for error handling is encouraged. Until further notice, allexceptions thrown are DuneEx.

• Debugging Code: Global debugging code is switched off by setting the symbol NDEBUG. Inparticular, all asserts are automatically removed. Use those asserts freely!”

2.4 Setup of a New Folder

In this section setting up a new folder is described. In fact it is very easy to create a new folder, butgetting DuMux to know the new folder takes some steps which will be explained in more detail below:

• create new folder with content

• adapt Makefile.am

• insert new folder in Makefile.am of the directory above

• adapt configure.ac in the $DUMUX_ROOT (the directory you checked out, probably dumux)

• newly compile DuMux

In more detail:First of all, the new folder including all relevant files needs to be created (see Section 5.2 and 5.3

for description of a problem).Second, a new Makefile.am for the new Folder needs to be created. It is good practice to simply

copy an existing file. For example the file $DUMUX_ROOT/test/2p/Makefile.am looks as follows:

bin_PROGRAMS = test_2p

test_2p_SOURCES = test_2p.cc

test_2p_CXXFLAGS = $(MPI_CPPFLAGS)

test_2p_LDADD = $(MPI_LDFLAGS)

include $(top_srcdir)/am/global-rules

All occurrences of test_2p need to be replaced by the name of the new project, e.g. New_Project.At least if the name of the source file as well as the name of the new project are New_Project.Third: In the directory above your new Project there is also a Makefile.am . In this file the

subdirectories are listed. As you introduced a new subdirectory, it needs to be included here. In thiscase the name of the new Folder is New_Project . Don’t forget the trailing backslash.

SUBDIRS = . \

1p \

1p2c \

2p \

2p2c \

2p2cni \

17

Page 18: Dumux Handbook

2 Getting started

2pni \

New_Project \

...

Fourth: In $DUMUX_ROOT there is a file configure.ac. In this file, the respective Makefiles arelisted. After a line readingAC_CONFIG_FILES([Makefile

a line, declaring a new Makefile, needs to be included. The Makefile itself will be generated automati-cally. For keeping track of the included files, inserting in alphabetical order is good practice. The newline could read: test/New_Project/MakefileFifth: Compile DuMux as described in Section 2.1.

18

Page 19: Dumux Handbook

3 Design Patterns

This chapter tries to give a high-level understanding of some of the fundamental techniques which areused by DUNE and DuMux and the motivation behind these design decisions. It is assumed that thereader already has basic experience in object oriented programming with C++.First, a quick motivation of C++ template programming is given. Then follows an introduction

to polymorphism and the opportunities for it opened by the template mechanism. After that, somedrawbacks associated with template programming are discussed, in particular the blow-up of identi-fier names and proliferation of template arguments and some approaches on how to deal with theseproblems.

3.1 C++ Template Programming

One of the main features of modern versions of the C++ programming language is robust support fortemplates. Templates are a mechanism for code generation build directly into the compiler. For themotivation behind templates, consider a linked list of double values which could be implemented likethis:

1 struct DoubleList {

2 DoubleList(const double &val , DoubleList *prevNode = 0)

3 { value = val; if (prevNode) prevNode ->next = this; };

4 double value;

5 DoubleList *next;

6 };

7 int main() {

8 DoubleList *head , *tail;

9 head = tail = new DoubleList (1.23);

10 tail = new DoubleList (2.34, tail);

11 tail = new DoubleList (3.56, tail);

12 };

But what should be done if a list of strings is also required? The only “clean” way to achive thiswithout templates would be to copy DoubleList, then rename it and change the type of the value

attribute. It is obvious that this is a very cumbersome, error-prone and unproductive process. Forthis reason, recent standards of the C++ programming language specify the template mechanism,which is a way to let the compiler do the tedious work. Using templates, a generic linked list can beimplemented like this:

1 template <class ValueType >

2 struct List {

3 List(const ValueType &val , List *prevNode = 0)

4 { value = val; if (prevNode) prevNode ->next = this; };

5 ValueType value;

6 List *next;

7 };

8 int main() {

9 typedef List <double > DoubleList;

10 DoubleList *head , *tail;

11 head = tail = new DoubleList (1.23);

19

Page 20: Dumux Handbook

3 Design Patterns

12 tail = new DoubleList (2.34, tail);

13 tail = new DoubleList (3.56, tail);

14

15 typedef List <const char*> StringList;

16 StringList *head2 , *tail2;

17 head2 = tail2 = new StringList("Hello");

18 tail2 = new StringList(", ", tail2 );

19 tail2 = new StringList("World!", tail2 );

20 };

Compared to approaches which use external tools for code generation – which is the approach chosenfor example by the FEniCS [18] project – or heavy (ab)use of the C preprocessor – as done for exampleby the UG framework [23] – templates have several advantages:

Well Programmable: Programming errors are directly detected by the C++ compiler. Thus, diagnos-tic messages from the compiler are directly useful because the source code which gets compiledis the same as the one written by the developer. This is not the case for code generators andC-preprocessor macros where the actual statements processed by the compiler are obfuscated.

Easily Debugable: Programs which use the template mechanism can be debugged almost as easily asC++ programs which do not use templates. This is due to the fact that the debugger alwaysknows the “real” source file and line number.

For these reasons DUNE and DuMux extensively use the template mechanism. Both projects also tryto avoid duplicating functionality provided by the Standard Template Library (STL, [22]) which ispart of the C++ standard and functionality provided by the quasi-standard Boost [7] libraries.

3.2 Polymorphism

In object oriented programming, some methods often makes sense for all classes in a hierarchy, butwhat actually needs to be done can differ for each concrete class. This observation motivates poly-

morphism. Fundamentally, polymorphism means all techniques where a method call results in theprocessor executing code which is specific to the type of object for which the method is called1.In C++, there are two common ways to achieve polymorphism: The traditional dynamic polymor-

phism which does not require template programming, and static polymorphism which is made possibleby the template mechanism.

Dynamic Polymorphism

To utilize dynamic polymorphism in C++, the polymorphic methods are marked with the virtual

keyword in the base class. Internally, the compiler realizes dynamic polymorphism by storing a pointerto a so-called vtable within each object of polymorphic classes. The vtable itself stores the entrypoint of each method which is declared virtual. If such a method is called on an object, the compilergenerates code which retrieves the method’s memory address from the object’s vtable and then con-tinues execution at this address. This explains why this mechanism is called dynamic polymorphism:the code which is actually executed is dynamically determined at run time.

1This is poly of polymorphism: There are multiple ways to achieve the same goal.

20

Page 21: Dumux Handbook

3 Design Patterns

Example 3.1 A class called Car could feature the methods gasUsage, which by default correspondsto the current CO2 emission goal of the European Union – line 5 – but can be changed by classesrepresenting actual cars. Also, a method called fuelTankSize makes sense for all cars, but since thereis no useful default, its vtable entry is set to 0 – line 6 – in the base class. This tells the compilerthat it is mandatory for this method to be defined in derived classes. Finally, the method range maycalculate the expected remaining kilometers the car can drive given a fill level of the fuel tank. Sincethe range method can retrieve information it needs, it does not need to be polymorphic.

1 // The base c l a s s2 class Car

3 {public:

4 virtual double gasUsage ()

5 { return 4.5; };

6 virtual double fuelTankSize () = 0;

7

8 double range(double fuelTankFillLevel )

9 { return 100* fuelTankFillLevel *fuelTankSize ()/ gasUsage (); }

10 };

Actual car models can now be derived from the base class like this:

1 // A Mercedes S−c l a s s car2 class S : public Car

3 {public:

4 virtual double gasUsage () { return 9.0; };

5 virtual double fuelTankSize () { return 65.0; };

6 };

7

8 // A VW Lupo9 class Lupo : public Car

10 {public:

11 virtual double gasUsage () { return 2.99; };

12 virtual double fuelTankSize () { return 30.0; };

13 };

Calling the range method yields the correct result for any kind of car:

1 void printMaxRange (Car &car)

2 { std::cout << "Maximum Range: " << car.range (1.00) << "\n"; }

3

4 int main()

5 {

6 Lupo lupo;

7 S s;

8 std::cout << "VW Lupo:";

9 std::cout << "Median range: " << lupo.range (0.50) << "\n";

10 printMaxRange (lupo);

11 std::cout << "Mercedes S-Class:";

12 std::cout << "Median range: " << s.range (0.50) << "\n";

13 printMaxRange (s);

14 }

For both types of cars, Lupo and S the printMaxRange function works as expected, yielding 1003.3 kmfor the Lupo and 722.2 km for the S-Class.

Exercise 3.2 What happens if . . .

• . . . the gasUsage method is removed from the Lupo class?

• . . . the virtual qualifier is removed in front of the gasUsage method in the base class?

21

Page 22: Dumux Handbook

3 Design Patterns

• . . . the fuelTankSize method is removed from the Lupo class?

• . . . the range method in the S class is overwritten?

Static Polymorphism

Dynamic polymorphism has a few disadvantages. The most relevant in the context of DuMux isthat the compiler can not see “inside” the called methods and thus cannot optimize properly. Forexample, modern C++ compilers ’inline’ short methods, i.e. they copy the method’s body to whereit is called. First, inlining allows to save a few instructions by avoiding to jump into and out of themethod. Second, and more importantly, inlining also allows further optimizations which depend onspecific properties of the function arguments (e.g. constant value elimination) or the contents of thefunction body (e.g. loop unrolling). Unfortunately, inlining and other cross-method optimizations aremade next to impossible by dynamic polymorphism. This is because these optimizations are done bythe compiler (i.e. at compile time) whilst the code which actually gets executed is only determined atrun time for virtual methods. To overcome this issue, template programming can be used to achivepolymorphism at compile time. This works by supplying the type of the derived class as an additionaltemplate parameter to the base class. Whenever the base class needs to call back the derived class, thethis pointer of the base class is reinterpreted as a being a pointer to an object of the derived class andthe method is then called on the reinterpreted pointer. This scheme gives the C++ compiler completetransparency of the code executed and thus opens much better optimization oportunities. Since thismechanism completely happens at compile time, it is called “static polymorphism” because the calledmethod cannot be dynamically changed at runtime.

Example 3.3 Using static polymorphism, the base class of example 3.1 can be implemented like:

1 // The base c l a s s . The ’Imp ’ templa te parameter i s the2 // type o f the implementation , i . e . the der i ved c l a s s3 template <class Imp >

4 class Car

5 {public:

6 double gasUsage ()

7 { return 4.5; };

8 double fuelTankSize ()

9 { throw "The derived class needs to implement the fuelTankSize () method"; };

10

11 double range(double fuelTankFillLevel )

12 { return 100* fuelTankFillLevel *asImp_ (). fuelTankSize ()/ asImp_ (). gasUsage (); }

13

14 protected:

15 // r e i n t e r p r e t ’ t h i s ’ as a po in t e r to an o b j e c t o f type ’Imp ’16 Imp &asImp_ () { return *static_cast <Imp*>(this); }

17 };

(Notice the asImp () calls in the range method.) The derived classes may now be defined like this:

18 // A Mercedes S−c l a s s car19 class S : public Car <S>

20 {public:

21 double gasUsage () { return 9.0; };

22 double fuelTankSize () { return 65.0; };

23 };

24

25 // A VW Lupo26 class Lupo : public Car <Lupo >

22

Page 23: Dumux Handbook

3 Design Patterns

27 {public:

28 double gasUsage () { return 2.99; };

29 double fuelTankSize () { return 30.0; };

30 };

Analogous to example 3.1, the two kinds of cars can be used generically within (template) functions:

31 template <class CarType >

32 void printMaxRange (CarType &car)

33 { std::cout << "Maximum Range: " << car.range (1.00) << "\n"; }

34

35 int main()

36 {

37 Lupo lupo;

38 S s;

39 std::cout << "VW Lupo:";

40 std::cout << "Median range: " << lupo.range (0.50) << "\n";

41 printMaxRange (lupo);

42 std::cout << "Mercedes S-Class:";

43 std::cout << "Median range: " << s.range (0.50) << "\n";

44 printMaxRange (s);

45 return 0;

46 }

3.3 Common Template Programming Related Problems

Although C++ template programming opens a few intriguing possibilities, it also has a few disadvan-tages. In this section, a few of them are outlined and some hints on how they can be dealt with areprovided.

Identifier-Name Blow-Up

One particular problem with advanced use of C++ templates is that the canonical identifier names fortypes and methods quickly become really long and unintelligible. For example, a typical error messagegenerated using GCC 4.5 and DUNE-PDELab looks like

test_pdelab.cc :171:9: error: no matching function for call to ‘Dune ::\

PDELab :: GridOperatorSpace <Dune:: PDELab :: PowerGridFunctionSpace <Dune ::\

PDELab :: GridFunctionSpace <Dune::GridView <Dune:: DefaultLeafGridViewTraits \

<const Dune::UGGrid <3>, (Dune:: PartitionIteratorType )4u> >, Dune ::\

PDELab :: Q1LocalFiniteElementMap <double , double , 3>, Dune:: PDELab ::\

NoConstraints , Dumux :: PDELab :: BoxISTLVectorBackend <Dumux :: Properties ::\

TTag:: LensProblem > >, 2, Dune:: PDELab :: GridFunctionSpaceBlockwiseMapper >\

, Dune:: PDELab :: PowerGridFunctionSpace <Dune:: PDELab :: GridFunctionSpace <\

Dune::GridView <Dune:: DefaultLeafGridViewTraits <const Dune::UGGrid <3>, \

(Dune:: PartitionIteratorType )4u> >, Dune:: PDELab :: Q1LocalFiniteElementMap \

<double , double , 3>, Dune:: PDELab :: NoConstraints , Dumux :: PDELab ::\

BoxISTLVectorBackend <Dumux :: Properties ::TTag:: LensProblem > >, 2, Dune ::\

PDELab :: GridFunctionSpaceBlockwiseMapper >, Dumux :: PDELab :: BoxLocalOperator\

<Dumux :: Properties ::TTag:: LensProblem >, Dune:: PDELab ::\

ConstraintsTransformation <long unsigned int , double >, Dune:: PDELab ::\

ConstraintsTransformation <long unsigned int , double >, Dune:: PDELab ::\

ISTLBCRSMatrixBackend <2, 2>, true >:: GridOperatorSpace ()’

This seriously complicates diagnostics. Although there is no full solution for this problem yet, aneffective way of dealing with such kinds of error messages is to ignore the type information and to justlook at the location given at the beginning of the line. If nested templates are used, the lines printed

23

Page 24: Dumux Handbook

3 Design Patterns

by the compiler above the actual error message specify how exactly the code was instantiated (thelines starting with “instantiated from”). In this case it is advisable to look at the innermost sourcecode location of “recently added” source code.

Proliferation of Template Parameters

Templates often need a large number of template parameters. For example, the error message abovewas produced by the following snipplet:

1 int main()

2 {

3 enum {numEq = 2};

4 enum {dim = 3};

5 typedef Dune::UGGrid <dim > Grid;

6 typedef Grid:: LeafGridView GridView;

7 typedef Dune:: PDELab :: Q1LocalFiniteElementMap <double ,double ,dim > FEM;

8 typedef TTAG(LensProblem) TypeTag;

9 typedef Dune:: PDELab :: NoConstraints Constraints;

10 typedef Dune:: PDELab :: GridFunctionSpace <

11 GridView , FEM , Constraints , Dumux :: PDELab :: BoxISTLVectorBackend <TypeTag >

12 >

13 doubleGridFunctionSpace ;

14 typedef Dune:: PDELab :: PowerGridFunctionSpace <

15 doubleGridFunctionSpace ,

16 numEq ,

17 Dune:: PDELab :: GridFunctionSpaceBlockwiseMapper

18 >

19 GridFunctionSpace ;

20 typedef typename GridFunctionSpace :: ConstraintsContainer <double >:: Type

21 ConstraintsTrafo;

22 typedef Dumux :: PDELab :: BoxLocalOperator <TypeTag > LocalOperator ;

23 typedef Dune:: PDELab :: GridOperatorSpace <

24 GridFunctionSpace ,

25 GridFunctionSpace ,

26 LocalOperator ,

27 ConstraintsTrafo ,

28 ConstraintsTrafo ,

29 Dune:: PDELab :: ISTLBCRSMatrixBackend <numEq , numEq >,

30 true

31 >

32 GOS;

33 GOS gos; // i n s t a n t i a t e g r i d operator space34 }

Although the code above is not really intuitivly readable, this does not pose a severe problem aslong as the type (in this case the grid operator space) needs to be specified exactly once in the wholeprogram. If, on the other hand, it needs to be consistend over multiple locations in the source code,measures have to be taken in order to keep the code maintainable.

3.4 Traits Classes

A classic approach to reduce the number of template parameters is to gather all the arguments in aspecial class, a so-called traits class. Instead of writing

1 template <class A, class B, class C, class D>

2 class MyClass {};

one can use

24

Page 25: Dumux Handbook

3 Design Patterns

1 template <class Traits >

2 class MyClass {};

where the Traits class contains public type definitions for A, B, C and D, e.g.

1 struct MyTraits

2 {

3 typedef float A;

4 typedef double B;

5 typedef short C;

6 typedef int D;

7 };

As there is no free lunch, the traits approach comes with a few disadvantages of its own:

1. Hierarchies of traits classes are problematic. This is due to the fact that each level of the hierarchymust be self-contained. As a result it is impossible to define parameters in the base class whichdepend on parameters which only later get specified by a derived traits class.

2. Traits quickly lead to circular dependencies. In practice this means that traits classes can notextract any information from templates which get the traits class as an argument – even if theextracted information does not require the traits class.

To see the point of the first issue, consider the following:

1 struct MyBaseTraits {

2 typedef int Scalar;

3 typedef std::vector <Scalar > Vector;

4 typedef std::list <Scalar > List;

5 typedef std::array <Scalar > Array;

6 typedef std::set <Scalar > Set;

7 };

8

9 struct MyDoubleTraits : public MyBaseTraits {

10 typedef double Scalar;

11 };

12

13 int main() {

14 MyDoubleTraits :: Vector v{1.41421 , 1.73205 , 2};

15 for (int i = 0; i < v.size (); ++i)

16 std::cout << v[i]*v[i] << std::endl;

17 }

Contrary to what is intended, v is a vector of integers. This problem can also not be solved using staticpolymorphism, since it would lead to a cyclic dependency between MyBaseTraits and MyDoubleTraits.

The second issue is illuminated by the following example, where one would expect the MyTraits::

VectorType to be std::vector<double>:

1 template <class Traits >

2 class MyClass {

3 public: typedef double ScalarType;

4 private: typedef typename Traits :: VectorType VectorType;

5 };

6

7 struct MyTraits {

8 typedef MyClass <MyTraits >:: ScalarType ScalarType;

9 typedef std::vector <ScalarType > VectorType

10 };

Although this example seems to be quite pathetic, in practice it is often useful to specify parametersin such a way.

25

Page 26: Dumux Handbook

4 The DuMux Property System

This section is dedicated to the DuMux property system. First, a high level overview over its designand principle ideas is given, then follows a short reference and a short self-contained example.

4.1 Concepts and Features of the DuMux Property System

The DuMux property system was designed as an attempt to mitigate the problems of traits classes.In fact, it can be seen as a traits system which allows easy inheritance and any acyclic dependencyof parameter definitions. Just like traits, the DuMux property system is a compile time mechanism,which means that there are no run-time performance penalties associated with it. It is based on thefollowing concepts:

Property: In the context of the DuMux property system, a property is an arbitrary class body whichmay contain type definitions, values and methods. Each property has a so-called property tagwhich can be seen as a label with its name.

Property Inheritance: Just like normal classes, properties can be arranged in hierarchies. In thecontext of the DuMux property system, nodes of the inheritance hierarchy are called type tags.

It also supports property nesting and introspection. Property nesting means that the definitionof a property can depend on the value of other properties which may be defined for arbitrary levels ofthe inheritance hierarchy. The term introspection denotes the ability to generate diagnostic messageswhich can be used to find out where a certain property was defined and how it was inherited.

4.2 DuMux Property System Reference

All source files which use the DuMux property system should include the header file dumux/common/

propertysystem.hh. Declaration of type tags and property tags as well as defining properties mustbe done inside the namespace Dumux::Properties.

Defining Type Tags

New nodes in the type tag hierarchy can be defined using

NEW_TYPE_TAG(NewTypeTagName , INHERITS_FROM (BaseTagName1 , BaseTagName2 , ...));

where the INHERITS FROM part is optional. To avoid inconsistencies in the hierarchy, each type tagmay be defined only once for a program.

Example:

namespace Dumux {

namespace Properties {

NEW_TYPE_TAG(MyBaseTypeTag1 );

26

Page 27: Dumux Handbook

4 The DuMux Property System

NEW_TYPE_TAG(MyBaseTypeTag2 );

NEW_TYPE_TAG(MyDerivedTypeTag , INHERITS_FROM (MyBaseTypeTag1 , MyBaseTypeTag2 ));

}}

Declaring Property Tags

New property tags – i.e. labels for properties – are declared using

NEW_PROP_TAG(NewPropTagName );

A property tag can be declared arbitrarily often, in fact it is recomended that all properties are declaredin each file where they are used.

Example:

namespace Dumux {

namespace Properties {

NEW_PROP_TAG(MyPropertyTag );

}}

Defining Properties

The value of a property on a given node of the type tag hierarchy is defined using

SET_PROP(TypeTagName , PropertyTagName )

{

// a r b i t r a r y body o f a s t r u c t};

For each program, a property itself can be declared at most once, although properties may be over-written for derived type tags.Also, the following convenience macros are available to define simple properties:

SET_TYPE_PROP (TypeTagName , PropertyTagName , type);

SET_BOOL_PROP (TypeTagName , PropertyTagName , booleanValue );

SET_INT_PROP(TypeTagName , PropertyTagName , integerValue );

SET_SCALAR_PROP (TypeTagName , PropertyTagName , floatingPointValue );

Example:

namespace Dumux {

namespace Properties {

NEW_TYPE_TAG(MyTypeTag );

NEW_PROP_TAG(MyCustomProperty );

NEW_PROP_TAG(MyType );

NEW_PROP_TAG(MyBoolValue );

NEW_PROP_TAG(MyIntValue );

NEW_PROP_TAG(MyScalarValue );

SET_PROP(MyTypeTag , MyCustomProperty)

{

static void print () { std::cout << "Hello , World !\n"; }

};

SET_TYPE_PROP (MyTypeTag , MyType , unsigned int);

SET_BOOL_PROP (MyTypeTag , MyBoolValue , true);

SET_INT_PROP(MyTypeTag , MyIntValue , 12345);

27

Page 28: Dumux Handbook

4 The DuMux Property System

SET_SCALAR_PROP (MyTypeTag , MyScalarValue , 12345.67890);

}}

Un-setting Properties

Sometimes some inherited properties do not make sense for a certain node in the type tag hierarchy.These properties can be explicitly un-set using

UNSET_PROP(TypeTagName , PropertyTagName );

The un-set property can not be set for the same type tag, but of course derived type tags may set itagain.

Example:

namespace Dumux {

namespace Properties {

NEW_TYPE_TAG(BaseTypeTag );

NEW_TYPE_TAG(DerivedTypeTag , INHERITS_FROM (BaseTypeTag ));

NEW_PROP_TAG(TestProp );

SET_TYPE_PROP (BaseTypeTag , TestProp , int);

UNSET_PROP(DerivedTypeTag , TestProp );

// t r y i n g to access the ’ TestProp ’ proper ty f o r ’DerivedTypeTag ’// w i l l t r i g g e r a compi ler error !}}

Converting Tag Names to Tag Types

For the C++ compiler, property and type tags are like ordinary types. Both can thus be used astemplate arguments. To convert a property tag name or a type tag name into the corrosponding type,the macros TTAG(TypeTagName) and PTAG(PropertyTagName) ought to be used.

Retrieving Property Values

The value of a property can be retrieved using

GET_PROP(TypeTag , PropertyTag)

or using the convenience macros

GET_PROP_TYPE (TypeTag , PropertyTag)

GET_PROP_VALUE(TypeTag , PropertyTag)

The first convenience macro retrieves the type defined using SET TYPE PROP and is equivalent to

GET_PROP(TypeTag , PropertyTag ):: type

while the second convenience macro retrieves the value of any property defined using SET {INT,BOOL,SCALAR} -

PROP and is equivalent to

GET_PROP(TypeTag , PropertyTag ):: value

Example:

28

Page 29: Dumux Handbook

4 The DuMux Property System

template <TypeTag >

class MyClass {

// r e t r i e v e the : : va lue a t t r i b u t e o f the ’NumEq ’ proper tyenum { numEq = GET_PROP(TypeTag , PTAG(NumEq )):: value };

// r e t r i e v e the : : va lue a t t r i b u t e o f the ’NumPhases ’ proper ty us ing the convenience macroenum { numPhases = GET_PROP_VALUE(TypeTag , PTAG(NumPhases )) };

// r e t r i e v e the : : type a t t r i b u t e o f the ’ Sca lar ’ proper tytypedef typename GET_PROP(TypeTag , PTAG(Scalar )):: type Scalar;

// r e t r i e v e the : : type a t t r i b u t e o f the ’ Vector ’ proper ty us ing the convenience macrotypedef typename GET_PROP_TYPE (TypeTag , PTAG(Vector )) Vector;

};

Nesting Property Definitions

Inside property definitions there is access to all other properties which are defined somewhere on thetype tag hierarchy. The node for which the current property is requested is available via the keywordTypeTag. Inside property class bodies this can be used to retrieve other properties using the GET PROP

macros.

Example:

SET_PROP(MyModelTypeTag , Vector)

{

private: typedef typename GET_PROP_TYPE (TypeTag , PTAG(Scalar )) Scalar;

public: typedef std::vector <Scalar > type;

};

4.3 A Self-Contained Example

As a concrete example, let us consider some kinds of cars: Compact cars, sedans, trucks, pickups,military tanks and the Hummer-H1 sports utility vehicle. Since all these cars share some characteristics,it makes sense to inherit those from the closest matching car type and only specify the properties whichare different. Thus, an inheritance diagram for the car types above might look like outlined in Figure4.1a.Using the DuMux property system, this inheritance hierarchy is defined by:

1 #include <dumux/common/propertysystem.hh >

2 #include <iostream >

3

4 namespace Dumux {

5 namespace Properties {

6 NEW_TYPE_TAG(CompactCar );

7 NEW_TYPE_TAG(Truck );

8 NEW_TYPE_TAG(Tank);

9 NEW_TYPE_TAG(Sedan , INHERITS_FROM (CompactCar ));

10 NEW_TYPE_TAG(Pickup , INHERITS_FROM (Sedan , Truck ));

11 NEW_TYPE_TAG(HummerH1 , INHERITS_FROM (Pickup , Tank ));

Figure 4.1b lists a few property names which make sense for at least one of the nodes of Figure 4.1a.These property names can be declared as follows:

12 NEW_PROP_TAG(TopSpeed ); // [km/h ]13 NEW_PROP_TAG(NumSeats ); // [ ]14 NEW_PROP_TAG(CanonCaliber ); // [mm]15 NEW_PROP_TAG(GasUsage ); // [ l /100km]

29

Page 30: Dumux Handbook

4 The DuMux Property System

(a) (b)

Figure 4.1: (a) A possible property inheritance graph for various kinds of cars. The lower nodesinherit from higher ones; Inherited properties from nodes on right take precedence over theproperties defined on the left. (b) Property names which make sense for at least one ofthe car types of (a).

16 NEW_PROP_TAG(AutomaticTransmission ); // true / f a l s e17 NEW_PROP_TAG(Payload ); // [ t ]

So far, the inheritance hierarchy and the property names are completely separate. What is missingis setting some values for the property names on specific nodes of the inheritance hierarchy. Let usassume the following:

• For a compact car, the top speed is the gas usage in l/100km times 30, the number of seats is 5and the gas usage is 4 l/100km.

• A truck is by law limited to 100 km/h top speed, the number of seats is 2, it uses 18 l/100kmand has a cargo payload of 35 t.

• A tank exhibits a top speed of 60 km/h, uses 65 l/100km and features a 120 mm diameter canon

• A sedan has a gas usage of 7 l/100km, as well as an automatic transmission, in every otheraspect it is like a compact car.

• A pick-up truck has a top speed of 120 km/h and a payload of 5 t. In every other aspect it islike a sedan or a truck but if in doubt it is more like a truck.

• The Hummer-H1 SUV exhibits the same top speed as a pick-up truck. In all other aspects it issimilar to a pickup and a tank, but if in doubt more like a tank.

Using the DuMux property system, these assumptions are formulated using

18 SET_INT_PROP(CompactCar , TopSpeed , GET_PROP_VALUE(TypeTag , PTAG(GasUsage )) * 30);

19 SET_INT_PROP(CompactCar , NumSeats , 5);

20 SET_INT_PROP(CompactCar , GasUsage , 4);

30

Page 31: Dumux Handbook

4 The DuMux Property System

21

22 SET_INT_PROP(Truck , TopSpeed , 100);

23 SET_INT_PROP(Truck , NumSeats , 2);

24 SET_INT_PROP(Truck , GasUsage , 18);

25 SET_INT_PROP(Truck , Payload , 35);

26

27 SET_INT_PROP(Tank , TopSpeed , 60);

28 SET_INT_PROP(Tank , GasUsage , 65);

29 SET_INT_PROP(Tank , CanonCaliber , 120);

30

31 SET_INT_PROP(Sedan , GasUsage , 7);

32 SET_BOOL_PROP (Sedan , AutomaticTransmission , true);

33

34 SET_INT_PROP(Pickup , TopSpeed , 120);

35 SET_INT_PROP(Pickup , Payload , 5);

36

37 SET_INT_PROP(HummerH1 , TopSpeed , GET_PROP_VALUE(TTAG(Pickup), PTAG(TopSpeed )));

At this point, the Hummer-H1 has a 120 mm canon which it inherited from its military ancestor. Itcan be removed by

38 UNSET_PROP(HummerH1 , CanonCaliber );

39

40 }} // c l o s e namespaces

Now property values can be retrieved and some diagnostic messages can be generated. For example

41 int main()

42 {

43 std::cout << "top speed of sedan: " << GET_PROP_VALUE(TTAG(Sedan), PTAG(TopSpeed )) << "\n";

44 std::cout << "top speed of truck: " << GET_PROP_VALUE(TTAG(Truck), PTAG(TopSpeed )) << "\n";

45

46 std::cout << PROP_DIAGNOSTIC (TTAG(Sedan), PTAG(TopSpeed ));

47 std::cout << PROP_DIAGNOSTIC (TTAG(HummerH1), PTAG(CanonCaliber ));

48 }

will yield the following output:

1 top speed of sedan: 210

2 top speed of truck: 100

3 Property ’TopSpeed ’ for type tag ’Sedan ’

4 inherited from ’CompactCar ’

5 defined at test_propertysystem .cc:90

6 Property ’CanonCaliber ’ for type tag ’HummerH1 ’

7 explicitly unset at test_propertysystem .cc:113

31

Page 32: Dumux Handbook

5 Tutorial

In DuMux two sorts of models are implemented: Fully-coupled models and decoupled models. In thefully-coupled models a flow system is described by a system of strongly coupled equations which can bemass balance equations, balance equations of components, energy balance equations, etc. In contrast adecoupled model consists of a pressure equation which is iteratively coupled to a saturation equation,concentration equations, energy balance equations, etc.Examples for different kinds of both coupled and decoupled models are isothermal two-phase models,

isothermal two-phase two-component models, non-isothermal two-phase models, non-isothermal two-phase two-component models, etc.In section 5.1 a short introduction about the box method is given. The box method is used for the

spatial discretization of the system of equations. The other two sections of the tutorial demonstratehow to solve problems first using a coupled model (section 5.2) and second using a decoupled model(section 5.3). Being the easiest case, an isothermal two-phase system (two fluid phases, one solidphase) will be considered.

5.1 Box method - A short introduction

For the spatial discretization the so called BOX-method is used which unites the advantages of thefinite-volume (FV) and finite-element (FE) methods.First, the model domain G is discretized with a FE mesh consisting of nodes i and corresponding

elements Ek. Then, a secondary FV mesh is constructed by connecting the midpoints and barycentersof the elements surrounding node i creating a box Bi around node i (see Figure 5.1a).The FE mesh divides the box Bi into subcontrolvolumes (scv’s) bki (see Figure 5.1b). Figure 5.1c

shows the finite element Ek and the scv’s bki inside Ek, which belong to four different boxes Bi. Alsonecessary for the discretization are the faces of the subcontrolvolumes (scvf’s) ekij between the scv’s bkiand bkj , where |ekij | is the length of the scvf. The integration points xkij on ekij and the outer normal

vector nkij are also to be defined (see Figure 5.1c).

The advantage of the FE method is that unstructured grids can be used, while the FV method ismass conservative. The idea is to apply the FV method (balance of fluxes across the interfaces) toeach FV box Bi and to get the fluxes across the interfaces ekij at the integration points xkij from theFE approach. Consequently, at each scvf the following expression results:

f(u(xkij)) · nkij |e

kij | with u(xkij) =

i

Ni(xkij) · ui. (5.1)

In the following the discretization of the balance equation is going to be derived. From thereynoldss transport theorem follows the general balance equation:

32

Page 33: Dumux Handbook

5 Tutorial

scvi

k

FE mesh

secondary FV mesh

node i

Ek

Bi

Ek

Bi

i

i

j

xij

k

eij

k

a) b)

c)

nij

k

bi

k

Figure 5.1: Discretization of the BOX-method

G

∂tu dG

︸ ︷︷ ︸

1

+

∂G

(vu+w) · n dΓ

︸ ︷︷ ︸

2

=

G

q dG

︸ ︷︷ ︸

3

(5.2)

f(u) =

G

∂u

∂tdG+

G

∇ · [vu+w(u)]︸ ︷︷ ︸

F (u)

dG−

G

q dG = 0 (5.3)

where term 1 describes the changes of entity u within a control volume over time, term 2 the advec-tive, diffusive and dispersive fluxes over the interfaces of the control volume and term 3 is the sourceand sink term. G denotes the model domain and F (u) = F (v, p) = F (v(x, t), p(x, t)).

Like the FE method, the BOX-method follows the principle of weighted residuals. In the functionf(u) the unknown u is approximated by discrete values at the nodes of the FE mesh ui and linearbasis functions Ni yielding an approximate function f(u). For u ∈ {v, p, xκ} this means

p =∑

i

Nipi (5.4)

v =∑

i

Niv (5.5)

xκ =∑

i

Nixκ (5.6)

∇p =∑

i

∇Nipi (5.7)

∇v =∑

i

∇Niv (5.8)

∇xκ =∑

i

∇Nixκ. (5.9)

Due to the approximation with node values and basis functions the differential equations are notexactly fulfilled anymore but a residual ε is produced.

33

Page 34: Dumux Handbook

5 Tutorial

f(u) = 0 ⇒ f(u) = ε (5.10)

Application of the principle of weighted residuals, meaning the multiplication of the residual ε witha weighting function Wj and claiming that this product has to vanish within the whole domain,

G

Wj · ε!= 0 with

j

Wj = 1 (5.11)

yields the following equation:

G

Wj∂u

∂tdG+

G

Wj · [∇ · F (u)] dG−

G

Wj · q dG =

G

Wj · ε dG!= 0. (5.12)

Then, the chain rule and the green-gaussian integral theorem are applied.

G

Wj∂∑

iNiui∂t

dG+

∂G

[Wj · F (u)] · n dΓG +

G

∇Wj · F (u) dG−

G

Wj · q dG = 0 (5.13)

A mass lumping technique is applied by assuming that the storage capacity is reduced to the nodes.This means that the integrals Mi,j =

GWj Ni dG are replaced by the mass lumping term M lump

i,j

which is defined as:

M lumpi,j =

{∫

GWj dG =

GNi dG = Vi i = j

0 i 6= j(5.14)

where Vi is the volume of the FV box Bi associated with node i. The application of this assumptionin combination with

GWj q dG = Vi q yields

Vi∂ui∂t

+

∂G

[Wj · F (u)] · n dΓG +

G

∇Wj · F (u) dG− Vi · q = 0 (5.15)

Defining the weighting function Wj to be piecewise constant over a control volume box Bi

Wj(x) =

{

1 x ∈ Bi

0 x /∈ Bi

(5.16)

causes ∇Wj = 0:

Vi∂ui∂t

+

∂Bi

[Wj · F (u)] · n dΓBi− Vi · q = 0. (5.17)

The consideration of the time discretization and inserting Wj = 1 finally leads to the discretizedform which will be applied to the mathematical flow and transport equations:

Viun+1i − uni

∆t+

∂Bi

F (un+1) · n dΓBi− Vi q

n+1 = 0 (5.18)

34

Page 35: Dumux Handbook

5 Tutorial

5.2 Solving a problem using a Fully-Coupled Model

The process of solving a problem using DuMux can be roughly divided into four parts:

1. The geometry of the problem and correspondingly a grid have to be defined.

2. Material properties and constitutive relationships have to be selected.

3. Boundary conditions as well as initial conditions have to be defined.

4. A suitable model has to be chosen.

The problem that is solved in this tutorial is illustrated in Figure 5.2. A rectangular domain withno flow boundaries on the top and on the bottom, which is initially saturated with oil, is considered.Water infiltrates from the left side into the domain. Gravity effects are neglected.

x

yno flow

no flow

water oil

pw = 2× 105 [Pa] pwinitial= 2× 105 [Pa]

Sn = 0 Sninitial= 1

qw = 0[

kgm2s

]

qn = −3× 10−2[

kgm2s

]

Figure 5.2: Geometry of the tutorial problem with initial and boundary conditions.

The equations that are solved here are the mass balances of oil and water:

∂(φSw w)

∂t−∇ ·

(

wkrwµw

K ∇pw

)

− qw = 0 (5.19)

∂(φSo o)

∂t−∇ ·

(

okroµo

K ∇po

)

− qo = 0 (5.20)

5.2.1 The main file

Listing 1 shows the main file tutorial/tutorial coupled.cc for the coupled two-phase model. Thisfile needs to be executed to solve the problem described above.

Listing 1 (File tutorial/tutorial coupled.cc)

1 #include "config.h"

2 #include "tutorialproblem_coupled .hh"

3

4 #include <dune/common/mpihelper.hh >

5 #include <iostream >

6

7 void usage(const char *progname)

8 {

9 std::cout << "usage: " << progname << " [--restart restartTime] tEnd dt\n";

10 exit (1);

11 };

12

35

Page 36: Dumux Handbook

5 Tutorial

13 int main(int argc , char ** argv)

14 {

15 try {

16 typedef TTAG(TutorialProblemCoupled ) TypeTag;

17 typedef GET_PROP_TYPE (TypeTag , PTAG(Grid)) Grid;

18 typedef GET_PROP_TYPE (TypeTag , PTAG(TimeManager )) TimeManager;

19 typedef GET_PROP_TYPE (TypeTag , PTAG(Problem )) Problem;

20

21 // I n i t i a l i z e MPI22 Dune:: MPIHelper :: instance(argc , argv);

23

24 // parse the command l i n e arguments25 if (argc < 3)

26 usage(argv [0]);

27

28 // parse r e s t a r t time i f r e s t a r t i s r eques t ed29 int argPos = 1;

30 bool restart = false;

31 double restartTime = 0;

32 if (std:: string("--restart") == argv[argPos ]) {

33 restart = true;

34 ++ argPos;

35

36 std:: istringstream (argv[argPos ++]) >> restartTime;

37 }

38

39 // read the i n i t i a l time s t ep and the end time40 if (argc - argPos != 2)

41 usage(argv [0]);

42

43 double tEnd , dt;

44 std:: istringstream (argv[argPos ++]) >> tEnd;

45 std:: istringstream (argv[argPos ++]) >> dt;

46

47 // crea t e the g r i d48 Grid *gridPtr = GET_PROP(TypeTag , PTAG(Grid )):: create ();

49

50 // crea t e time manager r e s p on s i b l e f o r g l o b a l s imu la t ion con t ro l51 TimeManager timeManager;

52

53 // i n s t a n t i a t e the problem on the l e a f g r i d54 Problem problem(timeManager , gridPtr ->leafView ());

55 timeManager.init(problem , 0, dt , tEnd , !restart );

56 // load some p r e v i ou s l y saved s t a t e from d i s k57 if (restart)

58 problem.restart(restartTime );

59 // run the s imu la t ion60 timeManager.run();

61 return 0;

62 }

63 catch (Dune:: Exception &e) {

64 // Catch excep t i ons thrown somewhere in DUNE65 std::cerr << "Dune reported error: " << e << std::endl;

66 }

67 catch (...) {

68 // Catch excep t i ons thrown e l sewhere69 std::cerr << "Unknown exception thrown !\n";

70 throw;

71 }

72

73 return 3;

74 }

36

Page 37: Dumux Handbook

5 Tutorial

From line 1 to line 5 the DUNE and DuMux files which contain the needed functions and classes areincluded.At line 16 the type tag of the problem which is going to be simulated is set. All other data types

can be retrieved by the DuMux property system and only depend on this single type tag. Retrievingthem is done between line 17 and 19. For an introduction to the property system, see section 4.The first thing which should be done at run time is to initialize the message passing interface using

DUNE’s MPIHelper class. Line 22 is essential if the simulation is intended to be run on more than oneprocessor at the same time. Next, the command line arguments are parsed starting at line 25 until line45. In this example, it is checked if and from which time on a previous run of the simulation shouldbe restarted. Furthermore, we parse the time when the simulation ends and the initial time step size.After this, a grid is created in line 48 and the problem is instantiated for its leaf grid view in line

54. Finally, on line 58 a state written to disk by a previous simulation run is restored if requested bythe user. The simulation procedure is started at line 60.

5.2.2 The problem class

When solving a problem using DuMux, the most important file is the so-called problem file as shownin listing 2 of tutorialproblem coupled.hh.

Listing 2 (File tutorial/tutorialproblem coupled.hh)

1 #ifndef DUMUX_TUTORIALPROBLEM_COUPLED_HH // guardian macro2 #define DUMUX_TUTORIALPROBLEM_COUPLED_HH // guardian macro3

4 // the numerical model5 #include <dumux/boxmodels /2p/2 pmodel.hh >

6

7 // the DUNE gr id used8 #include <dune/grid/sgrid.hh >

9

10 // s p a t i a l y dependent parameters11 #include "tutorialspatialparameters_coupled .hh"

12

13 // the components t ha t are used14 #include <dumux/material/components/h2o.hh >

15 #include <dumux/material/components/oil.hh >

16

17 namespace Dumux

18 {

19

20 // forward de c l a r a t i on o f the problem c l a s s21 template <class TypeTag >

22 class TutorialProblemCoupled ;

23

24 namespace Properties

25 {

26 // crea t e a new type tag f o r the problem27 NEW_TYPE_TAG(TutorialProblemCoupled , INHERITS_FROM (BoxTwoP ));

28

29 // Set the ”Problem” proper ty30 SET_PROP(TutorialProblemCoupled , Problem)

31 { typedef Dumux :: TutorialProblemCoupled <TypeTag > type ;};

32

33 // Set the g r i d34 SET_PROP(TutorialProblemCoupled , Grid)

35 {

36 typedef Dune::SGrid <2,2> type;

37

Page 38: Dumux Handbook

5 Tutorial

37 static type *create ()

38 {

39 typedef typename type:: ctype ctype;

40 Dune:: FieldVector <int , 2> cellRes; // vec to r ho ld ing r e s o l u t i o n o f the g r i d41 Dune:: FieldVector <ctype , 2> lowerLeft (0.0); // Coordinate o f lower l e f t corner o f the g r i d42 Dune:: FieldVector <ctype , 2> upperRight; // Coordinate o f upper r i g h t corner o f the g r i d43 cellRes [0] = 100;

44 cellRes [1] = 1;

45 upperRight [0] = 300;

46 upperRight [1] = 60;

47 return new Dune::SGrid <2,2>(cellRes ,

48 lowerLeft ,

49 upperRight );

50 }

51 };

52

53 // Set the we t t ing phase54 SET_PROP(TutorialProblemCoupled , WettingPhase)

55 {

56 private: typedef typename GET_PROP_TYPE (TypeTag , PTAG(Scalar )) Scalar;

57 public: typedef Dumux :: LiquidPhase <Scalar , Dumux ::H2O <Scalar > > type;

58 };

59

60 // Set the non−wet t ing phase61 SET_PROP(TutorialProblemCoupled , NonwettingPhase )

62 {

63 private: typedef typename GET_PROP_TYPE (TypeTag , PTAG(Scalar )) Scalar;

64 public: typedef Dumux :: LiquidPhase <Scalar , Dumux ::Oil <Scalar > > type;

65 };

66

67

68 // Set the s p a t i a l parameters69 SET_PROP(TutorialProblemCoupled , SpatialParameters )

70 { typedef Dumux :: TutorialSpatialParametersCoupled <TypeTag > type; };

71

72 // Disab l e g r a v i t y73 SET_BOOL_PROP (TutorialProblemCoupled , EnableGravity , false );

74 }

75

76 /∗ !77 ∗ \ ingroup TwoPBoxModel78 ∗79 ∗ \ b r i e f Tutor ia l problem fo r a f u l l y coup led twophase box model .80 ∗/81

82 // De f i n i t i on o f the ac tua l problem83 template <class TypeTag >

84 class TutorialProblemCoupled : public TwoPProblem <TypeTag >

85 {

86 typedef TwoPProblem <TypeTag > ParentType;

87 typedef typename GET_PROP_TYPE (TypeTag , PTAG(Scalar )) Scalar;

88 typedef typename GET_PROP_TYPE (TypeTag , PTAG(GridView )) GridView;

89

90 // Grid dimension91 enum { dim = GridView :: dimension };

92

93 // Types from DUNE−Grid94 typedef typename GridView :: template Codim <0>:: Entity Element;

95 typedef typename GridView :: template Codim <dim >:: Entity Vertex;

96 typedef typename GridView :: Intersection Intersection;

97 typedef Dune:: FieldVector <Scalar , dim > GlobalPosition;

98

99 // Dumux s p e c i f i c t ypes

38

Page 39: Dumux Handbook

5 Tutorial

100 typedef typename GET_PROP_TYPE (TypeTag , PTAG(TimeManager )) TimeManager;

101 typedef typename GET_PROP_TYPE (TypeTag , PTAG(TwoPIndices )) Indices;

102 typedef typename GET_PROP_TYPE (TypeTag , PTAG(PrimaryVariables )) PrimaryVariables;

103 typedef typename GET_PROP_TYPE (TypeTag , PTAG(BoundaryTypes )) BoundaryTypes ;

104 typedef typename GET_PROP_TYPE (TypeTag , PTAG(FVElementGeometry )) FVElementGeometry ;

105

106 public:

107 TutorialProblemCoupled (TimeManager &timeManager ,

108 const GridView &gridView)

109 : ParentType(timeManager , gridView)

110 {

111 }

112

113 // Sp e c i f i e s the problem name . This i s used as a p r e f i x f o r f i l e s114 // generated by the s imu la t ion .115 const char *name() const

116 { return "tutorial_coupled"; }

117

118 // ! Returns t rue i f a r e s t a r t f i l e shou ld be wr i t t en .119 /∗ The d e f a u l t behaviour i s to wr i t e no r e s t a r t f i l e .120 ∗/121 bool shouldWriteRestartFile () const

122 {

123 return false;

124 }

125

126 // ! Returns t rue i f the current s o l u t i on shou ld be wr i t t en to d i s k ( i . e . as a VTK f i l e )127 /∗ ! The d e f a u l t behaviour i s to wr i t e out the s o l u t i on fo r128 ∗ every time s t ep . Else , the user has to change the d i v i s o r in t h i s func t i on .129 ∗/130 bool shouldWriteOutput () const

131 {

132 return this ->timeManager (). timeStepIndex () > 0 &&

133 (this ->timeManager (). timeStepIndex () % 1 == 0);

134 }

135

136 // Return the temperature wi th in a f i n i t e volume . We use cons tant137 // 10 degrees Ce l s i u s .138 Scalar temperature(const Element &element ,

139 const FVElementGeometry &fvElemGeom ,

140 int scvIdx) const

141 { return 283.15; };

142

143 // Sp e c i f i e s which kind o f boundary cond i t i on shou ld be used f o r144 // which equat ion fo r a f i n i t e volume on the boundary .145 void boundaryTypes (BoundaryTypes &BCtypes , const Vertex &vertex) const

146 {

147 const GlobalPosition &pos = vertex.geometry (). center ();

148 if (pos [0] < eps_) // D i r i c h l e t cond i t i ons on l e f t boundary149 BCtypes.setAllDirichlet ();

150 else // neuman fo r the remaining boundaries151 BCtypes.setAllNeumann ();

152

153 }

154

155 // Evaluate the D i r i c h l e t boundary cond i t i ons f o r a f i n i t e volume156 // on the g r i d boundary . Here , the ’ va lue s ’ parameter s t o r e s157 // primary v a r i a b l e s .158 void dirichlet(PrimaryVariables &values , const Vertex &vertex) const

159 {

160 values[Indices :: pwIdx] = 200.0 e3; // 200 kPa = 2 bar161 values[Indices :: SnIdx] = 0.0; // 0 % o i l s a tu ra t i on on l e f t boundary162 }

39

Page 40: Dumux Handbook

5 Tutorial

163

164 // Evaluate the boundary cond i t i ons f o r a Neumann boundary165 // segment . Here , the ’ va lue s ’ parameter s t o r e s the mass f l u x in166 // normal d i r e c t i on o f each phase . Negat ive va lue s mean i n f l u x .167 void neumann(PrimaryVariables &values ,

168 const Element &element ,

169 const FVElementGeometry &fvElemGeom ,

170 const Intersection &isIt ,

171 int scvIdx ,

172 int boundaryFaceIdx ) const

173 {

174 const GlobalPosition &pos =

175 fvElemGeom.boundaryFace[boundaryFaceIdx ]. ipGlobal;

176 Scalar right = this ->bboxMax ()[0];

177 // e x t r a c t i on o f o i l on the r i g h t boundary f o r approx . 1 . e6 seconds178 if (pos [0] > right - eps_) {

179 // o i l o u t f l u x o f 30 g /(m ∗ s ) on the r i g h t boundary .180 values[Indices :: contiWEqIdx] = 0;

181 values[Indices :: contiNEqIdx] = 3e-2;

182 } else {

183 // no−f l ow on the remaining Neumann−boundaries .184 values[Indices :: contiWEqIdx] = 0;

185 values[Indices :: contiNEqIdx] = 0;

186 }

187 }

188

189 // Evaluate the i n i t i a l va lue f o r a con t ro l volume . For t h i s190 // method , the ’ va lue s ’ parameter s t o r e s primary v a r i a b l e s .191 void initial(PrimaryVariables &values ,

192 const Element &element ,

193 const FVElementGeometry &fvElemGeom ,

194 int scvIdx) const

195 {

196 values[Indices :: pwIdx] = 200.0 e3; // 200 kPa = 2 bar197 values[Indices :: SnIdx] = 1.0;

198 }

199

200 // Evaluate the source term fo r a l l phases wi th in a g iven201 // sub−contro l−volume . In t h i s case , the ’ va lue s ’ parameter s t o r e s202 // the ra t e mass generated or ann i h i l a t e per volume uni t . Po s i t i v e203 // va lue s mean tha t mass i s crea ted .204 void source(PrimaryVariables &values ,

205 const Element &element ,

206 const FVElementGeometry &fvElemGeom ,

207 int scvIdx) const

208 {

209 values[Indices :: contiWEqIdx] = 0.0;

210 values[Indices :: contiNEqIdx ]= 0.0;

211 }

212

213 private:

214 // smal l e p s i l on va lue215 static const Scalar eps_ = 3e-6;

216 };

217 }

218

219 #endif

First, a new type tag is created for the problem in line 27. In this case, the new type tag inheritsall properties defined for the BoxTwoP type tag, which means that for this problem the two-phase boxmodel is chosen as discretization scheme. On line 30, a problem class is attached to the new type tag,while the grid which is going to be used is defined in line 34 – in this case that is SGrid. Since there’s

40

Page 41: Dumux Handbook

5 Tutorial

no uniform mechanism to allocate grids in DUNE, the Grid property also contains a static create()method which provides just that. Therein, the three variables of Type Dune::FieldVector define thelower left corner of the domain (L), the upper right corner of the domain (H) and the number of cellsin x and y direction (N). Next, the appropriate fluid system, that specifies both information about thefluid mixture as well as about the pure substances, has to be chosen. The two-phase model defaults tothe FluidSystem2P which assumes immiscibility of the phases, but requires that the wetting and non-wetting phases are explicitly set. In this case, liquid water which uses the relations from IAPWS’97 [19]is chosen as the wetting phase on line 57 and a liquid model oil is chosen as the non-wetting phase online 64.For all parameters that depend on space, such as the properties of the soil, the specific spatial

parameters for the problem of interest are specified in line 69. The final property, which is set on line73, is optional and tells the model not to use gravity.Parameters which are specific to a set-up – like boundary and initial conditions, source terms or

temperature within the domain – but are required to solve the differential equations of the modelsare specified via a problem class. If the two-phase box model is used, this class must be derived fromTwoPBoxProblem as done on line 84.The problem class always has at least five methods:

• Amethod boundaryTypes() specifying the kind of boundary conditions to be used for a boundarysegment

• A method dirichlet() specifying the actual values for the Dirichlet conditions on a boundarysegment

• A method neumann() specifying the actual values for the Neumann conditions on a boundarysegment

• A method for source or sink terms called source()

• A method called initial() for specifying the initial condition.

For the definition of the the boundary condition types and of the values of the Dirichlet boundaries,two parameters are required:

values: A vector which stores the result of the method. What the values in this vector mean isdepending on the method: For dirichlet() it contains the actual values of the primary variables,for boundaryTypes() it contains the boundary condition type. It has as many entries as themodel has primary variables / equations. For the typical case where all equations have thesame boundary condition at a certain position, there are two methods that set the appropriateconditions for all primary variables / equations: Either setAllDirichlet() or setAllNeumann()

vertex: The boundary condition and the Dirichlet values are specified at the vertex, which representsa subcontrol volume. This avoids to specify two different boundary condition types at one sub-control volume. Be aware that the second parameter is a Dune grid entity with the codimensiondim.

To ensure that no boundaries are undefined, a small safeguard value eps is usually added whencomparing spatial coordinates. The left boundary is hence not assigned where the first coordinate isequal to zero, but where it is smaller than a very small value eps .

41

Page 42: Dumux Handbook

5 Tutorial

Methods which make statements about boundary segments of the grid (i.e. neumann()) get sixparameters:

values: A vector neumann(), in which the mass fluxes per area unit over the boundary segment arespecified.

element: The element of the grid where the boundary segment is located.

fvElemGeometry: The finite-volume geometry induced on the finite element by the box scheme.

isIt: The Intersection of the boundary segment as given by the grid.

scvIdx: The index of the sub-control volume in fvElementGeometry adjacent to the boundary segment.

boundaryFaceIdx: The index of the boundary face in fvElementGeometry which represents the bound-ary segment.

Similarly, the initial() and source() methods specify properties of sub-control volumes and thusonly get values, element, fvElemGeom and scvIdx as parameters.In addition to these five methods, there might be some model-specific methods. If the isothermal

two-phase model is used, this includes for example a temperature() method which returns the tem-perature in Kelvin of the fluids and the rock matrix in the domain. This temperature is then usedby the model to calculate fluid properties which possibly depend on it, e.g. density. The bboxMax()

method that is used here, is a vector that provides information about the spatial extends of the sim-ulation domain. This method and the respective bboxMin() method can be found in the base classDumux::BoxProblem<TypeTag>.

5.2.3 Defining fluid properties

The DuMux distribution includes some common substances which can be used out of the box. Theproperties of the pure substances (such as the component nitrogen, water, or pseudo-component air)are stored in header files in the folder dumux/material/components. Each of these files defines a classwith the same name as the component but starting with a capital letter, e.g. Water, and are derivedfrom Component.Most often, when two or more components are considered, fluid interactions such as solubility

effects come into play and properties of mixtures such as the density are of interest. These interac-tions are defined in a specific fluidsystem in the folder dumux/material/fluidsystems. It featuresmethods returning fluid properties like density, enthalpy, viscosity, etc. by accessing the pure com-ponents as well as binary coefficients such as Henry or diffusion coefficients, which are stored indumux/material/binarycoefficients. New fluids which are not yet available in the DuMux distri-bution can be defined analogously.

5.2.4 The definition of the parameters that are dependent on space

In DuMux, the properties of the porous medium such as intrinsic permeability, the porosity, the heat

capacity as well as the heat conductivity can be defined in space using a so-called spatial parameters

class. However, because the soil also has an effect on the material laws of the fluids (e.g. capillarity),

42

Page 43: Dumux Handbook

5 Tutorial

their selection and definition of their attributes (e.g. residual saturations) are also accomplished inthe spatial parameters.The base class Dumux::BoxSpatialParameters<TypeTag> holds a general averaging procedure for

vertex-centered box-methods.Listing 3 shows the file tutorialspatialparameters_coupled.hh:

Listing 3 (File tutorial/tutorialspatialparameters coupled.hh)

1 #ifndef TUTORIALSPATIALPARAMETERS_COUPLED_HH

2 #define TUTORIALSPATIALPARAMETERS_COUPLED_HH

3

4 // inc lude parent spa t i a l pa rame te r s5 #include <dumux/material/spatialparameters/boxspatialparameters.hh >

6

7 // inc lude mater ia l laws8 #include <dumux/material/fluidmatrixinteractions /2p/regularizedbrookscorey .hh >

9 #include <dumux/material/fluidmatrixinteractions /2p/efftoabslaw.hh >

10

11 namespace Dumux

12 {

13 /∗ !14 ∗ \ ingroup TwoPBoxModel15 ∗16 ∗ \ b r i e f The s p a t i a l parameters f o r the f u l l y coup led t u t o r i a l problem17 ∗ which uses the twophase box model .18 ∗/19 template <class TypeTag >

20 class TutorialSpatialParametersCoupled : public BoxSpatialParameters <TypeTag >

21 {

22 // Get in format ions f o r current implementation v ia proper ty system23 typedef typename GET_PROP_TYPE (TypeTag , PTAG(Grid)) Grid;

24 typedef typename GET_PROP_TYPE (TypeTag , PTAG(GridView )) GridView;

25 typedef typename GET_PROP_TYPE (TypeTag , PTAG(Scalar )) Scalar;

26 enum

27 {

28 dim = Grid::dimension ,

29 dimWorld = Grid:: dimensionworld ,

30 };

31 typedef Dune:: FieldVector <Scalar , dim > GlobalPosition;

32

33 // Get o b j e c t t ypes f o r func t i on arguments34 typedef typename GET_PROP_TYPE (TypeTag , PTAG(FVElementGeometry )) FVElementGeometry ;

35 typedef typename Grid:: Traits :: template Codim <0>:: Entity Element;

36

37 // s e l e c t mater ia l law to be used38 typedef RegularizedBrooksCorey <Scalar > EffectiveMaterialLaw;

39

40 public:

41 // adapter f o r a b s o l u t e law42 typedef EffToAbsLaw <EffectiveMaterialLaw > MaterialLaw;

43 // determine appropr ia t e parameters depening on s e l e c t e d materialLaw44 typedef typename MaterialLaw :: Params MaterialLawParams;

45

46

47 // method re turn ing the i n t r i n s i c p e rmeab i l i t y t ensor K depending48 // on the po s i t i on wi th in the domain49 const Dune:: FieldMatrix <Scalar , dim , dim > &intrinsicPermeability (const Element &element ,

50 const FVElementGeometry &fvElemGeom ,

51 int scvIdx) const

52 {

53 return K_;

54 }

43

Page 44: Dumux Handbook

5 Tutorial

55

56 // method re turn ing the po ro s i t y o f the porous matrix depending on57 // the po s i t i on wi th in the domain58 double porosity(const Element &element ,

59 const FVElementGeometry &fvElemGeom ,

60 int scvIdx) const

61 {

62 return 0.2;

63 }

64

65 // re turn the parameter o b j e c t f o r the mater ia l law ( i . e . Brooks−Corey )66 // which may vary with the s p a t i a l p o s i t i on67 const MaterialLawParams & materialLawParams (const Element &element ,

68 const FVElementGeometry &fvElemGeom ,

69 int scvIdx) const

70 {

71 return materialParams_ ;

72 }

73

74 // cons t ruc to r75 TutorialSpatialParametersCoupled (const GridView& gridView) :

76 BoxSpatialParameters <TypeTag >( gridView),

77 K_(0)

78 {

79 // s e t main d iagona l e n t r i e s o f the pe rmeab i l i t y t ensor to a va lue80 // s e t t i n g to one va lue means : i s o t r op i c , homogeneous81 for (int i = 0; i < dim; i++)

82 K_[i][i] = 1e-7;

83

84 // s e t r e s i d ua l s a t u ra t i on s85 materialParams_ .setSwr (0.0);

86 materialParams_ .setSnr (0.0);

87

88 // parameters o f Brooks & Corey Law89 materialParams_ .setPe (500.0);

90 materialParams_ .setAlpha (2);

91 }

92

93 private:

94 Dune:: FieldMatrix <Scalar , dim , dim > K_;

95 // Object t ha t ho ld s the va lue s /parameters o f the s e l e c t e d mater ia l law .96 MaterialLawParams materialParams_ ;

97 };

98 } // end namespace99 #endif

First, a certain material law that best describes the problem at hand has to be selected in line 38.DuMux provides several material laws in the folder dumux/material/fluidmatrixinteractions. Theselected one – here it is a relation according to a regularized version of Brooks & Corey – is includedin line 8. After the selection, an adapter in line 42 translates between the law for effective values (theBrooks & Corey model) and the saturations generated as simulations results, i.e. residual saturationsare considered. As the applied raw law knows best which kind of parameters are necessary, it providesa parameter class RegularizedBrooksCoreyParams that is accessible via the member Params anddefined in line 44. The material law object is now instantiated correctly as a private object in line 96.In line 49 the function returning the intrinsic permeability can be found. As can be seen, the

function has to be called with three different arguments. (Element) is again the current element,which also holds information about its geometry and position, the second argument (fvElemGeom)holds information about the finite-volume geometry induced by the box-method, and the third defines

44

Page 45: Dumux Handbook

5 Tutorial

the index of the current sub-control volume. The intrinsic permeability is a tensor and is thus returnedin form of a dim× dim-matrix where dim is the dimension of the problem.The function porosity() defined in line 58 is called with the same arguments as the permeability

function described before and returns the porosity dependent on the position in the domain.Next, the method materialLawParams() defines in line 67 which materialLawParams object should

be applied at this specific position. Although in this case only one objects is returned, in generalthe problem may be heterogeneous, demanding for different objects at different positions in space.While the selection of the type of this object was already explained (line 8), some specific parametervalues of the applied material law are still needed. This is done in the constructor body (line 85).Depending on the type of the materialLaw object, the adequate set-methods are provided by theobject to access all necessary parameters for the applied material law. The name of the access /set functions as well as the rest of the implementation of the material description can be found indumux/material/fluidmatrixinteractions/2p.

5.2.5 Exercises

The following exercises will give you the opportunity to learn how you can change soil parameters,boundary conditions and fluid properties in DuMux.

Exercise 1

For Exercise 1 you only have to make some small changes in the tutorial files.

a) Run the ModelTo get an impression what the results should look like you can first run the original version ofthe coupled tutorial model by typing ./tutorial coupled 5e5 10. The first number behindthe simulation name defines the timespan of the simulation run in seconds, the second numberdefines the initial time step size. Note that the time step size is automatically optimized duringthe simulation. For the visualization with paraview please refer to 2.2.

b) Changing the Model Domain and the Boundary ConditionsChange the size of the model domain so that you get a rectangle with edge lengths of x = 400mand y = 500m and with discretization lengths of ∆x = 20 m and ∆y = 20 m.

Change the boundary conditions in the file tutorialproblem coupled.hh so that water entersfrom the bottom and oil is extracted from the top boundary. The right and the left boundaryshould be closed for water and oil fluxes.

Compile the main file by typing make tutorial coupled and run the model.

c) Changing FluidsNow you can change the fluids. Use DNAPL instead of Oil and Brine instead of Water. To dothat you have to select different components via the property system in the problem file:

a) Brine: The class Dumux::Brine acts as a adapter to the fluid system that alters a pure waterclass by adding some salt. Hence, the class Dumux::Brine uses a pure water class, such asDumux::H2O, as a second template argument after the data type <Scalar> as a templateargument (be aware to use the complete water class with its own template parameter).

45

Page 46: Dumux Handbook

5 Tutorial

b) DNAPL: A standard set of chemical substances, such as Oil and Brine, is already included(via a list of #include .. commandos) and hence easy accessible by default. This isnot the case for the class Dumux::SimpleDNAPL, however, which is located in the folderdumux/material/components/. Try to include the file as well as select the component viathe property system.

If you want to take a closer look how the fluid classes are defined and which substances are alreadyavailable please browse through the files in the directory /dumux/material/components.

d) Use the DuMux fluid systemDuMux usually organizes fluid mixtures via a fluidsystem. In order to include a fluidsystemyou first have to comment the lines 54 to 65 in the problem file. If you use eclipse, this can easilybe done by pressing str + shift + 7 – the same as to cancel the comment later on.Now include the file fluidsystems/h2o n2 system.hh in the material folder, and set a propertyFluidSystem with the appropriate type, Dumux::H2O N2 System<TypeTag>. However, the com-plicated fluidsystem uses tabularized fluid data, which need to be initialized in the constructorbody of the current problem by adding GET PROP TYPE(TypeTag, PTAG(FluidSystem))::init();,hence using the initialization function of the applied fluidsystem. As water flow replacing a gasis much faster, test your simulation only until 2e3 seconds and start with a time step of 1 second.Please reverse the changes of this example, as we still use bulk phases and hence do not needsuch an extensive fluid system.

e) Changing Constitutive RelationsUse an unregularized linear law with an entry pressure of pe = 0.0 and maximal capillary pressureof e.g. pcmax

= 2000.0 instead of using a regularized Brooks-Corey law for the relative perme-ability and for the capillary pressure saturation relationship. To do that you have to changethe file tutorialspatialparameters coupled.hh. You can find the material laws in the folderdumux/material/fluidmatrixinteractions. The necessary parameters of the linear law andthe respective set-functions can be found in the filedumux/material/fluidmatrixinteractions/2p/linearmaterialparams.hh.

f) HeterogeneitiesSet up a model domain with the soil properties given in Figure 5.3. Adjust the boundaryconditions so that water is again flowing from the left to the right of the domain. You can use

K = 10−8 m2

φ = 0.15K = 10−9 m2

φ = 0.3

600 m

300 m

Figure 5.3: Exercise 1f: Set-up of a model domain with a heterogeneity. ∆x = 20 m ∆y = 20 m.

the fluids of exercise 1c).Hint: The current position of the element can be obtained via element.geometry().center();.

46

Page 47: Dumux Handbook

5 Tutorial

When does the front cross the material border? In paraview, the option View → Animation View

is nice to get a rough feeling of the timestep sizes.

Exercise 2

For this exercise you should create a new problem file analogous to the file tutorialproblem -

coupled.hh (e.g. with the name ex2 tutorialproblem coupled.hh and new spatial parameters justlike tutorialspatialparameters coupled.hh. The new problem file needs to be included in the filetutorial coupled.cc.The new files should contain the definition of a new classes with names that relate to the file name,such as Ex2TutorialProblemCoupled. Make sure that you also adjust the guardian macros in lines 1and 1 in the header files (e.g. changeDUMUX TUTORIALPROBLEM COUPLED HH to DUMUX EX2 TUTORIALPROBLEM COUPLED HH). Besides also ad-justing the guardian macros, the new problem file should define and use a new type tag for the problemas well as a new problem class e.g. Ex2TutorialProblemCoupled. Make sure you assign your newlydefined spatial parameter class to the SpatialParameters property for the new type tag.After this, change the create() method of the Grid property so that it matches the domain describedby figure 5.4. Adapt the problem class so that the boundary conditions are consistent with figure 5.5.Initially the domain is fully saturated with water and the pressure is pw = 5 × 105Pa. Oil infiltratesfrom the left side. Create a grid with 20 cells in x-direction and 10 cells in y-direction. The simulationtime should be set to 1× 106 s with an initial time step size of 100 s.Now include your new problem file in the main file and replace the TutorialProblemCoupled type

tag by the one you’ve created and compile the program.

K = 10−7 m2

φ = 0.2Brooks-Corey Lawλ = 1.8, pe = 1000

K = 10−9 m2

φ = 0.15Brooks-Corey Lawλ = 2, pe = 1500

50 m

15 m

20 m

100 m

50 m

25 m

Figure 5.4: Set-up of the model domain and the soil parameters

• Increase the simulation time to e.g. 4 × 107 s. Investigate the saturation: Is the value rangereasonable?

47

Page 48: Dumux Handbook

5 Tutorial

pw = 5× 105 [Pa]

Sn = 1.0

qw = 2× 10−4 [kg/m2s]

qn = 0.0 [kg/m2s]

no flow

no flow

Figure 5.5: Boundary Conditions

• What happens if you increase the resolution of the grid?

Exercise 3

Create a new file for benzene called benzene.hh and implement a new fluid system. (You may get ahint by looking at existing fluid systems in the directory /dumux/material/fluidsystems.)Use benzene as a new fluid and run the model of Exercise 2 with water and benzene. Benzene has adensity of 889.51 kg/m3 and a viscosity of 0.00112Pa s.

48

Page 49: Dumux Handbook

5 Tutorial

5.3 Solving a problem using a Decoupled Model

The process of solving a problem using DuMux can be roughly divided into four parts:

a) The geometry of the problem and correspondingly a grid have to be defined.

b) Material properties and constitutive relationships have to be defined.

c) Boundary conditions as well as initial conditions have to be defined.

d) A suitable model has to be chosen.

In contrast to the last section, we now apply a decoupled solution procedure, a so-called IMPET

(IMplicit Pressure Explicit T ransport) algorithm. This means that the pressure equation is firstsolved using an implicit method. The resulting velocities are then used to solve a transport equationexplicitly.In this tutorial, pure fluid phases are solved with a finite volume discretization of both pressure- andtransport step. Primary variables, according to default settings of the model, are the pressure and thesaturation of the wetting phase.The problem which is solved in this tutorial is illustrated in figure 5.6. A rectangular domain with

now flow boundaries on the top and at the bottom, which is initially saturated with oil, is considered.Water infiltrates from the left side into the domain. Gravity effects are neglected.

x

yno flow

no flow

water oil

pw = 2× 105 [Pa] pwinitial= 2× 105 [Pa]

Sw = 1 Swinitial= 0

qw = 0[

kgm2s

]

qn = −3× 10−2[

kgm2s

]

Figure 5.6: Geometry of the tutorial problem with initial and boundary conditions.

Listing 4 shows how the main file, which has to be executed, has to be set up, if the problemdescribed above is to be solved using a decoupled model. This main file can be found in the directory/tutorial of the stable part of DuMux.

Listing 4 (File tutorial/tutorial decoupled.cc)

1 #include "config.h"

2

3 #include "tutorialproblem_decoupled .hh"

4

5 #include <dune/grid/common/gridinfo.hh >

6

7 #include <dune/common/exceptions.hh >

8 #include <dune/common/mpihelper.hh >

9

10 #include <iostream >

11 #include <boost/format.hpp >

12

13

49

Page 50: Dumux Handbook

5 Tutorial

14 ////////////////////////////////////////////15 // func t i on to check the input parameters16 ////////////////////////////////////////////17 void usage(const char *progname)

18 {

19 std::cout << boost :: format("usage: %s [--restart restartTime] tEnd\n")% progname;

20 exit (1);

21 }

22

23 ////////////////////////24 // the main func t i on25 ////////////////////////26 int main(int argc , char ** argv)

27 {

28 try {

29 typedef TTAG(TutorialProblemDecoupled ) TypeTag;

30 typedef GET_PROP_TYPE (TypeTag , PTAG(Scalar )) Scalar;

31 typedef GET_PROP_TYPE (TypeTag , PTAG(Grid)) Grid;

32 typedef GET_PROP_TYPE (TypeTag , PTAG(Problem )) Problem;

33 typedef Dune:: FieldVector <Scalar , Grid:: dimensionworld > GlobalPosition;

34

35 // i n i t i a l i z e MPI, f i n a l i z e i s done au toma t i ca l l y on e x i t36 Dune:: MPIHelper :: instance(argc , argv);

37

38 ////////////////////////////////////////////////////////////39 // parse the command l i n e arguments40 ////////////////////////////////////////////////////////////41 if (argc < 2)

42 usage(argv [0]);

43

44 // dea l wi th the r e s t a r t s t u f f45 int argPos = 1;

46 bool restart = false;

47 double restartTime = 0;

48 if (std:: string("--restart") == argv[argPos ]) {

49 restart = true;

50 ++ argPos;

51

52 std:: istringstream (argv[argPos ++]) >> restartTime;

53 }

54 // output in case o f wrong numbers o f input parameters55 if (argc - argPos != 1) {

56 usage(argv [0]);

57 }

58

59 // read the i n i t i a l time s t ep and the end time60 double tEnd , dt;

61 std:: istringstream (argv[argPos ++]) >> tEnd;

62 dt = tEnd;

63

64 // crea t e the g r i d65 Grid *gridPtr = GET_PROP(TypeTag , PTAG(Grid )):: create ();

66

67

68 ////////////////////////////////////////////////////////////69 // i n s t a n t i a t e and run the concre te problem70 ////////////////////////////////////////////////////////////71

72 Problem problem(gridPtr ->leafView ());

73

74 // load r e s t a r t f i l e i f necessary75 if (restart)

76 problem.deserialize(restartTime );

50

Page 51: Dumux Handbook

5 Tutorial

77

78 // de f i ne s imu la t ion parameters79 problem.timeManager (). init(problem , 0, dt , tEnd , !restart );

80 // run the s imu la t ion81 problem.timeManager ().run ();

82 return 0;

83 }

84 catch (Dune:: Exception &e) {

85 std::cerr << "Dune reported error: " << e << std::endl;

86 }

87 catch (...) {

88 std::cerr << "Unknown exception thrown !\n";

89 throw;

90 }

91

92 return 3;

93 }

First, from line 1 to line 11 the DUNE and DuMux files containing essential functions and classesare included.At line 29 the type tag of the problem which is going to be simulated is set. All other data types

can be retrieved by the DuMux property system and only depend on this single type tag. Retrievingthem is done between line 30 and 33. For an introduction to the property system, see section 4.The first thing which should be done at run time is to initialize the message passing interface using

DUNE’s MPIHelper class. Line 36 is essential if the simulation is intended to be run on more than oneprocessor at the same time. Next, the command line arguments are parsed starting at line 41 untilline 62. In this case, we check weather and at which time a previous run of the simulation shouldbe restarted, and we parse the time when the simulation ends. As the maximum time-step in thesequential model is strictly bound by a CFL-criterion, the first time-step size is initialized with thesimulation time.After this, a grid is created on line 65 and the problem is instantiated with information about the

grid (via its leaf grid view) on line 72. If demanded, on line 75 a state written to disk by a previoussimulation run is restored on request by the user. Finally, the time manager controlling the simulationrun is instantiated with the start parameters in line 79 and the simulation proceedure is started bythe time manager at line 81.

5.3.1 The problem class

When solving a problem using DuMux, the most important file is the so-called problem file as shownin listing 5 of tutorialproblem decoupled.hh.

Listing 5 (File tutorial/tutorialproblem decoupled.hh)

1 #ifndef DUMUX_TUTORIALPROBLEM_DECOUPLED_HH // guardian macro2 #define DUMUX_TUTORIALPROBLEM_DECOUPLED_HH // guardian macro3

4 // the g r i d inc l ude s5 #include <dune/grid/sgrid.hh >

6

7 // dumux 2p−decoupled environment8 #include <dumux/decoupled /2p/impes/impesproblem2p.hh >

9 #include <dumux/decoupled /2p/diffusion/fv/fvvelocity2p.hh >

10 #include <dumux/decoupled /2p/transport/fv/fvsaturation2p.hh >

11 #include <dumux/decoupled /2p/transport/fv/capillarydiffusion .hh >

51

Page 52: Dumux Handbook

5 Tutorial

12

13 // as s i gn parameters dependent on space ( e . g . s p a t i a l parameters )14 #include "tutorialspatialparameters_decoupled .hh"

15

16 // the components t ha t are used17 #include <dumux/material/components/h2o.hh >

18 #include <dumux/material/components/oil.hh >

19

20 namespace Dumux

21 {

22

23 template <class TypeTag >

24 class TutorialProblemDecoupled ;

25

26 //////////27 // Spec i f y the p r op e r t i e s f o r the l en s problem28 //////////29 namespace Properties

30 {

31 // crea t e a new type tag f o r the problem32 NEW_TYPE_TAG(TutorialProblemDecoupled , INHERITS_FROM (DecoupledTwoP ));

33

34 // Set the problem proper ty35 SET_PROP(TutorialProblemDecoupled , Problem)

36 {

37 typedef Dumux :: TutorialProblemDecoupled <TypeTag > type;

38 };

39

40 // Set the g r i d type41 SET_PROP(TutorialProblemDecoupled , Grid)

42 {

43 typedef Dune::SGrid <2, 2> type;

44 static type *create ()

45 {

46 typedef typename type:: ctype ctype;

47 Dune:: FieldVector <int , 2> cellRes; // vec to r ho ld ing r e s o l u t i o n o f the g r i d48 Dune:: FieldVector <ctype , 2> lowerLeft (0.0); // Coordinate o f lower l e f t corner o f the g r i d49 Dune:: FieldVector <ctype , 2> upperRight; // Coordinate o f upper r i g h t corner o f the g r i d50 cellRes [0] = 100;

51 cellRes [1] = 1;

52 upperRight [0] = 300;

53 upperRight [1] = 60;

54 return new Dune::SGrid <2,2>(cellRes ,

55 lowerLeft ,

56 upperRight );

57 }

58 };

59

60 // Set the we t t ing phase61 SET_PROP(TutorialProblemDecoupled , WettingPhase)

62 {

63 private:

64 typedef typename GET_PROP_TYPE (TypeTag , PTAG(Scalar )) Scalar;

65 public:

66 typedef Dumux :: LiquidPhase <Scalar , Dumux ::H2O <Scalar > > type;

67 };

68

69 // Set the non−wet t ing phase70 SET_PROP(TutorialProblemDecoupled , NonwettingPhase )

71 {

72 private:

73 typedef typename GET_PROP_TYPE (TypeTag , PTAG(Scalar )) Scalar;

74 public:

52

Page 53: Dumux Handbook

5 Tutorial

75 typedef Dumux :: LiquidPhase <Scalar , Dumux ::Oil <Scalar > > type;

76 };

77

78 // Set the s p a t i a l parameters79 SET_PROP(TutorialProblemDecoupled , SpatialParameters )

80 {

81 typedef Dumux :: TutorialSpatialParametersDecoupled <TypeTag > type;

82 };

83

84 // Set the model p r op e r t i e s85 SET_PROP(TutorialProblemDecoupled , TransportModel)

86 {

87 typedef Dumux :: FVSaturation2P <TTAG(TutorialProblemDecoupled )> type;

88 };

89

90 SET_PROP(TutorialProblemDecoupled , PressureModel )

91 {

92 typedef Dumux :: FVVelocity2P <TTAG(TutorialProblemDecoupled )> type;

93 };

94

95 // model−s p e c i f i c s e t t i n g s96 SET_INT_PROP(TutorialProblemDecoupled , VelocityFormulation ,

97 GET_PROP_TYPE (TypeTag , PTAG(TwoPIndices )):: velocityW );

98

99

100 SET_TYPE_PROP (TutorialProblemDecoupled , DiffusivePart ,

101 Dumux :: CapillaryDiffusion <TypeTag >);

102

103 SET_SCALAR_PROP (TutorialProblemDecoupled , CFLFactor , 0.5);

104

105 // Disab l e g r a v i t y106 SET_BOOL_PROP (TutorialProblemDecoupled , EnableGravity , false );

107 }

108

109 /∗ ! \ ingroup DecoupledProblems110 ∗ @brie f Problem c l a s s f o r the decoupled t u t o r i a l111 ∗/112 template <class TypeTag >

113 class TutorialProblemDecoupled : public IMPESProblem2P <TypeTag , TutorialProblemDecoupled <TypeTag > >

114 {

115 typedef TutorialProblemDecoupled <TypeTag > ThisType;

116 typedef IMPESProblem2P <TypeTag , ThisType > ParentType;

117 typedef typename GET_PROP_TYPE (TypeTag , PTAG(GridView )) GridView;

118

119 typedef typename GET_PROP_TYPE (TypeTag , PTAG(TwoPIndices )) Indices;

120

121 typedef typename GET_PROP_TYPE (TypeTag , PTAG(FluidSystem )) FluidSystem;

122 typedef typename GET_PROP_TYPE (TypeTag , PTAG(FluidState )) FluidState;

123

124 enum

125 {

126 dim = GridView ::dimension , dimWorld = GridView :: dimensionworld

127 };

128

129 enum

130 {

131 wPhaseIdx = Indices ::wPhaseIdx , nPhaseIdx = Indices :: nPhaseIdx

132 };

133

134 typedef typename GET_PROP_TYPE (TypeTag , PTAG(Scalar )) Scalar;

135

136 typedef typename GridView :: Traits :: template Codim <0>:: Entity Element;

137 typedef typename GridView :: Intersection Intersection;

53

Page 54: Dumux Handbook

5 Tutorial

138 typedef Dune:: FieldVector <Scalar , dimWorld > GlobalPosition;

139 typedef Dune:: FieldVector <Scalar , dim > LocalPosition ;

140

141 public:

142 TutorialProblemDecoupled (const GridView &gridView ,

143 const GlobalPosition lowerLeft = GlobalPosition (0.),

144 const GlobalPosition upperRight = GlobalPosition (0.)) : ParentType(gridView)

145 { }

146

147 // ! The problem name .148 /∗ ! This i s used as a p r e f i x f o r f i l e s generated by the s imu la t ion .149 ∗/150 const char *name() const

151 {

152 return "tutorial_decoupled ";

153 }

154

155 // ! Returns t rue i f a r e s t a r t f i l e shou ld be wr i t t en .156 /∗ The d e f a u l t behaviour i s to wr i t e no r e s t a r t f i l e .157 ∗/158 bool shouldWriteRestartFile () const

159 {

160 return false;

161 }

162

163 // ! Returns t rue i f the current s o l u t i on shou ld be wr i t t en to d i s k ( i . e . as a VTK f i l e )164 /∗ ! The d e f a u l t behaviour i s to wr i t e out every the s o l u t i on fo r165 ∗ very time s t ep . Else , change d i v i s o r .166 ∗/167 bool shouldWriteOutput () const

168 {

169 return this ->timeManager (). timeStepIndex () > 0 &&

170 (this ->timeManager (). timeStepIndex () % 1 == 0);

171 }

172

173 // ! Returns the temperature wi th in the domain .174 /∗ ! This problem assumes a temperature o f 10 degrees Ce l s i u s .175 ∗/176 Scalar temperature(const GlobalPosition& globalPos , const Element& element) const

177 {

178 return 273.15 + 10; // −> 10A◦C179 }

180

181 // ! Returns a cons tant pres sure to enter mater ia l laws182 /∗ For inc rompre s s i b l e s imula t ions , a cons tant pres sure i s necessary183 ∗ to enter the mater ia l laws to gain a cons tant dens i t y e t c . In the compress i b l e184 ∗ case , the pres sure i s used f o r the i n i t i a l i z a t i o n o f mater ia l laws .185 ∗/186 Scalar referencePressure (const GlobalPosition& globalPos , const Element& element) const

187 {

188 return 2e5;

189 }

190 // ! Source o f mass \ f$ [\ f r a c { kg }{mˆ3 \ cdot s } ] \ f$191 /∗ ! Eva luate the source term fo r a l l phases wi th in a g iven192 ∗ volume . The method re turns the mass generated ( p o s i t i v e ) or193 ∗ ann i h i l a t e d ( nega t i v e ) per volume uni t .194 ∗/195 std::vector <Scalar > source(const GlobalPosition& globalPos , const Element& element)

196 {

197 return std::vector <Scalar >(2, 0.);

198 }

199

200 // ! Type o f pres sure boundary cond i t i on .

54

Page 55: Dumux Handbook

5 Tutorial

201 /∗ ! Def ines the type the boundary cond i t i on fo r the pres sure equation ,202 ∗ e i t h e r pres sure ( d i r i c h l e t ) or f l u x (neumann ) .203 ∗/204 typename BoundaryConditions :: Flags bctypePress(const GlobalPosition& globalPos ,

205 const Intersection& intersection) const

206 {

207 if (globalPos [0] < this ->bboxMin ()[0] + eps_)

208 return BoundaryConditions :: dirichlet;

209 else // a l l o ther boundaries210 return BoundaryConditions :: neumann;

211 }

212

213 // ! Type o f Transport boundary cond i t i on .214 /∗ ! Def ines the type the boundary cond i t i on fo r the t ranspor t equation ,215 ∗ e i t h e r sa tu ra t i on ( d i r i c h l e t ) or f l u x (neumann ) .216 ∗/217 BoundaryConditions :: Flags bctypeSat(const GlobalPosition& globalPos ,

218 const Intersection& intersection) const

219 {

220 if (globalPos [0] < this ->bboxMin ()[0] + eps_)

221 return BoundaryConditions :: dirichlet;

222 else

223 return BoundaryConditions :: neumann;

224 }

225 // ! Value f o r d i r i c h l e t pres sure boundary cond i t i on \ f$ [Pa ] \ f$ .226 /∗ ! In case o f a d i r i c h l e t BC fo r the pres sure equation , the pres sure227 ∗ have to be de f ined on boundaries .228 ∗/229 Scalar dirichletPress(const GlobalPosition& globalPos ,

230 const Intersection& intersection) const

231 {

232 return 2e5;

233 }

234 // ! Value f o r t ranspor t d i r i c h l e t boundary cond i t i on ( d imens ion le s s ) .235 /∗ ! In case o f a d i r i c h l e t BC fo r the t ranspor t equation , a sa tu ra t i on236 ∗ has to be de f ined on boundaries .237 ∗/238 Scalar dirichletSat(const GlobalPosition& globalPos ,

239 const Intersection& intersection) const

240 {

241 return 1;

242 }

243 // ! Value f o r neumann boundary cond i t i on \ f$ [\ f r a c { kg }{mˆ3 \ cdot s } ] \ f$ .244 /∗ ! In case o f a neumann boundary condi t ion , the f l u x o f matter245 ∗ i s re turned as a vec to r .246 ∗/247 std::vector <Scalar > neumann(const GlobalPosition& globalPos ,

248 const Intersection& intersection) const

249 {

250 std::vector <Scalar > neumannFlux (2 ,0.0);

251 if (globalPos [0] > this ->bboxMax ()[0] - eps_)

252 {

253 neumannFlux[nPhaseIdx] = 3e-2;

254 }

255 return neumannFlux;

256 }

257 // ! Satura t ion i n i t i a l cond i t i on ( d imens ion le s s )258 /∗ ! The problem i s i n i t i a l i z e d with the f o l l ow i n g sa tu ra t i on .259 ∗/260 Scalar initSat(const GlobalPosition& globalPos , const Element& element) const

261 {

262 return 0;

263 }

55

Page 56: Dumux Handbook

5 Tutorial

264

265 private:

266 GlobalPosition lowerLeft_;

267 GlobalPosition upperRight_;

268

269 static const Scalar eps_ = 1e-6;

270 };

271 } //end namespace272

273 #endif

First, both DUNE grid handlers and the decoupled model of DuMux have to be included. Then, anew type tag is created for the problem on line 32. In this case, the new type tag inherits all propertiesdefined for the DecoupledTwoP type tag, which means that for this problem the two-phase decoupledapproach is chosen as discretization scheme (defined via the include in line 8). On line 35, a problemclass is attached to the new type tag, while the grid which is going to be used is defined on line 43 –in this case an SGrid is created. Since in DUNE, there’s no uniform mechanism to allocate grids, theGrid property also contains a static create() method which provides just that: From line 41 to 57, thegeometry is defined and the grid is generated. The three variables of Type Dune::FieldVector definethe lower left corner of the domain (L), the upper right corner of the domain (H) and the numberof cells in x and y direction (N). The grid of type Dune::SGrid is then generated in line 57. Formore information about the DUNE grid interface, the different grid types that are supported and thegeneration of different grids it is referred to the Dune Grid Interface HOWTO [12].Next, we select the material of the simulation: In case of a pure two-phase model, each phase is a

bulk fluid, and the complex (compositional) fluidsystems do not need to be used. However, they canbe used (see exercise 1 4). Instead, we use a simplified fluidsystem container that provides classes forliquid and gas phases, line 61 to 76. These are linked to the appropriate chemical species in line 66and 75. For all parameters that depend on space, such as the properties of the soil, the specific spatialparameters for the problem of interest are specified in line 79.Now we arrive at some model parameters of the applied two-phase decoupled model. Line 97 defines

that the wetting phase velocity rather than e.g. a total velocity is used for the transport system. As weregard capillary pressure, a capillary diffusive term is regarded, selected in line 101. Line 103 assignsthe CFL-factor to be used in the simulation run. The final property on line 106 is optional and tellsthe model not to use gravity.After all necessary information is written into the property system and its namespace is closed in

line 107, the problem class is defined in line 113. As its property, the problem class itsself is alsoderived from a parent, IMPESProblem2P. The class constructor (line 144) is able to hold two vectors,which is not needed in this tutorial.Besides the definition of the boundary and initial conditions (discussed in subsection ), the problem

class also contains general information about the current simulation. First, the name used by theVTK-writer to generate output is defined in the method of line 150, and line 158 indicates weatherrestart files are written. As decoupled schemes usually feature small timesteps, the method controllingthe output in line 167 is very useful. The divisor of the modulo operation defines after how manytimesteps output should be written out – the default “1” resembles output after each step.The following methods all have in common that they may be dependent on space. Hence, they all

feature a common argument list:

• globalPos: A vector holding the global Coordinates.

56

Page 57: Dumux Handbook

5 Tutorial

• element or intersection: Input for an iterator, that is depending weather the parameter of themethod is defined in an element, such as initial values, or on an intersection, such as a boundarycondition.

In the following, there are the methods for general parameters, source- or sinkterms, boundary condi-tions (lines 205 to 248) and initial values for the transported quantity in line . For more informationon the functions, it is referred to the documentation in the code.

5.3.2 The definition of the parameters that are dependent on space

Listing 6 shows the file tutorialspatialparameters_decoupled.hh:

Listing 6 (File tutorial/tutorialspatialparameters decoupled.hh)

1 #ifndef TUTORIALSPATIALPARAMETERS_DECOUPLED_HH

2 #define TUTORIALSPATIALPARAMETERS_DECOUPLED_HH

3

4

5 //#inc lude <dumux/mater ia l / f l u i dma t r i x i n t e r a c t i o n s /2p/ l i n e a rma t e r i a l . hh>6 #include <dumux/material/fluidmatrixinteractions /2p/regularizedbrookscorey .hh >

7 #include <dumux/material/fluidmatrixinteractions /2p/efftoabslaw.hh >

8

9 namespace Dumux

10 {

11 // ! De f i n i t i on o f the s p a t i a l parameters f o r the decoupled t u t o r i a l12

13 template <class TypeTag >

14 class TutorialSpatialParametersDecoupled

15 {

16 typedef typename GET_PROP_TYPE (TypeTag , PTAG(Grid)) Grid;

17 typedef typename GET_PROP_TYPE (TypeTag , PTAG(GridView )) GridView;

18 typedef typename GET_PROP_TYPE (TypeTag , PTAG(Scalar )) Scalar;

19 typedef typename Grid::ctype CoordScalar;

20

21 enum

22 {dim=Grid::dimension , dimWorld=Grid:: dimensionworld , numEq =1};

23 typedef typename Grid:: Traits :: template Codim <0>:: Entity Element;

24

25 typedef Dune:: FieldVector <CoordScalar , dimWorld > GlobalPosition;

26 typedef Dune:: FieldVector <CoordScalar , dim > LocalPosition ;

27 typedef Dune:: FieldMatrix <Scalar ,dim ,dim > FieldMatrix;

28

29 // mater ia l law t yp ed e f s30 typedef RegularizedBrooksCorey <Scalar > EffectiveMaterialLaw;

31 // t ypede f LinearMateria l<Scalar> Ef fec t i veMater ia lLaw ;32 public:

33 typedef EffToAbsLaw <EffectiveMaterialLaw > MaterialLaw;

34 typedef typename MaterialLaw :: Params MaterialLawParams;

35

36 // ! Update the s p a t i a l parameters with the f l ow s o l u t i on a f t e r a t imes tep .37 /∗ ! Function l e f t b lank as there i s nothing to do fo r the t u t o r i a l .38 ∗/39 void update (Scalar saturationW , const Element& element)

40 { }

41 // ! I n t r i n s i c p e rmeab i l i t y t ensor42 /∗ ! Apply the i n t r i n s i c p e rmeab i l i t y t ensor \ f$ [mˆ2]\ f$ to a43 ∗ pressure p o t e n t i a l g rad i en t .44 ∗/45 const FieldMatrix& intrinsicPermeability (const GlobalPosition& globalPos ,

46 const Element& element) const

57

Page 58: Dumux Handbook

5 Tutorial

47 {

48 return K_;

49 }

50

51 // ! Define the po ro s i t y \ f$ [−]\ f$ o f the s p a t i a l parameters52 double porosity(const GlobalPosition& globalPos , const Element& element) const

53 {

54 return 0.2;

55 }

56

57 // ! re turn the parameter o b j e c t f o r the mater ia l law ( i . e . Brooks−Corey )58 // ! which may vary with the s p a t i a l p o s i t i on59 const MaterialLawParams & materialLawParams (const GlobalPosition& globalPos ,

60 const Element &element) const

61 {

62 return materialLawParams_ ;

63 }

64

65 // ! Constructor66 TutorialSpatialParametersDecoupled (const GridView& gridView)

67 : K_(0)

68 {

69 for (int i = 0; i < dim; i++)

70 K_[i][i] = 1e-7;

71

72 // r e s i d ua l s a t u ra t i on s73 materialLawParams_ .setSwr (0);

74 materialLawParams_ .setSnr (0);

75

76 // parameters f o r the Brooks−Corey Law77 // entry pre s sure s78 materialLawParams_ .setPe (500);

79

80 // Brooks−Corey shape parameters81 materialLawParams_ .setAlpha (2);

82 }

83

84 private:

85 MaterialLawParams materialLawParams_ ;

86 FieldMatrix K_;

87 };

88

89 } // end namespace90 #endif

As this file only slightly differs from the coupled version, it is referred to chapter 5.2.4 for explanations.However, as a standard Finite-Volume–scheme is used, in contrast to the box-method in the coupledcase, the argument list here is the same as for the problem functions:

• globalPos: A vector holding the global Coordinates.

• element: Input for an element iterator, providing access to the current element of interest.

5.3.3 Exercise

The following exercises will give you the opportunity to learn how you can change soil parameters,boundary conditions and fluid properties in DuMux and to play along with the decoupled modellingframework.

58

Page 59: Dumux Handbook

5 Tutorial

Exercise 1

For Exercise 1 you only have to make some small changes in the tutorial files.

a) Altering output To get an impression what the results should look like you can first run theoriginal version of the decoupled tutorial model by typing ./tutorial decoupled 1e5. Thenumber behind the simulation name defines the timespan of the simulation run in seconds. Forthe visualisation with paraview please refer to 2.2.As you can see, the simulation creates roughly 150 output files. To reduce these to perform longersimulations, change the method responsible for output (line 167 in the file tutorialproblem -

decoupled) to write an output only every 20 timesteps by changeing the divisor. Compile themain file by typing make tutorial decoupled and run the model. Now, run the simulation for5e5 seconds.

b) Changing the Model Domain and the Boundary ConditionsChange the size of the model domain so that you get a rectangle with edge lengths of x = 300 mand y = 300 m and with discretisation lengths of ∆x = 20 m and ∆y = 10 m.Change the boundary conditions in the file tutorialproblem decoupled.hh so that water entersfrom the bottom and oil flows out at the top boundary. The right and the left boundary shouldbe closed for water and oil fluxes.

c) Changing FluidsNow you can change the fluids. Use DNAPL instead of Oil and Brine instead of Water. To dothat you have to select different components via the property system in the problem file:

a) Brine: The class Dumux::Brine acts as a adapter to the fluid system that alters a pure waterclass by adding some salt. Hence, the class Dumux::Brine uses a pure water class, such asDumux::H2O, as a second template argument after the data type <Scalar> as a templateargument (be aware to use the complete water class with its own template parameter).

b) DNAPL: A standard set of chemical substances, such as Oil and Brinde, is already included(via a list of #include .. commandos) and hence easy accessible by default. This isnot the case for the class Dumux::SimpleDNAPL, however, which is located in the folderdumux/material/components/. Try to include the file as well as select the component viathe property system.

If you want to take a closer look how the fluid classes are defined and which substances are alreadyavailable please browse through the files in the directory /dumux/material/components.

d) Use the DuMux fluid systemAs you have experienced in the coupled tutorial (chapter 5.3), DuMux usually organises fluidmixtures via a fluidsystem. This is also possible for the decoupled models: Uncomment, as wewant to reuse it later on, the lines 61 to 76 in the problem file. If you use eclipse, this can easilybe done by pressing str + shift + 7, the same shortcut works to cancel the comment later on.Now include the file fluidsystems/h2o n2 system.hh in the material folder, and set a propertyFluidSystem with the appropriate type, Dumux::H2O N2 System<TypeTag>. However, the com-plicated fluidsystem uses tabularized fluid data, which need to be initialized in the constructorbody of the current problem by adding GET PROP TYPE(TypeTag, PTAG(FluidSystem))::init();,

59

Page 60: Dumux Handbook

5 Tutorial

hence using the initialization function of the applied fluidsystem. As an alternative, use a simplerversion of water, e.g. Dumux::SimpleH2O, and apply it for the property Components with typeH2O. The density of the gas is magnitudes smaller than that of oil, so please decrease the injection

rate to qn = −3× 10−4[

kgm2s

]

. Also reduce the simultation duration to 2e4 seconds.

Please reverse the changes of this example, as we still use bulk phases and hence do not needsuch an extensive fluid system.

e) HeterogeneitiesSet up a model domain with the soil properties given in Figure 5.7. Adjust the boundaryconditions so that water is again flowing from left to right. When does the front cross the

K = 10−8 m2

φ = 0.15K = 10−9 m2

φ = 0.3

600 m

300 m

Figure 5.7: Exercise 1d: Set-up of a model domain a heterogeneity. ∆x = 20 m ∆y = 20 m.

material border? In paraview, the option View → Animation View is nice to get a rough feelingof the timestep sizes.

Exercise 2

For this exercise you should create a new proplem file analogous to the file tutorialproblem -

decoupled.hh (e.g. with the name ex2 tutorialproblem decoupled.hh and new spatial parame-ters just like tutorialspatialparameters decoupled.hh. These files need to be included in the filetutorial decoupled.cc.The new files should contain the definition of a new classes with names that relate to the file name,

such as Ex2TutorialProblemDecoupled. Make sure that you also adjust the guardian macros in lines1 and 2 in the header files (e.g. changeDUMUX TUTORIALPROBLEM DECOUPLED HH to DUMUX EX2 TUTORIALPROBLEM DECOUPLED HH). Besides alsoadjusting the guardian macros, the new problem file should define and use a new type tag for theproblem as well as a new problem class e.g. Ex2TutorialProblemDecoupled. Make sure you assignyour newly defined spatial parameter class to the SpatialParameters property for the new type tag.After this, change the create()method of the Grid property so that it matches the domain described

by figure 5.8. Adapt the problem class so that the boundary conditions are consistent with figure 5.9.Initially the domain is fully saturated with water and the pressure is pw = 2× 105Pa . Oil infiltratesfrom the left side. Create a grid with 20 cells in x-direction and 10 cells in y-direction. The simulationtime should be set to 2e4s.Now include your new problem file in the main file and replace the TutorialProblemDecoupled

type tag by the one you’ve created and compile the program.

• What happens if you increase the resolution of the grid? Hint: Paraview can visualize thetimesteps via the “Animation View” (to be enabled unter the button View).

60

Page 61: Dumux Handbook

5 Tutorial

K = 10−7 m2

φ = 0.2Brooks Corey Lawλ = 1.8, pb = 100

K = 10−9 m2

φ = 0.15Brooks Corey Lawλ = 2, pb = 500

50 m

15 m

20 m

100 m

50 m

25 m

Figure 5.8: Set-up of the model domain and the soil parameters

• Set the CFL-factor to 1 and investigate the saturation: Is the value range reasonable?

• Further increase the CFL-factor to 2 and investigate the saturation.

Exercise 3

Create a new file for benzene called benzene.hh and implement a new fluid system. (You may get ahint by looking at existing fluid systems in the directory /dumux/material/fluidsystems.)

Use benzene as a new fluid and run the model of Exercise 2 with water and benzene. Benzene hasa density of 889.51 kg/m3 and a viscosity of 0.00112Pa s.

61

Page 62: Dumux Handbook

5 Tutorial

pw = 2× 105 [Pa]

Sw = 0.0

qw = 3× 10−4 [kg/m2s]

qn = 0.0 [kg/m2s]

no flow

no flow

Figure 5.9: Boundary Conditions

62

Page 63: Dumux Handbook

6 Directory Structure

We briefly describe the directory structure of DuMux in terms of subdirectories, source files, andtests. For more details, the Doxygen documentation should be considered. DuMux comes in formof a DUNE module dumux. It has a similar structure as other DUNE modules like dune-grid. Thefollowing subdirectories are within the module’s root directory, from now on assumed to be /:

• CMake: the configuration options for building DuMux using CMake. See the file INSTALL.cmakein the root directory of dumux for details. Of course, it is also possible to use the DUNEbuildsystem just like for the other DUNE modules.

• doc: contains the Doxygen documentation in doxygen, this handbook in handbook, and theDuMux logo in various formats in logo. The html documentation produced by Doxygen can beaccessed as usual, namely, by opening doc/doxygen/html/index.html with a web browser.

• dumux: the DuMux source files. See Section 6.1 for details.

• test: tests for each numerical model and the property system. See Section 6.2 for details.

• tutorial: contains the tutorials described in Chapter 5.

6.1 The directory dumux

The directory dumux contains the DuMux source files. It consists of the following subdirectories (seeFigure 6.1):

• boxmodels: the general fully implicit box method is contained in the subdirectory common, whileeach of the other subdirectories contains a derived specific numerical model. The subdirectorycommon also contains the file boxfvelementgeometry.hh employed by the box method to extractthe dual mesh geometry information out of the primal one. The files pdelabboxassembler.hhand pdelabboxlocaloperator.hh allow the use of the DUNE module dune-pdelab.

• common: general stuff like the property system and the time management for the fully coupledas well as the decoupled models, the interface for the Pardiso direct solver library [21], and thestart.hh file that includes the common routine for starting a model called in the main function.

• decoupled: numerical models to solve the pressure equation as part of the fractional flow for-mulation. The specific models are contained in corresponding subdirectories. In each modelfolder are subdirectories for the implicit pressure equation sorted by the employed discretizationmethod, and for the explicit transport equation. The general decoupled formulation for theimplicit pressure explicit transport formulation can be found in the subdirectory common.

• io: additional in-/output possibilities like restart files and a VTKWriter extension.

63

Page 64: Dumux Handbook

6 Directory Structure

• material: everything related to material parameters and constitutive equations. The propertiesof a pure chemical substance (e.g. water) or pseudo substance (e.g. air) can be found in thesubdirectory components with the base class components/component.hh. The fluidsytem inthe folder fluidsystems collects the information from the respective component and binarycoefficients files, and contains the fluid characteristics of phases (e.g. viscosity, density, enthalpy,diffusion coefficients) for compositional or non-compositional multi-phase flow.

The base class for all spatially dependend variables – like permeability and porosity – can be foundin spatialparameters. The base class in boxspatialparameters.hh also provides spatial aver-aging routines. All other spatial properties are specified in the specific files of the respective mod-els. Furthermore, the constitutive relations – e.g. pc(Sw) – are in fluidmatrixinteractions,while the necessary binary coefficients like the Henry coefficient or binary diffusion coefficientsare definded in binarycoefficients.

• nonlinear: Newton’s method.

6.2 The directory test

The directory test contains a test for each numerical model and for the property system. The testsfor the property system and the pardiso solver can be found in common. The subfolder boxmodels

contains tests for the fully coupled models (1p, 1p2c, 2p, 2p2c, 2p2cni, 2pni, and richards), while thesubdirectory decoupled corresponds to the decoupled models. Each subdirectory contains one or moreprogram files test *.cc, where * usually is the name of the folder. Moreover, the problem definitionscan be found in the *problem.hh files and the definition of the spatially dependend parameters in*spatialparameters.hh. Simply executing the tests should either run the full test or give a list ofrequired command line arguments. After test execution, VTK output files should have been generated.For more detailed descriptions of the tests, the problem definitions and their corresponding Doxygendocumentation should be considered.

64

Page 65: Dumux Handbook

6Directo

ryStru

cture

dum

ux

boxmodels

common

decoupled

io

material

nonlinear

common

specific models

common

specific models

binarycoefficients

components

fluidmatrix-

interactions

fluidsystems

spatialprameters

model and problem definition: implementation of equations, model specific properties,

fluidstates and indices.

general fully implicit boxmethod: assembling in boxlocaljacobian.hh, evaluation of partial derivative

in boxlocalresidual.hh, dual mesh geometry in fvelementgeometry.hh, base clases for model and

problem definition, interface for compatibility with pdelab.

common files of the boxmodels and the decoupled models: pardiso interface, time

integration, start routine, the propterty sytem, ... .

specific model definition for the decoupled formulation. In each model folder are

subdirectories for the implicit pressure equation sorted by discretization method, and for

the explicit transport.

additional in-/output possibilities like restart files and a VTKWriter extension.

base classes and general files for the decoupled formulation.

binary coefficients (like binary diffusion coefficients) and those needed for the constitutive

relationships (e.g. Henry coefficient).

properties of a pure chemical substance (e.g. water) or pseudo substance (e.g. air).

constitutive relationships (e.g. capillary pressure - saturation - curve).

the fluid system collects the information (e.g. from components, binary coefficients ...)

and contains the fluid characteristics of phases (e.g. viscosity, density, enthalpy,

diffusion coefficients) for compositional or non-compositional multi-phase flow.

base class for all spatially dependent variables, like permeability and porosity, includes

spatial averaging routines. All other properties are specified in the specific files of the

respective models.

Newton's method.

Figure 6.1: Structure of the directory dumux containing the DuMux source files.

65

Page 66: Dumux Handbook

7 Physical and numerical models

7.1 Physical and mathematical description

Characteristic of compositional multiphase models is that the phases are not only matter of a singlechemical substance. Instead, their composition in general includes several species, and for the masstransfer, the component behavior is quite different from the phase behavior. In the following, we givesome basic definitions and assumptions that are required for the formulation of the model conceptbelow. As an example, we take a three-phase three-component system water-NAPL-gas [9]. Themodification for other multicomponent systems is straightforward and can be found, e. g., in [6, 1].

7.1.1 Basic Definitions and Assumptions for the Compositional Model Concept

Components: The term component stands for constituents of the phases which can be associatedwith a unique chemical species, or, more generally, with a group of species exploiting similar physicalbehavior. In this work, we assume a water-gas-NAPL system composed of the phases water (subscriptw), gas (g), and NAPL (n). These phases are composed of the components water (superscript w), air(a), and the organic contaminant (c) (see Fig. 7.1).

Figure 7.1: Mass and energy transfer between the phases

Equilibrium: For the nonisothermal multiphase processes in porous media under consideration,we state that the assumption of local thermal equilibrium is valid since flow velocities are small. Weneglect chemical reactions and biological decomposition and assume chemical equilibrium. Mechanical

66

Page 67: Dumux Handbook

7 Models

equilibrium is not valid in a porous medium, since discontinuities in pressure can occur across a fluid-fluid interface due to capillary effects.Notation: The index α ∈ {w, n, g} refers to the phase, while the superscript κ ∈ {w, a, c} refers to

the component.pα phase pressure φ porosityT temperature K absolute permeability tensorSα phase saturation τ tortuosityxκα mole fraction of component κ in phase α g gravitational accelerationXκ

α mass fraction of component κ in phase α qκα volume source term of κ in αmol,α molar density of phase α uα specific internal energyα mass density of phase α hα specific enthalpykrα relative permeability cs specific heat enthalpyµα phase viscosity λpm heat conductivityDκ

α diffusivity of component κ in phase α qh heat source termvα Darcy velocity va,α advective velocity

7.1.2 Balance Equations

For the balance equations for multicomponent systems, it is in many cases convenient to use a molarformulation of the continuity equation. Considering the mass conservation for each component allowsus to drop source/sink terms for describing the mass transfer between phases. Then, the molar massbalance can be written as:

φ∂(∑

α mol,αxκαSα)

∂t−∑

α

div

(krαµα

mol,αxκαK(grad pα − αg)

)

−∑

α

div (τφSαDκαmol,α gradx

κα)− qκ = 0, κ ∈ {w,a,c}.

The component mass balance can also be written in terms of mass fractions by replacing molardensities by mass densities and mole by mass fractions. To obtain a single conserved quantity in thetemporal derivative, the total concentration, representing the mass of one component per unit volume,is defined as

Cκ =∑

α

φSαmass,αXκα .

Using this definition, the component mass balance is written as:

∂Cκ

∂t=

α

div

(krαµα

mass,αXκαK(grad pα + mass,αg)

)

+∑

α

div (τφSαDκαmass,α gradX

κα) + qκ = 0, κ ∈ {w,a,c}.

In the case of non-isothermal systems, we further have to balance the thermal energy. We assumefully reversible processes, such that entropy is not needed as a model parameter. Furthermore, we

67

Page 68: Dumux Handbook

7 Models

neglect dissipative effects and the heat transport due to molecular diffusion. The heat balance canthen be formulated as:

φ∂ (

α αuαSα)

∂t+ (1− φ)

∂scsT

∂t− div (λpm gradT )

−∑

α

div

(krαµα

αhαK (grad pα − αg)

)

− qh = 0.

In order to close the system, supplementary constraints for capillary pressure, saturations and molefractions are needed, [20]. According to the Gibbsian phase rule, the number of degrees of freedomin a non-isothermal compositional multiphase system is equal to the number of components plus one.This means we need as many independent unknowns in the system description. The available primaryvariables are, e. g., saturations, mole/mass fractions, temperature, pressures, etc.

7.2 Available models

The following description of the available models is automatically extracted from the Doxygen docu-mentation. TODO: Unify notation.

7.2.1 Fully coupled models

The single-phase model: OnePBoxModel

Adaption of the BOX scheme to the single phase isothermal flow model. Single phase compressibleisothermal flow model,

φ∂

∂t+ ~∇ · (−

¯K

µ(∇p− ~g)) = q,

discretized using a vertex centered finite volume (box) scheme as spatial and the implicit Euler methodas time discretization. Of course, the model can also be used for incompressible single phase flowmodeling, if in the problem file a fluid with constant density is chosen.

The single-phase, two-component model: OnePTwoCBoxModel

Adaption of the BOX scheme to the one-phase two-component flow model. This model implementsan one-phase flow of an incompressible fluid, that consists of two components, using a standard Darcyapproach as the equation for the conservation of momentum:

vD = −K

µ(gradp− g)

Gravity can be enabled or disabled via the Property system. By inserting this into the continuityequation, one gets

−div

{

K

µ(gradp− g)

}

= q ,

68

Page 69: Dumux Handbook

7 Models

The transport of the components is described by the following equation:

Φ∂x

∂t− div

(

Kx

µ(gradp− g) + τΦDgradx

)

= q.

All equations are discretized using a fully-coupled vertex centered finite volume (box) scheme asspatial and the implicit Euler method as time discretization.The primary variables are the pressure p and the mole fraction of dissolved component x.

The two-phase model using Richards’ assumption: RichardsBoxModel

This model implements a variant of the Richards equation for quasi-twophase flow. In the unsaturatedzone, Richards’ equation is frequently used to calculate the water distribution above the groundwaterlevel. It can be derived from the twophase equations, i.e.

∂ φSαρα∂t

− div

{

ραkrαµα

Kgrad [pα − gρα]

}

= qα,

where α ∈ {w, n} is the fluid phase, ρα is the fluid density, Sα is the fluid saturation, φ is the porosityof the soil, krα is the relative permeability for the fluid, µα is the fluid’s dynamic viscosity, K is theintrinsic permeability, pα is the fluid pressure and g is the potential of the gravity field.In contrast to the full twophase model, the Richards model assumes gas as the non-wetting fluid and

that it exhibits a much lower viscosity than the (liquid) wetting phase. (For example at atmosphericpressure and at room temperature, the viscosity of air is only about 1% of the viscosity of liquidwater.) As a consequence, the krα

µαterm typically is much larger for the gas phase than for the wetting

phase. For this reason, the Richards model assumes that krnµn

tends to infinity. This implies that thepressure of the gas phase is equivalent to a static pressure and can thus be specified externally andthat therefore, mass conservation only needs to be considered for the wetting phase.The model thus choses the absolute pressure of the wetting phase pw as its only primary variable.

The wetting phase saturation is calculated using the inverse of the capillary pressure, i.e.

Sw = p−1c (pn − pw)

holds, where pn is a given reference pressure. Nota bene that the last step is assumes that the capillarypressure-saturation curve can be inverted uniquely, so it is not possible to set the capillary pressure tozero when using the Richards model!

The two-phase model: TwoPBoxModel

Adaption of the BOX scheme to the twophase flow model. This model implements two-phase flowof two completely immiscible fluids α ∈ {w, n} using a standard multiphase Darcy approach as theequation for the conservation of momentum:

vα = −krαµα

K (gradpα − αg)

By inserting this into the equation for the conservation of the phase mass, one gets

φ∂αSα

∂t− div

{

αkrαµα

K (grad pα − αg)

}

− qα = 0 ,

69

Page 70: Dumux Handbook

7 Models

discretized by a fully-coupled vertex centered finite volume (box) scheme as spatial and the implicitEuler method as time discretization.By using constitutive relations for the capillary pressure pc = pn − pw and relative permeability

krα and taking advantage of the fact that Sw + Sn = 1, the number of unknowns can be reduced totwo. Currently the model supports choosing either pw and Sn or pn and Sw as primary variables. Theformulation which ought to be used can be specified by setting the Formulation property to eitherTwoPCommonIndices::pWsN or TwoPCommonIndices::pNsW. By default, the model uses pw and Sn.

The non-isothermal two-phase model: TwoPNIBoxModel

Adaption of the BOX scheme to the non-isothermal twophase flow model. This model implements anon-isothermal two-phase flow of two completely immiscible fluids α ∈ {w, n}. Using the standardmultiphase Darcy approach, the mass conservation equations for both phases can be described asfollows:

φ∂(αSα)

∂t− div

{

αkrαµα

K(grad pα − αg)

}

− qκα = 0 α ∈ {w, n}

For the energy balance, local thermal equilibrium is assumed which results in one energy conservationequation for the porous solid matrix and the fluids:

φ∂ (

α αuαSα)

∂t+ (1− φ)

∂(scsT )

∂t−

α

div

{

αhαkrαµα

K (grad pα − αg)

}

− div (λpmgradT )− qh = 0, α ∈ {w, n}.

The equations are discretized using a fully-coupled vertex centered finite volume (box) scheme asspatial and the implicit Euler method as time discretization.Currently the model supports choosing either pw, Sn and T or pn, Sw and T as primary variables.

The formulation which ought to be used can be specified by setting the Formulation property toeither TwoPNIIndices::pWsN or TwoPIndices::pNsW. By default, the model uses pw, Sn and T .

The two-phase, two-component model: TwoPTwoCBoxModel

Adaption of the BOX scheme to the two-phase two-component flow model. This model implementstwo-phase two-component flow of two compressible and partially miscible fluids α ∈ {w, n} composedof the two components κ ∈ {w, a}. The standard multiphase Darcy approach is used as the equationfor the conservation of momentum:

vα = −krαµα

K (grad pα − αg)

By inserting this into the equations for the conservation of the components, one gets one transportequation for each component

φ∂(∑

α αXκαSα)

∂t−∑

α

div

{

αXκα

krαµα

K(grad pα − αg)

}

−∑

α

div{Dκ

α,pmαgradXκα

}−∑

α

qκα = 0 κ ∈ {w, a} , α ∈ {w, g} (7.1)

70

Page 71: Dumux Handbook

7 Models

This is discretized using a fully-coupled vertex centered finite volume (box) scheme as spatial andthe implicit Euler method as temporal discretization.By using constitutive relations for the capillary pressure pc = pn − pw and relative permeability krα

and taking advantage of the fact that Sw +Sn = 1 and Xκw +Xκ

n = 1, the number of unknowns can bereduced to two. The used primary variables are, like in the two-phase model, either pw and Sn or pnand Sw. The formulation which ought to be used can be specified by setting the Formulation propertyto either TwoPTwoCIndices::pWsN or TwoPTwoCIndices::pNsW. By default, the model uses pw andSn. Moreover, the second primary variable depends on the phase state, since a primary variable switchis included. The phase state is stored for all nodes of the system. Following cases can be distinguished:

• Both phases are present: The saturation is used (either Sn or Sw, dependent on the chosenFormulation), as long as 0 < Sα < 1.

• Only wetting phase is present: The mass fraction of, e.g., air in the wetting phase Xaw is used,

as long as the maximum mass fraction is not exceeded ( Xaw < Xa

w,max)

• Only non-wetting phase is present: The mass fraction of, e.g., water in the non-wetting phase,Xw

n , is used, as long as the maximum mass fraction is not exceeded ( Xwn < Xw

n,max)

The non-isothermal two-phase, two-component model: TwoPTwoCNIBoxModel

Adaption of the BOX scheme to the non-isothermal two-phase two-component flow model. This modelimplements a non-isothermal two-phase flow of two compressible and partly miscible fluids α ∈ {w, n}.Thus each component κ{w, a} can be present in each phase. Using the standard multiphase Darcyapproach a mass balance equation is solved:

φ∂(∑

α αXκαSα)

∂t−∑

α

div

{

αXκα

krαµα

K(grad pα − αg)

}

−∑

α

div{Dκ

α,pmαgradXκα

}−∑

α

qκα = 0 κ ∈ {w, a} , α ∈ {w, n}

For the energy balance, local thermal equilibrium is assumed which results in one energy conservationequation for the porous solid matrix and the fluids:

φ∂ (

α αuαSα)

∂t+ (1− φ)

∂(scsT )

∂t−∑

α

div

{

αhαkrαµα

K (grad pα − αg)

}

− div (λpmgradT )− qh = 0 α ∈ {w, n}

This is discretized using a fully-coupled vertex centered finite volume (box) scheme as spatial andthe implicit Euler method as temporal discretization.By using constitutive relations for the capillary pressure pc = pn − pw and relative permeability krα

and taking advantage of the fact that Sw +Sn = 1 and Xκw +Xκ

n = 1, the number of unknowns can bereduced to two. If both phases are present the primary variables are, like in the nonisothermal two-phase model, either pw, Sn and temperature or pn, Sw and temperature. The formulation which oughtto be used can be specified by setting the Formulation property to either TwoPTwoIndices::pWsN

or TwoPTwoCIndices::pNsW. By default, the model uses pw and Sn. In case that only one phase(nonwetting or wetting phase) is present the second primary variable represents a mass fraction. The

71

Page 72: Dumux Handbook

7 Models

correct assignment of the second primary variable is performed by a phase state dependent primaryvariable switch. The phase state is stored for all nodes of the system. The following cases can bedistinguished:

• Both phases are present: The saturation is used (either Sn or Sw, dependent on the chosenformulation).

• Only wetting phase is present: The mass fraction of air in the wetting phase Xaw is used.

• Only non-wetting phase is present: The mass fraction of water in the non-wetting phase, Xwn , is

used.

7.2.2 Decoupled models

FractionalFlow Model

Decoupled2p2c

(Extracted from decoupled2p2c.hh:)

72

Page 73: Dumux Handbook

8 The flow of things in DuMux

This chapter is supposed to show how things are “handed around” in DuMux. This is not a compre-henisve guide through the modeling framework of DuMux, but hopefully it will help getting to gripswith it.In Section 8.1 the structure of DuMux is shown from a content point of view. Section 8.2 is written

from the point of view of the implementation. These two approaches are linked by the circled numbers(like 1©) in the flowchart of Section 8.2 corresponding to the enumeration of the list of Section 8.1. Thisis supposed to demonstrate at which point of the program-flow you are content- and implementation-wise.Section 8.2 is structured by boxes and −−−−→arrows. Boxes stand for more or less important points in

the programm. They may may be reckoned “step stones”. Likewise, the arrows connect the boxes. Ifimportant things happen in between, it is written under the arrows.

Plain boxes stand for generic parts of the program. double {{boundings}} stand for the imple-

mentatin specific part of the program, like 2p, 2p2c.... This will be the most important part formost users.

:::::::::

snakelike::::::

lines tell you that this part is specific to the components considered.For keeping things simple, the program flow of a 2p model is shown. There are extensive comments

regarding the formating in the tex file: so feel free, to enhance this description.

8.1 Structure – by content

This list shows the algorithmic outline of a typical DuMux run employing a fully coupled model. Eachitem stands for a characteristic step within the modeling framework.

73

Page 74: Dumux Handbook

8 The flow of things in DuMux

1. main 2. time step 3. Newton step 4. Element

initializefor each time step

pre-process solutionfor each Newton iteration

for each elementcalculate element’s local residualcalculate element’s local Jacobianadd local resdidual to global residual vectoradd local Jacobian to global Jacobian matrix

end forsolve linear system of equationsupdate current iterative solutionif converged

stop Newton iterationend if

endforif converged

post-process solutionwrite resultadapt timestep size

else if not convergedretry with half time step size

end ifend forfinalize

8.1.1 Levels

1© main2© time step3© Newton step4© Element

8.2 Structure – by implementation

This section is supposed to help you in getting an idea how things are handled in DuMux and in whichfiles things are written down. This is not intuitivly clear, therefore it is mentioned for each step-stone .

called by tells you from which file a function is accessed. implemented in tells you in which file thefunction is written down. The name of the function is set in typewriter. Being a function is indicatedby round brackets () but only the function name is given and not the full signature (arguments...) .Comments regarding the events within one step-stone are set smaller.

74

Page 75: Dumux Handbook

1©timeManager.init()

initialization

called by: main()implemented in: timemanager.hh

−→

1©timeManager.run()

called by: main()implemented in: timemanager.hh

−−−−−−−−−−−−−−−−−−−→while(!finished)loop1©→ 2©

2©problem->timeIntegration()

execute time integration scheme

called by: timemanager.hhimplemented in: boxproblem.hh

−−−−−−−−−−−−−−−−−−−−−−−−−−→define # allowed Newton fails’(each halving dt)

2©model->update()

sth like numerical model

called by: boxproblem.hhimplemented in: boxscheme.hh

−→

2©solver.execute()not only solving in there: applying Newton method solver keeps track of thingscatching errors

called by: boxmodel.hhimplemented in: newtonmethod.hh

−−−−−−−−−−−−−−−−−→execute ()

in newtonmethod.hh

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−→2©→ 3©

while(ctl.newtonProceed())

init: uCurrentIter, uLastIter← model.uCur()

3©jacobianAsm.assemble()

linearize the problem:

add all element contributions to global Jacobian and global residual

called by: newtonmethod.hhimplemented in: boxassembler.hh

−→

3©resetSystem_()

always set r.h.s. (i.e. residual) to 0

partially set Jacobian to zero in case of partial reassembly

called by: boxassembler.hhimplemented in: boxassembler.hh

−−−−−−−−−−−−−−−−→3©→ 4©

loop all elements

4©assembleElement_()

call local Jacobian and residual assembly

called by: boxassembler.hhimplemented in: boxassembler.hh

Page 76: Dumux Handbook

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−→(if color == red or !partialassembling )

4©model_().localJacobian().assemble()

set curr. element, update element’s fin.vol.geom.

reset local Jacobian to 0

update types of boundaries on this element

called by: boxassembler.hhimplemented in: boxjacobian.hh

−→

4©prevVolVars_.update()

call model specific update of quantities defined for the volume:

variables for the previous timestep!!

called by: boxlocaljacobian.hhimplemented in: boxelementvolumevariables.hh

−→

4©update()

calculate all two-phase specific quantites defined in the volume

called by: boxelementvolumevariables.hhimplemented in: 2pvolumevariables.hh

−→

4©fluidState_.update()

calculate all required fluid properties from the primary variables

called by: 2pvolumevariables.hhimplemented in: 2pfluidstate.hh

−→

::::::::::::::::::::::::::::::::::::::::::::::::::::::

4© e.g: density_ = Fluidsystem::phaseDensity()

The fluid system deals does the real work:

calculates densities, diffusivities ...

called by: 2pfluidstate.hhimplemented in: 2p system.hh

::::::::::::::::::::::::::::::::::::::::::::::::::::::

−→

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

4©curVolVars_.update()

call model specific update of quantities defined for the volume:

variables for the current time step!!

called by: boxlocaljacobian.hhimplemented in: boxelementvolumevariables.hh

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Page 77: Dumux Handbook

−→

4©localResidual().eval()

the element’s local residual is calculated:

see the next two stepstones

called by: boxlocaljacobian.hhimplemented in: boxlocalresidual.hh

−→

4©asImp_().evalFluxes_()

evaluate the fluxes going into each finite volume

how this is done is model specific (see below)

called by: boxlocalresidual.hhimplemented in: boxlocalresidual.hh

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−→calculating the fluxes takes two more steps

4©FluxVariables vars()

this a call to a constructor:

calculate the gradients and average the K

called by: 2plocalresidual.hhimplemented in: 2pfluxvariables.hh

−→

4©computeAdvectiveFlux() (other models: also diffusive)-all velocities are calculated

called by: 2plocalresidual.hhimplemented in: 2plocalresidual.hh

−→

4©asImp_().evalVolumeTerms_()

evaluate the storage and source terms for each finite volume

how this is done is model specific (see below)

called by: boxlocalresidual.hhimplemented in: boxlocalresidual.hh

−→

4©asImp_().evalBoundary_()

deal with the boundary conditions

may be model specific

called by: boxlocalresidual.hhimplemented in: boxlocalresidual.hh (or modelspecific)

−→

4©asImp_().evalPartialDerivative()

actually calculate the element’s (local) Jacobian matrix

a property chooses backward/central/foward differences

here: central differences

called by: boxlocaljacobian.hhimplemented in: boxlocaljacobian.hh

Page 78: Dumux Handbook

−→

approximation of partial derivatives: numerical differentiation

add ±ǫ solution, divide difference of residual by 2ǫ

all partial derivatives for the element are local Jacobian matrix

priVars[pvIdx]+=eps

this is adding eps to the current solution

curVolVars_[scvIdx].update(+eps)

recalculate volume variables, having ǫ added

localResidual().eval(+eps)

calculate local residual for modified solution as before: involves

- computeFlux

- computeStorage

- computeSource

store the residual()

repeat for priVars[pvIdx]-=eps

derivative is (residual(+eps) - residual(-eps))/2eps

−→

∣∣∣∣∣∣

residual of the current solution is now“numerically differentiated”, for the element i.e.the local Jacobian matrix is calculated

∣∣∣∣∣∣

−→

4©assembleElement_()

The contribution of a single element is done.

Now, it needs to be added to the global quantities:

Add to global residual and global Jacobian.

called by: continuing in the function.implemented in: boxassembler.hh

−−−−−−−−−−−−−−−−−−−−→partial assembling:if !vertexColor==Green

4©resdidual_[globI]+=

model_().globalJacobian().resdidual(i)

Add to global residual.

called by: continuing in the function.implemented in: boxassembler.hh

−−−−−−−−−−−→loop verticesof an element

4©(*matrix_)[globI][globJ] +=

model_().localJacobian().mat(i,j)

Add to global Jacobian.

called by: continuing in the function.implemented in: boxassembler.hh

−−−−−−−−→4©→ 3©

3©assemble()

Assembling of elements to global quantities is done.

called by: continuing in the function.implemented in: boxassembler.hh

Page 79: Dumux Handbook

−→

3©execute_() , while newtonProceed()

Print information.

start/ stop timer.

called by: continuing in the function.implemented in: newtonmethod.hh

−−−−−−−−−−−−−−−−−−−→set delta Vector to zero(this is what issolved for later)

3©execute_() , newtonSolveLinear()

Ask the linear solver to solve the system.

i.e. : give Jacobian(matrix), delta(x), r.h.s.(residual) to linear solver

tricky: each Newtonstep solves a linear system of equations.

called by: continuing in the function.implemented in: newtonmethod.hh

−→

3©newtonSolveLinear()

Catching errors.

called by: newtonmethod.hhimplemented in: newtoncontroller.hh

−→

3©solveLinear_()

typedef Dune::PDELab::ISTLBackend_SEQ_BCGS_SSOR Solver;

Selecting Solver (BiCGStab) and preconditioner (SSOR)

Instantiate linear solver (set max # iterations, verbosity)

called by: newtoncontroller.hhimplemented in: newtoncontroller.hh

−→

3©solver.apply(A, x, bTmp, residReduction)

Finally handing matrix, unknowns and r.h.s. to the solver backend.

Preconditioning and solving the system.

called by: newtoncontroller.hhimplemented in: istlsolverbackend.hh

−→

3©solveLinear_()

dealing with errors, infs, nans

called by: continuing in functionimplemented in: newtoncontroller.hh

Page 80: Dumux Handbook

−→

3©newtonupdateRelError()

calculate the relative error between two iterations

find the prim. var. that changed most between

last(uLastIter) and current (uCurrentIter)

Newton iteration.

called by: newtoncontroller.hhimplemented in: newtoncontroller.hh

−→

3©ctl.newtonUpdate()

We solved for the change in solution, but need the solution:

Calculate current (this iteration) solution

from last (iteration) solution and current (iteration) change in solution.

If partial assembly: Mark vertices with big changes for reassembly.

called by: newtonmethod.hhimplemented in: newtoncontroller.hh

−→

3©ctl.newtonEndStep()

Increase counter for number of Newton steps.

Print info.

called by: newtonmethod.hhimplemented in: newtoncontroller.hh

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−→check in whether to do another Newton iteration:that is: check if the error is below tolerance ormaximum number of iterations was reached.

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−→3©→ 2©

Newton done.if failed halve timestep size, restart loop

2©ctl.newtonEnd()

Tell the controller we are done

called by: newtonmethod.hhimplemented in: newtoncontroller.hh

−→

2©ctl.updateSuccessfull()

Can be filled by the model .

called by: boxmodel.hhimplemented in: newtoncontroller.hh

−−−−−−−−−−−−−−−→in while(!finished)

2©postTimeStep()

Give the problem the chance to

post-process the solution.

called by: boxmodel.hhimplemented in: newtoncontroller.hh

−→

2©suggestTimestepSize()

Determine new time step size from # Newton steps.

called by: timemanager.hh, boxproblem.hhimplemented in: newtoncontroller.hh

−−−−−−−−−−−−−−−−−−−−−−−−−→write outputuCur → uPrevtime += dt, timestepIdx++deal with restart and episodes

−−−−−−−−−−−−−−→timemanager.hh2©→ 1©

Page 81: Dumux Handbook

9 Newton in a Nutshell

When using a fully coupled numerical model, one timestep essentially consists of the application ofthe Newton algorithm to solve the nonlinear system.One step of the Newton method can be formalized as follows:Newton method:

ur+1 = ur −(f′(ur)

)−1f(ur) (9.1a)

⇔ (ur+1 − ur)f′(ur) = −f(ur) (9.1b)

⇔ (ur − ur+1) f′(ur)︸ ︷︷ ︸

Jacobian

= f(ur) (9.1c)

with

• r: last iteration, r+1: current iteration,

• ′: derivative

• u: vector of unknowns

• f(ur): function of vector of unknowns

1-D example with slope m:

m =y(ur+1)− y(ur)

ur+1 − urfor a root of a function: m = −

y(ur)

ur+1 − ur(9.2)

The value of u (generally a vector of unknowns) for which f becomes zero is searched for. Thereforethe quantity of interest is ur+1.But the (BiCGSTAB / Pardiso / ...) linear solver solves systems of the form:

Ax = b. (9.3)

Comparing (9.3) with (9.1c) leads to:

• b = f(ur) r.h.s. as it is known from the last iteration. Here, f(ur) is called residual. It isobtained by evaluating the balance equations with the primary variables, as obtained from thelast iteration step.

• A = f′(ur) coefficient matrix or Jacobian. It is obtained by numerical differentiation. Evalu-ating the balance equations at the last solution + eps, then evaluating the balance equations atthe last solution - eps, division by 2eps: numerical differentiation complete.

• x = (ur+1 − ur) this is what the linear solver finds as an solution.

81

Page 82: Dumux Handbook

9 Newton in a Nutshell

This is equivalent to stating that the implemented algorithm solves for the change of the solution.Or in other words: until the u does not change with one more Newton-iteration (not confuse withtimestep!).In the rest of Dumux (everywhere besides in the solver), not the change of the solution is looked for,

but the actual solution is used. Therefore the outcome of the linear solver needs to be reformulated asdone in updateMethod.update(*this, u, *uOld, model);. In this function the “change in solution”is changed to “solution”. Afterwards the quantity *u stands for the solution.

82

Page 83: Dumux Handbook

10 Tips & Tricks

This chapter tries to be a useful collection of tips and tricks that can be handy when working withDuMux. One of the most prominent ideas for developing DUNE/ DuMux is that reinventing the wheelin terms of FEM-code should be avoided. We try to follow this idea also in the day-to-day work bystating the tell us dogma: “If you found something useful, handy or for other reasons helping whenworking with DuMux: put it into this chapter.” (or at least write it to the mailing [email protected] so somebody else can).

• Using the DuMux-Eclipse profile:

Everybody using the same profile has the advantage of resulting in less conflicts when differentdeveloping environments are used:

– in eclipse open: window->preferences->C/C++->Code Style

– press the Import button

– choose the file eclipse_profile.xml from your dumux-devel directory

– make sure that that now DuMux is chosen in “select a profile”

• Checking whether commit worked:

DuMux is developed with the help of svn (which is pronounced “subversion”, seehttp://subversion.apache.org/pronunciation/index.html). This means that at some pointyou will commit your new and/or advanced features (hereafter called “stuff”) to the repository.But maybe you forgot to commit this one and tiny change in one file you forgot about. This mayresult in DuMux not compiling any more on another person’s computer after updating . How toprevent this?

Simply check out DUNE/ DuMux twice. How is this helping? Now you can work in one versionand after commiting you can simply update the pristine version and see whether it still worksthere, too. This approach really helps keeping the bumps in the work-flow small.

• Using DUNE debug streams:

DUNE provides a helpful feature, for keeping your debug-output organized. In stead of jugglingwith a bazillion std::cout<< statements or keeping some debug-precompiler statements orga-nized (which are generally and strongly discouraged see 2.3 ) in order not to get flooded awayby your output DUNE gives you a nice tool: so called debug streams.

These are streams (like cout) but they can be switched on and off for the whole project. Maybe if you are really in the dark you want to see all your debug information. Another time youmay only want to be warned if something is going seriously wrong during a simulation. This canbe achieved by setting the debug streams to desired values. There are 5 levels:

83

Page 84: Dumux Handbook

10 Tips & Tricks

5 - grave (dgrave)

4 - warning (dwarn)

3 - info (dinfo)

2 - verbose (dverb)

1 - very verbose (dvverb)

Which are used as follows:

Dune::dinfo << "here I am \n " ;

orDune::dgrave << "This value should not be reached \n " ; .The debug streams are switched on/off via setting#define DUNE_MINIMAL_DEBUG_LEVEL 4

indumux-devel/config.h

to the desired value and recompiling your application. E.g. if the value is set to 4 the out putgenerated after Dune::dinfo (level 4 and 5) will printed anywhere.

• filename / line number predefined macro:

If you want to know where some output / debug information came from, you can use the prede-fined macros __FILE__ and __LINE__ which are used like

dataFile << "# This was written from "<< __FILE__ << ", line " <<__LINE__ << "\n";

which translates into a line in the output file reading

# This was written from [..]/DUMUX_kila/dumux/dumux/io/outputToFile.hh, line 261

This can also be very useful, if you want to have information about where some warning / debuginformation was issued.

• optim.opts / debug.opts

As explained on page 11 DUNE and DuMux are built with the help of the dunecontrol buildsys-tem. A lot of options need to be specified for that, which is done in the debug.opts resp.optim.opts (plus .suse11.2 if applicable) in your dumux-devel directory. These two files differin the way DUNE/ DuMux is compiled: either for debugging or for fast simulation. Switchingbetween these two states is really worth it: speedup of factor ≈ 2.

If you want your DuMux fast than simply build dunecontrol with the optim.opts. BUT: Pro-grams that are compiled with optimization can hardly be debugged because the debugger getsconfused. But the cool thing is, that you do NOT need to run dunecontrol if you want to startdebugging. You can simply remove the optimization options from your application’s Makefile:

– open your application’s Makefile with the text editor of your choice

– find the line including CXXFLAGS = [...]

– these are the options given to the C++ compiler

– add -g (debugging symbols)

– remove -O3 (third level optimization, i.e. do not care for anything but execution speed),-march=native and -DNDEBUG.

84

Page 85: Dumux Handbook

10 Tips & Tricks

– build your application again.

– as long as you only debug your application (and no DUNE stuff) this works, otherwiserecompile with dunecontrol and debug.opts

– compiling without optimization takes also shorter time

(The other possibility is to run dunecontrol with debug.opts and afterwards adding -O3 intoyour application Makefile. The performance penalty does not make a big difference and so dothe other options besides -O3.)

Debugging with the optimization options active will lead to erratic beviour while debugging.

• Faster build with dunecontrol:A complete build using ./dune-common/bin/dunecontrol --opts=$DUMUX ROOT/debug.opts

all takes some time. If there were just small changes in the folder structure, it is usuallysufficient to run dunecontrol with option autogen instead of all, and afterwards creating themakefiles with option configure.

85

Page 86: Dumux Handbook

Bibliography

[1] M. Acosta, C. Merten, G. Eigenberger, H. Class, R. Helmig, B. Thoben, and H. Muller-Steinhagen.Modeling non-isothermal two-phase multicomponent flow in the cathode of pem fuel cells. Journalof Power Sources, page in print, 2006.

[2] The ALBERTA website: http://www.alberta-fem.de/.

[3] The ALU-Grid website: http://www.mathematik.uni-freiburg.de/IAM/Research/alugrid/.

[4] The apache subversion website: http://subversion.apache.org/.

[5] P. Bastian, M. Blatt, A. Dedner, C. Engwer, R. Klofkorn, R. Kornhuber, M. Ohlberger, andO. Sander. A generic grid interface for parallel and adaptive scientific computing. part ii: imple-mentation and tests in DUNE. Computing, 82(2):121–138, 2008.

[6] A. Bielinski. Numerical Simulation of CO2 Sequestration in Geological Formations. PhD thesis,Institut fur Wasserbau, Universitat Stuttgart, 2006.

[7] The Boost homepage: http://www.boost.org/.

[8] A. Burri, A. Dedner, R. Klofkorn, and M. Ohlberger. An efficient implementation of an adap-tive and parallel grid in dune. In Computational Science and High Performance Computing II,volume 91, pages 67–82. Springer, 2006.

[9] H. Class, R. Helmig, and P. Bastian. Numerical simulation of nonisothermal multiphase mul-ticomponent processes in porous media – 1. an efficient solution technique. Advances in Water

Resources, 25:533–550, 2002.

[10] Doxgen’s homepage: http://www.stack.nl/~dimitri/doxygen/.

[11] The Dumux homepage: http://www.dumux.org/.

[12] The DUNE project: http://www.dune-project.org/.

[13] DUNE build system howto: http://www.dune-project.org/doc/buildsystem/buildsystem.pdf.

[14] Download of DUNE via svn: http://www.dune-project.org/downloadsvn.html.

[15] Use of external libraries in dune http://www.dune-project.org/external_libraries/index.html.

[16] Use of external modules in dune http://www.dune-project.org/downloadext.html.

[17] Installation notes to DUNE: http://www.dune-project.org/doc/installation-notes.html.

[18] The FEniCS project: http://www.fenicsproject.org/.

86

Page 87: Dumux Handbook

Bibliography

[19] IAPWS (The International Association for the Properties of Water and Steam). Revised releaseon the iapws industrial formulation 1997 for the thermodynamic properties of water and steam.http://www.iapws.org/IF97-Rev.pdf, 1997.

[20] R. Helmig. Multiphase Flow and Transport Processes in the Subsurface — A Contribution to the

Modeling of Hydrosystems. Springer Verlag, 1997.

[21] Olaf Schenk and Klaus Gartner. Solving unsymmetric sparse systems of linear equations withPARDISO. Future Generation Computer Systems, 20(3):475 – 487, 2004.

[22] A STL reference: http://www.cplusplus.com/reference/stl/.

[23] The UG homepage: http://atlas.gcsc.uni-frankfurt.de/~ug/.

[24] wikipedia about gnu build system: http://en.wikipedia.org/wiki/GNU_build_system.

[25] wikipedia about aliasing an optimzation: http://en.wikipedia.org/wiki/Aliasing_(computing).

87