mirror of
https://gitlab.rlp.net/mobitar/ReCo.jl.git
synced 2024-09-19 19:01:17 +00:00
109 lines
2.7 KiB
Julia
109 lines
2.7 KiB
Julia
|
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)
|
||
|
for j in (i + 1):args.N
|
||
|
p1 = args.particles[i]
|
||
|
p2 = args.particles[j]
|
||
|
|
||
|
overlapping, r⃗₁₂, distance² = are_overlapping(p1, p2, args.skin_r², args.l)
|
||
|
|
||
|
if overlapping
|
||
|
push!(args.verlet_list[i], j)
|
||
|
push!(args.verlet_list[j], i)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function euler!(args)
|
||
|
Threads.@threads for p in args.particles
|
||
|
verlet_list = args.verlet_list[p.id]
|
||
|
|
||
|
for i in 1:verlet_list.last_ind
|
||
|
p2 = args.particles[verlet_list.v[i]]
|
||
|
|
||
|
overlapping, r⃗₁₂, distance² = are_overlapping(p, p2, args.interaction_r², args.l)
|
||
|
|
||
|
if overlapping
|
||
|
c = args.c₁ / (distance²^4) * (args.c₂ / (distance²^3) - 1)
|
||
|
@simd for j in 1:2
|
||
|
p.tmp_c[j] -= c * r⃗₁₂[j]
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
e = SVector(cos(p.φ), sin(p.φ))
|
||
|
|
||
|
@simd 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; l=args.l)
|
||
|
end
|
||
|
|
||
|
@simd for particle in args.particles
|
||
|
update!(particle)
|
||
|
end
|
||
|
|
||
|
return nothing
|
||
|
end
|
||
|
|
||
|
function simulate(args, save_at::Float64, δt::Float64, T::Float64, n_steps_before_verlet_list_update::Int64)
|
||
|
sol = Solution(args.N, args.n_frames)
|
||
|
save_timer = save_at
|
||
|
frame = 0
|
||
|
|
||
|
start_time = now()
|
||
|
println("Started simulation at $start_time.")
|
||
|
|
||
|
update_verlet_list_at = n_steps_before_verlet_list_update * δt
|
||
|
update_verlet_list_timer = update_verlet_list_at
|
||
|
|
||
|
@showprogress 0.2 for t in 0:δt:T
|
||
|
if save_timer >= save_at
|
||
|
frame += 1
|
||
|
|
||
|
sol.t[frame] = t
|
||
|
|
||
|
@simd for p in args.particles
|
||
|
p_id = p.id
|
||
|
|
||
|
pre_pos = sol.position[p_id, frame]
|
||
|
|
||
|
@simd for i in 1:2
|
||
|
pre_pos[i] = p.c[i]
|
||
|
end
|
||
|
|
||
|
sol.φ[p_id, frame] = p.φ
|
||
|
end
|
||
|
|
||
|
save_timer = 0.0
|
||
|
else
|
||
|
save_timer += δt
|
||
|
end
|
||
|
|
||
|
if update_verlet_list_timer >= update_verlet_list_at
|
||
|
update_verlet_list!(args)
|
||
|
|
||
|
update_verlet_list_timer = 0.0
|
||
|
else
|
||
|
update_verlet_list_timer += δt
|
||
|
end
|
||
|
|
||
|
euler!(args)
|
||
|
end
|
||
|
|
||
|
end_time = now()
|
||
|
elapsed_time = canonicalize(CompoundPeriod(end_time - start_time))
|
||
|
println("Done simulation at $end_time and took $elapsed_time.")
|
||
|
|
||
|
return (sol, end_time)
|
||
|
end
|