Skip to content

Commit 2a99564

Browse files
authored
Merge pull request #10 from JuliaGeodynamics/upwind_debug
add simple upwind mode
2 parents 835f3d5 + 018f5fd commit 2a99564

19 files changed

+662
-155
lines changed

examples/1D/1D_linear_KA.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ using KernelAbstractions
44

55
function main(backend = CPU(), nx = 400)
66

7-
backend = CPU()
8-
nx = 400
97

108
x_min = -1.0
119
x_max = 1.0

examples/2D/2D_linear_KA.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ using GLMakie
44

55
function main(; backend = CPU(), nx = 400, ny = 400, stag = true)
66

7-
nx = 400
8-
ny = 400
9-
stag = true
107

118
Lx = 1.0
129
Δx = Lx / nx
@@ -43,7 +40,7 @@ function main(; backend = CPU(), nx = 400, ny = 400, stag = true)
4340
u = KernelAbstractions.zeros(backend, Float64, nx, ny)
4441
copyto!(u, u0)
4542

46-
weno = WENOScheme(u, backend; boundary = (2, 2, 2, 2), stag = stag, multithreading = true)
43+
weno = WENOScheme(u, backend; boundary = (2, 2, 2, 2), stag = stag)
4744

4845
if stag
4946
v = (;
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using FiniteDiffWENO5
2+
using GLMakie
3+
4+
function main(; nx = 400, ny = 400)
5+
6+
Lx = 1.0
7+
Δx = Lx / nx
8+
Δy = Lx / ny
9+
10+
x = range(0, stop = Lx, length = nx)
11+
12+
# Courant number
13+
CFL = 0.7
14+
period = 1
15+
16+
# Grid x assumed defined
17+
x = range(0, length = nx, stop = Lx)
18+
y = range(0, length = ny, stop = Lx)
19+
grid = (x .* ones(ny)', ones(nx) .* y')
20+
21+
# Staggered grids:
22+
# vx at x-faces → (nx+1, ny)
23+
x_vx = range(0, stop = Lx, length = nx + 1)
24+
y_vx = range(Δy / 2, stop = Lx - Δy / 2, length = ny)
25+
26+
# vy at y-faces → (nx, ny+1)
27+
x_vy = range(Δx / 2, stop = Lx - Δx / 2, length = nx)
28+
y_vy = range(0, stop = Lx, length = ny + 1)
29+
30+
# Make 2D coordinate arrays with correct orientation
31+
X_vx = repeat(x_vx, 1, ny) # (nx+1, ny)
32+
Y_vx = repeat(y_vx', nx + 1, 1) # (nx+1, ny)
33+
34+
X_vy = repeat(x_vy, 1, ny + 1) # (nx, ny+1)
35+
Y_vy = repeat(y_vy', nx, 1) # (nx, ny+1)
36+
37+
# Define velocity field (example: divergence-free vortex)
38+
vx0 = .-2π .* sin.(π .* X_vx) .* cos.(π .* Y_vx) # (nx+1, ny)
39+
vy0 = 2π .* cos.(π .* X_vy) .* sin.(π .* Y_vy) # (nx, ny+1)
40+
41+
v = (; x = vx0, y = vy0)
42+
43+
x0 = 1 / 4
44+
c = 0.08
45+
46+
u0 = zeros(ny, nx)
47+
48+
for I in CartesianIndices((ny, nx))
49+
u0[I] = sign(exp(-((grid[1][I] - x0)^2 + (grid[2][I]' - x0)^2) / c^2) - 0.5) * 0.5 + 0.5
50+
end
51+
52+
u = copy(u0)
53+
weno = WENOScheme(u; boundary = (2, 2, 2, 2), stag = true, lim_ZS = true, multithreading = true)
54+
55+
56+
# grid size
57+
Δt = CFL * min(Δx, Δy)^(5 / 3)
58+
59+
tmax = 1
60+
t = 0
61+
counter = 0
62+
63+
f = Figure(size = (800, 600))
64+
ax = Axis(f[1, 1], title = "t = $(round(t, digits = 2))")
65+
u_obser = Observable(u0)
66+
hm = heatmap!(ax, x, y, u_obser; colormap = cgrad(:roma, rev = true), colorrange = (0, 1))
67+
Colorbar(f[1, 2], label = "u", hm)
68+
display(f)
69+
counter_half = 0
70+
71+
while t < tmax
72+
WENO_step!(u, v, weno, Δt, Δx, Δy; u_min = 0.0, u_max = 1.0)
73+
74+
75+
if t > tmax / 2 && counter_half == 0
76+
println("reversing velocity field...")
77+
vx0 .= .- vx0
78+
vy0 .= .- vy0
79+
counter_half += 1
80+
end
81+
82+
t += Δt
83+
84+
if t + Δt > tmax
85+
Δt = tmax - t
86+
end
87+
88+
if counter % 100 == 0
89+
u_obser[] = u
90+
ax.title = "t = $(round(t, digits = 2))"
91+
end
92+
93+
counter += 1
94+
95+
96+
end
97+
98+
return
99+
end
100+
101+
main(nx = 400, ny = 400)

examples/2D/2D_linear_rotation_KA.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function main(; backend = CPU(), nx = 400, ny = 400)
3333
u = KernelAbstractions.zeros(backend, Float64, nx, ny)
3434
copyto!(u, u0)
3535

36-
weno = WENOScheme(u, backend; boundary = (2, 2, 2, 2), stag = false, multithreading = true)
36+
weno = WENOScheme(u, backend; boundary = (2, 2, 2, 2), stag = false)
3737

3838

3939
v = (;

examples/3D/3D_linear_chmy.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function main(; backend = CPU(), nx = 50, ny = 50, nz = 50)
5454

5555
u = Field(backend, grid, Center())
5656
set!(u, u0)
57-
weno = WENOScheme(u, grid; boundary = (2, 2, 2, 2, 2, 2), stag = false, multithreading = true)
57+
weno = WENOScheme(u, grid; boundary = (2, 2, 2, 2, 2, 2), stag = false)
5858

5959
Δt = CFL * min(Δx, Δy, Δz)^(5 / 3)
6060
tmax = period * Lx / max(maximum(abs.(vx0)), maximum(abs.(vy0)), maximum(abs.(vz0)))
@@ -82,6 +82,7 @@ function main(; backend = CPU(), nx = 50, ny = 50, nz = 50)
8282
KernelAbstractions.synchronize(backend)
8383
u_obser[] = (interior(u) |> Array)[:, :, div(nz, 2)]
8484
ax.title = "t = $(round(t, digits = 2))"
85+
display(f)
8586
end
8687
end
8788

ext/ChmyExt.jl

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Create a WENO scheme structure for the given field `u` on the specified `grid` u
2222
- `boundary::NTuple{2N, Int}`: Tuple specifying the boundary conditions for each dimension (0: homogeneous Neumann, 1: homogeneous Dirichlet, 2: periodic). Default is periodic (2).
2323
- `stag::Bool`: Whether the grid is staggered (velocities on cell faces) or not (velocities on cell centers).
2424
"""
25-
function WENOScheme(c0::AbstractField{T, N}, grid::StructuredGrid; boundary::NTuple = (2, 2), stag::Bool = true, lim_ZS::Bool = false, kwargs...) where {T, N}
25+
function WENOScheme(c0::AbstractField{T, N}, grid::StructuredGrid; boundary::NTuple = (2, 2), stag::Bool = true, lim_ZS::Bool = false, upwind_mode = false) where {T, N}
2626

2727
# check that boundary conditions are correctly defined
2828
@assert length(boundary) == 2N "Boundary conditions must be a tuple of length $(2N) for $(N)D data."
@@ -44,7 +44,7 @@ function WENOScheme(c0::AbstractField{T, N}, grid::StructuredGrid; boundary::NTu
4444
TFlux = typeof(fl)
4545
TArray = typeof(du)
4646

47-
return WENOScheme{T, TArray, TFlux, N_boundary}(stag = stag, boundary = boundary, multithreading = multithreading, lim_ZS = lim_ZS, fl = fl, fr = fr, du = du, ut = ut)
47+
return WENOScheme{T, TArray, TFlux, N_boundary}(stag = stag, boundary = boundary, multithreading = multithreading, lim_ZS = lim_ZS, fl = fl, fr = fr, du = du, ut = ut, upwind_mode = upwind_mode)
4848
end
4949

5050
function WENOScheme(c0::AbstractField; kwargs...)
@@ -103,22 +103,27 @@ function WENO_step!(u::T_field, v::NamedTuple{(:x,), <:Tuple{<:AbstractField{<:R
103103
nx = grid.axes[1].length
104104
Δx_ = inv(Δx)
105105

106-
@unpack ut, du, fl, fr, stag, lim_ZS, boundary, χ, γ, ζ, ϵ = weno
106+
@unpack ut, du, fl, fr, stag, lim_ZS, boundary, χ, γ, ζ, ϵ, upwind_mode = weno
107107

108-
launch(arch, grid, WENO_flux_KA_1D => (fl.x, fr.x, u, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
109-
launch(arch, grid, WENO_semi_discretisation_weno5_KA_1D! => (du, fl, fr, v, stag, Δx_, grid))
108+
if !upwind_mode
110109

111-
interior(ut) .= @muladd interior(u) .- Δt .* interior(du)
110+
launch(arch, grid, WENO_flux_KA_1D => (fl.x, fr.x, u, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
111+
launch(arch, grid, WENO_semi_discretisation_weno5_KA_1D! => (du, fl, fr, v, stag, Δx_, grid))
112112

113-
launch(arch, grid, WENO_flux_KA_1D => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
114-
launch(arch, grid, WENO_semi_discretisation_weno5_KA_1D! => (du, fl, fr, v, stag, Δx_, grid))
113+
interior(ut) .= @muladd interior(u) .- Δt .* interior(du)
115114

116-
interior(ut) .= @muladd 0.75 .* interior(u) .+ 0.25 .* interior(ut) .- 0.25 .* Δt .* interior(du)
115+
launch(arch, grid, WENO_flux_KA_1D => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
116+
launch(arch, grid, WENO_semi_discretisation_weno5_KA_1D! => (du, fl, fr, v, stag, Δx_, grid))
117117

118-
launch(arch, grid, WENO_flux_KA_1D => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
119-
launch(arch, grid, WENO_semi_discretisation_weno5_KA_1D! => (du, fl, fr, v, stag, Δx_, grid))
118+
interior(ut) .= @muladd 0.75 .* interior(u) .+ 0.25 .* interior(ut) .- 0.25 .* Δt .* interior(du)
120119

121-
interior(u) .= @muladd inv(3.0) .* interior(u) .+ 2.0 / 3.0 .* interior(ut) .- 2.0 / 3.0 .* Δt .* interior(du)
120+
launch(arch, grid, WENO_flux_KA_1D => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
121+
launch(arch, grid, WENO_semi_discretisation_weno5_KA_1D! => (du, fl, fr, v, stag, Δx_, grid))
122+
123+
interior(u) .= @muladd inv(3.0) .* interior(u) .+ 2.0 / 3.0 .* interior(ut) .- 2.0 / 3.0 .* Δt .* interior(du)
124+
else
125+
launch(arch, grid, upwind_update_KA_1D! => (u, v, nx, Δx_, Δt, stag, boundary, grid))
126+
end
122127

123128
return nothing
124129
end
@@ -159,25 +164,29 @@ function WENO_step!(u::T_field, v::NamedTuple{(:x, :y), <:Tuple{Vararg{AbstractF
159164
Δx_ = inv(Δx)
160165
Δy_ = inv(Δy)
161166

162-
@unpack ut, du, fl, fr, stag, lim_ZS, boundary, χ, γ, ζ, ϵ = weno
167+
@unpack ut, du, fl, fr, stag, lim_ZS, boundary, χ, γ, ζ, ϵ, upwind_mode = weno
163168

164-
launch(arch, grid, WENO_flux_KA_2D_x => (fl.x, fr.x, u, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
165-
launch(arch, grid, WENO_flux_KA_2D_y => (fl.y, fr.y, u, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
166-
launch(arch, grid, WENO_semi_discretisation_weno5_KA_2D! => (du, fl, fr, v, stag, Δx_, Δy_, grid))
169+
if !upwind_mode
170+
launch(arch, grid, WENO_flux_KA_2D_x => (fl.x, fr.x, u, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
171+
launch(arch, grid, WENO_flux_KA_2D_y => (fl.y, fr.y, u, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
172+
launch(arch, grid, WENO_semi_discretisation_weno5_KA_2D! => (du, fl, fr, v, stag, Δx_, Δy_, grid))
167173

168-
interior(ut) .= @muladd interior(u) .- Δt .* interior(du)
174+
interior(ut) .= @muladd interior(u) .- Δt .* interior(du)
169175

170-
launch(arch, grid, WENO_flux_KA_2D_x => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
171-
launch(arch, grid, WENO_flux_KA_2D_y => (fl.y, fr.y, ut, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
172-
launch(arch, grid, WENO_semi_discretisation_weno5_KA_2D! => (du, fl, fr, v, stag, Δx_, Δy_, grid))
176+
launch(arch, grid, WENO_flux_KA_2D_x => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
177+
launch(arch, grid, WENO_flux_KA_2D_y => (fl.y, fr.y, ut, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
178+
launch(arch, grid, WENO_semi_discretisation_weno5_KA_2D! => (du, fl, fr, v, stag, Δx_, Δy_, grid))
173179

174-
interior(ut) .= @muladd 0.75 .* interior(u) .+ 0.25 .* interior(ut) .- 0.25 .* Δt .* interior(du)
180+
interior(ut) .= @muladd 0.75 .* interior(u) .+ 0.25 .* interior(ut) .- 0.25 .* Δt .* interior(du)
175181

176-
launch(arch, grid, WENO_flux_KA_2D_x => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
177-
launch(arch, grid, WENO_flux_KA_2D_y => (fl.y, fr.y, ut, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
178-
launch(arch, grid, WENO_semi_discretisation_weno5_KA_2D! => (du, fl, fr, v, stag, Δx_, Δy_, grid))
182+
launch(arch, grid, WENO_flux_KA_2D_x => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
183+
launch(arch, grid, WENO_flux_KA_2D_y => (fl.y, fr.y, ut, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
184+
launch(arch, grid, WENO_semi_discretisation_weno5_KA_2D! => (du, fl, fr, v, stag, Δx_, Δy_, grid))
179185

180-
interior(u) .= @muladd inv(3.0) .* interior(u) .+ 2.0 / 3.0 .* interior(ut) .- 2.0 / 3.0 .* Δt .* interior(du)
186+
interior(u) .= @muladd inv(3.0) .* interior(u) .+ 2.0 / 3.0 .* interior(ut) .- 2.0 / 3.0 .* Δt .* interior(du)
187+
else
188+
launch(arch, grid, upwind_update_KA_2D! => (u, v, nx, ny, Δx_, Δy_, Δt, stag, boundary, grid))
189+
end
181190

182191
return nothing
183192
end
@@ -223,28 +232,32 @@ function WENO_step!(u::T_field, v::NamedTuple{(:x, :y, :z), <:Tuple{Vararg{Abstr
223232
Δy_ = inv(Δy)
224233
Δz_ = inv(Δz)
225234

226-
@unpack ut, du, fl, fr, stag, lim_ZS, boundary, χ, γ, ζ, ϵ = weno
235+
@unpack ut, du, fl, fr, stag, lim_ZS, boundary, χ, γ, ζ, ϵ, upwind_mode = weno
227236

228-
launch(arch, grid, WENO_flux_KA_3D_x => (fl.x, fr.x, u, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
229-
launch(arch, grid, WENO_flux_KA_3D_y => (fl.y, fr.y, u, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
230-
launch(arch, grid, WENO_flux_KA_3D_z => (fl.z, fr.z, u, boundary, nz, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
231-
launch(arch, grid, WENO_semi_discretisation_weno5_KA_3D! => (du, fl, fr, v, stag, Δx_, Δy_, Δz_, grid))
237+
if !upwind_mode
238+
launch(arch, grid, WENO_flux_KA_3D_x => (fl.x, fr.x, u, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
239+
launch(arch, grid, WENO_flux_KA_3D_y => (fl.y, fr.y, u, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
240+
launch(arch, grid, WENO_flux_KA_3D_z => (fl.z, fr.z, u, boundary, nz, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
241+
launch(arch, grid, WENO_semi_discretisation_weno5_KA_3D! => (du, fl, fr, v, stag, Δx_, Δy_, Δz_, grid))
232242

233-
interior(ut) .= @muladd interior(u) .- Δt .* interior(du)
243+
interior(ut) .= @muladd interior(u) .- Δt .* interior(du)
234244

235-
launch(arch, grid, WENO_flux_KA_3D_x => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
236-
launch(arch, grid, WENO_flux_KA_3D_y => (fl.y, fr.y, ut, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
237-
launch(arch, grid, WENO_flux_KA_3D_z => (fl.z, fr.z, ut, boundary, nz, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
238-
launch(arch, grid, WENO_semi_discretisation_weno5_KA_3D! => (du, fl, fr, v, stag, Δx_, Δy_, Δz_, grid))
245+
launch(arch, grid, WENO_flux_KA_3D_x => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
246+
launch(arch, grid, WENO_flux_KA_3D_y => (fl.y, fr.y, ut, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
247+
launch(arch, grid, WENO_flux_KA_3D_z => (fl.z, fr.z, ut, boundary, nz, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
248+
launch(arch, grid, WENO_semi_discretisation_weno5_KA_3D! => (du, fl, fr, v, stag, Δx_, Δy_, Δz_, grid))
239249

240-
interior(ut) .= @muladd 0.75 .* interior(u) .+ 0.25 .* interior(ut) .- 0.25 .* Δt .* interior(du)
250+
interior(ut) .= @muladd 0.75 .* interior(u) .+ 0.25 .* interior(ut) .- 0.25 .* Δt .* interior(du)
241251

242-
launch(arch, grid, WENO_flux_KA_3D_x => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
243-
launch(arch, grid, WENO_flux_KA_3D_y => (fl.y, fr.y, ut, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
244-
launch(arch, grid, WENO_flux_KA_3D_z => (fl.z, fr.z, ut, boundary, nz, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
245-
launch(arch, grid, WENO_semi_discretisation_weno5_KA_3D! => (du, fl, fr, v, stag, Δx_, Δy_, Δz_, grid))
252+
launch(arch, grid, WENO_flux_KA_3D_x => (fl.x, fr.x, ut, boundary, nx, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
253+
launch(arch, grid, WENO_flux_KA_3D_y => (fl.y, fr.y, ut, boundary, ny, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
254+
launch(arch, grid, WENO_flux_KA_3D_z => (fl.z, fr.z, ut, boundary, nz, χ, γ, ζ, ϵ, lim_ZS, u_min, u_max, grid))
255+
launch(arch, grid, WENO_semi_discretisation_weno5_KA_3D! => (du, fl, fr, v, stag, Δx_, Δy_, Δz_, grid))
246256

247-
interior(u) .= @muladd inv(3.0) .* interior(u) .+ 2.0 / 3.0 .* interior(ut) .- 2.0 / 3.0 .* Δt .* interior(du)
257+
interior(u) .= @muladd inv(3.0) .* interior(u) .+ 2.0 / 3.0 .* interior(ut) .- 2.0 / 3.0 .* Δt .* interior(du)
258+
else
259+
launch(arch, grid, upwind_update_KA_3D! => (u, v, nx, ny, nz, Δx_, Δy_, Δz_, Δt, stag, boundary, grid))
260+
end
248261

249262
return nothing
250263
end

0 commit comments

Comments
 (0)