Skip to content

Commit

Permalink
Changing OPF cost definition:
Browse files Browse the repository at this point in the history
The sign was confusing and maximization and minimization could not be clearly distinguished. Tutorial and further tests are coming.
  • Loading branch information
friederikemeier committed Apr 18, 2018
1 parent 47d026a commit b509a75
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 103 deletions.
4 changes: 2 additions & 2 deletions pandapower/converter/pypower/from_ppc.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def _create_costs(net, ppc, gen_lookup, type, idx):
idx)
pp.create_piecewise_linear_cost(net, gen_lookup.element.at[idx],
gen_lookup.element_type.at[idx],
ppc['gencost'][idx, 4:], type)
- ppc['gencost'][idx, 4:], type)
elif ppc['gencost'][idx, 0] == 2:
if len(ppc['gencost'][idx, 4:]) == ppc['gencost'][idx, 3]:
n = len(ppc['gencost'][idx, 4:])
Expand All @@ -41,7 +41,7 @@ def _create_costs(net, ppc, gen_lookup, type, idx):
logger.error("In gencost line %s, the number n does not fit to the number of values" %
idx)
pp.create_polynomial_cost(net, gen_lookup.element.at[idx], gen_lookup.element_type.at[idx],
values, type)
- values, type)
else:
logger.info("Cost mode of gencost line %s is unknown." % idx)

Expand Down
8 changes: 4 additions & 4 deletions pandapower/opf/make_objective.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# and Energy System Technology (IEE), Kassel. All rights reserved.


from numpy import zeros, array, concatenate, power
from numpy import zeros, array, concatenate, power, ndarray
from pandapower.idx_cost import MODEL, NCOST, COST


Expand Down Expand Up @@ -133,7 +133,7 @@ def _make_objective(ppci, net):
n_piece_lin_coefficients+1:2] = - f * 1e3
else:
ppci["gencost"][elements, COST+1:COST+n_piece_lin_coefficients +
1:2] = f * 1e3 * sign_corr
1:2] = - f * 1e3 * sign_corr

ppci["gencost"][elements, NCOST] = n_coefficients / 2
ppci["gencost"][elements, MODEL] = 1
Expand Down Expand Up @@ -172,7 +172,7 @@ def _make_objective(ppci, net):
c = costs.loc[(costs.element_type == el) &
(costs.element.isin(el_is))].c.reset_index(drop=True)

if len(c) > 0:
if len(c) > 0 and isinstance(idx, ndarray):
c = concatenate(c)
n_c = c.shape[1]
c = c * power(1e3, array(range(n_c))[::-1])
Expand All @@ -188,7 +188,7 @@ def _make_objective(ppci, net):
if el in ["load", "dcline"]:
ppci["gencost"][elements, COST:(COST + n_c):] = - c
else:
ppci["gencost"][elements, -n_c:n_gencost] = c * sign_corr
ppci["gencost"][elements, -n_c:n_gencost] = - c * sign_corr

ppci["gencost"][elements, NCOST] = n_coefficients
ppci["gencost"][elements, MODEL] = 2
Expand Down
8 changes: 4 additions & 4 deletions pandapower/test/opf/test_3point_pwl.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def test_3point_pwl():
c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876,
max_loading_percent=100 * 690)
pp.create_piecewise_linear_cost(net, 0, "sgen", np.array(
[[-100, 1], [0, 0], [100, 1], ]), type="q")
[[-100, -1], [0, 0], [100, -1], ]), type="q")

# creating a pwl cost function that actually is realistic: The absolute value of the reactive power has costs.

Expand All @@ -33,14 +33,14 @@ def test_3point_pwl():

# the first sgen is only representing the positive segment of the function:
net.piecewise_linear_cost.p.at[0] = np.array([[0, 1]])
net.piecewise_linear_cost.f.at[0] = np.array([[0, 1]])
net.piecewise_linear_cost.f.at[0] = np.array([[0, -1]])
net.sgen.min_q_kvar.at[0] = 0

