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
2021-12-07 01:52:34 +01:00

128 lines
3.1 KiB
Julia

using ProgressMeter: @showprogress
using LoopVectorization: @turbo
using Distributions: Normal
using Dates: Dates, now
import Base: wait
rand_normal01() = rand(Normal(0, 1))
function update_verlet_list!(args)
@simd for pv in args.verlet_list
reset!(pv)
end
for i in 1:(args.N - 1)
p1 = args.particles[i]
for j in (i + 1):(args.N)
p2 = args.particles[j]
overlapping = are_overlapping(p1, p2, args.skin_r², args.l).overlapping
if overlapping
push!(args.verlet_list[i], j)
end
end
end
return nothing
end
function euler!(args)
for i in 1:(args.N - 1)
p1 = args.particles[i]
verlet_list = args.verlet_list[p1.id]
for j in 1:(verlet_list.last_ind)
p2 = args.particles[verlet_list.v[j]]
overlapping, r⃗₁₂, distance² = are_overlapping(
p1, p2, args.interaction_r², args.l
)
if overlapping
c = args.c₁ / (distance²^4) * (args.c₂ / (distance²^3) - 1)
@turbo for k in 1:2
dc = c * r⃗₁₂[k]
p1.tmp_c[k] -= dc
p2.tmp_c[k] += dc
end
end
end
end
@simd for p in args.particles
e = SVector(cos(p.φ), sin(p.φ))
@turbo for i in 1:2
p.tmp_c[i] += args.vδt * e[i] + args.c₃ * rand_normal01()
end
p.φ += args.c₄ * rand_normal01()
restrict_coordinates!(p, args.l)
update!(p)
end
return nothing
end
wait(n::Nothing) = n
function simulate(
args,
δt::Float64,
T0::Float64,
T::Float64,
n_steps_before_verlet_list_update::Int64,
n_steps_before_snapshot::Int64,
n_bundles::Int64,
dir::String,
save_data::Bool,
)
bundle_snapshot_counter = 0
start_time = now()
println("Started simulation at $start_time.")
task::Union{Task,Nothing} = nothing
@showprogress 0.6 for (integration_step, t) in enumerate(T0:δt:T)
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(dir, args.bundle, n_bundles, t)
end
end
end
if integration_step % n_steps_before_verlet_list_update == 0
update_verlet_list!(args)
end
euler!(args)
end
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
end_time = now()
elapsed_time = Dates.canonicalize(Dates.CompoundPeriod(end_time - start_time))
println("Simulation done at $end_time and took $elapsed_time.")
return nothing
end