Skip to content

Commit ea047af

Browse files
authored
Merge pull request #163 from tmigot/add-docs
Add docs
2 parents 27f5353 + f20d64f commit ea047af

File tree

6 files changed

+319
-0
lines changed

6 files changed

+319
-0
lines changed

.github/workflows/Documentation.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Documentation
2+
on:
3+
push:
4+
branches:
5+
- main
6+
tags: '*'
7+
pull_request:
8+
types: [opened, synchronize, reopened]
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v2
14+
- uses: julia-actions/setup-julia@latest
15+
with:
16+
version: '1'
17+
- name: Install dependencies
18+
run: julia --project=docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
19+
- name: Build and deploy
20+
env:
21+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22+
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
23+
run: julia --project=docs --color=yes docs/make.jl

docs/Project.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[deps]
2+
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
4+
5+
[compat]
6+
Documenter = "0.27"
7+
Literate = "2"

docs/assets/swm_equations.jl

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# # ShallowWaters.jl - The equations
2+
#
3+
# The shallow water equations for the prognostic variables velocity $\mathbf{u} = (u,v)$ and sea surface elevation $\eta$ over the 2-dimensional domain $\Omega$ in $x,y$ are
4+
#
5+
# ```math
6+
# \begin{align}
7+
# \partial_t u &+ u\partial_xu + v\partial_yu - fv = -g\partial_x\eta + D_x(u,v,\eta) + F_x, \\
8+
# \partial_t v &+ u\partial_xv + v\partial_yv + fu = -g\partial_y\eta + D_y(u,v,\eta) + F_y, \\
9+
# \partial_t \eta &+ \partial_x(uh) + \partial_y(vh) = 0.
10+
# \end{align}
11+
# ```
12+
# where the first two are the momentum equations for $u,v$ and the latter is the continuity equation. The layer thickness is $h = \eta + H$ with $H=H(x,y)$ being the bottom topography. The gravitational acceleration is $g$, the coriolis parameter $f = f(y)$ depends only (i.e. latitude) only and the beta-plane approximation is used. $(D_x,D_y) = \mathbf{D}$ are the dissipative terms
13+
#
14+
# ```math
15+
# \mathbf{D} = -\frac{c_D}{h}\vert \mathbf{u} \vert \mathbf{u} - u \nabla^4\mathbf{u}
16+
# ```
17+
18+
# which are a sum of a quadratic bottom drag with dimensionless coefficient $c_D$ and a biharmonic diffusion with viscosity coefficient $u$. $\mathbf{F} = (F_x,F_y)$ is the wind forcing which can depend on time and space, i.e. $F_x = F_x(x,y,t)$ and $F_y = F_y(x,y,t)$.
19+
20+
# ## The vector invariant formulation
21+
22+
# The Bernoulli potential $p$ is introduced as
23+
24+
# ```math
25+
# p = \frac{1}{2}(u^2 + v^2) + gh
26+
# ```
27+
28+
# The relative vorticity $\zeta = \partial_xv + \partial_yu$ lets us define the potential vorticity $q$ as
29+
30+
# ```math
31+
# q = \frac{f + \zeta}{h}
32+
# ```
33+
34+
# such that we can rewrite the shallow water equations as
35+
36+
# ```math
37+
# \begin{align}
38+
# \partial_t u &= qhv -g\partial_xp + D_x(u,v,\eta) + F_x, \\
39+
# \partial_t v &= -qhu -g\partial_yp + D_y(u,v,\eta) + F_y, \\
40+
# \partial_t \eta &= -\partial_x(uh) -\partial_y(vh).
41+
# \end{align}
42+
# ```
43+
44+
# ## Runge-Kutta time discretisation
45+
46+
# Let
47+
# ```math
48+
# R(u,v,\eta) = \begin{pmatrix}
49+
# qhv-g\partial_xp+F_x
50+
# -qhu-g\partial_yp+F_y
51+
# -\partial_x(uh) -\partial_y(vh)
52+
# \end{pmatrix}
53+
# ```
54+
#
55+
# be the non-dissipative right-hand side, i.e. excluding the dissipative terms $\mathbf{D}$. Then we dicretise the time derivative with 4th order Runge-Kutta with $\mathbf{k}_n = (u_n,v_n,\eta_n)$ by
56+
#
57+
# ```math
58+
# \begin{align}
59+
# \mathbf{d}_1 &= R(\mathbf{k}_n) , \\
60+
# \mathbf{d}_2 &= R(\mathbf{k}_n + \frac{1}{2}\Delta t \mathbf{d}_1), \\
61+
# \mathbf{d}_3 &= R(\mathbf{k}_n + \frac{1}{2}\Delta t \mathbf{d}_2), \\
62+
# \mathbf{d}_4 &= R(\mathbf{k}_n + \Delta t \mathbf{d}_3), \\
63+
# u_{n+1}^*,v_{n+1}^*,\eta_{n+1} = \mathbf{k}_{n+1} &= \mathbf{k}_n + \frac{1}{6}\Delta t(\mathbf{d}_1 + 2\mathbf{d}_2 + 2\mathbf{d}_3 + \mathbf{d}_1),
64+
# \end{align}
65+
# ```
66+
67+
# and the dissipative terms are then added semi-implictly.
68+
69+
# ```math
70+
# \begin{align}
71+
# u_{n+1} = u_{n+1}^* + \Delta t D_x(u_{n+1}^*,v_{n+1}^*,\eta_{n+1}) , \\
72+
# v_{n+1} = v_{n+1}^* + \Delta t D_y(u_{n+1}^*,v_{n+1}^*,\eta_{n+1}).
73+
# \end{align}
74+
# ```
75+
76+
77+
# Consequently, the dissipative terms only have to be evaluated once per time step, which reduces the computational cost of the right=hand side drastically. This is motivated as the Courant number $C = \sqrt{gH_0}$ is restricted by gravity waves, which are caused by $\partial_t\mathbf{u} = -g\nabla\eta$ and $\partial_t\eta = -H_0\nabla \cdot \mathbf{u}$. The other terms have longer time scales, and it is therefore sufficient to solve those with larger time steps. With this scheme, the shallow water model runs stable at $C=1$."
78+
79+
# ## Strong stability preserving Runge-Kutta with semi-implicit continuity equation
80+
81+
# We split the right-hand side into the momentum equations and the continuity equation
82+
83+
# ```math
84+
# R_m(u,v,\eta) = \begin{pmatrix}
85+
# qhv-g\partial_xp+F_x
86+
# -qhu-g\partial_yp+F_y
87+
# \end{pmatrix}, \quad R_\eta(u,v,\eta) = -\partial_x(uh) -\partial_y(vh)
88+
# ```
89+
90+
# The 4-stage strong stability preserving Runge-Kutta scheme, with a semi-implicit treatment of the continuity equation then reads as
91+
92+
# ```math
93+
# \begin{align}
94+
# \mathbf{u}_1 &= \mathbf{u}_n + \frac{1}{2} \Delta t R_m(u_n,v_n,\eta_n), \quad \text{then}
95+
# \quad \eta_1 = \eta_n + \frac{1}{2} \Delta t R_\eta(u_1,v_1,\eta_n), \\
96+
# \mathbf{u}_2 &= \mathbf{u}_1 + \frac{1}{2} \Delta t R_m(u_1,v_1,\eta_1), \quad \text{then}
97+
# \quad \eta_2 = \eta_1 + \frac{1}{2} \Delta t R_\eta(u_2,v_2,\eta_1) , \\
98+
# \mathbf{u}_3 &= \frac{2}{3}\mathbf{u}_n + \frac{1}{3}\mathbf{u}_2 + \frac{1}{6} \Delta t R_m(u_2,v_2,\eta_2), \quad \text{then}
99+
# \quad \eta_3 = \frac{2}{3}\eta_n + \frac{1}{3}\eta_2 + \frac{1}{6} \Delta t R_\eta(u_3,v_3,\eta_2), \\
100+
# \mathbf{u}_{n+1} &= \mathbf{u}_3 + \frac{1}{2} \Delta t R_m(u_3,v_3,\eta_3), \quad \text{then}
101+
# \quad \eta_{n+1} = \eta_3 + \frac{1}{2} \Delta t R_\eta(u_{n+1},v_{n+1},\eta_3).
102+
# \end{align}
103+
# ```
104+
105+
# ## Splitting the continuity equation
106+
107+
# From
108+
# ```math
109+
# \partial_t = -\partial_x(uh) - \partial_y(vh)
110+
# ```