# what we can do instead is modelling a second sgen on the same bus representing the negative segment of the function:
pp.create_sgen(net, 1, p_kw=0, q_kvar=0, controllable=True, max_p_kw=0.01, min_p_kw=-0.01, max_q_kvar=0,
min_q_kvar=-10)
pp.create_piecewise_linear_cost(net, 1, "sgen", np.array(
[[-100, 100], [0, 0], ]), type="q")
[[-100, -100], [0, 0], ]), type="q")

# runOPF
pp.runopp(net, verbose=False)
Expand All @@ -55,5 +55,5 @@ def test_3point_pwl():


if __name__ == "__main__":
pytest.main(["test_3point_pwl.py", "-xs"])
pytest.main(['-s', __file__])
# test_cost_piecewise_linear_eg_q()
120 changes: 60 additions & 60 deletions pandapower/test/opf/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def test_simplest_voltage():
pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876,
c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876,
max_loading_percent=100)
pp.create_polynomial_cost(net, 0, "gen", np.array([-100, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([100, 0]))
# run OPF
for init in ["pf", "flat"]:
pp.runopp(net, verbose=False, init=init)
Expand Down Expand Up @@ -158,9 +158,9 @@ def test_simplest_dispatch():
pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4)
pp.create_gen(net, 1, p_kw=-100, controllable=True, max_p_kw=-5, min_p_kw=-150, max_q_kvar=50,
min_q_kvar=-50)
pp.create_polynomial_cost(net, 0, "gen", np.array([-100, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([100, 0]))
pp.create_ext_grid(net, 0)
pp.create_polynomial_cost(net, 0, "ext_grid", np.array([-101, 0]))
pp.create_polynomial_cost(net, 0, "ext_grid", np.array([101, 0]))
pp.create_load(net, 1, p_kw=20, controllable=False)
pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876,
c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876,
Expand Down Expand Up @@ -203,7 +203,7 @@ def test_opf_gen_voltage():
in_service=True, index=None, max_loading_percent=200)
pp.create_gen(net, 3, p_kw=-10, controllable=True, max_p_kw=0, min_p_kw=-25, max_q_kvar=500,
min_q_kvar=-500)
pp.create_polynomial_cost(net, 0, "gen", np.array([-10, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([10, 0]))
pp.create_ext_grid(net, 0)
pp.create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876,
c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876,
Expand Down Expand Up @@ -249,7 +249,7 @@ def test_opf_sgen_voltage():
in_service=True, index=None, max_loading_percent=1000000)
pp.create_sgen(net, 3, p_kw=-10, controllable=True, max_p_kw=-5, min_p_kw=-15, max_q_kvar=25,
min_q_kvar=-25)
pp.create_polynomial_cost(net, 0, "sgen", np.array([-100, 0]))
pp.create_polynomial_cost(net, 0, "sgen", np.array([100, 0]))
pp.create_ext_grid(net, 0)
pp.create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876,
c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876,
Expand Down Expand Up @@ -296,9 +296,9 @@ def test_opf_gen_loading():
in_service=True, index=None, max_loading_percent=145)
pp.create_gen(net, 3, p_kw=-10, controllable=True, max_p_kw=-5, min_p_kw=-15, max_q_kvar=50,
min_q_kvar=-50)
pp.create_polynomial_cost(net, 0, "gen", np.array([10, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([-10, 0]))
pp.create_ext_grid(net, 0)
pp.create_polynomial_cost(net, 0, "ext_grid", np.array([-.1, 0]))
pp.create_polynomial_cost(net, 0, "ext_grid", np.array([.1, 0]))
pp.create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876,
c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876,
max_loading_percent=max_line_loading)
Expand Down Expand Up @@ -347,9 +347,9 @@ def test_opf_sgen_loading():
max_loading_percent=max_trafo_loading)
pp.create_sgen(net, 3, p_kw=-10, controllable=True, max_p_kw=-5, min_p_kw=-15, max_q_kvar=25,
min_q_kvar=-25)
pp.create_polynomial_cost(net, 0, "sgen", np.array([10, 0]))
pp.create_polynomial_cost(net, 0, "sgen", np.array([-10, 0]))
pp.create_ext_grid(net, 0)
pp.create_polynomial_cost(net, 0, "ext_grid", np.array([-.1, 0]))
pp.create_polynomial_cost(net, 0, "ext_grid", np.array([.1, 0]))
pp.create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876,
c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876,
max_loading_percent=max_line_loading)
Expand Down Expand Up @@ -392,7 +392,7 @@ def test_unconstrained_line():
pp.create_load(net, 1, p_kw=20, controllable=False)
pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876,
c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876)
pp.create_polynomial_cost(net, 0, "gen", np.array([-1, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([1, 0]))
# run OPF
for init in ["pf", "flat"]:
pp.runopp(net, verbose=False, init=init)
Expand Down Expand Up @@ -430,7 +430,7 @@ def test_trafo3w_loading():

def test_dcopf_poly(simple_opf_test_net):
net = simple_opf_test_net
pp.create_polynomial_cost(net, 0, "gen", np.array([-100, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([100, 0]))
# run OPF
pp.rundcopp(net, verbose=False)

Expand All @@ -444,7 +444,7 @@ def test_dcopf_poly(simple_opf_test_net):

def test_opf_poly(simple_opf_test_net):
net = simple_opf_test_net
pp.create_polynomial_cost(net, 0, "gen", np.array([-100, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([100, 0]))
# run OPF
for init in ["pf", "flat"]:
pp.runopp(net, verbose=False, init=init)
Expand All @@ -462,7 +462,7 @@ def test_opf_pwl(simple_opf_test_net):
# create net
net = simple_opf_test_net
# pp.create_polynomial_cost(net, 0, "gen", np.array([-100, 0]))
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[-200, 20000], [-100, 10000], [0, 0]]))
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[-200, -20000], [-100, -10000], [0, 0]]))
# run OPF
for init in ["pf", "flat"]:
pp.runopp(net, verbose=False, init=init)
Expand All @@ -481,7 +481,7 @@ def test_dcopf_pwl(simple_opf_test_net):
# create net
net = simple_opf_test_net
# pp.create_polynomial_cost(net, 0, "gen", np.array([-100, 0]))
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[-200, 20000], [-100, 10000], [0, 0]]))
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[-200, -20000], [-100, -10000], [0, 0]]))
# run OPF
pp.rundcopp(net, verbose=False)
assert net["OPF_converged"]
Expand Down Expand Up @@ -522,8 +522,8 @@ def test_opf_varying_max_line_loading():
min_q_kvar=-25)
pp.create_sgen(net, 2, p_kw=-100, controllable=True, max_p_kw=-5, min_p_kw=-150, max_q_kvar=25,
min_q_kvar=-25)
pp.create_polynomial_cost(net, 0, "sgen", np.array([-10, 0]))
pp.create_polynomial_cost(net, 1, "sgen", np.array([-10, 0]))
pp.create_polynomial_cost(net, 0, "sgen", np.array([10, 0]))
pp.create_polynomial_cost(net, 1, "sgen", np.array([10, 0]))
pp.create_ext_grid(net, 0)
pp.create_polynomial_cost(net, 0, "ext_grid", np.array([-.1, 0]))
pp.create_line_from_parameters(net, 1, 2, 1, name="line1", r_ohm_per_km=0.876,
Expand Down Expand Up @@ -585,13 +585,13 @@ def test_storage_opf():


# costs
pp.create_polynomial_cost(net, 0, "ext_grid", np.array([0, 3, 0]))
pp.create_polynomial_cost(net, 0, "ext_grid", np.array([0, -3, 0]))
#pp.create_polynomial_cost(net, 0, "load", np.array([0, -1, 0]))
# TODO - Gitlab Issue #27 - OPF error wenn Kosten für non-controllable PQ-Element zugewiesen
# vgl. make_objective.py, Z.47ff.
pp.create_polynomial_cost(net, 0, "sgen", np.array([0, 2, 0]))
pp.create_polynomial_cost(net, 0, "storage", np.array([0, 1, 0]))
pp.create_polynomial_cost(net, 1, "sgen", np.array([0, 1, 0]))
pp.create_polynomial_cost(net, 0, "sgen", np.array([0, -2, 0]))
pp.create_polynomial_cost(net, 0, "storage", np.array([0, -1, 0]))
pp.create_polynomial_cost(net, 1, "sgen", np.array([0, -1, 0]))
pp.create_polynomial_cost(net, 1, "load", np.array([0, -3, 0]))

# test storage generator behaviour
Expand Down Expand Up @@ -633,7 +633,7 @@ def test_storage_opf():
net["storage"].min_q_kvar.iloc[0] = -25
# gencost for storages: positive costs in pandapower per definition
# --> storage gencosts are similar to sgen gencosts (make_objective.py, l.128ff. and l.185ff.)
net["polynomial_cost"].c.iloc[2] = - net["polynomial_cost"].c.iloc[4]
net["polynomial_cost"].c.iloc[2] = net["polynomial_cost"].c.iloc[4]
net["sgen"].in_service.iloc[1] = False
net["load"].in_service.iloc[1] = False

Expand Down Expand Up @@ -710,57 +710,57 @@ def test_no_controllables(simple_opf_test_net):
net.gen.controllable = False
# pp.runopp(net)
# net.gen = net.gen.drop(index=0)
pp.create_polynomial_cost(net, 0, "gen", np.array([0, 2, 0]))
pp.create_polynomial_cost(net, 0, "load", np.array([0, -1, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([0, -2, 0]))
pp.create_polynomial_cost(net, 0, "load", np.array([0, 1, 0]))
pp.runopp(net)

def test_controllables_default():
""" Testing sgens/gens/loads with no defined controllable parameter """
# boundaries
vm_max = 1.1
#todo
vm_min = 0.9
max_line_loading_percent = 100

# create network
net = pp.create_empty_network()
b1 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min)
b2 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min)

pp.create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE",
max_loading_percent=max_line_loading_percent)

