Skip to content

Commit bc8e3c6

Browse files
committed
Fix precomputed quantities for Rosenbrock timestepper
1 parent 9ae6551 commit bc8e3c6

File tree

7 files changed

+198
-27
lines changed

7 files changed

+198
-27
lines changed

.buildkite/pipeline.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,28 @@ steps:
981981
agents:
982982
slurm_gpus: 1
983983

984+
- label: "GPU: Analytic Schar Mountain Test (2D, Float32)"
985+
command: >
986+
julia --color=yes --project=examples examples/hybrid/driver.jl
987+
--config_file $CONFIG_PATH/plane_analytic_schar_mountain_float32_test.yml
988+
--job_id gpu_plane_analytic_schar_mountain_float32_test
989+
artifact_paths: "gpu_plane_analytic_schar_mountain_float32_test/output_active/*"
990+
env:
991+
CLIMACOMMS_DEVICE: "CUDA"
992+
agents:
993+
slurm_gpus: 1
994+
995+
- label: "GPU: Analytic Teeny Teeny Teeny Tiny Schar Mountain Test (2D, Float32)"
996+
command: >
997+
julia --color=yes --project=examples examples/hybrid/driver.jl
998+
--config_file $CONFIG_PATH/plane_analytic_teeny_teeny_teeny_tiny_schar_mountain_float32_test.yml
999+
--job_id gpu_plane_analytic_teeny_teeny_teeny_tiny_schar_mountain_float32_test
1000+
artifact_paths: "gpu_plane_analytic_teeny_teeny_teeny_tiny_schar_mountain_float32_test/output_active/*"
1001+
env:
1002+
CLIMACOMMS_DEVICE: "CUDA"
1003+
agents:
1004+
slurm_gpus: 1
1005+
9841006
- label: "GPU: Analytic Schar Mountain Test (2D, Higher Horizontal Resolution)"
9851007
command: >
9861008
julia --color=yes --project=examples examples/hybrid/driver.jl
@@ -1003,6 +1025,17 @@ steps:
10031025
agents:
10041026
slurm_gpus: 1
10051027

1028+
- label: "GPU: Analytic Schar Mountain Test (2D, Stretched Grid)"
1029+
command: >
1030+
julia --color=yes --project=examples examples/hybrid/driver.jl
1031+
--config_file $CONFIG_PATH/plane_analytic_schar_mountain_stretched_grid_test.yml
1032+
--job_id gpu_plane_analytic_schar_mountain_stretched_grid_test
1033+
artifact_paths: "gpu_plane_analytic_schar_mountain_stretched_grid_test/output_active/*"
1034+
env:
1035+
CLIMACOMMS_DEVICE: "CUDA"
1036+
agents:
1037+
slurm_gpus: 1
1038+
10061039
- label: "GPU: Analytic Cosine Mountain Test (2D)"
10071040
command: >
10081041
julia --color=yes --project=examples examples/hybrid/driver.jl
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
config: "plane"
2+
FLOAT_TYPE: "Float32"
3+
initial_condition: "ConstantBuoyancyFrequencyProfile"
4+
topography: "Schar"
5+
x_max: 100e3
6+
z_max: 21e3
7+
x_elem: 100
8+
z_elem: 100
9+
z_stretch: false
10+
dt: "0.5secs"
11+
t_end: "24hours"
12+
rayleigh_sponge: true
13+
toml: [toml/analytic_mountain_test.toml]
14+
analytic_check: true
15+
output_default_diagnostics: false
16+
diagnostics:
17+
- short_name: [orog, ua, wa, uapredicted, wapredicted, uaerror, waerror, c1error, c3error]
18+
period: 1hours
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
config: "plane"
2+
FLOAT_TYPE: "Float64"
3+
initial_condition: "ConstantBuoyancyFrequencyProfile"
4+
topography: "Schar"
5+
x_max: 100e3
6+
z_max: 21e3
7+
x_elem: 100
8+
z_elem: 100
9+
dz_bottom: 50
10+
dz_top: 1000
11+
dt: "0.5secs"
12+
t_end: "24hours"
13+
rayleigh_sponge: true
14+
toml: [toml/analytic_mountain_test.toml]
15+
analytic_check: true
16+
output_default_diagnostics: false
17+
diagnostics:
18+
- short_name: [orog, ua, wa, uapredicted, wapredicted, uaerror, waerror, c1error, c3error]
19+
period: 1hours

