Source code for pwrs.core.makeSbus

# Copyright (c) 1996-2016, Power Systems Engineering Research Center (PSERC) by Ray Zimmerman, PSERC Cornell
# Modifications Copyright (c) 2026, Liangyu Zhang
# SPDX-License-Identifier: BSD-3-Clause
import numpy as np
from scipy import sparse

from ..corex import ArrayLike, ComplexArray, FloatArray, MatpowerConfig, SparseMatrix, as_csc_matrix
from .idx_gen import GEN_BUS, GEN_STATUS, PG, QG
from .makeSdzip import makeSdzip


[docs] def makeSbus_dV( baseMVA: float, bus: FloatArray, gen: FloatArray, mpopt: MatpowerConfig | None = None, Vm: ArrayLike | None = None, ) -> tuple[FloatArray, SparseMatrix]: """Return ``(empty, dSbus_dVm)`` with explicit Python semantics.""" nb = bus.shape[0] Sd = makeSdzip(baseMVA, bus, mpopt) if Vm is None or np.size(Vm) == 0: dSbus_dVm = sparse.csc_matrix((nb, nb), dtype=complex) else: Vm = np.asarray(Vm) diag = -(Sd["i"] + 2 * Vm * Sd["z"]) dSbus_dVm = sparse.diags(diag, shape=(nb, nb), format="csc").tocsc() return np.zeros((0, 0)), as_csc_matrix(dSbus_dVm)
[docs] def makeSbus_value_dV( baseMVA: float, bus: FloatArray, gen: FloatArray, mpopt: MatpowerConfig | None = None, Vm: ArrayLike | None = None, Sg: ArrayLike | None = None, ) -> tuple[ComplexArray, SparseMatrix]: """Return power injections together with the ZIP-load voltage derivative.""" return makeSbus_value(baseMVA, bus, gen, mpopt, Vm, Sg), makeSbus_dV(baseMVA, bus, gen, mpopt, Vm)[1]
[docs] def makeSbus_value( baseMVA: float, bus: FloatArray, gen: FloatArray, mpopt: MatpowerConfig | None = None, Vm: ArrayLike | None = None, Sg: ArrayLike | None = None, ) -> ComplexArray: """Return the complex bus injection vector with explicit Python semantics.""" nb = bus.shape[0] Sd = makeSdzip(baseMVA, bus, mpopt) on = np.where(gen[:, GEN_STATUS] > 0)[0] gbus = gen[on, GEN_BUS].astype(int) - 1 ngon = on.size Cg = sparse.csc_matrix((np.ones(ngon), (gbus, np.arange(ngon))), shape=(nb, ngon)) if Sg is not None and np.size(Sg): Sg = np.asarray(Sg) Sbusg = Cg @ Sg[on] else: Sbusg = Cg @ ((gen[on, PG] + 1j * gen[on, QG]) / baseMVA) if Vm is None or np.size(Vm) == 0: Vm = np.ones(nb) else: Vm = np.asarray(Vm) Sbusd = Sd["p"] + Sd["i"] * Vm + Sd["z"] * Vm**2 return Sbusg - Sbusd
[docs] def makeSbus( baseMVA: float, bus: FloatArray, gen: FloatArray, mpopt: MatpowerConfig | None = None, Vm: ArrayLike | None = None, Sg: ArrayLike | None = None, nargout: int | None = None, ) -> ComplexArray | tuple[FloatArray, SparseMatrix]: """Build the vector of complex bus power injections. Parameters ---------- baseMVA : float System base MVA. bus : array_like MATPOWER bus matrix. gen : array_like MATPOWER generator matrix. mpopt : dict, optional MATPOWER options dict. When provided together with ``Vm``, ZIP loads are evaluated using the configured system-wide ZIP coefficients. Vm : array_like, optional Bus voltage magnitudes used to evaluate voltage-dependent ZIP loads. If omitted or empty, nominal voltage is assumed. Sg : array_like, optional Complex generator injections in per unit. When provided, these values override the ``PG``/``QG`` columns in ``gen`` and ``gen`` is used only for connectivity. nargout : int, optional MATLAB-compatibility output selector. If ``nargout == 2``, the first return value is an empty array and the second is ``dSbus_dVm``. Returns ------- numpy.ndarray or tuple With the default single-output form, returns the complex bus injection vector in per unit, i.e. generation minus load. With ``nargout == 2``, returns ``(empty, dSbus_dVm)`` where ``dSbus_dVm`` is the partial derivative of bus injections with respect to voltage magnitude. See Also -------- makeYbus, makeSdzip """ if nargout == 2: return makeSbus_dV(baseMVA, bus, gen, mpopt, Vm) return makeSbus_value(baseMVA, bus, gen, mpopt, Vm, Sg)