# test elements static
pp.create_ext_grid(net, b2)
pp.create_load(net, b1, p_kw=7.5, max_p_kw=10, min_p_kw=0,
max_q_kvar=2.5, min_q_kvar=-2.5)
net.load["controllable"] = False
# load should default to controllable =False
# pp.create_sgen(net, b1, p_kw=-25, max_p_kw=-10, min_p_kw=-25,
# max_q_kvar=25, min_q_kvar=-25)
# # sgen should default to controllable =True
# pp.create_gen(net, b1, p_kw=-25, max_p_kw=-10, min_p_kw=-25,
# max_q_kvar=25, min_q_kvar=-25)
# # gen should default to controllable =True

# costs
pp.create_polynomial_cost(net, 0, "ext_grid", np.array([0, 3, 0]))
pp.create_polynomial_cost(net, 0, "load", np.array([0, -1, 0]))
# def test_controllables_default():
# """ Testing sgens/gens/loads with no defined controllable parameter """
# # boundaries
# vm_max = 1.1
# #todo
# vm_min = 0.9
# max_line_loading_percent = 100
#9
# # create network
# net = pp.create_empty_network()
# b1 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min)
# b2 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min)
#
# pp.create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE",
# max_loading_percent=max_line_loading_percent)
#
# # test elements static
# pp.create_ext_grid(net, b2)
# pp.create_load(net, b1, p_kw=7.5, max_p_kw=10, min_p_kw=0,
# max_q_kvar=2.5, min_q_kvar=-2.5)
# net.load["controllable"] = False
# # load should default to controllable =False
# # pp.create_sgen(net, b1, p_kw=-25, max_p_kw=-10, min_p_kw=-25,
# # max_q_kvar=25, min_q_kvar=-25)
# # # sgen should default to controllable =True
# # pp.create_gen(net, b1, p_kw=-25, max_p_kw=-10, min_p_kw=-25,
# # max_q_kvar=25, min_q_kvar=-25)
# # # gen should default to controllable =True
#
# # costs
# pp.create_polynomial_cost(net, 0, "ext_grid", np.array([0,-3, 0]))
# pp.create_polynomial_cost(net, 0, "load", np.array([0, 1, 0]))
# pp.create_polynomial_cost(net, 0, "sgen", np.array([0, 2, 0]))
# pp.create_polynomial_cost(net, 0, "gen", np.array([0, 2, 0]))

