Source code for pwrs.core.dcpf
# 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 scipy.sparse.linalg import spsolve
[docs]
def dcpf(B, Pbus, Va0, ref, pv, pq):
"""Solve the linear DC power flow equations.
solves for the bus voltage angles at all but the reference bus,
given the full system B matrix and the vector of bus real power injections,
the initial vector of bus voltage angles (in radians), and column vectors with
the lists of bus indices for the swing bus, PV buses, and PQ buses,
respectively. Returns a vector of bus voltage angles in radians.
Parameters
----------
B : array_like or sparse matrix
DC power flow susceptance matrix.
Pbus : array_like
Real bus power injections.
Va0 : array_like
Initial/reference bus voltage angles.
ref : array_like
One-based reference bus indices.
pv : array_like
One-based PV bus indices.
pq : array_like
One-based PQ bus indices.
Returns
-------
tuple
``(Va, success)`` with solved bus voltage angles and a convergence flag.
"""
va_threshold = 1e5
if sparse.issparse(B):
B = B.tocsc()
else:
B = np.asarray(B)
Pbus = np.asarray(Pbus, dtype=float).reshape(-1)
Va0 = np.asarray(Va0, dtype=float).reshape(-1)
ref = np.asarray(ref, dtype=int).reshape(-1) - 1
pv = np.asarray(pv, dtype=int).reshape(-1) - 1
pq = np.asarray(pq, dtype=int).reshape(-1) - 1
Va = Va0.copy()
success = 1.0
pvpq = np.r_[pv, pq]
try:
rhs = Pbus[pvpq] - B[np.ix_(pvpq, ref)] @ Va0[ref]
submatrix = B[np.ix_(pvpq, pvpq)]
if sparse.issparse(submatrix):
Va[pvpq] = spsolve(submatrix, rhs)
else:
Va[pvpq] = np.linalg.solve(submatrix, rhs)
except Exception:
success = 0.0
if np.max(np.abs(Va)) > va_threshold:
success = 0.0
return Va.reshape(-1, 1), success