SCJ_Projekt/src/visualization.jl

165 lines
4.4 KiB
Julia
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

module Visualization
include("gray_scott_solver.jl")
using GLMakie, Observables, Makie
using .GrayScottSolver
"""
step_through_solution(sol::SolutionType, N::Int)
Function for visualization for the output of run_simulation
# Arguments
- `sol`: computed differential equation by run_simulation
- `N`: size of the N×N grid
# Returns
- ``: Displays created figure
"""
function step_through_solution(sol, N::Int)
fig = Figure(resolution=(600, 600))
ax = Axis(fig[1, 1])
slider = Slider(fig[2, 1], range=1:length(sol), startvalue=1)
textbox = Textbox(fig[1, 2], placeholder="Feed Rate", validator=Float64)
F = Observable(0.060)
# Initialize heatmap with first time step
u0 = reshape(sol[1][1:N^2], N, N)
heat_obs = Observable(u0)
hmap = heatmap!(ax, heat_obs, colormap=:magma)
on(textbox.stored_string) do s
F[] = parse(Float64, s)
end
# Update heatmap on slider movement
on(slider.value) do i
u = reshape(sol[i][1:N^2], N, N)
heat_obs[] = u
end
display(fig)
end
function coord_to_index(x, y, N)
ix = clamp(round(Int, x), 1, N)
iy = clamp(round(Int, y), 1, N)
return ix, iy
end
function reset!(U, V, heat_obs)
U .= 1.0
V .= 0.0
center = size(U, 1) ÷ 2
radius = 10
U[center-radius:center+radius, center-radius:center+radius] .= 0.50
V[center-radius:center+radius, center-radius:center+radius] .= 0.25
heat_obs[] = copy(U)
end
function param_box!(grid, row, labeltxt, observable::Observable)
Label(grid[row, 1], labeltxt)
box = Textbox(grid[row, 2], validator=Float64, width=50, placeholder=labeltxt, stored_string="$(observable[])")
on(box.stored_string) do s
try
observable[] = parse(Float64, s)
println("changed $labeltxt to $s")
catch
@warn "Invalid input for $labeltxt: $s"
end
end
end
function build_ui(U, V, Du, Dv, F, k, params_obs, heat_obs)
reset!(U, V, heat_obs)
fig = Figure(size=(800, 800))
gh = GridLayout(fig[1, 1])
ax = Axis(gh[1, 1])
hm = Makie.heatmap!(ax, heat_obs, colormap=:viridis)
deactivate_interaction!(ax, :rectanglezoom)
ax.aspect = DataAspect()
run_label = Observable{String}("Run")
stepsize = Observable(30)
spoint = select_point(ax.scene)
# # Controls
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)
btn_reset = Button(buttongrid[1, 3], width=50, label="Reset")
slidergrid = SliderGrid(fig[3, 1], (label="Speed", range=1:1:100, format="{}x", width=350, startvalue=stepsize[]))
speed_slider = slidergrid.sliders[1].value
gh[1, 2] = textboxgrid = GridLayout(ax.scene, tellwidth=false)
rowsize!(gh, 1, Relative(1.0))
param_box!(textboxgrid, 1, "Du", Du)
param_box!(textboxgrid, 2, "Dv", Dv)
param_box!(textboxgrid, 3, "Feed", F)
param_box!(textboxgrid, 4, "kill", k)
# Timer and state for animation
running = Observable(false)
on(running) do r
run_label[] = r ? "Pause" : "Run"
end
on(speed_slider) do s
try
stepsize[] = s
println("Changed stepsize to $s")
catch
@warn "Invalid input for $s"
end
end
# Button Listeners
on(btn_step.clicks) do _
multi_step!((U, V), stepsize[], heat_obs, params_obs)
end
on(btn_start.clicks) do _
running[] = !running[]
end
on(btn_start.clicks) do _
@async while running[]
multi_step!((U, V), stepsize[], heat_obs, params_obs)
sleep(0.0015) # ~20 FPS
end
end
on(btn_reset.clicks) do _
running[] = false
reset!(U, V, heat_obs)
end
on(spoint) do pt
r = 5
if pt === nothing
return
end
x, y = pt
println("params_obs[].N, ", params_obs[].N)
i, j = coord_to_index(x, y, params_obs[].N)
# get corners of square that will get filled with concentration
imin = max(i - r, 1)
imax = min(i + r, params_obs[].N)
jmin = max(j - r, 1)
jmax = min(j + r, params_obs[].N)
# set disbalanced concentration of U and V
U[imin:imax, jmin:jmax] .= 0.5
V[imin:imax, jmin:jmax] .= 0.25
heat_obs[] = copy(U)
end
return fig
end
export step_through_solution, build_ui
end