pp.runopp(net, verbose=True)
assert net["OPF_converged"]

if __name__ == "__main__":
# pytest.main(['-s', __file__])
#test_storage_opf()
#test_opf_varying_max_line_loading()
pytest.main(['-s', __file__])
# test_storage_opf()
# test_opf_varying_max_line_loading()
# pytest.main(["test_basic.py", "-s"])
# test_simplest_dispatch()
# test_trafo3w_loading()
# test_trafo3w_loading()
# test_dcopf_pwl()
net = simple_opf_test_net()
test_no_controllables(net)
# net = simple_opf_test_net()
# test_no_controllables(net)
# test_controllables_default()
16 changes: 8 additions & 8 deletions pandapower/test/opf/test_costs_mixed.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ def test_cost_mixed():
max_loading_percent=100 * 690)

# testing some combinations
pp.create_polynomial_cost(net, 0, "gen", np.array([0, 1, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([0, -1, 0]))
pp.runopp(net, verbose=False)
assert net["OPF_converged"]
assert net.res_cost == - net.res_gen.p_kw.values

net.polynomial_cost.c.at[0] = np.array([[1, 0, 0]])
net.polynomial_cost.c.at[0] = np.array([[-1, 0, 0]])
pp.runopp(net, verbose=False)
assert net["OPF_converged"]
assert net.res_cost - net.res_gen.p_kw.values**2 < 1e-5

net.polynomial_cost.c.at[0] = np.array([[1, 0, 1]])
net.polynomial_cost.c.at[0] = np.array([[-1, 0, -1]])
pp.runopp(net, verbose=False)
assert net["OPF_converged"]
assert net.res_cost - net.res_gen.p_kw.values**2 - 1 < 1e-5
Expand All @@ -58,7 +58,7 @@ def test_cost_mixed():
pp.runopp(net, verbose=False)
assert net.res_cost - net.res_gen.p_kw.values ** 2 - 1 < 1e-5

pp.create_piecewise_linear_cost(net, 0, "load", np.array([[0, 0], [100, 100]]), type="p")
pp.create_piecewise_linear_cost(net, 0, "load", np.array([[0, 0], [100, -100]]), type="p")
pp.runopp(net, verbose=False)
assert net.res_cost - net.res_gen.p_kw.values ** 2 - 1 - net.res_load.p_kw.values < 1e-5

Expand All @@ -81,8 +81,8 @@ def test_mixed_p_q_pol():
max_loading_percent=100 * 690)

# testing some combinations
pp.create_polynomial_cost(net, 0, "gen", np.array([0, 1, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([0, 1, 0]), type ="q")
pp.create_polynomial_cost(net, 0, "gen", np.array([0, -1, 0]))
pp.create_polynomial_cost(net, 0, "gen", np.array([0, -1, 0]), type ="q")
pp.runopp(net, verbose=False)
assert net["OPF_converged"]
assert net.res_cost == - net.res_gen.p_kw.values + net.res_gen.q_kvar.values
Expand All @@ -106,8 +106,8 @@ def test_mixed_p_q_pwl():
max_loading_percent=100 * 690)

# testing some combinations
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[-150, -150],[150, 150]]))
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[-150, -150],[150, 150]]), type ="q")
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[-150, 150],[150, -150]]))
pp.create_piecewise_linear_cost(net, 0, "gen", np.array([[-150, 150],[150, -150]]), type ="q")
pp.runopp(net, verbose=False)
assert net["OPF_converged"]
assert net.res_cost == - net.res_gen.p_kw.values + net.res_gen.q_kvar.values
Expand Down
Loading

0 comments on commit b509a75

Please sign in to comment.