1
+ """ A SpeedyWeather forcing term that stochastically stirrs relative vorticity in
2
+ the BarotropicModel or the ShallowWaterModel.
3
+ $(TYPEDFIELDS) """
1
4
Base. @kwdef struct StochasticStirring{NF} <: SpeedyWeather.AbstractForcing{NF}
2
5
3
6
# DIMENSIONS from SpectralGrid
@@ -47,12 +50,22 @@ Base.@kwdef struct StochasticStirring{NF} <: SpeedyWeather.AbstractForcing{NF}
47
50
lat_mask:: Vector{NF} = zeros (NF,nlat)
48
51
end
49
52
53
+ """
54
+ $(TYPEDSIGNATURES)
55
+ Generator function for StochasticStirring using resolution and number format
56
+ from a SpectralGrid. Further options should be provided as keyword arguments."""
50
57
function StochasticStirring (SG:: SpectralGrid ;kwargs... )
51
58
(;trunc,Grid,nlat_half) = SG
52
59
nlat = RingGrids. get_nlat (Grid,nlat_half)
53
60
return StochasticStirring {SG.NF} (;trunc,nlat,kwargs... )
54
61
end
55
62
63
+ """
64
+ $(TYPEDSIGNATURES)
65
+ Extends the initialize! function for StochasticStirring to precompute
66
+ the AR1 coefficients for the stochastic processes per spherical harmonic.
67
+ Also precomputes a Gaussian latitudinal mask to only force at given latitude
68
+ with width as specified in StochasticStirring."""
56
69
function SpeedyWeather. initialize! ( forcing:: StochasticStirring ,
57
70
model:: ModelSetup )
58
71
@@ -61,14 +74,14 @@ function SpeedyWeather.initialize!( forcing::StochasticStirring,
61
74
A = radius^ 2 * forcing. strength
62
75
63
76
# precompute noise and auto-regressive factor, packed in RefValue for mutability
64
- dt = model. time_stepping. Δt_sec
77
+ dt = model. time_stepping. Δt_sec # in seconds
65
78
τ = forcing. decorrelation_time. value # in seconds
66
79
forcing. a[] = A* sqrt (1 - exp (- 2 dt/ τ))
67
80
forcing. b[] = exp (- dt/ τ)
68
81
69
- # precompute the latitudinal mask
82
+ # precompute the Gaussian latitudinal mask
70
83
(;Grid,nlat_half) = model. spectral_grid
71
- latd = RingGrids. get_latd (Grid,nlat_half)
84
+ latd = RingGrids. get_latd (Grid,nlat_half) # in ˚N
72
85
73
86
for j in eachindex (forcing. lat_mask)
74
87
# Gaussian centred at forcing.latitude of width forcing.width
@@ -78,6 +91,7 @@ function SpeedyWeather.initialize!( forcing::StochasticStirring,
78
91
return nothing
79
92
end
80
93
94
+ # function barrier to unpack from model what's needed (spectral transform only here)
81
95
function SpeedyWeather. forcing! (diagn:: DiagnosticVariablesLayer ,
82
96
progn:: PrognosticVariablesLayer ,
83
97
forcing:: StochasticStirring ,
@@ -86,6 +100,13 @@ function SpeedyWeather.forcing!(diagn::DiagnosticVariablesLayer,
86
100
SpeedyWeather. forcing! (diagn,forcing,model. spectral_transform)
87
101
end
88
102
103
+ """
104
+ $(TYPEDSIGNATURES)
105
+ Extends the forcing! function for StochasticStirring. Evolves the stochastic
106
+ coefficients S of the forcing following an AR1 process in time, transforms
107
+ to grid-point space to apply a mask to only force specified latitudes then
108
+ transforms back to force in spectral space where also the time stepping is
109
+ applied."""
89
110
function SpeedyWeather. forcing! (diagn:: DiagnosticVariablesLayer ,
90
111
forcing:: StochasticStirring{NF} ,
91
112
spectral_transform:: SpectralTransform ) where NF
@@ -108,16 +129,15 @@ function SpeedyWeather.forcing!(diagn::DiagnosticVariablesLayer,
108
129
end
109
130
110
131
# to grid-point space
111
- S_grid = diagn. dynamics_variables. a_grid
132
+ S_grid = diagn. dynamics_variables. a_grid # reuse general work array
112
133
SpeedyTransforms. gridded! (S_grid,S,spectral_transform)
113
134
114
135
# mask everything but mid-latitudes
115
136
RingGrids. _scale_lat! (S_grid,forcing. lat_mask)
116
137
117
- # back to spectral space
138
+ # back to spectral space, write directly into vorticity tendency
118
139
(;vor_tend) = diagn. tendencies
119
140
SpeedyTransforms. spectral! (vor_tend,S_grid,spectral_transform)
120
- SpeedyTransforms. spectral_truncation! (vor_tend) # set lmax+1 to zero
121
141
122
142
return nothing
123
143
end
0 commit comments