{ "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": 100, "metadata": {}, "outputs": [], "source": [ "import pandapower as pp\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=100)\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=100)\n", "pp.create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0', max_loading_percent=100)\n", "pp.create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0', max_loading_percent=100)\n", "\n", "#create loads\n", "pp.create_load(net, bus2, p_mw=60, controllable=False)\n", "pp.create_load(net, bus3, p_mw=70, controllable=False)\n", "pp.create_load(net, bus4, p_mw=10, controllable=False)\n", "\n", "#create generators\n", "eg = pp.create_ext_grid(net, bus1)\n", "g0 = pp.create_gen(net, bus3, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01, controllable=True)\n", "g1 = pp.create_gen(net, bus4, p_mw=100, min_p_mw=0, max_p_mw=100, vm_pu=1.01, controllable=True)" ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "tazan.pandapower.run - INFO: These elements have missing power constraint values, which are considered in OPF as +- 1000 TW: ['gen']\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "PYPOWER Version 5.1.4, 27-June-2018 -- AC Optimal Power Flow\n", "Python Interior Point Solver - PIPS, Version 1.0, 07-Feb-2011\n", "Converged!\n", "\n", "Converged in 1.19 seconds\n", "================================================================================\n", "| System Summary |\n", "================================================================================\n", "\n", "How many? How much? P (MW) Q (MVAr)\n", "--------------------- ------------------- ------------- -----------------\n", "Buses 4 Total Gen Capacity 1000000180.0 -3000000000.0 to 3000000000.0\n", "Generators 3 On-line Capacity 1000000180.0 -3000000000.0 to 3000000000.0\n", "Committed Gens 3 Generation (actual) 143.2 1.3\n", "Loads 3 Load 140.0 0.0\n", " Fixed 3 Fixed 140.0 0.0\n", " Dispatchable 0 Dispatchable 0.0 of 0.0 0.0\n", "Shunts 0 Shunt (inj) 0.0 0.0\n", "Branches 4 Losses (I^2 * Z) 3.11 6.73\n", "Transformers 4 Branch Charging (inj) - 5.4\n", "Inter-ties 0 Total Inter-tie Flow 0.0 0.0\n", "Areas 1\n", "\n", " Minimum Maximum\n", " ------------------------- --------------------------------\n", "Voltage Magnitude 1.000 p.u. @ bus 0 1.020 p.u. @ bus 3 \n", "Voltage Angle -1.33 deg @ bus 2 3.20 deg @ bus 3 \n", "P Losses (I^2*R) - 1.54 MW @ line 3-1\n", "Q Losses (I^2*X) - 3.26 MVAr @ line 3-1\n", "\n", "================================================================================\n", "| Area Summary |\n", "================================================================================\n", "Area # of # of Gens # of Loads # of # of # of # of\n", " Num Buses Total Online Total Fixed Disp Shunt Brchs Xfmrs Ties\n", "---- ----- ----- ------ ----- ----- ----- ----- ----- ----- -----\n", " 1 4 3 3 3 3 0 0 4 4 0\n", "---- ----- ----- ------ ----- ----- ----- ----- ----- ----- -----\n", "Tot: 4 3 3 3 3 0 0 4 4 0\n", "\n", "Area Total Gen Capacity On-line Gen Capacity Generation\n", " Num MW MVAr MW MVAr MW MVAr\n", "---- ------ ------------------ ------ ------------------ ------ ------\n", " 1 1000000180.0 -3000000000.0 to 3000000000.0 1000000180.0 -3000000000.0 to 3000000000.0 143.2 1.3\n", "---- ------ ------------------ ------ ------------------ ------ ------\n", "\n", "Area Disp Load Cap Disp Load Fixed Load Total Load\n", " Num MW MVAr MW MVAr MW MVAr MW MVAr\n", "---- ------ ------ ------ ------ ------ ------ ------ ------\n", " 1 0.0 0.0 0.0 0.0 140.0 0.0 140.0 0.0\n", "---- ------ ------ ------ ------ ------ ------ ------ ------\n", "Tot: 0.0 0.0 0.0 0.0 140.0 0.0 140.0 0.0\n", "\n", "Area Shunt Inj Branch Series Losses Net Export\n", " Num MW MVAr Charging MW MVAr MW MVAr\n", "---- ------ ------ -------- ------ ------ ------ ------\n", " 1 0.0 0.0 5.4 3.11 6.73 0.0 0.0\n", "---- ------ ------ -------- ------ ------ ------ ------\n", "Tot: 0.0 0.0 5.4 3.11 6.73 - -\n", "\n", "================================================================================\n", "| Generator Data |\n", "================================================================================\n", " Gen Bus Status Pg Qg \n", " # # (MW) (MVAr) \n", "---- ----- ------ -------- --------\n", " 0 0 1 11.88 -0.16\n", " 1 2 1 31.31 26.77\n", " 2 3 1 99.98 -25.32\n", " -------- --------\n", " Total: 143.16 1.29\n", "\n", "================================================================================\n", "| Bus Data |\n", "================================================================================\n", " Bus Voltage Generation Load \n", " # Mag(pu) Ang(deg) P (MW) Q (MVAr) P (MW) Q (MVAr)\n", "----- ------- -------- -------- -------- -------- --------\n", " 0 1.000 0.000* 11.88 -0.16 - - \n", " 1 1.000 -0.815 - - 60.00 0.00 \n", " 2 1.020 -1.327 31.31 26.77 70.00 0.00 \n", " 3 1.020 3.203 99.98 -25.32 10.00 0.00 \n", " -------- -------- -------- --------\n", " Total: 143.16 1.29 140.00 0.00\n", "\n", "================================================================================\n", "| Branch Data |\n", "================================================================================\n", "Brnch From To From Bus Injection To Bus Injection Loss (I^2 * Z) \n", " # Bus Bus P (MW) Q (MVAr) P (MW) Q (MVAr) P (MW) Q (MVAr)\n", "----- ----- ----- -------- -------- -------- -------- -------- --------\n", " 0 1 2 -0.11 -9.53 0.19 7.32 0.078 0.17\n", " 1 2 3 -38.88 19.45 40.37 -18.05 1.483 3.13\n", " 2 3 1 49.61 -7.27 -48.07 9.17 1.544 3.26\n", " 3 0 1 11.88 -0.16 -11.82 0.35 0.004 0.17\n", " -------- --------\n", " Total: 3.109 6.73\n", "\n", "Converged in 1.19 seconds\n", "================================================================================\n", "| System Summary |\n", "================================================================================\n", "\n", "How many? How much? P (MW) Q (MVAr)\n", "--------------------- ------------------- ------------- -----------------\n", "Buses 4 Total Gen Capacity 1000000180.0 -3000000000.0 to 3000000000.0\n", "Generators 3 On-line Capacity 1000000180.0 -3000000000.0 to 3000000000.0\n", "Committed Gens 3 Generation (actual) 143.2 1.3\n", "Loads 3 Load 140.0 0.0\n", " Fixed 3 Fixed 140.0 0.0\n", " Dispatchable 0 Dispatchable 0.0 of 0.0 0.0\n", "Shunts 0 Shunt (inj) 0.0 0.0\n", "Branches 4 Losses (I^2 * Z) 3.11 6.73\n", "Transformers 4 Branch Charging (inj) - 5.4\n", "Inter-ties 0 Total Inter-tie Flow 0.0 0.0\n", "Areas 1\n", "\n", " Minimum Maximum\n", " ------------------------- --------------------------------\n", "Voltage Magnitude 1.000 p.u. @ bus 0 1.020 p.u. @ bus 3 \n", "Voltage Angle -1.33 deg @ bus 2 3.20 deg @ bus 3 \n", "P Losses (I^2*R) - 1.54 MW @ line 3-1\n", "Q Losses (I^2*X) - 3.26 MVAr @ line 3-1\n", "\n", "================================================================================\n", "| Area Summary |\n", "================================================================================\n", "Area # of # of Gens # of Loads # of # of # of # of\n", " Num Buses Total Online Total Fixed Disp Shunt Brchs Xfmrs Ties\n", "---- ----- ----- ------ ----- ----- ----- ----- ----- ----- -----\n", " 1 4 3 3 3 3 0 0 4 4 0\n", "---- ----- ----- ------ ----- ----- ----- ----- ----- ----- -----\n", "Tot: 4 3 3 3 3 0 0 4 4 0\n", "\n", "Area Total Gen Capacity On-line Gen Capacity Generation\n", " Num MW MVAr MW MVAr MW MVAr\n", "---- ------ ------------------ ------ ------------------ ------ ------\n", " 1 1000000180.0 -3000000000.0 to 3000000000.0 1000000180.0 -3000000000.0 to 3000000000.0 143.2 1.3\n", "---- ------ ------------------ ------ ------------------ ------ ------\n", "\n", "Area Disp Load Cap Disp Load Fixed Load Total Load\n", " Num MW MVAr MW MVAr MW MVAr MW MVAr\n", "---- ------ ------ ------ ------ ------ ------ ------ ------\n", " 1 0.0 0.0 0.0 0.0 140.0 0.0 140.0 0.0\n", "---- ------ ------ ------ ------ ------ ------ ------ ------\n", "Tot: 0.0 0.0 0.0 0.0 140.0 0.0 140.0 0.0\n", "\n", "Area Shunt Inj Branch Series Losses Net Export\n", " Num MW MVAr Charging MW MVAr MW MVAr\n", "---- ------ ------ -------- ------ ------ ------ ------\n", " 1 0.0 0.0 5.4 3.11 6.73 0.0 0.0\n", "---- ------ ------ -------- ------ ------ ------ ------\n", "Tot: 0.0 0.0 5.4 3.11 6.73 - -\n", "\n", "================================================================================\n", "| Generator Data |\n", "================================================================================\n", " Gen Bus Status Pg Qg \n", " # # (MW) (MVAr) \n", "---- ----- ------ -------- --------\n", " 0 0 1 11.88 -0.16\n", " 1 2 1 31.31 26.77\n", " 2 3 1 99.98 -25.32\n", " -------- --------\n", " Total: 143.16 1.29\n", "\n", "================================================================================\n", "| Bus Data |\n", "================================================================================\n", " Bus Voltage Generation Load \n", " # Mag(pu) Ang(deg) P (MW) Q (MVAr) P (MW) Q (MVAr)\n", "----- ------- -------- -------- -------- -------- --------\n", " 0 1.000 0.000* 11.88 -0.16 - - \n", " 1 1.000 -0.815 - - 60.00 0.00 \n", " 2 1.020 -1.327 31.31 26.77 70.00 0.00 \n", " 3 1.020 3.203 99.98 -25.32 10.00 0.00 \n", " -------- -------- -------- --------\n", " Total: 143.16 1.29 140.00 0.00\n", "\n", "================================================================================\n", "| Branch Data |\n", "================================================================================\n", "Brnch From To From Bus Injection To Bus Injection Loss (I^2 * Z) \n", " # Bus Bus P (MW) Q (MVAr) P (MW) Q (MVAr) P (MW) Q (MVAr)\n", "----- ----- ----- -------- -------- -------- -------- -------- --------\n", " 0 1 2 -0.11 -9.53 0.19 7.32 0.078 0.17\n", " 1 2 3 -38.88 19.45 40.37 -18.05 1.483 3.13\n", " 2 3 1 49.61 -7.27 -48.07 9.17 1.544 3.26\n", " 3 0 1 11.88 -0.16 -11.82 0.35 0.004 0.17\n", " -------- --------\n", " Total: 3.109 6.73\n" ] } ], "source": [ "pp.create_poly_cost(net, 0, 'gen', cp1_eur_per_mw=-1)\n", "pp.create_poly_cost(net, 1, 'gen', cp1_eur_per_mw=-1)\n", "pp.create_poly_cost(net, 0, 'ext_grid', cp1_eur_per_mw=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, which is constrained by their maximum power:" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "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", "
p_mwmin_p_mwmax_p_mw
031.3053680.080.0
199.9815960.0100.0
\n", "
" ], "text/plain": [ " p_mw min_p_mw max_p_mw\n", "0 31.305368 0.0 80.0\n", "1 99.981596 0.0 100.0" ] }, "execution_count": 103, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.concat([net.res_gen.p_mw, net.gen.min_p_mw, net.gen.max_p_mw], axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "While gen 1 is operating at the limit, gen 0 is below the maximum output. Apparently the generator can not reach its maximum output without violating at least one power flow constraint. Let's check on the constraints.\n", "\n", "The line and transformer constraints are not reached:" ] }, { "cell_type": "code", "execution_count": 104, "metadata": { "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", "
max_loading_percentloading_percent
0100.010.638708
1100.048.412397
2100.054.898286
\n", "
" ], "text/plain": [ " max_loading_percent loading_percent\n", "0 100.0 10.638708\n", "1 100.0 48.412397\n", "2 100.0 54.898286" ] }, "execution_count": 104, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.concat([net.line.max_loading_percent, net.res_line.loading_percent], axis=1)" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
max_loading_percentloading_percent
0100.011.878335
\n", "
" ], "text/plain": [ " max_loading_percent loading_percent\n", "0 100.0 11.878335" ] }, "execution_count": 105, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.concat([net.trafo.max_loading_percent, net.res_trafo.loading_percent], axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But the voltage constraints are:" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "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", "
vm_pumin_vm_pumax_vm_pu
01.001.01.02
11.001.01.02
21.021.01.02
31.021.01.02
\n", "
" ], "text/plain": [ " vm_pu min_vm_pu max_vm_pu\n", "0 1.00 1.0 1.02\n", "1 1.00 1.0 1.02\n", "2 1.02 1.0 1.02\n", "3 1.02 1.0 1.02" ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "pd.concat([net.res_bus.vm_pu, net.bus.min_vm_pu, net.bus.max_vm_pu], axis=1)" ] }, { "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": 107, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "tazan.pandapower.run - INFO: These elements have missing power constraint values, which are considered in OPF as +- 1000 TW: ['gen']\n" ] } ], "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": 108, "metadata": {}, "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", "
p_mwmin_p_mwmax_p_mw
079.9999130.080.0
199.9999130.0100.0
\n", "
" ], "text/plain": [ " p_mw min_p_mw max_p_mw\n", "0 79.999913 0.0 80.0\n", "1 99.999913 0.0 100.0" ] }, "execution_count": 108, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.concat([net.res_gen.p_mw, net.gen.min_p_mw, net.gen.max_p_mw], axis=1)" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "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", "
vm_puva_degreep_mwq_mvarlam_plam_q
01.0000000.00000035.779664-0.218723-6.239991e-21-1.507018e-23
11.0016042.45848060.0000000.000000-1.885653e-062.145492e-05
21.0411185.810889-9.999913-9.092366-1.657955e-051.758919e-21
31.0451117.687818-89.9999134.650025-1.871357e-05-9.301560e-22
\n", "
" ], "text/plain": [ " vm_pu va_degree p_mw q_mvar lam_p lam_q\n", "0 1.000000 0.000000 35.779664 -0.218723 -6.239991e-21 -1.507018e-23\n", "1 1.001604 2.458480 60.000000 0.000000 -1.885653e-06 2.145492e-05\n", "2 1.041118 5.810889 -9.999913 -9.092366 -1.657955e-05 1.758919e-21\n", "3 1.045111 7.687818 -89.999913 4.650025 -1.871357e-05 -9.301560e-22" ] }, "execution_count": 109, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.res_bus" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "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.6.5" } }, "nbformat": 4, "nbformat_minor": 1 }