examples/hybrid/driver.jl

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ClimaAtmos as CA
1010
import Random
1111
Random.seed!(1234)
1212

13+
include("fix_rosenbrock_precomputed_quantities.jl")
1314
include("fix_1d_spectral_space_on_gpu.jl")
1415
# include("disable_topography_dss.jl")
1516

@@ -122,25 +123,21 @@ if config.parsed_args["analytic_check"]
122123
@info "Comparing final state against predicted steady-state solution"
123124

124125
Y_end = integrator.sol.u[end]
125-
(; predicted_steady_state) = integrator.p
126+
(; predicted_steady_state, params) = integrator.p
126127
@assert !isnothing(predicted_steady_state)
127128

129+
FT = eltype(Y_end)
130+
(; zd_rayleigh) = params
131+
128132
ᶜuₕ_error_squared =
129133
norm_sqr.(Y_end.c.uₕ .- CA.C12.(predicted_steady_state.ᶜu))
130134
ᶠu₃_error_squared =
131135
norm_sqr.(Y_end.f.u₃ .- CA.C3.(predicted_steady_state.ᶠu))
132136

133-
ᶜsponge_mask = ifelse.(Fields.coordinate_field(Y_end.c).z .< 13e3, 1.0, 0.0)
134-
ᶠsponge_mask = ifelse.(Fields.coordinate_field(Y_end.f).z .< 13e3, 1.0, 0.0)
135-
ᶠsponge_and_surface_mask = copy(ᶠsponge_mask)
136-
Fields.level(ᶠsponge_and_surface_mask, Fields.half) .= 0.0
137-
137+
ᶜsponge_mask = FT.(Fields.coordinate_field(Y_end.c).z .< zd_rayleigh)
138+
ᶠsponge_mask = FT.(Fields.coordinate_field(Y_end.f).z .< zd_rayleigh)
138139
uₕ_rmse = sqrt(sum(ᶜuₕ_error_squared .* ᶜsponge_mask) / sum(ᶜsponge_mask))
139140
u₃_rmse = sqrt(sum(ᶠu₃_error_squared .* ᶠsponge_mask) / sum(ᶠsponge_mask))
140-
u₃_rmse_no_sfc = sqrt(
141-
sum(ᶠu₃_error_squared .* ᶠsponge_and_surface_mask) /
142-
sum(ᶠsponge_and_surface_mask),
143-
)
144141

145142
uₕ_rmse_by_level = map(1:5) do level
146143
sqrt(mean(Fields.level(ᶜuₕ_error_squared, level)))
@@ -151,7 +148,6 @@ if config.parsed_args["analytic_check"]
151148

