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 be occured…
Parameters: - Np: int
Number of persons
- dom: Domain
contains everything for managing the domain
- xmin: float
minimal abscissa of the box
- xmax : float
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
- ——-
- people : numpy 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, we move the individual 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: - I : numpy array
people index i
- J : numpy array
people index j
- Vd : numpy 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 overvalps are not treated for the moment but we check 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, we change 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
- 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
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 exits 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_data : numpy 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_uzawa(dt, people, contacts, Vd, dmin=0.0, nb_iter_max=100000, rho=0.1, tol=0.01, log=False)[source]¶ From the desired velocities Vd, this projection step consists to compute the global velocity field which shall be defined as the closest to the desired one among all those feasible fields (i.e. fields which do not lead to overlapping of disks).
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 accurancy, number of iterations,…
Returns: - B: numpy array
constraint matrix
- U: numpy array
new people velocities ensuring there is no overlap between individuals
- L: numpy array
Lagrange multipliers
- P: numpy array
pressure on each individual
- 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 like 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