Skip to main content

powerio_matrix/matrix/
bdoubleprime.rs

1//! FDPF `B''` matrix. Reactive power Jacobian.
2//!
3//! Per MATPOWER `makeB.m`:
4//! - **XB scheme**: `B'' = -Im(Y_bus)` with phase shifts zeroed.
5//! - **BX scheme**: `B'' = -Im(Y_bus)` with line resistance and phase shifts
6//!   zeroed.
7//!
8//! Tap ratios, line charging, and bus shunts are kept in both schemes —
9//! they are what give B″ its strict diagonal dominance (full rank).
10
11use sprs::CsMat;
12
13use crate::Result;
14use crate::indexed::IndexedNetwork;
15
16use super::ybus::{YbusFlags, build_ybus_with_flags};
17use super::{BuildOptions, Scheme, negate_into};
18
19pub fn build_bdoubleprime(case: &IndexedNetwork, opts: &BuildOptions) -> Result<CsMat<f64>> {
20    let flags = YbusFlags {
21        zero_resistance: matches!(opts.scheme, Scheme::Bx),
22        zero_charging: false,
23        unity_taps: false,
24        zero_shifts: true,
25        skip_bus_shunts: false,
26    };
27    // `parts.b` is owned and discarded here, so negate it in place rather than
28    // cloning the structure.
29    let parts = build_ybus_with_flags(case, flags)?;
30    Ok(negate_into(parts.b))
31}