1
0
Fork 0
mirror of https://gitlab.rlp.net/mobitar/ReCo.jl.git synced 2024-09-19 19:01:17 +00:00
ReCo.jl/src/simulation.jl

182 lines
4.6 KiB
Julia
Raw Normal View History

2021-12-07 03:19:35 +00:00
using Dates: Dates, now
2021-12-02 22:13:54 +00:00
using ProgressMeter: @showprogress
using Distributions: Normal
2021-12-07 03:19:35 +00:00
using CellListMap: Box, CellList, map_pairwise!, UpdateCellList!
2021-12-07 04:52:10 +00:00
using StaticArrays: SVector
2021-12-07 03:19:35 +00:00
2021-12-02 22:13:54 +00:00
import Base: wait
2021-11-10 14:41:04 +00:00
rand_normal01() = rand(Normal(0, 1))
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,
state_hook::Function,
integration_hook::Function,
rl_params::Union{RL.Params,Nothing},
)
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
2021-12-12 17:27:56 +00:00
state_hook(id1, id2, r⃗₁₂, distance², rl_params)
2021-11-10 14:41:04 +00:00
if overlapping
2021-12-08 20:53:15 +00:00
c = args.c₁ / (distance²^4) * (args.c₂ / (distance²^3) - 1.0)
2021-11-16 21:26:08 +00:00
2021-12-07 04:52:10 +00:00
dc = c * r⃗₁₂
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
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
2021-12-13 01:24:34 +00:00
integration_hook(p, rl_params, args.δt, si, co)
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
2021-12-12 14:29:08 +00:00
wait(::Nothing) = nothing
2021-11-26 13:50:47 +00:00
2021-12-12 17:27:56 +00:00
gen_run_hooks(::Nothing, args...) = false
2021-12-12 23:19:18 +00:00
function gen_run_hooks(rl_params::RL.Params, integration_step::Int64)
return (integration_step == 1) ||
2021-12-12 17:27:56 +00:00
(integration_step % rl_params.n_steps_before_actions_update == 0)
end
2021-11-16 21:26:08 +00:00
function simulate(
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,
2021-12-12 23:19:18 +00:00
rl_params::Union{RL.Params,Nothing},
pre_integration_hook!::Function,
integration_hook::Function,
post_integration_hook::Function,
)
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-12 17:27:56 +00:00
run_hooks = false
state_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
2021-12-12 17:27:56 +00:00
run_hooks = gen_run_hooks(rl_params, integration_step)
2021-12-12 14:29:08 +00:00
2021-12-12 17:27:56 +00:00
if run_hooks
pre_integration_hook!(rl_params, args.n_particles)
2021-12-12 23:19:18 +00:00
state_hook = RL.state_hook
2021-12-12 14:29:08 +00:00
end
2021-12-12 23:19:18 +00:00
euler!(args, state_hook, integration_hook, rl_params)
2021-12-12 14:29:08 +00:00
2021-12-12 17:27:56 +00:00
if run_hooks
2021-12-13 01:24:34 +00:00
post_integration_hook(
rl_params, args.n_particles, args.particles, args.half_box_len
)
2021-12-12 17:27:56 +00:00
state_hook = empty_hook
2021-12-12 14:29:08 +00:00
end
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