Optimization with PandaModels.jl
Installation
If you are not yet using Julia, install it. Note that you need a version that is supported PowerModels, PyCall and pyjulia for the interface to work. Currently, Julia 1.5 is the most recent version of Julia that supports all these packages.
Note
You don’t necessarily need a Julia IDE if you are using PandaModels through pandapower, but it might help for debugging to install an IDE such as Juno. Also, PyCharm has a Julia Plugin.
Add the Julia binary folder (e.g. /Julia-1.5.0/bin on Windows or /Applications/Julia-1.5.app/Contents/Resources/julia/bin on MacOS) to the system variable PATH. Providing the path is correct, you can now enter the julia prompt by executing
julia
in your shell.The library PyCall allows to use Python from inside julia. By default, PyCall uses the Conda.jl package to install a Miniconda distribution private to Julia. To use an already installed Python distribution (e.g. Anaconda), set the
PYTHON
environment variable inside the Julia prompt.On Windows:
ENV["PYTHON"]="C:\\Anaconda3\\python.exe"
On MacOS:
ENV["PYTHON"]="/Users/%Username/opt/anaconda3/bin/python"
Access the package manager by typing ]. Now install the packages:
add Ipopt PowerModels PyCall
.Inside package manager, test your PowerModels installation by executing
test PowerModels
. Alternatively, you can callusing Pkg
and thenPkg.test("PowerModels")
Then, test if calling Python from Julia works as described here.
Note
If you cannot plot using PyCall and PyPlot in Julia, see the workarounds offered here.
To call Julia from Python, install the pyjulia package with
pip install julia
. Afterwards, test if everything works by importing PowerModels from Python with:from julia.PowerModels import run_ac_opf
. This takes some time, since Python starts a julia instance in the background, but it if the import completes without error everything is configured correctly and you can now use PowerModels to optimize pandapower networks.Additional packages are required to use the pandapower - PandaModels.jl interface with all features like TNEP or OTS. Install the “JSON” and “JuMP” packages with, e.g.,
julia -e 'import Pkg; Pkg.add("JSON"); Pkg.add("JuMP");
and maybe also julia -e ‘import Pkg; Pkg.add(“Cbc”); Pkg.add(“Juniper”)’ to get the TNEP and OTS libraries. Alternatively, install these packages by entering]
inside the julia console and callingadd JSON
add JuMP
Now install our interface PandaModels.jl by type
add PandaModels
inside Julia package manager.
You can then finally test if the PandaModels.jl interface works by navigating to your local pandapower test folder
pandapower/pandapower/test/opf
folder and runpython-jl test_powermodels.py
orpytest test_powermodels.py
if pytest is intalled. If everything works there should be no error.
Additional Solvers
Optional additional solvers, such as Gurobi are compatible to PowerModels.jl. To use these solvers, you first have to install the solver itself on your system and then the julia interface. Gurobi is very fast for linear problems such as the DC model and free for academic usage. Let’s do this step by step for Gurobi:
Download and install from Gurobi download (you’ll need an account for this)
Run the file to get the gurobi folder, e.g., in linux you need to run
tar -xzf gurobi<version>_linux64.tar.gz
Get your Gurobi license at Gurobi license and download it (remember where you stored it).
Activate the license by calling
grbgetkey YOUR_KEY
as described on the Gurobi license page.Add some Gurobi paths and the license path to your local PATH environment variables. In linux you can just open your .bashrc file with, e.g.,
nano .bashrc
in your home folder and add:
# Linux
# gurobi
export GUROBI_HOME="/opt/gurobi_VERSION/linux64"
export PATH="${PATH}:${GUROBI_HOME}/bin"
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${GUROBI_HOME}/lib"
export GRB_LICENSE_FILE="/PATH_TO_YOUR_LICENSE_DIR/gurobi.lic"
# MacOS
# gurobi
export GUROBI_HOME="/Library/gurobiVERSION/mac64"
export PATH="$PATH:$GUROBI_HOME/bin"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$GUROBI_HOME/lib"
export GRB_LICENSE_FILE="/PATH_TO_YOUR_LICENSE_DIR/gurobi.lic"
Install the julia - Gurobi interface and set the GUROBI_HOME environment with
julia -e 'import Pkg; Pkg.add("Gurobi");'
or type
add Gurobi
inside Julia package mode.
Build and test your Gurobi installation by entering
julia
prompt and thenimport Pkg; Pkg.build("Gurobi")
. This should compile without an error.Now, you can use Gurobi to solve your linear problems, e.g., the DC OPF, with
runpm_dc_opf(net, pm_model="DCPPowerModel", pm_solver="gurobi")
Usage
The usage is explained in the PowerModels tutorial.
- pandapower.runpm_ac_opf(net, pp_to_pm_callback=None, calculate_voltage_angles=True, trafo_model='t', delta=1e-08, 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', pm_tol=1e-08, pdm_dev_mode=False, **kwargs)
Runs a non-linear power system optimization using PowerModels.jl.
Flexibilities, constraints and cost parameters are defined in the pandapower element tables.
Flexibilities can be defined in net.sgen / net.gen /net.load net.sgen.controllable if a static generator is controllable. If False, the active and reactive power are assigned as in a normal power flow. If True, the following flexibilities apply:
net.sgen.min_p_mw / net.sgen.max_p_mw
net.sgen.min_q_mvar / net.sgen.max_q_mvar
net.load.min_p_mw / net.load.max_p_mw
net.load.min_q_mvar / net.load.max_q_mvar
net.gen.min_p_mw / net.gen.max_p_mw
net.gen.min_q_mvar / net.gen.max_q_mvar
net.ext_grid.min_p_mw / net.ext_grid.max_p_mw
net.ext_grid.min_q_mvar / net.ext_grid.max_q_mvar
net.dcline.min_q_to_mvar / net.dcline.max_q_to_mvar / net.dcline.min_q_from_mvar / net.dcline.max_q_from_mvar
Controllable loads behave just like controllable static generators. It must be stated if they are controllable. Otherwise, they are not respected as flexibilities. Dc lines are controllable per default
Network constraints can be defined for buses, lines and transformers the elements in the following columns:
net.bus.min_vm_pu / net.bus.max_vm_pu
net.line.max_loading_percent
net.trafo.max_loading_percent
net.trafo3w.max_loading_percent
How these costs are combined into a cost function depends on the cost_function parameter.
- INPUT:
net - The pandapower format network
- OPTIONAL:
pp_to_pm_callback (function, None) - callback function to add data to the PowerModels data structure pm_model (str, “ACPPowerModel”) - model to use. Default is AC model pm_solver (str, “ipopt”) - default solver to use. If ipopt is not available use Ipopt correct_pm_network_data (bool, True) - checks if network data is correct. If not tries to correct it 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_log_level (int, 0) - solver log level in power models 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)
- delete_buffer_file (Bool, True) - If True, the .json file used by powermodels will be deleted after
optimization.
- pm_file_path (str, None) - Specifiy the filename, under which the .json file for powermodels is stored. If
you want to keep the file after optimization, you should also set delete_buffer_file to False!
pdm_dev_mode (bool, False) - If True, the develope mode of PdM is called.
- pandapower.runpm_dc_opf(net, pp_to_pm_callback=None, calculate_voltage_angles=True, trafo_model='t', delta=1e-08, 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, pm_tol=1e-08, pdm_dev_mode=False, **kwargs)
Runs a linearized power system optimization using PowerModels.jl.
Flexibilities, constraints and cost parameters are defined in the pandapower element tables.
Flexibilities can be defined in net.sgen / net.gen /net.load net.sgen.controllable if a static generator is controllable. If False, the active and reactive power are assigned as in a normal power flow. If True, the following flexibilities apply:
net.sgen.min_p_mw / net.sgen.max_p_mw
net.sgen.min_q_mvar / net.sgen.max_q_mvar
net.load.min_p_mw / net.load.max_p_mw
net.load.min_q_mvar / net.load.max_q_mvar
net.gen.min_p_mw / net.gen.max_p_mw
net.gen.min_q_mvar / net.gen.max_q_mvar
net.ext_grid.min_p_mw / net.ext_grid.max_p_mw
net.ext_grid.min_q_mvar / net.ext_grid.max_q_mvar
net.dcline.min_q_to_mvar / net.dcline.max_q_to_mvar / net.dcline.min_q_from_mvar / net.dcline.max_q_from_mvar
Controllable loads behave just like controllable static generators. It must be stated if they are controllable. Otherwise, they are not respected as flexibilities. Dc lines are controllable per default
Network constraints can be defined for buses, lines and transformers the elements in the following columns:
net.bus.min_vm_pu / net.bus.max_vm_pu
net.line.max_loading_percent
net.trafo.max_loading_percent
net.trafo3w.max_loading_percent
How these costs are combined into a cost function depends on the cost_function parameter.
- INPUT:
net - The pandapower format network
- OPTIONAL:
pp_to_pm_callback (function, None) - callback function to add data to the PowerModels data structure pm_model (str, “DCPPowerModel”) - model to use. Default is DC model pm_solver (str, “ipopt”) - The “main” power models solver correct_pm_network_data (bool, True) - checks if network data is correct. If not tries to correct it 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_log_level (int, 0) - solver log level in power models pm_tol (float, 1e-8) - default desired convergence tolerance for solver to use. pdm_dev_mode (bool, False) - If True, the develope mode of PdM is called.
- pandapower.runpm(net, julia_file=None, pp_to_pm_callback=None, calculate_voltage_angles=True, trafo_model='t', delta=1e-08, 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', pm_tol=1e-08, pdm_dev_mode=False, **kwargs)
Runs a power system optimization using PowerModels.jl. with a custom julia file.
Flexibilities, constraints and cost parameters are defined in the pandapower element tables.
Flexibilities can be defined in net.sgen / net.gen /net.load net.sgen.controllable if a static generator is controllable. If False, the active and reactive power are assigned as in a normal power flow. If True, the following flexibilities apply:
net.sgen.min_p_mw / net.sgen.max_p_mw
net.sgen.min_q_mvar / net.sgen.max_q_mvar
net.load.min_p_mw / net.load.max_p_mw
net.load.min_q_mvar / net.load.max_q_mvar
net.gen.min_p_mw / net.gen.max_p_mw
net.gen.min_q_mvar / net.gen.max_q_mvar
net.ext_grid.min_p_mw / net.ext_grid.max_p_mw
net.ext_grid.min_q_mvar / net.ext_grid.max_q_mvar
net.dcline.min_q_to_mvar / net.dcline.max_q_to_mvar / net.dcline.min_q_from_mvar / net.dcline.max_q_from_mvar
Controllable loads behave just like controllable static generators. It must be stated if they are controllable. Otherwise, they are not respected as flexibilities. Dc lines are controllable per default
Network constraints can be defined for buses, lines and transformers the elements in the following columns:
net.bus.min_vm_pu / net.bus.max_vm_pu
net.line.max_loading_percent
net.trafo.max_loading_percent
net.trafo3w.max_loading_percent
How these costs are combined into a cost function depends on the cost_function parameter.
- INPUT:
net - The pandapower format network
- 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, “ipopt”) - 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 delete_buffer_file (Bool, True) - If True, the .json file used by powermodels will be deleted after
optimization.
- pm_file_path (str, None) - Specifiy the filename, under which the .json file for powermodels is stored. If
you want to keep the file after optimization, you should also set 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)
pm_tol (float, 1e-8) - default desired convergence tolerance for solver to use. pdm_dev_mode (bool, False) - If True, the develope mode of PdM is called.
The TNEP optimization is explained in the PowerModels TNEP tutorial. Additional packages including “juniper”
- pandapower.runpm_tnep(net, pp_to_pm_callback=None, calculate_voltage_angles=True, trafo_model='t', delta=1e-08, 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', pm_tol=1e-08, pdm_dev_mode=False, **kwargs)
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 model.
pm_tol (float, 1e-8) - default desired convergence tolerance for solver to use. pdm_dev_mode (bool, False) - If True, the develope mode of PdM is called.