Summary: The design_verification extension applies proposed pipe diameter changes and WNTR time and hydraulic simulation options to independent copies of a WNTR water-distribution network model. It runs hydraulic simulations and checks whether pressure, velocity and pump operating requirements are satisfied. The verification scope is limited to pipe diameters and the WNTR time and hydraulic option groups. Additional pipe parameters and operating conditions, including controls, are not included in the verification.

Point of contact: Rheal Thomas, thom1505

Overview#

The extension provides a repeatable hydraulic-verification layer for design, rehabilitation, optimisation and scenario-analysis workflows.

It can:

  • apply proposed pipe diameters without modifying the original network;

  • apply WNTR time and hydraulic simulation options;

  • run simulations using WNTRSimulator or EpanetSimulator;

  • assess minimum junction pressure;

  • assess maximum absolute pipe velocity;

  • audit head-pump flows against the maximum flow represented by their pump curves;

  • identify critical components and simulation times;

  • calculate compliance percentages;

  • return an overall hydraulic-feasibility result; and

  • produce an audit record describing the verification run.

Overall feasibility#

A verification is feasible only when:

  • the required pressure compliance is achieved;

  • the required velocity compliance is achieved; and

  • all head pumps pass the pump-curve audit.

A network containing no head pumps does not fail solely because the pump audit is not applicable.

Basic use#

A hydraulic scenario uses WNTR’s native simulation options:

>>> from wntr.network import Options
>>> from wntr.extensions.design_verification import HydraulicScenario
>>> options = Options()
>>> options.hydraulic.demand_model = "DD"
>>> options.time.duration = 0
>>> options.time.hydraulic_timestep = 3600
>>> options.time.report_timestep = 3600
>>> scenario = HydraulicScenario(
...     name="Baseline DD",
...     options=options,
... )
>>> scenario.name
'Baseline DD'
>>> isinstance(scenario.options, Options)
True

The following doctest builds a small water network, applies a candidate pipe-diameter design and hydraulic simulation options, and verifies the result against pressure and velocity constraints.

>>> import wntr
>>> from wntr.extensions.design_verification import (
...     HydraulicScenario,
...     PipeDesign,
...     run_design_verification,
... )
>>> wn = wntr.network.WaterNetworkModel()
>>> wn.add_reservoir(
...     "R1",
...     base_head=50.0,
...     coordinates=(0.0, 0.0),
... )
>>> wn.add_junction(
...     "J1",
...     base_demand=0.01,
...     demand_pattern=None,
...     elevation=10.0,
...     coordinates=(100.0, 0.0),
... )
>>> wn.add_pipe(
...     "P1",
...     start_node_name="R1",
...     end_node_name="J1",
...     length=100.0,
...     diameter=0.150,
...     roughness=100.0,
...     minor_loss=0.0,
... )
>>> options = wntr.network.Options()
>>> options.time.duration = 0
>>> options.time.hydraulic_timestep = 3600
>>> options.time.report_timestep = 3600
>>> options.hydraulic.demand_model = "DD"
>>> options.hydraulic.demand_multiplier = 1.0
>>> scenario = HydraulicScenario(
...     name="Baseline",
...     options=options,
... )
>>> design = PipeDesign(
...     name="Candidate pipe design",
...     diameters_m={"P1": 0.200},
... )
>>> verification, hydraulic_results, audit = run_design_verification(
...     wn=wn,
...     scenario=scenario,
...     design=design,
...     simulator="WNTRSimulator",
...     minimum_pressure_m=15.0,
...     maximum_velocity_mps=2.5,
... )
>>> print(f"Overall verification feasible: {verification.feasible}")
Overall verification feasible: True
>>> print(
...     "Minimum-pressure constraint satisfied: "
...     f"{verification.pressure_result.feasible}"
... )
Minimum-pressure constraint satisfied: True
>>> print(
...     "Maximum-velocity constraint satisfied: "
...     f"{verification.velocity_result.feasible}"
... )
Maximum-velocity constraint satisfied: True
>>> print(
...     "Critical pressure junction: "
...     f"{verification.pressure_result.critical_component}"
... )
Critical pressure junction: J1
>>> print(
...     "Critical velocity pipe: "
...     f"{verification.velocity_result.critical_component}"
... )
Critical velocity pipe: P1
>>> assert verification.feasible
>>> assert verification.pressure_result.feasible
>>> assert verification.velocity_result.feasible

The True results show that the candidate design satisfies both the minimum-pressure and maximum-velocity requirements for this scenario. The critical component outputs identify where the governing pressure and velocity values occurred.

Numerical tolerances#

Floating-point simulation results can differ from an engineering constraint by a very small numerical amount. Optional tolerances can therefore be applied at the pressure and velocity boundaries.

A junction-pressure observation is compliant when:

pressure >= minimum_pressure_m - pressure_tolerance_m

A pipe-velocity observation is compliant when:

abs(velocity) <= maximum_velocity_mps + velocity_tolerance_mps

Both tolerances must be finite and non-negative. Their default value is 0.0, which preserves strict comparison behaviour. Tolerances should be selected only to accommodate insignificant numerical variation and should not be used to conceal meaningful hydraulic constraint violations.

The selected tolerance values are recorded in the verification audit. For batch assessments, they are also recorded in every summary row and included in configuration_hash. Experiments using different tolerances therefore receive different configuration identities.

Checking expectations#

