Hydraulic Design and Optimisation#

pysewer.optimization.place_lifting_station(G, node)[source]#

Places a lifting station at the specified node in the graph.

Parameters:
  • G (networkx.Graph) – The graph to add the lifting station to.

  • node (int) – The node to add the lifting station to.

Returns:

The graph with the added lifting station.

Return type:

networkx.Graph

pysewer.optimization.get_max_upstream_diameter(G: DiGraph, edge: tuple)[source]#

Returns the maximum diameter of all upstream edges of the given edge in the directed graph G.

Parameters:
  • G (networkx.DiGraph) – The directed graph.

  • edge (tuple) – The edge for which to find the maximum upstream diameter.

Returns:

The maximum diameter of all upstream edges of the given edge.

Return type:

float

pysewer.optimization.place_pump(G, node)[source]#

Places a pump at the specified node in the graph G and sets downstream edges “pressurized” attribute.

Parameters:
  • G (networkx.Graph) – The graph in which the pump is to be placed.

  • node (hashable) – The node at which the pump is to be placed.

Returns:

The graph with the pump placed at the specified node and downstream edges “pressurized” attribute set.

Return type:

networkx.Graph

pysewer.optimization.set_diameter(G: Graph, edge: tuple, diameter: float)[source]#

Set the diameter of an edge in a graph.

Parameters:#

Gnetworkx.Graph

The graph to modify.

edgetuple

The edge to modify.

diameterfloat

The diameter to set.

Returns:#

networkx.Graph

The modified graph.

pysewer.optimization.get_downstream_junction(G: Graph, node: int)[source]#

Returns the next downstream junction from the specified node in G.

Parameters:
  • G (networkx.Graph) – The graph to search for the downstream junction.

  • node (int) – The node to start the search from.

Returns:

The downstream junction from the specified node in G.

Return type:

int

Notes

The downstream junction is defined as the next junction in the graph that has a degree greater than 2 or an out-degree of 0.

pysewer.optimization.get_junction_front(G: Graph, junctions)[source]#

Returns a list of junctions or terminals which have as many entries for inflow trench depths as they have incoming edges.

Parameters:
  • G (networkx.DiGraph) – A directed graph representing the sewer network.

  • junctions (list) – A list of junctions or terminals in the sewer network.

Returns:

A list of junctions or terminals which have as many entries for inflow trench depths as they have incoming edges.

Return type:

list

pysewer.optimization.reverse_bfs(G, sink: str, include_private_sewer: bool = True)[source]#

Returns an iterator over edges in a sequential fashion, starting at the terminals (i.e. buildings) and returning all upstream edges of a junction before moving downstream

Parameters:
  • G (networkx.DiGraph) – The graph to traverse

  • sink (str) – The node to start the traversal from

  • include_private_sewer (bool, optional) – Whether to include private sewer nodes in the traversal, by default True

Yields:

tuple – A tuple representing an edge in the graph, in the form (source, target)

pysewer.optimization.calculate_hydraulic_parameters(G, sinks: list, pressurized_diameter: float | None = None, diameters: list[float] | None = None, roughness: float | None = None, include_private_sewer: bool | None = None, combined_sewer_factor: float = 1.0)[source]#

Calculates hydraulic parameters for a sewer network graph.

Parameters:
  • G (networkx.Graph) – The sewer network graph.

  • sinks (list) – A list of sink nodes in the graph.

  • pressurized_diameter (float) – The diameter of pressurized pipes in the network.

  • diameters (list) – A list of available pipe diameters.

  • roughness (float) – The roughness coefficient of the pipes.

  • include_private_sewer (bool, optional) – Whether to include private sewer connections in the graph, by default True.

  • combined_sewer_factor (float, optional) – Multiplicative factor applied to the dry-weather peak wastewater flow to represent additional stormwater and inflow contributions in a combined sewer system. The design flow used for pipe sizing becomes:

    Q_design = Q_peak_wastewater * combined_sewer_factor

    where Q_peak_wastewater is computed in estimate_peakflow as

    Q_peak_wastewater = (((P * daily_wastewater_person)/24) * peak_factor) / 3600

    with P being the total upstream population. Typical values vary by catchment and design standard; use calibration (see Notes) if a reference network exists.

Returns:

The sewer network graph with updated hydraulic parameters.

Return type:

networkx.Graph

Notes

This function places pumps/lifting stations on linear sections between road junctions. Three cases are possible: 1. Terrain does not allow for gravity flow to the downstream node (this check uses the “needs_pump” attribute from the preprocessing to reduce computational load) -> place pump 2. Terrain does not require pump but lowest inflow trench depth is too low for gravitational flow -> place lifting station 3. Gravity flow is possible within given constraints

