SIIP Tutorial

Large Scale Production Cost Modeling with PowerSimulations.jl

Originally Contributed by: Clayton Barrows

Introduction

This example shows a basic PCM simulation using the system data assembled in the US-System example.

Dependencies

using PowerSystems
using PowerSimulations
using PowerGraphics
using Logging
using Dates

PSI = PowerSimulations
plotlyjs()
LoadError: ArgumentError: Package PlotlyJS not found in current path:
- Run `import Pkg; Pkg.add("PlotlyJS")` to install the PlotlyJS package.

Stacktrace:
  [1] require(into::Module, mod::Symbol)
    @ Base ./loading.jl:967

Optimization packages

You can use the free solvers as in one of the other PowerSimulations.jl examples, but on large problems it's useful to have a solver with better performance. I'll use the Xpress solver since I have a license, but others such as Gurobi or CPLEX work well too.

using Xpress
solver = optimizer_with_attributes(Xpress.Optimizer, "MIPRELSTOP" => 0.1, "OUTPUTLOG" => 1)
LoadError: ArgumentError: Package Xpress not found in current path:
- Run `import Pkg; Pkg.add("Xpress")` to install the Xpress package.

Stacktrace:
  [1] require(into::Module, mod::Symbol)
    @ Base ./loading.jl:967
  [2] eval
    @ ./boot.jl:373 [inlined]
  [3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base ./loading.jl:1196
  [4] include_string
    @ ./loading.jl:1180 [inlined]
  [5] #61
    @ ~/.julia/packages/Xranklin/rDvw7/src/context/code/notebook_code.jl:178 [inlined]
  [6] (::IOCapture.var"#3#5"{DataType, Xranklin.var"#61#62"{Module, String}, Task, IOContext{Base.PipeEndpoint}, IOContext{Base.PipeEndpoint}, Base.PipeEndpoint, Base.PipeEndpoint})()
    @ IOCapture ~/.julia/packages/IOCapture/sXY71/src/IOCapture.jl:118
  [7] with_logstate(f::Function, logstate::Any)
    @ Base.CoreLogging ./logging.jl:511
  [8] with_logger
    @ ./logging.jl:623 [inlined]
  [9] capture(f::Xranklin.var"#61#62"{Module, String}; rethrow::Type, color::Bool)
    @ IOCapture ~/.julia/packages/IOCapture/sXY71/src/IOCapture.jl:116
 [10] capture
    @ ~/.julia/packages/IOCapture/sXY71/src/IOCapture.jl:75 [inlined]
 [11] _eval_code_cell(mdl::Module, code::String, cell_name::String)
    @ Xranklin ~/.julia/packages/Xranklin/rDvw7/src/context/code/notebook_code.jl:177
 [12] eval_code_cell!(ctx::Xranklin.LocalContext, cell_code::SubString{String}, cell_name::String; imgdir_html::String, imgdir_latex::String, force::Bool, indep::Bool)
    @ Xranklin ~/.julia/packages/Xranklin/rDvw7/src/context/code/notebook_code.jl:114
 [13] html_code_block(b::FranklinParser.Block, lc::Xranklin.LocalContext)
    @ Xranklin ~/.julia/packages/Xranklin/rDvw7/src/convert/markdown/rules/code.jl:242

Load the US System.

If you have run the US-System example, the data will be serialized in the json and H5 format, so we can efficiently deserialize it:

pkgpath = joinpath("how-to", "create-system-representing-united-states", "data")

sys = System(joinpath("how-to", "create-system-representing-united-states", "data", "SIIP", "sys.json"))
horizon = 24;
interval = Dates.Hour(24);
transform_single_time_series!(sys, horizon, interval);
LoadError: IOError: cd("how-to/create-system-representing-united-states/data/SIIP"): no such file or directory (ENOENT)
Stacktrace:
  [1] uv_error
    @ ./libuv.jl:97 [inlined]
  [2] cd(dir::String)
    @ Base.Filesystem ./file.jl:89
  [3] PowerSystems.System(file_path::String; assign_new_uuids::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ PowerSystems ~/.julia/packages/PowerSystems/zVsmd/src/base.jl:183
  [4] PowerSystems.System(file_path::String)
    @ PowerSystems ~/.julia/packages/PowerSystems/zVsmd/src/base.jl:168

Selecting flow limited lines

Since PowerSimulations will apply constraints by component type (e.g. Line), we need to change the component type of the lines on which we want to enforce flow limits. So, let's change the device type of certain branches from Line to MonitoredLine differentiate treatment when we build the model. Here, we can select inter-regional lines, or lines above a voltage threshold.

for line in get_components(Line, sys)
    if (get_base_voltage(get_from(get_arc(line))) >= 230.0) &&
       (get_base_voltage(get_to(get_arc(line))) >= 230.0)
LoadError: syntax: incomplete: premature end of input
Stacktrace:

if getarea(get_from(get_arc(line))) != getarea(get_to(get_arc(line)))

@info "Changing $(get_name(line)) to MonitoredLine"
        convert_component!(MonitoredLine, line, sys)
    end
end
LoadError: UndefVarError: line not defined
Stacktrace:

Create a template

Now we can create a template that applies an unbounded formulation to Lines and the standard flow limited formulation to MonitoredLines.

template = ProblemTemplate(DCPPowerModel)
set_device_model!(template, Line, StaticBranchUnbounded)
set_device_model!(template, TapTransformer, StaticBranchUnbounded)
set_device_model!(template, MonitoredLine, StaticBranch)
set_device_model!(template, ThermalStandard, ThermalStandardUnitCommitment)
set_device_model!(template, RenewableDispatch, RenewableFullDispatch)
set_device_model!(template, PowerLoad, StaticPowerLoad)
set_device_model!(template, HydroDispatch, FixedOutput)

Build and execute single step problem

op_problem = DecisionModel(template, sys; optimizer=solver, horizon=24)

build!(op_problem, output_dir=mktempdir(), console_level=Logging.Info)

solve!(op_problem)
LoadError: UndefVarError: solver not defined
Stacktrace:

Analyze results

res = ProblemResults(op_problem)
plot_fuel(res)
LoadError: UndefVarError: op_problem not defined
Stacktrace:

Sequential Simulation

In addition to defining the formulation template, sequential simulations require definitions for how information flows between problems.

sim_folder = mkpath(joinpath(pkgpath, "Texas-sim"))
models = SimulationModels(
    decision_models=[
        DecisionModel(
            template,
            sys,
            name="UC",
            optimizer=solver,
            system_to_file=false,
        ),
    ],
)
DA_sequence =
    SimulationSequence(models=models, ini_cond_chronology=IntraProblemChronology())
LoadError: UndefVarError: solver not defined
Stacktrace:

Define and build a simulation

sim = Simulation(
    name="Texas-test",
    steps=3,
    models=models,
    sequence=DA_sequence,
    simulation_folder="Texas-sim",
)

build!(
    sim,
    console_level=Logging.Info,
    file_level=Logging.Debug,
    recorders=[:simulation],
)
LoadError: UndefVarError: models not defined
Stacktrace:

Execute the simulation

nb execute!(sim)

Load and analyze results

nb results = SimulationResults(sim); nb ucresults = getdecisionproblemresults(results, "UC");

nb plot_fuel(uc_results)

CC BY-SA 4.0 "Dheepak Krishnamurthy". Last modified: August 26, 2022. Website built with Franklin.jl and the Julia programming language.