Skip to content

Commit

Permalink
WIP VSC as slack
Browse files Browse the repository at this point in the history
  • Loading branch information
rbolgaryn committed Nov 18, 2023
1 parent 7544a20 commit fd838b8
Show file tree
Hide file tree
Showing 14 changed files with 249 additions and 114 deletions.
7 changes: 5 additions & 2 deletions pandapower/auxiliary.py
Original file line number Diff line number Diff line change
Expand Up @@ -1508,8 +1508,11 @@ def _init_runpp_options(net, algorithm, calculate_voltage_angles, init,
if init_va_degree is None or (isinstance(init_va_degree, str) and init_va_degree == "auto"):
init_va_degree = "dc" if calculate_voltage_angles and not with_facts else "flat"
if init_vm_pu is None or (isinstance(init_vm_pu, str) and init_vm_pu == "auto"):
init_vm_pu = (net.ext_grid.vm_pu.values.sum() + net.gen.vm_pu.values.sum()) / \
(len(net.ext_grid.vm_pu.values) + len(net.gen.vm_pu.values))
init_vm_pu = (net.ext_grid.query("in_service").vm_pu.values.sum() +
net.gen.query("in_service").vm_pu.values.sum() +
net.vsc.query("in_service & (control_mode_ac == 'slack')").control_value_ac.values.sum()) / \
(len(net.ext_grid.query("in_service")) + len(net.gen.query("in_service")) +
len(net.vsc.query("in_service & (control_mode_ac == 'slack')")))
elif init == "dc":
init_vm_pu = "flat"
init_va_degree = "dc"
Expand Down
17 changes: 11 additions & 6 deletions pandapower/build_bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
from .pypower.idx_svc import svc_cols, SVC_BUS, SVC_SET_VM_PU, SVC_MIN_FIRING_ANGLE, SVC_MAX_FIRING_ANGLE, SVC_STATUS, \
SVC_CONTROLLABLE, SVC_X_L, SVC_X_CVAR, SVC_THYRISTOR_FIRING_ANGLE
from .pypower.idx_vsc import vsc_cols, VSC_BUS, VSC_INTERNAL_BUS, VSC_R, VSC_X, VSC_STATUS, VSC_CONTROLLABLE, \
VSC_BUS_DC, VSC_MODE_AC, VSC_VALUE_AC, VSC_MODE_DC, VSC_VALUE_DC
VSC_BUS_DC, VSC_MODE_AC, VSC_VALUE_AC, VSC_MODE_DC, VSC_VALUE_DC, VSC_MODE_AC_V, VSC_MODE_AC_Q, VSC_MODE_AC_SL, \
VSC_MODE_DC_V, VSC_MODE_DC_P

try:
from numba import jit
Expand Down Expand Up @@ -729,22 +730,26 @@ def _build_vsc_ppc(net, ppc, mode):
vsc[f:t, VSC_R] = net["vsc"]["r_ohm"].values / baseZ
vsc[f:t, VSC_X] = net["vsc"]["x_ohm"].values / baseZ

if np.any(~np.isin(mode_ac, ["vm_pu", "q_mvar"])):
if np.any(~np.isin(mode_ac, ["vm_pu", "q_mvar", "slack"])):
raise NotImplementedError("VSC element only supports the following control modes for AC side: vm_pu, q_mvar")

if np.any(~np.isin(mode_dc, ["vm_pu", "p_mw"])):
raise NotImplementedError("VSC element only supports the following control modes for AC side: vm_pu, q_mvar")

mode_ac_code = np.where(mode_ac == "vm_pu", 0, 1)
mode_ac_code = np.where(mode_ac == "vm_pu", VSC_MODE_AC_V,
np.where(mode_ac == "q_mvar", VSC_MODE_AC_Q, VSC_MODE_AC_SL))
vsc[f:t, VSC_MODE_AC] = mode_ac_code
vsc[f:t, VSC_VALUE_AC] = np.where(mode_ac_code == 0, value_ac, value_ac / baseMVA)
mode_dc_code = np.where(mode_dc == "vm_pu", 0, 1)
vsc[f:t, VSC_VALUE_AC] = np.where((mode_ac_code == VSC_MODE_AC_V) | (mode_ac_code == VSC_MODE_AC_SL),
value_ac, value_ac / baseMVA)
mode_dc_code = np.where(mode_dc == "vm_pu", VSC_MODE_DC_V, VSC_MODE_DC_P)
vsc[f:t, VSC_MODE_DC] = mode_dc_code
vsc[f:t, VSC_VALUE_DC] = np.where(mode_dc_code == 0, value_dc, value_dc / baseMVA)
vsc[f:t, VSC_VALUE_DC] = np.where(mode_dc == "vm_pu", value_dc, value_dc / baseMVA)

vsc[f:t, VSC_STATUS] = net._is_elements["vsc"].astype(np.int64)
vsc[f:t, VSC_CONTROLLABLE] = controllable & net["vsc"]["in_service"].values.astype(bool)
ppc["bus"][aux["vsc"][~controllable], BUS_TYPE] = PV
# it has a role of REF but internally it is PQ and we set the behavior of REF with the Jacobian and mismatch:
ppc["bus"][bus[mode_ac_code == 2], BUS_TYPE] = REF
# maybe we add this in the future
# ppc["bus"][aux["vsc"][~controllable], VM] = net["vsc"].loc[~controllable, "vm_internal_pu"].values

Expand Down
7 changes: 5 additions & 2 deletions pandapower/build_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
from pandapower.pypower.idx_brch import F_BUS, T_BUS
from pandapower.auxiliary import _subnetworks, _sum_by_group
from pandapower.pypower.idx_ssc import SSC_BUS, SSC_SET_VM_PU, SSC_CONTROLLABLE
from pandapower.pypower.idx_vsc import VSC_MODE_AC, VSC_BUS, VSC_VALUE_AC, VSC_CONTROLLABLE
from pandapower.pypower.idx_vsc import VSC_MODE_AC, VSC_BUS, VSC_VALUE_AC, VSC_CONTROLLABLE, VSC_MODE_AC_V, \
VSC_MODE_AC_SL

try:
import pandaplan.core.pplog as logging
Expand Down Expand Up @@ -336,7 +337,9 @@ def _check_voltage_setpoints_at_same_bus(ppc):
# ssc setpoints:
ssc_vm = ppc['ssc'][ssc_relevant, SSC_SET_VM_PU]
# vsc buses:
vsc_relevant = np.flatnonzero((ppc['vsc'][:, VSC_MODE_AC] == 0) & (ppc['vsc'][:, VSC_CONTROLLABLE] == 1))
vsc_relevant = np.flatnonzero(((ppc['vsc'][:, VSC_MODE_AC] == VSC_MODE_AC_V) |
(ppc['vsc'][:, VSC_MODE_AC] == VSC_MODE_AC_SL)) &
(ppc['vsc'][:, VSC_CONTROLLABLE] == 1))
vsc_bus = ppc['vsc'][vsc_relevant, VSC_BUS].astype(np.int64)
# vsc setpoints:
vsc_vm = ppc['vsc'][vsc_relevant, VSC_VALUE_AC]
Expand Down
3 changes: 2 additions & 1 deletion pandapower/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,8 @@ def create_empty_network(name="", f_hz=50., sn_mva=1, add_stdtypes=True):
("vm_internal_pu", "f8"),
("va_internal_degree", "f8"),
("vm_pu", "f8"),
("va_degree", "f8")],
("va_degree", "f8"),
("vm_dc_pu", "f8")],
"_empty_res_switch": [("i_ka", "f8"),
("loading_percent", "f8")],
"_empty_res_impedance": [("p_from_mw", "f8"),
Expand Down
9 changes: 5 additions & 4 deletions pandapower/pd2ppc.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from pandapower.pypower.idx_ssc import SSC_STATUS, SSC_BUS, SSC_INTERNAL_BUS
from pandapower.pypower.idx_tcsc import TCSC_STATUS, TCSC_F_BUS, TCSC_T_BUS
from pandapower.pypower.idx_svc import SVC_STATUS, SVC_BUS
from pandapower.pypower.idx_vsc import VSC_BUS_DC, VSC_STATUS, VSC_MODE_AC
from pandapower.pypower.idx_vsc import VSC_BUS_DC, VSC_STATUS, VSC_MODE_AC, VSC_MODE_AC_V, VSC_MODE_AC_Q, VSC_MODE_AC_SL
from pandapower.pypower.run_userfcn import run_userfcn


Expand Down Expand Up @@ -73,9 +73,10 @@ def _check_line_dc_at_b2b_buses(ppci):


def _check_vsc_different_ac_control_modes_at_same_bus(ppci):
ac_vm_pu_buses = ppci["vsc"][ppci["vsc"][:, VSC_MODE_AC] == 0, VSC_BUS]
ac_q_mvar_buses = ppci["vsc"][ppci["vsc"][:, VSC_MODE_AC] == 1, VSC_BUS]
ac_bus_intersection = np.intersect1d(ac_vm_pu_buses, ac_q_mvar_buses)
ac_vm_pu_buses = ppci["vsc"][ppci["vsc"][:, VSC_MODE_AC] == VSC_MODE_AC_V, VSC_BUS]
ac_q_mvar_buses = ppci["vsc"][ppci["vsc"][:, VSC_MODE_AC] == VSC_MODE_AC_Q, VSC_BUS]
ac_slack_buses = ppci["vsc"][ppci["vsc"][:, VSC_MODE_AC] == VSC_MODE_AC_SL, VSC_BUS]
ac_bus_intersection = np.intersect1d(np.intersect1d(ac_vm_pu_buses, ac_q_mvar_buses), ac_slack_buses)
if len(ac_bus_intersection) != 0:
raise NotImplementedError("Found multiple VSC converters that share the same AC bus and have "
"different AC control modes - not implemented. VSC converters can only "
Expand Down
Loading

0 comments on commit fd838b8

Please sign in to comment.