Water Quality

EPyT-Flow supports basic and advanced water quality analysis – the former is realized through EPANET and the latter one through the usage of EPANET-MSX.

Basic Water Quality Analysis

The basic water quality analysis supports water age analysis, simple chemical analysis, and source tracing analysis.

Note

Note that only one of these analyses can be performed at a time – i.e. multiple simulation runs are necessary if different quality analyses are requested.

If the hydraulic analysis of the WDN has already been computed and stored as an .hyd file, those can be utilized when running the quality analysis without having to re-compute the hydraulics. The functions run_basic_quality_simulation() and run_basic_quality_simulation_as_generator() of a ScenarioSimulator instance run the quality analysis without re-computing the hydraulics.

The requested quality analysis must be set (i.e. activated) before the simulation is run:

Quality Analysis

Function for enabling the analysis

Water age

enable_waterage_analysis()

Chemical

enable_chemical_analysis()

Source tracing

enable_sourcetracing_analysis()

In order to access the quality results, quality sensors must be placed at the links and nodes of interest.

Example for performing a water age analysis at all nodes:

# Open/Create a new scenario based on the Hanoi network
network_config = load_hanoi()
with ScenarioSimulator(scenario_config=network_config) as sim:
    # Enable water age analysis
    sim.enable_waterage_analysis()

    # Places quality sensors at all nodes -- i.e. measuring the water age at each node
    sim.set_node_quality_sensors(sensor_locations=sim.sensor_config.nodes)

    # Run simulation
    scada_data = sim.run_simulation()

    # Retrieve simulated water age at all nodes
    nodes_quality = scada_data.get_data_nodes_quality()

Chemical Analysis

In the case of a chemical analysis, it is also necessary to set at least one source of chemicals if not already set in the .inp file. This can be done by calling add_quality_source() of the ScenarioSimulator instance. Besides the location (i.e. node ID), the source pattern together with its type and (name, optional) must be specified as well. Note that the pattern repeats automatically when the simulation duration exceeds the pattern length.

# ...

# Adds a source pattern called "my-pattern" at node "1".
# The pattern alternates the chemical concentration leaving this node between 1. and 0.
sim.add_quality_source(node_id="1", pattern_id="my-pattern",
                        pattern=numpy.array([1., 0.]),
                        source_type=EpanetConstants.EN_SETPOINT)

Different types of source patterns are supported:

Source type

Description

EN_CONCEN

Sets the concentration of external inflow entering a node

EN_MASS

Injects a given mass/minute into a node

EN_SETPOINT

Sets the concentration leaving a node to a given value

EN_FLOWPACED

Adds a given value to the concentration leaving a node

Furthermore, initial node concentrations, and reaction options such as bulk and wall coefficients can be set as well by either setting the options in the .inp file or by calling set_quality_parameters().

Example of running a chemical analysis where the concentration at the reservoir is fixed over time.

# Open/Create a new scenario based on the Hanoi network
network_config = load_hanoi()
with ScenarioSimulator(scenario_config=network_config) as sim:
    # Enable chemical analysis
    sim.enable_chemical_analysis()

    # Sets the concentration at node "1" (reservoir) to 1.0 for all time steps --
    # this constant concentration pattern is named "my-constant-pattern"
    sim.add_quality_source(node_id="1", pattern_id="my-constant-pattern",
                            pattern=numpy.array([1.]),
                            source_type=EpanetConstants.EN_CONCEN)

    # Places quality sensors at all nodes --
    # i.e. measuring the chemical concentration at all nodes
    sim.set_node_quality_sensors(sensor_locations=sim.sensor_config.nodes)

    # Run simulation
    scada_data = sim.run_simulation()

    # Retrieve simulated chemical concentrations at all nodes
    nodes_quality = scada_data.get_data_nodes_quality()

Advanced Water Quality Analysis

EPyT-Flow provides advanced water quality analysis through EPANET-MSX.

The central concept in advanced quality analysis is the concept of a species. A species can be living matter such as bacteria or chemicals such as chlorine, arsenite, etc. In EPANET-MSX, we distinguish between two types of species: bulk species, which are species “living” in the water, and surface/wall species, which are species “living” on link/pipe walls. The interaction of different species is modeled by reaction equations.

More details about species and their reaction equations can be found in the EPANET-MSX user manual.

The adavanced quality analysis requires an additional .msx file (f_msx_in) when creating a new ScenarioSimulator instance:

scenario = ScenarioSimulator(f_inp_in="net2-cl2.inp", f_msx_in="net2-cl2.msx")

The .msx file contains the specifications of different species as well as their reaction dynamics. By passing an .msx file to f_msx_in, EPANET-MSX is loaded and initialized automatically.

Specifying an injection of an existing species can be done by calling the function add_species_injection_source(). In addition, note that injection events are also implemented. In this context, note that the pattern time step is equivalent to the EPANET pattern time step.

Specifying the initial concentration of bulk and surface species can be done by calling the functions set_bulk_species_node_initial_concentrations() and set_species_link_initial_concentrations()

When running the simulation by calling run_simulation(), first the hydraulics for the entire duration are simulated, and then the quality dynamics for the entire duration.

Similar to the case of basic quality analysis, if the hydraulic analysis of the WDN has already been computed and stored as an .hyd file, those can be utilized when running the advanced quality analysis without having to re-compute the hydraulics. The functions run_advanced_quality_simulation() and run_advanced_quality_simulation_as_generator() of a ScenarioSimulator instance run the advanced quality analysis without re-computing the hydraulics.

Note

EPANET and EPANET-MSX do NOT support the simultaneous step-wise simulation of hydraulics and advanced quality.

Similar to all other quantities, species sensors must be specified in order to retrieve the concentrations of those species.

Example of a scenario where we want to monitor chlorine in Net2:

# Load EPANET-MSX scenario "net2-cl2" -- note that an .inp file as well
# as an .msx file is required
with ScenarioSimulator(f_inp_in="net2-cl2.inp", f_msx_in="net2-cl2.msx") as sim:
    # Set simulation duration to 5 days
    sim.set_general_parameters(simulation_duration=to_seconds(days=5))

    # Monitor bulk species "CL2" at every node
    sim.set_bulk_species_node_sensors(sensor_info={"CL2": sim.sensor_config.nodes})

    # Run entire simulation
    res = sim.run_simulation(verbose=True)

    # Show concentration of chlorine species at every node
    print(res.get_data_bulk_species_node_concentration())