Skip to content

Variables

At the top of SpeedyWeather's type tree sits the Simulation, containing Variables and model (e.g. BarotropicModel), which in itself contains model components with their own fields and so on, see Models.

The variables are split into

  • groups: prognostic, grid, tendencies, dynamics, parameterizations, particles and scratch

  • namespace, these are optional sub-categories, e.g. prognostic.land and prognostic.ocean

Such that their paths are fully defined by

julia
simulation.variables.group.namespace.name  # if they are in a namespace
simulaiton.variables.group.name            # otherwise

Where to find the variables can quickly get complicated at that degre of nesting. The following is to give users a better overview of how simulation, variables and model are structured within SpeedyWeather.

Simulation

Let's start at the top. When creating a Simulation, its fields are

julia
using SpeedyWeather
spectral_grid = SpectralGrid(nlayers = 1)
model = BarotropicModel(spectral_grid)
simulation = initialize!(model)
Simulation{...} (688.46 KB)
variables::Variables{...} (158.02 KB)
model::BarotropicModel{...} (588.86 KB)

the variables contain all arrays but also the clock or other scalars that are supposed to be variable, so changing while a simulation is running. Note that the variables depend on what variables are requested by the model and its components, see Variables and Variable system for more information.

In contrast, we largely think of model as being constant after initialization. This is not completely true, as model does contain mutuable structs but mostly for output and feedback. Values that would influence the variables are considered read-only after initialization but there is no hard restriction on this, e.g. you can use Intrusive callbacks to change the model during integration.

The Variables struct

All simulation variables (prognostic and diagnostic) are stored in simulation.variables, which is a Variables struct with 7 (hardcoded) groups prognostic, grid, tendencies, dynamics, parameterizations, particles and scratch. The variables are model-specific, each model only allocates the variables it needs. The prognostic variables in variables.prognostic are generally in spectral coefficients, variables.grid hold gridded variables, variables.tendencies the tendencies, variables.dynamics work arrays that are computed by the dynamical core. variables.parameterizations are those required by the parameterizations and variables.particles by the particle advection. variables.scratch are scratch arrays: These can be used in any computation by should be considered in an undefined state, so write to it before you read from it. Any other component can leave this in any state. But you can use them to avoid allocations and hold intermediate results.

A full overview of all variables can be easily printed with:

julia
simulation.variables
Variables{@NamedTuple{...}, ...} (319.40 KB)
 prognostic (14.81 KB)
│ ├ clock: Clock{DateTime, Second, Int64, Millisecond}
│ ├ scale: Base.RefValue{Float32}
│ └ vorticity: 560×1×1 LowerTriangularArray{ComplexF32, 3, Array{...}}
 grid (116.88 KB)
│ ├ vorticity: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Arr...
│ ├ u: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on CP...
│ └ v: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on CP...
 tendencies (136.10 KB)
│ ├ vorticity: 560×1×2 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ └ grid
│   ├ vorticity: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as A...
│   ├ u: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on ...
│   └ v: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on ...
 dynamics (0 bytes)
 parameterizations (0 bytes)
 particles (0 bytes)
 scratch (51.60 KB)
│ ├ a: 560×1 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ ├ b: 560×1 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ └ transform_memory: 57×1×24×2 ScratchMemory{Array{ComplexF32,...}, ...}
 fused (0 bytes)

These are the default variables of the BarotropicModel, for the ShallowWaterModel we have

julia
spectral_grid = SpectralGrid(nlayers = 1)
model = ShallowWaterModel(spectral_grid)
simulation = initialize!(model)
simulation.variables
Variables{@NamedTuple{...}, ...} (660.00 KB)
 prognostic (57.73 KB)
│ ├ clock: Clock{DateTime, Second, Int64, Millisecond}
│ ├ scale: Base.RefValue{Float32}
│ ├ vorticity: 560×1×2 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ divergence: 560×1×2 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ └ η: 560×2 LowerTriangularArray{ComplexF32, 2, Array{...}}
 grid (194.79 KB)
│ ├ vorticity: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Arr...
│ ├ u: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on CP...
│ ├ v: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on CP...
│ ├ divergence: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Ar...
│ └ η: 3168×1, 48-ring OctahedralGaussianField{Float32, 2} as Array on CPU
 tendencies (239.02 KB)
│ ├ vorticity: 560×1×1 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ divergence: 560×1×1 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ η: 560×1 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ └ grid
│   ├ vorticity: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as A...
│   ├ u: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on ...
│   ├ v: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on ...
│   ├ divergence: 3168×1×1, 48-ring OctahedralGaussianField{Float32, 3} as ...
│   └ η: 3168×1, 48-ring OctahedralGaussianField{Float32, 2} as Array on CP...
 dynamics (38.95 KB)
