pub struct RealSparseSystem { /* private fields */ }Expand description
A real sparse system whose sparsity pattern is fixed across repeated solves (Newton-Raphson’s Jacobian: same bus topology every iteration, only numeric values change) — caches both the LU symbolic factorization (ordering + fill-in) and the triplet argsort (which sparse-matrix slot each triplet’s value lands in) once, and reuses both on each call.
Reusing the argsort matters on its own, separately from the LU symbolic
reuse: without it, every call would still re-sort and re-deduplicate the
full triplet list from scratch even though only the values differ
between calls — profiling with perf on a 2,605-node benchmark showed
this re-sorting cost was ~10% of total Newton-Raphson time (comparable to
the LU factorization itself), since a fresh try_new_from_triplets was
being paid for on every iteration despite the (row, col) pattern never
changing. new_from_argsort skips straight to placing values using the
cached order.
Implementations§
Source§impl RealSparseSystem
impl RealSparseSystem
Sourcepub fn new(n: usize, entries: &[(usize, usize, f64)]) -> Option<Self>
pub fn new(n: usize, entries: &[(usize, usize, f64)]) -> Option<Self>
Builds the symbolic factorization and argsort from an initial
sparsity pattern. Subsequent calls to factor_and_solve must supply
entries with the exact same (row, col) pairs in the exact same order
(values may differ) — the cached argsort assumes positional
correspondence, not just set equality.
Sourcepub fn factor_and_solve(
&self,
entries: &[(usize, usize, f64)],
rhs: &[f64],
) -> Option<Vec<f64>>
pub fn factor_and_solve( &self, entries: &[(usize, usize, f64)], rhs: &[f64], ) -> Option<Vec<f64>>
Numeric-only refactorization against the cached symbolic pattern and
argsort, then solves A x = b. Returns None if the matrix is
singular (see solve_complex’s doc comment for why this needs an
explicit check).
Sourcepub fn solve_values(&self, vals: &[f64], rhs: &[f64]) -> Option<Vec<f64>>
pub fn solve_values(&self, vals: &[f64], rhs: &[f64]) -> Option<Vec<f64>>
The body of factor_and_solve once the
(row, col) half of the triplets has been dropped — which this
backend never needed after new built the argsort.
A vals length other than the one new was given means the caller’s
pattern is not this factorization’s — a stale cache, which
gridoxide’s PersistentSolver::invalidate_admittances
can produce when a topology change alters the bus types and therefore
the unknown count. That is refused here rather than left to trip an
assertion inside faer: this type’s whole contract is None on a
system it cannot solve, and a panic crossing an FFI boundary is a much
worse failure than a reported one.
Trait Implementations§
Source§impl LinearSolver for RealSparseSystem
factor_and_solve is inherently &self here (faer keeps no mutable
per-solve state), but the trait takes &mut self because the FFI-backed
backends genuinely need it. Taking the stricter receiver costs nothing.
impl LinearSolver for RealSparseSystem
factor_and_solve is inherently &self here (faer keeps no mutable
per-solve state), but the trait takes &mut self because the FFI-backed
backends genuinely need it. Taking the stricter receiver costs nothing.
Source§fn new(n: usize, entries: &[(usize, usize, f64)]) -> Option<Self>
fn new(n: usize, entries: &[(usize, usize, f64)]) -> Option<Self>
entries’ sparsity pattern (fill-reducing ordering,
elimination structure) and factors it once. None if the pattern is
structurally invalid or the matrix is singular.Auto Trait Implementations§
impl Freeze for RealSparseSystem
impl RefUnwindSafe for RealSparseSystem
impl Send for RealSparseSystem
impl Sync for RealSparseSystem
impl Unpin for RealSparseSystem
impl UnsafeUnpin for RealSparseSystem
impl UnwindSafe for RealSparseSystem
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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