diff --git a/src/fhn_solver.jl b/src/fhn_solver.jl index 90a842f..f22c072 100644 --- a/src/fhn_solver.jl +++ b/src/fhn_solver.jl @@ -57,7 +57,7 @@ function step_fhn!(U, V, params_obs::Observable; dx=1) # Define one integration step using your fhn! function prob = ODEProblem((du, u, p, t) -> fhn!(du, u, p, t), u_init, (0.0, 0.1), p) - sol = solve(prob, Tsit5(); dt=0.1, save_start=false, saveat=10.0) + sol = solve(prob, BS3(); save_start=false, saveat=10.0) # Extract solution and reshape u_new = reshape(sol[end][1:p.N^2], p.N, p.N) @@ -67,6 +67,17 @@ function step_fhn!(U, V, params_obs::Observable; dx=1) U .= u_new V .= v_new + # Apply periodic boundary conditions + U[1, :] .= U[end-1, :] + U[end, :] .= U[2, :] + U[:, 1] .= U[:, end-1] + U[:, end] .= U[:, 2] + + V[1, :] .= V[end-1, :] + V[end, :] .= V[2, :] + V[:, 1] .= V[:, end-1] + V[:, end] .= V[:, 2] + return U end diff --git a/src/utils/laplacian.jl b/src/utils/laplacian.jl index 814573a..ff74151 100644 --- a/src/utils/laplacian.jl +++ b/src/utils/laplacian.jl @@ -11,6 +11,6 @@ function laplacian(U::AbstractMatrix{<:Real}, dx::Real) return (up .+ down .+ left .+ right .- 4 .* center) ./ h2 end -export laplacian, laplacian5 +export laplacian end # module Laplacian diff --git a/src/utils/templates.jl b/src/utils/templates.jl index e4577c0..e328085 100644 --- a/src/utils/templates.jl +++ b/src/utils/templates.jl @@ -1,7 +1,8 @@ +# helper functions for filling cells in specific places of the matrix +# Not all functions are used. Those are for experimenting and debugging purposes module Templates -# helper functions for filling cells in specific places of the matrix function blocks_ic(N) u = fill(1.0, N, N) v = fill(0.0, N, N) @@ -9,9 +10,9 @@ function blocks_ic(N) function safe_block!(u, row_center, col_center) row_start = max(row_center - 8, 1) - row_end = min(row_center + 7, N) + row_end = min(row_center + 7, N) col_start = max(col_center - 8, 1) - col_end = min(col_center + 7, N) + col_end = min(col_center + 7, N) u[row_start:row_end, col_start:col_end] .= -0.01 end @@ -35,6 +36,17 @@ function column_ic(N) return u, v end +function stripe_ic(N) + u = zeros(N, N) + v = zeros(N, N) + for i in 1:N + for j in 1:N + u[i, j] = 0.1 + 0.05 * sin(2π * j / 10) + 0.01 * randn() + end + end + return u, v +end + function two_rows_edge_distance_ic(N) row_width = 8 distance_from_edge = 50 @@ -126,7 +138,7 @@ function three_circles_random_ic(N) end end - return vec(u), vec(v) + return u, v end function squiggle_ic(N, Lx=400.0, Ly=400.0) @@ -151,7 +163,7 @@ function squiggle_ic(N, Lx=400.0, Ly=400.0) v = fill(vplus, N, N) # Apply squiggle - u[Z .> 0.8] .= uminus + u[Z.>0.8] .= uminus return vec(u), vec(v) end @@ -160,7 +172,7 @@ function coral_ic(N) u = fill(0.534522, N, N) v = fill(0.381802, N, N) - for _ in 1:40 # place 15 noisy seeds + for _ in 1:20 # place 15 noisy seeds i, j = rand(10:N-10), rand(10:N-10) u[i-2:i+2, j-2:j+2] .= -0.534522 .+ 0.2 * rand(5, 5) end @@ -168,6 +180,6 @@ function coral_ic(N) return u, v end -export blocks_ic, column_ic, squiggle_ic, three_circles_random_ic, circle_ic, center_band_ic, two_rows_edge_distance_ic +export blocks_ic, column_ic, squiggle_ic, three_circles_random_ic, circle_ic, center_band_ic, two_rows_edge_distance_ic, coral_ic end \ No newline at end of file diff --git a/src/visualization.jl b/src/visualization.jl index 48b03b7..ad12daa 100644 --- a/src/visualization.jl +++ b/src/visualization.jl @@ -43,6 +43,7 @@ function reset!(U, V, heat_obs) 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 @@ -101,8 +102,9 @@ function build_ui(U, V, param_obs_map::NamedTuple, params_obs, heat_obs) gh[1, 2] = templategrid = GridLayout(ax.scene, tellwidth=false) templategrid[1, 1] = Label(fig, "Templates:") btn_zebra = Button(templategrid[1, 2], width=100, label="Zebra Stripes") - btn_cheetah = Button(templategrid[1, 3], width=100, label="Cheetah Spots") - btn_coral = Button(templategrid[1, 4], width=100, label="Coral Pattern") + btn_cow = Button(templategrid[1, 3], width=100, label="Cow Spots") + btn_cheetah = Button(templategrid[1, 4], width=100, label="Cheetah Spots") + #btn_coral = Button(templategrid[1, 4], width=100, label="Coral Pattern") # place all the parameter boxes gh[2, 2] = textboxgrid = GridLayout(ax.scene, tellwidth=false) @@ -130,7 +132,7 @@ function build_ui(U, V, param_obs_map::NamedTuple, params_obs, heat_obs) colsize!(textboxgrid, c, Relative(0.1)) end - # Events ############################################################## + # ======== Events ======== # Timer and state for animation running = Observable(false) @@ -163,6 +165,7 @@ function build_ui(U, V, param_obs_map::NamedTuple, params_obs, heat_obs) on(btn_reset.clicks) do _ running[] = false + hm.colormap[] = :viridis reset!(U, V, heat_obs) end @@ -172,24 +175,40 @@ function build_ui(U, V, param_obs_map::NamedTuple, params_obs, heat_obs) # add column to center of matrix U, V = Templates.column_ic(params_obs[].N) - hm.colormap[] = :berlin + hm.colormap[] = :grayC # change params - param_obs_map.Du[] = 0.016 - param_obs_map.Dv[] = 0.1 - param_obs_map.ϵ[] = 0.1 - param_obs_map.a[] = 0.5 - param_obs_map.b[] = 0.9 + param_obs_map.Du[] = 1.0 + param_obs_map.Dv[] = 2.0 + param_obs_map.ϵ[] = 0.3 + param_obs_map.a[] = 0.0 + param_obs_map.b[] = 1.4 heat_obs[] = copy(U) end # Template Control + on(btn_cow.clicks) do _ + # fill matrix with random noise + U = 0.05 .* (2 .* rand(params_obs[].N, params_obs[].N) .- 1) # noise in [-0.05, 0.05] + V = 0.05 .* (2 .* rand(params_obs[].N, params_obs[].N) .- 1) + + hm.colormap[] = :grayC + + # change params + param_obs_map.Du[] = 1.0 + param_obs_map.Dv[] = 10.0 + param_obs_map.ϵ[] = 0.01 + param_obs_map.a[] = -0.1 + param_obs_map.b[] = 1.2 + heat_obs[] = copy(U) + end + on(btn_cheetah.clicks) do _ # fill matrix with random noise U = 0.05 .* (2 .* rand(params_obs[].N, params_obs[].N) .- 1) # noise in [-0.05, 0.05] V = 0.05 .* (2 .* rand(params_obs[].N, params_obs[].N) .- 1) - hm.colormap[] = :magma + hm.colormap[] = cgrad(:lajolla, rev = true) # change params param_obs_map.Du[] = 0.182 @@ -200,21 +219,6 @@ function build_ui(U, V, param_obs_map::NamedTuple, params_obs, heat_obs) heat_obs[] = copy(U) end - # Template Control - on(btn_coral.clicks) do _ - U, V = Templates.coral_ic(params_obs[].N) - - hm.colormap[] = :plasma - - # change params - param_obs_map.Du[] = 0.001 - param_obs_map.Dv[] = 0.06 - param_obs_map.ϵ[] = 0.05 - param_obs_map.a[] = 0.0 - param_obs_map.b[] = 1.2 - heat_obs[] = copy(U) - end - on(spoint) do pt r = 5 if pt === nothing