1
0
Fork 0
mirror of https://gitlab.rlp.net/mobitar/ReCo.jl.git synced 2024-12-21 00:51:21 +00:00
ReCo.jl/src/simulation.jl
2022-09-25 15:54:46 +02:00

205 lines
5.5 KiB
Julia
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Distributions: Normal
using ProgressMeter: ProgressMeter
using StaticArrays: SVector
using CellListMap: CellListMap
function rand_normal01()
return rand(Normal(0, 1))
end
function push_to_verlet_list!(verlet_lists, i, j)
if i < j
push!(verlet_lists[i], Int64(j))
else
push!(verlet_lists[j], Int64(i))
end
return nothing
end
function update_verlet_lists!(args, cl::CellListMap.CellList)
@simd for pre_vec in args.verlet_lists
reset!(pre_vec)
end
@simd for i in 1:(args.n_particles)
args.particles_c[i] = args.particles[i].c
end
cl = CellListMap.UpdateCellList!(args.particles_c, args.box, cl; parallel=false)
CellListMap.map_pairwise!(
(x, y, i, j, d2, output) -> push_to_verlet_list!(args.verlet_lists, i, j),
nothing,
args.box,
cl;
parallel=false,
)
return cl
end
function euler!(
args,
first_integration_step::Bool,
env_helper::Union{RL.EnvHelper,Nothing},
state_update_helper_hook!::Function,
state_update_hook!::Function,
update_table_and_actions_hook!::Function,
)
for id1 in 1:(args.n_particles - 1)
p1 = args.particles[id1]
p1_c = p1.c
verlet_list = args.verlet_lists[id1]
for id2 in view(verlet_list.v, 1:(verlet_list.last_ind))
p2 = args.particles[id2]
overlapping, r⃗₁₂, distance² = are_overlapping(
p1_c, p2.c, args.interaction_radius², args.half_box_len
)
state_update_helper_hook!(env_helper, id1, id2, r⃗₁₂, distance²)
if overlapping
factor = args.ϵσ⁶δtμₜ24 / (distance²^4) * (1.0 - args.σ⁶2 / (distance²^3))
μₜF⃗₁₂ = factor * r⃗₁₂ # Force acting on 1 from 2 multiplied with μₜ
p1.tmp_c += μₜF⃗₁₂
p2.tmp_c -= μₜF⃗₁₂
end
end
end
RL.copy_states_to_old_states_hook!(env_helper)
state_update_hook!(env_helper, args.particles)
@simd for p in args.particles
si, co = sincos(p.φ)
p.tmp_c += SVector(
args.v₀δt * co + args.sqrt_Dₜδt2 * rand_normal01(),
args.v₀δt * si + args.sqrt_Dₜδt2 * rand_normal01(),
)
restrict_coordinates!(p, args.half_box_len)
update_table_and_actions_hook!(env_helper, p, first_integration_step)
RL.act_hook!(p, env_helper, args.δt, si, co)
p.φ += args.sqrt_Dᵣδt2 * rand_normal01()
p.c = p.tmp_c
end
return nothing
end
function Base.wait(::Nothing)
return nothing
end
function gen_run_additional_hooks(::Nothing, args...)
return false
end
function gen_run_additional_hooks(env_helper::RL.EnvHelper, integration_step::Int64)
return (integration_step % env_helper.shared.n_steps_before_actions_update == 0) ||
(integration_step == 1)
end
function gen_cell_list(particles_c::Vector{SVector{2,Float64}}, box::CellListMap.Box)
return CellListMap.CellList(particles_c, box; parallel=false)
end
function simulate!(
args,
T0::Float64,
T::Float64,
n_steps_before_verlet_list_update::Int64,
n_steps_before_snapshot::Int64,
n_bundles::Int64,
sim_dir::String,
save_data::Bool,
env_helper::Union{RL.EnvHelper,Nothing},
)
bundle_snapshot_counter = 0
task::Union{Task,Nothing} = nothing
cl = gen_cell_list(args.particles_c, args.box)
cl = update_verlet_lists!(args, cl)
first_integration_step = true
state_update_helper_hook! =
state_update_hook! = update_table_and_actions_hook! = empty_hook
time_range = T0:(args.δt):T
progress = ProgressMeter.Progress(
length(time_range); dt=2, enabled=args.show_progress, desc="Simulation: "
)
for (integration_step, t) in enumerate(time_range)
if (integration_step % n_steps_before_snapshot == 0) && save_data
wait(task)
bundle_snapshot_counter += 1
save_snapshot!(args.bundle, bundle_snapshot_counter, t, args.particles)
if bundle_snapshot_counter == args.n_bundle_snapshots
task = @async begin
bundle_snapshot_counter = 0
n_bundles += 1
save_bundle(sim_dir, args.bundle, n_bundles, t)
end
end
end
if integration_step % n_steps_before_verlet_list_update == 0
cl = update_verlet_lists!(args, cl)
end
run_additional_hooks = gen_run_additional_hooks(env_helper, integration_step)
if run_additional_hooks
RL.pre_integration_hook!(env_helper)
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!
end
euler!(
args,
first_integration_step,
env_helper,
state_update_helper_hook!,
state_update_hook!,
update_table_and_actions_hook!,
)
if run_additional_hooks
state_update_helper_hook! =
state_update_hook! = update_table_and_actions_hook! = empty_hook
end
first_integration_step = false
ProgressMeter.next!(progress)
end
wait(task)
if bundle_snapshot_counter > 0
bundle = first_n_snapshots(args.bundle, bundle_snapshot_counter)
n_bundles += 1
save_bundle(sim_dir, bundle, n_bundles, T)
end
return nothing
end