{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Distribution Generation Curtailment with OPF\n", "This is an introduction on how to use the pandapower optimal power flow for calculation optimal distributed generation curtailment.\n", "\n", "## Example Network\n", "\n", "We use the four bus example network from the basic OPF tutorial:\n", "\n", "\n", "\n", "We first create this network in pandapower:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import pandapower as pp\n", "from numpy import array\n", "net = pp.create_empty_network()\n", "\n", "#create buses\n", "bus1 = pp.create_bus(net, vn_kv=220., min_vm_pu=1.0, max_vm_pu=1.02)\n", "bus2 = pp.create_bus(net, vn_kv=110., min_vm_pu=1.0, max_vm_pu=1.02)\n", "bus3 = pp.create_bus(net, vn_kv=110., min_vm_pu=1.0, max_vm_pu=1.02)\n", "bus4 = pp.create_bus(net, vn_kv=110., min_vm_pu=1.0, max_vm_pu=1.02)\n", "\n", "#create 220/110 kV transformer\n", "pp.create_transformer(net, bus1, bus2, std_type=\"100 MVA 220/110 kV\", max_loading_percent=50)\n", "\n", "#create 110 kV lines\n", "pp.create_line(net, bus2, bus3, length_km=70., std_type='149-AL1/24-ST1A 110.0', max_loading_percent=50)\n", "pp.create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0', max_loading_percent=50)\n", "pp.create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0', max_loading_percent=50)\n", "\n", "#create loads\n", "pp.create_load(net, bus2, p_kw=60e3, controllable = False)\n", "pp.create_load(net, bus3, p_kw=70e3, controllable = False)\n", "pp.create_load(net, bus4, p_kw=10e3, controllable = False)\n", "\n", "#create generators\n", "eg = pp.create_ext_grid(net, bus1)\n", "g0 = pp.create_gen(net, bus3, p_kw=-80e3, min_p_kw=-80e3, max_p_kw=0., vm_pu=1.01, controllable=True)\n", "g1 = pp.create_gen(net, bus4, p_kw=-100e3, min_p_kw=-100e3, max_p_kw=0., vm_pu=1.01, controllable=True)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PYPOWER Version 5.0.0, 29-May-2015 -- AC Optimal Power Flow\n", "Python Interior Point Solver - PIPS, Version 1.0, 07-Feb-2011\n", "Converged!\n" ] } ], "source": [ "pp.create_polynomial_cost(net, 0, 'gen', array([-1e5, 0]))\n", "pp.create_polynomial_cost(net, 1, 'gen', array([-1e5, 0]))\n", "pp.runopp(net, verbose=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Because of the negative costs, the OPF now maximizes power generation at the generators:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
p_kwq_kvarva_degreevm_pu
0-46052.570188-18913.037576-0.4850661.02
1-85097.85929219478.2592002.8699681.02
\n", "
" ], "text/plain": [ " p_kw q_kvar va_degree vm_pu\n", "0 -46052.570188 -18913.037576 -0.485066 1.02\n", "1 -85097.859292 19478.259200 2.869968 1.02" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.res_gen" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "-13115042947.98368" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.res_cost" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
p_kwq_kvar
0-11071.749595153.95827
\n", "
" ], "text/plain": [ " p_kw q_kvar\n", "0 -11071.749595 153.95827" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.res_ext_grid" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
vm_puva_degreep_kwq_kvar
01.000.000000-11071.749595153.958270
11.00-0.75944460000.0000000.000000
21.02-0.48506623947.429812-18913.037576
31.022.869968-75097.85929219478.259200
\n", "
" ], "text/plain": [ " vm_pu va_degree p_kw q_kvar\n", "0 1.00 0.000000 -11071.749595 153.958270\n", "1 1.00 -0.759444 60000.000000 0.000000\n", "2 1.02 -0.485066 23947.429812 -18913.037576\n", "3 1.02 2.869968 -75097.859292 19478.259200" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.res_bus" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
p_hv_kwq_hv_kvarp_lv_kwq_lv_kvarpl_kwql_kvari_hv_kai_lv_kaloading_percent
011071.749595-153.95827-11013.580692324.3085358.168903170.350260.0290590.05783111.07282
\n", "
" ], "text/plain": [ " p_hv_kw q_hv_kvar p_lv_kw q_lv_kvar pl_kw ql_kvar \\\n", "0 11071.749595 -153.95827 -11013.580692 324.30853 58.168903 170.35026 \n", "\n", " i_hv_ka i_lv_ka loading_percent \n", "0 0.029059 0.057831 11.07282 " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.res_trafo" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
p_from_kwq_from_kvarp_to_kwq_to_kvarpl_kwql_kvari_from_kai_to_kai_kaloading_percent
0-4940.648422-7253.5110435009.6597895024.01503469.011368-2229.4960090.0460640.0365080.0460649.800771
1-28957.08960113889.02254229770.915374-13899.350544813.825772-10.3280030.1652590.1690670.16906735.971608
245326.943919-5578.908656-44045.7708866929.2025121281.1730321350.2938560.2350000.2340240.23500050.000000
\n", "
" ], "text/plain": [ " p_from_kw q_from_kvar p_to_kw q_to_kvar pl_kw \\\n", "0 -4940.648422 -7253.511043 5009.659789 5024.015034 69.011368 \n", "1 -28957.089601 13889.022542 29770.915374 -13899.350544 813.825772 \n", "2 45326.943919 -5578.908656 -44045.770886 6929.202512 1281.173032 \n", "\n", " ql_kvar i_from_ka i_to_ka i_ka loading_percent \n", "0 -2229.496009 0.046064 0.036508 0.046064 9.800771 \n", "1 -10.328003 0.165259 0.169067 0.169067 35.971608 \n", "2 1350.293856 0.235000 0.234024 0.235000 50.000000 " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.res_line" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Obviously the voltage profile was the limiting factor for the generator feed-in. If we relax this constraint a little bit:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "net.bus[\"max_vm_pu\"] = 1.05\n", "pp.runopp(net)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see an increased feed-in of the generators:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
p_kwq_kvarva_degreevm_pu
0-80000.00000-17252.5348362.3282681.050000
1-66517.8777510226.3734973.6660031.040019
\n", "
" ], "text/plain": [ " p_kw q_kvar va_degree vm_pu\n", "0 -80000.00000 -17252.534836 2.328268 1.050000\n", "1 -66517.87775 10226.373497 3.666003 1.040019" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.res_gen" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
vm_puva_degreep_kwq_kvar
01.0000000.0000004542.4180418523.878212
11.0103730.29833460000.0000000.000000
21.0500002.328268-10000.000000-17252.534836
31.0400193.666003-56517.87775010226.373497
\n", "
" ], "text/plain": [ " vm_pu va_degree p_kw q_kvar\n", "0 1.000000 0.000000 4542.418041 8523.878212\n", "1 1.010373 0.298334 60000.000000 0.000000\n", "2 1.050000 2.328268 -10000.000000 -17252.534836\n", "3 1.040019 3.666003 -56517.877750 10226.373497" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.res_bus" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "-14651787774.974997" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.res_cost" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python [default]", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" } }, "nbformat": 4, "nbformat_minor": 0 }