@@ -81,23 +81,22 @@ function time_integration( Prog::PrognosticVars{Tprog},
81
81
82
82
for rki = 1 : RKs
83
83
if rki > 1
84
- # TODO technically the ghost point copy for u1,v1 is redundant as done further down
85
- ghost_points! (u1,v1,η1,S)
84
+ ghost_points_η! (η1,S)
86
85
end
87
86
88
87
# type conversion for mixed precision
89
88
u1rhs = convert (Diag. PrognosticVarsRHS. u,u1)
90
89
v1rhs = convert (Diag. PrognosticVarsRHS. v,v1)
91
90
η1rhs = convert (Diag. PrognosticVarsRHS. η,η1)
92
91
93
- rhs! (u1rhs,v1rhs,η1rhs,Diag,S,t)
92
+ rhs! (u1rhs,v1rhs,η1rhs,Diag,S,t) # momentum only
94
93
95
94
# the update step
96
95
axb! (u1,Δt_Δs,du) # u1 = u1 + Δt/(s-1)*RHS(u1)
97
96
axb! (v1,Δt_Δs,dv)
98
97
99
- # semi-implicit for continuity equation, use u1,v1 to calcualte dη
100
- ghost_points ! (u1,v1,S)
98
+ # semi-implicit for continuity equation, use new u1,v1 to calcualte dη
99
+ ghost_points_uv ! (u1,v1,S)
101
100
u1rhs = convert (Diag. PrognosticVarsRHS. u,u1)
102
101
v1rhs = convert (Diag. PrognosticVarsRHS. v,v1)
103
102
continuity! (u1rhs,v1rhs,η1rhs,Diag,S,t)
@@ -109,8 +108,54 @@ function time_integration( Prog::PrognosticVars{Tprog},
109
108
cxayb! (u0,a,u,b,u1)
110
109
cxayb! (v0,a,v,b,v1)
111
110
cxayb! (η0,a,η,b,η1)
111
+
112
+ elseif time_scheme == " SSPRK3" # s-stage 3rd order SSPRK
113
+
114
+ @unpack s,kn,mn,kna,knb,Δt_Δnc,Δt_Δn = S. constants. SSPRK3c
115
+
116
+ for rki = 1 : s # number of stages
117
+ if rki > 1
118
+ ghost_points_η! (η1,S)
119
+ end
120
+
121
+ # type conversion for mixed precision
122
+ u1rhs = convert (Diag. PrognosticVarsRHS. u,u1)
123
+ v1rhs = convert (Diag. PrognosticVarsRHS. v,v1)
124
+ η1rhs = convert (Diag. PrognosticVarsRHS. η,η1)
125
+
126
+ rhs! (u1rhs,v1rhs,η1rhs,Diag,S,t)
127
+
128
+ if rki == kn # special case combining more previous stages
129
+ dxaybzc! (u1,kna,u1,knb,u0,Δt_Δnc,du)
130
+ dxaybzc! (v1,kna,v1,knb,v0,Δt_Δnc,dv)
131
+ else # normal update case
132
+ axb! (u1,Δt_Δn,du)
133
+ axb! (v1,Δt_Δn,dv)
134
+ end
135
+
136
+ # semi-implicit for continuity equation, use new u1,v1 to calcualte dη
137
+ ghost_points_uv! (u1,v1,S)
138
+ u1rhs = convert (Diag. PrognosticVarsRHS. u,u1)
139
+ v1rhs = convert (Diag. PrognosticVarsRHS. v,v1)
140
+ continuity! (u1rhs,v1rhs,η1rhs,Diag,S,t)
141
+
142
+ if rki == kn
143
+ dxaybzc! (η1,kna,η1,knb,η0,Δt_Δnc,dη)
144
+ else
145
+ axb! (η1,Δt_Δn,dη)
146
+ end
147
+
148
+ # special stage that is needed later for the kn-th stage, store in u0,v0,η0 therefore
149
+ # or for the last step, as u0,v0,η0 is used as the last step's result of any RK scheme.
150
+ if rki == mn || rki == s
151
+ copyto! (u0,u1)
152
+ copyto! (v0,v1)
153
+ ghost_points_η! (η1,S)
154
+ copyto! (η0,η1)
155
+ end
156
+ end
112
157
113
- elseif time_scheme == " SSPRK3 " # 4-stage SSPRK3
158
+ elseif time_scheme == " 4SSPRK3 " # 4-stage SSPRK3
114
159
115
160
for rki = 1 : 4
116
161
if rki > 1
@@ -130,7 +175,7 @@ function time_integration( Prog::PrognosticVars{Tprog},
130
175
cxab! (v1,1 / 2 ,v1,v0) # same
131
176
132
177
# semi-implicit for continuity equation, use u1,v1 to calcualte dη
133
- ghost_points ! (u1,v1,S)
178
+ ghost_points_uv ! (u1,v1,S)
134
179
u1rhs = convert (Diag. PrognosticVarsRHS. u,u1)
135
180
v1rhs = convert (Diag. PrognosticVarsRHS. v,v1)
136
181
continuity! (u1rhs,v1rhs,η1rhs,Diag,S,t)
@@ -172,7 +217,7 @@ function time_integration( Prog::PrognosticVars{Tprog},
172
217
bottom_drag! (u0rhs,v0rhs,η0rhs,Diag,S)
173
218
diffusion! (u0rhs,v0rhs,Diag,S)
174
219
add_drag_diff_tendencies! (u0,v0,Diag,S)
175
- ghost_points ! (u0,v0,S)
220
+ ghost_points_uv ! (u0,v0,S)
176
221
end
177
222
178
223
t += dtint
@@ -244,7 +289,7 @@ function cxab!(c::Array{T,2},x::Real,a::Array{T,2},b::Array{T,2}) where {T<:Abst
244
289
end
245
290
end
246
291
247
- """ c equals add x multiplied to a plus b. c = x*(a+b) """
292
+ """ c = x*a + y*b """
248
293
function cxayb! (c:: Array{T,2} ,x:: Real ,a:: Array{T,2} ,y:: Real ,b:: Array{T,2} ) where {T<: AbstractFloat }
249
294
m,n = size (a)
250
295
@boundscheck (m,n) == size (b) || throw (BoundsError ())
@@ -259,6 +304,27 @@ function cxayb!(c::Array{T,2},x::Real,a::Array{T,2},y::Real,b::Array{T,2}) where
259
304
end
260
305
end
261
306
307
+ """ d = x*a + y*b + z*c"""
308
+ function dxaybzc! ( d:: Array{T,2} ,
309
+ x:: Real ,a:: Array{T,2} ,
310
+ y:: Real ,b:: Array{T,2} ,
311
+ z:: Real ,c:: Array{T,2} ) where {T<: AbstractFloat }
312
+ m,n = size (a)
313
+ @boundscheck (m,n) == size (b) || throw (BoundsError ())
314
+ @boundscheck (m,n) == size (c) || throw (BoundsError ())
315
+ @boundscheck (m,n) == size (d) || throw (BoundsError ())
316
+
317
+ xT = T (x) # convert to type T
318
+ yT = T (y)
319
+ zT = T (z)
320
+
321
+ @inbounds for j ∈ 1 : n
322
+ for i ∈ 1 : m
323
+ d[i,j] = xT* a[i,j] + yT* b[i,j] + zT* c[i,j]
324
+ end
325
+ end
326
+ end
327
+
262
328
""" Convert function for two arrays, X1, X2, in case their eltypes differ.
263
329
Convert every element from X1 and store it in X2."""
264
330
function Base. convert (X2:: Array{T2,N} ,X1:: Array{T1,N} ) where {T1,T2,N}
0 commit comments