uwgeodynamics documentation...quick start / testing we provide a docker container via binder_. this...

54
UWGeodynamics Documentation Release 2.7 Romain Beucher Jun 26, 2020

Upload: others

Post on 16-Oct-2020

18 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics DocumentationRelease 2.7

Romain Beucher

Jun 26, 2020

Page 2: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without
Page 3: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

Contents

1 UWGeodynamics and Underworld 3

2 Versioning 5

3 Quick Start / Testing 73.1 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.2 User Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.3 Troubleshoot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483.4 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483.5 Benchmarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483.6 Tutorials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

i

Page 4: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

ii

Page 5: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

The UWGeodynamics module intents to facilitate rapid prototyping of geodynamics models using Underworld. It canbe seen as a set of high-level functions within the Underworld ecosystem. It is a means to quickly get the user intoUnderworld modelling and assumes very little knowledge in coding. The module make some assumptions based onhow the user defines the boundary conditions and the properties of the materials (rocks, phases). Its simplicity comeswith a relatively more rigid workflow (compared to the classic Underworld functions). However, the user can easilybreak the high level objects and get back to core Underworld function at any step of model design.

The UWGeodynamics is inspired by the Lithospheric Modelling Recipe (LMR) originally developed by Luke Mondy,Guillaume Duclaux and Patrice Rey for Underworld 1. Some of the naming conventions have been reused to facilitatethe transition from LMR. The Rheological libraries are also taken from LMR.

As we think the low-level interface is more flexible, and in so allows for more complex models, we strongly encourageusers to explore and break the High Level functions.

We hope that the user will naturally move to the low-level functionalities as he or her gets more confident, and bydoing so will access the wide range of possibilities offered by Underworld.

Contents 1

Page 6: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

2 Contents

Page 7: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

CHAPTER 1

UWGeodynamics and Underworld

UWGeodynamics uses the Underworld_ Application Programming Interface (API). Both projects are supported by TheUnderworld development team led by Louis Moresi and based in Melbourne, Australia at the University of Melbourneand at Monash University.

Underworld and UWGeodynamics both provide powerful tools to develop numerical geodynamic models. But theirapproaches are different: UWGeodynamics largely guides users into a way of doing things. The Underworld APIprovides a series of tools and components (Mesh, Mesh variables, system of equations, functions) and leaves theresponsibility to arrange those components to the user. The main advantage of the Underworld API is its flexibility.The main inconvenient resides in a somewhat steeper learning curve. UWGeodynamics components are designed tobe more natural to non-experimented numerical modellers or people with little knowledge in programming. It is away to quickly get started and design numerical models. Developing complex models can also be facilitated by theUWGeodynamics high-level interface as it requires less time and less involvement with the details of the UnderworldAPI.

The two approaches are complementary and mixing the two approaches is possible and highly encouraged.

3

Page 8: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

4 Chapter 1. UWGeodynamics and Underworld

Page 9: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

CHAPTER 2

Versioning

Since version 1.0 The Underworld development team has decided to match the UWGeodynamics version number withthe latest supported version of Underworld. UWGeodynamics v2.7 is then supporing Underworld up to version 2.7.

The third number is used for UWGeodynamics only (v2.7.1, v2.7.2 etc.)

The development branch is based on the current Underworld development branch.

5

Page 10: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

6 Chapter 2. Versioning

Page 11: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

CHAPTER 3

Quick Start / Testing

We provide a docker container via binder_. This is a quick solution to get you started and run the examples andtutorials without installing anything on your machine. That is a good way to see if the software can actually be usefulto you. The ressource are however limited and you should not try to run model with high resolution. 3D models cannot be run in the binder.

3.1 Installation

3.1.1 Docker installation

Docker containers provide and easy-way to set up and distribute applications. They also provide a safe and consistentenvironment which facilitate debugging and reproducibility of models. The image we provide contains all the depen-dencies and configuration files required to run Underworld models. Users can start developping model as soon as theyhave downloaded the image, independently of the operating system running on their machine.

We strongly encourage users to run UWGeodynamics using the docker images we provide on Docker Hub

Different version of the underworldcode/uwgeodynamics image can be pulled using a tag:

1. The latest tag points to the github master branch and uses the latest underworld release.

2. The dev tag points to the github development and uses the development branch of underworld.

3. release tags such as 0.9.8 points to the specified version.

Command line

Once you have installed docker on your system you can pull the UWGeodynamics official image as follow:

docker pull underworldcode/uwgeodynamics

You can list all the images available on your system as follow:

7

Page 12: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

docker images

An image can be deleted as follow:

docker rmi underworldcode/uwgeodynamics

You can then start a docker container. (An instance of an image).

docker run -d \--name my_container \-p 8888:8888 \--mount source=myvol,target=/workspace/user-data \underworldcode/uwgeodynamics

You can access the container via your browser at the following address: http://localhost:8888

It is also possible to ssh into the container as follow:

docker exec -it my_container /bin/bash

You can list the containers currently existing on your machine by running:

docker ps -a

The “a” means “all container”. The docker ps command only list running containers.

Docker containers can be stop (so that they do not use CPU or RAM ressource):

docker stop my_container

They can also be deleted:

docker rm my_container

Warning: It’s a good idea to keep track of how many containers have been created as they can rapidly take a lotof space on your machine.

Kitematic

Kitematic is a program that provides a graphical user interface to the docker daemon and to Docker Hub. The softwareis available for Windows, MacOsx and Linux. Be aware that on linux the installation may differ depending on thedistribution you are running.

1. Download and Install Kitematic

2. Open Kitematic and search for the uwgeodynamics image.

3. Create a container by clicking on the create button.

You should now have a container appearing on the left side of your kitematic window. The first thing to do now isto create a link between a local directory (A directory on your physical hard drive) and a volume directory inside thedocker container. A volume is a special directory that can be accessed from outside the container. It is the locationyou will use to save your results.

8 Chapter 3. Quick Start / Testing

Page 13: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

3.1.2 Local Installation

This is not recommended and involves installing Underworld and all its dependencies. Docker is highly recom-mended!!!

Requirements

• Python >= 2.7

• A Working version of Underworld2 >=2.6.0 (Please refer to the Underworld documentation)

• pint >= 0.8

Note on Python 3 compatibility: The bleeding edge version of Underworld (development branch) is now python 3compatible only. UWGeodynamics is python 3 ready and can thus be used with it.

Install

from Pip

The UWGeodynamics module can be installed directly from the Python Package Index:

pip install UWGeodynamics

from sources

The module source files are available through github

git clone https://github.com/underworldcode/UWGeodynamics.git

It can then be installed globally on your system using

pip install UWGeodynamics/

3.1.3 HPC Installation

• python >= 3.6

• openmpi >= 1.8

• hdf5 >= 1.8

NCI Gadi

We provide a script to install UWGeodynamics, Underworld and Badlands inside a virtual environment on Gadi. Aminimal PBS script is also available.

3.1.4 Pawsey MAGNUS

The recommended way to run Underworld / UWGeodynamics model is to use Singularity.

You can have a look at the Pawsey documentation if you want to know more about Singularity:

3.1. Installation 9

Page 14: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Pre-requisites

ssh [email protected]

Singularity module needs to be loaded:

module load singularity

The following command will pull the latest version of the image:

singularity pull --dir $MYGROUP/singularity/UWGeodynamics docker://underworldcode/→˓uwgeodynamics:latest

NOTE: You might need to create the $MYGROUP/singularity/UWGeodynamics directory.

You can list images that are already present in the cache using the following command:

singularity cache list

Once you have finished, we recommend you clean the cache:

singularity cache clean -a

Setting up a job

Here we assume that we have a copy of the UWGeodynamics Tutorial 1 model saved as a python file (Tu-torial_1_ThermoMechanical_Model.py), inside a folder UWGeo_Tutorial1 located in the /scratch/your-project-account/your-username folder:

