Skip to content

Commit b3e1f20

Browse files
author
Denis Bonnand
committed
Add comments and fix dc losses
Signed-off-by: Denis Bonnand <[email protected]>
1 parent 99be249 commit b3e1f20

File tree

8 files changed

+29
-75
lines changed

8 files changed

+29
-75
lines changed

pypowsybl/opf/impl/bounds/dc_node_voltage_bounds.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ def add(self, parameters: ModelParameters, network_cache: NetworkCache,
1616
variable_context: VariableContext, model: ipopt.Model):
1717
for dc_node_num, row in enumerate(network_cache.dc_nodes.itertuples()):
1818
#TODO add voltage limits in DC NODE core modelization
19-
low_voltage_limit = -1.2
20-
high_voltage_limit = 1.2
19+
low_voltage_limit = -1
20+
high_voltage_limit = 1
2121
v_bounds = Bounds(low_voltage_limit, high_voltage_limit)
2222
logger.log(TRACE_LEVEL, f"Add voltage magnitude bounds {v_bounds} to dc_node '{row.Index}' (num={dc_node_num})'")
2323
model.set_variable_bounds(variable_context.v_dc_vars[dc_node_num],

pypowsybl/opf/impl/bounds/voltage_source_converter_power_bounds.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ def add(self, parameters: ModelParameters, network_cache: NetworkCache,
1717
# Voltage source converter active and reactive power bounds
1818
for converter_num, row in enumerate(network_cache.voltage_source_converters.itertuples()):
1919
#TODO implements max P, Q in converter core modelization
20-
max_p = 100000.0
21-
max_q = 100000.0
20+
max_p = 100.0
21+
max_q = 100.0
2222
p_bounds = Bounds(-max_p, max_p).mirror()
2323
logger.log(TRACE_LEVEL,
2424
f"Add active power bounds {p_bounds} to converter '{row.Index}' (num={converter_num})")

pypowsybl/opf/impl/constraints/voltage_source_converter_constraints.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,8 @@ def add(self, parameters: ModelParameters, network_cache: NetworkCache, variable
3333
if control_mode == "P_PCC":
3434
p_ac_eq = conv_p_var - target_p
3535
model.add_nl_constraint(p_ac_eq == 0.0)
36-
# elif control_mode == "V_DC":
37-
# if dc_connected2:
38-
# dc_node_v_eq = v1_var - v2_var - target_v_dc
39-
# else:
40-
# dc_node_v_eq = v1_var - target_v_dc
41-
# model.add_nl_constraint(dc_node_v_eq == 0.0)
36+
37+
# if control_mode == "V_DC", we let the opf determine the value of U
4238

4339
if voltage_regulator_on:
4440
bus_v_eq = bus_v_var - target_v_ac
@@ -47,11 +43,17 @@ def add(self, parameters: ModelParameters, network_cache: NetworkCache, variable
4743
q_ac_eq = conv_q_var - target_q
4844
model.add_nl_constraint(q_ac_eq == 0.0)
4945

46+
# P_loss = loss_1 + loss_2*I_ac + loss_3*I_ac**2 with the 3 loss coefficients
5047
i_ac_var = nl.sqrt(nl.pow(conv_p_var,2) + nl.pow(conv_q_var,2))/1000.0
5148
p_loss = idle_loss + switching_loss*i_ac_var + resistive_loss*nl.pow(i_ac_var,2)
49+
50+
u_var = 0
51+
if dc_connected1:
52+
u_var+= v1_var
5253
if dc_connected2:
53-
conv_p_dc_eq = (-conv_p_var - p_loss) - conv_i_var*(v1_var - v2_var + 0.001)
54-
else:
55-
conv_p_dc_eq = (-conv_p_var - p_loss) - conv_i_var * (v1_var + 0.001)
54+
u_var-= v2_var
55+
# P_dc = -P_ac - P_loss because we consider that the power P_dc injected in DC is positive,
56+
# and the power P_ac flowing out of AC is negative
57+
conv_p_dc_eq = (-conv_p_var - p_loss) - conv_i_var * (u_var + 0.001)
5658

5759
model.add_nl_constraint(conv_p_dc_eq == 0.0)

pypowsybl/opf/impl/costs/maximal_dc_voltage_cost_function.py

Lines changed: 0 additions & 18 deletions
This file was deleted.

pypowsybl/opf/impl/costs/minimize_dc_losses.py

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,5 @@ def __init__(self):
1313
def create(self, network_cache: NetworkCache, variable_context: VariableContext) -> ExprBuilder:
1414
cost = poi.ExprBuilder()
1515
for dc_line_num, dc_line_row in enumerate(network_cache.dc_lines.itertuples()):
16-
p_line_loss = dc_line_row.r * variable_context.closed_dc_line_i1_vars[dc_line_num]*variable_context.closed_dc_line_i1_vars[dc_line_num]
17-
cost+= p_line_loss
18-
# for conv_num, conv_row in enumerate(network_cache.voltage_source_converters.itertuples()):
19-
# if conv_row.bus_id:
20-
# conv_q_var = variable_context.conv_q_vars[conv_num]
21-
# conv_p_var = variable_context.conv_p_vars[conv_num]
22-
# cost += conv_q_var * conv_q_var + conv_p_var * conv_p_var
23-
# if conv_row.dc_connected1 and conv_row.dc_connected2:
24-
# dc_node1_num = network_cache.dc_nodes.index.get_loc(conv_row.dc_node1_id)
25-
# dc_node2_num = network_cache.dc_nodes.index.get_loc(conv_row.dc_node2_id)
26-
# v1_var = variable_context.v_dc_vars[dc_node1_num]
27-
# v2_var = variable_context.v_dc_vars[dc_node2_num]
28-
# cost += (v1_var - v2_var) * (v1_var - v2_var)
29-
# elif conv_row.dc_connected1:
30-
# dc_node1_num = network_cache.dc_nodes.index.get_loc(conv_row.dc_node1_id)
31-
# v1_var = variable_context.v_dc_vars[dc_node1_num]
32-
# cost += v1_var * v1_var
16+
cost+= variable_context.closed_dc_line_i1_vars[dc_line_num]**2 + variable_context.closed_dc_line_i2_vars[dc_line_num]**2
3317
return cost

pypowsybl/opf/impl/model/variable_context.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ def build(network_cache: NetworkCache, model: ipopt.Model) -> 'VariableContext':
254254
converter_nums.append(converter_num)
255255
conv_p_vars = model.add_m_variables(len(converter_nums), name="conv_p_vars")
256256
conv_q_vars = model.add_m_variables(len(converter_nums), name="conv_q_vars")
257+
# for one converter, conv_i is the DC current flowing from dc_node1 to dc_node2
257258
conv_i_vars = model.add_m_variables(len(converter_nums), name="conv_i_vars")
258259

259260
return VariableContext(v_vars, ph_vars,

pypowsybl/opf/impl/opf.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
from pypowsybl.opf.impl.constraints.dc_ground_constraints import DcGroundConstraints
3131
from pypowsybl.opf.impl.costs.minimize_against_reference_cost_function import MinimizeAgainstReferenceCostFunction
3232
from pypowsybl.opf.impl.costs.redispatching_cost_function import RedispatchingCostFunction
33-
from pypowsybl.opf.impl.costs.maximal_dc_voltage_cost_function import MaximalDcVoltageCostFunction
3433
from pypowsybl.opf.impl.costs.minimize_dc_losses import MinimizeDcLossesFunction
3534
from pypowsybl.opf.impl.model.bounds import Bounds
3635
from pypowsybl.opf.impl.model.constraints import Constraints
@@ -91,21 +90,20 @@ def run(self, parameters: OptimalPowerFlowParameters) -> bool:
9190
constraints.append(CurrentLimitConstraints())
9291
cost_function = RedispatchingCostFunction(1.0, 1.0, 1.0)
9392
else:
94-
# cost_function = MinimizeAgainstReferenceCostFunction()
95-
# cost_function = MaximalDcVoltageCostFunction()
9693
cost_function = MinimizeDcLossesFunction()
9794
model_parameters = ModelParameters(parameters.reactive_bounds_reduction,
9895
parameters.twt_split_shunt_admittance,
9996
Bounds(parameters.default_voltage_bounds[0], parameters.default_voltage_bounds[1]))
10097
opf_model = OpfModel.build(network_cache, model_parameters, variable_bounds, constraints, cost_function)
10198

99+
#BATTERY don't have target_v attribute and VSC_CONVERTER no target_p
102100
network_stats = NetworkStatistics(network_cache)
103101
network_stats.add(ElementType.GENERATOR, 'target_v')
104-
network_stats.add(ElementType.BATTERY, 'target_v')
102+
# network_stats.add(ElementType.BATTERY, 'target_v')
105103
network_stats.add(ElementType.VSC_CONVERTER_STATION, 'target_v')
106104
network_stats.add(ElementType.GENERATOR, 'target_p')
107105
network_stats.add(ElementType.BATTERY, 'target_p')
108-
network_stats.add(ElementType.VSC_CONVERTER_STATION, 'target_p')
106+
# network_stats.add(ElementType.VSC_CONVERTER_STATION, 'target_p')
109107

110108
logger.info("Starting optimization...")
111109
start = time.perf_counter()

tests/test_opf.py

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,13 @@ def run_opf_then_lf(network: pp.network.Network,
8080
print(network.get_voltage_source_converters())
8181
print(network.get_buses())
8282
print(network.get_lines())
83+
84+
# validate is not implemented for DC components yet
8385
# validate(network, lf_parameters=lf_parameters)
8486

8587
lf_parameters.voltage_init_mode = pp.loadflow.VoltageInitMode.PREVIOUS_VALUES
8688
lf_result = pp.loadflow.run_ac(network, lf_parameters)
87-
print(network.get_dc_nodes())
88-
print(network.get_dc_lines())
89-
print(network.get_voltage_source_converters())
90-
print(network.get_buses())
91-
print(network.get_lines())
92-
print(lf_result[0].status)
89+
9390
assert lf_result[0].status == pp.loadflow.ComponentStatus.CONVERGED
9491
assert lf_result[0].iteration_count == iteration_count
9592

@@ -222,23 +219,13 @@ def test_micro_grid_nl():
222219
run_opf_then_lf(pp.network.create_micro_grid_nl_network())
223220

224221
def test_ac_dc_network():
225-
import logging
226-
logging.basicConfig()
227-
logging.getLogger('powsybl').setLevel(0)
228-
parameters = lf.Parameters(provider_parameters={'maxNewtonRaphsonIterations': '16', 'acDcNetwork': 'True', 'slackBusSelector': 'FIRST'})
229-
run_opf_then_lf(pp.network.create_ac_dc_network(), lf_parameters=parameters)
222+
parameters = lf.Parameters(provider_parameters={'slackBusSelector': 'FIRST'})
223+
run_opf_then_lf(pp.network.create_ac_dc_network(), lf_parameters=parameters, iteration_count=2)
230224

231225
def test_ac_dc_bipolar_network():
232-
import logging
233-
logging.basicConfig()
234-
logging.getLogger('powsybl').setLevel(0)
235-
parameters = lf.Parameters(provider_parameters={'maxNewtonRaphsonIterations': '16', 'acDcNetwork': 'True', 'slackBusSelector': 'FIRST'})
236-
run_opf_then_lf(pp.network.create_ac_dc_bipolar_network(), lf_parameters=parameters)
226+
parameters = lf.Parameters(provider_parameters={'slackBusSelector': 'FIRST'})
227+
run_opf_then_lf(pp.network.create_ac_dc_bipolar_network(), lf_parameters=parameters, iteration_count=3)
237228

238229
def test_ac_dc_bipolar_network_with_metallic_return():
239-
import logging
240-
logging.basicConfig()
241-
logging.getLogger('powsybl').setLevel(0)
242-
parameters = lf.Parameters(provider_parameters={'maxNewtonRaphsonIterations': '16', 'acDcNetwork': 'True',
243-
'slackBusSelector': 'FIRST'})
244-
run_opf_then_lf(pp.network.create_ac_dc_bipolar_network_with_metallic_return(), lf_parameters=parameters)
230+
parameters = lf.Parameters(provider_parameters={'slackBusSelector': 'FIRST'})
231+
run_opf_then_lf(pp.network.create_ac_dc_bipolar_network_with_metallic_return(), lf_parameters=parameters, iteration_count=3)

0 commit comments

Comments
 (0)