If you need the modeled design flows or aggregate volumes to match a known/reference combined system (e.g., legacy network capacity), you can iteratively adjust combined_sewer_factor:

  1. Choose an initial value (e.g., 1–10).

  2. Run estimate_peakflow (dry-weather) and then this function with that factor.

  3. Compute a comparison metric (e.g., sum of edge design flows at a key cross-section,

    maximum trunk flow, or total storage/throughput proxy) and compare to the reference.

  4. Update the factor using a simple proportional control, e.g.,

    factor_new = factor_old * (ReferenceValue / ModeledValue), and iterate until within tolerance.

This approach scales the design flows uniformly and is a coarse substitute for a full hydrologic rainfall–runoff model when only reference totals are available.

pysewer.optimization.estimate_peakflow(G: Graph, inhabitants_dwelling: int | None = None, inhabitants_dwelling_attribute_name: str | None = None, daily_wastewater_person: float | None = None, peak_factor: float | None = None)[source]#

Estimate the peakflow in m³/s for a node n in Graph G.

Parameters:
  • G (networkx.Graph) – The graph to estimate peakflow for.

  • inhabitants_dwelling (int) – The number of inhabitants per dwelling to use if inhabitants_dwelling_attribute_name is empty.

  • inhabitants_dwelling_attribute_name (str) – The attribute name with the number of inhabitants per dwelling.

  • daily_wastewater_person (float) – The daily wastewater generated per person in m³.

  • peak_factor (float, optional) – The peak factor to use in the calculation, by default 2.3.

Returns:

The graph with updated node attributes for peak flow, average daily flow, and upstream pe.

Return type:

networkx.Graph

pysewer.optimization.mannings_equation(pipe_diameter: float, roughness: float, slope: float) float[source]#

Calculates the volume flow rate of a pipe using Manning’s equation.

Parameters:
  • pipe_diameter (float) – Diameter of the pipe in meters.

  • roughness (float) – Roughness coefficient of the pipe.

  • slope (float) – Slope of the pipe in units of elevation drop per unit length.

Returns:

Volume flow rate of the pipe in cubic meters per second.

Return type:

float

Raises:

ValueError – If the slope is greater than 0.

Notes

Manning’s equation is used to calculate the volume flow rate of a pipe based on its diameter, roughness coefficient, and slope.

pysewer.optimization.select_diameter(target_flow: float, diameters: list[float], roughness: float, slope: float)[source]#

Returns the minimum pipe diameter.

Parameters:
  • target_flow (float) – The target flow rate in cubic meters per second.

  • diameters (list) – A list of possible pipe diameters in meters.

  • roughness (float) – The pipe roughness coefficient in meters.

  • slope (float) – The pipe slope in meters per meter.

Returns:

The minimum pipe diameter required to achieve the target flow rate.

Return type:

float

Raises:

ValueError – If the maximum diameter is insufficient to reach the target flow rate.

pysewer.optimization.select_diameter_with_constraints(target_flow: float, diameters: list[float], roughness: float, slope: float, max_depth_ratio: float, vmin: float, vmax: float)[source]#

Pick the smallest diameter whose full-flow capacity satisfies the maximum depth ratio. Velocity bounds are evaluated at partial flow on the selected pipe and recorded as violations only: sizing cannot fix a slow pipe (a smaller pipe raises velocity but breaks capacity, a larger one lowers it further), so velocity must not drive the size choice.

Returns (diameter, violations).

pysewer.optimization.needs_pump(profile, min_slope: float | None = None, tmax: float | None = None, tmin: float | None = None, inflow_trench_depth: float | None = None)[source]#

Traces a profile to determine if gravitational flow can be achieved within slope and trench depth constraints.

Parameters:
  • profile (list of tuples) – A list of (x, y) tuples representing the profile to be traced.

  • min_slope (float, optional) – The minimum slope required for gravitational flow. Default is -0.01.

  • tmax (float, optional) – The maximum trench depth allowed. Default is 8.

  • tmin (float, optional) – The minimum trench depth allowed. Default is 0.25.

  • inflow_trench_depth (float, optional) – The trench depth at the inflow point. If not specified, it is set to tmin.

Returns:

A tuple containing: - A boolean indicating whether a pump is needed. - The height difference between the outflow and the trench depth at the outflow point. - A list of (x, trench_depth) tuples representing the trench depth at each point along the profile.

Return type:

tuple