Skip to content

Commit

Permalink
Merge branch 'main' into mk/josspaper
Browse files Browse the repository at this point in the history
  • Loading branch information
milankl committed Mar 3, 2024
2 parents 5a4e5a4 + 3c974d5 commit d4e5125
Show file tree
Hide file tree
Showing 141 changed files with 7,507 additions and 5,489 deletions.
1 change: 1 addition & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:
version:
- '1.8'
- '1.9'
- '1.10'
os:
- ubuntu-latest
arch:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/DocPreviewCleanup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout gh-pages branch
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
ref: gh-pages
- name: Delete preview and history + push changes
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/Documenter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@latest
with:
version: '1.8'
version: '1.10'
- name: Install dependencies
run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
run: julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
- name: Build and deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key
run: julia --project=docs/ docs/make.jl
run: JULIA_DEBUG=Documenter julia --color=yes --project=docs/ docs/make.jl
20 changes: 13 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "SpeedyWeather"
uuid = "9e226e20-d153-4fed-8a5b-493def4f21a9"
authors = ["Milan Klöwer and SpeedyWeather contributors"]
version = "0.6.0"
version = "0.8"

[deps]
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
Expand Down Expand Up @@ -30,22 +30,28 @@ UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"

[compat]
AbstractFFTs = "1"
Adapt = "3"
Adapt = "3, 4"
AssociatedLegendrePolynomials = "1"
BitInformation = "0.6"
CUDA = "4"
CUDA = "4, 5"
CodecZlib = "0.7"
Dates = "1.8"
DocStringExtensions = "0.9"
FFTW = "1"
FLoops = "0.2"
FastGaussQuadrature = "0.4, 0.5"
FastGaussQuadrature = "0.4, 0.5, 1"
GenericFFT = "0.1"
JLD2 = "0.4"
KernelAbstractions = "0.9"
NCDatasets = "0.12"
LinearAlgebra = "1.8"
NCDatasets = "0.12, 0.13, 0.14"
Primes = "0.5"
ProgressMeter = "^1.7"
UnicodePlots = "^3.3"
Printf = "1.8"
ProgressMeter = "1.7"
Random = "1.8"
Statistics = "1.8"
TOML = "1"
UnicodePlots = "3.3"
julia = "1.8"

