using Random: Random using JSON3: JSON3 using JLD2: JLD2 using StaticArrays: SVector empty_hook(args...) = nothing function run_sim( dir::String; duration::Float64, snapshot_at::Float64=0.1, seed::Int64=42, n_bundle_snapshots::Int64=100, rl_params::Union{ReCo.Params,Nothing}=nothing, ) @assert length(dir) > 0 @assert duration > 0 @assert snapshot_at in 0.001:0.001:duration @assert duration % snapshot_at == 0 @assert seed > 0 @assert n_bundle_snapshots >= 0 Random.seed!(seed) sim_consts = JSON3.read(read("$dir/sim_consts.json", String)) integration_steps = floor(Int64, duration / sim_consts.δt) + 1 n_steps_before_snapshot = round(Int64, snapshot_at / sim_consts.δt) n_snapshots = floor(Int64, integration_steps / n_steps_before_snapshot) + 1 n_bundle_snapshots = min(n_snapshots, n_bundle_snapshots) sim_state = JSON3.read(read("$dir/sim_state.json", String)) n_bundles = sim_state.n_bundles T0::Float64 = sim_state.T T = T0 + duration if n_bundle_snapshots > 0 save_data = true else save_data = false end @async begin start_datetime = now() run_params = (; # Input duration, snapshot_at, seed, n_bundle_snapshots, # Calculated integration_steps, n_steps_before_snapshot, n_snapshots, T, # Read T0, start_datetime, ) next_bundle = n_bundles + 1 runs_dir = "$dir/runs" if save_data write_struct_to_json(run_params, "$runs_dir/run_params_$next_bundle") end end bundles_dir = "$dir/bundles" bundle = JLD2.load_object("$bundles_dir/bundle_$n_bundles.jld2") particles = gen_particles(bundle, sim_consts.n_particles) args = ( v₀=sim_consts.v₀, δt=sim_consts.δt, skin_r=sim_consts.skin_r, skin_r²=sim_consts.skin_r^2, n_snapshots=n_snapshots, c₁=4 * sim_consts.ϵ * 6 * sim_consts.σ^6 * sim_consts.δt * sim_consts.μ, c₂=2 * sim_consts.σ^6, c₃=sqrt(2 * sim_consts.D₀ * sim_consts.δt), c₄=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, n_particles=sim_consts.n_particles, half_box_len=sim_consts.half_box_len, particles=particles, particles_c=[particles[i].c for i in 1:(sim_consts.n_particles)], verlet_lists=[ PreVector{Int64}(sim_consts.n_particles - i) for i in 1:(sim_consts.n_particles - 1) ], n_bundle_snapshots=n_bundle_snapshots, bundle=Bundle(sim_consts.n_particles, n_bundle_snapshots), box=Box( SVector(2 * sim_consts.half_box_len, 2 * sim_consts.half_box_len), sim_consts.skin_r, ), ) if !isnothing(rl_params) pre_integration_hook! = ReCoRL.pre_integration_hook integration_hook = ReCoRL.integration_hook post_integration_hook = ReCoRL.post_integration_hook else pre_integration_hook! = empty_hook integration_hook = empty_hook post_integration_hook = empty_hook end simulate( args, sim_consts.δt, T0, T, sim.consts.n_steps_before_verlet_list_update, n_steps_before_snapshot, n_bundles, dir, save_data, rl_params, pre_integration_hook!, integration_hook, post_integration_hook, ) return nothing end