Hello everyone, I have made a MWE for collision problem (2d example) in Agent Based model this based on some of my previous questions. Im using interacting_pairs to find pairs in model and count collision if it finds an agent in some distance ‘d’. Issue at the moment is while increasing resolution of simulation so making dt smaller I see drastic change in collision number. My intuition say that shouldn’t be the case.
You can run this model and check number of collision for different dt values.
using Agents
@agent struct ball(ContinuousAgent{2, Float64})
radius::Float64
mass::Float64
end
mutable struct prop
dt::Float64
collision_count::Int64
end
function model_step!(model)
d = 2*model[1].radius
for (a1, a2) in interacting_pairs(model, d, :nearest)
model.collision_count += 1
elastic_collision!(a1, a2, :mass)
end
end
function agent_step!(agent, model)
xx, xy = agent.pos
vx, vy = agent.vel
if xx ≥ 9.99
vx > 0.0 && (vx = -vx)
xx = 9.99
end
if xx ≤ min_dim
vx < 0.0 && (vx = -vx)
xx = min_dim
end
if xy ≥ 0.99
vy > 0.0 && (vy = -vy)
xy = 0.99
end
if xy ≤ min_dim
vy < 0.0 && (vy = -vy)
xy = min_dim
end
agent.pos = SVector(xx, xy)
agent.vel = SVector(vx, vy)
move_agent!(agent, model, model.dt)
end
using Random: Xoshiro
rng = Xoshiro(42)
function ball_model(;
number_of_particles=100,
sides=SVector(10.0, 1.0),
dt=dt,
collision_count = 0,
speed = speed
)
# initial random positions
positions = [sides .* rand(SVector{2,Float64}) for _ in 1:number_of_particles]
properties = prop(dt, collision_count)
# Space and agents
space2d = ContinuousSpace(sides; periodic=true)
model = StandardABM(ball, space2d, agent_step! = agent_step!,
model_step! = model_step!, properties = properties,
rng = rng)
# Create active agents
for id in 1:number_of_particles
pos = positions[id]
radius = 0.1
vel = speed * randn(SVector{2}) # initial velocities)
mass = 1
add_agent!(pos, model, vel, radius, mass)
end
return model
end
model = ball_model(speed = 0.2, dt = 0.01)
# abmqueue(model)
min_dim = 0.01
step = 5 / model.dt
adf, mdf = run!(model, step; mdata = [:collision_count], init = true, when = (model, t) -> true, showprogress = false)