GithubHelp home page GithubHelp logo

mtanneau / opfgenerator Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ai4opt/opfgenerator

1.0 0.0 0.0 162 KB

Instance generator for OPF problems

License: MIT License

Shell 3.40% Julia 96.60%

opfgenerator's Introduction

Copyright Georgia Tech 2022-2024

Build codecov

OPFGenerator

Instance generator for various OPF problems (ACOPF & DCOPF currently supported)

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("[email protected]:AI4OPT/OPFGenerator.git")
  • Option 2: clone the repository. Use this if you want to change the code

    git clone [email protected]: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

Generating random instances

using Random, PGLib, PowerModels
using OPFGenerator
PowerModels.silence()

using StableRNGs
rng = StableRNG(42)

old_data = make_basic_network(pglib("3_lmbd"))

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

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

old_data["load"]["1"]["pd"]  # old 
1.1

new_data["load"]["1"]["pd"]  # new
1.1596456429775048

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

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

Building and solving OPF problems

OPFGenerator supports multiple OPF formulations, based on PowerModels.

using PowerModels
using PGLib

using JuMP
using Ipopt

using OPFGenerator

data = make_basic_network(pglib("14_ieee"))
acopf = OPFGenerator.build_opf(PowerModels.ACPPowerModel, data, Ipopt.Optimizer)
optimize!(acopf.model)
res = OPFGenerator.extract_result(acopf)

res["objective"]  # should be close to 2178.08041

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.

Solution format

Individual solutions are stored in a dictionary that follows the PowerModels result data format. As a convention, dual variables of equality constraints are named lam_<constraint_ref>, dual variables of (scalar) inequality constraints are named mu_<constraint_ref>, and dual variables of conic constraints are named nu_<constraint_ref>_<i> where i denotes the coordinate index.

Collections of instances & solutions are stored in a compact, array-based HDF5 file (see Datasets/Format below.)

ACPPowerModel

See PowerModels documentation.

Primal variables

Component Key Description
bus "vm" Nodal voltage magnitude
"va" Nodal voltage angle
generator "pg" Active power generation
"qg" Reactive power generation
branch "pf" Branch active power flow (fr)
"pt" Branch active power flow (to)
"qf" Branch reactive power flow (fr)
"qt" Branch reactive power flow (to)

Dual variables

Component Key Constraint
bus "mu_vm_lb" Nodal voltage magnitude lower bound
"mu_vm_ub" Nodal voltage magnitude upper bound
"lam_kirchhoff_active" Nodal active power balance
"lam_kirchhoff_reactive" Nodal reactive power balance
generator "mu_pg_lb" Active power generation lower bound
"mu_pg_ub" Active power generation upper bound
"mu_qg_lb" Reactive power generation lower bound
"mu_qg_ub" Reactive power generation upper bound
branch "mu_sm_fr" Thermal limit (fr)
"mu_sm_to" Thermal limit (to)
"lam_ohm_active_fr" Ohm's law; active power (fr)
"lam_ohm_active_to" Ohm's law; active power (to)
"lam_ohm_reactive_fr" Ohm's law; reactive power (fr)
"lam_ohm_reactive_to" Ohm's law; reactive power (to)
"mu_va_diff" Voltage angle difference

DCPPowerModel

See PowerModels documentation.

Primal variables

Component Key Description
bus "va" Voltage angle
generator "pg" Power generation
branch "pf" Power flow

Dual variables

Component Key Constraint
bus "lam_kirchhoff" Power balance
generator "mu_pg_lb" Power generation lower bound
"mu_pg_ub" Power generation upper bound
branch "lam_ohm" Ohm's law
"mu_sm_lb" Thermal limit (lower bound)
"mu_sm_ub" Thermal limit (upper bound)
"mu_va_diff" Voltage angle difference

SOCWRPowerModel

See PowerModels documentation.

Primal variables

Component Key Description
bus "w" Squared voltage magnitude
generator "pg" Active power generation
"qg" Reactive power generation
branch "pf" Branch active power flow (fr)
"pt" Branch active power flow (to)
"qf" Branch reactive power flow (fr)
"qt" Branch reactive power flow (to)
"wr" Real part of voltage product
"wi" Imaginary part of voltage product

Dual variables depend on whether a quadratic (SOCWRPowerModel) or conic (SOCWRConicPowerModel) formulation is considered. The former are identified with (quad), the latter with (cone) in the table below. Only the dual variables of quadratic constraints are affected by this distinction. Note that conic dual are high-dimensional variables, and separate coordinates are stored separately.

