Skip to main content

NodeBreakerNetwork

Struct NodeBreakerNetwork 

Source
pub struct NodeBreakerNetwork {
    pub buses: Vec<Bus>,
    pub lines: Vec<Line>,
    pub transformers: Vec<Transformer>,
    pub shunts: Vec<ShuntAdm>,
    pub view: BusView,
    pub topology: NodeBreakerTopology,
    pub switch_labels: Vec<String>,
    pub zero_injection: Vec<bool>,
    /* private fields */
}
Expand description

A network whose retained switches are addressable elements.

The problem this solves is index arithmetic. regularized_branches appends switch branches to a transformer list, so a switch’s flat branch index is lines.len() + model_transformers + n — which the caller had to compute, and which silently desynchronizes the moment anything about the branch order changes. Owning the mapping removes that whole class of mistake, and it is what makes the rest of the crate usable on switches without knowing they are switches.

§What comes free

A retained switch is a branch, so nothing else needed changing to make the existing machinery work on one:

  • DC — linear::dc_power_flow takes the branch lists, so a switch’s active flow appears in DcSolution::branch_p at its own index.
  • Sensitivities — DcSensitivity::lodf_column at a switch’s branch index is its bus-split distribution factor.
  • AC contingencies — batch::BatchSolver::solve_contingencies outages a switch by its branch index like any other branch, so a switching campaign is an ordinary contingency sweep.

The one thing that is not free is the flow through a closed switch inside a loop of closed switches: see degenerate_switches and zero_impedance_branches.md.

Fields§

§buses: Vec<Bus>§lines: Vec<Line>§transformers: Vec<Transformer>

The model’s own transformers, followed by one branch per non-degenerate retained switch.

§shunts: Vec<ShuntAdm>§view: BusView§topology: NodeBreakerTopology

The switch graph the view was derived from, kept so a switch can report its own kind — a caller deciding whether to operate something needs to know a breaker from a disconnector, and neither BusView nor RetainedSwitch carries that.

§switch_labels: Vec<String>

Per switch, a human-meaningful identifier from the source model (a CGMES mRID). Empty when the source has none, in which case callers fall back to SwitchIdx.

§zero_injection: Vec<bool>

Per bus, whether no injecting equipment terminates on it.

State estimation’s reason for existing on this network: a bay’s internal nodes carry switches and nothing else, so the finer the topology, the more of the state is pinned by exact zero-injection constraints rather than by sensors. See SeNetwork::from_node_breaker.

Implementations§

Source§

impl NodeBreakerNetwork

Source

pub fn new( buses: Vec<Bus>, lines: Vec<Line>, transformers: Vec<Transformer>, shunts: Vec<ShuntAdm>, view: BusView, topology: NodeBreakerTopology, switch_labels: Vec<String>, zero_injection: Vec<bool>, treatment: SwitchTreatment, ) -> Self

Assembles the network, stamping retained switches under treatment.

Source

pub fn switch_kind(&self, switch: SwitchIdx) -> Option<SwitchKind>

A switch’s kind — breaker, disconnector, fuse and so on.

Source

pub fn switch_label(&self, switch: SwitchIdx) -> String

A switch’s source-model identifier, or its index rendered as text when the source supplied none.

Source

pub fn n_branches(&self) -> usize

Total branch count — the length of every branch-indexed vector the solvers return for this network.

Source

pub fn branch_of_retained(&self, n: usize) -> Option<usize>

The flat branch index of the nth retained switch, or None if it was degenerate (both ends on one bus) and therefore not stamped.

Source

pub fn branch_of_switch(&self, switch: SwitchIdx) -> Option<usize>

The flat branch index of a switch named by its position in the source topology, or None if it was not retained or was degenerate.

Source

pub fn switch_branches(&self) -> Vec<(SwitchIdx, usize)>

Every retained switch’s (SwitchIdx, branch index), skipping degenerate ones — the list a contingency campaign iterates.

Source

pub fn set_switch_open(&mut self, switch: SwitchIdx, open: bool) -> bool

Opens or closes a retained switch in place.

Changes Y-bus values only: the branch keeps its structural entries at zero when open, so the Y-bus sparsity pattern is unchanged.

The Jacobian pattern is a separate question, and the distinction matters for what a caller must invalidate:

  • A cached JacobianPattern is always stale afterwards, since it stores each entry’s admittance.
  • Its size changes too whenever the flip severs part of the network: connected_components sees the opening (it reads values, not just structure), mark_unreferenced_islands pins the stranded buses to Slack, and the unknown count moves with them.

So PersistentSolver::invalidate_admittances — which keeps the symbolic factorization — is correct only for a switch the caller knows cannot island anything. Otherwise use reset. Getting this wrong used to panic inside faer; RealSparseSystem::solve_values now refuses the mismatched call instead, so it surfaces as a failed solve.

Returns false if the switch is not retained or was degenerate.

Source

pub fn is_switch_open(&self, switch: SwitchIdx) -> Option<bool>

Whether a retained switch is currently open. None if it is not retained or was degenerate.

Source

pub fn constrained_switches(&self) -> Vec<ConstrainedSwitch>

This network’s retained switches as equality constraints, for constrained::solve_constrained.

Positionally matches BusView::retained, including the degenerate switches — a switch whose two ends already share a bus becomes a self-loop, which the constrained solver reports as indeterminate rather than skipping. Keeping them here is what lets a caller index straight from a switch to its flow.

Only meaningful under SwitchTreatment::Constrain. Under Regularize the switches are already in the branch list, and passing them here as well would model each of them twice.

Source

pub fn switch_flow( &self, switch: SwitchIdx, voltages: &[Complex<f64>], ) -> Option<(f64, f64)>

Complex power entering a switch at its from terminal, given solved bus voltages. None if the switch has no branch.

This is branch_flow::terminal_flow at the switch’s own index — a switch reports its flow through exactly the same path any other branch does.

Trait Implementations§

Source§

impl Clone for NodeBreakerNetwork

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for NodeBreakerNetwork

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByRef<T> for T

Source§

fn by_ref(&self) -> &T

Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DistributionExt for T
where T: ?Sized,

Source§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V