docs/make.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using Documenter
2+
using Literate
3+
using ShallowWaters
4+
5+
EXAMPLE = joinpath(@__DIR__, "assets", "swm_equations.jl")
6+
OUTPUT = joinpath(@__DIR__, "src")
7+
8+
# Generate markdown
9+
binder_badge = "# [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/milankl/ShallowWaters.jl/gh-pages?labpath=dev%2Fswm_equations.ipynb)"
10+
function preprocess_docs(content)
11+
return string(binder_badge, "\n\n", content)
12+
end
13+
14+
Literate.markdown(EXAMPLE, OUTPUT; preprocess=preprocess_docs, codefence="```julia" => "```")
15+
Literate.notebook(EXAMPLE, OUTPUT)
16+
17+
pages = [
18+
"Introduction" => "index.md",
19+
"Tutorial" => "swm_equations.md",
20+
"Reference" => "reference.md",
21+
]
22+
23+
makedocs(
24+
sitename = "ShallowWaters.jl",
25+
format = Documenter.HTML(prettyurls = get(ENV, "CI", nothing) == "true"),
26+
modules = [ShallowWaters],
27+
pages = pages,
28+
)
29+
30+
deploydocs(
31+
repo = "github.com/milankl/ShallowWaters.jl.git",
32+
push_preview = true,
33+
devbranch = "main",
34+
)

