chicken jockey. Kill me

pull/5/head
2211567 2025-06-15 17:46:35 +02:00
parent 0e408df833
commit 3aaef9fabe
6 changed files with 68 additions and 47 deletions

View File

@ -2,7 +2,7 @@
julia_version = "1.11.5"
manifest_format = "2.0"
project_hash = "5fd84347cd356de5b819aa3ea793fa63c45180e4"
project_hash = "b5f5f0b50b1e0b7dd05bb93e0b1bb03fea235d53"
[[deps.ADTypes]]
git-tree-sha1 = "e2478490447631aedba0823d4d7a80b2cc8cdb32"
@ -635,9 +635,9 @@ uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56"
version = "1.0.5"
[[deps.EnzymeCore]]
git-tree-sha1 = "7d7822a643c33bbff4eab9c87ca8459d7c688db0"
git-tree-sha1 = "8272a687bca7b5c601c0c24fc0c71bff10aafdfd"
uuid = "f151be2c-9106-41f4-ab19-57ee4f262869"
version = "0.8.11"
version = "0.8.12"
weakdeps = ["Adapt"]
[deps.EnzymeCore.extensions]
@ -1419,9 +1419,9 @@ version = "1.11.0"
[[deps.MathTeXEngine]]
deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"]
git-tree-sha1 = "31a99cb7537f812e1d6be893a71804c35979f1be"
git-tree-sha1 = "6e64d2321257cc52f47e193407d0659ea1b2b431"
uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53"
version = "0.6.4"
version = "0.6.5"
[[deps.MatrixFactorizations]]
deps = ["ArrayLayouts", "LinearAlgebra", "Printf", "Random"]
@ -2784,9 +2784,9 @@ version = "2.0.3+0"
[[deps.libpng_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"]
git-tree-sha1 = "002748401f7b520273e2b506f61cab95d4701ccf"
git-tree-sha1 = "cd155272a3738da6db765745b89e466fa64d0830"
uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f"
version = "1.6.48+0"
version = "1.6.49+0"
[[deps.libsixel_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "libpng_jll"]

View File

@ -9,6 +9,16 @@ using GLMakie
using .Constants
using .Visualization
# Rebuild when model or sliders change
function setup_param_binding!(model_type, gray_params, fhn_params, params_obs)
if model_type[] == :gray_scott
return gray_params
else
return fhn_params
end
end
model_type = Observable(:gray_scott) # or :fhn
# GSParams
@ -35,19 +45,9 @@ fhn_params = (
params_obs = Observable(Constants.GSParams(N, dx, gray_params.Du[], gray_params.Dv[], gray_params.F[], gray_params.k[]))
#params_obs = Observable(Constants.FHNParams(N=N, dx=dx, Du=Du[], Dv=Dv[], ϵ=ϵ[], a=a[], b=b[]))
# Rebuild when model or sliders change
function setup_param_binding!(model_type, gray_params, fhn_params, params_obs)
if model_type[] == :gray_scott
lift(gray_params.Du, gray_params.Dv, gray_params.F, gray_params.k) do Du, Dv, F, k
params_obs[] = GSParams(N, dx, Du, Dv, F, k)
end
else
lift(fhn_params.Du, fhn_params.Dv, fhn_params.ϵ, fhn_params.a, fhn_params.b) do Du, Dv, ϵ, a, b
params_obs[] = FHNParams(N, dx, Du, Dv, ϵ, a, b)
end
end
end
param_observables = setup_param_binding!(model_type, gray_params, fhn_params, params_obs)
"""
lift(Du, Dv, ϵ, a, b) do d_u, d_v, eps, aa, bb
params_obs[] = FHNParams(N=N, dx=dx, Du=d_u, Dv=d_v, ϵ=eps, a=aa, b=bb)
end

View File

@ -1,3 +1,5 @@
module FHNSolver
include("utils/laplacian.jl")
using DifferentialEquations
@ -83,8 +85,4 @@ function step_fhn!(U, V, params_obs::Observable; dx=1)
return U
end
function multi_step!(state, n_steps, heat_obs::Observable, params_obs::Observable; dx=1)
for _ in 1:n_steps
heat_obs[] = step_fhn!(state[1], state[2], params_obs; dx=1)
end
end
end # Module end

View File

@ -1,3 +1,5 @@
module GrayScottSolver
include("utils/constants.jl")
include("utils/laplacian.jl")
@ -42,8 +44,5 @@ function step_gray_scott!(U, V, params_obs::Observable; dx=1)
return U # for visualization
end
function multi_step!(state, n_steps, heat_obs::Observable, params_obs::Observable; dx=1)
for _ in 1:n_steps
heat_obs[] = step_gray_scott!(state[1], state[2], params_obs; dx=1)
end
end
end # Module end

View File

@ -10,11 +10,6 @@ struct FHNParams <: PDEParams
ϵ::Float64
a::Float64
b::Float64
# Inner constructor that takes keyword arguments
# The semicolon ';' separates positional arguments from keyword arguments
FHNParams(; N::Int, dx::Float64, Du::Float64, Dv::Float64, ϵ::Float64, a::Float64, b::Float64) =
new(N, dx, Du, Dv, ϵ, a, b)
end
struct GSParams <: PDEParams

View File

@ -1,8 +1,17 @@
module Visualization
include("../src/utils/constants.jl")
include("gray_scott_solver.jl")
#include("fhn_solver.jl")
include("fhn_solver.jl")
using GLMakie, Observables, Makie
using Observables, Makie, GLMakie
using .Constants
using .GrayScottSolver: step_gray_scott!
using .FHNSolver: step_fhn!
const STEP_FUNCTIONS = Dict(
:gray_scott => GrayScottSolver.step_gray_scott!,
:fhn => FHNSolver.step_fhn!
)
function coord_to_index(x, y, N)
ix = clamp(round(Int, x), 1, N)
@ -64,11 +73,21 @@ function rebuild_param_boxes!(grid, model_type, gray_params, fhn_params)
end
end
function step_model!(U, V, model_type, params_obs, heat_obs)
function setup_param_binding!(model_type, gray_params, fhn_params, params_obs)
if model_type[] == :gray_scott
heat_obs[] = step_gray_scott!(U, V, params_obs)
lift(gray_params.Du, gray_params.Dv, gray_params.F, gray_params.k) do Du, Dv, F, k
params_obs[] = Constants.GSParams(N, dx, Du, Dv, F, k)
end
else
heat_obs[] = step_fhn!(U, V, params_obs)
lift(fhn_params.Du, fhn_params.Dv, fhn_params.ϵ, fhn_params.a, fhn_params.b) do Du, Dv, ϵ, a, b
params_obs[] = Constants.FHNParams(N, dx, Du, Dv, ϵ, a, b)
end
end
end
function multi_step!(state, n_steps, heat_obs::Observable, params_obs::Observable; step_method=step_gray_scott!, dx=1)
for _ in 1:n_steps
heat_obs[] = step_method(state[1], state[2], params_obs; dx=1)
end
end
@ -85,9 +104,10 @@ function build_ui(U, V, param_obs_map::NamedTuple, params_obs, heat_obs)
run_label = Observable{String}("Run")
stepsize = Observable(30)
spoint = select_point(ax.scene)
step_method = Observable(step_gray_scott!)
# Controls
dropdown = Dropdown(fig[0, 1], options=["Gray-Scott" => :gray_scott, "FHN" => :fhn])
dropdown = Menu(fig, options = ["Gray-Scott" => :gray_scott, "FHN" => :fhn])
fig[2, 1] = buttongrid = GridLayout(ax.scene, tellwidth=false)
btn_step = Button(buttongrid[1, 1], width=50, label="Step")
btn_start = Button(buttongrid[1, 2], width=50, label=run_label)
@ -96,7 +116,6 @@ function build_ui(U, V, param_obs_map::NamedTuple, params_obs, heat_obs)
speed_slider = slidergrid.sliders[1].value
gh[1, 2] = textboxgrid = GridLayout(ax.scene, tellwidth=false)
rowsize!(gh, 1, Relative(1.0))
@ -129,7 +148,7 @@ function build_ui(U, V, param_obs_map::NamedTuple, params_obs, heat_obs)
end
# Button Listeners
on(btn_step.clicks) do _
multi_step!((U, V), stepsize[], heat_obs, params_obs)
multi_step!((U, V), stepsize[], heat_obs, params_obs; step_method=step_method[])
end
on(btn_start.clicks) do _
@ -138,7 +157,7 @@ function build_ui(U, V, param_obs_map::NamedTuple, params_obs, heat_obs)
on(btn_start.clicks) do _
@async while running[]
multi_step!((U, V), stepsize[], heat_obs, params_obs)
multi_step!((U, V), stepsize[], heat_obs, params_obs; step_method=step_method[])
sleep(0.0015) # ~20 FPS
end
end
@ -170,11 +189,21 @@ function build_ui(U, V, param_obs_map::NamedTuple, params_obs, heat_obs)
heat_obs[] = copy(U)
end
on(dropdown.selection) do sel
model_type[] = sel
setup_param_binding!(model_type, gray_params, fhn_params, params_obs)
rebuild_param_boxes!(param_grid, model_type, gray_params, fhn_params)
on(dropdown.selection) do sel_pair
selected_model = sel_pair[2] # get :gray_scott or :fhn from ("Gray-Scott" => :gray_scott)
# Safely assign correct function to step_method
if haskey(STEP_FUNCTIONS, selected_model)
step_method[] = STEP_FUNCTIONS[selected_model]
else
@warn "Unknown model selected: $selected_model"
end
# Update param bindings and input fields
setup_param_binding!(selected_model, gray_params, fhn_params, params_obs)
rebuild_param_boxes!(textboxgrid, selected_model, gray_params, fhn_params)
end
return fig
end