From 3aaef9fabe3bdeb8d236083385bff61ca47adc91 Mon Sep 17 00:00:00 2001 From: 2211567 Date: Sun, 15 Jun 2025 17:46:35 +0200 Subject: [PATCH] chicken jockey. Kill me --- Manifest.toml | 14 +++++----- scripts/main.jl | 24 +++++++++--------- src/fhn_solver.jl | 8 +++--- src/gray_scott_solver.jl | 9 +++---- src/utils/constants.jl | 5 ---- src/visualization.jl | 55 ++++++++++++++++++++++++++++++---------- 6 files changed, 68 insertions(+), 47 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 6c62bc0..718c6fb 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -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"] diff --git a/scripts/main.jl b/scripts/main.jl index b9f5213..7bf1f84 100644 --- a/scripts/main.jl +++ b/scripts/main.jl @@ -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 diff --git a/src/fhn_solver.jl b/src/fhn_solver.jl index cd412e7..835872f 100644 --- a/src/fhn_solver.jl +++ b/src/fhn_solver.jl @@ -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 \ No newline at end of file diff --git a/src/gray_scott_solver.jl b/src/gray_scott_solver.jl index ffc7161..418015a 100644 --- a/src/gray_scott_solver.jl +++ b/src/gray_scott_solver.jl @@ -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 \ No newline at end of file diff --git a/src/utils/constants.jl b/src/utils/constants.jl index a07f4f0..1908d86 100644 --- a/src/utils/constants.jl +++ b/src/utils/constants.jl @@ -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 diff --git a/src/visualization.jl b/src/visualization.jl index 751764a..a7c8f6e 100644 --- a/src/visualization.jl +++ b/src/visualization.jl @@ -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