mirror of
https://gitlab.rlp.net/mobitar/ReCo.jl.git
synced 2024-11-08 22:21:08 +00:00
SVector
This commit is contained in:
parent
2a052cb205
commit
389f99221b
8 changed files with 34 additions and 68 deletions
|
@ -1,16 +1,15 @@
|
||||||
using StaticArrays: SVector
|
using StaticArrays: SVector
|
||||||
using LoopVectorization: @turbo
|
|
||||||
|
|
||||||
mutable struct Particle
|
mutable struct Particle
|
||||||
id::Int64
|
id::Int64
|
||||||
|
|
||||||
c::Vector{Float64} # Center
|
c::SVector{2,Float64} # Center
|
||||||
tmp_c::Vector{Float64} # Temporary center
|
tmp_c::SVector{2,Float64} # Temporary center
|
||||||
|
|
||||||
φ::Float64 # Angle
|
φ::Float64 # Angle
|
||||||
|
|
||||||
function Particle(id::Int64, c::Vector{Float64}, φ::Float64)
|
function Particle(id::Int64, c::SVector{2,Float64}, φ::Float64)
|
||||||
return new(id, c, copy(c), φ)
|
return new(id, c, c, φ)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -25,9 +24,7 @@ function restrict_coordinate(value::Float64, l::Float64)
|
||||||
end
|
end
|
||||||
|
|
||||||
function restrict_coordinates!(p::Particle, l::Float64)
|
function restrict_coordinates!(p::Particle, l::Float64)
|
||||||
@simd for i in 1:2
|
p.tmp_c = SVector{2}(restrict_coordinate(p.tmp_c[i], l) for i in 1:2)
|
||||||
p.tmp_c[i] = restrict_coordinate(p.tmp_c[i], l)
|
|
||||||
end
|
|
||||||
|
|
||||||
return nothing
|
return nothing
|
||||||
end
|
end
|
||||||
|
@ -43,11 +40,11 @@ function minimum_image_coordinate(value::Float64, l::Float64)
|
||||||
end
|
end
|
||||||
|
|
||||||
function minimum_image(v::SVector{2,Float64}, l::Float64)
|
function minimum_image(v::SVector{2,Float64}, l::Float64)
|
||||||
return SVector(minimum_image_coordinate(v[1], l), minimum_image_coordinate(v[2], l))
|
return SVector{2}(minimum_image_coordinate(v[i], l) for i in 1:2)
|
||||||
end
|
end
|
||||||
|
|
||||||
function are_overlapping(p1::Particle, p2::Particle, overlapping_r²::Float64, l::Float64)
|
function are_overlapping(p1::Particle, p2::Particle, overlapping_r²::Float64, l::Float64)
|
||||||
r⃗₁₂ = SVector(p2.c[1] - p1.c[1], p2.c[2] - p1.c[2]) # 1 -> 2
|
r⃗₁₂ = p2.c - p1.c # 1 -> 2
|
||||||
|
|
||||||
r⃗₁₂ = minimum_image(r⃗₁₂, l)
|
r⃗₁₂ = minimum_image(r⃗₁₂, l)
|
||||||
|
|
||||||
|
@ -57,11 +54,3 @@ function are_overlapping(p1::Particle, p2::Particle, overlapping_r²::Float64, l
|
||||||
|
|
||||||
return (; overlapping, r⃗₁₂, distance²)
|
return (; overlapping, r⃗₁₂, distance²)
|
||||||
end
|
end
|
||||||
|
|
||||||
function update!(p::Particle)
|
|
||||||
@turbo for i in 1:2
|
|
||||||
p.c[i] = p.tmp_c[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
return nothing
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using CairoMakie, LaTeXStrings
|
using CairoMakie, LaTeXStrings
|
||||||
using StaticArrays
|
using StaticArrays
|
||||||
using LoopVectorization: @tturbo
|
using LoopVectorization: @turbo
|
||||||
|
|
||||||
using ReCo: minimum_image
|
using ReCo: minimum_image
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ function pair_correlation(sol, variables)
|
||||||
c1 = sol.center[i, frame]
|
c1 = sol.center[i, frame]
|
||||||
c2 = sol.center[j, frame]
|
c2 = sol.center[j, frame]
|
||||||
|
|
||||||
r⃗₁₂ = SVector(c1[1] - c2[1], c1[2] - c2[2])
|
r⃗₁₂ = c1 - c2
|
||||||
|
|
||||||
r⃗₁₂ = minimum_image(r⃗₁₂, variables.l)
|
r⃗₁₂ = minimum_image(r⃗₁₂, variables.l)
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ function pair_correlation(sol, variables)
|
||||||
r = radius[r_ind]
|
r = radius[r_ind]
|
||||||
tmp_g = 0.0
|
tmp_g = 0.0
|
||||||
|
|
||||||
@tturbo for i in 1:(variables.N)
|
@turbo for i in 1:(variables.N)
|
||||||
tmp_g += N_g[i, r_ind]
|
tmp_g += N_g[i, r_ind]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ function animate_bundle!(args)
|
||||||
|
|
||||||
for frame in 1:length(bundle_t)
|
for frame in 1:length(bundle_t)
|
||||||
@simd for i in 1:(args.N)
|
@simd for i in 1:(args.N)
|
||||||
args.circles[][i] = Circle(Point2(bundle_c[i, frame]), args.particle_radius)
|
c = bundle_c[i, frame]
|
||||||
|
args.circles[][i] = Circle(Point2(c[1], c[2]), args.particle_radius)
|
||||||
|
|
||||||
color = get(args.color_scheme, rem2pi(bundle_φ[i, frame], RoundDown) / π2)
|
color = get(args.color_scheme, rem2pi(bundle_φ[i, frame], RoundDown) / π2)
|
||||||
args.colors[][i] = RGBAf(color)
|
args.colors[][i] = RGBAf(color)
|
||||||
|
|
23
src/data.jl
23
src/data.jl
|
@ -1,18 +1,17 @@
|
||||||
using StaticArrays: SVector
|
using StaticArrays: SVector
|
||||||
using LoopVectorization: @turbo
|
|
||||||
using JLD2: JLD2
|
using JLD2: JLD2
|
||||||
|
|
||||||
struct Bundle
|
struct Bundle
|
||||||
t::Vector{Float64}
|
t::Vector{Float64}
|
||||||
c::Matrix{Vector{Float64}}
|
c::Matrix{SVector{2,Float64}}
|
||||||
φ::Matrix{Float64}
|
φ::Matrix{Float64}
|
||||||
end
|
end
|
||||||
|
|
||||||
function Bundle(N::Int64, n_snapshots::Int64)
|
function Bundle(N::Int64, n_snapshots::Int64)
|
||||||
return Bundle(
|
return Bundle(
|
||||||
zeros(n_snapshots),
|
Vector{Float64}(undef, n_snapshots),
|
||||||
[zeros(2) for i in 1:N, j in 1:n_snapshots],
|
Matrix{SVector{2,Float64}}(undef, (N, n_snapshots)),
|
||||||
zeros(N, n_snapshots),
|
Matrix{Float64}(undef, (N, n_snapshots)),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -25,20 +24,10 @@ function save_snapshot!(
|
||||||
)
|
)
|
||||||
bundle.t[n_snapshot] = t
|
bundle.t[n_snapshot] = t
|
||||||
|
|
||||||
bundle_c = bundle.c
|
|
||||||
bundle_φ = bundle.φ
|
|
||||||
|
|
||||||
@simd for p in particles
|
@simd for p in particles
|
||||||
p_id = p.id
|
bundle.c[p.id, n_snapshot] = p.c
|
||||||
p_c = p.c
|
|
||||||
|
|
||||||
bundle_c_id = bundle_c[p_id, n_snapshot]
|
bundle.φ[p.id, n_snapshot] = p.φ
|
||||||
|
|
||||||
@turbo for j in 1:2
|
|
||||||
bundle_c_id[j] = p_c[j]
|
|
||||||
end
|
|
||||||
|
|
||||||
bundle_φ[p_id, n_snapshot] = p.φ
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return nothing
|
return nothing
|
||||||
|
|
|
@ -43,11 +43,6 @@ function run_sim(
|
||||||
|
|
||||||
particles = generate_particles(bundle, sim_consts.N)
|
particles = generate_particles(bundle, sim_consts.N)
|
||||||
|
|
||||||
particles_c = [SVector(0.0, 0.0) for i in 1:(sim_consts.N)]
|
|
||||||
for i in 1:(sim_consts.N)
|
|
||||||
particles_c[i] = SVector(particles[i].c[1], particles[i].c[2])
|
|
||||||
end
|
|
||||||
|
|
||||||
args = (
|
args = (
|
||||||
v=sim_consts.v,
|
v=sim_consts.v,
|
||||||
skin_r=skin_r,
|
skin_r=skin_r,
|
||||||
|
@ -65,7 +60,7 @@ function run_sim(
|
||||||
l=sim_consts.l,
|
l=sim_consts.l,
|
||||||
particle_diameter=sim_consts.particle_diameter,
|
particle_diameter=sim_consts.particle_diameter,
|
||||||
particles=particles,
|
particles=particles,
|
||||||
particles_c=particles_c,
|
particles_c=[particles[i].c for i in 1:(sim_consts.N)],
|
||||||
verlet_list=[PreVector{Int64}(sim_consts.N - 1) for i in 1:(sim_consts.N - 1)],
|
verlet_list=[PreVector{Int64}(sim_consts.N - 1) for i in 1:(sim_consts.N - 1)],
|
||||||
n_bundle_snapshots=n_bundle_snapshots,
|
n_bundle_snapshots=n_bundle_snapshots,
|
||||||
bundle=Bundle(sim_consts.N, n_bundle_snapshots),
|
bundle=Bundle(sim_consts.N, n_bundle_snapshots),
|
||||||
|
|
|
@ -4,7 +4,7 @@ using JSON3: JSON3
|
||||||
|
|
||||||
function initial_particle_grid_pos(i::Int64, j::Int64, grid_box_width::Float64, l::Float64)
|
function initial_particle_grid_pos(i::Int64, j::Int64, grid_box_width::Float64, l::Float64)
|
||||||
term = -0.5 * grid_box_width - l
|
term = -0.5 * grid_box_width - l
|
||||||
return [k * grid_box_width + term for k in (i, j)]
|
return SVector{2}(k * grid_box_width + term for k in (i, j))
|
||||||
end
|
end
|
||||||
|
|
||||||
function generate_particles(grid_n::Int64, grid_box_width::Float64, l::Float64)
|
function generate_particles(grid_n::Int64, grid_box_width::Float64, l::Float64)
|
||||||
|
@ -28,7 +28,7 @@ end
|
||||||
function generate_particles(bundle::Bundle, N::Int64)
|
function generate_particles(bundle::Bundle, N::Int64)
|
||||||
particles = Vector{Particle}(undef, N)
|
particles = Vector{Particle}(undef, N)
|
||||||
|
|
||||||
for id in 1:N
|
@simd for id in 1:N
|
||||||
particles[id] = Particle(id, bundle.c[id, end], bundle.φ[id, end])
|
particles[id] = Particle(id, bundle.c[id, end], bundle.φ[id, end])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ function project_back_from_unit_circle(θ, l)
|
||||||
end
|
end
|
||||||
|
|
||||||
function center_of_mass(args)
|
function center_of_mass(args)
|
||||||
x_proj_sum = SVector(0, 0)
|
x_proj_sum = SVector(0.0, 0.0)
|
||||||
y_proj_sum = SVector(0, 0)
|
y_proj_sum = SVector(0.0, 0.0)
|
||||||
|
|
||||||
for p in args.particles
|
for p in args.particles
|
||||||
x_proj_sum += project_to_unit_circle(p.c[1], args.l)
|
x_proj_sum += project_to_unit_circle(p.c[1], args.l)
|
||||||
|
@ -37,10 +37,7 @@ function center_of_mass(args)
|
||||||
y_θ = atan(y_proj_sum[2], y_proj_sum[1])
|
y_θ = atan(y_proj_sum[2], y_proj_sum[1])
|
||||||
end
|
end
|
||||||
|
|
||||||
return SVector(
|
return SVector{2}(project_back_from_unit_circle(θ, args.l) for θ in (x_θ, y_θ))
|
||||||
project_back_from_unit_circle(x_θ, args.l),
|
|
||||||
project_back_from_unit_circle(y_θ, args.l),
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function gyration_tensor(args)
|
function gyration_tensor(args)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
using Dates: Dates, now
|
using Dates: Dates, now
|
||||||
using ProgressMeter: @showprogress
|
using ProgressMeter: @showprogress
|
||||||
using LoopVectorization: @turbo
|
|
||||||
using Distributions: Normal
|
using Distributions: Normal
|
||||||
using CellListMap: Box, CellList, map_pairwise!, UpdateCellList!
|
using CellListMap: Box, CellList, map_pairwise!, UpdateCellList!
|
||||||
|
using StaticArrays: SVector
|
||||||
|
|
||||||
import Base: wait
|
import Base: wait
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ function update_verlet_list!(args, cl)
|
||||||
reset!(pv)
|
reset!(pv)
|
||||||
end
|
end
|
||||||
|
|
||||||
for i in 1:(args.N)
|
@simd for i in 1:(args.N)
|
||||||
args.particles_c[i] = SVector(args.particles[i].c[1], args.particles[i].c[2])
|
args.particles_c[i] = args.particles[i].c
|
||||||
end
|
end
|
||||||
|
|
||||||
cl = UpdateCellList!(args.particles_c, args.box, cl; parallel=false)
|
cl = UpdateCellList!(args.particles_c, args.box, cl; parallel=false)
|
||||||
|
@ -55,28 +55,23 @@ function euler!(args)
|
||||||
if overlapping
|
if overlapping
|
||||||
c = args.c₁ / (distance²^4) * (args.c₂ / (distance²^3) - 1)
|
c = args.c₁ / (distance²^4) * (args.c₂ / (distance²^3) - 1)
|
||||||
|
|
||||||
@turbo for k in 1:2
|
dc = c * r⃗₁₂
|
||||||
dc = c * r⃗₁₂[k]
|
p1.tmp_c -= dc
|
||||||
|
p2.tmp_c += dc
|
||||||
p1.tmp_c[k] -= dc
|
|
||||||
p2.tmp_c[k] += dc
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@simd for p in args.particles
|
@simd for p in args.particles
|
||||||
e = SVector(cos(p.φ), sin(p.φ))
|
p.tmp_c +=
|
||||||
|
args.vδt * SVector(cos(p.φ), sin(p.φ)) +
|
||||||
@turbo for i in 1:2
|
args.c₃ * SVector(rand_normal01(), rand_normal01())
|
||||||
p.tmp_c[i] += args.vδt * e[i] + args.c₃ * rand_normal01()
|
|
||||||
end
|
|
||||||
|
|
||||||
p.φ += args.c₄ * rand_normal01()
|
p.φ += args.c₄ * rand_normal01()
|
||||||
|
|
||||||
restrict_coordinates!(p, args.l)
|
restrict_coordinates!(p, args.l)
|
||||||
|
|
||||||
update!(p)
|
p.c = p.tmp_c
|
||||||
end
|
end
|
||||||
|
|
||||||
return nothing
|
return nothing
|
||||||
|
|
Loading…
Reference in a new issue