rb5533@magnus-1:/scratch/q97/rb5533/UWGeo_Tutorial1> lsTutorial_1_ThermoMechanical_Model.py

SLURM file

Following is an example of a SLURM file (job.slurm) showing how to run Tutorial 1 on 1 node using 4 cores:

#!/bin/bash -l#SBATCH --nodes=1#SBATCH --time=00:10:00#SBATCH --account=q97#SBATCH --partition=workq#SBATCH --export=NONE

echo "PRINTING ENVIRONMENT"env

echo "PRINTING SLURM SCRIPT"scontrol show job ${SLURM_JOBID} -ddd

module load singularity

export myRepository=$MYGROUP/singularity/UWGeodynamicsexport containerImage=$myRepository/uwgeodynamics_latest.sif

(continues on next page)

10 Chapter 3. Quick Start / Testing

Page 15: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

(continued from previous page)

srun --export=ALL singularity exec -C -B $PWD:/home/jovyan $containerImage python→˓Tutorial_1_ThermoMechanical_Model.py

Running a job

After the above we should have the following files in our UWGeo_Tutorial1 folder:

rb5533@magnus-1:/scratch/q97/rb5533/UWGeo_Tutorial1> lsTutorial_1_ThermoMechanical_Model.py job.slurm

The job can now be submitted to the queue system using:

sbatch job.slurm

That’s it!!!

3.2 User Guide

3.2.1 The Jupyter notebook

The Jupyter notebook provides a powerful environment for the development and analysis of Underworld models.Underworld and UWGeodynamics recommend using Jupyter notebooks for the development of geodynamic models.

If you are not familiar with Jupyter notebooks, we suggest you follow a quick introduction here.

3.2.2 Where to find documentation?

Additional documentation and function specific documentation can be find in the python doctrings. You can accesthem in the Jupyter notebook by prepending or appending the method, variable or function with ?.

3.2.3 Design principles

3.2.4 import UWGeodynamics

UWGeodynamics can be imported as follow:

>>> import UWGeodynamics as GEO...

3.2.5 Visualization

glucifer can be used to plot the fields produced by Underworld / UWGeodynamics. The module is a wrapper aroundLavavu and is readily available from Underworld.

It can be imported as follow

3.2. User Guide 11

Page 16: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

>>> import glucifer

Warning: Although many plotting modules are available, we strongly encourage people to use glucifer. Itintegrates very well inside the Jupyter notebook, is parallel safe, and can take Underworld function as arguments.

Warning: We provide some basic examples. Look at the glucifer documentation for more details.

Simple examples:

Plot Material Field or any field / variable defined on the swarm (e.g. plasticstrain, viscosityField, densityField etc.):

>>> import glucifer>>> Model = GEO.Model()>>> Fig = glucifer.Figure(figsize=(1200,400), title="Material Field")>>> Fig.Points(Model.swarm, Model.materialField, fn_size=3.0)...>>> Fig.show()>>> Fig.save("MaterialField.png")'MaterialField.png'

Plot Temperature Field or any field / variable defined on the mesh (e.g. temperature, pressureField, velocityField,strainRateField) as well as projected swarm field / variables (e.g. projMaterialField, projViscosityField etc.)

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model()>>> Fig = glucifer.Figure(figsize=(1200,400), title="Temperature")>>> Fig.Surface(Model.mesh, GEO.dim(Model.temperature, u.degK))...>>> Fig.show()>>> Fig.save("Temperature.png")'Temperature.png'

Note: Fields can be dimensionalized using the GEO.dimensionalise function (see below)

Plot Velocity Fields or any vector field.

The example below plots a temperature field with the velocity vectors on top:

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model()>>> Fig = glucifer.Figure(figsize=(1200,400), title="Velocity")>>> Fig.Surface(Model.mesh, GEO.dim(Model.temperature, u.degK))...>>> Fig.VectorArrows(Model.mesh, Model.velocityField)

(continues on next page)

12 Chapter 3. Quick Start / Testing

Page 17: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

(continued from previous page)

...>>> Fig.show()>>> Fig.save("VelocityField.png")'VelocityField.png'

3.2.6 Working with units

UWGeodynamics uses Pint, a Python package to define, operate and manipulate physical quantities (A numericalvalue with unit of measurement). Pint is a very powerful package that handles conversion and operation betweenunits.

We recommend using SI units but other systems are also available.

Pint Unit Registry can be used as follow:

>>> import UWGeodynamics as GEO>>> u = GEO.UnitRegistry

or simply

>>> import UWGeodynamics as GEO>>> u = GEO.u

You can have a quick overview of all the units available by hitting tab after the . of the u object.

Quantities can then be defined as follow:

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> length = 100. * u.kilometre>>> width = 50. * u.kilometre>>> gravity = 9.81 * u.metre / u.second**2

Pint offers the possibility to append a prefix to the units. 1 million years can thus be defined as follow:

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> length = 1.0 * u.megayear

Note: Unit abbreviation is also possible u.km is equivalent to u.kilometer. You can refer to the Pint documen-tation for all abbreviations available.

3.2.7 Model Scaling

Model can be scaled using a series of scaling coefficients

>>> import UWGeodynamics as GEO>>> GEO.scaling_coefficients...

3.2. User Guide 13

Page 18: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

The default scaling coefficients are defined as follow:

Dimension value[mass] 1.0 kilogram[length] 1.0 metre[temperature] 1.0 kelvin[time] 1.0 second[substance] 1.0 mole

The scaling value can be changed by accessing each scaling coefficient as follow

>>> import UWGeodynamics as GEO>>> u = GEO.u

>>> GEO.scaling_coefficients["[length]"] = 3. * u.kilometre>>> GEO.scaling_coefficients["[mass]"] = 4. * u.kilogram>>> GEO.scaling_coefficients["[temperature]"] = 273.15 * u.degK>>> GEO.scaling_coefficients["[time]"] = 300. * u.years

The unit entered are checked internally and an error is raised if the units are incompatible. The value is automaticallyconverted to the base units (metre, second, degree, etc).

To scale a model, the user must define a series of characteristic physical values and assign them to the scaling object.

Arguments with units will be scaled by the UWGeodynamics functions.

>>> import UWGeodynamics as GEO>>> u = GEO.u

>>> KL = 100 * u.kilometre>>> Kt = 1. * u.year>>> KM = 3000. * u.kilogram>>> KT = 1200. * u.degK

>>> GEO.scaling_coefficients["[length]"] = KL>>> GEO.scaling_coefficients["[time]"] = Kt>>> GEO.scaling_coefficients["[mass]"]= KM>>> GEO.scaling_coefficients["[temperature]"] = KT

dimensionalise / non-dimensionalise

We provide 2 functions GEO.non_dimensionalise and GEO.dimensionalise to convert between non-dimensional and dimensional values. The function are also available respectively as GEO.nd and GEO.dim.

Example:

1. define a length of 300 kilometres.

2. use the GEO.nd function to scale it.

3. convert the value back to SI units.

>>> import UWGeodynamics as GEO>>> u = GEO.u

>>> GEO.scaling_coefficients["[length]"] = 300. * u.kilometre

(continues on next page)

14 Chapter 3. Quick Start / Testing

Page 19: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

(continued from previous page)

>>> length = 300. * u.kilometre>>> scaled_length = GEO.nd(length)>>> print(scaled_length)1.0>>> length_metres = GEO.dimensionalise(scaled_length, u.metre)>>> print(length_metres)300000.0 meter

3.2.8 The Model object

The central element or “object” of the UWGeodynamics module is the Model object.

It has several uses:

• It defines the extent and the outside geometry of your problem.

• It works as a container for the field variables.

It basically defines the universe on which you are going to apply physical rules (Gravity field, boundary condition,composition, temperature etc.) It is the equivalent of the box in which you would put the sand and silicon if you wereto build an analog experiment in a lab. One important difference is that the “box” his not empty, it is populated withparticles that have already some properties. The properties are changed by defining new materials.

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model(elementRes=(64, 64),... minCoord=(0. * u.kilometre, 0. * u.kilometre),... maxCoord=(64. * u.kilometre, 64. * u.kilometre))

