1
+ const LTM = LowerTriangularMatrix # for convenience
2
+
1
3
""" A SpeedyWeather forcing term that stochastically stirrs relative vorticity in
2
4
the BarotropicModel or the ShallowWaterModel.
3
5
$(TYPEDFIELDS) """
4
- Base. @kwdef struct StochasticStirring{NF} <: SpeedyWeather.AbstractForcing{NF}
6
+ Base. @kwdef struct StochasticStirring{NF} <: SpeedyWeather.AbstractForcing
5
7
6
8
# DIMENSIONS from SpectralGrid
7
9
" Spectral resolution as max degree of spherical harmonics"
@@ -16,13 +18,13 @@ Base.@kwdef struct StochasticStirring{NF} <: SpeedyWeather.AbstractForcing{NF}
16
18
decorrelation_time:: Second = Day (2 )
17
19
18
20
" Stirring strength A [1/s²]"
19
- strength:: Float64 = 7e-11
21
+ strength:: NF = 7e-11
20
22
21
23
" Stirring latitude [˚N]"
22
- latitude:: Float64 = 45
24
+ latitude:: NF = 45
23
25
24
26
" Stirring width [˚]"
25
- width:: Float64 = 24
27
+ width:: NF = 24
26
28
27
29
" Minimum degree of spherical harmonics to force"
28
30
lmin:: Int = 8
@@ -38,7 +40,7 @@ Base.@kwdef struct StochasticStirring{NF} <: SpeedyWeather.AbstractForcing{NF}
38
40
39
41
# TO BE INITIALISED
40
42
" Stochastic stirring term S"
41
- S:: LowerTriangularMatrix {Complex{NF}} = zeros (LowerTriangularMatrix {Complex{NF}},trunc+ 2 ,trunc+ 1 )
43
+ S:: LTM {Complex{NF}} = zeros (LTM {Complex{NF}},trunc+ 2 ,trunc+ 1 )
42
44
43
45
" a = A*sqrt(1 - exp(-2dt/τ)), the noise factor times the stirring strength [1/s²]"
44
46
a:: Base.RefValue{NF} = Ref (zero (NF))
54
56
$(TYPEDSIGNATURES)
55
57
Generator function for StochasticStirring using resolution and number format
56
58
from a SpectralGrid. Further options should be provided as keyword arguments."""
57
- function StochasticStirring (SG:: SpectralGrid ;kwargs... )
58
- (;trunc,Grid,nlat_half) = SG
59
- nlat = RingGrids. get_nlat (Grid,nlat_half)
60
- return StochasticStirring {SG.NF} (;trunc,nlat,kwargs... )
59
+ function StochasticStirring (SG:: SpectralGrid ; kwargs... )
60
+ (;trunc, Grid, nlat_half) = SG
61
+ nlat = RingGrids. get_nlat (Grid, nlat_half)
62
+ return StochasticStirring {SG.NF} (; trunc, nlat, kwargs... )
61
63
end
62
64
63
65
"""
@@ -70,7 +72,7 @@ function SpeedyWeather.initialize!( forcing::StochasticStirring,
70
72
model:: ModelSetup )
71
73
72
74
# precompute forcing strength, scale with radius^2 as is the vorticity equation
73
- (;radius) = model. spectral_grid
75
+ (; radius) = model. spectral_grid
74
76
A = radius^ 2 * forcing. strength
75
77
76
78
# precompute noise and auto-regressive factor, packed in RefValue for mutability
@@ -91,12 +93,14 @@ function SpeedyWeather.initialize!( forcing::StochasticStirring,
91
93
end
92
94
93
95
# function barrier to unpack from model what's needed (spectral transform only here)
94
- function SpeedyWeather. forcing! (diagn:: DiagnosticVariablesLayer ,
95
- progn:: PrognosticVariablesLayer ,
96
- forcing:: StochasticStirring ,
97
- time:: DateTime ,
98
- model:: ModelSetup )
99
- SpeedyWeather. forcing! (diagn,forcing,model. spectral_transform)
96
+ function SpeedyWeather. forcing! (
97
+ diagn:: DiagnosticVariablesLayer ,
98
+ progn:: PrognosticVariablesLayer ,
99
+ forcing:: StochasticStirring ,
100
+ time:: DateTime ,
101
+ model:: ModelSetup ,
102
+ )
103
+ SpeedyWeather. forcing! (diagn, forcing, model. spectral_transform)
100
104
end
101
105
102
106
"""
@@ -106,9 +110,11 @@ coefficients S of the forcing following an AR1 process in time, transforms
106
110
to grid-point space to apply a mask to only force specified latitudes then
107
111
transforms back to force in spectral space where also the time stepping is
108
112
applied."""
109
- function SpeedyWeather. forcing! (diagn:: DiagnosticVariablesLayer ,
110
- forcing:: StochasticStirring{NF} ,
111
- spectral_transform:: SpectralTransform ) where NF
113
+ function SpeedyWeather. forcing! (
114
+ diagn:: DiagnosticVariablesLayer ,
115
+ forcing:: StochasticStirring{NF} ,
116
+ spectral_transform:: SpectralTransform
117
+ ) where NF
112
118
113
119
# noise and auto-regressive factors
114
120
a = forcing. a[] # = sqrt(1 - exp(-2dt/τ))
@@ -130,14 +136,14 @@ function SpeedyWeather.forcing!(diagn::DiagnosticVariablesLayer,
130
136
131
137
# to grid-point space
132
138
S_grid = diagn. dynamics_variables. a_grid # reuse general work array
133
- SpeedyTransforms. gridded! (S_grid,S, spectral_transform)
139
+ SpeedyTransforms. gridded! (S_grid, S, spectral_transform)
134
140
135
141
# mask everything but mid-latitudes
136
- RingGrids. _scale_lat! (S_grid,forcing. lat_mask)
142
+ RingGrids. _scale_lat! (S_grid, forcing. lat_mask)
137
143
138
144
# back to spectral space, write directly into vorticity tendency
139
- (;vor_tend) = diagn. tendencies
140
- SpeedyTransforms. spectral! (vor_tend,S_grid,spectral_transform)
145
+ (; vor_tend) = diagn. tendencies
146
+ SpeedyTransforms. spectral! (vor_tend, S_grid, spectral_transform)
141
147
142
148
return nothing
143
149
end
0 commit comments