{
"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",
" p_kw | \n",
" q_kvar | \n",
" va_degree | \n",
" vm_pu | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" -46052.570188 | \n",
" -18913.037576 | \n",
" -0.485066 | \n",
" 1.02 | \n",
"
\n",
" \n",
" 1 | \n",
" -85097.859292 | \n",
" 19478.259200 | \n",
" 2.869968 | \n",
" 1.02 | \n",
"
\n",
" \n",
"
\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",
" p_kw | \n",
" q_kvar | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" -11071.749595 | \n",
" 153.95827 | \n",
"
\n",
" \n",
"
\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",
" vm_pu | \n",
" va_degree | \n",
" p_kw | \n",
" q_kvar | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1.00 | \n",
" 0.000000 | \n",
" -11071.749595 | \n",
" 153.958270 | \n",
"
\n",
" \n",
" 1 | \n",
" 1.00 | \n",
" -0.759444 | \n",
" 60000.000000 | \n",
" 0.000000 | \n",
"
\n",
" \n",
" 2 | \n",
" 1.02 | \n",
" -0.485066 | \n",
" 23947.429812 | \n",
" -18913.037576 | \n",
"
\n",
" \n",
" 3 | \n",
" 1.02 | \n",
" 2.869968 | \n",
" -75097.859292 | \n",
" 19478.259200 | \n",
"
\n",
" \n",
"
\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",
" p_hv_kw | \n",
" q_hv_kvar | \n",
" p_lv_kw | \n",
" q_lv_kvar | \n",
" pl_kw | \n",
" ql_kvar | \n",
" i_hv_ka | \n",
" i_lv_ka | \n",
" loading_percent | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 11071.749595 | \n",
" -153.95827 | \n",
" -11013.580692 | \n",
" 324.30853 | \n",
" 58.168903 | \n",
" 170.35026 | \n",
" 0.029059 | \n",
" 0.057831 | \n",
" 11.07282 | \n",
"
\n",
" \n",
"
\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",
" p_from_kw | \n",
" q_from_kvar | \n",
" p_to_kw | \n",
" q_to_kvar | \n",
" pl_kw | \n",
" ql_kvar | \n",
" i_from_ka | \n",
" i_to_ka | \n",
" i_ka | \n",
" loading_percent | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" -4940.648422 | \n",
" -7253.511043 | \n",
" 5009.659789 | \n",
" 5024.015034 | \n",
" 69.011368 | \n",
" -2229.496009 | \n",
" 0.046064 | \n",
" 0.036508 | \n",
" 0.046064 | \n",
" 9.800771 | \n",
"
\n",
" \n",
" 1 | \n",
" -28957.089601 | \n",
" 13889.022542 | \n",
" 29770.915374 | \n",
" -13899.350544 | \n",
" 813.825772 | \n",
" -10.328003 | \n",
" 0.165259 | \n",
" 0.169067 | \n",
" 0.169067 | \n",
" 35.971608 | \n",
"
\n",
" \n",
" 2 | \n",
" 45326.943919 | \n",
" -5578.908656 | \n",
" -44045.770886 | \n",
" 6929.202512 | \n",
" 1281.173032 | \n",
" 1350.293856 | \n",
" 0.235000 | \n",
" 0.234024 | \n",
" 0.235000 | \n",
" 50.000000 | \n",
"
\n",
" \n",
"
\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",
" p_kw | \n",
" q_kvar | \n",
" va_degree | \n",
" vm_pu | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" -80000.00000 | \n",
" -17252.534836 | \n",
" 2.328268 | \n",
" 1.050000 | \n",
"
\n",
" \n",
" 1 | \n",
" -66517.87775 | \n",
" 10226.373497 | \n",
" 3.666003 | \n",
" 1.040019 | \n",
"
\n",
" \n",
"
\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",
" vm_pu | \n",
" va_degree | \n",
" p_kw | \n",
" q_kvar | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1.000000 | \n",
" 0.000000 | \n",
" 4542.418041 | \n",
" 8523.878212 | \n",
"
\n",
" \n",
" 1 | \n",
" 1.010373 | \n",
" 0.298334 | \n",
" 60000.000000 | \n",
" 0.000000 | \n",
"
\n",
" \n",
" 2 | \n",
" 1.050000 | \n",
" 2.328268 | \n",
" -10000.000000 | \n",
" -17252.534836 | \n",
"
\n",
" \n",
" 3 | \n",
" 1.040019 | \n",
" 3.666003 | \n",
" -56517.877750 | \n",
" 10226.373497 | \n",
"
\n",
" \n",
"
\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
}