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 + vertical | 3D + time | 4D + vertical + time | |
|---|---|---|---|---|
grid (Field) | XY (default) | XYZ | XYT | XYZT |
spectral (LowerTriangularArray) | LM (default) | LMZ | LMT | LMZT |
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
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.44798207f0imhere (LMZ) says that the 3 elements in the second array dimension are vertical layers. Without an explicit tag the default applies
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.91808814f0imand 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
L.dimsSpeedyWeatherInternals.ArrayDimensions.LMZ()All of the above works the same for Field, e.g.
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.0f0What 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
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.