3.2.9 The Material object

The UWGeodynamics module is designed around the idea of materials, which are essentially a way to define physicalproperties across the Model domain.

Predefined Material objects

A library of predefined material is available through the MaterialRegistry object:

import UWGeodynamics as GEO

materials_database = GEO.MaterialRegistry()

Note: The MaterialRegistry object can import a database of materials from a json file by passing its path as argument.The ‘default json‘__ file can be used as an example.

User defined

Materials are defined using the Material object as follow:

3.2. User Guide 15

Page 20: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

>>> import UWGeodynamics as GEO

>>> crust = GEO.Material(name="Crust")

Typing the name of the material in an empty cell will return a table which summarizes the property of the material:

As you can see, most of the property are undefined.

They are several ways to define the physical parametres of our Material.

• The first one is to add them directly when creating the object itself:

>>> import UWGeodynamics as GEO

>>> u = GEO.u>>> crust = GEO.Material(name="Crust", density=3000*u.kilogram/u.metre**3)

• The second option is to change the property after creating the Material:

>>> import UWGeodynamics as GEO

>>> u = GEO.u>>> crust = GEO.Material(name="Crust")>>> crust.density = 3000. * u.kilogram / u.metre **3

The second option is often easier to read.

Warning: UWGeodynamics contains some basic dimensionality checks. Entering wrong units will raise an error

Material can be added to a model as follow:

16 Chapter 3. Quick Start / Testing

Page 21: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()>>> crust = Model.add_material(name="Crust")

Although optional, it is a good idea to give a name to the material. The Model.add_material method will return aMaterial object. That object is a python object that will then be used to define the property of the material.

Material Attributes

The Material object comes with a series of attribute that can be used to define its physical behavior.

Table 1: Materials attributesName Descriptionshape Initial Geometrical Representationdensity Densitydiffusivity Thermal Diffusivitycapacity Thermal CapacityradiogenicHeatProd Radiogenic Heat Productionviscosity Viscous behaviorplasticity Plastic behaviorelasticity Elastic behaviorminViscosity Minimum Viscosity allowedmaxViscosity Maximum Viscosity allowedstressLimiter Maximum sustainable stresshealingRate Plastic Strain Healing Ratesolidus Solidusliquidus LiquiduslatentHeatFusion Latent Heat Fusion (Enthalpy of Fusion)meltExpansion Melt ExpansionmeltFraction Initial Melt FractionmeltFractionLimit Maximum Fraction of MeltviscosityChange Change in Viscosity over Melt Fraction rangeviscosityChangeX1 Melt Fraction Range beginviscosityChangeX2 Melt Fraction Range end

Examples

>>> u = GEO.u>>> Model = GEO.Model()

>>> Model.density = 200. * u.kg / u.m**3>>> myMaterial = GEO.Material(name="My Material")>>> myMaterial.density = 3000 * u.kilogram / u.metre**3>>> myMaterial.viscosity = 1e19 * u.pascal * u.second>>> myMaterial.radiogenicHeatProd = 0.7 * u.microwatt / u.metre**3>>> myMaterial.diffusivity = 1.0e-6 * u.metre**2 / u.second

3.2. User Guide 17

Page 22: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Global properties

The user can define attributes on the Model itself. The values will be used as global values for materials with undefinedattributes

Example

>>> u = GEO.u>>> Model = GEO.Model()>>> Model.density = 200. * u.kg / u.m**3>>> myMaterial = GEO.Material(name="My Material")

The density of myMaterial will default to 200. kilogram / cubic metre unless its density attribute is explicitly specified.

Material shape

The shape attribute essentially describes the initial location of a material. It is used to build the initial geometry of themodel.

There are a range of available/pre-defined shapes

• Layer (2D/3D)

• Polygon (2D)

• Box (2D)

• Disk (2D)

• Spheres (3D)

• Annulus (2D)

• CombinedShape (Combination of any of the above) (2D)

• HalfSpace (3D)

Layer

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model()>>> shape = GEO.shapes.Layer(top=30.*u.kilometre, bottom=0.*u.kilometre)>>> material = Model.add_material(name="Material", shape=shape)

>>> Fig = glucifer.Figure(figsize=(1200,400))>>> Fig.Points(Model.swarm, Model.materialField)...>>> Fig.show()

18 Chapter 3. Quick Start / Testing

Page 23: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Polygon

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model()>>> polygon = GEO.shapes.Polygon(vertices=[(10.* u.kilometre, 10.*u.kilometre),... (20.* u.kilometre, 35.*u.kilometre),... (35.* u.kilometre, 5.*u.kilometre)])>>> material = Model.add_material(name="Material", shape=polygon)

>>> Fig = glucifer.Figure(figsize=(1200,400))>>> Fig.Points(Model.swarm, Model.materialField)>>> Fig.show()

3.2. User Guide 19

Page 24: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Box

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model()>>> box = GEO.shapes.Box(top=10.* u.kilometre, bottom=5*u.kilometre,... minX=10.*u.kilometre, maxX=15*u.kilometre)>>> material = Model.add_material(name="Material", shape=box)

>>> Fig = glucifer.Figure(figsize=(1200,400))>>> Fig.Points(Model.swarm, Model.materialField)>>> Fig.show()

20 Chapter 3. Quick Start / Testing

Page 25: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Disk

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model()>>> disk = GEO.shapes.Disk(center=(32. * u.kilometre, 32. * u.kilometre),... radius=10.*u.kilometre)>>> material = Model.add_material(name="Material", shape=disk)

>>> Fig = glucifer.Figure(figsize=(1200,400))>>> Fig.Points(Model.swarm, Model.materialField)>>> Fig.show()

3.2. User Guide 21

Page 26: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Sphere (3D)

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model(elementRes=(16, 16, 16),... minCoord=(-1. * u.m, -1. * u.m, -50. * u.cm),... maxCoord=(1. * u.m, 1. * u.m, 50. * u.cm))

>>> sphereShape = GEO.shapes.Sphere(center=(0., 0., 20.*u.centimetre),radius=20. * u.centimetre))

Annulus

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model()>>> annulus = GEO.shapes.Annulus(center=(35.*u.kilometre, 50.*u.kilometre),

(continues on next page)

22 Chapter 3. Quick Start / Testing

Page 27: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

(continued from previous page)

... r1=5.*u.kilometre,

... r2=10.*u.kilometre)>>> material = Model.add_material(name="Material", shape=annulus)

>>> Fig = glucifer.Figure(figsize=(400,400))>>> Fig.Points(Model.swarm, Model.materialField)>>> Fig.show()

CombinedShape

Several shapes can be combined to form a material shape:

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model()>>> disk1 = GEO.shapes.Disk(center=(10. * u.kilometre, 10. * u.kilometre),... radius=10.*u.kilometre)>>> disk2 = GEO.shapes.Disk(center=(20. * u.kilometre, 20. * u.kilometre),

(continues on next page)

3.2. User Guide 23

Page 28: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

(continued from previous page)

... radius=5.*u.kilometre)

>>> shape = disk1 | disk2>>> material = Model.add_material(name="Material", shape=shape)

>>> Fig = glucifer.Figure(figsize=(400,400))>>> Fig.Points(Model.swarm, Model.materialField)>>> Fig.show()

You can also take the intersection of some shapes:

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model()>>> disk1 = GEO.shapes.Disk(center=(32. * u.kilometre, 32. * u.kilometre),... radius=10.*u.kilometre)>>> disk2 = GEO.shapes.Disk(center=(32. * u.kilometre, 22. * u.kilometre),

(continues on next page)

24 Chapter 3. Quick Start / Testing

Page 29: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

(continued from previous page)

... radius=10.*u.kilometre)

