@@ -7,6 +7,8 @@ using LinearAlgebra
7
7
import ClimaComms
8
8
ClimaComms. @import_required_backends
9
9
using OrdinaryDiffEqSSPRK: ODEProblem, solve, SSPRK33
10
+ using ClimaCore. CommonGrids
11
+ using ClimaCore. Grids
10
12
using ClimaTimeSteppers
11
13
12
14
import ClimaCore:
@@ -28,15 +30,26 @@ import ClimaCore:
28
30
29
31
# visualization artifacts
30
32
ENV [" GKSwstype" ] = " nul"
31
- using ClimaCorePlots, Plots
33
+ import ClimaCorePlots
34
+ import Plots
32
35
Plots. GRBackend ()
33
36
dir = " vert_mass_borrow_advection"
34
37
path = joinpath (@__DIR__ , " output" , dir)
35
38
mkpath (path)
36
39
37
40
function lim! (y, parameters, t, y_ref)
38
41
(; w, Δt, limiter) = parameters
39
- Limiters. apply_limiter! (y. q, limiter)
42
+ Limiters. apply_limiter! (y. q, y. ρ, limiter)
43
+ return nothing
44
+ end
45
+
46
+ function perturb_field! (f:: Fields.Field ; perturb_radius)
47
+ device = ClimaComms. device (f)
48
+ ArrayType = ClimaComms. array_type (device)
49
+ rand_data = ArrayType (rand (size (parent (f))... )) # [0-1]
50
+ rand_data = rand_data .- sum (rand_data) / length (rand_data) # make centered about 0 ([-0.5:0.5])
51
+ rand_data = (rand_data ./ maximum (rand_data)) .* perturb_radius # rand_data now in [-perturb_radius:perturb_radius]
52
+ parent (f) .= parent (f) .+ rand_data # f in [f ± perturb_radius]
40
53
return nothing
41
54
end
42
55
@@ -57,10 +70,7 @@ function tendency!(yₜ, y, parameters, t)
57
70
top = Operators. ThirdOrderOneSided (),
58
71
)
59
72
If = Operators. InterpolateC2F ()
60
- @. yₜ. q =
61
- # -divf2c(w * If(y.q))
62
- - divf2c (upwind1 (w, y. q) * If (y. q))
63
- # -divf2c(upwind3(w, y.q) * If(y.q))
73
+ @. yₜ. q = - divf2c (upwind1 (w, y. q) * If (y. q))
64
74
return nothing
65
75
end
66
76
@@ -76,30 +86,51 @@ z₁ = FT(1.0)
76
86
speed = FT (- 1.0 )
77
87
pulse (z, t, z₀, zₕ, z₁) = abs (z - speed * t) ≤ zₕ ? z₁ : z₀
78
88
79
- n = 2 .^ 6
80
-
81
- domain = Domains. IntervalDomain (
82
- Geometry. ZPoint {FT} (- π),
83
- Geometry. ZPoint {FT} (π);
84
- boundary_names = (:bottom , :top ),
85
- )
86
-
87
- # stretch_fns = (Meshes.Uniform(), Meshes.ExponentialStretching(FT(7.0)))
88
- stretch_fns = (Meshes. Uniform (),)
89
+ stretch_fns = (Meshes. Uniform (), Meshes. ExponentialStretching (FT (7.0 )))
89
90
plot_string = [" uniform" , " stretched" ]
90
91
91
92
@testset " VerticalMassBorrowingLimiter on advection" begin
92
- for (i, stretch_fn) in enumerate (stretch_fns)
93
- mesh = Meshes. IntervalMesh (domain, stretch_fn; nelems = n)
94
- cent_space = Spaces. CenterFiniteDifferenceSpace (mesh)
95
- face_space = Spaces. FaceFiniteDifferenceSpace (cent_space)
96
- z = Fields. coordinate_field (cent_space). z
97
- O = ones (FT, face_space)
93
+ for (i, stretch) in enumerate (stretch_fns)
94
+ i = 1
95
+ stretch = Meshes. Uniform ()
96
+
97
+ z_elem = 2 ^ 6
98
+ z_min = - π
99
+ z_max = π
100
+ device = ClimaComms. device ()
101
+
102
+ # use_column = true
103
+ use_column = false
104
+ if use_column
105
+ grid = ColumnGrid (; z_elem, z_min, z_max, stretch, device)
106
+ cspace = Spaces. FiniteDifferenceSpace (grid, Grids. CellCenter ())
107
+ fspace = Spaces. FaceFiniteDifferenceSpace (cspace)
108
+ else
109
+ grid = ExtrudedCubedSphereGrid (;
110
+ z_elem,
111
+ z_min,
112
+ z_max,
113
+ stretch,
114
+ radius = 10 ,
115
+ h_elem = 10 ,
116
+ n_quad_points = 4 ,
117
+ device,
118
+ )
119
+ cspace =
120
+ Spaces. ExtrudedFiniteDifferenceSpace (grid, Grids. CellCenter ())
121
+ fspace = Spaces. FaceExtrudedFiniteDifferenceSpace (cspace)
122
+ end
123
+
124
+ z = Fields. coordinate_field (cspace). z
125
+ O = ones (FT, fspace)
98
126
99
127
# Initial condition
100
128
q_init = pulse .(z, 0.0 , z₀, zₕ, z₁)
101
129
q = q_init
102
- y = Fields. FieldVector (; q)
130
+ coords = Fields. coordinate_field (q)
131
+ ρ = map (coord -> 1.0 , coords)
132
+ perturb_field! (ρ; perturb_radius = 0.1 )
133
+ y = Fields. FieldVector (; q, ρ)
103
134
limiter = Limiters. VerticalMassBorrowingLimiter (q, (0.0 ,))
104
135
105
136
# Unitary, constant advective velocity
@@ -127,17 +158,48 @@ plot_string = ["uniform", "stretched"]
127
158
rel_mass_err = norm ((sum (q_final) - sum (q_init)) / sum (q_init))
128
159
129
160
130
- p = plot ()
131
- Plots. plot! (q_init, label = " init" )
132
- Plots. plot! (q_final, label = " computed" )
133
- Plots. plot! (q_analytic, label = " analytic" )
134
- Plots. plot! (; legend = :topright )
135
- Plots. plot! (; xlabel = " q" , title = " VerticalMassBorrowingLimiter" )
136
- f = joinpath (
137
- path,
138
- " VerticalMassBorrowingLimiter_comparison_$(plot_string[i]) .png" ,
139
- )
140
- Plots. png (p, f)
161
+ if use_column
162
+ p = Plots. plot ()
163
+ Plots. plot! (q_init, label = " init" )
164
+ Plots. plot! (q_final, label = " computed" )
165
+ Plots. plot! (q_analytic, label = " analytic" )
166
+ Plots. plot! (; legend = :topright )
167
+ Plots. plot! (; xlabel = " q" , title = " VerticalMassBorrowingLimiter" )
168
+ f = joinpath (
169
+ path,
170
+ " VerticalMassBorrowingLimiter_comparison_$(plot_string[i]) .png" ,
171
+ )
172
+ Plots. png (p, f)
173
+ else
174
+ colidx = Fields. ColumnIndex ((1 , 1 ), 1 )
175
+ p = Plots. plot ()
176
+ Plots. plot! (
177
+ vec (parent (z[colidx])),
178
+ vec (parent (q_init[colidx])),
179
+ label = " init" ,
180
+ )
181
+ Plots. plot! (
182
+ vec (parent (z[colidx])),
183
+ vec (parent (q_final[colidx])),
184
+ label = " computed" ,
185
+ )
186
+ Plots. plot! (
187
+ vec (parent (z[colidx])),
188
+ vec (parent (q_analytic[colidx])),
189
+ label = " analytic" ,
190
+ )
191
+ Plots. plot! (; legend = :topright )
192
+ Plots. plot! (;
193
+ xlabel = " q" ,
194
+ ylabel = " z" ,
195
+ title = " VerticalMassBorrowingLimiter" ,
196
+ )
197
+ f = joinpath (
198
+ path,
199
+ " VerticalMassBorrowingLimiter_comparison_$(plot_string[i]) .png" ,
200
+ )
201
+ Plots. png (p, f)
202
+ end
141
203
@test err ≤ 0.25
142
204
@test rel_mass_err ≤ 10 eps ()
143
205
@test minimum (q_final) ≥ 0
0 commit comments