Skip to content

Commit

Permalink
Trying to debug some PV buses not trying hard enough
Browse files Browse the repository at this point in the history
  • Loading branch information
miek770 committed Nov 5, 2018
1 parent 0157205 commit 150fa84
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 23 deletions.
15 changes: 9 additions & 6 deletions UnderDevelopment/GridCal/Engine/CalculationEngine.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ def __init__(self, n_bus, n_br, n_ld, n_ctrl_gen, n_sta_gen, n_batt, n_sh, n_tim
# bus
self.bus_names = np.empty(n_bus, dtype=object)
self.bus_vnom = np.zeros(n_bus, dtype=float)
self.bus_vset = np.ones(n_bus, dtype=float)
self.V0 = np.ones(n_bus, dtype=complex)
self.Vmin = np.ones(n_bus, dtype=float)
self.Vmax = np.ones(n_bus, dtype=float)
Expand Down Expand Up @@ -466,6 +467,7 @@ def compute(self, add_storage=True, add_generation=True, apply_temperature=False
circuit.controlled_gen_pmax = self.controlled_gen_pmax
circuit.controlled_gen_enabled = self.controlled_gen_enabled
circuit.controlled_gen_dispatchable = self.controlled_gen_dispatchable
circuit.bus_vset = self.bus_vset
circuit.battery_pmin = self.battery_pmin
circuit.battery_pmax = self.battery_pmax
circuit.battery_Enom = self.battery_Enom
Expand Down Expand Up @@ -1299,7 +1301,7 @@ def get_catalogue_dict_by_name(self, type_class=None):
def get_json_dict(self, id):
"""
Get json dictionary
:return:
:return:
"""
return {'id': id,
'type': 'circuit',
Expand Down Expand Up @@ -1765,8 +1767,8 @@ def set_object_attributes(obj_, attr_list, values):
def save_file(self, file_path):
"""
Save File
:param file_path:
:return:
:param file_path:
:return:
"""

if file_path.endswith('.xlsx'):
Expand Down Expand Up @@ -2055,9 +2057,9 @@ def save_excel(self, file_path):

def save_json(self, file_path):
"""
:param file_path:
:return:
:param file_path:
:return:
"""

from GridCal.Engine.Importers.JSON_parser import save_json_file
Expand Down Expand Up @@ -2178,6 +2180,7 @@ def compile(self, use_opf_vals=False, opf_time_series_results=None, logger=list(
circuit.Vmax[i] = bus.Vmax
circuit.Vmin[i] = bus.Vmin
circuit.bus_types[i] = bus.determine_bus_type().value[0]
circuit.bus_vset[i] = bus.determine_vset()

# Add buses dictionary entry
self.bus_dictionary[bus] = i
Expand Down
21 changes: 20 additions & 1 deletion UnderDevelopment/GridCal/Engine/Devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,25 @@ def __init__(self, name="Bus", vnom=10, vmin=0.9, vmax=1.1, xpos=0, ypos=0, heig
'zone': str,
'substation': str}


def determine_vset(self):
vset = None
conflict = None
previous = None
for elm in self.controlled_generators:
if vset is None or elm.Vset != vset:
if previous is None:
previous = elm
vset = elm.Vset
else:
print(f"More than one generators control bus {self.name}'s voltage, the higher setpoint will be used")
if vset < elm.Vset:
vset = elm.Vset
conflict = True
previous = elm.Vset
return vset


def determine_bus_type(self):
"""
Infer the bus type from the devices attached to it
Expand Down Expand Up @@ -786,7 +805,7 @@ def set_tap(self, tap_module):
self.tap = int((tap_module - 1.0) / self.inc_reg_up)
elif tap_module < 1:
self.tap = -int((1.0 - tap_module) / self.inc_reg_down)


class Branch(ReliabilityDevice):

Expand Down
1 change: 1 addition & 0 deletions UnderDevelopment/GridCal/Engine/IoStructures.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ def __init__(self, nbus, nbr, ntime, nbat, nctrlgen):
self.controlled_gen_pmax = np.zeros(nctrlgen, dtype=float)
self.controlled_gen_enabled = np.zeros(nctrlgen, dtype=bool)
self.controlled_gen_dispatchable = np.zeros(nctrlgen, dtype=bool)
self.bus_vset = np.ones(nbus, dtype=float)

self.battery_pmin = np.zeros(nbat, dtype=float)
self.battery_pmax = np.zeros(nbat, dtype=float)
Expand Down
49 changes: 33 additions & 16 deletions UnderDevelopment/GridCal/Engine/PowerFlowDriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,10 +336,10 @@ def single_power_flow(self, circuit: CalculationInputs, solver_type: SolverType,
any_tap_control_issue = True

# The control iterations are either the number of tap_regulated transformers or 10, the larger of the two
control_max_iter = 10
for k in circuit.bus_to_regulated_idx: # indices of the branches that are regulated at the bus "to"
control_max_iter = max(control_max_iter, circuit.max_tap[k] + circuit.min_tap[k])
# control_max_iter = max(len(circuit.bus_to_regulated_idx), 10)
# control_max_iter = 10
# for k in circuit.bus_to_regulated_idx: # indices of the branches that are regulated at the bus "to"
# control_max_iter = max(control_max_iter, circuit.max_tap[k] + circuit.min_tap[k])
control_max_iter = 99

inner_it = list()
outer_it = 0
Expand Down Expand Up @@ -388,7 +388,7 @@ def single_power_flow(self, circuit: CalculationInputs, solver_type: SolverType,
Qnew, \
types_new, \
any_q_control_issue = self.switch_logic(V=voltage_solution,
Vset=np.abs(voltage_solution),
Vset=circuit.bus_vset,
Q=Scalc.imag,
Qmax=circuit.Qmax,
Qmin=circuit.Qmin,
Expand Down Expand Up @@ -449,6 +449,9 @@ def single_power_flow(self, circuit: CalculationInputs, solver_type: SolverType,
# append converged
converged_lst.append(bool(converged))

if self.options.verbose:
print(f"Power flow completed in {outer_it} iterations")

# Compute the branches power and the slack buses power
Sbranch, Ibranch, loading, losses, \
flow_direction, Sbus = self.power_flow_post_process(calculation_inputs=circuit, V=voltage_solution)
Expand Down Expand Up @@ -609,44 +612,58 @@ def switch_logic(V, Vset, Q, Qmax, Qmin, types, original_types, verbose):
if types[i] == BusMode.REF.value[0]:
pass

# If the bus was a PV bus, but is now a PQ bus...
elif types[i] == BusMode.PQ.value[0] and original_types[i] == BusMode.PV.value[0]:

if Vm[i] != Vset[i]:
# If the voltage is not equal to its setpoint...
if round(Vm[i], 4) != round(Vset[i], 4):

if Q[i] >= Qmax[i]: # it is still a PQ bus but set Qi = Qimax .
if round(Q[i], 4) >= round(Qmax[i], 4):
# it is still a PQ bus but set Qi = Qimax.
Qnew[i] = Qmax[i]

elif Q[i] <= Qmin[i]: # it is still a PQ bus and set Qi = Qimin .
elif round(Q[i], 4) <= round(Qmin[i], 4):
# it is still a PQ bus and set Qi = Qimin .
Qnew[i] = Qmin[i]

else: # switch back to PV, set Vinew = Viset.
else:
# switch back to PV, set Vinew = Viset.
if verbose:
print('Bus', i, ' switched back to PV')
print(f"Bus {i} switched back to PV")
types_new[i] = BusMode.PV.value[0]
Vnew[i] = complex(Vset[i], 0)

any_control_issue = True

else:
pass # The voltages are equal
# The voltages are equal, it remains a PQ bus
pass

elif types[i] == BusMode.PV.value[0]:

if Q[i] >= Qmax[i]: # it is switched to PQ and set Qi = Qimax .
if round(Q[i], 4) > round(Qmax[i], 4): # it is switched to PQ and set Qi = Qimax .
if verbose:
print('Bus', i, ' switched to PQ: Q', Q[i], ' Qmax:', Qmax[i])
print(f"Bus {i} switched to PQ (Q > Qmax): Q: {round(Q[i], 4)}, Qmax: {round(Qmax[i], 4)}")
types_new[i] = BusMode.PQ.value[0]
Qnew[i] = Qmax[i]
any_control_issue = True

elif Q[i] <= Qmin[i]: # it is switched to PQ and set Qi = Qimin .
elif round(Q[i], 4) < round(Qmin[i], 4): # it is switched to PQ and set Qi = Qimin .
if verbose:
print('Bus', i, ' switched to PQ: Q', Q[i], ' Qmin:', Qmin[i])
print(f"Bus {i} switched to PQ (Q < Qmin): Q: {round(Q[i], 4)}, Qmin: {round(Qmin[i], 4)}")
types_new[i] = BusMode.PQ.value[0]
Qnew[i] = Qmin[i]
any_control_issue = True

else: # it is still a PV bus.
else:
# It is still a PV bus.
if verbose:
print(f"Bus {i} remains a PV bus:")
print(f" - V {round(Vm[i], 2)}")
print(f" - Vset {round(Vset[i], 4)}")
print(f" - Q {round(Q[i], 2)}")
print(f" - Qmin {round(Qmin[i], 2)}")
print(f" - Qmax {round(Qmax[i], 2)}")
pass

else:
Expand Down

0 comments on commit 150fa84

Please sign in to comment.