>>> shape = disk1 & disk2>>> material = Model.add_material(name="Material", shape=shape)

>>> Fig = glucifer.Figure(figsize=(400,400))>>> Fig.Points(Model.swarm, Model.materialField)>>> Fig.show()

HalfSpace

HalfSpaces can be used to divide space in 2 domains. The divide is a plan defined by its normal vector. The conventionis to keep the domain opposite to direction defined by the normal vector.

Note: HalfSpaces can be combined to define 3D shapes / volumes.

3.2. User Guide 25

Page 30: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.UnitRegistry

>>> Model = GEO.Model(elementRes=(34, 34, 12),... gravity=(0., 0., -9.81 * u.m / u.s**2),... minCoord=(0. * u.km, 0. * u.km, -2880. * u.km),... maxCoord=(9000. * u.km, 2000. * u.km, 20. * u.km))

>>> halfspace1 = GEO.shapes.HalfSpace(normal=(-1.,0.,1.), origin=(4000. * u.km, 0. *→˓u.km, -1000. * u.km))>>> halfspace2 = GEO.shapes.HalfSpace(normal=(0.,0.,1.), origin=(7000. * u.km, 1000.→˓* u.km, 0. * u.km))>>> halfspace3 = GEO.shapes.HalfSpace(normal=(1.,0.,0.), origin=(9000. * u.km, 1000.→˓* u.km, -500. * u.km))>>> halfspace4 = GEO.shapes.HalfSpace(normal=(0.,0.,-1.), origin=(6500. * u.km, 1000.→˓* u.km, -1000. * u.km))

>>> compositeShape = halfspace1 & halfspace2 & halfspace3 & halfspace4>>> polygon= Model.add_material(name="polygon", shape=compositeShape)

>>> Fig = glucifer.Figure()>>> Fig.Points(Model.swarm, Model.materialField, cullface=False, opacity=1.)>>> Fig.Mesh(Model.mesh)>>> viewer = Fig.viewer(resolution=(1200,600))>>> viewer = Fig.viewer(axis=True)>>> viewer.rotatex(-70)>>> viewer.rotatey(-10)>>> viewer.window()

26 Chapter 3. Quick Start / Testing

Page 31: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Multiple materials

You can add as many materials as needed:

>>> import UWGeodynamics as GEO>>> import glucifer

>>> u = GEO.u>>> Model = GEO.Model()

>>> shape = GEO.shapes.Layer(top=30.*u.kilometre, bottom=0.*u.kilometre)>>> material1 = Model.add_material(name="Material 1", shape=shape)

>>> polygon = GEO.shapes.Polygon(vertices=[(10.* u.kilometre, 10.*u.kilometre),... (20.* u.kilometre, 35.*u.kilometre),... (35.* u.kilometre, 5.*u.kilometre)])

>>> material2 = Model.add_material(name="Material 2", shape=polygon)

>>> Fig = glucifer.Figure(figsize=(400,400))>>> Fig.Points(Model.swarm, Model.materialField, fn_size=3.)...>>> Fig.show()>>> Fig.save("multiple_materials.png")'multiple_materials.png'

Temperature and Pressure dependent densities

Temperature and Pressure dependent densities can be assigned to a Material using the GEO.LinearDensity func-tion which calculates:

‘𝜌 = 𝜌0(1 + (𝛽 * 𝛿𝑃 )− (𝛼 * 𝛿𝑇 ))‘ (3.1)

where 𝜌 is the reference density, 𝛽 a factor, 𝛿𝑃 the difference between the pressure and the reference pressure, 𝛼 is thethermal expansivity and 𝛿𝑇 is the difference between the temperature and the reference temperature.

3.2. User Guide 27

Page 32: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> material1 = Model.add_material(name="Material 1", shape=shape)>>> material1.density = GEO.LinearDensity(reference_density=3370. * u.kilogram / u.→˓metre**3,... thermalExpansivity= 2.8e-5 * u.kelvin**-1,... beta=1.0)

3.2.10 Rheologies

Newtonian Rheology

A newtonian rheology can be applied by assigning a viscosity to a already defined material

>>> import UWGeodynamics as GEO

>>> myMaterial = GEO.Material(name="Newtonian Material")>>> myMaterial.viscosity = 1e19 * u.pascal * u.second

Non-Newtonian Rheology

Deformation of materials on long timescale is predominantly achieved through viscous diffusion and dislocation creep.Those processes can be expressed using the following equation:

𝜂𝑣𝑐𝑟𝑒𝑒𝑝eff =1

2𝐴

−1𝑛 �̇�

(1−𝑛)𝑛 𝑑

𝑚𝑛 exp

(︂𝐸 + 𝑃𝑉

𝑛𝑅𝑇

)︂with A the prefactor, �̇� the square root of the second invariant of the deviatoric strain rate tensor, d the grain size, p thegrain size exponent, E the activation energy, P the pressure, V the activation volume, n the stress exponent, R the GasConstant and T the temperature.

UWGeodynamics provides a library of commonly used Viscous Creep Flow Laws. These can be accessed using theGEO.ViscousCreepRegistry:

Note: The ViscousCreepRegistry object can import a database of rheologies from a json file by passing its path asargument. The ‘default json‘__ file can be find here and can be used as an example.

Example:

>>> import UWGeodynamics as GEO>>> material = GEO.Material(name="Material")

>>> rh = GEO.ViscousCreepRegistry()>>> material.viscosity = rh.Wet_Quartz_Dislocation_Gleason_and_Tullis_1995

You can scale viscosity by using a multiplier. For example to make the Gleason and Tullis, 1995 rheology 30 timesstronger you can do:

28 Chapter 3. Quick Start / Testing

Page 33: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

>>> import UWGeodynamics as GEO>>> material = GEO.Material(name="Material")

>>> rh = GEO.ViscousCreepRegistry()>>> material.viscosity = 30 * rh.Wet_Quartz_Dislocation_Gleason_and_Tullis_1995

The user can of course define their own ViscousCreep rheology.

>>> import UWGeodynamics as GEO>>> viscosity = GEO.ViscousCreep(preExponentialFactor=1.0,... stressExponent=1.0,... activationVolume=0.,... activationEnergy=200 * u.kilojoules,... waterFugacity=0.0,... grainSize=0.0,... meltFraction=0.,... grainSizeExponent=0.,... waterFugacityExponent=0.,... meltFractionFactor=0.0,... f=1.0)

Single parametres can then be modified.

viscosity.activationEnergy = 300. * u.kilojoule

Composite Viscosity

Material viscosity can be assigned a combination of viscosities. The effective viscosity is calculated as the harmonicmean of all viscosities.

This is useful to combine diffusion and dislocation creep:

𝜂𝑣𝑐𝑟𝑒𝑒𝑝eff =

(︂1

𝜂diffeff

+1

𝜂disleff

)︂

>>> import UWGeodynamics as GEO

>>> viscosity1 = GEO.ViscousCreep(preExponentialFactor=1.0,... stressExponent=1.0,... activationVolume=0.,... activationEnergy=200 * u.kilojoules,... waterFugacity=0.0,... grainSize=0.0,... meltFraction=0.,... grainSizeExponent=0.,... waterFugacityExponent=0.,... meltFractionFactor=0.0,... f=1.0)

>>> viscosity2 = GEO.ViscousCreep(preExponentialFactor=1.0,... stressExponent=1.0,... activationVolume=0.,... activationEnergy=200 * u.kilojoules,... waterFugacity=0.0,

(continues on next page)

3.2. User Guide 29

Page 34: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

(continued from previous page)

... grainSize=0.0,

... meltFraction=0.,

... grainSizeExponent=0.,

... waterFugacityExponent=0.,

... meltFractionFactor=0.0,

... f=1.0)>>> combined_viscosity = GEO.CompositeViscosity([viscosity1, viscosity2])

Plastic Behavior (Yield)

Plastic yielding can be added and will result in rescaling the effective viscosity for a stress limited to the yield stressof the material.

