Skip to content

Array dimensions

SpeedyWeather's two main array types, Field (see RingGrids) for gridded data and LowerTriangularArray (see LowerTriangularArrays) for spectral coefficients, unravel the horizontal into the first array dimension. Any additional array dimension can then represent whatever you like: the vertical, time (or time steps of the time integration), etc. To record what these additional dimensions actually mean, both types (optionally) carry a dimension tag from the ArrayDimensions module alongside their data. The following tags are defined

2D (horizontal only)3D + vertical3D + time4D + vertical + time
grid (Field)XY (default)XYZXYTXYZT
spectral (LowerTriangularArray)LM (default)LMZLMTLMZT

with X, Y for longitude, latitude and L, M for degree, order of the spherical harmonics (both pairs unravelled into a single array dimension), Z for the vertical and T for time. For a ColumnField (vertical first) there are also ZXY and ZXYT. The defaults XY and LM make no assumption about the meaning of any additional dimension.

All of these are singleton types: they hold no data, do not change the memory layout of the arrays, and, being known at compile time, come at no runtime cost.

Where to see the dimensions

The array summary includes the dimension tag in parentheses

julia
using SpeedyWeather
spectrum = Spectrum(trunc=5)
L = rand(ComplexF32, spectrum, ArrayDimensions.LMZ(), 3)
21×3 (LMZ) LowerTriangularArray{ComplexF32, 2, Array{...}}
  0.5495338f0 + 0.85617507f0im   …   0.3832693f0 + 0.14771658f0im
 0.25250167f0 + 0.34652948f0im      0.32182723f0 + 0.01544565f0im
 0.16193259f0 + 0.13495082f0im      0.94626653f0 + 0.26517606f0im
 0.16482687f0 + 0.5160543f0im       0.71985084f0 + 0.550727f0im
 0.45775408f0 + 0.8657239f0im       0.85987383f0 + 0.09043217f0im
  0.4883036f0 + 0.3988183f0im    …  0.31412518f0 + 0.7238646f0im
 0.73194784f0 + 0.45712626f0im       0.7321764f0 + 0.8487993f0im
 0.61145836f0 + 0.26266122f0im      0.46270537f0 + 0.5318322f0im
 0.06408459f0 + 0.36252087f0im      0.61085045f0 + 0.6662761f0im
 0.13353157f0 + 0.0924567f0im       0.40269643f0 + 0.6489929f0im
              ⋮                  ⋱  
 0.29902136f0 + 0.27241814f0im      0.06956583f0 + 0.38148677f0im
 0.22147328f0 + 0.26481986f0im        0.941793f0 + 0.80952847f0im
 0.99720937f0 + 0.049242556f0im      0.5348013f0 + 0.19190854f0im
  0.6846129f0 + 0.06575823f0im   …  0.34098476f0 + 0.9436216f0im
 0.21927404f0 + 0.46466905f0im      0.80336833f0 + 0.2338273f0im
  0.9456021f0 + 0.5473409f0im       0.11122483f0 + 0.5273304f0im
  0.6472176f0 + 0.19517517f0im       0.9412847f0 + 0.76192695f0im
 0.16090089f0 + 0.94818056f0im      0.39025456f0 + 0.7940589f0im
  0.4999041f0 + 0.2646863f0im    …    0.175026f0 + 0.44798207f0im

here (LMZ) says that the 3 elements in the second array dimension are vertical layers. Without an explicit tag the default applies

julia
L2 = rand(ComplexF32, spectrum, 3)
21×3 (LM+) LowerTriangularArray{ComplexF32, 2, Array{...}}
 0.85484886f0 + 0.95688665f0im  …  0.19321424f0 + 0.99328303f0im
 0.46177757f0 + 0.8006432f0im       0.8279084f0 + 0.05851412f0im
 0.97508943f0 + 0.20931792f0im     0.33476275f0 + 0.6468134f0im
  0.6538409f0 + 0.63650143f0im      0.5073716f0 + 0.9006762f0im
  0.7937963f0 + 0.6108911f0im      0.06937432f0 + 0.73154247f0im
 0.55228955f0 + 0.36720383f0im  …  0.44917816f0 + 0.47987092f0im
   0.893504f0 + 0.6691619f0im      0.27290112f0 + 0.42504835f0im
 0.94796324f0 + 0.33080673f0im     0.96722823f0 + 0.6013405f0im
  0.8287775f0 + 0.56906843f0im     0.47677034f0 + 0.99385434f0im
 0.40640885f0 + 0.79079926f0im     0.91624886f0 + 0.34039104f0im
              ⋮                 ⋱  
 0.12023038f0 + 0.83530635f0im      0.5356873f0 + 0.6541905f0im
 0.54252696f0 + 0.25864333f0im      0.5956267f0 + 0.63105154f0im
 0.05833423f0 + 0.33821762f0im     0.64706933f0 + 0.17262793f0im
 0.37622857f0 + 0.21111095f0im  …  0.98133457f0 + 0.50133646f0im
 0.29230762f0 + 0.9459249f0im      0.27015108f0 + 0.03556323f0im
 0.48394996f0 + 0.8298916f0im      0.75122744f0 + 0.8380352f0im
 0.29172027f0 + 0.64567477f0im      0.8622771f0 + 0.83662176f0im
 0.73435694f0 + 0.01346451f0im     0.18777055f0 + 0.81318474f0im
  0.4093191f0 + 0.59641314f0im  …  0.01111424f0 + 0.91808814f0im

and the summary reads (LM+): the + denotes that the array has more dimensions than the tag describes, i.e. no assumption is made about what the second dimension means. The tag is also directly accessible as a field

julia
L.dims
SpeedyWeatherInternals.ArrayDimensions.LMZ()

All of the above works the same for Field, e.g.

julia
field = zeros(FullGaussianGrid(4), ArrayDimensions.XYZ(), 3)
128×3, 8-ring (XYZ) FullGaussianField{Float32, 2} as Array on CPU
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0

 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.0f0

What the dimensions are (not) used for

The dimension tags are bookkeeping only. They do not change how an array is indexed, computed on, or broadcast: multiplying an XYZ field with an XYT field will not return an XYZT field — broadcasting ignores the tags entirely (the result simply carries over the tag of one of its inputs). Instead, the tags allow manual decisions whenever the meaning of a dimension matters, through

julia
ArrayDimensions.hasvertical(L), ArrayDimensions.hastime(L)
(true, false)

or through dispatch on the tag types and their unions like ArrayDimensions.DimensionsWithTime and ArrayDimensions.DimensionsWithVertical.

The tags are preserved through similar, zero, views and broadcasting; indexing into a tagged dimension with an integer drops it accordingly, e.g. L[:, 1] of an LMZ-tagged array returns an LM-tagged one.

Within SpeedyWeather, the variables in simulation.variables carry these tags; in particular the step dimension that prognostic and tendency variables have for the time integration is tagged as time T, so their summaries show, e.g., (LMZT) or (XYZT), see Step dimension. For more details on the two array types see Array dimensions of a Field and Array dimensions for LowerTriangularArray.