PowerWaterModels.jl Documentation


PowerWaterModels.jl is a Julia/JuMP package for the joint optimization of steady-state power and water distribution networks. It is designed to enable the computational evaluation of historical and emerging power-water network optimization formulations and algorithms using a common platform. The code is engineered to decouple Problem Specifications (e.g., power-water flow, optimal power-water flow) from Network Formulations (e.g., mixed-integer linear, mixed-integer nonlinear). This decoupling enables the definition of a variety of optimization formulations and their comparison on common problem specifications.


The latest stable release of PowerWaterModels can be installed using the Julia package manager with

] add PowerWaterModels

For the current development version, install the package using

] add PowerWaterModels#master

Finally, test that the package works as expected by executing

] test PowerWaterModels

Usage at a Glance

At least one optimization solver is required to run PowerWaterModels. The solver selected typically depends on the type of problem formulation being employed. As an example, the mixed-integer nonlinear programming solver Juniper can be used for testing any of the problem formulations considered in this package. Juniper itself depends on the installation of a nonlinear programming solver (e.g., Ipopt) and a mixed-integer linear programming solver (e.g., HiGHS). Installation of the JuMP interfaces to Juniper, Ipopt, and HiGHS can be performed via the Julia package manager, i.e.,

] add JuMP Juniper Ipopt HiGHS

After installation of the required solvers, an example optimal power-water flow problem (whose file inputs can be found in the examples directory within the PowerWaterModels repository) can be solved via

using JuMP, Juniper, Ipopt, HiGHS
using PowerWaterModels

# Set up the optimization solvers.
ipopt = JuMP.optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0, "sb" => "yes")
highs = JuMP.optimizer_with_attributes(HiGHS.Optimizer, "log_to_console" => false)
juniper = JuMP.optimizer_with_attributes(
    Juniper.Optimizer, "nl_solver" => ipopt, "mip_solver" => highs,
    "time_limit" => 60.0)

# Specify paths to the power, water, and power-water linking files.
p_file = "examples/data/opendss/IEEE13_CDPSM.dss" # Power network.
w_file = "examples/data/epanet/cohen-short.inp" # Water network.
pw_file = "examples/data/json/zamzam.json" # Power-water linking.

# Specify the power and water formulation types separately.
pwm_type = PowerWaterModel{LinDist3FlowPowerModel, CRDWaterModel}

# Solve the joint optimal power-water flow problem and store the result.
result = solve_opwf(p_file, w_file, pw_file, pwm_type, juniper)

After solving the problem, results can then be analyzed, e.g.,

# Objective value, representing the cost of power generation.

# Generator 1's real power generation at the first time step.

# Pump 2's head gain at the third time step.