Microscopic models : granular and social force model¶

cromosim.micro.
add_people_in_box
(Np, dom, xmin, xmax, ymin, ymax, rmin, rmax, rng)[source]¶ Adds new persons in the box [xmin,xmax]x[ymin,ymax] Be careful : overlaps can occur…
 Parameters
 Np: int
Number of persons
 dom: Domain
contains everything for managing the domain
 xmin: float
minimal abscissa of the box
 xmaxfloat
maximal abscissa of the box
 ymin: float
minimal ordinate of the box
 ymax: float
maximal ordinate of the box
 rmin: float
minimum radius for the individuals
 rmax: float
maximum radius for the individuals
 rng: scipy.random.RandomState
container for the Mersenne Twister pseudorandom number generator
 Returns
 ——
 peoplenumpy array
people coordinates and radius

cromosim.micro.
check_people_in_box
(dom, box, p, rng)[source]¶ To check that people coordinates are in the given box (test 1) and in an usable space i.e. in an area accessible and not concerned by obstacles (test 2). On the other hand, one moves the individuals which do not satisfy these two tests.
 Parameters
 dom: Domain
contains everything for managing the domain
 box: list
coordinates of the box [xmin, xmax, ymin, ymax]
 p: numpy array
people coordinates x y r
 rng: RandomState
scipy random state object (see scipy.random.RandomState)
 Returns
 p: numpy array
new people coordinates x y r

cromosim.micro.
compute_contacts
(dom, people, dmax)[source]¶ This function uses a KDTree method to find the contacts between individuals. Moreover the contacts with the walls are also determined from the wall distance (obtained by the fastmarching method).
 Parameters
 dom: Domain
contains everything for managing the domain
 people: numpy array
people coordinates and radius : x,y,r
 dmax: float
threshold value used to consider a contact as active (dij<dmax)
 Returns
 contacts: numpy array
all the contacts i,j,dij,eij_x,eij_y such that dij<dmax and i<j (no duplication)

cromosim.micro.
compute_desired_velocity
(dom, people)[source]¶ This function determines people desired velocities from the desired velocity array computed by Domain thanks to a fastmarching method.
 Parameters
 dom: Domain
contains everything for managing the domain
 people: numpy array
people coordinates and radius : x,y,r
 Returns
 Inumpy array
people index i
 Jnumpy array
people index j
 Vdnumpy array
people desired velocity

cromosim.micro.
compute_forces
(F, Fwall, people, contacts, U, Vd, lambda_, delta, k, eta)[source]¶ This function computes all the forces (isentropic interaction and friction) and sums them. The correcting prefactor due to the vision angle is also used into the social force term.
 Parameters
 F: float
social trend of an individual to keep apart from another (homogeneous to a force)
 Fwall: float
social trend of an individual to keep apart from a wall (homogeneous to a force)
 people: numpy array
people coordinates and radius : x,y,r
 contacts: numpy array
all the contacts : i,j,dij,eij_x,eij_y
 U: numpy array
people velocities
 Vd: numpy array
people desired velocities
 lambda_: float
quantifies the directional dependence when the vision angle is considered (between [0,1], if equal to 1 the fully isotropic case is recovered)
 delta: float
maintains a certain distance between neighbors
 k: float
used when there is overlapping, k is a stiffness constant of individuals seen as deformable bodies
 eta: float
friction coefficient
 Returns
 Forces: numpy array
sum of all forces for each individual

cromosim.micro.
create_people_in_box
(np, box, rmin, rmax, dom, rng)[source]¶ To create np persons in a given box. The overlaps are not treated for the moment but one checks that the individuals are located in an area where the desired velocity is well defined (outside inaccessible areas or obstacles). If it is not the case, one changes their coordinates in consequence.
 Parameters
 np: integer
number of individuals to create
 box: list
coordinates of the box [xmin, xmax, ymin, ymax]
 rmin: float
people minimal radius
 rmax: float
people maximal radius
 dom: Domain
contains everything for managing the domain
 rng: RandomState
scipy random state object (see scipy.random.RandomState)
 Returns
 p: numpy array
new people coordinates x y r

cromosim.micro.
exit_box
(box, sexit, people, U, arrays=[])[source]¶ Removes individuals outside the box according to a threshold value.
 Parameters
 box: numpy array
box vertice coordinates [xmin, xmax, ymin, ymax]
 sexit: float
threshold value used to remove individuals close to the exit
 peoplenumpy array
people coordinates and radius : x,y,r
 U: numpy array
