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 pseudo-random 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 fast-marching 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 fast-marching 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 pre-factor 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 y-coordinate y less than ymin (respectively greater than ymax) are reinjected at y+(ymax-ymin) (respectively at y-(ymax-ymin)) with (optionally) random x-coordinates (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