The effective plastic viscosity is given by:

𝜂eff =𝜎𝑦

2�̇�

Where �̇� is the second invariant of the strain rate tensor defined as �̇� =√︁

12 �̇�𝑖𝑗 �̇�𝑖𝑗 The yield value 𝜎𝑦 is defined using a

Drucker-Prager yield-criterion:

𝜎𝑦 = 𝐶 cos𝜑+ sin𝜑𝑃 (2D)

𝜎𝑦 =6𝐶 cos𝜑√3(3− sin𝜑)

+6 sin𝜑𝑃√3(3− sin𝜑)

(3D)(3.2)

Setting the friction angle 𝜑 = 0 gives the von Mises Criterion. In 2D, equation (3.2) corresponds to the Mohr-Coulombcriterion, while in 3D it circumscribes the Mohr-Coulomb yield surface.

Linear cohesion and friction weakening can be added by defining their initial and final values over a range of accumu-lated plastic strain.

As with Viscous Creep, we also provide a registry of commmonly used plastic behaviors. They can be accessed usingthe GEO.PlasticityRegistry registry.

Note: The PlasticityRegistry object can import a database of plasticity from a json file by passing its path as argument.The ‘default json‘__ file can be find here and can be used as an example.

Users can define their own parametres:

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()>>> material = Model.add_material()

>>> material.plasticity = GEO.DruckerPrager(... cohesion=10. * u.megapascal,... cohesionAfterSoftening=10. * u.megapascal,... frictionCoefficient = 0.3,... frictionAfterSoftening = 0.2,... epsilon1=0.5,... epsilon2=1.5)

30 Chapter 3. Quick Start / Testing

Page 35: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Viscous Creep and Plastic yielding are combined by assuming that they act in parallel as independent processes. Theeffective viscoplastic viscosity is calculated as:

𝜂effvp = min (𝜂vcreepeff , 𝜂pl

eff)

Elasticity

Elastic behavior can be added to a material:

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()>>> material = Model.add_material()

>>> material.elasticity(shear_modulus=10e9 * u.pascal,observation_time=10000 * u.year)

3.2.11 Simple phase change

One can change the property of one material to another depending on some time, tepmerature, pressure etc. criteria.This is not a phase change sensu-stricto but this allows for simple change such as transition from mantle to oceanic-crust behavior or simply air to water. . .

Warning: Phase changes can only occur between predefined material. If you plan to add a material during theModel run, you will have to define it beforehand.

In the following example we change air into water when the air particles move below the 0. level.

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> air = Model.add_material(name="air")>>> water = Model.add_material(name="water")>>> air.phase_changes = GEO.PhaseChange((Model.y < 0.), water.index)

The above example essentially fills the basins with water. For such a specific purpose you can use the WaterFillclass.

>>> air = Model.add_material(name="air")>>> water = Model.add_material(name="water")>>> air.phase_changes = GEO.WaterFill(sealevel=0., result=water)

This is easier to read but equivalent.

3.2.12 Melt

Materials can be assigned a Solidus and a Liquidus defined as polynomial function of temperature. This allowsto calculate the fraction of melt present in the material.

3.2. User Guide 31

Page 36: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Warning: There is no seggregation of the melt from its source.

A registry of Solidii and Liquidii are available:

>>> import UWGeodynamics as GEO

>>> solidii = GEO.SolidusRegistry()>>> crust_solidus = solidii.Crustal_Solidus

>>> liquidii = GEO.LiquidusRegistry()>>> crust_liquidus = liquidii.Crustal_Liquidus

The percentage of melt results in a linear decrease of the viscosity of a factor viscosityChange over theviscosityChangeX1 - viscosityChangeX2 melt fraction interval.

The latent heat of fusion is embedded in the energy equation and affects the temperature field of the Model.

The meltExpansion factor affects the density of the materials and equation (3.1) becomes:

: 𝑙𝑎𝑏𝑒𝑙 : 𝑙𝑖𝑛𝑒𝑎𝑟𝐷𝑒𝑛𝑠𝑖𝑡𝑦𝑀𝑒𝑙𝑡

‘𝜌 = 𝜌0(1 + (𝛽 * 𝛿𝑃 )− (𝛼 * 𝛿𝑇 )− 𝛾𝐹 )‘

with gamma the factor of melt expansion and F the fraction of melt.

The following example prescribes a decrease in viscosity of 3 order of magnitude over a range of 0.15 to 0.30 fractionof melt. The fraction of the melt is limited to 0.3

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> continentalcrust = Model.add_material(name="Continental Crust")>>> continentalcrust.radiogenicHeatProd = 7.67e-7 * u.watt / u.meter**3>>> continentalcrust.density = 2720. * u.kilogram / u.metre**3

>>> continentalcrust.add_melt_modifier(crust_solidus, crust_liquidus,... latentHeatFusion=250.0 * u.kilojoules / u.→˓kilogram / u.kelvin,... meltFraction=0.,... meltFractionLimit=0.3,... meltExpansion=0.13,... viscosityChangeX1 = 0.15,... viscosityChangeX2 = 0.30,... viscosityChange = 1e-3... )...

3.2.13 Mechanical Boundary Conditions

Mechanical boundary conditions are a critical part of any geodynamic model design. In what follows, we quicklydetail the options available for defining the mechanical boundary conditions in Underworld using the UWGeodynamicsmodule.

Questions like how to define boundary conditions and to make sure that those are consistent are beyond the scope ofthis manual.

We will define a simple model for the sake of the example.

32 Chapter 3. Quick Start / Testing

Page 37: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

>>> import UWGeodynamics as GEO

>>> u = GEO.u

>>> Model = GEO.Model(elementRes=(64, 64),... minCoord=(0. * u.kilometre, 0. * u.kilometre),... maxCoord=(64. * u.kilometre, 64. * u.kilometre))

Kinematic boundary conditions