152149
@info " RMSE of uₕ below sponge layer: $uₕ_rmse"
153150
@info " RMSE of u₃ below sponge layer: $u₃_rmse"
154-
@info " RMSE of u₃ below sponge layer and above surface: $u₃_rmse_no_sfc"
155151
@info " RMSE of uₕ on first 5 levels: $uₕ_rmse_by_level"
156152
@info " RMSE of u₃ on first 5 levels: $u₃_rmse_by_level"
157153
end
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import ClimaTimeSteppers as CTS
2+
import LinearAlgebra: ldiv!
3+
4+
function CTS.step_u!(int, cache::CTS.RosenbrockCache{Nstages}) where {Nstages}
5+
(; m, Γ, A, α, C) = int.alg.tableau
6+
(; u, p, t, dt) = int
7+
(; W, U, fU, fU_imp, fU_exp, fU_lim, k, ∂Y∂t) = cache
8+
T_imp! = int.sol.prob.f.T_imp!
9+
T_exp! = int.sol.prob.f.T_exp!
10+
T_exp_lim! = int.sol.prob.f.T_exp_T_lim!
11+
tgrad! = isnothing(T_imp!) ? nothing : T_imp!.tgrad
12+
13+
(; post_explicit!, post_implicit!, dss!) = int.sol.prob.f
14+
15+
# TODO: This is only valid when Γ[i, i] is constant, otherwise we have to
16+
# move this in the for loop
17+
dtγ = dt * Γ[1, 1]
18+
19+
if !isnothing(T_imp!)
20+
Wfact! = int.sol.prob.f.T_imp!.Wfact
21+
Wfact!(W, u, p, dtγ, t)
22+
end
23+
24+
if !isnothing(tgrad!)
25+
tgrad!(∂Y∂t, u, p, t)
26+
end
27+
28+
for i in 1:Nstages
29+
# Reset tendency
30+
fill!(fU, 0)
31+
32+
αi = sum(α[i, 1:(i - 1)])
33+
γi = sum(Γ[i, 1:i])
34+
35+
U .= u
36+
for j in 1:(i - 1)
37+
U .+= A[i, j] .* k[j]
38+
end
39+
40+
if !isnothing(post_implicit!) && i != 1
41+
# NOTE: post_implicit! is a misnomer
42+
post_implicit!(U, p, t + αi * dt)
43+
end
44+
45+
if !isnothing(T_imp!)
46+
T_imp!(fU_imp, U, p, t + αi * dt)
47+
fU .+= fU_imp
48+
end
49+
50+
if !isnothing(T_exp!)
51+
T_exp!(fU_exp, U, p, t + αi * dt)
52+
fU .+= fU_exp
53+
end
54+
55+
if !isnothing(T_exp_lim!)
56+
T_exp_lim!(fU_exp, fU_lim, U, p, t + αi * dt)
57+
fU .+= fU_exp
58+
fU .+= fU_lim
59+
end
60+
61+
if !isnothing(tgrad!)
62+
fU .+= γi .* dt .* ∂Y∂t
63+
end
64+
65+
# We dss the tendency at every stage but the last. At the last stage, we
66+
# dss the incremented state
67+
(i != Nstages) && dss!(fU, p, t + αi * dt)
68+
69+
for j in 1:(i - 1)
70+
fU .+= (C[i, j] / dt) .* k[j]
71+
end
72+
73+
fU .*= -dtγ
74+
75+
if !isnothing(T_imp!)
76+
if W isa Matrix
77+
ldiv!(k[i], lu(W), fU)
78+
else
79+
ldiv!(k[i], W, fU)
80+
end
81+
else
82+
k[i] .= .-fU
83+
end
84+
end
85+
86+
for i in 1:Nstages
87+
u .+= m[i] .* k[i]
88+
end
89+
90+
dss!(u, p, t + dt)
91+
post_explicit!(u, p, t + dt)
92+
return nothing
93+
end

post_processing/ci_plots.jl

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ function plot_contours!(place, var)
348348