Component Key Constraint
bus "mu_vm_lb" Nodal voltage magnitude lower bound
"mu_vm_ub" Nodal voltage magnitude upper bound
"lam_kirchhoff_active" Nodal active power balance
"lam_kirchhoff_reactive" Nodal reactive power balance
generator "mu_pg_lb" Active power generation lower bound
"mu_pg_ub" Active power generation upper bound
"mu_qg_lb" Reactive power generation lower bound
"mu_qg_ub" Reactive power generation upper bound
branch "lam_ohm_active_fr" Ohm's law; active power (fr)
"lam_ohm_active_to" Ohm's law; active power (to)
"lam_ohm_reactive_fr" Ohm's law; reactive power (fr)
"lam_ohm_reactive_to" Ohm's law; reactive power (to)
"mu_va_diff_lb" Voltage angle difference lower bound
"mu_va_diff_ub" Voltage angle difference upper bound
"mu_sm_fr" (quad) Thermal limit (fr)
"mu_sm_to" (quad) Thermal limit (to)
"mu_voltage_prod_quad" (quad) Voltage product relaxation (Jabr)
"nu_voltage_prod_soc_1" (cone) Voltage product relaxation (Jabr)
"nu_voltage_prod_soc_2" (cone) Voltage product relaxation (Jabr)
"nu_voltage_prod_soc_3" (cone) Voltage product relaxation (Jabr)
"nu_voltage_prod_soc_4" (cone) Voltage product relaxation (Jabr)
"nu_sm_fr_1" (cone) Thermal limit (fr)
"nu_sm_fr_2" (cone) Thermal limit (fr)
"nu_sm_fr_3" (cone) Thermal limit (fr)
"nu_sm_to_1" (cone) Thermal limit (to)
"nu_sm_to_2" (cone) Thermal limit (to)
"nu_sm_to_3" (cone) Thermal limit (to)

Datasets

Format

Each dataset is stored in an .h5 file, organized as follows. See Solution format for a list of each formulation's primal and dual variables.

/
|-- meta
|   |-- ref
|   |-- config
|-- input
|   |-- seed
|   |-- pd
|   |-- qd
|   |-- br_status
|-- ACPPowerModel
|   |-- meta
|   |   |-- termination_status
|   |   |-- primal_status
|   |   |-- dual_status
|   |   |-- solve_time
|   |-- primal
|   |   |-- pg
|   |   |-- qg
|   |   |-- ...
|   |-- dual
|       |-- lam_kirchhoff_active
|       |-- lam_kirchhoff_reactive
|       |-- ...
|-- DCPPowerModel
|   |-- meta
|   |-- primal
|   |-- dual
|-- SOCWRConicPowerModel
    |-- meta
    |-- primal
    |-- dual

Loading from julia

using HDF5

D = h5read("dataset.h5", "/")  # read all the dataset into a dictionary

Loading from python

The following code provides a starting point to load h5 datasets in python

import h5py
import numpy as np


def parse_hdf5(path: str, preserve_shape: bool=False):
    dat = dict()

    def read_direct(dataset: h5py.Dataset):
        arr = np.empty(dataset.shape, dtype=dataset.dtype)
        dataset.read_direct(arr)
        return arr

    def store(name: str, obj):
        if isinstance(obj, h5py.Group):
            return
        elif isinstance(obj, h5py.Dataset):
            dat[name] = read_direct(obj)
        else:
            raise ValueError(f"Unexcepted type: {type(obj)} under name {name}. Expected h5py.Group or h5py.Dataset.")

    with h5py.File(path, "r") as f:
        f.visititems(store)

    if preserve_shape:
        # recursively correct the shape of the dictionary
        ret = dict()

        def r_correct_shape(d: dict, ret: dict):
            for k in list(d.keys()):
                if "/" in k:
                    k1, k2 = k.split("/", 1)
                    if k1 not in ret:
                        ret[k1] = dict()
                    r_correct_shape({k2: d[k]}, ret[k1])
                    del d[k]
                else:
                    ret[k] = d[k]

        r_correct_shape(dat, ret)

        return ret
    else:
        return dat

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.

opfgenerator's People

Contributors

mtanneau avatar klamike avatar ivanightingale avatar some-wallace avatar

Stargazers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.