people velocities
 arrays: list of numpy array
other arrays to resize similarly as people and U
 Returns
 people: numpy array
new people coordinates (outside individuals had been removed)
 U: numpy array
new people velocities (outside individuals had been removed)
 arrays: list of numpy array
new resized arrays taking into account deleted individuals

cromosim.micro.
exit_door
(sexit, dom, people, U, arrays=[])[source]¶ Removes individuals who are at a distance less than sexit to the closest door
 Parameters
 sexit: float
threshold value used to remove individuals close to the exit
 dom: Domain
contains everything for managing the domain
 people: numpy array
people coordinates and radius : x,y,r
 U: numpy array
people velocities
 arrays: list of numpy array
other arrays to resize similarly as people and U arrays
 Returns
 people: numpy array
new people positions (outside individuals had been removed)
 U: numpy array
new poeple velocities (outside individuals had been removed)
 arrays: list of numpy array
new array resized

cromosim.micro.
exit_out_of_domain
(dom, people, arrays=[], box=None)[source]¶ Removes individuals who are outside the domain or outside a given box
 Parameters
 dom: Domain
contains everything for managing the domain
 people: numpy array
people coordinates and radius : x,y,r
 arrays: list of numpy array
other arrays to resize similarly as people and U
 box: numpy array
box coordinates [xmin,xmax,ymin,ymax] which replace the domain minimum and maximum coordinates
 Returns
 people: numpy array
new people array (outside individuals had been removed)
 arrays: list of numpy array
new arrays resized similarly as people array

cromosim.micro.
move_people
(time, dt, people, U, crosslines=[])[source]¶ Updates the people positions according to the new velocities U. If there exists crosslines (i.e. sensors), computes also the id, time, direction and impact points for the individuals who cross the lines.
 Parameters
 time: float
current time
 dt: float
time step
 people: numpy array
people coordinates and radius : x,y,r
 U: numpy array
people velocities
 crosslines: list of numpy array
list of lines [[x0,y0,x1,y1], [x0,y0,x1,y1], …]
 Returns
 people: numpy array
new people positions after moving
 io_id: list of integers
indices of people who cross the lines (sensors)
 io_times: list of floats
times when people cross the lines (sensors)
 io_pts: list of floats
impact points for people crossing the lines (sensors)
 io_dir: list of floats
directions for people crossing the lines (sensors), i.e. entry or exit

cromosim.micro.
people_initialization
(N, init_people_box, dom, dt, rmin, rmax, dmin=0, seed=0, itermax=10)[source]¶ To initialize people array (xyr) with coordinates in several boxes and without overlaps between them.
 Parameters
 N: list
list of the numbers of persons to add in each box
 init_people_box: list
list of the boxes [[xmin, xmax, ymin, ymax],…]
 dom: Domain
contains everything for managing the domain
 dt: float
time step
 rmin: float
people minimal radius
 rmax: float
people maximal radius
 dmin: float
minimal distance allowed between individuals (0 by default)
 seed: integer
seed to initialize the RandomState (0 by default means different seed at each run)
 itermax: integer
maximal number of Uzawa projections (10 by default)
 Returns
 people: numpy array
new people coordinates x y r
 people_init_box_id: numpy array
box number for each individual
 rng: RandomState
scipy random state object (see scipy.random.RandomState)

