/OPFGenerator

Instance generator for OPF problems

Primary LanguageJuliaMIT LicenseMIT

Copyright Georgia Tech 2022-2024

Build codecov docs-dev

OPFGenerator

Instance generator for various OPF problems.

Installation instructions

This repository is a non-registered Julia package.

  • Option 1: install as a Julia package. You can use it, but not modify the code

    using Pkg
    Pkg.add("git@github.com:AI4OPT/OPFGenerator.git")
  • Option 2: clone the repository. Use this if you want to change the code

    git clone git@github.com:AI4OPT/OPFGenerator.git

    To use the package after cloning the repo

    $ cd OPFGenerator
    $ julia --project=.
    julia> using OPFGenerator

    If you are modifying the source code, it is recommened to use the package Revise.jl so that you can use the changes without having to start Julia. Make sure you load Revise before loading OPFGenerator in your julia session.

    using Revise
    using OPFGenerator

Using HSL solvers (ma27, ma57)

Please refer to Ipopt.jl installation instructions for how to install non-default linear solvers, e.g., HSL, Pardiso, etc... Note that a specific license may be required.

To use HSL linear solvers when solving OPF instances, set the parameter "linear_solver" to "ma27" or "ma57" in the config file. The recommended solver for Ipopt is ma27.

solver.name = "Ipopt"
solver.attributes.linear_solver = "ma27"

Quick start

Building and solving an OPF problem

using PGLib, PowerModels
using OPFGenerator
using Ipopt

# Load data from PGLib case
pm_network = PowerModels.make_basic_network(pglib("14_ieee"))
data = OPFGenerator.OPFData(pm_network)

# Build OPF optimization model
# To switch formulations, replace ACOPF with, e.g., DCOPF or SOCOPF
opf = OPFGenerator.build_opf(OPFGenerator.ACOPF, data, Ipopt.Optimizer)

# Solve and extract result
OPFGenerator.solve!(opf)
res = OPFGenerator.extract_result(opf)

Generating random OPF instances

using Random 
using PGLib, PowerModels
using OPFGenerator

# Load data from PGLib case
pm_network = PowerModels.make_basic_network(pglib("14_ieee"))
data = OPFGenerator.OPFData(pm_network)

# Load scaler using global scaling + uncorrelated LogNormal noise
config = Dict(
    "load" => Dict(
        "noise_type" => "ScaledUniform",
        "l" => 0.8,
        "u" => 1.2,
        "sigma" => 0.10,       
    )
)
opf_sampler = SimpleOPFSampler(data, config)

# Generate a new instance
rng = MersenneTwister(42)
new_data = rand(rng, opf_sampler)

data.pd[1] # old 
0.217

new_data.pd[1]  # new
0.21480423013573954  # ⚠️ exact value depends on Julia version)

To generate multiple instances, run the above code in a loop

dataset = [
    OPFGenerator.rand(rng, opf_sampler)
    for i in 1:100
]

Generating datasets

A script for generating multiple ACOPF instances is given in exp/sampler.jl.

It is called from the command-line as follows:

julia --project=. exp/sampler.jl <path/to/config.toml> <seed_min> <seed_max>

where

  • <path/to/config.toml> is a path to a valid configuration file in TOML format (see exp/config.toml for an example)
  • <seed_min> and <seed_max> are minimum and maximum values for the random seed. Must be integer values. The script will generate instances for values smin, smin+1, ..., smax-1, smax.

Acknowledgements

This material is based upon work supported by the National Science Foundation under Grant No. 2112533 NSF AI Institute for Advances in Optimization (AI4OPT). Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.