│ └ geopotential: 3168×1, 48-ring OctahedralGaussianField{Float32, 2} as Ar...
 parameterizations (0 bytes)
 particles (0 bytes)
 scratch (129.50 KB)
│ ├ a: 560×1 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ ├ b: 560×1 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ ├ transform_memory: 57×1×24×2 ScratchMemory{Array{ComplexF32,...}, ...}
│ └ grid
│   ├ a: 3168×1, 48-ring OctahedralGaussianField{Float32, 2} as Array on CP...
│   └ b: 3168×1, 48-ring OctahedralGaussianField{Float32, 2} as Array on CP...
 fused (0 bytes)

The PrimitiveDryModel has the following default variables

julia
spectral_grid = SpectralGrid(nlayers = 8)
model = PrimitiveDryModel(spectral_grid)
simulation = initialize!(model)
simulation.variables
Variables{@NamedTuple{...}, ...} (5.16 MB)
 prognostic (394.63 KB)
│ ├ clock: Clock{DateTime, Second, Int64, Millisecond}
│ ├ scale: Base.RefValue{Float32}
│ ├ vorticity: 560×8×2 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ divergence: 560×8×2 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ temperature: 560×8×2 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ pressure: 560×2 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ ├ land
│ │ └ soil_temperature: 3168×2, 48-ring OctahedralGaussianField{Float32, 2}...
│ └ ocean
│   ├ sea_surface_temperature: 3168-element, 48-ring OctahedralGaussianFiel...
│   └ sea_ice_concentration: 3168-element, 48-ring OctahedralGaussianField{...
 grid (1.20 MB)
│ ├ vorticity: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as Arr...
│ ├ u: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as Array on CP...
│ ├ v: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as Array on CP...
│ ├ divergence: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as Ar...
│ ├ temperature: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as A...
│ └ pressure: 3168×2, 48-ring OctahedralGaussianField{Float32, 2} as Array ...
 tendencies (830.32 KB)
│ ├ vorticity: 560×8×1 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ divergence: 560×8×1 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ temperature: 560×8×1 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ pressure: 560×1 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ └ grid
│   ├ vorticity: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as A...
│   ├ u: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on ...
│   ├ v: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on ...
│   ├ divergence: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as ...
│   ├ temperature: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as...
│   └ pressure: 3168×1, 48-ring OctahedralGaussianField{Float32, 2} as Arra...
 dynamics (939.99 KB)
│ ├ dpres_dx: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as ...
│ ├ dpres_dy: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as ...
│ ├ pres_flux: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as Array...
│ ├ virtual_temperature: 560×8 LowerTriangularArray{ComplexF32, 2, Array{.....
│ ├ u_mean_grid: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} ...
│ ├ v_mean_grid: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} ...
│ ├ div_mean_grid: 3168-element, 48-ring OctahedralGaussianField{Float32, 1...
│ ├ div_mean: 560-element, 33x32 LowerTriangularMatrix{ComplexF32, Array{.....
│ ├ div_sum_above: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as A...
│ ├ pres_flux_sum_above: 3168×8, 48-ring OctahedralGaussianField{Float32, 2...
│ ├ w: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as Array on CPU
│ ├ geopotential: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as Ar...
│ ├ spectral_geopotential: 560×8 LowerTriangularArray{ComplexF32, 2, Array{...
│ └ average_temperature_profile: 8-element Vector{Float32}
 parameterizations (1.17 MB)
│ ├ surface_pressure: 3168-element, 48-ring OctahedralGaussianField{Float32...
│ ├ surface_shortwave_down: 3168-element, 48-ring OctahedralGaussianField{F...
│ ├ surface_longwave_down: 3168-element, 48-ring OctahedralGaussianField{Fl...
│ ├ cos_zenith: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} a...
│ ├ albedo: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as Ar...
│ ├ surface_roughness: 3168-element, 48-ring OctahedralGaussianField{Float3...
│ ├ boundary_layer_drag: 3168-element, 48-ring OctahedralGaussianField{Floa...
│ ├ boundary_layer_height: 3168-element, 48-ring OctahedralGaussianField{Fl...
│ ├ surface_wind_speed: 3168-element, 48-ring OctahedralGaussianField{Float...
│ ├ surface_air_density: 3168-element, 48-ring OctahedralGaussianField{Floa...
│ ├ surface_air_temperature: 3168-element, 48-ring OctahedralGaussianField{...
│ ├ sensible_heat_flux: 3168-element, 48-ring OctahedralGaussianField{Float...
│ ├ surface_shortwave_up: 3168-element, 48-ring OctahedralGaussianField{Flo...
│ ├ outgoing_shortwave: 3168-element, 48-ring OctahedralGaussianField{Float...
│ ├ surface_longwave_up: 3168-element, 48-ring OctahedralGaussianField{Floa...
│ ├ outgoing_longwave: 3168-element, 48-ring OctahedralGaussianField{Float3...
│ ├ land
│ │ ├ surface_shortwave_up: 3168-element, 48-ring OctahedralGaussianField{F...
│ │ ├ surface_longwave_up: 3168-element, 48-ring OctahedralGaussianField{Fl...
│ │ ├ sensible_heat_flux: 3168-element, 48-ring OctahedralGaussianField{Flo...
│ │ ├ albedo: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as ...
│ │ ├ surface_roughness: 3168-element, 48-ring OctahedralGaussianField{Floa...
│ │ └ surface_shortwave_down: 3168-element, 48-ring OctahedralGaussianField...
│ └ ocean
│   ├ surface_shortwave_up: 3168-element, 48-ring OctahedralGaussianField{F...
│   ├ surface_longwave_up: 3168-element, 48-ring OctahedralGaussianField{Fl...
│   ├ surface_humidity_flux: 3168-element, 48-ring OctahedralGaussianField{...
│   ├ surface_sensible_heat_flux: 3168-element, 48-ring OctahedralGaussianF...
│   ├ albedo: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as ...
│   ├ surface_roughness: 3168-element, 48-ring OctahedralGaussianField{Floa...
│   ├ sensible_heat_flux: 3168-element, 48-ring OctahedralGaussianField{Flo...
│   └ surface_shortwave_down: 3168-element, 48-ring OctahedralGaussianField...
 particles (0 bytes)
 scratch (630.30 KB)
│ ├ a: 560×8 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ ├ b: 560×8 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ ├ a_2D: 560-element, 33x32 LowerTriangularMatrix{ComplexF32, Array{...}}
│ ├ b_2D: 560-element, 33x32 LowerTriangularMatrix{ComplexF32, Array{...}}
│ ├ transform_memory: 57×8×24×2 ScratchMemory{Array{ComplexF32,...}, ...}
│ └ grid
│   ├ a: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as Array on CP...
│   ├ b: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as Array on CP...
│   ├ a_2D: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as Ar...
│   └ b_2D: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as Ar...
 fused (0 bytes)

And the most complex model, the PrimitiveWetModel allocates

julia
spectral_grid = SpectralGrid(nlayers = 8)
model = PrimitiveWetModel(spectral_grid)
simulation = initialize!(model)
simulation.variables
Variables{@NamedTuple{...}, ...} (6.36 MB)
 prognostic (567.14 KB)
│ ├ clock: Clock{DateTime, Second, Int64, Millisecond}
│ ├ scale: Base.RefValue{Float32}
│ ├ vorticity: 560×8×2 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ divergence: 560×8×2 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ temperature: 560×8×2 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ pressure: 560×2 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ ├ humidity: 560×8×2 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ land
│ │ ├ soil_temperature: 3168×2, 48-ring OctahedralGaussianField{Float32, 2}...
│ │ ├ soil_moisture: 3168×2, 48-ring OctahedralGaussianField{Float32, 2} as...
│ │ └ snow_depth: 3168-element, 48-ring OctahedralGaussianField{Float32, 1}...
│ └ ocean
│   ├ sea_surface_temperature: 3168-element, 48-ring OctahedralGaussianFiel...
│   └ sea_ice_concentration: 3168-element, 48-ring OctahedralGaussianField{...
 grid (1.43 MB)
│ ├ vorticity: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as Arr...
│ ├ u: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as Array on CP...
│ ├ v: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as Array on CP...
│ ├ divergence: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as Ar...
│ ├ temperature: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as A...
│ ├ pressure: 3168×2, 48-ring OctahedralGaussianField{Float32, 2} as Array ...
│ └ humidity: 3168×8×2, 48-ring OctahedralGaussianField{Float32, 3} as Arra...
 tendencies (1.00 MB)
│ ├ vorticity: 560×8×1 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ divergence: 560×8×1 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ temperature: 560×8×1 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ ├ pressure: 560×1 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ ├ humidity: 560×8×1 LowerTriangularArray{ComplexF32, 3, Array{...}}
│ └ grid
│   ├ vorticity: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as A...
│   ├ u: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on ...
│   ├ v: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as Array on ...
│   ├ divergence: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as ...
│   ├ temperature: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as...
│   ├ pressure: 3168×1, 48-ring OctahedralGaussianField{Float32, 2} as Arra...
│   └ humidity: 3168×8×1, 48-ring OctahedralGaussianField{Float32, 3} as Ar...
 dynamics (939.99 KB)
│ ├ dpres_dx: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as ...
│ ├ dpres_dy: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as ...
│ ├ pres_flux: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as Array...
│ ├ virtual_temperature: 560×8 LowerTriangularArray{ComplexF32, 2, Array{.....
│ ├ u_mean_grid: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} ...
│ ├ v_mean_grid: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} ...
│ ├ div_mean_grid: 3168-element, 48-ring OctahedralGaussianField{Float32, 1...
│ ├ div_mean: 560-element, 33x32 LowerTriangularMatrix{ComplexF32, Array{.....
│ ├ div_sum_above: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as A...
│ ├ pres_flux_sum_above: 3168×8, 48-ring OctahedralGaussianField{Float32, 2...
│ ├ w: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as Array on CPU
│ ├ geopotential: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as Ar...
│ ├ spectral_geopotential: 560×8 LowerTriangularArray{ComplexF32, 2, Array{...
│ └ average_temperature_profile: 8-element Vector{Float32}
 parameterizations (1.79 MB)
│ ├ surface_pressure: 3168-element, 48-ring OctahedralGaussianField{Float32...
│ ├ surface_shortwave_down: 3168-element, 48-ring OctahedralGaussianField{F...
│ ├ surface_longwave_down: 3168-element, 48-ring OctahedralGaussianField{Fl...
│ ├ rain_rate: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as...
│ ├ cos_zenith: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} a...
│ ├ albedo: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as Ar...
│ ├ surface_roughness: 3168-element, 48-ring OctahedralGaussianField{Float3...
│ ├ boundary_layer_drag: 3168-element, 48-ring OctahedralGaussianField{Floa...
│ ├ boundary_layer_height: 3168-element, 48-ring OctahedralGaussianField{Fl...
│ ├ surface_wind_speed: 3168-element, 48-ring OctahedralGaussianField{Float...
│ ├ surface_air_density: 3168-element, 48-ring OctahedralGaussianField{Floa...
│ ├ surface_air_temperature: 3168-element, 48-ring OctahedralGaussianField{...
│ ├ sensible_heat_flux: 3168-element, 48-ring OctahedralGaussianField{Float...
│ ├ surface_humidity_flux: 3168-element, 48-ring OctahedralGaussianField{Fl...
│ ├ rain_large_scale: 3168-element, 48-ring OctahedralGaussianField{Float32...
│ ├ snow_large_scale: 3168-element, 48-ring OctahedralGaussianField{Float32...
│ ├ rain_rate_large_scale: 3168-element, 48-ring OctahedralGaussianField{Fl...
│ ├ snow_rate_large_scale: 3168-element, 48-ring OctahedralGaussianField{Fl...
│ ├ snow_rate: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as...
│ ├ cloud_top: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as...
│ ├ rain_convection: 3168-element, 48-ring OctahedralGaussianField{Float32,...
│ ├ rain_rate_convection: 3168-element, 48-ring OctahedralGaussianField{Flo...
│ ├ surface_shortwave_up: 3168-element, 48-ring OctahedralGaussianField{Flo...
│ ├ outgoing_shortwave: 3168-element, 48-ring OctahedralGaussianField{Float...
│ ├ surface_longwave_up: 3168-element, 48-ring OctahedralGaussianField{Floa...
│ ├ outgoing_longwave: 3168-element, 48-ring OctahedralGaussianField{Float3...
│ ├ land
│ │ ├ surface_shortwave_up: 3168-element, 48-ring OctahedralGaussianField{F...
│ │ ├ surface_longwave_up: 3168-element, 48-ring OctahedralGaussianField{Fl...
│ │ ├ sensible_heat_flux: 3168-element, 48-ring OctahedralGaussianField{Flo...
│ │ ├ river_runoff: 3168-element, 48-ring OctahedralGaussianField{Float32, ...
│ │ ├ surface_humidity_flux: 3168-element, 48-ring OctahedralGaussianField{...
│ │ ├ snow_melt_rate: 3168-element, 48-ring OctahedralGaussianField{Float32...
│ │ ├ vegetation_high: 3168-element, 48-ring OctahedralGaussianField{Float3...
│ │ ├ vegetation_low: 3168-element, 48-ring OctahedralGaussianField{Float32...
│ │ ├ soil_moisture_availability: 3168-element, 48-ring OctahedralGaussianF...
│ │ ├ albedo: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as ...
│ │ ├ surface_roughness: 3168-element, 48-ring OctahedralGaussianField{Floa...
│ │ └ surface_shortwave_down: 3168-element, 48-ring OctahedralGaussianField...
│ └ ocean
│   ├ surface_shortwave_up: 3168-element, 48-ring OctahedralGaussianField{F...
│   ├ surface_longwave_up: 3168-element, 48-ring OctahedralGaussianField{Fl...
│   ├ surface_humidity_flux: 3168-element, 48-ring OctahedralGaussianField{...
│   ├ surface_sensible_heat_flux: 3168-element, 48-ring OctahedralGaussianF...
│   ├ albedo: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as ...
│   ├ surface_roughness: 3168-element, 48-ring OctahedralGaussianField{Floa...
│   ├ sensible_heat_flux: 3168-element, 48-ring OctahedralGaussianField{Flo...
│   └ surface_shortwave_down: 3168-element, 48-ring OctahedralGaussianField...
 particles (0 bytes)
 scratch (630.30 KB)
│ ├ a: 560×8 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ ├ b: 560×8 LowerTriangularArray{ComplexF32, 2, Array{...}}
│ ├ a_2D: 560-element, 33x32 LowerTriangularMatrix{ComplexF32, Array{...}}
│ ├ b_2D: 560-element, 33x32 LowerTriangularMatrix{ComplexF32, Array{...}}
│ ├ transform_memory: 57×8×24×2 ScratchMemory{Array{ComplexF32,...}, ...}
│ └ grid
│   ├ a: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as Array on CP...
│   ├ b: 3168×8, 48-ring OctahedralGaussianField{Float32, 2} as Array on CP...
│   ├ a_2D: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as Ar...
│   └ b_2D: 3168-element, 48-ring OctahedralGaussianField{Float32, 1} as Ar...
 fused (0 bytes)

Setting variables

The prognostic variables can be mutated (e.g. to set new initial conditions) with the SpeedyWeather.set! function. Other variables can be set too but they might be overwritten such that your changes may have a different effect than you expect. You can specify group (default =:prognostic) and namespace (default =nothing) in set! to set variables, e.g.

julia
set!(simulation, sea_surface_temperature=300, namespace=:ocean)

For another example, see Set tracers.

Step dimension

As you'll notice when inspecting simulation.variables is that many prognostic and tendency variables will have one more dimension than you may think they should have. This is the step dimension as many time stepping schemes require either several steps in the prognostic variables (think Leapfrog) or several tendency steps (think multi-step methods). In many cases this additional dimension will just be a trailing singleton dimension and you can drop it by selecting it, e.g. [:, 1]. As the step dimension essentially contains several "versions" of the same variable the error you will make by selecting the wrong one is generally small. In Leapfrog, you would simply select the previous time step for example, see Time steppers. So prognostic and tendency variables have the following dimensions in that order:

  • horizontal dimension (unravalled longitude and latitude, or degree/order of spherical harmonics)

  • vertical (optional, many 2D variables will drop this)

  • step (all Time stepped variables and tendencies have this)

So a conceptually 2D horizontal-only variable may use an array of

  • one dimesion (unravelled horizontal dimension),

  • two dimensions (trailing singleton dimension for the vertical),

  • two dimensions (trailing dimension for the step),

  • or three dimesions (singleton dimension for the vertical, and dimension for step)

and similar with 3D variables (but the vertical dimension isn't singleton then). Whether the step dimension is singleton or not depends on the time stepping scheme in use.

To ease the selection of the step dimension you can use the get_step function without any argument which will automatically create a view onto the array selecting the last step as this in many cases represents the "current" step and not any previous ones. But this depends on your time stepping scheme (which the variable itself does not know about). For example

julia
size(simulation.variables.grid.u)

is a 3D array representing a 3D variable. The array has one more dimension (the last) for the step but one less because horizontal dimensions are unravelled into one. The step dimension here has two steps which represent with Leapfrog time stepping the previous and current step, so to not select the previous time step, you should index [ij, k, 2] here. This is what the get_step function will do for you

julia
get_step(simulation.variables.grid.u)       # selects the last step index automatically
get_step(simulation.variables.grid.u, 1)    # select first step
get_steP(simulation.variables.grid.u, 2)    # select 2nd step

Then you can use [ij, k] indexing afterwards again.