From f4d47c7d2d760b88f49d1a6542ab2347321d0b34 Mon Sep 17 00:00:00 2001 From: Mo8it Date: Sat, 29 Jan 2022 14:32:04 +0100 Subject: [PATCH] Fixed graphics --- analysis/mean_squared_displacement.jl | 25 +- .../radial_distribution_function.jl | 2 +- graphics/pontential.jl | 2 +- src/Animation.jl | 322 ------------------ src/RL/LocalCOMEnv.jl | 10 +- src/RL/RL.jl | 10 +- src/ReCo.jl | 5 +- src/Visualization/Animation.jl | 257 ++++++++++++++ src/Visualization/SnapshotPlot.jl | 86 +++++ src/Visualization/common.jl | 26 ++ .../Visualization}/common_CairoMakie.jl | 0 src/data.jl | 27 +- src/run.jl | 14 +- src/setup.jl | 19 +- src/simulation.jl | 2 +- 15 files changed, 442 insertions(+), 365 deletions(-) delete mode 100644 src/Animation.jl create mode 100644 src/Visualization/Animation.jl create mode 100644 src/Visualization/SnapshotPlot.jl create mode 100644 src/Visualization/common.jl rename {graphics => src/Visualization}/common_CairoMakie.jl (100%) diff --git a/analysis/mean_squared_displacement.jl b/analysis/mean_squared_displacement.jl index 04834ac..78db318 100644 --- a/analysis/mean_squared_displacement.jl +++ b/analysis/mean_squared_displacement.jl @@ -9,7 +9,7 @@ using ProgressMeter: ProgressMeter using ReCo: ReCo -includet("../graphics/common_CairoMakie.jl") +includet("../src/Visualization/common_CairoMakie.jl") # IMPORTANT: Disable the periodic boundary conditions # The arguments types have to match for the function to be overwritten! @@ -35,10 +35,11 @@ function msd_simulation( half_box_len::Float64, T::Float64, snapshot_at::Float64, - parent_dir::String, + parent_dir::String; comment::String="", + seed::Int64=42, ) - Random.seed!(42) + Random.seed!(seed) dir = ReCo.init_sim(; n_particles=1, @@ -76,7 +77,7 @@ function mean_squared_displacement(; parent_dir = main_parent_dir * "/$v₀" Threads.@threads for sim_ind in 1:n_simulations - dir = msd_simulation(v₀, half_box_len, T, 0.5, parent_dir, "$sim_ind") + dir = msd_simulation(v₀, half_box_len, T, 0.5, parent_dir; comment="$sim_ind") sim_dirs[sim_ind, v₀_ind] = dir @@ -172,10 +173,8 @@ function run_msd_analysis() end function plot_random_walk(; T::Float64, v₀::Float64, seed::Int64) - Random.seed!(seed) - half_box_len = max_possible_displacement(T, v₀) - dir = msd_simulation(v₀, half_box_len, T, 8.0, "random_walk_$(Dates.now())") + dir = msd_simulation(v₀, half_box_len, T, 8.0, "random_walk_$(Dates.now())"; seed=seed) ts = Float64[] cs = SVector{2,Float64}[] @@ -209,12 +208,14 @@ function plot_random_walk(; T::Float64, v₀::Float64, seed::Int64) end_point_plot = scatter!(ax, cs[end]; markersize=marker_size, color=:red) - expected_mean_squared_displacement_plot = poly!( + expected_mean_squared_displacement_plot = arc!( ax, - Circle(Point2(0.0, 0.0), expected_mean_displacement); - strokecolor=:orange, - strokewidth=1, - color=RGBAf(0.0, 0.0, 0.0, 0.0), + Point2(0.0, 0.0), + expected_mean_displacement, + 0, + 2 * π; + color=:orange, + linewidth=1, ) Legend( diff --git a/analysis/radial_distribution_function/radial_distribution_function.jl b/analysis/radial_distribution_function/radial_distribution_function.jl index c4cf3a3..7cb9957 100644 --- a/analysis/radial_distribution_function/radial_distribution_function.jl +++ b/analysis/radial_distribution_function/radial_distribution_function.jl @@ -9,7 +9,7 @@ using Random: Random using ReCo: ReCo -includet("../../graphics/common_CairoMakie.jl") +includet("../../src/Visualization/common_CairoMakie.jl") function radial_distribution_simulation(; n_particles::Int64, v₀s::NTuple{N,Float64}, T::Float64, packing_ratio::Float64 diff --git a/graphics/pontential.jl b/graphics/pontential.jl index 60c2fd2..687ac53 100644 --- a/graphics/pontential.jl +++ b/graphics/pontential.jl @@ -1,7 +1,7 @@ using CairoMakie using LaTeXStrings: @L_str -includet("common_CairoMakie.jl") +includet("../src/Visualization/common_CairoMakie.jl") const minimum_r_σ_ratio = 2^(1 / 6) diff --git a/src/Animation.jl b/src/Animation.jl deleted file mode 100644 index 569638f..0000000 --- a/src/Animation.jl +++ /dev/null @@ -1,322 +0,0 @@ -module Animation - -export animate, plot_snapshot - -using CairoMakie -using GLMakie -using ColorSchemes: ColorSchemes -using LaTeXStrings: @L_str -using JLD2: JLD2 -using ProgressMeter: ProgressMeter - -using ..ReCo: ReCo - -include("../graphics/common_CairoMakie.jl") - -const DEFAULT_CENTER_OF_MASS_CIRCLE_COLOR = RGBAf(1, 1, 1, 0.5) - -function angle_color(φ::Float64, color_scheme::ColorSchemes.ColorScheme) - return get(color_scheme, rem2pi(φ, RoundDown) / (2 * π)) -end - -function animate_bundle!(args, sim_consts::ReCo.SimConsts) - bundle_t = args.bundle.t - bundle_c = args.bundle.c - bundle_φ = args.bundle.φ - - for snapshot in 1:length(bundle_t) - @simd for particle_ind in 1:(sim_consts.n_particles) - c = bundle_c[particle_ind, snapshot] - φ = bundle_φ[particle_ind, snapshot] - - args.circles[][particle_ind] = Circle( - Point2(c[1], c[2]), sim_consts.particle_radius - ) - - color = angle_color(φ, args.color_scheme) - args.colors[][particle_ind] = RGBAf(color) - - if args.show_interaction_circle - args.interaction_circles[][particle_ind] = Circle( - Point2(c[1], c[2]), sim_consts.interaction_r - ) - args.interaction_colors[][particle_ind] = RGBAf(color, 0.08) - end - - if args.show_skin_circle - args.skin_circles[][particle_ind] = Circle( - Point2(c[1], c[2]), sim_consts.skin_r - ) - - args.skin_colors[][particle_ind] = RGBAf(color, 0.04) - end - end - - if args.show_center_of_mass - center_of_mass = ReCo.center_of_mass( - view(bundle_c, :, snapshot), sim_consts.half_box_len - ) - args.center_of_mass_circle[] = Circle( - Point2(center_of_mass[1], center_of_mass[2]), - args.center_of_mass_circle_radius, - ) - end - - if args.n_bundle == 1 && snapshot == 1 - poly!(args.ax, args.circles; color=args.colors) - - if args.show_center_of_mass - poly!( - args.ax, - args.center_of_mass_circle; - color=DEFAULT_CENTER_OF_MASS_CIRCLE_COLOR, - ) - end - - if args.show_interaction_circle - poly!(args.ax, args.interaction_circles; color=args.interaction_colors) - end - - if args.show_skin_circle - poly!(args.ax, args.skin_circles; color=args.skin_colors) - end - - println("Recording started!") - else - if args.show_frame_diff && snapshot > 1 - @simd for i in 1:(sim_consts.n_particles) - first_ind = 2 * i - 1 - second_ind = 2 * i - frame_min_1 = snapshot - 1 - - args.segments_x[][first_ind] = bundle_c[i, frame_min_1][1] - args.segments_x[][second_ind] = bundle_c[i, snapshot][1] - - args.segments_y[][first_ind] = bundle_c[i, frame_min_1][2] - args.segments_y[][second_ind] = bundle_c[i, snapshot][2] - end - - if snapshot == 2 - linesegments!( - args.ax, args.segments_x, args.segments_y; color=args.colors - ) - end - - notify(args.segments_x) - notify(args.segments_y) - end - - notify(args.circles) - notify(args.colors) - - if args.show_center_of_mass - notify(args.center_of_mass_circle) - end - - if args.show_interaction_circle - notify(args.interaction_circles) - notify(args.interaction_colors) - end - - if args.show_skin_circle - notify(args.skin_circles) - notify(args.skin_colors) - end - end - - args.ax.title = "t = $(round(bundle_t[snapshot], digits=3))" - - recordframe!(args.io) - end - - return nothing -end - -function gen_axis_and_colorbar(fig, sim_consts::ReCo.SimConsts) - ax = Axis( - fig[1, 1]; - limits=( - -sim_consts.half_box_len, - sim_consts.half_box_len, - -sim_consts.half_box_len, - sim_consts.half_box_len, - ), - aspect=AxisAspect(1), - xlabel=L"x", - ylabel=L"y", - ) - - color_scheme = ColorSchemes.cyclic_mrybm_35_75_c68_n256_s25 - - Colorbar(fig[1, 2]; limits=(0, 2), colormap=color_scheme, label=L"\varphi / \pi") - - return (ax, color_scheme) -end - -function animate( - sim_dir::String; - framerate::Int64=1, - show_center_of_mass::Bool=false, - show_interaction_circle::Bool=false, - show_skin_circle::Bool=false, - show_frame_diff::Bool=false, - show_progress::Bool=true, -) - println("Generating animation...") - - GLMakie.activate!() - set_theme!(theme_black()) - - fig = Figure(; resolution=(1080, 1080)) - - sim_consts = ReCo.load_sim_consts(sim_dir) - - ax, color_scheme = gen_axis_and_colorbar(fig, sim_consts) - - n_particles = sim_consts.n_particles - - animation_path = "$sim_dir/animation.mkv" - - record(fig, animation_path; framerate=framerate) do io - circles = Observable(Vector{Circle}(undef, n_particles)) - colors = Observable(Vector{RGBAf}(undef, n_particles)) - - center_of_mass_circle = - segments_x = - segments_y = - interaction_circles = - skin_circles = interaction_colors = skin_colors = nothing - - center_of_mass_circle_radius = 3 * sim_consts.particle_radius - - if show_center_of_mass - center_of_mass_circle = Observable( - Circle(Point2(0.0, 0.0), center_of_mass_circle_radius) - ) - end - - if show_interaction_circle - interaction_circles = Observable(Vector{Circle}(undef, n_particles)) - skin_circles = Observable(Vector{Circle}(undef, n_particles)) - end - - if show_skin_circle - interaction_colors = Observable(Vector{RGBAf}(undef, n_particles)) - skin_colors = Observable(Vector{RGBAf}(undef, n_particles)) - end - - if show_frame_diff - segments_x = Observable(zeros(2 * n_particles)) - segments_y = Observable(zeros(2 * n_particles)) - end - - bundle_paths = ReCo.sorted_bundle_paths(sim_dir) - - progress = ProgressMeter.Progress( - length(bundle_paths); dt=2, enabled=show_progress, desc="Animation: " - ) - - for (n_bundle, bundle_path) in enumerate(bundle_paths) - bundle::ReCo.Bundle = JLD2.load_object(bundle_path) - - args = (; - # Input - show_center_of_mass, - show_interaction_circle, - show_skin_circle, - show_frame_diff, - # Internal - io, - ax, - bundle, - circles, - colors, - center_of_mass_circle_radius, - center_of_mass_circle, - segments_x, - segments_y, - interaction_circles, - skin_circles, - interaction_colors, - skin_colors, - color_scheme, - n_bundle, - ) - - animate_bundle!(args, sim_consts) - - ProgressMeter.next!(progress) - end - end - - println("Animation done.") - - return nothing -end - -function get_wanted_snapshot_number(n_snapshots::Int64) - print("There are $n_snapshots snapshots. Enter the wanted snapshot number: ") - answer = readline() - - snapshot = parse(Int64, answer) - - @assert 0 < snapshot <= n_snapshots - - return snapshot -end - -function plot_snapshot(sim_dir::String; show_center_of_mass::Bool=false) - bundles_info = ReCo.BundlesInfo(sim_dir) - snapshot = get_wanted_snapshot_number(bundles_info.total_n_snapshots) - - bundle_path = "" - snapshot_counter = 0 - bundle_snapshot = 0 - - for bundle_ind in 1:(bundles_info.n_bundles) - bundle_n_snapshots = bundles_info.bundle_n_snapshots[bundle_ind] - snapshot_counter += bundle_n_snapshots - if snapshot_counter >= snapshot - bundle_snapshot = bundle_n_snapshots - snapshot_counter + snapshot - bundle_path = bundles_info.sorted_bundle_paths[bundle_ind] - break - end - end - - bundle::ReCo.Bundle = JLD2.load_object(bundle_path) - sim_consts = ReCo.load_sim_consts(sim_dir) - - println("Initializing") - - init_cairomakie!() - fig = gen_figure() - - ax, color_scheme = gen_axis_and_colorbar(fig, sim_consts) - - @simd for particle_ind in 1:(sim_consts.n_particles) - c = bundle.c[particle_ind, bundle_snapshot] - φ = bundle.φ[particle_ind, bundle_snapshot] - - color = angle_color(φ, color_scheme) - - poly!(ax, Circle(Point2(c[1], c[2]), sim_consts.particle_radius); color=color) - end - - if show_center_of_mass - center_of_mass = ReCo.center_of_mass( - view(bundle.c, :, bundle_snapshot), sim_consts.half_box_len - ) - circle = Circle( - Point2(center_of_mass[1], center_of_mass[2]), 3 * sim_consts.particle_radius - ) - poly!(ax, circle; color=DEFAULT_CENTER_OF_MASS_CIRCLE_COLOR) - end - - set_gaps!(fig) - - save_fig("$snapshot.pdf", fig; parent_dir="$sim_dir/graphics") - - return nothing -end - -end # module \ No newline at end of file diff --git a/src/RL/LocalCOMEnv.jl b/src/RL/LocalCOMEnv.jl index 771ce14..75df014 100644 --- a/src/RL/LocalCOMEnv.jl +++ b/src/RL/LocalCOMEnv.jl @@ -17,7 +17,7 @@ struct LocalCOMEnv <: Env direction_angle_state_space = gen_angle_state_space(n_direction_angle_states) min_distance = 0.0 - max_distance = args.skin_r + max_distance = args.skin_radius distance_state_space = gen_distance_state_space( min_distance, max_distance, n_distance_states @@ -50,10 +50,12 @@ mutable struct LocalCOMEnvHelper <: EnvHelper half_box_len::Float64 max_elliptical_distance::Float64 - function LocalCOMEnvHelper(shared::EnvHelperSharedProps, half_box_len::Float64, skin_r) + function LocalCOMEnvHelper( + shared::EnvHelperSharedProps, half_box_len::Float64, skin_radius + ) max_elliptical_distance = sqrt(2) * half_box_len / shared.elliptical_a_b_ratio - max_distance_to_local_center_of_mass = skin_r + max_distance_to_local_center_of_mass = skin_radius return new( shared, @@ -72,7 +74,7 @@ mutable struct LocalCOMEnvHelper <: EnvHelper end function gen_env_helper(::LocalCOMEnv, env_helper_shared::EnvHelperSharedProps; args) - return LocalCOMEnvHelper(env_helper_shared, args.half_box_len, args.skin_r) + return LocalCOMEnvHelper(env_helper_shared, args.half_box_len, args.skin_radius) end function pre_integration_hook!(env_helper::LocalCOMEnvHelper) diff --git a/src/RL/RL.jl b/src/RL/RL.jl index 51aaf3e..75febee 100644 --- a/src/RL/RL.jl +++ b/src/RL/RL.jl @@ -62,7 +62,7 @@ function run_rl(; n_particles::Int64=100, seed::Int64=42, ϵ_stable::Float64=0.0001, - skin_to_interaction_r_ratio::Float64=ReCo.DEFAULT_SKIN_TO_INTERACTION_R_RATIO, + skin_to_interaction_radius_ratio::Float64=ReCo.DEFAULT_SKIN_TO_INTERACTION_R_RATIO, packing_ratio::Float64=0.15, show_progress::Bool=true, ) where {E<:Env} @@ -79,12 +79,12 @@ function run_rl(; sim_consts = ReCo.gen_sim_consts( n_particles, 0.0; - skin_to_interaction_r_ratio=skin_to_interaction_r_ratio, + skin_to_interaction_radius_ratio=skin_to_interaction_radius_ratio, packing_ratio=packing_ratio, ) n_particles = sim_consts.n_particles # Not always equal to the input! - env_args = (skin_r=sim_consts.skin_r,) + env_args = (skin_radius=sim_consts.skin_radius,) env = EnvType(; args=env_args) @@ -98,7 +98,9 @@ function run_rl(; env, agent, hook, n_steps_before_actions_update, elliptical_a_b_ratio, n_particles ) - env_helper_args = (half_box_len=sim_consts.half_box_len, skin_r=sim_consts.skin_r) + env_helper_args = ( + half_box_len=sim_consts.half_box_len, skin_radius=sim_consts.skin_radius + ) env_helper = gen_env_helper(env, env_helper_shared; args=env_helper_args) diff --git a/src/ReCo.jl b/src/ReCo.jl index a474180..7ce2bcd 100644 --- a/src/ReCo.jl +++ b/src/ReCo.jl @@ -33,7 +33,10 @@ using .RL include("simulation.jl") include("run.jl") -include("Animation.jl") +include("Visualization/Animation.jl") using .Animation +include("Visualization/SnapshotPlot.jl") +using .SnapshotPlot + end # module \ No newline at end of file diff --git a/src/Visualization/Animation.jl b/src/Visualization/Animation.jl new file mode 100644 index 0000000..6cce2d8 --- /dev/null +++ b/src/Visualization/Animation.jl @@ -0,0 +1,257 @@ +module Animation + +export animate + +using GLMakie +using ColorSchemes: ColorSchemes +using LaTeXStrings: @L_str +using JLD2: JLD2 +using ProgressMeter: ProgressMeter + +using ..ReCo: ReCo + +include("common.jl") + +function animate_bundle!(args, sim_consts::ReCo.SimConsts) + bundle_t = args.bundle.t + bundle_c = args.bundle.c + bundle_φ = args.bundle.φ + + for bundle_snapshot in 1:length(bundle_t) + @simd for particle_ind in 1:(sim_consts.n_particles) + c = bundle_c[particle_ind, bundle_snapshot] + φ = bundle_φ[particle_ind, bundle_snapshot] + + args.particle_xs[][particle_ind] = c[1] + args.particle_ys[][particle_ind] = c[2] + + color = angle_color(φ, args.color_scheme) + args.particle_colors[][particle_ind] = color + + if args.show_interaction_circle + args.interaction_colors[][particle_ind] = ColorSchemes.ColorTypes.RGBA( + color, 0.08 + ) + end + + if args.show_skin_circle + args.skin_colors[][particle_ind] = ColorSchemes.ColorTypes.RGBA(color, 0.04) + end + end + + if args.show_center_of_mass + center_of_mass = ReCo.center_of_mass( + view(bundle_c, :, bundle_snapshot), sim_consts.half_box_len + ) + args.center_of_mass_point[] = Point(center_of_mass) + end + + if args.n_bundle == 1 && bundle_snapshot == 1 + scatter!( + args.ax, + args.particle_xs, + args.particle_ys; + markersize=2 * sim_consts.particle_radius, + markerspace=SceneSpace, + color=args.particle_colors, + ) + + if args.show_center_of_mass + scatter!( + args.ax, + args.center_of_mass_point; + markersize=6 * sim_consts.particle_radius, + markerspace=SceneSpace, + color=ColorSchemes.ColorTypes.RGBA(1.0, 1.0, 1.0, 0.6), + ) + end + + if args.show_interaction_circle + scatter!( + args.ax, + args.particle_xs, + args.particle_ys; + markersize=2 * sim_consts.interaction_radius, + markerspace=SceneSpace, + color=args.interaction_colors, + ) + end + + if args.show_skin_circle + scatter!( + args.ax, + args.particle_xs, + args.particle_ys; + markersize=2 * sim_consts.skin_radius, + markerspace=SceneSpace, + color=args.skin_colors, + ) + end + + println("Recording started!") + else + if args.show_frame_diff && bundle_snapshot > 1 + @simd for i in 1:(sim_consts.n_particles) + first_ind = 2 * i - 1 + second_ind = 2 * i + frame_min_1 = bundle_snapshot - 1 + + args.segment_xs[][first_ind] = bundle_c[i, frame_min_1][1] + args.segment_xs[][second_ind] = bundle_c[i, bundle_snapshot][1] + + args.segment_ys[][first_ind] = bundle_c[i, frame_min_1][2] + args.segment_ys[][second_ind] = bundle_c[i, bundle_snapshot][2] + end + + if bundle_snapshot == 2 + linesegments!( + args.ax, + args.segment_xs, + args.segment_ys; + color=args.particle_colors, + ) + end + + notify(args.segment_xs) + notify(args.segment_ys) + end + + notify(args.particle_xs) + notify(args.particle_ys) + notify(args.particle_colors) + + if args.show_center_of_mass + notify(args.center_of_mass_point) + end + + if args.show_interaction_circle + notify(args.interaction_colors) + end + + if args.show_skin_circle + notify(args.skin_colors) + end + end + + args.ax.title = "t = $(round(bundle_t[bundle_snapshot], digits=3))" + + recordframe!(args.io) + end + + return nothing +end + +function animate( + sim_dir::String; + framerate::Int64=1, + show_center_of_mass::Bool=false, + show_interaction_circle::Bool=false, + show_skin_circle::Bool=false, + show_frame_diff::Bool=false, + show_progress::Bool=true, +) + println("Initializing GLMakie...") + + GLMakie.activate!() + set_theme!(theme_black()) + + fig = Figure(; resolution=(1080, 1080)) + + sim_consts = ReCo.load_sim_consts(sim_dir) + + ax, color_scheme = gen_axis_and_colorbar(fig, sim_consts) + + n_particles = sim_consts.n_particles + + animation_path = "$sim_dir/animation.mkv" + + record(fig, animation_path; framerate=framerate) do io + particle_xs = Observable(Vector{Float64}(undef, n_particles)) + particle_ys = Observable(Vector{Float64}(undef, n_particles)) + + particle_colors = Observable( + Vector{ColorSchemes.ColorTypes.RGB{Float64}}(undef, n_particles) + ) + + center_of_mass_point = + segment_xs = + segment_ys = + interaction_circle_xs = + interaction_circle_ys = + skin_circle_xs = + skin_circle_ys = interaction_colors = skin_colors = nothing + + if show_center_of_mass + center_of_mass_point = Observable(Point2(0.0, 0.0)) + end + + if show_interaction_circle + interaction_circle_xs = Observable(Vector{Float64}(undef, n_particles)) + interaction_circle_ys = Observable(Vector{Float64}(undef, n_particles)) + + interaction_colors = Observable( + Vector{ColorSchemes.ColorTypes.RGBA{Float64}}(undef, n_particles) + ) + end + + if show_skin_circle + skin_circle_xs = Observable(Vector{Float64}(undef, n_particles)) + skin_circle_ys = Observable(Vector{Float64}(undef, n_particles)) + + skin_colors = Observable( + Vector{ColorSchemes.ColorTypes.RGBA{Float64}}(undef, n_particles) + ) + end + + if show_frame_diff + segment_xs = Observable(zeros(2 * n_particles)) + segment_ys = Observable(zeros(2 * n_particles)) + end + + bundle_paths = ReCo.sorted_bundle_paths(sim_dir) + + progress = ProgressMeter.Progress( + length(bundle_paths); dt=2, enabled=show_progress, desc="Animation: " + ) + + for (n_bundle, bundle_path) in enumerate(bundle_paths) + bundle::ReCo.Bundle = JLD2.load_object(bundle_path) + + args = (; + # Input + show_center_of_mass, + show_interaction_circle, + show_skin_circle, + show_frame_diff, + # Internal + io, + ax, + bundle, + particle_xs, + particle_ys, + particle_colors, + center_of_mass_point, + segment_xs, + segment_ys, + interaction_circle_xs, + interaction_circle_ys, + skin_circle_xs, + skin_circle_ys, + interaction_colors, + skin_colors, + color_scheme, + n_bundle, + ) + + animate_bundle!(args, sim_consts) + + ProgressMeter.next!(progress) + end + end + + println("Animation done.") + + return nothing +end + +end # module \ No newline at end of file diff --git a/src/Visualization/SnapshotPlot.jl b/src/Visualization/SnapshotPlot.jl new file mode 100644 index 0000000..57ff885 --- /dev/null +++ b/src/Visualization/SnapshotPlot.jl @@ -0,0 +1,86 @@ +module SnapshotPlot + +export plot_snapshot + +using CairoMakie +using ColorSchemes: ColorSchemes +using LaTeXStrings: @L_str + +using ..ReCo: ReCo + +include("common.jl") +include("common_CairoMakie.jl") + +function get_wanted_snapshot_number(total_n_snapshots::Int64) + print("There are $total_n_snapshots snapshots. Enter the wanted snapshot number: ") + answer = readline() + + snapshot = parse(Int64, answer) + + return snapshot +end + +function plot_snapshot(sim_dir::String; show_center_of_mass::Bool=false) + bundles_info = ReCo.BundlesInfo(sim_dir) + wanted_snapshot_out_of_total = get_wanted_snapshot_number( + bundles_info.total_n_snapshots + ) + + bundle, bundle_snapshot = ReCo.get_bundle_to_snapshot( + bundles_info, wanted_snapshot_out_of_total + ) + + sim_consts = ReCo.load_sim_consts(sim_dir) + + println("Initializing CairoMakie...") + + init_cairomakie!() + fig = gen_figure() + + ax, color_scheme = gen_axis_and_colorbar(fig, sim_consts) + + particle_xs = Vector{Float64}(undef, sim_consts.n_particles) + particle_ys = Vector{Float64}(undef, sim_consts.n_particles) + particle_colors = Vector{ColorSchemes.ColorTypes.RGB}(undef, sim_consts.n_particles) + + @simd for particle_ind in 1:(sim_consts.n_particles) + c = bundle.c[particle_ind, bundle_snapshot] + φ = bundle.φ[particle_ind, bundle_snapshot] + + color = angle_color(φ, color_scheme) + + particle_xs[particle_ind] = c[1] + particle_ys[particle_ind] = c[2] + particle_colors[particle_ind] = color + end + + scatter!( + ax, + particle_xs, + particle_ys; + markersize=2 * sim_consts.particle_radius, + markerspace=SceneSpace, + color=particle_colors, + ) + + if show_center_of_mass + center_of_mass = ReCo.center_of_mass( + view(bundle.c, :, bundle_snapshot), sim_consts.half_box_len + ) + scatter!( + ax, + Point(center_of_mass); + markersize=6 * sim_consts.particle_radius, + markerspace=SceneSpace, + color=ColorSchemes.ColorTypes.RGBA(0.0, 0.0, 0.0, 0.6), + ) + end + + set_gaps!(fig) + + save_fig("$wanted_snapshot_out_of_total.pdf", fig; parent_dir="$sim_dir/graphics") + + return nothing +end + +end # module \ No newline at end of file diff --git a/src/Visualization/common.jl b/src/Visualization/common.jl new file mode 100644 index 0000000..41070ba --- /dev/null +++ b/src/Visualization/common.jl @@ -0,0 +1,26 @@ +using ColorSchemes + +function angle_color(φ::Float64, color_scheme::ColorSchemes.ColorScheme) + return get(color_scheme, rem2pi(φ, RoundDown) / (2 * π)) +end + +function gen_axis_and_colorbar(fig, sim_consts::ReCo.SimConsts) + ax = Axis( + fig[1, 1]; + limits=( + -sim_consts.half_box_len, + sim_consts.half_box_len, + -sim_consts.half_box_len, + sim_consts.half_box_len, + ), + aspect=AxisAspect(1), + xlabel=L"x", + ylabel=L"y", + ) + + color_scheme = ColorSchemes.cyclic_mrybm_35_75_c68_n256_s25 + + Colorbar(fig[1, 2]; limits=(0, 2), colormap=color_scheme, label=L"\varphi / \pi") + + return (ax, color_scheme) +end \ No newline at end of file diff --git a/graphics/common_CairoMakie.jl b/src/Visualization/common_CairoMakie.jl similarity index 100% rename from graphics/common_CairoMakie.jl rename to src/Visualization/common_CairoMakie.jl diff --git a/src/data.jl b/src/data.jl index 7ed30d9..b425f57 100644 --- a/src/data.jl +++ b/src/data.jl @@ -9,8 +9,8 @@ struct SimConsts Dᵣ::Float64 σ::Float64 ϵ::Float64 - interaction_r::Float64 - skin_r::Float64 + interaction_radius::Float64 + skin_radius::Float64 n_steps_before_verlet_list_update::Int64 grid_n::Int64 half_box_len::Float64 @@ -116,7 +116,7 @@ function append_bundle_properties!( for bundle_ind in first_bundle:length(bundle_paths) bundle::Bundle = JLD2.load_object(bundle_paths[bundle_ind]) - for (v_ind, v) in enumerat(vs) + for (v_ind, v) in enumerate(vs) property = properties[v_ind] bundle_property = getproperty(bundle, property) @@ -164,4 +164,25 @@ function load_sim_consts(dir::String) sim_consts::ReCo.SimConsts = JLD2.load_object("$dir/sim_consts.jld2") return sim_consts +end + +function get_bundle_to_snapshot( + bundles_info::BundlesInfo, snapshot::Int64 +)::Tuple{Bundle,Int64} + @assert 0 < snapshot <= bundles_info.total_n_snapshots + + snapshot_counter = 0 + + for bundle_ind in 1:(bundles_info.n_bundles) + bundle_n_snapshots = bundles_info.bundle_n_snapshots[bundle_ind] + snapshot_counter += bundle_n_snapshots + if snapshot_counter >= snapshot + bundle_snapshot = bundle_n_snapshots - snapshot_counter + snapshot + bundle_path = bundles_info.sorted_bundle_paths[bundle_ind] + + bundle::ReCo.Bundle = JLD2.load_object(bundle_path) + + return (bundle, bundle_snapshot) + end + end end \ No newline at end of file diff --git a/src/run.jl b/src/run.jl index e446e03..efa49d7 100644 --- a/src/run.jl +++ b/src/run.jl @@ -2,8 +2,8 @@ function empty_hook(args...) return nothing end -function gen_cell_list_box(half_box_len::Float64, skin_r::Float64) - return CellListMap.Box(SVector(2 * half_box_len, 2 * half_box_len), skin_r) +function gen_cell_list_box(half_box_len::Float64, skin_radius::Float64) + return CellListMap.Box(SVector(2 * half_box_len, 2 * half_box_len), skin_radius) end function run_sim( @@ -81,8 +81,8 @@ function run_sim( args = ( v₀=sim_consts.v₀, δt=sim_consts.δt, - skin_r=sim_consts.skin_r, - skin_r²=sim_consts.skin_r^2, + skin_radius=sim_consts.skin_radius, + skin_radius²=sim_consts.skin_radius^2, n_snapshots=n_snapshots, ϵσ⁶δtμₜ24=24 * sim_consts.ϵ * sim_consts.σ^6 * sim_consts.δt * sim_consts.μₜ, σ⁶2=2 * sim_consts.σ^6, @@ -90,8 +90,8 @@ function run_sim( sqrt_Dᵣδt2=sqrt(2 * sim_consts.Dᵣ * sim_consts.δt), v₀δt=sim_consts.v₀ * sim_consts.δt, μₜ=sim_consts.μₜ, - interaction_r=sim_consts.interaction_r, - interaction_r²=sim_consts.interaction_r^2, + interaction_radius=sim_consts.interaction_radius, + interaction_radius²=sim_consts.interaction_radius^2, n_particles=sim_consts.n_particles, half_box_len=sim_consts.half_box_len, particles=particles, @@ -102,7 +102,7 @@ function run_sim( ], n_bundle_snapshots=n_bundle_snapshots, bundle=Bundle(sim_consts.n_particles, n_bundle_snapshots), - box=gen_cell_list_box(sim_consts.half_box_len, sim_consts.skin_r), + box=gen_cell_list_box(sim_consts.half_box_len, sim_consts.skin_radius), show_progress=show_progress, ) diff --git a/src/setup.jl b/src/setup.jl index 61b7f29..a15f755 100644 --- a/src/setup.jl +++ b/src/setup.jl @@ -51,7 +51,7 @@ function gen_sim_consts( v₀::Float64; δt::Float64=DEFAULT_δt, packing_ratio::Float64=DEFAULT_PACKING_RATIO, - skin_to_interaction_r_ratio::Float64=DEFAULT_SKIN_TO_INTERACTION_R_RATIO, + skin_to_interaction_radius_ratio::Float64=DEFAULT_SKIN_TO_INTERACTION_R_RATIO, half_box_len::Float64=0.0, ) @assert n_particles > 0 @@ -65,17 +65,18 @@ function gen_sim_consts( Dᵣ = 3 * Dₜ / ((2 * particle_radius)^2) σ = 2 * particle_radius * 2^(-1 / 6) ϵ = DEFAULT_ϵ - interaction_r = 2^(1 / 6) * σ + interaction_radius = 2^(1 / 6) * σ - skin_r = skin_to_interaction_r_ratio * interaction_r + skin_radius = skin_to_interaction_radius_ratio * interaction_radius buffer = 2.5 max_approach_after_one_integration_step = buffer * (2 * v₀ * δt) - @assert skin_r >= interaction_r + max_approach_after_one_integration_step + @assert skin_radius >= interaction_radius + max_approach_after_one_integration_step if v₀ != 0.0 n_steps_before_verlet_list_update = floor( - Int64, (skin_r - interaction_r) / max_approach_after_one_integration_step + Int64, + (skin_radius - interaction_radius) / max_approach_after_one_integration_step, ) else n_steps_before_verlet_list_update = 1000 @@ -106,8 +107,8 @@ function gen_sim_consts( Dᵣ, σ, ϵ, - interaction_r, - skin_r, + interaction_radius, + skin_radius, n_steps_before_verlet_list_update, grid_n, half_box_len, @@ -159,7 +160,7 @@ function init_sim(; v₀::Float64, δt::Float64=DEFAULT_δt, packing_ratio::Float64=DEFAULT_PACKING_RATIO, - skin_to_interaction_r_ratio::Float64=DEFAULT_SKIN_TO_INTERACTION_R_RATIO, + skin_to_interaction_radius_ratio::Float64=DEFAULT_SKIN_TO_INTERACTION_R_RATIO, exports_dir::String=DEFAULT_EXPORTS_DIR, parent_dir::String=DEFAULT_PARENT_DIR, comment::String=DEFAULT_COMMENT, @@ -170,7 +171,7 @@ function init_sim(; v₀; δt=δt, packing_ratio=packing_ratio, - skin_to_interaction_r_ratio=skin_to_interaction_r_ratio, + skin_to_interaction_radius_ratio=skin_to_interaction_radius_ratio, half_box_len, ) diff --git a/src/simulation.jl b/src/simulation.jl index 0ddbad4..b85eb27 100644 --- a/src/simulation.jl +++ b/src/simulation.jl @@ -51,7 +51,7 @@ function euler!( p2 = args.particles[id2] overlapping, r⃗₁₂, distance² = are_overlapping( - p1_c, p2.c, args.interaction_r², args.half_box_len + p1_c, p2.c, args.interaction_radius², args.half_box_len ) state_update_helper_hook!(env_helper, id1, id2, r⃗₁₂)