For routine analysis, verification results can be checked directly using simple assertions, as demonstrated in the doctest above. This keeps the workflow focused on whether a candidate design satisfies the hydraulic pressure, velocity and pump-operating requirements.

Returned information#

run_design_verification returns three objects.

verification

A structured result containing the pressure assessment, velocity assessment, pump-curve audit, simulator error code and overall feasibility result.

hydraulic_results

The raw hydraulic simulation results returned by WNTR.

audit

A dictionary recording the applied design, hydraulic scenario, simulator, engineering limits, assessed components and pump-curve audit.

Pressure assessment#

Pressure requirements are applied to demand junctions. Reservoirs and tanks are excluded from the minimum-pressure assessment.

The pressure result reports:

  • the minimum simulated pressure;

  • the pressure-compliance percentage;

  • whether the required compliance was achieved;

  • the critical junction; and

  • the critical simulation time.

Velocity assessment#

Velocity requirements are applied to pipes. Pumps and valves are excluded from the pipe-velocity assessment.

Absolute velocity is used so that reverse flow does not conceal a velocity-limit exceedance.

The velocity result reports:

  • the maximum absolute pipe velocity;

  • the velocity-compliance percentage;

  • whether the required compliance was achieved;

  • the critical pipe; and

  • the critical simulation time.

Pump-curve audit#

The pump audit evaluates active head-pump flow observations against the maximum flow represented by each pump curve.

When pump-speed information is available, the represented curve limit is adjusted using the simulated or configured operating speed.

A head pump fails the audit when an active flow exceeds its adjusted curve-domain limit. A head pump that cannot be evaluated does not silently pass the audit.

The pump audit checks whether simulated flow remains within the represented curve domain. It does not assess pump efficiency, energy consumption, cavitation, net positive suction head or manufacturer selection requirements.

Batch verification#

run_verification_batch evaluates every requested combination of pipe design, hydraulic scenario and simulator. It returns a summary pandas.DataFrame and a dictionary that can optionally retain the hydraulic results from successful experiments.

For example:

from wntr.extensions.design_verification import (
    run_verification_batch,
)

summary, hydraulic_results = run_verification_batch(
    wn=wn,
    scenarios=[
        baseline_scenario,
        peak_demand_scenario,
    ],
    designs=[
        None,
        candidate_design,
    ],
    simulators=(
        "WNTRSimulator",
        "EpanetSimulator",
    ),
    minimum_pressure_m=15.0,
    maximum_velocity_mps=2.5,
    required_compliance_pct=100.0,
    pressure_tolerance_m=1.0e-6,
    velocity_tolerance_mps=1.0e-8,
    continue_on_error=True,
    retain_hydraulic_results=False,
)

print(summary)

Using None in designs assesses the unchanged baseline network. When designs is omitted, only the baseline network is assessed.

Each batch row contains an experiment_id, network_hash and configuration_hash. The network_hash is a deterministic fingerprint of the serialized input water-network model. The configuration_hash includes that network identity together with the design, scenario, simulator, constraint limits, compliance requirement and numerical tolerances. Consequently, otherwise identical experiments on different network models receive different configuration hashes. The summary also records hydraulic feasibility, critical pressure and velocity information, pump diagnostics and any execution failure.

When continue_on_error=True, a failure during configuration preparation, hydraulic simulation or result processing is recorded as a failed row and the remaining combinations continue to run. If configuration preparation fails before a hash can be generated, the row uses unavailable for configuration_hash and an experiment_id ending in -unavailable. When continue_on_error=False, the first experiment failure is raised immediately.

Setting retain_hydraulic_results=True stores the hydraulic result object for each successful experiment in the returned dictionary, indexed by experiment_id. Retaining results can require substantial memory for large networks, long simulations or many experiment combinations.

Pump feasibility in batch summaries#

The pump_feasible field has three possible meanings:

  • True means that one or more head pumps were present and all evaluated pumps remained within the represented curve domain.

  • False means that one or more head pumps were present and at least one pump exceeded its represented curve domain or could not be evaluated safely.

  • A missing value with head_pumps_in_network equal to zero means that the network contained no head pumps to assess.

A missing pump_feasible value together with missing pump-count fields normally indicates that the experiment failed before a complete pump audit could be produced.

Additional pump-summary fields include head_pumps_evaluable, all_head_pumps_evaluable, number_of_pumps_exceeding_curves, total_curve_exceedance_observations, governing_pump_name and maximum_pump_flow_ratio.

Protection of the original network#

Pipe-diameter changes and WNTR time and hydraulic simulation options are applied to independent network copies. The original WaterNetworkModel supplied to run_design_verification is therefore preserved.

Verification selects junction-pressure and pipe-velocity results using WNTR’s junction and pipe name lists. WNTR’s network registry provides unique node and link names. Missing required result columns cause the corresponding pandas column selection to fail. Extra result columns for reservoirs, tanks, pumps, or valves are permitted and are excluded from the corresponding junction-pressure and pipe-velocity assessments.

Limitations#

Verification results depend on the quality and completeness of the network model, hydraulic options, demand assumptions, pump curves and simulation convergence. Existing network controls can influence the hydraulic simulation, but controls are not modified or parameterized by the design-verification extension.

Pressure and velocity limits are supplied by the user. Default values are not intended to replace applicable utility standards, engineering codes or regulatory requirements.

The extension verifies simulated hydraulic behaviour. It does not certify a design for construction or operation.