Kinematic boundary conditions are set using the set_velocityBCs method. Conditions are defined for each wall (left,right, bottom, top, back and front (3D only)). For each wall, the user must define the condition for each degree offreedom (2 in 2D (x,y), 3 in 3D (x,y,z).

if 𝑉 is a vector (𝑉𝑥, 𝑉𝑦, 𝑉𝑧) that we want to apply on the left wall, the left parametre must be defined as left=[Vx,Vy, Vz].

In the following example we set the boundary condition to be:

• left wall: 𝑉𝑥 = −1.0cm / yr, 𝑉 𝑦 = 𝑁𝑜𝑛𝑒

• right wall: 𝑉𝑥 = 1.0cm / yr, 𝑉 𝑦 = 𝑁𝑜𝑛𝑒

• bottom wall: 𝑉𝑥 = 𝑁𝑜𝑛𝑒, 𝑉𝑦 = 0. (free slip)

It is an extension model with a total rate of extension equal to 2.0 centimetre / year. No 𝑉𝑥 is prescribed at the bottom,while 𝑉𝑦 is set to 0. no material will be able to enter or leave the model domain from that side. The material is free tomove vertically along the side walls.

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> Model.set_velocityBCs(left=[1.0*u.centimetre/u.year, None],... right=[-1.0*u.centimetre/u.year, None],... bottom=[None, 0.],... top=[None,0.])...

3.2. User Guide 33

Page 38: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

3D

Defining boundary conditions for a 3D model is no different than above. The user must define the velocity componentswith 3 degree of freedom instead of 2.

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model(elementRes=(16, 16, 16),... minCoord=(0. * u.kilometre, 0. * u.kilometre, 0. * u.kilometre),... maxCoord=(64. * u.kilometre, 64. * u.kilometre, 64. * u.→˓kilometre))

>>> Model.set_velocityBCs(left=[1.0*u.centimetre/u.year, None, 0.],... right=[-1.0*u.centimetre/u.year, None, 0.],... bottom=[None, None, 0.],... top=[None, None, 0.],... front=[None, 0., None],... back=[None, 0., None])...

34 Chapter 3. Quick Start / Testing

Page 39: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Velocity varying along a wall

At times it is necessary to define a velocity only for a section of a wall and or varying velocities along that wall.

An Underworld function can be passed as a condition.

As an example, we will apply a velocity of 5.0cm/yr for the part of the left wall below 32 kilometre. Velocity is set tobe 1.0cm/yr above.

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> conditions = [(Model.y < GEO.nd(32 * u.kilometre), GEO.nd(5.0 * u.centimetre/u.→˓year)),

(True, GEO.nd(1.0*u.centimetre/u.year))]

>>> function = GEO.uw.fn.branching.conditional(conditions)

>>> Model.set_velocityBCs(left=[function, None],... right=[-1.0*u.centimetre/u.year, None],... bottom=[None, 10.*u.megapascal],... top=[None,0.])...

3.2. User Guide 35

Page 40: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Stress Conditions

Stress conditions can be applied to the boundaries using the set_stressBCs method:

In the following example we apply a stress of 200.0 megapascal to the bottom of our model:

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> Model.set_stressBCs(bottom=[None, 200. * u.megapascal])...

Note that you will have to make sure that kinematic and stress conditions are compatible.

Frictional Boundaries

Frictional Boundaries can be set as follow:

36 Chapter 3. Quick Start / Testing

Page 41: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> Model.set_frictional_boundary(left=frictionCoeff,... right=frictionCoeff,... bottom=frictionCoeff,... top=frictionCoeff,... thickness=3)...

Where the left, right, top, bottom parametres indicate the side to which you apply a frictional boundary conditionon. frictionCoeff is the friction coefficient (tangent of the friction angle in radians). thickness is the thickness of theboundary in number of elements.

Isostasy

Isostasy is an important concept in geodynamics. It is essentially a consequence of the redistribution of mass within adeforming Earth. One important limitation of our geodynamic model is that we model special cases inside rectangularboxes while earth is actually a sphere. One may however need to provide a way to maintain the volume / mass insidethe domain in order to mimic isostasy. There is no ideal way to model isostasy in a boxed model, it is however possibleto approach isostasy using a support condition.

Options are to:

• Balance flows using a kinematic condition at the base of the model.

• Balance flows using a stress condition at the base of the model.

• Balance flows along the sides.

Lecode Isostasy (kinematic)

The Lecode Isostasy submodule provides a way to model isostatic support at the base of the model. It calculatesthe velocity to apply at the base of each elemental column. It applies the principles of Airy isostatic model byapproximating the weight of each column. The calculation is done dynamically and velocities will change fromone step to the next. It is a good option to use in most cases.

The option can be used by creating a LecodeIsostasy object using the GEO.LecodeIsostasy class. The objectrequires the index of the material of reference (the material number). One can apply an average velocity (calculatedacross each column base) using the average parameter (default to False).

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> Model.set_velocityBCs(left=[1.0*u.centimetre/u.year, None],... right=[-1.0*u.centimetre/u.year, None],... bottom=[None, GEO.LecodeIsostasy(reference_mat=mantle)],... top=[None,0.])...

3.2. User Guide 37

Page 42: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Traction Condition (stress)

Another approach to model isostasy is to defined a certain stress at the base of the model. This is done using units ofstress (derived SI units = pascal). The model will then maintain the denfined stress by adjusting the flow across theborder/boundary.

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> Model.set_stressBCs(bottom=[None, 10.*u.megapascal])...

Lithostatic Pressure Condition (stress)

The lithostatic pressure field can be passed as a boundary condition (stress)

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> Model.set_stressBCs(left=[-Model.lithostatic_pressureField, None])...

3.2.14 Thermal Boundary Conditions

Absolute temperatures

Setting the temperature at the top of a model to be 500kelvin at the top and 1600kelvin at the bottom is done as follow.

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> Model.set_temperatureBCs(top=500. * u.degK, bottom=1600. * u.degK)...

You can of course define temperatures on the sidewalls:

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> Model.set_temperatureBCs(right=500. * u.degK, left=1600. * u.degK)...

Fix the temperature of a Material

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> Model.set_temperatureBCs(top=500. * u.degK,

(continues on next page)

38 Chapter 3. Quick Start / Testing

Page 43: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

(continued from previous page)

... bottom=-0.022 * u.milliwatt / u.metre**2,

... bottom_material=Model,

... materials=[(air, 273. * u.Kelvin)])

...

Note: Model inflow is negative, outflow is positive.

Fix the temperature of internal nodes

You can assign a temperature to a list of nodes by passing a list of node indices (global).

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> Model = GEO.Model()

>>> nodes = [0, 1, 2]>>> Model.set_temperatureBCs(top=500. * u.degK,... bottom=-0.022 * u.milliwatt / u.metre**2,... bottom_material=Model,... nodeSets=[(273. * u.Kelvin, nodes)])...

Heat flux

Heat Flux can be assign as follow:

>>> import UWGeodynamics as GEO

>>> u = GEO.u

>>> Model = GEO.Model()>>> Material = Model.add_material(shape=GEO.Layer(top=Model.top,... bottom=Model.bottom)>>> Model.set_heatFlowBCs(bottom=(-0.22 * u.milliwatt / u.metre**2,... Material))...

3.2.15 Model initialization

Initialization of the pressure and temperature fields is done by using the

Model.init_model method.

The default behavior is to initialise the temperature field to a steady-state while the pressure field is initialized to thelithostatic pressure.

You can deactivate pressure or temperature initialization by setting the corresponding argument to False(Model.init_model(temperature=False))

>>> import UWGeodynamics as GEO>>> u = GEO.u

>>> Model = GEO.Model()

(continues on next page)

3.2. User Guide 39

Page 44: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

(continued from previous page)

>>> Model.density = 2000. * u.kilogram / u.metre**3>>> Model.init_model(temperature=False, pressure=True)...

Warning: The lithostatic pressure calculation relies on a regular quadratic mesh. Most of the time this is fine formodel initialization as models often starts on a regular mesh. However, this will not work on a deformed mesh

3.2.16 Running the Model

Once your model is set up and initialized. You can run it using the Model.run_for method.

You have 2 options:

1. Run the model for some given number of steps:

Model.run_for(nstep=10)

1. Specify an endTime

Model.run_for(endTime=1.0* u.megayears)

which is equivalent to

Model.run_for(1.0*u.megayears)

Specify a timestep

UWGeodynamics calculates the time step automatically based on some numerical stability criteria. You can force aspecific time step or force the time step to be constant throughout

Model.run_for(1.0*u.megayears, dt=10000. * u.years)

Saving data

As your model is running you will need to save the results to files.

The Model.run_for method provides a series of arguments to help you save the results at some regular intervals and/orspecified times. You can define:

1. A checkpoint_interval

Model.run_for(endTime=1.0*u.megayears,checkpoint_interval=0.1* u.megayears)

The value passed to the checkpoint_interval must have units of time 1. A list of checkpoint times:

Model.run_for(endTime=1.0*u.megayears,checkpoint_interval=0.1* u.megayears,checkpoint_times=[0.85 * u.megayears,

0.21 * u.megayears])

40 Chapter 3. Quick Start / Testing

Page 45: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

This can be used together or without the checkpoint_interval

UWGeodynamics will save all the fields defined in the GEO.rcParams[“default.outputs”] list. You canchange that list before running the model.

Checkpointing

By checkpointing we mean saving the data required to restart the Model. This includes the mesh, the swarm and allthe associated variables.

However, as the swarm and the swarm variables can be very large and can take a lot of space on disk, the user candecide to save them only every second, third, fourth etc. checkpoint step.

This is done passing the restart_checkpoint argument to the Model.run_for function:

Model.run_for(endTime=1.0*u.megayears,checkpoint_interval=0.1* u.megayears,restart_checkpoint=2

By default, the swarm and the swarm variables are saved every time the model reaches a checkpoint time(restart_checkpoint=1).

3.2.17 Pre / Post-solve hook functions

We provide 2 access points for injection of custom functions.

def my_functionA():# do somethingprint("Hello, I am running a pre-solve function")return

def my_functionB():# do somethingprint("Hello, I am running a post-solve function")return

Model.pre_solve_function["A"] = my_functionAModel.post_solve_function["B"] = my_functionB

Note that the functions are executed in the order they were defined.

3.2.18 Solver Callback functions

User can provide custom callback functions to the solver itself. The function(s) will be executed after each solve. Thisgives the possibility to tweak the behaviour of the non-linear iterations loop.

def my_function()# do somethingprint("Hello, This is a solver callback")

Model.callback_function["my_function"] = my_function

3.2. User Guide 41

Page 46: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

3.2.19 Restarting the Model

When checkpointing a model only the mesh, swarms their associates variables are explicitely saved. Since the modelstate is not explicitly saved, thus the user needs to recreate the Model object before restarting it. In practice, this meansthe user must run all commands preceding the Model.run_for command.

The user can then restart a model using the restartStep and restartDir arguments:

• restartStep is None by default. The step numbercyou want to restart from. If -1, restarts from the last availablestep in restartDir

• restartDir is the folder where the program should look for previously saved data or checkpoints. It is set toModel.outputs by default.

import UWGeodynamics as GEO

u = GEO.u

Model = GEO.Model(elementRes=(64, 64),minCoord=(0. * u.kilometre, 0. * u.kilometre),maxCoord=(64. * u.kilometre, 64. * u.kilometre))

# Default (restart, restartDir are optional in this case)Model.run_for(2.0 * u.megayears, restartStep=-1, restartDir="your_restart_directory")

# Restart from step 10Model.run_for(2.0 * u.megayears, restartStep=10, restartDir="your_restart_directory")

# Overwrite existing outputsModel.run_for(2.0 * u.megayears, restartStep=False)

3.2.20 Model outputs

All mesh variables / fields defined in the GEO.rcParams["default.outputs"] are saved as HDF5 files to theoutputDir directory at every output times. An XMF file is provided and can be used to open the files in Paraview

All variables required for a restart are saved as HDF5 files to the outputDir directory at each checkpoint time. AnXMF file is also provided.

Passive Tracers and tracked fields are also saved as HDF5 files at every output and checkpoint times. Each of then hasan associated XMF file.

3.2.21 Parallel run

A Model can be run on multiple processors:

You first need to convert your jupyter notebook to a python script:

jupyter nbconvert --to python my_script.ipynb

You can then run the python script as follow:

mpirun -np 4 python my_script.py

42 Chapter 3. Quick Start / Testing

Page 47: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Warning: Underworld and UWGeodynamics functions are parallel safe and can be run on multiple CPUs. Thismight not be the case with other python libraries you might be interested in using with your Model. For example,matplotlib plots will not work in parallel and must be processed in serial. Tutorial 1 has examples of matplotlibplots which are only done on the rank 0 CPU.

3.2.22 Passive Tracers

>>> import UWGeodynamics as GEO>>> import numpy as np

>>> u = GEO.u

>>> Model = GEO.Model()>>> npoints = 1000>>> coords = np.ndarray((npoints, 2))>>> coords[:, 0] = np.linspace(GEO.nd(Model.minCoord[0]), GEO.nd(Model.maxCoord[0]),→˓npoints)>>> coords[:, 1] = GEO.nd(32. * u.kilometre)>>> tracers = Model.add_passive_tracers(vertices=coords)

You can pass a list of centroids to the Model.add_passive_tracers method. In that case, the coordinates of the passivetracers are relative to the position of the centroids. The pattern is repeated around each centroid.

>>> import UWGeodynamics as GEO>>> import numpy as np

>>> u = GEO.u>>> Model = GEO.Model()>>> cxpos = np.linspace(GEO.nd(20*u.kilometer), GEO.nd(40*u.kilometer),5)>>> cypos = np.linspace(GEO.nd(20*u.kilometer), GEO.nd(40*u.kilometer),5)>>> cxpos, cypos = np.meshgrid(cxpos, cypos)>>>>>> coords = np.zeros((1, 2))>>> tracers = Model.add_passive_tracers(vertices=coords,... centroids=[cxpos.ravel(),... cypos.ravel())

We provide a function to create circles on a grid:

>>> import UWGeodynamics as GEO

>>> coords = GEO.circles_grid(radius = 2.0 * u.kilometer,... minCoord=[Model.minCoord[0], lowercrust.bottom],... maxCoord=[Model.maxCoord[0], 0.*u.kilometer])

Tracking Values

Passive tracers can be used to track values of fields at specific location through time.

>>> import UWGeodynamics as GEO>>> import numpy as np

>>> u = GEO.u

(continues on next page)

3.2. User Guide 43

Page 48: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

(continued from previous page)

>>> Model = GEO.Model()

>>> npoints = 1000>>> coords = np.ndarray((npoints, 2))>>> coords[:, 0] = np.linspace(GEO.nd(Model.minCoord[0]), GEO.nd(Model.maxCoord[0]),→˓npoints)>>> coords[:, 1] = GEO.nd(32. * u.kilometre)>>> tracers = Model.add_passive_tracers(vertices=coords)

>>> tracers.add_tracked_field(Model.pressureField,name="tracers_press",units=u.megapascal,dataType="float")

>>> tracers.add_tracked_field(Model.strainRateField,name="tracers_strainRate",units=1.0/u.second,dataType="float")

3.2.23 Surface Processes

A range of basic surface processes function are available from the surfaceProcesses submodule. Surface processesare turned on once you have passed a valid surface processes function to the surfaceProcesses method of theModel object.

Example:

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> air = GEO.Material()>>> sediment = GEO.Material()>>> Model.surfaceProcesses = GEO.surfaceProcesses.SedimentationThreshold(... air=[air], sediment=[sediment], threshold=0. * u.metre)

Three simple function are available:

1. Total Erosion Above Threshold (ErosionThreshold).

2. Total Sedimentation Below Threshold (SedimentationThreshold)

3. Combination of the 2 above. (ErosionAndSedimentationThreshold)

Coupling with Badlands

UWGeodynamics provides a way to couple an Underworld model to Badlands.

>>> import UWGeodynamics as GEO>>> u = GEO.u>>> air = GEO.Material()>>> sediment = GEO.Material()>>> Model.surfaceProcesses = GEO.surfaceProcesses.Badlands(... airIndex=[air.index], sedimentIndex=sediment.index,... XML="ressources/badlands.xml", resolution=1. * u.kilometre,... checkpoint_interval=0.01 * u.megayears)

This will allow communication between the UWGeodynamics model and the Badlands surface processes model. Bad-lands input parameters must be defined inside an XML file as described in the module documentation. We provide

44 Chapter 3. Quick Start / Testing

Page 49: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

an XML example. The resulting Model is a 2-way coupled thermo-mechanical model with surface processes, wherethe velocity field retrieved from the thermo-mechanical model is used to advect the surface in the Surface ProcessesModel. The surface in subjected to erosion and deposition. The distribution of materials in the thermomechanicalmodel is then updated.

Users must define a list of material describing the air layers (usually, air and sticky air). It is also require to define anUWGeodynamics.Material object describing the sediment that will be deposited. The index of the Material is passedto the surfaceProcesses function. Users can also provide an Underworld function returning an index of an existingUWGeodynamics.Material.

It is recommended to use a higher spatial resolution in the surface processes model than in the thermo-mechanicalmodel.

Note: When the Thermomechanical model is 2D, the velocity field at the surface is extrapolated in the 3D dimensionand the resulting model is a T or 2.5D model (symmetric regional uplift). If the thermomechanical model is 3D thecoupling is done in 3D.

3.2.24 Deforming Mesh

Uniaxial deformation can be turned on using the Model.mesh_advector() method. The method takes an axisargument which defines the direction of deformation (x=0, y=1, z=2)

>>> Model.mesh_advector(axis=0)

Element are stretched or compressed uniformly across the model. This will result in a change in resolution with time.

3.2.25 Top Free surface

Free surface can be turned on using the Model.freesurface switch.

>>> Model.freesurface = True

Warning: No stabilization algorithm has been implemented yet.

3.2.26 Dynamic rc settings

You can dynamically change the default rc settings in a python script or interactively from the python shell. Allof the rc settings are stored in a dictionary-like variable called UWGeodynamics.rcParams, which is global to theUWGeodynamics package. rcParams can be modified directly, for example:

>>> import UWGeodynamics as GEO>>> GEO.rcParams['solver'] = "mumps">>> GEO.rcParams['penalty'] = 1e6

The UWGeodynamics.rcdefaults command will restore the standard UWGeodynamics default settings.

There is some degree of validation when setting the values of rcParams, see UWGeodynamics.rcsetup for details.

3.2. User Guide 45

Page 50: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Table 2: rcParamsName Function Default valueCFL Set CFL Factor 0.5solver Set Solver “mg” (multigrid), options

are “mumps”, “lu”penalty Set penalty value 0.0 or Noneinitial.nonlinear.tolerance Set nonlinear tolerance for Stokes first

solve1e-2

nonlinear.tolerance Set nonlinear tolerance for solves 1e-2initial.nonlinear.min.iterations Set minimal number of Picard itera-

tions (first solve)2

initial.nonlinear.max.iterations Set maximal number of Picard itera-tions (first solve)

500

nonlinear.min.iterations Set minimal number of Picard itera-tions

2

nonlinear.max.iterations Set maximal number of Picard itera-tions

500

default.outputs List of fields to be saved at checkpoint [“temperature”, “pres-sureField”, “strain-RateField”, “veloci-tyField”, “projStress-Field”, “projTimeField”,“projMaterialField”,“projViscosityField”,“projPlasticStrain”,“projDensityField”]

swarm.particles.per.cell.2D Initial number of particles per cell for2D models

40

swarm.particles.per.cell.3D Initial number of particles per cell for3D models

120

popcontrol.particles.per.cell.2D Minimum number of particles per cell 40popcontrol.particles.per.cell.3D Maximum number of particles per cell 120popcontrol.aggressive Turn on Aggressive population con-

trolTrue

popcontrol.split.threshold Population control split threshold 0.15popcontrol.max.splits Population control maximum number

of splits10

shear.heating Turn shear heating on / off Falsesurface.pressure.normalization Turn surface pressure normalization

on / offTrue

pressure.smoothing Turn pressure smoothing after solveon / off

True

advection.diffusion.method Advection Diffusion solve method “SUPG”rheologies.combine.method Visco-plastic rheology combination “Minimum”, options are

“Minimum”, “Harmonic”averaging.method Multi-material element averaging

method“arithmetic” optionsare “arithmetic”, “ge-ometric”, “harmonic”,“maximum”, “minimum”,“root mean square”

time.SIunits Default output units for time field u.yearviscosityField.SIunits Default output units for viscosity field u.pascal * u.second

Continued on next page

46 Chapter 3. Quick Start / Testing

Page 51: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

Table 2 – continued from previous pageName Function Default valuedensityField.SIunits Default output units for density field u.kilogram / u.metre**3velocityField.SIunits Default output units for velocity field u.centimetre / u.yeartemperature.SIunits Default output units for temperature

fieldu.degK

pressureField.SIunits Default output units for pressure field u.pascalstrainRateFieldSIunits Default output units for strain rate

fieldu.pascal

projStressTensor.SIunits Default output units for mesh pro-jected stress tensor field

u.pascal

projStressField.SIunits Default output units for mesh pro-jected stress field

u.pascal

projViscosityFIeld.SIunits Default output units for mesh pro-jected viscosities

u.pascal * u.second

projTimeField.SIunits Default output units for mesh pro-jected time field.

u.year

The uwgeodynamicsrc file

UWGeodynamics uses uwgeodynamicsrc configuration files to customize all kinds of properties, which we callrc settings or rc parameters. For now, you can control the defaults of a limited set of properties.

UWGeodynamics looks for uwgeodynamicsrc in four locations, in the following order:

1. uwgeodynamicsrc in the current working directory, usually used for specific customizations for a particularmodel setup that you do not want to apply elsewhere.

2. $UWGEODYNAMICSRC if it is a file, else $UWGEODYNAMICSRC/uwgeodynamicsrc.

3. It next looks in a user-specific place, depending on your platform:

• On Linux, it looks in .config/uwgeodynamics/uwgeodynamicsrc (or $XDG_CONFIG_HOME/uwgeodynamics/uwgeodynamicsrc) if you’ve customized your environment.

• On other platforms, it looks in .uwgeodynamics/uwgeodynamicsrc.

4. {INSTALL}/UWGeodynamics/uwgeo-data/uwgeodynamicsrc, where {INSTALL}is something like /usr/lib/python2.7/site-packages on Linux, and maybeC:\\Python27\\Lib\\site-packages on Windows. Every time you install UWgeodynamics,this file will be overwritten, so if you want your customizations to be saved, please move this file to youruser-specific directory.

To display where the currently active uwgeodynamicsrc file was loaded from, one can do the following:

>>> import UWGeodynamics as GEO>>> GEO.uwgeodynamics_fname()'/workspace/user_data/UWGeodynamics/UWGeodynamics/uwgeo-data/uwgeodynamicsrc'

See below for a sample.

3.2. User Guide 47

Page 52: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

_uwgeodynamicsrc-sample:

3.3 Troubleshoot

3.4 Examples

We provide a series of example to illustrate the functionalities available in UWGeodynamics.

1. Steady State heat

2. Convection

3. Blankenbach Benchmark

4. Rayleigh Taylor

5. Stokes sinker

6. Hypnic Jerk (Periodic Boundary Conditions)

7. Slab Subduction

8. Pure Shear example

9. Visco-elastic half space

10. Visco-elasto-plasticity in simple shear

11. 3D Stokes Sinker

12. 2D Bottom Traction condition (Stress condition)

13. 3D Bottom Traction condition (Stress condition)

14. Free surface simple example (Free Surface)

15. Hot Canon Ball (Internal boundary condition)

3.5 Benchmarks

3.5.1 Viscous Benchmarks

1. Slab Detachment

3.5.2 Visco-Plastic Benchmarks

1. Indentor Benchmark

2. Brick Benchmark in compression

3. Brick Benchmark in extension

3.5.3 Averaging Viscosity Method

1. Subduction Case 1

2. Subduction Case 2

48 Chapter 3. Quick Start / Testing

Page 53: UWGeodynamics Documentation...Quick Start / Testing We provide a docker container via binder_. This is a quick solution to get you started and run the examples and tutorials without

UWGeodynamics Documentation, Release 2.7

3.6 Tutorials

We provide a series of tutorials as Jupyter notebook:

1. Tutorial 1 Simple Rift

[Output Data](https://www.dropbox.com/s/3gy3boh9mf9s807/Tutorial1_BGH.zip?dl=0)

2. Tutorial 2 Melt

[Output Data](https://www.dropbox.com/s/x03vlj03zqvu6wa/Tutorial2_BGH.zip?dl=0)

3. Tutorial 3 Sandbox Extension

[Output Data](https://www.dropbox.com/s/9j24v5ex1eanro2/Tutorial3_BGH.zip?dl=0)

4. Tutorial 4 Sandbox Compression

[Output Data](https://www.dropbox.com/s/4wlp3cociwysz3l/Tutorial4_BGH.zip?dl=0)

5. Tutorial 5 Simple Compression

6. Tutorial 6 Simple Surface Processes

7. Tutorial 7 3D Rift

8. Tutorial 8 ViscoElasticity

9. Tutorial 9 Passive Margins

3.6. Tutorials 49