349349
n_levels = 21
350350
var_mean = round(mean(var.data))
351-
var_delta = minimum(abs, extrema(value -> value - var_mean, var.data))
351+
var_delta = maximum(abs, extrema(value -> value - var_mean, var.data))
352352
levels = range(var_mean - var_delta, var_mean + var_delta, n_levels + 1)
353353
spectral_colors = Makie.to_colormap(:Spectral)
354354
plot_kwargs = (;
@@ -367,7 +367,13 @@ function plot_contours!(place, var)
367367
# end # TODO: This is taking too long to render.
368368
plot = CairoMakie.contourf!(dim1, dim2, var.data; plot_kwargs...)
369369

370-
CairoMakie.Colorbar(place[1, 2], plot, label = "$var_name [$var_units]")
370+
try
371+
CairoMakie.Colorbar(place[1, 2], plot, label = "$var_name [$var_units]")
372+
catch _
373+
@show mean(var.data)
374+
@show var_mean
375+
@show var_delta
376+
end
371377
end
372378

373379
"""
@@ -713,8 +719,10 @@ const AnalyticMountainTest = Union{
713719
Val{:gpu_plane_analytic_teeny_tiny_schar_mountain_test},
714720
Val{:gpu_plane_analytic_teeny_teeny_tiny_schar_mountain_test},
715721
Val{:gpu_plane_analytic_teeny_teeny_teeny_tiny_schar_mountain_test},
722+
Val{:gpu_plane_analytic_schar_mountain_float32_test},
716723
Val{:gpu_plane_analytic_schar_mountain_high_horz_res_test},
717724
Val{:gpu_plane_analytic_schar_mountain_high_vert_res_test},
725+
Val{:gpu_plane_analytic_schar_mountain_stretched_grid_test},
718726
Val{:gpu_plane_analytic_cosine_mountain_test},
719727
Val{:gpu_extruded_plane_analytic_cosine_mountain_test},
720728
Val{:gpu_box_analytic_cosine_mountain_test},
@@ -738,17 +746,14 @@ function make_plots(
738746
Val(:gpu_plane_analytic_teeny_tiny_schar_mountain_test),
739747
Val(:gpu_plane_analytic_teeny_teeny_tiny_schar_mountain_test),
740748
Val(:gpu_plane_analytic_teeny_teeny_teeny_tiny_schar_mountain_test),
749+
Val(:gpu_plane_analytic_schar_mountain_float32_test),
741750
Val(:gpu_plane_analytic_schar_mountain_high_horz_res_test),
742751
Val(:gpu_plane_analytic_schar_mountain_high_vert_res_test),
752+
Val(:gpu_plane_analytic_schar_mountain_stretched_grid_test),
743753
)
744754

745-
error_short_names = ["uaerror", "waerror", "c1error", "c3error"]
746-
summary_short_names =
747-
["ua", "wa", "uapredicted", "wapredicted", error_short_names...]
748-
closeup_summary_short_names = ["wa", "wapredicted", "waerror", "c3error"]
749-
750755
rms_error_vars = Iterators.flatmap((level_rms, column_rms)) do rms_func
751-
Iterators.flatmap(error_short_names) do short_name
756+
Iterators.flatmap(["uaerror", "waerror"]) do short_name
752757
map(simdirs) do simdir
753758
data = get(simdir; short_name)
754759
data = window(data, "z_reference"; left = 0, right = 13e3)
@@ -764,7 +769,17 @@ function make_plots(
764769
output_name = "rms_errors_24h",
765770
)
766771

767-
slice_summary_vars = Iterators.flatmap(summary_short_names) do short_name
772+
all_short_names = [
773+
"ua",
774+
"wa",
775+
"uapredicted",
776+
"wapredicted",
777+
"uaerror",
778+
"waerror",
779+
"c1error",
780+
"c3error",
781+
]
782+
slice_summary_vars = Iterators.flatmap(all_short_names) do short_name
768783
hours_to_plot = short_name in ("ua", "wa") ? (1, 2, 5, 24) : (24,)
769784
Iterators.flatmap(hours_to_plot) do n_hours
770785
map(simdirs) do simdir
@@ -783,8 +798,9 @@ function make_plots(
783798
)
784799

785800
if is_schar_mountain
801+
closeup_short_names = ["wa", "wapredicted", "waerror", "c3error"]
786802
closeup_slice_summary_vars =
787-
Iterators.flatmap(closeup_summary_short_names) do short_name
803+
Iterators.flatmap(closeup_short_names) do short_name
788804
map(simdirs) do simdir
789805
data = get(simdir; short_name)
790806
data = window(data, "x"; left = 40e3, right = 60e3)

src/diagnostics/core_diagnostics.jl

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -881,16 +881,12 @@ add_diagnostic_variable!(
881881
comments = "Error of third covariant wind component against predicted value",
882882
compute! = (out, state, cache, time) -> begin
883883
if isnothing(out)
884-
out =
885-
state.f.u₃.components.data.:1 .-
886-
C3.(cache.predicted_steady_state.ᶠu).components.data.:1
884+
state.f.u₃.components.data.:1 .-
885+
C3.(cache.predicted_steady_state.ᶠu).components.data.:1
887886
else
888887
out .=
889888
state.f.u₃.components.data.:1 .-
890889
C3.(cache.predicted_steady_state.ᶠu).components.data.:1
891890
end
892-
# TODO: The surface level is currently off by an absurd amount.
893-
Fields.level(out, Fields.half) .= 0
894-
out
895891
end,
896892
)

0 commit comments

Comments
 (0)