2022-01-18 01:17:52 +00:00
|
|
|
function rand_normal01()
|
|
|
|
return rand(Normal(0, 1))
|
|
|
|
end
|
2021-11-10 14:41:04 +00:00
|
|
|
|
2021-12-10 02:16:18 +00:00
|
|
|
function push_to_verlet_list!(verlet_lists, i, j)
|
2021-12-07 03:19:35 +00:00
|
|
|
if i < j
|
2021-12-10 02:16:18 +00:00
|
|
|
push!(verlet_lists[i], Int64(j))
|
2021-12-07 03:19:35 +00:00
|
|
|
else
|
2021-12-10 02:16:18 +00:00
|
|
|
push!(verlet_lists[j], Int64(i))
|
2021-12-07 03:19:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
return nothing
|
|
|
|
end
|
|
|
|
|
2021-12-10 02:16:18 +00:00
|
|
|
function update_verlet_lists!(args, cl)
|
|
|
|
@simd for pre_vec in args.verlet_lists
|
|
|
|
reset!(pre_vec)
|
2021-11-10 14:41:04 +00:00
|
|
|
end
|
2021-11-16 21:26:08 +00:00
|
|
|
|
2021-12-10 02:16:18 +00:00
|
|
|
@simd for i in 1:(args.n_particles)
|
2021-12-07 04:52:10 +00:00
|
|
|
args.particles_c[i] = args.particles[i].c
|
2021-12-07 03:19:35 +00:00
|
|
|
end
|
2021-11-10 14:41:04 +00:00
|
|
|
|
2021-12-07 03:19:35 +00:00
|
|
|
cl = UpdateCellList!(args.particles_c, args.box, cl; parallel=false)
|
2021-11-10 14:41:04 +00:00
|
|
|
|
2021-12-07 03:19:35 +00:00
|
|
|
map_pairwise!(
|
2021-12-10 02:16:18 +00:00
|
|
|
(x, y, i, j, d2, output) -> push_to_verlet_list!(args.verlet_lists, i, j),
|
2021-12-07 03:19:35 +00:00
|
|
|
nothing,
|
|
|
|
args.box,
|
|
|
|
cl;
|
|
|
|
parallel=false,
|
|
|
|
)
|
2021-11-16 21:26:08 +00:00
|
|
|
|
2021-12-07 03:19:35 +00:00
|
|
|
return cl
|
2021-11-10 14:41:04 +00:00
|
|
|
end
|
|
|
|
|
2021-12-12 14:29:08 +00:00
|
|
|
function euler!(
|
2021-12-13 01:24:34 +00:00
|
|
|
args,
|
2021-12-20 23:31:44 +00:00
|
|
|
first_integration_step::Bool,
|
2022-01-11 00:31:30 +00:00
|
|
|
env_helper::Union{RL.EnvHelper,Nothing},
|
2022-01-18 01:17:52 +00:00
|
|
|
state_update_helper_hook!::Function,
|
|
|
|
state_update_hook!::Function,
|
|
|
|
update_table_and_actions_hook!::Function,
|
2021-12-13 01:24:34 +00:00
|
|
|
)
|
2021-12-10 02:16:18 +00:00
|
|
|
for id1 in 1:(args.n_particles - 1)
|
2021-12-08 20:53:15 +00:00
|
|
|
p1 = args.particles[id1]
|
|
|
|
p1_c = p1.c
|
2021-12-10 02:16:18 +00:00
|
|
|
verlet_list = args.verlet_lists[id1]
|
2021-11-10 14:41:04 +00:00
|
|
|
|
2021-12-08 20:53:15 +00:00
|
|
|
for id2 in view(verlet_list.v, 1:(verlet_list.last_ind))
|
|
|
|
p2 = args.particles[id2]
|
2021-11-10 14:41:04 +00:00
|
|
|
|
2021-11-16 21:26:08 +00:00
|
|
|
overlapping, r⃗₁₂, distance² = are_overlapping(
|
2021-12-10 02:16:18 +00:00
|
|
|
p1_c, p2.c, args.interaction_r², args.half_box_len
|
2021-11-16 21:26:08 +00:00
|
|
|
)
|
2021-11-10 14:41:04 +00:00
|
|
|
|
2022-01-18 01:17:52 +00:00
|
|
|
state_update_helper_hook!(env_helper, id1, id2, r⃗₁₂)
|
2021-12-12 17:27:56 +00:00
|
|
|
|
2021-11-10 14:41:04 +00:00
|
|
|
if overlapping
|
2021-12-20 23:31:44 +00:00
|
|
|
factor = args.c₁ / (distance²^4) * (args.c₂ / (distance²^3) - 1.0)
|
|
|
|
dc = factor * r⃗₁₂
|
2021-11-16 21:26:08 +00:00
|
|
|
|
2021-12-07 04:52:10 +00:00
|
|
|
p1.tmp_c -= dc
|
|
|
|
p2.tmp_c += dc
|
2021-11-10 14:41:04 +00:00
|
|
|
end
|
|
|
|
end
|
2021-11-11 00:25:06 +00:00
|
|
|
end
|
2021-11-10 14:41:04 +00:00
|
|
|
|
2022-01-18 01:17:52 +00:00
|
|
|
state_update_hook!(env_helper, args.particles)
|
2021-12-20 23:31:44 +00:00
|
|
|
|
2021-11-11 00:25:06 +00:00
|
|
|
@simd for p in args.particles
|
2021-12-08 20:53:15 +00:00
|
|
|
si, co = sincos(p.φ)
|
|
|
|
p.tmp_c += SVector(
|
2021-12-12 14:29:08 +00:00
|
|
|
args.v₀δt * co + args.c₃ * rand_normal01(),
|
|
|
|
args.v₀δt * si + args.c₃ * rand_normal01(),
|
2021-12-08 20:53:15 +00:00
|
|
|
)
|
2021-11-10 14:41:04 +00:00
|
|
|
|
2021-12-10 02:16:18 +00:00
|
|
|
restrict_coordinates!(p, args.half_box_len)
|
2021-11-10 14:41:04 +00:00
|
|
|
|
2022-01-18 01:17:52 +00:00
|
|
|
update_table_and_actions_hook!(env_helper, p, first_integration_step)
|
2021-12-20 23:31:44 +00:00
|
|
|
|
2022-01-18 01:17:52 +00:00
|
|
|
RL.act_hook!(p, env_helper, args.δt, si, co)
|
2021-12-13 01:24:34 +00:00
|
|
|
|
|
|
|
p.φ += args.c₄ * rand_normal01()
|
2021-12-12 14:29:08 +00:00
|
|
|
|
2021-12-07 04:52:10 +00:00
|
|
|
p.c = p.tmp_c
|
2021-11-10 14:41:04 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
return nothing
|
|
|
|
end
|
|
|
|
|
2022-01-18 01:17:52 +00:00
|
|
|
function Base.wait(::Nothing)
|
|
|
|
return nothing
|
|
|
|
end
|
2021-11-26 13:50:47 +00:00
|
|
|
|
2022-01-18 01:17:52 +00:00
|
|
|
function gen_run_additional_hooks(::Nothing, args...)
|
|
|
|
return false
|
|
|
|
end
|
2021-12-12 17:27:56 +00:00
|
|
|
|
2022-01-11 00:31:30 +00:00
|
|
|
function gen_run_additional_hooks(env_helper::RL.EnvHelper, integration_step::Int64)
|
2022-01-11 17:39:38 +00:00
|
|
|
return (integration_step % env_helper.shared.n_steps_before_actions_update == 0) ||
|
2021-12-14 03:03:14 +00:00
|
|
|
(integration_step == 1)
|
2021-12-12 17:27:56 +00:00
|
|
|
end
|
|
|
|
|
2022-01-18 01:17:52 +00:00
|
|
|
function simulate!(
|
2021-11-16 21:26:08 +00:00
|
|
|
args,
|
2021-11-26 05:55:27 +00:00
|
|
|
T0::Float64,
|
|
|
|
T::Float64,
|
2021-11-10 23:24:07 +00:00
|
|
|
n_steps_before_verlet_list_update::Int64,
|
2021-11-26 05:55:27 +00:00
|
|
|
n_steps_before_snapshot::Int64,
|
|
|
|
n_bundles::Int64,
|
|
|
|
dir::String,
|
|
|
|
save_data::Bool,
|
2022-01-11 00:31:30 +00:00
|
|
|
env_helper::Union{RL.EnvHelper,Nothing},
|
2021-12-12 23:19:18 +00:00
|
|
|
)
|
2021-11-26 05:55:27 +00:00
|
|
|
bundle_snapshot_counter = 0
|
2021-11-16 21:26:08 +00:00
|
|
|
|
2021-12-07 03:19:35 +00:00
|
|
|
task::Union{Task,Nothing} = nothing
|
|
|
|
|
|
|
|
cl = CellList(args.particles_c, args.box; parallel=false)
|
2021-12-10 02:16:18 +00:00
|
|
|
cl = update_verlet_lists!(args, cl)
|
2021-12-07 03:19:35 +00:00
|
|
|
|
2021-12-20 23:31:44 +00:00
|
|
|
first_integration_step = true
|
|
|
|
|
2022-01-18 01:17:52 +00:00
|
|
|
state_update_helper_hook! =
|
|
|
|
state_update_hook! = update_table_and_actions_hook! = empty_hook
|
2021-12-12 14:29:08 +00:00
|
|
|
|
2021-11-10 14:41:04 +00:00
|
|
|
start_time = now()
|
|
|
|
println("Started simulation at $start_time.")
|
|
|
|
|
2021-12-12 23:19:18 +00:00
|
|
|
@showprogress 0.6 for (integration_step, t) in enumerate(T0:(args.δt):T)
|
2021-11-26 05:55:27 +00:00
|
|
|
if (integration_step % n_steps_before_snapshot == 0) && save_data
|
2021-11-26 13:50:47 +00:00
|
|
|
wait(task)
|
2021-12-07 06:08:22 +00:00
|
|
|
|
2021-11-26 05:55:27 +00:00
|
|
|
bundle_snapshot_counter += 1
|
|
|
|
save_snapshot!(args.bundle, bundle_snapshot_counter, t, args.particles)
|
|
|
|
|
|
|
|
if bundle_snapshot_counter == args.n_bundle_snapshots
|
2021-11-26 13:50:47 +00:00
|
|
|
task = @async begin
|
|
|
|
bundle_snapshot_counter = 0
|
|
|
|
n_bundles += 1
|
2021-11-26 05:55:27 +00:00
|
|
|
|
2021-11-26 13:50:47 +00:00
|
|
|
save_bundle(dir, args.bundle, n_bundles, t)
|
|
|
|
end
|
2021-11-26 05:55:27 +00:00
|
|
|
end
|
2021-11-10 14:41:04 +00:00
|
|
|
end
|
|
|
|
|
2021-11-10 23:24:07 +00:00
|
|
|
if integration_step % n_steps_before_verlet_list_update == 0
|
2021-12-10 02:16:18 +00:00
|
|
|
cl = update_verlet_lists!(args, cl)
|
2021-11-10 14:41:04 +00:00
|
|
|
end
|
|
|
|
|
2022-01-11 00:31:30 +00:00
|
|
|
run_additional_hooks = gen_run_additional_hooks(env_helper, integration_step)
|
2021-12-20 23:31:44 +00:00
|
|
|
|
|
|
|
if run_additional_hooks
|
2022-01-18 01:17:52 +00:00
|
|
|
RL.pre_integration_hook!(env_helper)
|
2021-12-12 14:29:08 +00:00
|
|
|
|
2022-01-18 01:17:52 +00:00
|
|
|
state_update_helper_hook! = RL.state_update_helper_hook!
|
|
|
|
state_update_hook! = RL.state_update_hook!
|
|
|
|
update_table_and_actions_hook! = RL.update_table_and_actions_hook!
|
2021-12-12 14:29:08 +00:00
|
|
|
end
|
|
|
|
|
2021-12-20 23:31:44 +00:00
|
|
|
euler!(
|
|
|
|
args,
|
|
|
|
first_integration_step,
|
2022-01-11 00:31:30 +00:00
|
|
|
env_helper,
|
2022-01-18 01:17:52 +00:00
|
|
|
state_update_helper_hook!,
|
|
|
|
state_update_hook!,
|
|
|
|
update_table_and_actions_hook!,
|
2021-12-20 23:31:44 +00:00
|
|
|
)
|
2021-12-12 14:29:08 +00:00
|
|
|
|
2021-12-20 23:31:44 +00:00
|
|
|
if run_additional_hooks
|
2022-01-18 01:17:52 +00:00
|
|
|
state_update_helper_hook! =
|
|
|
|
state_update_hook! = update_table_and_actions_hook! = empty_hook
|
2021-12-12 14:29:08 +00:00
|
|
|
end
|
2021-12-20 23:31:44 +00:00
|
|
|
|
|
|
|
first_integration_step = false
|
2021-11-10 14:41:04 +00:00
|
|
|
end
|
|
|
|
|
2021-12-07 06:08:22 +00:00
|
|
|
wait(task)
|
|
|
|
|
2021-11-26 05:55:27 +00:00
|
|
|
if bundle_snapshot_counter > 0
|
|
|
|
bundle = first_n_snapshots(args.bundle, bundle_snapshot_counter)
|
|
|
|
|
|
|
|
n_bundles += 1
|
|
|
|
|
|
|
|
save_bundle(dir, bundle, n_bundles, T)
|
|
|
|
end
|
|
|
|
|
2021-11-10 14:41:04 +00:00
|
|
|
end_time = now()
|
2021-12-02 22:13:54 +00:00
|
|
|
elapsed_time = Dates.canonicalize(Dates.CompoundPeriod(end_time - start_time))
|
2021-11-18 18:42:11 +00:00
|
|
|
println("Simulation done at $end_time and took $elapsed_time.")
|
2021-11-10 14:41:04 +00:00
|
|
|
|
2021-11-26 05:55:27 +00:00
|
|
|
return nothing
|
2021-11-10 14:41:04 +00:00
|
|
|
end
|