docs/src/index.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# ShallowWaters.jl - A type-flexible 16-bit shallow water model
2+
[![CI](https://github.com/milankl/ShallowWaters.jl/actions/workflows/CI.yml/badge.svg)](https://github.com/milankl/ShallowWaters.jl/actions/workflows/CI.yml)
3+
[![DOI](https://zenodo.org/badge/132787050.svg)](https://zenodo.org/badge/latestdoi/132787050)
4+
![sst](https://github.com/milankl/ShallowWaters.jl/tree/main/figs/isambard_float16.png?raw=true "Float16 simulation with ShallowWaters.jl on Isambard's A64FX")
5+
6+
A shallow water model with a focus on type-flexibility and 16-bit number formats. ShallowWaters allows for Float64/32/16,
7+
[Posit32/16/8](https://github.com/milankl/SoftPosit.jl), [BFloat16](https://github.com/JuliaComputing/BFloat16s.jl),
8+
[LogFixPoint16](https://github.com/milankl/LogFixPoint16s.jl), [Sonum16](https://github.com/milankl/Sonums.jl),
9+
[Float32/16 & BFloat16 with stochastic rounding](https://github.com/milankl/StochasticRounding.jl) and in
10+
general every number format with arithmetics and conversions implemented. ShallowWaters also allows for
11+
mixed-precision and reduced precision communication.
12+
13+
ShallowWaters uses an energy and enstrophy conserving advection scheme and a Smagorinsky-like biharmonic diffusion operator.
14+
Tracer advection is implemented with a semi-Lagrangian advection scheme. Strong stability-preserving Runge-Kutta schemes of
15+
various orders and stages are used with a semi-implicit treatment of the continuity equation. Boundary conditions are either
16+
periodic (only in x direction) or non-periodic super-slip, free-slip, partial-slip, or no-slip.
17+
Output via [NetCDF](https://github.com/JuliaGeo/NetCDF.jl).
18+
19+
Please feel free to raise an [issue](https://github.com/milankl/ShallowWaters.jl/issues) if you discover bugs or have an idea how to improve ShallowWaters.
20+
21+
Requires: Julia 1.2 or higher
22+
23+
## How to use
24+
25+
`RunModel` initialises the model, preallocates memory and starts the time integration. You find the options and default parameters in `src/DefaultParameters.jl` (or by typing `?Parameter`).
26+
```julia
27+
help?> Parameter
28+
search: Parameter
29+
30+
Creates a Parameter struct with following options and default values
31+
32+
T::DataType=Float32 # number format
33+
34+
Tprog::DataType=T # number format for prognostic variables
35+
Tcomm::DataType=Tprog # number format for ghost-point copies
36+
37+
# DOMAIN RESOLUTION AND RATIO
38+
nx::Int=100 # number of grid cells in x-direction
39+
Lx::Real=2000e3 # length of the domain in x-direction [m]
40+
L_ratio::Real=2 # Domain aspect ratio of Lx/Ly
41+
...
42+
```
43+
They can be changed with keyword arguments. The number format `T` is defined as the first (but optional) argument of `RunModel(T,...)`
44+
```julia
45+
julia> Prog = run_model(Float32,Ndays=10,g=10,H=500,Fx0=0.12);
46+
Starting ShallowWaters on Sun, 20 Oct 2019 19:58:25 without output.
47+
100% Integration done in 4.65s.
48+
```
49+
or by creating a Parameter struct
50+
```julia
51+
julia> P = Parameter(bc="nonperiodic",wind_forcing_x="double_gyre",L_ratio=1,nx=128);
52+
julia> Prog = run_model(P);
53+
```
54+
The number formats can be different (aka mixed-precision) for different parts of the model. `Tprog` is the number type for the prognostic variables, `Tcomm` is used for communication of boundary values.
55+
56+
## Double-gyre example
57+
58+
You can for example run a double gyre simulation like this
59+
```julia
60+
julia> using ShallowWaters
61+
julia> P = run_model(Ndays=100,nx=100,L_ratio=1,bc="nonperiodic",wind_forcing_x="double_gyre",topography="seamount");
62+
Starting ShallowWaters on Sat, 15 Aug 2020 11:59:21 without output.
63+
100% Integration done in 13.7s.
64+
```
65+
Sea surface height can be visualised via
66+
```julia
67+
julia> using PyPlot
68+
julia> pcolormesh(P.η')
69+
```
70+
![Figure_1](https://user-images.githubusercontent.com/25530332/90311163-1ee40a00-def0-11ea-8911-810d7762cd3f.png)
71+
72+
Or let's calculate the speed of the currents
73+
```julia
74+
julia> speed = sqrt.(Ix(P.u.^2)[:,2:end-1] + Iy(P.v.^2)[2:end-1,:])
75+
```
76+
`P.u` and `P.v` are the u,v velocity components on the Arakawa C-grid. To add them, we need to interpolate them with `Ix,Iy` (which are exported by `ShallowWaters.jl` too), then chopping off the edges to get two arrays of the same size.
77+
```julia
78+
julia> pcolormesh(speed')
79+
```
80+
![Figure_2](https://user-images.githubusercontent.com/25530332/90311211-88fcaf00-def0-11ea-8308-b4f438495152.png)
81+
82+
Such that the currents are strongest around the two eddies, as expected in this quasi-geostrophic setup.
83+
84+
## (Some) Features
85+
86+
- Interpolation of initial conditions from low resolution / high resolution runs.
87+
- Output of relative vorticity, potential vorticity and tendencies du,dv,deta
88+
- (Pretty accurate) duration estimate
89+
- Can be run in ensemble mode with ordered non-conflicting output files
90+
- Runs at CFL=1 (RK4), and more with the strong stability-preserving Runge-Kutta methods
91+
- Solving the tracer advection comes at basically no cost, thanks to semi-Lagrangian advection scheme
92+
- Also outputs the gradient operators ∂/∂x,∂/∂y and interpolations Ix, Iy for easier post-processing.
93+
94+
## Installation
95+
96+
ShallowWaters.jl is a registered package, so simply do
97+
98+
```julia
99+
julia> ] add ShallowWaters
100+
```
101+
102+
## References
103+
104+
ShallowWaters.jl was used and is described in more detail in
105+
106+
Klöwer M, Düben PD, Palmer TN. Number formats, error mitigation and scope for 16-bit arithmetics in weather and climate modelling analysed with a shallow water model. Journal of Advances in Modeling Earth Systems. doi: [10.1029/2020MS002246](https://dx.doi.org/10.1029/2020MS002246)
107+
108+
Klöwer M, Düben PD, Palmer TN. Posits as an alternative to floats for weather and climate models. In: Proceedings of the Conference for Next Generation Arithmetic 2019. doi: [10.1145/3316279.3316281](https://dx.doi.org/10.1145/3316279.3316281)
109+
110+
## The equations
111+
112+
The non-linear shallow water model plus tracer equation is
113+
114+
∂u/∂t + (u⃗⋅∇)u - f*v = -g*∂η/∂x - c_D*|u⃗|*u + ∇⋅ν*∇(∇²u) + Fx(x,y) (1)
115+
∂v/∂t + (u⃗⋅∇)v + f*u = -g*∂η/∂y - c_D*|u⃗|*v + ∇⋅ν*∇(∇²v) + Fy(x,y) (2)
116+
∂η/∂t = -∇⋅(u⃗h) + γ*(η_ref - η) + Fηt(t)*Fη(x,y) (3)
117+
∂ϕ/∂t = -u⃗⋅∇ϕ (4)
118+
119+
with the prognostic variables velocity u⃗ = (u,v) and sea surface heigth η. The layer thickness is h = η + H(x,y). The Coriolis parameter is f = f₀ + βy with beta-plane approximation. The graviational acceleration is g. Bottom friction is either quadratic with drag coefficient c_D or linear with inverse time scale r. Diffusion is realized with a biharmonic diffusion operator, with either a constant viscosity coefficient ν, or a Smagorinsky-like coefficient that scales as ν = c_Smag*|D|, with deformation rate |D| = √((∂u/∂x - ∂v/∂y)² + (∂u/∂y + ∂v/∂x)²). Wind forcing Fx is constant in time, but may vary in space.
120+
121+
The linear shallow water model equivalent is
122+
123+
∂u/∂t - f*v = -g*∂η/∂x - r*u + ∇⋅ν*∇(∇²u) + Fx(x,y) (1)
124+
∂v/∂t + f*u = -g*∂η/∂y - r*v + ∇⋅ν*∇(∇²v) + Fy(x,y) (2)
125+
∂η/∂t = -H*∇⋅u⃗ + γ*(η_ref - η) + Fηt(t)*Fη(x,y) (3)
126+
∂ϕ/∂t = -u⃗⋅∇ϕ (4)
127+
128+
ShallowWaters.jl discretises the equation on an equi-distant Arakawa C-grid, with 2nd order finite-difference operators. Boundary conditions are implemented via a ghost-point copy and each variable has a halo of variable size to account for different stencil sizes of various operators.

docs/src/reference.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Reference
2+
3+
## Contents
4+
5+
```@contents
6+
Pages = ["reference.md"]
7+
```
8+
9+
## Index
10+
11+
```@index
12+
Pages = ["reference.md"]
13+
```
14+
15+
```@autodocs
16+
Modules = [ShallowWaters]
17+
```

0 commit comments

Comments
 (0)