Modeling with JuMP

This page shows a minimal example of PowerSystems.jl used to develop and Economic Dispatch model. The code shows the stages to develop modeling code

  1. Make the data set from power flow and time series data,
  2. Serialize the data,
  3. Pass the data and algorithm to the model.

One of the main uses of `PowerSystems.jl is not having re-run the data generation for every model execution. The model code shows an example of populating the constraints and cost functions using accessor functions inside the model function. The example concludes by reading the data created earlier and passing the algorithm with the data.

using PowerSystems
const PSY = PowerSystems
using JuMP
using Ipopt

system_data = System(joinpath(DATA_DIR, "matpower/case5_re.m"))
add_time_series!(system_data, joinpath(DATA_DIR,"forecasts/5bus_ts/timeseries_pointers_da.json"))
to_json(system_data, "system_data.json")


function ed_model(system::System, optimizer)
    ed_m = Model(optimizer)
    time_periods = 24
    thermal_gens_names = get_name.(get_components(ThermalStandard, system))
    @variable(ed_m, pg[g in thermal_gens_names, t in time_periods] >= 0)

    for g in get_components(ThermalStandard, system), t in time_periods
        name = get_name(g)
        @constraint(ed_m, pg[name, t] >= get_active_power_limits(g).min)
        @constraint(ed_m, pg[name, t] <= get_active_power_limits(g).max)
    end

    net_load = zeros(time_periods)
    for g in get_components(RenewableGen, system)
        net_load -= get_time_series_values(SingleTimeSeries, g, "max_active_power")
    end

    for g in get_components(StaticLoad, system)
        net_load += get_time_series_values(SingleTimeSeries, g, "max_active_power")
    end

    for t in time_periods
        @constraint(ed_m, sum(pg[g, t] for g in thermal_gens_names) == net_load[t])
    end

    @objective(ed_m, Min, sum(
            pg[get_name(g), t]^2*get_cost(get_variable(get_operation_cost(g)))[1] +
            pg[get_name(g), t]*get_cost(get_variable(get_operation_cost(g)))[2]
            for g in get_components(ThermalGen, system), t in time_periods
                )
            )

    return optimize!(ed_m)
end

system_data = System("system_data.json")
results = ed_model(system_data, Ipopt.Optimizer)
[ Info: extending matpower format with data: areas 1x3
[ Info: extending matpower format with data: gen_name 7x4
[ Info: extending matpower format by appending matrix "gen_name" in to "gen"
[ Info: reversing the orientation of branch 6 (4, 3) to be consistent with other parallel branches
[ Info: the voltage setpoint on generator 4 does not match the value at bus 4
[ Info: the voltage setpoint on generator 1 does not match the value at bus 1
[ Info: the voltage setpoint on generator 5 does not match the value at bus 10
[ Info: the voltage setpoint on generator 2 does not match the value at bus 1
[ Info: the voltage setpoint on generator 3 does not match the value at bus 3
[ Info: removing 1 cost terms from generator 4: [4000.0, 0.0]
[ Info: removing 1 cost terms from generator 1: [1400.0, 0.0]
[ Info: removing 1 cost terms from generator 5: [1000.0, 0.0]
[ Info: removing 1 cost terms from generator 2: [1500.0, 0.0]
[ Info: removing 3 cost terms from generator 6: Float64[]
[ Info: removing 3 cost terms from generator 7: Float64[]
[ Info: removing 1 cost terms from generator 3: [3000.0, 0.0]
┌ Info: Constructing System from Power Models
│   data["name"] = "nesta_case5_pjm"
└   data["source_type"] = "matpower"
[ Info: Reading bus data
[ Info: Reading generator data
[ Info: Reading branch data
┌ Warning: Rate 1200.0 MW for bus2-bus3-i_4 is larger than the max expected in the range of (min = 134.0, max = 145.0).
└ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/utils/IO/branchdata_checks.jl:148
┌ Warning: Rate 200.0 MW for bus1-bus2-i_1 is larger than the max expected in the range of (min = 134.0, max = 145.0).
└ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/utils/IO/branchdata_checks.jl:148
┌ Warning: Rate 200.0 MW for bus1-bus4-i_2 is larger than the max expected in the range of (min = 134.0, max = 145.0).
└ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/utils/IO/branchdata_checks.jl:148
┌ Warning: Rate 200.0 MW for bus4-bus5-i_7 is larger than the max expected in the range of (min = 134.0, max = 145.0).
└ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/utils/IO/branchdata_checks.jl:148
┌ Warning: Rate 1000.0 MW for bus1-bus5-i_3 is larger than the max expected in the range of (min = 134.0, max = 145.0).
└ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/utils/IO/branchdata_checks.jl:148
[ Info: Reading branch data
[ Info: Reading DC Line data
[ Info: Reading storage data
[ Info: Serialized time series data to system_data_time_series_storage.h5.
[ Info: Serialized System to system_data.json
[ Info: Loaded time series from storage file existing=system_data_time_series_storage.h5 new=/tmp/jl_6UcrCO compression=CompressionSettings(false, CompressionTypes.DEFLATE = 1, 3, true)
┌ Warning: Rate 1000.0 MW for bus1-bus5-i_3 is larger than the max expected in the range of (min = 134.0, max = 145.0).
└ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/utils/IO/branchdata_checks.jl:148
┌ Warning: Rate 200.0 MW for bus1-bus4-i_2 is larger than the max expected in the range of (min = 134.0, max = 145.0).
└ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/utils/IO/branchdata_checks.jl:148
┌ Warning: Rate 200.0 MW for bus1-bus2-i_1 is larger than the max expected in the range of (min = 134.0, max = 145.0).
└ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/utils/IO/branchdata_checks.jl:148
┌ Warning: Rate 200.0 MW for bus4-bus5-i_7 is larger than the max expected in the range of (min = 134.0, max = 145.0).
└ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/utils/IO/branchdata_checks.jl:148
┌ Warning: Rate 1200.0 MW for bus2-bus3-i_4 is larger than the max expected in the range of (min = 134.0, max = 145.0).
└ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/utils/IO/branchdata_checks.jl:148

******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit https://github.com/coin-or/Ipopt
******************************************************************************

This is Ipopt version 3.13.4, running with linear solver mumps.
NOTE: Other linear solvers might be more efficient (see Ipopt documentation).

Number of nonzeros in equality constraint Jacobian...:        5
Number of nonzeros in inequality constraint Jacobian.:       10
Number of nonzeros in Lagrangian Hessian.............:        0

Total number of variables............................:        5
                     variables with only lower bounds:        5
                variables with lower and upper bounds:        0
                     variables with only upper bounds:        0
Total number of equality constraints.................:        1
Total number of inequality constraints...............:       10
        inequality constraints with only lower bounds:        5
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        5

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  1.0899989e+00 7.76e+00 6.07e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  4.1772942e+01 5.86e+00 3.94e+01  -1.0 1.62e+00    -  6.48e-03 2.45e-01h  1
   2  2.5126066e+01 5.74e+00 3.86e+01  -1.0 3.84e+01    -  1.40e-02 2.01e-02f  1
   3  2.6275680e+01 5.58e+00 3.75e+01  -1.0 8.75e+00    -  2.95e-01 2.93e-02h  1
   4  3.2142453e+01 4.78e+00 3.21e+01  -1.0 8.68e+00    -  2.33e-01 1.43e-01h  1
   5  4.6510267e+01 3.25e+00 2.32e+01  -1.0 5.56e+00    -  1.00e+00 3.19e-01h  1
   6  6.3496663e+01 1.61e+00 1.14e+01  -1.0 3.02e+00    -  5.86e-01 5.06e-01h  1
   7  6.7959825e+01 1.29e+00 9.50e+00  -1.0 1.66e+00    -  1.00e+00 1.99e-01h  1
   8  7.2487883e+01 9.85e-01 8.36e+00  -1.0 1.22e+00    -  1.03e-01 2.35e-01h  1
   9  8.7328266e+01 0.00e+00 1.00e-06  -1.0 1.03e+00    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  8.6924994e+01 0.00e+00 2.00e-07  -1.7 1.68e-02    -  1.00e+00 1.00e+00f  1
  11  8.6806908e+01 0.00e+00 6.67e-03  -3.8 1.81e-02    -  9.49e-01 1.00e+00f  1
  12  8.6804532e+01 8.88e-16 1.50e-09  -3.8 2.45e-03    -  1.00e+00 1.00e+00f  1
  13  8.6803646e+01 8.88e-16 1.85e-11  -5.7 1.43e-04    -  1.00e+00 1.00e+00f  1
  14  8.6803635e+01 0.00e+00 2.66e-14  -8.6 1.99e-06    -  1.00e+00 1.00e+00f  1

Number of Iterations....: 14

                                   (scaled)                 (unscaled)
Objective...............:   8.6803634508060696e+01    8.6803634508060696e+01
Dual infeasibility......:   2.6645352591003757e-14    2.6645352591003757e-14
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   2.5308018350058887e-09    2.5308018350058887e-09
Overall NLP error.......:   2.5308018350058887e-09    2.5308018350058887e-09


Number of objective function evaluations             = 15
Number of objective gradient evaluations             = 15
Number of equality constraint evaluations            = 15
Number of inequality constraint evaluations          = 15
Number of equality constraint Jacobian evaluations   = 1
Number of inequality constraint Jacobian evaluations = 1
Number of Lagrangian Hessian evaluations             = 1
Total CPU secs in IPOPT (w/o function evaluations)   =      0.305
Total CPU secs in NLP function evaluations           =      0.130

EXIT: Optimal Solution Found.