File size: 4,125 Bytes
c711202 | 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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | """
Visualize solution evolution for a single problem instance.
Creates an animation showing how different methods evolve over time.
"""
using CairoMakie
using Printf
include("run.jl")
# Pick ONE problem instance
ν = 0.001 # Low viscosity (problematic case)
problem = BurgersProblem(x_min=0.0, x_max=1.0, T_end=0.3, ν=ν, u_left=0.0, u_right=0.0)
instances = generate_problem_instances(problem, [:sine], 1; base_seed=42, verbose=false)
instance = instances[1]
N = 100
n_timesteps = 50
println("Solving Burgers equation: ν=$ν, N=$N, n_t=$n_timesteps")
println("="^60)
# Solve with different methods
println("Classical FVM...")
result_classical = solve_classical_fvm(instance, N; n_timesteps=n_timesteps)
println("GP-FVM (s=2)...")
result_gpfvm = solve_sparse_fvm(instance, N; n_timesteps=n_timesteps, ρ=3.0, smoothness=2)
println("Reference solution...")
# Get reference at same time points
ref_xs = range(0.0, 1.0, length=200)
ref_ts = result_classical.ts
# Create animation
println("\nCreating animation...")
fig = Figure(size=(800, 500))
ax = Axis(fig[1, 1],
xlabel = "x",
ylabel = "u(x,t)",
title = "Burgers equation: ν=$ν"
)
# Set axis limits based on data
all_vals = vcat(result_classical.mean[:], result_gpfvm.mean[:])
ymin, ymax = minimum(all_vals) - 0.1, maximum(all_vals) + 0.1
ylims!(ax, ymin, ymax)
xlims!(ax, 0, 1)
# Animation
n_frames = length(result_classical.ts)
record(fig, "solution_evolution.mp4", 1:n_frames; framerate=5) do frame_idx
empty!(ax)
t = result_classical.ts[frame_idx]
# Reference solution
ref_u = evaluate_reference(instance.reference, collect(ref_xs), t)
lines!(ax, collect(ref_xs), ref_u, color=:black, linewidth=2, label="Reference")
# Classical FVM
lines!(ax, result_classical.xs, result_classical.mean[:, frame_idx],
color=:orange, linewidth=2, label="Classical FVM")
# GP-FVM
u_gp = result_gpfvm.mean[:, frame_idx]
σ_gp = result_gpfvm.std[:, frame_idx]
lines!(ax, result_gpfvm.xs, u_gp, color=:blue, linewidth=2, label="GP-FVM")
band!(ax, result_gpfvm.xs, u_gp .- 2*σ_gp, u_gp .+ 2*σ_gp,
color=(:blue, 0.2))
ax.title = @sprintf("Burgers equation: ν=%.3f, t=%.3f", ν, t)
axislegend(ax, position=:rt)
ylims!(ax, ymin, ymax)
xlims!(ax, 0, 1)
end
println("Saved: solution_evolution.mp4")
# Also save a few snapshots
println("\nSaving snapshots...")
snapshot_times = [1, n_frames÷4, n_frames÷2, 3*n_frames÷4, n_frames]
fig2 = Figure(size=(1000, 600))
for (i, frame_idx) in enumerate(snapshot_times)
row = (i-1) ÷ 3 + 1
col = (i-1) % 3 + 1
ax = Axis(fig2[row, col],
xlabel = "x",
ylabel = "u",
title = @sprintf("t = %.3f", result_classical.ts[frame_idx])
)
t = result_classical.ts[frame_idx]
# Reference
ref_u = evaluate_reference(instance.reference, collect(ref_xs), t)
lines!(ax, collect(ref_xs), ref_u, color=:black, linewidth=2, label="Reference")
# Classical FVM
lines!(ax, result_classical.xs, result_classical.mean[:, frame_idx],
color=:orange, linewidth=2, label="Classical")
# GP-FVM
u_gp = result_gpfvm.mean[:, frame_idx]
σ_gp = result_gpfvm.std[:, frame_idx]
lines!(ax, result_gpfvm.xs, u_gp, color=:blue, linewidth=2, label="GP-FVM")
band!(ax, result_gpfvm.xs, u_gp .- 2*σ_gp, u_gp .+ 2*σ_gp, color=(:blue, 0.2))
if i == 1
axislegend(ax, position=:rt)
end
end
save("solution_snapshots.pdf", fig2)
println("Saved: solution_snapshots.pdf")
# Print some diagnostics
println("\n" * "="^60)
println("Diagnostics")
println("="^60)
println("Classical FVM final L2 error: $(round(compute_metrics(result_classical, :sine, 42, instance.reference).mean_l2_error * 100, digits=1))%")
println("GP-FVM final L2 error: $(round(compute_metrics(result_gpfvm, :sine, 42, instance.reference).mean_l2_error * 100, digits=1))%")
println("\nGP-FVM posterior std at final time:")
println(" min: $(minimum(result_gpfvm.std[:, end]))")
println(" max: $(maximum(result_gpfvm.std[:, end]))")
println(" mean: $(mean(result_gpfvm.std[:, end]))")
|