Geometry reference
- class hughes2d.NonConvexDomain(outer_vertices_list: list[list[float]] = [[0, 0], [1, 0], [0, 1]])
Object corresponding to the geometry of a domain. The domain can have walls and exits on its boundary as well as walls inside the domain.
Examples
Creating a square domain:
MyDomain = NonConvexDomain([[0,0],[0,3],[3,3],[3,0]])
Adding an exit:
MyDomain.add_exit([[0,1],[0,2]])
Creating a hole in the center of the domain:
MyDomain.add_wall([[1,1],[1,2],[2,2],[2,1]], cycle=True)
- Parameters:
outer_vertices_list (list[list[float]) – The ordered list of the coordinates of the vertices defining the boundary of the domain. A vertex is represented as a pair of floats i.e. [float,float].
Attributes
- outer_vertices
The list of the coordinates of the vertices located on the boundary of the domain. A vertex is represented as a pair of floats i.e. [float,float].
- wall_vertices
The list of the coordinates of the vertices located on walls inside the domain. A vertex is represented as a pair of floats i.e. [float,float].
- outer_boundary
The list of the edges of the outer boundary of the domain. An edge is represented as a pair of indices of the vertices of outer_vertices i.e. [int,int].
- wall_edges
The list of the edges of the outer boundary of the domain. An edge is represented as a pair of indices of the vertices of outer_vertices i.e. [int,int].
- wall_holes_point
The list of the coordinates of points located inside the holes of the domains. A point is represented as a pair of floats i.e. [float,float].
- exit_list
The list of the edges corresponding to exits of the domain. An edge is represented as a pair of indices of the vertices of outer_vertices i.e. [int,int].
Methods
- __contains__(point: list[float]) bool
Test if the point passed as a parameter is inside the convex hull of the domain.
- add_boundary_point(point: list[float]) int
Add a given point of the boundary to the list of points of the domain.
This is typically used in order to guarantee that the given point will be included as a vertex of the mesh generated from this domain. If the point is already in outer_vertices, the method returns the index of the point without adding it.
- Parameters:
point (list[float]) – The point to add to the boundary respresented as [float, float].
- Raises:
ValueError – The method raises a value error if the given point is not in the boundary of the domain.
- Returns:
- The method returns the index corresponding to the added point in the
outer_vertices list.
- Return type:
- add_exit(exit_edge: list[list[float]]) None
Add an exit passed in parameter.
If the two exit points are on different edges, the shortest path (in number of vertices crossed) following the wall is added as an exit.
- Parameters:
exit_edge (list[PointType]) – an exit defined by two extremal points.
- Raises:
ValueError – raises an error if: - at least one of the extremal points is not in a wall edge or a boundary edge; - there exists no path staying either in the walls or in the boundary that links the two extremal points of the exit.
- add_plot(fig: None, ax: None = None, preference: str = 'plotly') None
Non-blocking plot method for the domain object, does not show the graph.
- Parameters:
fig (matplotlib.Figure or plotly.graph_objects.Figure) – the instance of Figure to which the plot must be added. Depends on the library used.
ax (matplotlib.Axes or None) – the instance of Axes to use if matplotlib is used.
preference (str) – set to “plotly” or “matplotlib” to chose the preferred plotting package. If only one package is installed the preference is ignored.
- Raises:
ImportError – plotly or matplotlib should be installed for this method to work. If both are installed and no preference is set, plotly is used.
- add_wall(coord_wall: list[list[float]], *, cycle: bool = False) None
Add a wall in the domain.
If cycle is set to True, the wall is considered as an area to exclude from the domain. If not, only the edges defined by the coord_wall are excluded from the domain.
Note
- The cycle=True works properly only with convex holes in the domain. In fact,
the barycenters of all the points of the walls to add must be inside the hole for the exclusion to work properly.
- Parameters:
- Raises:
ValueError – raises a Value Error if the points of wall_coord are not inside the convex hull of the domain.
- add_wall_point(point: list[float]) int
Add a given point of the boundary to the list of points of the inner walls of the domain.
This is typically used in order to guarantee that the given point will be included as a vertex of the mesh generated from this domain. If the point is already in wall_vertices, the method returns the index of the point without adding it.
- Parameters:
point (list[float]) – the point to add on an inner wall of the domain.
- Raises:
ValueError – the method raises a value error if the given point is not in the inner walls of the domain.
- Returns:
- the method returns the index corresponding to the added point in the
wall_vertices list.
- Return type:
- add_zone(zone_name: str, zone_vertices: list[list[float]]) None
Add a zone to the dict of zones of the domain.
- static belong_segment(point: list[float], segment: list[list[float]]) bool
Check that a point belongs to a segment within an error margin of PRECISION.
- Parameters:
point (PointType) – the point to test.
segment (list[PointType]) – the segment to test.
- Returns:
bool
- find_boundary_point(point: list[float]) int
Search an edge of the boundary containing the given point.
- Parameters:
point (PointType) – the point the should be in the researched edge.
- Returns:
- the index of the first edge found in the boundary that contains P;
returns -1 if no such edge is found.
- Return type:
- find_wall_point(point: list[float]) int
Search an edge of the inner walls containing a given point.
- has_boundary_point(point: list[float]) bool
Check that the point passed as a parameter belongs to the outer boundary.
- has_exit_edge(edge: list[list[float]]) bool
Test if the segment defined by the pair of points passed as a parameter is inside an exit.
- Parameters:
edge (list[PointType]) – a pair of points defining a segment to test.
- Returns:
bool
- has_exit_point(point: list[float]) bool
Check that the point passed as a parameter belongs to the exits.
- has_outer_edge(edge: list[list[float]]) bool
Test if the segment defined by the pair of points passed as a parameter is inside the outer boundary.
- Parameters:
edge (list[PointType]) – a pair of points defining a segment to test.
- Returns:
bool
- has_wall_edge(edge: list[list[float]]) bool
Test if the segment defined by the pair of points passed as a parameter is inside an inner wall.
- Parameters:
edge (list[PointType]) – a pair of points defining a segment to test.
- Returns:
bool
- has_wall_point(point: list[float]) bool
Check that the point passed as a parameter belongs to the inner walls.
- import_from_dxf(filename: str) int
Import from a dxf file.
The dxf file can contain three layers:
a “domain” layer (mandatory) that contain the outer boundary
an “innerWalls” layer that contains all the inner structures of the domain.
an “exits” layer that contains all the exits of the domain.
(optional) “zone_<zone_name>” layers defining the zones with zone name.
The package ezdxf must be installed in order to use this method.
- static shortest_path_bfs(i_start: int, i_end: int, list_edges: list[list[int]]) list[int]
Compute the shortest path between i_start and i_end (in number of vertices) on the network defined by the integers as vertice and the edges of list_edges.
The method uses a Breadth First Search algorithm with memory of the pathes explored.
- Parameters:
- Returns:
- The shortest path found as a list of integers i.e. the list of
the successive vertices defining the path. If no path is found the method returns an empty list.
- Return type:
- show(preference: str = 'plotly') None
Plot method for the domain object.
The method opens either a new window or a default navigator tab.
- Parameters:
preference (str, optional) – set to “plotly” or “matplotlib” to chose the preferred plotting package. If only one package is installed the preference is ignored.
- Raises:
ImportError – plotly or matplotlib should be installed for this method to work. If both are installed and no preference is set, plotly is used.
- class hughes2d.Mesh
The Mesh Object is an object representing a triangular mesh of a given grain for a given domain object.
It contains all the useful lists of edges, triangles and vertices for optimized computations of the numerical scheme involved in the hughes2d package.
Examples
The mesh can be generated by using a NonConvexDomain as the basis of computations:
MyDomain = NonConvexDomain([[0,0],[0,1],[1,1],[1,0]]) MyMesh = Mesh() MyMesh.generate_mesh_from_domain(MyDomain,0.1)
It is also possible to import a mesh from a .msh file:
MyMesh = Mesh() MyMesh.import_mesh_from_msh("filename.msh")
See also import_mesh_from_msh_free_fem and import_from_lists for different import methods. The mesh can then be exported (see export_mesh_msh and export_mesh_msh_free_fem) or saved as a .json file:
MyMesh.save_to_json("filename")
And can be loaded from this .json file:
MyMesh2 = Mesh() MyMesh2.load_from_json("filename.json")
Attributes
- vertices
array of all the vertices triangle_edge_coordinates.
- Type:
ArrayLike
- edges
array of all the edges as [vertexIndex, vertexIndex].
- Type:
ArrayLike
- triangles
array of all the triangles as [vertexIndex, vertexIndex, vertexIndex].
- Type:
ArrayLike
- exit_vertices
array of the vertices index that belong to an exit.
- Type:
ArrayLike
- exit_edges
array of the edges index where the edge belongs to an exit.
- Type:
ArrayLike
- wall_edges
array of the edges index where the edge belongs to a wall.
- Type:
ArrayLike
- boundary_points
array of the indices of the vertices that belong to the outer boundary of the mesh.
- Type:
ArrayLike
- boundary_edges_index
array of the edges index where the edge belongs to the outer boundary.
- Type:
ArrayLike
- triangles_with_edges
array of triangles ordered as self.triangles, elements as [edge_index, edge_index, edge_index].
- Type:
ArrayLike
- pairs_of_triangles
nested list of length 1 or 2, ordered as self.edges, elements as [triangle_index, triangle_index] or [triangle_index]
- triangles_per_vertex
nested list, ordered as self.vertices, an element is a list of (number of triangles containing the vertex) elements as [[triangle index, [otherVertex1, otherVertex2 ]], …].
- outer_normal_vect_by_triangles
array order as self.tringles containing the unit normal vectors corresponding to the three edges of each triangle. The normal vectors are directed towards the exterior of the triangle.
- Type:
ArrayLike
- cell_areas
array ordered as self.triangles containing the area of each triangle of the mesh.
- Type:
ArrayLike
- edge_length
array ordered as self.edges containing the length of each edge.
- Type:
ArrayLike
Methods
- add_convex_zone(zone_name: str, zone_vertices: list[list[float]]) None
Add a convex zone to the Mesh object.
- add_plot(fig: None, ax: None = None, preference: str = 'plotly') None
Non-blocking plot method for the mesh object.
- Parameters:
fig (matplotlib.Figure or plotly.graph_objects.Figure) – the instance of Figure to which the plot must be added. Depends on the library used.
ax (matplotlib.Axes or None) – the instance of Axes to use if matplotlib is used.
preference (str) – set to “plotly” or “matplotlib” to chose the preferred plotting package. If only one package is installed the preference is ignored.
- Raises:
ImportError – plotly or matplotlib should be installed for this method to work. If both are installed and no preference is set, plotly is used.
- computations(domain: NonConvexDomain = None, requirements: list[str] = ['all'], *, verbose: bool = False) None
Trigger all the computations required for the Mesh object.
- Parameters:
domain (NonConvexDomain, optional) – the domain object to use in order to recover the exits and the zones.
verbose (bool, optional) – displaying progression in console.
requirements (list[str], optional) –
a list containing the computations that will be done using the mesh. The possible values are:
- EikonalSolverthe mesh will be used in order to solve an eikonal
equation
- LWRSolverthe mesh will be used in order to solve a scalar
conservation law
all : all the possible computations will be done
- integratethe mesh will be used in order to compute some
integrals over the domain
- FreeFEMthe mesh will be used in order to import/export mesh
file for FreeFEM
- compute_cell_areas() float
Compute the areas of each triangular cell.
Raises an error if a triangle is degenerated. Computes also the barycenter of each triangle.
- Returns:
the minimal area of a triangle in the mesh.
- Return type:
Note
Required for:
integrate
LWRSolver
- compute_edge_length() float
Compute the edge_length array.
Note
Required for:
LWRSolver
EikonalSolver
- Returns:
the maximal length of an edge in the mesh.
- Return type:
- compute_edge_list() None
Fill two arrays concerning the edges of the mesh.
The arrays are:
self.edges : cointaining all the edges of the mesh as a pair of vertex index.
- self.triangles_with_edgescontaining all the triangles of self.triangles,
in the same order, represented as a triplet of edge index.
Note
Required for:
LWRSolver
EikonalSolver
set_exits_from_domain
- compute_outer_normals() None
Compute the list outer_normal_vect_by_triangles.
Note
Required for:
LWRSolver
- compute_pair_of_triangles_list() None
Compute the lists pairs_of_triangles and boundary_edges_index.
Note
Required for:
LWRSolver
checkGradientValidity
- compute_triangles_per_vertex() None
Compute the self.triangles_per_vertex list.
Note
Required for:
EikonalSolver
integrateOverSquareBall
- compute_vertex_flags(domain: NonConvexDomain, flag_dict: dict = {'domain': 0, 'exit': [98], 'wall': [99]}) None
Compute the vertices flags necessary to export the Mesh as FreeFEM mesh file.
- Parameters:
domain (NonConvexDomain, optional) – the domain object to use in order to recover the exits and the zones.
flag_dict (dict) – dictionary prescribing the integer corresponding to the different types of vertex for an export as a FreeFEM .msh file.
Note
Required for:
export_mesh_msh_free_fem
- export_mesh_msh(filename: str) None
Export the data of the Mesh object in a .msh file.
- Parameters:
filename (str) – the complete path to the file.
- Raises:
ImportError – requires meshio to be installed to work properly.
- export_mesh_msh_free_fem(filename: str) None
Export the data of the Mesh object in a .msh file following the specific structure of the FreeFEM mesh files.
- Parameters:
filename (str) – the complete path to the file.
- generate_mesh_from_domain(domain: NonConvexDomain, dx: float, da: float = 30, requirements: list[str] = ['all'], *, verbose: bool = False) None
Compute a triangular mesh covering domain with the maximal length of an edge being set to dx.
The computations are done using triangle (see https://www.cs.cmu.edu/~quake/triangle.html)
- Parameters:
domain (NonConvexDomain) – the domain object from which the mesh must be generated.
dx (float) – max area of a triangle (heavy computations when set low, computation time ~ 1/(dx)^2 ).
da (float, optional) – min angle inside a triangle (be careful, crash if set too high). Default = 30.
verbose (bool, optional) – displaying progression in console.
requirements (list[str], optional) –
a list containing the computations that will be done using the mesh. The possible values are:
- EikonalSolverthe mesh will be used in order to solve an eikonal
equation
- LWRSolverthe mesh will be used in order to solve a scalar
conservation law
all : all the possible computations will be done
- integratethe mesh will be used in order to compute some
integrals over the domain
- FreeFEMthe mesh will be used in order to import/export mesh
file for FreeFEM
- get_limits() list[list[float]]
Compute and return the extremal coordinates of the vertices of the mesh.
- import_from_lists(vertices: list[list[float]], triangles: list[list[int]], domain: NonConvexDomain, requirements: list[str] = ['all'], *, verbose: bool = False) None
Import the lists passed as parameters into the Mesh object.
- Parameters:
vertices (list[PointType]) – list of all the vertices coordinates.
triangles (list[list[int]]) – list of the triangles symbolized by a triplet of the indices of the corresponding verttices in the vertices list.
domain (NonConvexDomain) – a NonConvexDomain instance corresponding to the mesh imported.
verbose (bool, optional) – displaying progression in console.
requirements (list[str], optional) –
a list containing the computations that will be done using the mesh. The possible values are:
- EikonalSolverthe mesh will be used in order to solve an eikonal
equation
- LWRSolverthe mesh will be used in order to solve a scalar
conservation law
all : all the possible computations will be done
- integratethe mesh will be used in order to compute some
integrals over the domain
- FreeFEMthe mesh will be used in order to import/export mesh
file for FreeFEM
- import_mesh_from_msh(filename: str, requirements: list[str] = ['all'], *, verbose: bool = False) None
Import the data from a .msh file into the Mesh object in the GMSH format.
- Parameters:
filename (string) – the path to the file to import.
verbose (bool, optional) – displays information in the console during the import.
requirements (list[str], optional) –
a list containing the computations that will be done using the mesh. The possible values are:
- EikonalSolverthe mesh will be used in order to solve an eikonal
equation.
- LWRSolverthe mesh will be used in order to solve a scalar
conservation law.
all : all the possible computations will be done
- integratethe mesh will be used in order to compute some
integrals over the domain.
- FreeFEMthe mesh will be used in order to import/export mesh
file for FreeFEM.
- Raises:
ImportError – requires the python library meshio.
- import_mesh_from_msh_free_fem(filename: str, flag_dict: dict = {'domain': 0, 'exit': [98], 'wall': [99]}, requirements: list[str] = ['all'], *, verbose: bool = False) None
Import the data from a mesh file constructed in FreeFEM into the Mesh object.
The specific structure (inner walls, exits…) can be specified by specifying different flags in FreeFEM.
- Parameters:
filename (str) – the path to the file to import.
flag_dict (dict) – a dictionary describing the specific translation of the FreeFEM flag number. Must contain the keys domain, exit and wall.
verbose (bool, optional) – displays information in the console during the import.
requirements (list[str], optional) –
a list containing the computations that will be done using the mesh. The possible values are:
- EikonalSolverthe mesh will be used in order to solve an eikonal
equation
- LWRSolverthe mesh will be used in order to solve a scalar
conservation law
all : all the possible computations will be done
- integratethe mesh will be used in order to compute some
integrals over the domain
- FreeFEMthe mesh will be used in order to import/export mesh
file for FreeFEM
- in_zone(point: list[float], zone_name: str) bool
Test if a given point is included in a given zone.
- Parameters:
point (PointType) – the point to test.
zone_name (str) – the name of the zone to test.
- load_from_json(filename: str) None
Load the mesh object with the data from a .json file.
- Parameters:
filename (str) – the name of the file to load. The extension .json is needed in the filename.
- Raises:
ImportError – the json module must be installed.
- save_to_json(filename: str) None
Save the mesh object in a .json file.
- Parameters:
filename (str) – the name of the file where the mesh will be saved. The extension .json is not needed in the filename.
- Raises:
ImportError – the json module must be installed.
- set_exits_from_domain(domain: NonConvexDomain) None
Configure the exits and the wall edges and vertices lists from the domain object passed in parameter.
- Parameters:
domain (NonConvexDomain) – the domain object containing information about the exits.
Note
Required for:
LWRSolver
EikonalSolver
- show(with_domain: NonConvexDomain = None, preference: str = 'plotly') None
Plot method for the Mesh object.
- Parameters:
with_domain (NonConvexDomain, optional) – domain object from which exits and walls can be recovered for plotting.
preference (str, optional) – set to “plotly” or “matplotlib” to chose the preferred plotting package. If only one package is installed the preference is ignored.
- Raises:
ImportError – plotly or matplotlib should be installed. If both are installed and no preference is set, plotly is used.
- class hughes2d.CellValueMap(mesh: Mesh)
An object to represent a cell valued map that corresponds to a function which is constant on the triangles of a mesh (mostly densities).
Attributes
Methods
- convolution_over_square_ball(radius: float, conv_func: Callable[[float], float]) list
Compute the convolution of the CellValueMap with the conv_func function on the support defined by the square of given radius (infinity-norm ball).
- Parameters:
radius (float) – the radius \(r\) of the convolution support.
conv_func (function, float -> float) –
the convolution function in the form \(F(\rho(y),|x_1-y_1|,|x_2-y_2|)\) where \(\rho\) is the cellValueMap and \(x = (x_1,x_2)\) is the vertex where the convolution is computed. The computed quantity is then, for any \(x = (x_1,x_2)\),
\[\iint_{[-r/2, r/2]^2} F(\rho(x+y), |y_1|,|y_2|) d y_1 d y_2.\]
- Returns:
a list containing the computed value of the convolution for each vertex of the mesh ordered in the same way as the vertices of the Mesh object.
- Return type:
- fit_averaged_map(other: Self) None
Fit a cellValueMap over another cellValueMap when the Mesh are different but the domains are the same by averaging over each triangle.
- Parameters:
other (CellValueMap) – the other map to fit onto the self map.
- generate_random(variability: float = 0.4, mean: float = 0.23) None
Generate random values for the map on each triangle of the mesh.
The random value follows a uniform law on [mean -variability/2, mean + variability/2].
- get_scatter(preference: str = 'plotly') list[None]
Non-blocking plot method for the cellValueMap object.
- Parameters:
preference (str, optional) – set to “plotly” or “matplotlib” to chose the preferred plotting package. If only one package is installed the preference is ignored.
- Raises:
ImportError – plotly or matplotlib should be installed. If both are installed and no preference is set, plotly is used.
- integrate() float
Compute the integral of the map over the whole domain.
- Returns:
the integral of the CellValueMap over the whole domain.
- Return type:
- set_constant(value: float) None
Set the value to “value” on every triangle.
- Parameters:
value (float) – the value to set on each triangle.
- set_constant_circle(center: list[list[float]], radius: float, value: float) None
Set to the given value all the cells for which the barycenter is inside the disk of given center and radius.
- show(preference: str = 'plotly') None
Plot method for the CellValueMap object.
- Parameters:
preference (str, optional) – set to “plotly” or “matplotlib” to chose the preferred plotting package. If only one package is installed the preference is ignored.
- Raises:
ImportError – plotly or matplotlib should be installed. If both are installed and no preference is set, plotly is used.
- class hughes2d.VertexValueMap(mesh: Mesh)
An object to represent a vertex valued map that corresponds to a function which is affine on the triangles, defined by its values on the vertices (often a potential).
Attributes
Methods
- add_3d_plot(fig: None, color: list[float] = [244, 22, 100, 0.6]) None
Non-blocking method that adds the 3D plot to a given Figure object.
Note
Only available with plotly at the moment.
- Parameters:
- Raises:
ImportError – plotlyshould be installed.
- compute_gradient_flow(normalization: ~collections.abc.Callable[[float, float], float] = <function VertexValueMap.<lambda>>, *, normalize: bool = True) numpy.typing.ArrayLike
Compute and return the gradients of the function defined by the vertex valued map. The gradient is computed on each triangle.
- Parameters:
- Raises:
ValueError – if at least one of the triangles is degenerated.
- Returns:
- an array containing all the gradients ordered as the list
Mesh.triangles.
- Return type:
ArrayLike
- compute_vertex_gradient_flow(normalization: ~collections.abc.Callable[[float, float], float] = <function VertexValueMap.<lambda>>, *, normalize: bool = True) numpy.typing.ArrayLike
Compute and return the gradients of the function defined by the vertex valued map.
The gradient is computed at each vertex as a weighted mean of the differences with the neighbouring vertices.
Note
This method is less precise than compute_gradient_flow in general. However due to its non-local construction, the gradient flow obtained with this method tends to be more regular.
- Parameters:
- Returns:
- an array containing all the gradients ordered as the
list Mesh.triangles.
- Return type:
ArrayLike
- generate_random(variability: float = 0.5) None
Generate random values for the maps distributed as 0.5 + variability*X where X is uniform on [-0.5,0.5].
- Parameters:
variability (float, optional) – the range of the uniform distribution.
- show(colorscale_name: str = 'viridis', *, grid: bool = False) None
Display the vertex valued map as a colorscale scatter plot in 2D.
Note
Only available with plotly at the moment.
- Parameters:
- Raises:
ImportError – plotly should be installed.
- show_3d() None
Display a 3D plot of the vertex valued map.
Note
Only available with plotly at the moment.
- Raises:
ImportError – plotly should be installed.
- show_vector_field(normalization: ~collections.abc.Callable[[float, float], float] = <function VertexValueMap.<lambda>>, *, normalize: bool = True) None
Display the vector field corresponding to the gradient flow (obtained with compute_gradient_flow) of the vertex valued map.
Note
Only available with plotly at the moment.
- Parameters:
- Raises:
ImportError – plotly should be installed.
Equation solvers reference
- class hughes2d.EikoSolver(mesh: ~hughes2d.Mesh2D.Mesh, density_map: ~hughes2d.Mesh2D.CellValueMap = [], cost_function: ~collections.abc.Callable[[float], float] = <function EikoSolver.<lambda>>, opt: dict = {})
An object wrapping together all the methods used to solve the eikonal equation in a discontinuous context.
We use the following notations for the eikonal equation:
\[|\nabla u | = c(\rho).\]Attributes
- density
a function constant on the triangle of the mesh representing the density of pedestrians.
- Type:
- fieldValues
the object corresponding to the approximated solution of the eikonal equation.
- Type:
- cost
the function c that must be applied to the density map. If we set \(c: \\rho \\mapsto 1\) the solution of the eikonal equation will correspond to the length of the shortest path to the exits, without taking the density into account.
- Type:
function, float -> float
- opt
the dictionary containing all the parameters of computation:
key
type
possible values
description
“method”
str
“FME” or “FMT”
corresponds to the computational method to use
“NarrowBandDepth”
int
1 or 2
the maximal degree of the neighbours explored at each iteration (only relevant if method=”FMT”)
“constrained”
bool
True or False
determines if the gradient computed must be constrained inside the triangle or not (only relevant if method=”FMT”)
“debugging”
bool
True or False
debugging option, for verbose outputs and detailled prints
- Type:
Note
The best combination of options with respect to the quality of the approximation appears to be:
{ "method" : "FMT", "NarrowBandDepth" : 2, "constrained" : True }
For further details about the algorithms and their comparison, we defer to https://hal.science/tel-05275359v1
Methods
- add_in_order_by_field_value(ordered_list: list[int], index: int) list[int]
Add the index given as an argument to the given list.
Returns the new list. The index is inserted such that the fieldValues corresponding to the vertices of the indices are increasing.
Example
If we have the following lists:
MyMesh = Mesh() MyMesh.vertices = [[0,0],[0,1],[1,1],[1,0]] MySolver = EikoSolver(MyMesh) MySolver.fieldValues.values = [0.5,4.5,2.0,3.0] Mylist = [0,3]
Then:
>>>MySolver.add_in_order_by_field_value(Mylist,1) [0,3,1] >>>MySolver.add_in_order_by_field_value(Mylist,2) [0,2,3]
Note
If an index is already present in the list, its position in the list is recomputed.
- compute_field() None
Compute the approximated solution of the eikonal equation and stores the approximation in “fieldValues”.
The method used depends on the options set in the “opt” dictionary.
- compute_field_by_edges() None
Compute a numerical approximation of the solution to the eikonal equation using a FME algorithm.
- compute_field_constrained_dep_1() None
Compute the approximated solution of the eikonal equation and stores the approximation in “fieldValues”.
The method used is the FMT algorithm with constraints on the gradient and vertices at distance one or two are considered neighbour. i.e. constrained = True and NarrowBandDepth = 1 see “opt”
- compute_field_constrained_dep_2() None
Compute the approximated solution of the eikonal equation and stores the approximation in “fieldValues”.
The method used is the FMT algorithm with constraints on the gradient and vertices at distance one or two are considered neighbour. i.e. constrained = True and NarrowBandDepth = 2 see “opt”
- compute_field_unconstrained_dep_1() None
Compute the approximated solution of the eikonal equation and stores the approximation in “fieldValues”.
The method used is the FMT algorithm with constraints on the gradient and vertices at distance one or two are considered neighbour. i.e. constrained = False and NarrowBandDepth = 1 see “opt”
- compute_field_unconstrained_dep_2() None
Compute the approximated solution of the eikonal equation and stores the approximation in “fieldValues”.
The method used is the FMT algorithm with no constraint on the gradient and vertices at distance one or two are considered neighbour. i.e. constrained = False and NarrowBandDepth = 2 see “opt”
- static compute_height_from_grad_constrained(a: list[float], b: list[float], c: list[float], v_b: float, v_c: float, slope: float) float
Compute and return the value of v_a.
v_a is computed such that, if we denote by \(\Phi_{ABC}(v_a,v_b,v_c)\) the unique affine function \(F\) of \(\mathbb{R}^2\) such that
\[F(A) = v_a, \; F(B) = v_b, \; F(C) = v_c\]then we have
\[\left| \nabla\Phi_{ABC}(v_a,v_b,v_c) \right| = slope.\]If the gradient found is not inside the triangle, v_a is taken as the smallest value found by following an edge of the triangle.
- static compute_height_from_grad_unconstrained(c: list[float], b: list[float], a: list[float], v_b: float, v_a: float, slope: float) float
Compute and return the value of v_c.
v_c is computed such that, if we denote by \(\Phi_{ABC}(v_a,v_b,v_c)\) the unique affine function \(F\) of \(\mathbb{R}^2\) such that
\[F(A) = v_a, \; F(B) = v_b, \; F(C) = v_c\]then we have
\[\left| \nabla\Phi_{ABC}(v_a,v_b,v_c) \right| = slope.\]
- static compute_height_length(b: float, c: float, a: float) float
Compute and return the length of the height of the triangle ABC passing through B.
- static dist(x0: float, y0: float, x1: float, y1: float) float
Compute and return the euclidian distance between (x0,y0) and (x1,y1).
- show_narrow_band_after_step(n: int) None
Compute the first n vertices of the approximation, then, display the narrow band.
- Parameters:
n (int) – number of vertices to compute.
- update_density(density: CellValueMap) None
Update the density of the solver with the new density passed as a parameter.
- Parameters:
density (CellValueMap) – the new density to update in the solver.
- class hughes2d.LWRSolver(mesh: ~hughes2d.Mesh2D.Mesh, dt: float, previous_density: list[float] = [], direction_map: list[list[float]] = [], speed_function: ~collections.abc.Callable[[float], float] = <function LWRSolver.<lambda>>, opt: dict = {'anNum': 'dichotomy', 'convexFlux': True, 'method': 'midVector'})
A solver for LWR-type scalar conservation law directed by a vector field in two dimensions.
We use the following notations:
\[\begin{split}\left\{ \begin{matrix} \partial_t \rho(t,x) + \mathbf{div}\left[ \rho(t,x) v(\rho(t,x)) \vec{V}(t,x) \right] = 0, \\ \rho(0,x) = \rho_0(x) \end{matrix} \right.\end{split}\]- Parameters:
Mesh (Mesh) – a mesh object on which the equation will be approximated.
previous_density (CellValueMap or list[float]) –
initial density for the solver. Must be of the shape of Mesh.triangles. Represents \(\rho_0(x)\) in
the equation above.
direction_map (list[list[float]]) – a vector field represented by a list of vectors with the shape of Mesh.triangles. Typically this corresponds to the output of VertexValueMap.computeGradientFlow(). Represents \(\vec{V}(t,x)\) in the equation above.
speed_function (function, float -> float) – a function respresenting the speed of the agents depending on the local density. Represents \(v(\cdot)\) in the equation above.
dt (float) –
the time division for the approximation.
Warning
The CFL condition must be satisfied for the simulations to make sense. Here the CFL condition is:
\[\Delta t \leq \frac{\underline{|\triangle|}}{3\underline{\textrm{$\triangle$}}Lip_f},\]where \(\underline{|\triangle|}\) denotes the minimal area of a triangle in the mesh \(M_\Delta\) and \(\underline{\textrm{$\triangle$}}\) denotes the maximal length of the edges of the mesh.
opt (dict) –
an optional dictionary prescribing the numerical method.
key
type
possible values
description
”method”
str
”tmap” or “midvector”
determines of the conflict between non-colinear vectors are resolved
”anNum”
str
”dichotomy”
only parameter available at the moment, numerical method to use for the approximations
”convexFlux”
bool
True or False
optimization of the computations when the flux is convex or concave
”ApproximationThreshold”
float
> 0
the precision to use for the numerical approximations
”debugging”
bool
True or False
determines if the solver will print debugging informations in the console or not
Attributes
- densityt0
initial density for the solver. Of the shape of Mesh.triangles. Represents \(\rho_0(x)\) in the equation above.
- Type:
ArrayLike
- densityt1
density computed by the solver after one time step. Of the shape of Mesh.triangles. Represents \(\rho(\Delta t, x)\).
- Type:
ArrayLike
- directions
a vector field represented by a list of vectors with the shape of Mesh.triangles. Typically this corresponds to the output of VertexValueMap.computeGradientFlow(). Represents \(\vec{V}(t,x)\) in the equation above.
- fluxFunction
a function respresenting the flux of agents depending on the local density. Represents \(\rho \mapsto \rho v(\cdot)\) in the equation above.
- Type:
function, float -> float
- dt
the time division for the approximation.
Warning
The CFL condition must be satisfied for the simulations to make sense. Here the CFL condition is:
\[\Delta t \leq \frac{\underline{|\triangle|}}{3\underline{\textrm{$\triangle$}}Lip_f},\]where \(\underline{|\triangle|}\) denotes the minimal area of a triangle in the mesh \(M_\Delta\) and \(\underline{\textrm{$\triangle$}}\) denotes the maximal length of the edges of the mesh.
- Type:
Methods
- static appro_zero_dichotomy(f: Callable[[float], float], a: float, b: float, precision: float = 1e-05, hints: list[float] = []) float
Numerically approximate the a root of the function f between a and b using a dichotomy method.
- Parameters:
f (function, float -> float) – the function f for which a root will be computed.
a (float) – one of the bounds for the search domain of the root.
b (float) – one of the bounds for the search domain of the root.
precision (float,optional) – the error margin for the approximation.
hints (list[float],optional) – possibles value to test before the dichotomy in order to optimize the computation time.
- Returns:
the approximated root computed.
- Return type:
- static approxi_max(f: Callable[[float], float], a: float, b: float, precision: float = 1e-05) float
Numerically approximates the maximum of the function f between a and b and returns the maximal value.
- Parameters:
- Returns:
the maximal value computed.
- Return type:
- static approxi_min(f: Callable[[float], float], a: float, b: float, precision: float = 1e-05) float
Numerically approximate the minimum of the function f between a and b and returns the minimal value.
- Parameters:
- Returns:
the minimal value computed.
- Return type:
- static arg_max(f: Callable[[float], float], a: float, b: float, precision: float = 1e-05) float
Numerically approximate the maximal point of the function f between a and b and returns the maximal argument.
- Parameters:
- Returns:
the argmax computed.
- Return type:
- check_cfl(lip_constant: float = 1) bool
Check if the CFL condition is satisfied.
Here the CFL condition is:
\[\Delta t \leq \frac{\underline{|\triangle|}}{3\underline{\textrm{$\triangle$}}Lip_f},\]where \(\underline{|\triangle|}\) denotes the minimal area of a triangle in the mesh \(M_\Delta\) and \(\underline{\textrm{$\triangle$}}\) denotes the maximal length of the edges of the mesh.
- compute_next_step() None
Compute the approximated solution to the scalar conservation law after one time step and stores it in densityt1.
- compute_step_mid_vector() None
Compute the approximated solution to the scalar conservation law after one time step with the mid vector method.
- compute_step_tmap() None
Compute the approximated solution to the scalar conservation law after one time step with the transmission maps method.
- static god(f: Callable[[float], float], a: float, b: float, precision: float = 1e-05) float
Numerically approximate the Godunov flux of the function f between a and b defined by the formula below.
\[\begin{split}\mathbf{God}_{f}(a,b) = \left\{ \begin{matrix} \mathbf{min}_{c \in [a,b]} f(c) \textrm{ if } a < b \\ \mathbf{max}_{c \in [b,a]} f(c) \textrm{ if } a > b. \end{matrix} \right.\end{split}\]- Parameters:
- Returns:
the Godunov flux computed.
- Return type:
- show_density(t: int = 1, preference: str = 'plotly') None
Display the density map. If t = 0, it shows the initial datum else if t = 1 (default), it shows the density computed after one time step.
- Parameters:
- Raises:
ValueError – if t is not 0 or 1.
- class hughes2d.PedestrianSolver(mesh: ~hughes2d.Mesh2D.Mesh, dt: float, initial_density: ~hughes2d.Mesh2D.CellValueMap, speed_function: ~collections.abc.Callable[[float], float] = <function PedestrianSolver.<lambda>>, cost_function: ~collections.abc.Callable[[float], float] = <function PedestrianSolver.<lambda>>, directions: list[list[float]] = [], options: dict = {'model': 'hughes'})
An object wrapping together different models for pedestrian flows.
Examples
First, we need a Mesh object in order to create the solver:
MyMesh = Mesh() MyMesh.loadFromJson("pathToMyMesh.json")
Then we need to declare the options in a dictionnary:
opt = dict( model = "hughes", filename = "pathForTheSavedFile", save = True, verbose = False, lwrSolver = { "convexFlux" : True, "method" : "midVector", "ApproximationThreshold" : 0.0001}, eikoSolver = { "method" : "FMT", "constrained" : True, "NarrowBandDepth" : 2})
Eventually, we need to define an initial datum and we are in a position to instantiate the solver:
InitialDatum = Mesh2D.CellValueMap(MyMesh) InitialDatum.generateRandom() MySolver = PedestrianSolver(MyMesh, 0.01, initial_density = InitialDatum, options=opt)
Now we can compute the approximation until the domain is empty:
MySolver.compute_until_empty()
- Models:
At the moment, three models are available for simulations:
Hughes” model: a model where the agents try to minimize their individual cost by avoiding high density regions.
Colombo-Garavello-Lecureux-Mercier-Lecureux-Mercier: a model where the agents try to take the shortest path to the exits but are deviated by high density regions.
LWR with constant direction field: a model where the agents take the shortest path to the exits without taking the surrounding density into account.
See the Mathematics section of the documentation for more details.
- Parameters:
Mesh (Mesh) – the mesh on which the approximations will be computed.
dt (float) – the duration of a time step. Be careful of the CFL condition see CFLwarning.
initial_density (CellValueMap) – the initial density in the domain.
speed_function (function, float -> float, optional) – the speed function corresponding to the speed of agents depending on the local density.
cost_function (function, float -> float, optional) – the cost function corresponding to the running cost in the eikonal equation. Useless if the model used is not “hughes”.
directions (list[list[float]], optional) – the direction vector field to use as trajectories for the agents. Useless for Hughes” model as the vector field is recomputed depending on the density. If not prescribed, the vector field is computed at the initialization of the solver as the shortest path towards the exits.
options (dict, optional) – an optional dictionary prescribing the model to use and various parameters for the numerical simulations. See Options: below.
- Options:
Options are passed as an optional dictionary as a parameter of the
PedestrianSolverobject.key
type
possible values
description
“model”
str
“hughes”, “colombo-garavello” or “constantDirectionField”
determines the model to use for the numerical simulation.
“save”
bool
True or False
determines whether the data of the simulation should be stored in .csv files.
“filename”
str
a valid path
sets the path and basename for the save files.
“framerate”
int
> 0
number of frame per seconds that will be saved in the .csv files. Useless if “save” = False.
“additional_computations”
dict
adds computations of non standard quantities to the simulation. See additional_computations for more information.
“verbose”
bool
True or False
determines if the solver will print informations in the console or not.
“lwrSolver”
dict
the dictionary containing all the options to use for the
LWRSolverobject (see the LWRSolver doc).“eikoSolver”
dict
the dictionary containing all the options to use for the
EikoSolverobject (see the EikoSolver doc).“CGparameters”
dict
the dictionary containing all the parameters to use for the Rinaldo-Garavello-Lecureux-Mercier (see CGparameters)
- additional_computations
This dictionary can contain 3 optional keys at the moment:
total_mass: computes the total mass in the domain for each time step.zones_mean_density: computes the mean density in each zone of the mesh defined inMesh.zonesfor each time step.max_density: computes the maximal density present in the domain for each time step.
- CGparameters
This dictionary contains two different keys:
radius(float): corresponds to the radius of the convolution.epsilon(flaoat): corresponds to the amount of influence of the deviation vector field.
See ColomboGaravelloModel in the documention for more details.
- Raises:
ValueError – if the “model” key in the option dictionary is not set properly.
Attributes
- speed_function
the speed function corresponding to the speed of agents depending on the local density.
- Type:
function, float -> float
- cost_function
the cost function corresponding to the running cost in the eikonal equation. Useless if the model used is not “hughes”.
- Type:
function, float -> float
- directions
the direction vector field to use as trajectories for the agents.
Methods
- compute_step() None
Compute one step of time of the approximation of the solution of the chosen model. Also saves the generated data if
options["save"] == True.
- compute_steps(n: int) None
Compute
nsteps of time of the approximation of the solution of the chosen model.Also saves the generated data if
options["save"] == True.- Parameters:
n (int) – the number of steps to compute.
- compute_steps_and_show(n: int) None
Compute
nsteps of time of the approximation of the solution of the chosen model.Then display the solution after
nsteps.- Parameters:
n (int) – the number of steps to compute.
- compute_until_empty(max_frames: int = 5000) None
Compute enough steps of time of the approximation so that the domain is empty.
Also saves the generated data if
options["save"] == True.- Parameters:
max_frames (int, optional) – the maximal number of steps to compute.
Plot utilities
- Plotter.convert_to_mp4(filename: str, limits: list[list[float]] = [], dpi_set: int = 300, pic_size: tuple[int, int] = (8, 6), *, plot_scale: bool = True) None
Create a video file from the data files of a simulation.
- Parameters:
filename (str) – the path and basename for the data files.
limits (list[list[float]], optional) – the scope of the simulation as [[x_min,x_max],[y_min,y_max]].
dpi_set (int, optional) – resolution of the video as dots per inches (dpi)
pic_size (tuple[int,int], optional) – size of the picture as (width,height)
plot_scale (bool, keyword-only) – toggles the plot of a color scale for the density.
- Raises:
ImportError – if matplotlib is not installed.
- Plotter.save_time_slices(times: list[float], filename: str, slicename: str, limits: list[list[float]] = [], dpi_set: int = 300, pic_size: tuple[int, int] = (8, 6), format: str = 'svg', *, plot_scale: bool = True) None
Export an image file from the data files of a simulation for each time slice required in the
timesparameter.- Parameters:
times (list[float]) – a list of the timing (in seconds) when a picture should be extracted from the simulation.
filename (str) – the path and basename for the data files.
slicename (str) – the path and basename for the exported pictures.
limits (list[list[float]]) – the scope of the simulation as [[x_min,x_max],[y_min,y_max]].
dpi_set (int) – resolution of the video as dots per inches (dpi)
pic_size (tuple[int,int], optional) – size of the picture as (width,height)
format (str, optional) – the output extension as a string.
plot_scale (bool, keyword-only) – toggles the plot of a color scale for the density.
- Raises:
ImportError – if matplotlib is not installed.
- Plotter.plot_vector_field(vertex_list: list[list[float]], triangle_list: list[list[int]], vector_field: list[list[float]], *, plot_mesh: bool = True) None
Display a vector field passed as a parameter with plotly.
- Parameters:
vertex_list (list[list[float]]) – a list of the vertices of the mesh on which the vector field will be plotted.
triangle_list (list[list[int]]) – a list of the triangles of the mesh on which the vector field will be plotted.
vector_field (list[list[float]]) – the vector field to plot. Must be of the same shape as
triangle_list.plot_mesh (bool, keyword-only) – whether or not the mesh should be plotted in background.
- Raises:
ImportError – if plotly is not installed.