1
0
Fork 0
mirror of https://gitlab.rlp.net/mobitar/ReCo.jl.git synced 2024-12-21 00:51:21 +00:00

Fixed graphics

This commit is contained in:
Mo8it 2022-01-29 14:32:04 +01:00
parent e8faf811f1
commit f4d47c7d2d
15 changed files with 442 additions and 365 deletions

View file

@ -9,7 +9,7 @@ using ProgressMeter: ProgressMeter
using ReCo: ReCo using ReCo: ReCo
includet("../graphics/common_CairoMakie.jl") includet("../src/Visualization/common_CairoMakie.jl")
# IMPORTANT: Disable the periodic boundary conditions # IMPORTANT: Disable the periodic boundary conditions
# The arguments types have to match for the function to be overwritten! # The arguments types have to match for the function to be overwritten!
@ -35,10 +35,11 @@ function msd_simulation(
half_box_len::Float64, half_box_len::Float64,
T::Float64, T::Float64,
snapshot_at::Float64, snapshot_at::Float64,
parent_dir::String, parent_dir::String;
comment::String="", comment::String="",
seed::Int64=42,
) )
Random.seed!(42) Random.seed!(seed)
dir = ReCo.init_sim(; dir = ReCo.init_sim(;
n_particles=1, n_particles=1,
@ -76,7 +77,7 @@ function mean_squared_displacement(;
parent_dir = main_parent_dir * "/$v₀" parent_dir = main_parent_dir * "/$v₀"
Threads.@threads for sim_ind in 1:n_simulations 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 sim_dirs[sim_ind, v₀_ind] = dir
@ -172,10 +173,8 @@ function run_msd_analysis()
end end
function plot_random_walk(; T::Float64, v₀::Float64, seed::Int64) function plot_random_walk(; T::Float64, v₀::Float64, seed::Int64)
Random.seed!(seed)
half_box_len = max_possible_displacement(T, v₀) 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[] ts = Float64[]
cs = SVector{2,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) 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, ax,
Circle(Point2(0.0, 0.0), expected_mean_displacement); Point2(0.0, 0.0),
strokecolor=:orange, expected_mean_displacement,
strokewidth=1, 0,
color=RGBAf(0.0, 0.0, 0.0, 0.0), 2 * π;
color=:orange,
linewidth=1,
) )
Legend( Legend(

View file

@ -9,7 +9,7 @@ using Random: Random
using ReCo: ReCo using ReCo: ReCo
includet("../../graphics/common_CairoMakie.jl") includet("../../src/Visualization/common_CairoMakie.jl")
function radial_distribution_simulation(; function radial_distribution_simulation(;
n_particles::Int64, v₀s::NTuple{N,Float64}, T::Float64, packing_ratio::Float64 n_particles::Int64, v₀s::NTuple{N,Float64}, T::Float64, packing_ratio::Float64

View file

@ -1,7 +1,7 @@
using CairoMakie using CairoMakie
using LaTeXStrings: @L_str using LaTeXStrings: @L_str
includet("common_CairoMakie.jl") includet("../src/Visualization/common_CairoMakie.jl")
const minimum_r_σ_ratio = 2^(1 / 6) const minimum_r_σ_ratio = 2^(1 / 6)

View file

@ -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

View file

@ -17,7 +17,7 @@ struct LocalCOMEnv <: Env
direction_angle_state_space = gen_angle_state_space(n_direction_angle_states) direction_angle_state_space = gen_angle_state_space(n_direction_angle_states)
min_distance = 0.0 min_distance = 0.0
max_distance = args.skin_r max_distance = args.skin_radius
distance_state_space = gen_distance_state_space( distance_state_space = gen_distance_state_space(
min_distance, max_distance, n_distance_states min_distance, max_distance, n_distance_states
@ -50,10 +50,12 @@ mutable struct LocalCOMEnvHelper <: EnvHelper
half_box_len::Float64 half_box_len::Float64
max_elliptical_distance::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_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( return new(
shared, shared,
@ -72,7 +74,7 @@ mutable struct LocalCOMEnvHelper <: EnvHelper
end end
function gen_env_helper(::LocalCOMEnv, env_helper_shared::EnvHelperSharedProps; args) 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 end
function pre_integration_hook!(env_helper::LocalCOMEnvHelper) function pre_integration_hook!(env_helper::LocalCOMEnvHelper)

View file

@ -62,7 +62,7 @@ function run_rl(;
n_particles::Int64=100, n_particles::Int64=100,
seed::Int64=42, seed::Int64=42,
ϵ_stable::Float64=0.0001, ϵ_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, packing_ratio::Float64=0.15,
show_progress::Bool=true, show_progress::Bool=true,
) where {E<:Env} ) where {E<:Env}
@ -79,12 +79,12 @@ function run_rl(;
sim_consts = ReCo.gen_sim_consts( sim_consts = ReCo.gen_sim_consts(
n_particles, n_particles,
0.0; 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, packing_ratio=packing_ratio,
) )
n_particles = sim_consts.n_particles # Not always equal to the input! 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) 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, 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) env_helper = gen_env_helper(env, env_helper_shared; args=env_helper_args)

View file

@ -33,7 +33,10 @@ using .RL
include("simulation.jl") include("simulation.jl")
include("run.jl") include("run.jl")
include("Animation.jl") include("Visualization/Animation.jl")
using .Animation using .Animation
include("Visualization/SnapshotPlot.jl")
using .SnapshotPlot
end # module end # module

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -9,8 +9,8 @@ struct SimConsts
Dᵣ::Float64 Dᵣ::Float64
σ::Float64 σ::Float64
ϵ::Float64 ϵ::Float64
interaction_r::Float64 interaction_radius::Float64
skin_r::Float64 skin_radius::Float64
n_steps_before_verlet_list_update::Int64 n_steps_before_verlet_list_update::Int64
grid_n::Int64 grid_n::Int64
half_box_len::Float64 half_box_len::Float64
@ -116,7 +116,7 @@ function append_bundle_properties!(
for bundle_ind in first_bundle:length(bundle_paths) for bundle_ind in first_bundle:length(bundle_paths)
bundle::Bundle = JLD2.load_object(bundle_paths[bundle_ind]) 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] property = properties[v_ind]
bundle_property = getproperty(bundle, property) bundle_property = getproperty(bundle, property)
@ -165,3 +165,24 @@ function load_sim_consts(dir::String)
return sim_consts return sim_consts
end 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

View file

@ -2,8 +2,8 @@ function empty_hook(args...)
return nothing return nothing
end end
function gen_cell_list_box(half_box_len::Float64, skin_r::Float64) 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_r) return CellListMap.Box(SVector(2 * half_box_len, 2 * half_box_len), skin_radius)
end end
function run_sim( function run_sim(
@ -81,8 +81,8 @@ function run_sim(
args = ( args = (
v₀=sim_consts.v₀, v₀=sim_consts.v₀,
δt=sim_consts.δt, δt=sim_consts.δt,
skin_r=sim_consts.skin_r, skin_radius=sim_consts.skin_radius,
skin_r²=sim_consts.skin_r^2, skin_radius²=sim_consts.skin_radius^2,
n_snapshots=n_snapshots, n_snapshots=n_snapshots,
ϵσ⁶δtμₜ24=24 * sim_consts.ϵ * sim_consts.σ^6 * sim_consts.δt * sim_consts.μₜ, ϵσ⁶δtμₜ24=24 * sim_consts.ϵ * sim_consts.σ^6 * sim_consts.δt * sim_consts.μₜ,
σ⁶2=2 * sim_consts.σ^6, σ⁶2=2 * sim_consts.σ^6,
@ -90,8 +90,8 @@ function run_sim(
sqrt_Dᵣδt2=sqrt(2 * sim_consts.Dᵣ * sim_consts.δt), sqrt_Dᵣδt2=sqrt(2 * sim_consts.Dᵣ * sim_consts.δt),
v₀δt=sim_consts.v₀ * sim_consts.δt, v₀δt=sim_consts.v₀ * sim_consts.δt,
μₜ=sim_consts.μₜ, μₜ=sim_consts.μₜ,
interaction_r=sim_consts.interaction_r, interaction_radius=sim_consts.interaction_radius,
interaction_r²=sim_consts.interaction_r^2, interaction_radius²=sim_consts.interaction_radius^2,
n_particles=sim_consts.n_particles, n_particles=sim_consts.n_particles,
half_box_len=sim_consts.half_box_len, half_box_len=sim_consts.half_box_len,
particles=particles, particles=particles,
@ -102,7 +102,7 @@ function run_sim(
], ],
n_bundle_snapshots=n_bundle_snapshots, n_bundle_snapshots=n_bundle_snapshots,
bundle=Bundle(sim_consts.n_particles, 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, show_progress=show_progress,
) )

View file

@ -51,7 +51,7 @@ function gen_sim_consts(
v₀::Float64; v₀::Float64;
δt::Float64=DEFAULT_δt, δt::Float64=DEFAULT_δt,
packing_ratio::Float64=DEFAULT_PACKING_RATIO, 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, half_box_len::Float64=0.0,
) )
@assert n_particles > 0 @assert n_particles > 0
@ -65,17 +65,18 @@ function gen_sim_consts(
Dᵣ = 3 * Dₜ / ((2 * particle_radius)^2) Dᵣ = 3 * Dₜ / ((2 * particle_radius)^2)
σ = 2 * particle_radius * 2^(-1 / 6) σ = 2 * particle_radius * 2^(-1 / 6)
ϵ = DEFAULT_ϵ ϵ = 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 buffer = 2.5
max_approach_after_one_integration_step = buffer * (2 * v₀ * δt) 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 if v₀ != 0.0
n_steps_before_verlet_list_update = floor( 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 else
n_steps_before_verlet_list_update = 1000 n_steps_before_verlet_list_update = 1000
@ -106,8 +107,8 @@ function gen_sim_consts(
Dᵣ, Dᵣ,
σ, σ,
ϵ, ϵ,
interaction_r, interaction_radius,
skin_r, skin_radius,
n_steps_before_verlet_list_update, n_steps_before_verlet_list_update,
grid_n, grid_n,
half_box_len, half_box_len,
@ -159,7 +160,7 @@ function init_sim(;
v₀::Float64, v₀::Float64,
δt::Float64=DEFAULT_δt, δt::Float64=DEFAULT_δt,
packing_ratio::Float64=DEFAULT_PACKING_RATIO, 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, exports_dir::String=DEFAULT_EXPORTS_DIR,
parent_dir::String=DEFAULT_PARENT_DIR, parent_dir::String=DEFAULT_PARENT_DIR,
comment::String=DEFAULT_COMMENT, comment::String=DEFAULT_COMMENT,
@ -170,7 +171,7 @@ function init_sim(;
v₀; v₀;
δt=δt, δt=δt,
packing_ratio=packing_ratio, 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, half_box_len,
) )

View file

@ -51,7 +51,7 @@ function euler!(
p2 = args.particles[id2] p2 = args.particles[id2]
overlapping, r⃗₁₂, distance² = are_overlapping( 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⃗₁₂) state_update_helper_hook!(env_helper, id1, id2, r⃗₁₂)