[extras]
Expand Down
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# SpeedyWeather.jl
[![CI](https://github.com/SpeedyWeather/SpeedyWeather.jl/actions/workflows/CI.yml/badge.svg)](https://github.com/SpeedyWeather/SpeedyWeather.jl/actions/workflows/CI.yml)
[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://speedyweather.github.io/SpeedyWeather.jl/stable/)
[![](https://img.shields.io/badge/docs-dev-blue.svg)](https://speedyweather.github.io/SpeedyWeather.jl/dev/)

[![CI](https://github.com/SpeedyWeather/SpeedyWeather.jl/actions/workflows/CI.yml/badge.svg)](https://github.com/SpeedyWeather/SpeedyWeather.jl/actions/workflows/CI.yml)
[![docs](https://img.shields.io/badge/documentation-latest_release-blue.svg)](https://speedyweather.github.io/SpeedyWeather.jl/stable/)
[![docs](https://img.shields.io/badge/documentation-main-blue.svg)](https://speedyweather.github.io/SpeedyWeather.jl/dev/)
[![status](https://joss.theoj.org/papers/515c81a4d6a69e31cc71ded65ac9c36a/status.svg)](https://joss.theoj.org/papers/515c81a4d6a69e31cc71ded65ac9c36a)

SpeedyWeather.jl is a global spectral atmospheric model with simple physics which is developed as a research playground
with an everything-flexible attitude as long as it is speedy. With minimal code redundancies it supports
Expand Down Expand Up @@ -31,7 +33,7 @@ With v0.6 the interface to SpeedyWeather.jl consist of 4 steps: define the grid,
spectral_grid = SpectralGrid(trunc=31, Grid=OctahedralGaussianGrid, nlev=8)
model = PrimitiveDryModel(;spectral_grid, orography = EarthOrography(spectral_grid))
simulation = initialize!(model)
run!(simulation,n_days=10,output=true)
run!(simulation,period=Day(10),output=true)
```
and you will see

Expand Down Expand Up @@ -63,11 +65,18 @@ at T511 (~20km resolution) and 31 vertical levels. The simulation was multi-thre
https://github.com/SpeedyWeather/SpeedyWeather.jl/assets/25530332/95897b82-9b81-4980-934b-cfdcf4d5a4b0

SpeedyWeather.jl can also solve the 2D barotropic vorticity equations on the sphere.
Here, we use single-threaded Float32 (single precision) at a resolution of T340 (40km) on
an [octahedral Gaussian grid](https://speedyweather.github.io/SpeedyWeather.jl/dev/grids/#Implemented-grids).
Initial conditions are randomly distributed relative vorticity on a slowly rotating Earth ($\Omega = 10^{-6}\text{ s}^{-1}$) and no forcing is applied
Here, we use Float32 (single precision) at a resolution of T340 (40km) on
an [octahedral Gaussian grid](https://speedyweather.github.io/SpeedyWeather.jl/dev/grids/#Implemented-grids).
Forcing is a stochastic stirring on northern hemisphere mid-latitudes following Barnes and Hartmann, 2011.
Map projection is orthographic centred on the north pole.

https://github.com/SpeedyWeather/SpeedyWeather.jl/assets/25530332/3d7fccd5-b66d-42e3-9f73-64dcf21d00ee

Here, SpeedyWeather.jl simulates atmospheric gravity waves, initialised randomly interacting with orography
over a period of 2 days. Each frame is one time step, solved with a centred semi-implicit scheme that
resolves gravity waves with a timestep of CFL=1.2-1.4 despite a single-stage RAW-filtered leapfrog integration.

https://github.com/SpeedyWeather/SpeedyWeather.jl/assets/25530332/8a7c6758-950f-424d-8ece-0480295386b3
https://github.com/SpeedyWeather/SpeedyWeather.jl/assets/25530332/510c38c7-12cb-42d5-b905-c66b4eaa514d

## History

Expand Down
6 changes: 3 additions & 3 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ PythonPlot = "274fc56d-3b97-40fa-a1cd-1b4a50311bf9"
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"

[compat]
Documenter = "0.26, 0.27"
NCDatasets = "0.12"
UnicodePlots = "^3.3"
Documenter = "0.26, 0.27, 1"
NCDatasets = "0.12, 0.13, 0.14"
PythonPlot = "1"
UnicodePlots = "3.3"
58 changes: 40 additions & 18 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,25 +1,47 @@
using Documenter, SpeedyWeather

makedocs(
format=Documenter.HTML(prettyurls=get(ENV, "CI", nothing)=="true",
ansicolor=true),
sitename="SpeedyWeather.jl",
authors="M Klöwer and SpeedyWeather contributors",
modules=[SpeedyWeather],
pages=["Home"=>"index.md",
format = Documenter.HTML(prettyurls=get(ENV, "CI", nothing)=="true",
ansicolor=true, collapselevel=1,
size_threshold = 600_000), # in bytes
sitename = "SpeedyWeather.jl",
authors = "M Klöwer and SpeedyWeather contributors",
modules = [SpeedyWeather],
pages = ["Home"=>"index.md",
"Installation"=>"installation.md",
"How to run SpeedyWeather.jl"=>"how_to_run_speedy.md",
"Spherical Harmonic Transform"=>"spectral_transform.md",
"Grids"=>"grids.md",
"Barotropic model"=>"barotropic.md",
"Shallow water model"=>"shallowwater.md",
"Primitive equation model"=>"primitiveequation.md",
"Parameterizations"=>"parameterizations.md",
"Extending SpeedyWeather"=>"extending.md",
"NetCDF output"=>"output.md",
"Submodule: RingGrids"=>"ringgrids.md",
"Submodule: LowerTriangularMatrices"=>"lowertriangularmatrices.md",
"Submodule: SpeedyTransforms"=>"speedytransforms.md",
"Dynamics" => [
"Barotropic model"=>"barotropic.md",
"Shallow water model"=>"shallowwater.md",
"Primitive equation model"=>"primitiveequation.md",
],
"Physics" => [
"Large-scale condensation"=>"large_scale_condensation.md",
"Convection"=>"convection.md",
"Radiation"=>"radiation.md",
"Vertical diffusion"=>"vertical_diffusion.md",
"Surface fluxes"=>"surface_fluxes.md",
],
"Discretization" => [
"Spherical Harmonic Transform"=>"spectral_transform.md",
"Grids"=>"grids.md",
],
"Running SpeedyWeather" => [
"How to run SpeedyWeather"=>"how_to_run_speedy.md",
"Model setups"=>"setups.md",
"NetCDF output"=>"output.md",
],
"Extending SpeedyWeather" => [
"Forcing and drag"=>"forcing_drag.md",
"Parameterizations"=>"parameterizations.md",
"Orography"=>"orography.md",
"Land-Sea Mask"=>"land_sea_mask.md",
"Callbacks"=>"callbacks.md",
],
"Submodules" => [
"RingGrids"=>"ringgrids.md",
"LowerTriangularMatrices"=>"lowertriangularmatrices.md",
"SpeedyTransforms"=>"speedytransforms.md",
],
"Function and type index"=>"functions.md"]
)

Expand Down
24 changes: 13 additions & 11 deletions docs/src/barotropic.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ single global layer on the sphere.

```math
\frac{\partial \zeta}{\partial t} + \nabla \cdot (\mathbf{u}(\zeta + f)) =
\nabla \times \mathbf{F} + (-1)^{n+1}\nu\nabla^{2n}\zeta
F_\zeta + \nabla \times \mathbf{F}_\mathbf{u} + (-1)^{n+1}\nu\nabla^{2n}\zeta
```
We denote time``t``, velocity vector ``\mathbf{u} = (u, v)``, Coriolis parameter ``f``,
and hyperdiffusion ``(-1)^{n+1} \nu \nabla^{2n} \zeta``
(``n`` is the hyperdiffusion order, see [Horizontal diffusion](@ref diffusion)).
We also include a forcing vector ``\mathbf{F} = (F_u,F_v)`` which acts on the
zonal velocity ``u`` and the meridional velocity ``v`` and hence its curl ``\nabla \times \mathbf{F}``
is a tendency for relative vorticity ``\zeta``.
We also include possible forcing terms
``F_\zeta, \mathbf{F}_\mathbf{u} = (F_u,F_v)`` which act on the vorticity and/or on the
zonal velocity ``u`` and the meridional velocity ``v`` and hence the curl
``\nabla \times \mathbf{F}_\mathbf{u}`` is a tendency for relative vorticity ``\zeta``.
See [Extending SpeedyWeather](@ref) how to define these.

Starting with some relative vorticity ``\zeta``, the [Laplacian](@ref) is
inverted to obtain the stream function ``\Psi``
Expand All @@ -51,7 +53,7 @@ which is described in [Derivatives in spherical coordinates](@ref). Using ``u``
advect the absolute vorticity ``\zeta + f``. In order to avoid to calculate both the curl and the
divergence of a flux we rewrite the barotropic vorticity equation as
```math
\frac{\partial \zeta}{\partial t} =
\frac{\partial \zeta}{\partial t} = F_\zeta +
\nabla \times (\mathbf{F} + \mathbf{u}_\perp(\zeta + f)) + (-1)^{n+1}\nu\nabla^{2n}\zeta
```
with ``\mathbf{u}_\perp = (v,-u)`` the rotated velocity vector, because
Expand All @@ -74,11 +76,11 @@ transform this model state to grid-point space:

Now loop over

1. Compute the forcing vector ``\mathbf{F} = (F_u,F_v)`` for ``u`` and ``v``
1. Compute the forcing (or drag) terms ``F_\zeta, \mathbf{F}_\mathbf{u}``
2. Multiply ``u,v`` with ``\zeta+f`` in grid-point space
3. Add ``A = F_u + v(\zeta + f)`` and ``B = F_v - u(\zeta + f)``
4. Transform these vector components to spectral space ``A_{lm}``, ``B_{lm}``
5. Compute the curl of ``(A,B)_{lm}`` in spectral space which is the tendency of ``\zeta_{lm}``
5. Compute the curl of ``(A,B)_{lm}`` in spectral space, add to ``F_\zeta`` to accumulate the tendency of ``\zeta_{lm}``
6. Compute the [horizontal diffusion](@ref diffusion) based on that tendency
7. Compute a leapfrog time step as described in [Time integration](@ref leapfrog) with a [Robert-Asselin and Williams filter](@ref)
8. Transform the new spectral state of ``\zeta_{lm}`` to grid-point ``u,v,\zeta`` as described in 0.
Expand All @@ -89,7 +91,7 @@ Now loop over

## [Horizontal diffusion](@id diffusion)

In SpeedyWeather.jl we use hyerdiffusion through an ``n``-th power Laplacian ``(-1)^{n+1}\nabla^{2n}`` (hyper when ``n>1``) which
In SpeedyWeather.jl we use hyperdiffusion through an ``n``-th power Laplacian ``(-1)^{n+1}\nabla^{2n}`` (hyper when ``n>1``) which
can be implemented as a multiplication of the spectral coefficients ``\Psi_{lm}`` with ``(-l(l+1))^nR^{-2n}`` (see
spectral [Laplacian](@ref)) It is therefore computationally not more expensive to apply hyperdiffusion over diffusion
as the ``(-l(l+1))^nR^{-2n}`` can be precomputed. Note the sign change ``(-1)^{n+1}`` here is such that the dissipative nature of the diffusion operator is retained for ``n`` odd and even.
Expand Down Expand Up @@ -162,7 +164,7 @@ A scaling for vorticity ``\zeta`` and stream function ``\Psi`` is used that is
\tilde{\zeta} = \zeta R, \tilde{\Psi} = \Psi R^{-1}.
```
This is also convenient as vorticity is often ``10^{-5}\text{ s}^{-1}`` in the atmosphere,
but the streamfunction more like ``10^5\text{ m}^2\text{ s}^{-1}`` and so this scaling
but the stream function more like ``10^5\text{ m}^2\text{ s}^{-1}`` and so this scaling
brings both closer to 1 with a typical radius of the Earth of 6371km.
The inversion of the Laplacians in order to obtain ``\Psi`` from ``\zeta`` therefore becomes
```math
Expand All @@ -184,7 +186,7 @@ with
So scaling with the radius squared means we can use dimensionless operators, however, this comes at the
cost of needing to deal with both a time step in seconds as well as a scaled time step in seconds per
meter, which can be confusing. Furthermore, some constants like Coriolis or the diffusion coefficient
need to be scaled too during initialisation, which may be confusing too because values are not
need to be scaled too during initialization, which may be confusing too because values are not
what users expect them to be. SpeedyWeather.jl follows the logic that the scaling to the prognostic
variables is only applied just before the time integration and variables are unscaled for output
and after the time integration finished. That way, the scaling is hidden as much as possible from
Expand All @@ -211,7 +213,7 @@ For the Leapfrog time integration two time steps of the prognostic variables hav
to ``i-1`` in a step that also swaps the indices for the next time step ``i \to i-1`` and ``i+1 \to i``,
so that no additional memory than two time steps have to be stored at the same time.

The Leapfrog time integration has to be initialised with an Euler forward step in order
The Leapfrog time integration has to be initialized with an Euler forward step in order
to have a second time step ``i+1`` available when starting from ``i`` to actually leapfrog over.
SpeedyWeather.jl therefore does two initial time steps that are different from
the leapfrog time steps that follow and that have been described above.
Expand Down
Loading

0 comments on commit d4e5125

Please sign in to comment.