cromosim.micro.
periodic_bc_vertical
(ymin, ymax, people, U, xmin=None, xmax=None, rng=None)[source]¶ Does not exactly correspond to periodic boundary conditions (in the mathematical sense): the persons having an ycoordinate y less than ymin (respectively greater than ymax) are reinjected at y+(ymaxymin) (respectively at y(ymaxymin)) with (optionally) random xcoordinates (between xmin and xmax, and with velocities equal to 0.
 Parameters
 ymin: float
minimal ordinate of the box
 ymax: float
maximal ordinate of the box
 people: numpy array
people coordinates and radius : x,y,r
 U: numpy array
people velocities
 xmin: float
minimal abscissa of the box
 xmax: float
maximal abscissa of the box
 rng: RandomState
scipy random state object (see scipy.random.RandomState)
 Returns
 people: numpy array
new people coordinates (outside individuals had been moved)
 U: numpy array
new people velocities

cromosim.micro.
plot_people
(ifig, dom, people, contacts, U, colors, time=1, axis=None, plot_people=True, plot_contacts=True, plot_velocities=True, plot_paths=False, paths=None, plot_sensors=False, sensors=[], savefig=False, filename='fig.png', cmap='winter')[source]¶ This function draws spheres for the individuals, lines for the active contacts and arrows for the (desired or real) velocities.
 Parameters
 ifig: int
figure number
 dom: Domain
contains everything for managing the domain
 people: numpy array
people coordinates and radius : x,y,r
 contacts: numpy array
all the contacts : i,j,dij,eij_x,eij_y
 U: numpy array
people velocities
 colors: numpy array
scalar field used to define people colors
 time: float
time in seconds
 axis: numpy array
matplotlib axis : [xmin, xmax, ymin, ymax]
 plot_people: boolean
draws spheres for people if true
 plot_paths: boolean
draws people paths if true
 paths: numpy array
coordinates of the people paths
 plot_sensors: boolean
draws sensor lines if true
 sensors: numpy array
sensor line coordinates (see also the sensor function below)
 savefig: boolean
writes the figure as a png file if true
 filename: string
png filename used to write the figure
 cmap: string
matplotlib colormap name

cromosim.micro.
plot_sensor_data
(ifig, sensor_data, time, initial_door_dist=None, axis=None, flux_timestep=1, savefig=False, filename='fig.png', cmap='winter')[source]¶ When a sensor line is defined this function allows to draw the repartition of the people exit times.
 Parameters
 ifig: int
figure number
 sensor_datanumpy array
[time, direction, intersection_point[2]] for each individual
 time: float
time in seconds
 initial_door_dist: numpy array
people initial distance to the door
 axis: numpy array
matplotlib axis : [xmin, xmax, ymin, ymax]
 flux_timestep: float
timestep for the fluxes : number of persons per flux_timestep seconds
 savefig: boolean
writes the figure as a png file if true
 filename: string
png filename used to write the figure
 cmap: string
matplotlib colormap name

cromosim.micro.
projection
(dt, people, contacts, Vd, dmin=0.0, nb_iter_max=100000, rho=0.1, tol=0.01, log=False, method='cvxopt')[source]¶ From the desired velocities Vd, this projection step consists of computing the global velocity field defined as the closest velocity to the desired one among all the feasible fields (i.e. fields which do not lead to disks overlapping).
 Parameters
 dt: float
time step
 people: numpy array
people coordinates and radius : x,y,r
 contacts: numpy array
all the contacts : i,j,dij,eij_x,eij_y
 Vd: numpy array
people desired velocities
 dmin: float
minimum distance guaranteed between individuals
 nb_iter_max: integer
maximum number of iterations allowed
 rho: float
parameter of the Uzawa method
 tol: float
tolerance wished
 log: boolean
to print the final accuracy, number of iterations,…
 method: string
optimization algorithm : ‘cvxopt’ (default) or ‘uzawa’ (or ‘mosek’ if installed with a license file).
 Returns
 B: numpy array
constraint matrix
 U: numpy array
new people velocities ensuring that there is no overlap between individuals
 L: numpy array
Lagrange multipliers (only when method=’uzawa’, None otherwise)
 P: numpy array
pressure on each individual (only when method=’uzawa’, None otherwise)
 info: integer
number of iterations needed

cromosim.micro.
remove_overlaps_in_box
(dom, box, p, dt, rng, dmin, itermax=10)[source]¶ To remove the overlaps between individuals (spheres) in the given box. Several Uzawa projections are used to give a better robustness to this process when the number of overlaps is very high e.g. during the initialization when the individuals have random positions.
 Parameters
 dom: Domain
contains everything for managing the domain
 box: list
coordinates of the box [xmin, xmax, ymin, ymax]
 p: numpy array
people coordinates x y r
 dt: float
time step
 rng: RandomState
scipy random state object (see scipy.random.RandomState)
 dmin: float
minimal distance allowed between individuals
 itermax: integer
maximal number of Uzawa projections (10 by default)
 Returns
 p: numpy array
new people coordinates x y r

cromosim.micro.
sensor
(door, xy0, xy1, t0, t1)[source]¶ Compute the number of entries/exits through a door as a pedestrian sensor could do
 Parameters
 door: numpy array
door coordinates [x0,y0,x1,y1]
 t0: float
time
 t1: float
time
 xy0: numpy array
people coordinates at time t0
 xy1: numpy array
people coordinates at time t1
 Returns
 id: numpy array
index of persons who go through the door
 p: numpy array
coordinates of intersection points between the door and people trajectories
 io: numpy array
the exit direction is the normal direction, 1 = exit, 1 = entry
 times: numpy array
exit or entry times
 entries: int
number of entries
 exits: int
number of exits