-
Notifications
You must be signed in to change notification settings - Fork 207
/
Copy pathhydrostatic_free_surface_ab2_step.jl
106 lines (80 loc) · 3.3 KB
/
hydrostatic_free_surface_ab2_step.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using Oceananigans.Fields: location
using Oceananigans.TimeSteppers: ab2_step_field!
using Oceananigans.TurbulenceClosures: implicit_step!
using Oceananigans.ImmersedBoundaries: retrieve_interior_active_cells_map, retrieve_surface_active_cells_map
import Oceananigans.TimeSteppers: ab2_step!
#####
##### Step everything
#####
setup_free_surface!(model, free_surface, χ) = nothing
function ab2_step!(model::HydrostaticFreeSurfaceModel, Δt)
χ = model.timestepper.χ
setup_free_surface!(model, model.free_surface, χ)
# Step locally velocity and tracers
@apply_regionally local_ab2_step!(model, Δt, χ)
# blocking step for implicit free surface, non blocking for explicit
ab2_step_free_surface!(model.free_surface, model, Δt, χ)
return nothing
end
function local_ab2_step!(model, Δt, χ)
ab2_step_velocities!(model.velocities, model, Δt, χ)
ab2_step_tracers!(model.tracers, model, Δt, χ)
return nothing
end
#####
##### Step velocities
#####
function ab2_step_velocities!(velocities, model, Δt, χ)
for (i, name) in enumerate((:u, :v))
Gⁿ = model.timestepper.Gⁿ[name]
G⁻ = model.timestepper.G⁻[name]
velocity_field = model.velocities[name]
launch!(model.architecture, model.grid, :xyz,
ab2_step_field!, velocity_field, Δt, χ, Gⁿ, G⁻)
# TODO: let next implicit solve depend on previous solve + explicit velocity step
# Need to distinguish between solver events and tendency calculation events.
# Note that BatchedTridiagonalSolver has a hard `wait`; this must be solved first.
implicit_step!(velocity_field,
model.timestepper.implicit_solver,
model.closure,
model.diffusivity_fields,
nothing,
model.clock,
Δt)
end
return nothing
end
#####
##### Step velocities
#####
const EmptyNamedTuple = NamedTuple{(),Tuple{}}
ab2_step_tracers!(::EmptyNamedTuple, model, Δt, χ) = nothing
function ab2_step_tracers!(tracers, model, Δt, χ)
closure = model.closure
# Tracer update kernels
for (tracer_index, tracer_name) in enumerate(propertynames(tracers))
# TODO: do better than this silly criteria, also need to check closure tuples
if closure isa FlavorOfCATKE && tracer_name == :e
@debug "Skipping AB2 step for e"
elseif closure isa FlavorOfTD && tracer_name == :ϵ
@debug "Skipping AB2 step for ϵ"
elseif closure isa FlavorOfTD && tracer_name == :e
@debug "Skipping AB2 step for e"
else
Gⁿ = model.timestepper.Gⁿ[tracer_name]
G⁻ = model.timestepper.G⁻[tracer_name]
tracer_field = tracers[tracer_name]
closure = model.closure
launch!(model.architecture, model.grid, :xyz,
ab2_step_field!, tracer_field, Δt, χ, Gⁿ, G⁻)
implicit_step!(tracer_field,
model.timestepper.implicit_solver,
closure,
model.diffusivity_fields,
Val(tracer_index),
model.clock,
Δt)
end
end
return nothing
end