Skip to content

Commit

Permalink
Merge pull request e2nIEE#1191 from MMajidi137/develop
Browse files Browse the repository at this point in the history
fix tol issue for powermodels
  • Loading branch information
MMajidi137 authored Aug 13, 2021
2 parents 9be21a0 + 1e811b7 commit ac0a6c1
Show file tree
Hide file tree
Showing 9 changed files with 483 additions and 493 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ pandapower/test/timeseries/run_timeseries_output/*
pandapower/timeseries/logs/*
*/data/*
/.vscode/

pandapower/test/opf/buffer_file.json

pandapower/test/buffer_file.json
793 changes: 389 additions & 404 deletions pandapower/converter/powermodels/to_pm.py

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions pandapower/opf/pm_storage.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import numpy as np
import pandas as pd


def add_storage_opf_settings(net, ppci, pm):
# callback function to add storage settings. Must be called after initializing pm data structure since the
# pm["storage"] dict is filled
Expand Down Expand Up @@ -52,7 +51,6 @@ def add_storage_opf_settings(net, ppci, pm):
"discharge_efficiency": 1.0
}


def read_pm_storage_results(net):
# reads the storage results from multiple time steps from the PowerModels optimization
pm_result = net._pm_result
Expand Down Expand Up @@ -90,3 +88,4 @@ def read_pm_storage_results(net):
# print("\n")

return storage_results

1 change: 0 additions & 1 deletion pandapower/opf/pp_2_pm.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

module PP2PM
export load_pm_from_json, get_model, get_solver

Expand Down
15 changes: 1 addition & 14 deletions pandapower/opf/run_powermodels.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
using PowerModels
using .PP2PM
#using Debugger
# include("pp_2_pm.jl")

function run_powermodels(json_path)
pm = PP2PM.load_pm_from_json(json_path)
model = PP2PM.get_model(pm["pm_model"])
#
solver = PP2PM.get_solver(pm["pm_solver"], pm["pm_nl_solver"], pm["pm_mip_solver"],
pm["pm_log_level"], pm["pm_time_limit"], pm["pm_nl_time_limit"], pm["pm_mip_time_limit"], pm["tol"])
pm["pm_log_level"], pm["pm_time_limit"], pm["pm_nl_time_limit"], pm["pm_mip_time_limit"], pm["pm_tol"])

if haskey(pm["branch"]["1"],"c_rating_a")
for (key, value) in pm["gen"]
Expand All @@ -30,9 +28,6 @@ function run_powermodels(json_path)
value["qd"] *= 0.01
end

# pm["bus"]["4"]["vmax"] = 1.1
# pm["bus"]["4"]["vmin"] = 0.9

result = PowerModels._run_opf_cl(pm, model, solver,
setting = Dict("output" => Dict("branch_flows" => true)))
else
Expand All @@ -47,11 +42,3 @@ function run_powermodels(json_path)
return result
end


# json_path = "C:/Users/fmeier/pandapower/pandapower/test/opf/case5_clm_matfile_va.json"
# # #@enter run_powermodels(json_path)
# #
# result = run_powermodels(json_path)
# println(result["termination_status"] == LOCALLY_SOLVED)
# println(isapprox(result["objective"], 17015.5; atol = 1e0))
# mit eingeschränkter slack spannung: 17082.819507648066
5 changes: 0 additions & 5 deletions pandapower/opf/run_powermodels.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,12 @@ def _runpm(net, delete_buffer_file=True, pm_file_path = None): # pragma: no cov
"""
Converts the pandapower net to a pm json file, saves it to disk, runs a PowerModels.jl julia function and reads
the results back to the pandapower net
INPUT
----------
**net** - pandapower net
OPTIONAL
----------
**delete_buffer_file** (bool, True) - deletes the pm buffer json file if True.
"""
# convert pandapower to power models file -> this is done in python
net, pm, ppc, ppci = convert_to_pm_structure(net)
Expand All @@ -40,7 +36,6 @@ def _runpm(net, delete_buffer_file=True, pm_file_path = None): # pragma: no cov
# delete buffer file after calculation
os.remove(buffer_file)


def _call_powermodels(buffer_file, julia_file): # pragma: no cover
# checks if julia works, otherwise raises an error
try:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
using PowerModels
using Ipopt
using Gurobi
using JuMP
using .PP2PM

import JSON

function read_time_series(json_path)
time_series = Dict()
open(json_path, "r") do f
Expand Down
106 changes: 49 additions & 57 deletions pandapower/runpm.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def runpm(net, julia_file=None, pp_to_pm_callback=None, calculate_voltage_angles
trafo_model="t", delta=1e-8, trafo3w_losses="hv", check_connectivity=True,
correct_pm_network_data=True, pm_model="ACPPowerModel", pm_solver="ipopt",
pm_mip_solver="cbc", pm_nl_solver="ipopt", pm_time_limits=None, pm_log_level=0,
delete_buffer_file=True, pm_file_path = None, opf_flow_lim="S", **kwargs): # pragma: no cover
delete_buffer_file=True, pm_file_path = None, opf_flow_lim="S", pm_tol=1e-8, **kwargs): # pragma: no cover
"""
Runs a power system optimization using PowerModels.jl. with a custom julia file.
Expand Down Expand Up @@ -82,9 +82,10 @@ def runpm(net, julia_file=None, pp_to_pm_callback=None, calculate_voltage_angles
delete_buffer_file to False!
**opf_flow_lim** (str, "I") - Quantity to limit for branch flow constraints, in line with matpower's
"opf.flowlim" parameter
"S" - apparent power flow (limit in MVA),
"I" - current magnitude (limit in MVA at 1 p.u. voltage)
"opf.flowlim" parameter:
"S" - apparent power flow (limit in MVA),
"I" - current magnitude (limit in MVA at 1 p.u. voltage)
**pm_tol** (float, 1e-8) - default desired convergence tolerance for solver to use.
"""
net._options = {}
ac = True if "DC" not in pm_model else False
Expand All @@ -98,14 +99,15 @@ def runpm(net, julia_file=None, pp_to_pm_callback=None, calculate_voltage_angles
pp_to_pm_callback=pp_to_pm_callback, julia_file=julia_file, pm_solver=pm_solver, pm_model=pm_model,
correct_pm_network_data=correct_pm_network_data, pm_mip_solver=pm_mip_solver,
pm_nl_solver=pm_nl_solver, pm_time_limits=pm_time_limits, pm_log_level=pm_log_level,
opf_flow_lim=opf_flow_lim)
opf_flow_lim=opf_flow_lim, pm_tol=pm_tol)
_runpm(net, delete_buffer_file=delete_buffer_file, pm_file_path = pm_file_path)


def runpm_dc_opf(net, pp_to_pm_callback=None, calculate_voltage_angles=True,
trafo_model="t", delta=1e-8, trafo3w_losses="hv", check_connectivity=True,
correct_pm_network_data=True, pm_model="DCPPowerModel", pm_solver="ipopt",
pm_time_limits=None, pm_log_level=0, delete_buffer_file=True, pm_file_path = None, **kwargs): # pragma: no cover
pm_time_limits=None, pm_log_level=0, delete_buffer_file=True, pm_file_path = None,
pm_tol=1e-8, **kwargs): # pragma: no cover
"""
Runs a linearized power system optimization using PowerModels.jl.
Expand Down Expand Up @@ -155,28 +157,28 @@ def runpm_dc_opf(net, pp_to_pm_callback=None, calculate_voltage_angles=True,
{"pm_time_limit": 300.}
**pm_log_level** (int, 0) - solver log level in power models
**pm_tol** (float, 1e-8) - default desired convergence tolerance for solver to use.
"""
julia_file = os.path.join(pp_dir, "opf", 'run_powermodels.jl')
ac = True if "DC" not in pm_model else False

net._options = {}
_add_ppc_options(net, calculate_voltage_angles=calculate_voltage_angles,
trafo_model=trafo_model, check_connectivity=check_connectivity,
mode="opf", switch_rx_ratio=2, init_vm_pu="flat", init_va_degree="flat",
enforce_q_lims=True, recycle=dict(_is_elements=False, ppc=False, Ybus=False),
voltage_depend_loads=False, delta=delta, trafo3w_losses=trafo3w_losses)
_add_opf_options(net, trafo_loading='power', ac=ac, init="flat", numba=True,
_add_opf_options(net, trafo_loading='power', ac=False, init="flat", numba=True,
pp_to_pm_callback=pp_to_pm_callback, julia_file=julia_file,
correct_pm_network_data=correct_pm_network_data, pm_model=pm_model, pm_solver=pm_solver,
pm_time_limits=pm_time_limits, pm_log_level=pm_log_level, opf_flow_lim="S")
pm_time_limits=pm_time_limits, pm_log_level=pm_log_level, opf_flow_lim="S", pm_tol=pm_tol)
_runpm(net, delete_buffer_file, pm_file_path)


def runpm_ac_opf(net, pp_to_pm_callback=None, calculate_voltage_angles=True,
trafo_model="t", delta=1e-8, trafo3w_losses="hv", check_connectivity=True,
pm_model="ACPPowerModel", pm_solver="ipopt", correct_pm_network_data=True,
pm_time_limits=None, pm_log_level=0, pm_file_path = None, delete_buffer_file=True,
opf_flow_lim="S", tol=1e-8, **kwargs): # pragma: no cover
opf_flow_lim="S", pm_tol=1e-8, **kwargs): # pragma: no cover
"""
Runs a non-linear power system optimization using PowerModels.jl.
Expand Down Expand Up @@ -241,48 +243,40 @@ def runpm_ac_opf(net, pp_to_pm_callback=None, calculate_voltage_angles=True,
"""

julia_file = os.path.join(pp_dir, "opf", 'run_powermodels.jl')
ac = True if "DC" not in pm_model else False

net._options = {}
_add_ppc_options(net, calculate_voltage_angles=calculate_voltage_angles,
trafo_model=trafo_model, check_connectivity=check_connectivity,
mode="opf", switch_rx_ratio=2, init_vm_pu="flat", init_va_degree="flat",
enforce_q_lims=True, recycle=dict(_is_elements=False, ppc=False, Ybus=False),
voltage_depend_loads=False, delta=delta, trafo3w_losses=trafo3w_losses)
_add_opf_options(net, trafo_loading='power', ac=ac, init="flat", numba=True,
voltage_depend_loads=False, delta=delta, trafo3w_losses=trafo3w_losses)
_add_opf_options(net, trafo_loading='power', ac=True, init="flat", numba=True,
pp_to_pm_callback=pp_to_pm_callback, julia_file=julia_file, pm_model=pm_model, pm_solver=pm_solver,
correct_pm_network_data=correct_pm_network_data, pm_time_limits=pm_time_limits,
pm_log_level=pm_log_level, opf_flow_lim=opf_flow_lim, tol=tol)
pm_log_level=pm_log_level, opf_flow_lim=opf_flow_lim, pm_tol=pm_tol)

_runpm(net, pm_file_path=pm_file_path, delete_buffer_file=delete_buffer_file)


def runpm_tnep(net, pp_to_pm_callback=None, calculate_voltage_angles=True,
trafo_model="t", delta=1e-8, trafo3w_losses="hv", check_connectivity=True,
pm_model="DCPPowerModel", pm_solver=None, correct_pm_network_data=True,
pm_nl_solver="ipopt", pm_mip_solver="cbc", pm_time_limits=None, pm_log_level=0,
opf_flow_lim="S", **kwargs): # pragma: no cover
opf_flow_lim="S", pm_tol=1e-8, **kwargs): # pragma: no cover
"""
Runs a non-linear transmission network extension planning (tnep) optimization using PowerModels.jl.
OPTIONAL:
**julia_file** (str, None) - path to a custom julia optimization file
**pp_to_pm_callback** (function, None) - callback function to add data to the PowerModels data structure
**correct_pm_network_data** (bool, True) - checks if network data is correct. If not tries to correct it
**pm_model** (str, "ACPPowerModel") - The PowerModels.jl model to use
**pm_solver** (str, "juniper") - The "main" power models solver
**pm_mip_solver** (str, "cbc") - The mixed integer solver (when "main" solver == juniper)
**pm_nl_solver** (str, "ipopt") - The nonlinear solver (when "main" solver == juniper)
**pm_time_limits** (Dict, None) - Time limits in seconds for power models interface. To be set as a dict like
{"pm_time_limit": 300., "pm_nl_time_limit": 300., "pm_mip_time_limit": 300.}
**pm_log_level** (int, 0) - solver log level in power models
**pm_log_level** (int, 0) - solver log level in power model
**pm_tol** (float, 1e-8) - default desired convergence tolerance for solver to use.
"""
julia_file = os.path.join(pp_dir, "opf", 'run_powermodels_tnep.jl')
ac = True if "DC" not in pm_model else False
Expand All @@ -304,39 +298,29 @@ def runpm_tnep(net, pp_to_pm_callback=None, calculate_voltage_angles=True,
pp_to_pm_callback=pp_to_pm_callback, julia_file=julia_file, pm_model=pm_model, pm_solver=pm_solver,
correct_pm_network_data=correct_pm_network_data, pm_nl_solver=pm_nl_solver,
pm_mip_solver=pm_mip_solver, pm_time_limits=pm_time_limits, pm_log_level=pm_log_level,
opf_flow_lim=opf_flow_lim)
opf_flow_lim=opf_flow_lim, pm_tol=pm_tol)
_runpm(net)
read_tnep_results(net)


def runpm_ots(net, pp_to_pm_callback=None, calculate_voltage_angles=True,
trafo_model="t", delta=1e-8, trafo3w_losses="hv", check_connectivity=True,
pm_model="DCPPowerModel", pm_solver="juniper", pm_nl_solver="ipopt", pm_mip_solver="cbc",
correct_pm_network_data=True, pm_time_limits=None, pm_log_level=0, **kwargs): # pragma: no cover
correct_pm_network_data=True, pm_time_limits=None, pm_log_level=0, pm_tol=1e-8, **kwargs): # pragma: no cover
"""
Runs a non-linear optimal transmission switching (OTS) optimization using PowerModels.jl.
OPTIONAL:
**julia_file** (str, None) - path to a custom julia optimization file
**pp_to_pm_callback** (function, None) - callback function to add data to the PowerModels data structure
**correct_pm_network_data** (bool, True) - checks if network data is correct. If not tries to correct it
**pm_model** (str, "ACPPowerModel") - The PowerModels.jl model to use
**pm_solver** (str, "juniper") - The "main" power models solver
**pm_mip_solver** (str, "cbc") - The mixed integer solver (when "main" solver == juniper)
**pm_nl_solver** (str, "ipopt") - The nonlinear solver (when "main" solver == juniper)
**pm_time_limits** (Dict, None) - Time limits in seconds for power models interface. To be set as a dict like
{"pm_time_limit": 300., "pm_nl_time_limit": 300., "pm_mip_time_limit": 300.}
**pm_log_level** (int, 0) - solver log level in power models
**pm_tol** (float, 1e-8) - default desired convergence tolerance for solver to use.
"""
julia_file = os.path.join(pp_dir, "opf", 'run_powermodels_ots.jl')
ac = True if "DC" not in pm_model else False
Expand All @@ -353,48 +337,56 @@ def runpm_ots(net, pp_to_pm_callback=None, calculate_voltage_angles=True,
pp_to_pm_callback=pp_to_pm_callback, julia_file=julia_file, pm_model=pm_model, pm_solver=pm_solver,
correct_pm_network_data=correct_pm_network_data, pm_mip_solver=pm_mip_solver,
pm_nl_solver=pm_nl_solver, pm_time_limits=pm_time_limits, pm_log_level=pm_log_level,
opf_flow_lim="S")
opf_flow_lim="S", pm_tol=pm_tol)
_runpm(net)
read_ots_results(net)


def runpm_storage_opf(net, calculate_voltage_angles=True,
trafo_model="t", delta=1e-8, trafo3w_losses="hv", check_connectivity=True,
n_timesteps=24, time_elapsed=1.0, correct_pm_network_data=True,
pm_model="ACPPowerModel", pm_time_limits=None, pm_log_level=0, **kwargs): # pragma: no cover
n_timesteps=24, time_elapsed=1., correct_pm_network_data=True,
pm_model="ACPPowerModel", pm_time_limits=None, pm_log_level=0,
opf_flow_lim="S", charge_efficiency=1., discharge_efficiency=1.,
standby_loss=1e-8, p_loss=1e-8, q_loss=1e-8, pm_tol=1e-8, **kwargs):
"""
Runs a non-linear power system optimization with storages and time series using PowerModels.jl.
INPUT:
**net** - The pandapower format network
OPTIONAL:
**n_timesteps** (int, 24) - number of time steps to optimize
**time_elapsed** (float, 1.0) - time elapsed between time steps (1.0 = 1 hour)
**pm_time_limits** (Dict, None) - Time limits in seconds for power models interface. To be set as a dict like
{"pm_time_limit": 300., "pm_nl_time_limit": 300., "pm_mip_time_limit": 300.}
**pm_log_level** (int, 0) - solver log level in power models
"""
julia_file = os.path.join(pp_dir, "opf", 'run_powermodels_mn_storage.jl')
"""
julia_file = os.path.join(pp_dir, "opf", 'run_powermodels_storage.jl')
ac = True if "DC" not in pm_model else False
net._options = {}
_add_ppc_options(net, calculate_voltage_angles=calculate_voltage_angles,
trafo_model=trafo_model, check_connectivity=check_connectivity,
mode="opf", switch_rx_ratio=2, init_vm_pu="flat", init_va_degree="flat",
enforce_q_lims=True, recycle=dict(_is_elements=False, ppc=False, Ybus=False),
voltage_depend_loads=False, delta=delta, trafo3w_losses=trafo3w_losses)
trafo_model=trafo_model, check_connectivity=check_connectivity,
mode="opf", switch_rx_ratio=2, init_vm_pu="flat", init_va_degree="flat",
enforce_q_lims=True, recycle=dict(_is_elements=False, ppc=False, Ybus=False),
voltage_depend_loads=False, delta=delta, trafo3w_losses=trafo3w_losses)
_add_opf_options(net, trafo_loading='power', ac=ac, init="flat", numba=True,
pp_to_pm_callback=add_storage_opf_settings, julia_file=julia_file,
correct_pm_network_data=correct_pm_network_data, pm_model=pm_model, pm_time_limits=pm_time_limits,
pm_log_level=pm_log_level)
pp_to_pm_callback=add_storage_opf_settings, julia_file=julia_file,
correct_pm_network_data=correct_pm_network_data, pm_model=pm_model, pm_time_limits=pm_time_limits,
pm_log_level=pm_log_level, opf_flow_lim=opf_flow_lim, pm_tol=pm_tol)

net._options["n_time_steps"] = n_timesteps
net._options["time_elapsed"] = time_elapsed

net._options["charge_efficiency"] = charge_efficiency
net._options["discharge_efficiency"] = discharge_efficiency

net._options["standby_loss"] = standby_loss
net._options["p_loss"] = p_loss
net._options["q_loss"] = q_loss

_runpm(net)
storage_results = read_pm_storage_results(net)
return storage_results






Loading

0 comments on commit ac0a6c1

Please sign in to comment.