Source code for geopulse.solver.base

"""Abstract base class for circuit solvers.

The solver takes a :class:`~geopulse.network.base.ConductorNetwork` (which
provides ``Y_n``, ``Z_e``, and ``V_th``) and returns the GIC in every branch
and the voltage at every node.

References
----------
.. [1] Lehtinen, M., & Pirjola, R. (1985). Currents produced in earthed
   conductor networks by geomagnetically-induced electric fields. Annales
   Geophysicae, 3, 479-484.
.. [2] Boteler, D. H. (2014). Methodology for simulation of geomagnetically
   induced currents in power systems. J. Space Weather Space Clim., 4, A21.
"""

from __future__ import annotations

import abc
from dataclasses import dataclass
from typing import TYPE_CHECKING

import numpy as np

if TYPE_CHECKING:  # pragma: no cover
    from geopulse.network.base import ConductorNetwork

__all__ = ["Solver", "SolverResult"]


[docs] @dataclass(frozen=True) class SolverResult: """Result container from a circuit solve. Attributes ---------- node_voltages_V : numpy.ndarray Voltage at each node relative to remote earth. Shape ``(n_nodes,)`` or ``(n_times, n_nodes)`` for a time series. branch_currents_A : numpy.ndarray Current in each branch, in Amperes. Shape ``(n_branches,)`` or ``(n_times, n_branches)``. node_ids : list of str Ordered node IDs matching the columns of :attr:`node_voltages_V`. branch_ids : list of str Ordered branch IDs matching the columns of :attr:`branch_currents_A`. """ node_voltages_V: np.ndarray branch_currents_A: np.ndarray node_ids: list[str] branch_ids: list[str]
[docs] class Solver(abc.ABC): """Abstract base class for circuit solvers. Subclasses: * ``LPMSolver`` — Lehtinen-Pirjola matrix (resistive, single-phase). * ``MNASolver`` — Modified Nodal Analysis (reactive, multi-phase). * ``PySpiceSolver`` — nonlinear transient via SPICE backend. """
[docs] @abc.abstractmethod def solve( self, network: "ConductorNetwork", network_admittance: np.ndarray, earthing_impedance: np.ndarray, thevenin_voltages: np.ndarray, ) -> SolverResult: """Solve the circuit for GIC. Parameters ---------- network : ConductorNetwork The network the matrices were assembled from. Solvers use it to pull metadata that the numeric matrices do not carry — branch endpoints, node/branch IDs for :class:`SolverResult`, and any solver-specific data (transformer types for MNA, netlist for PySpiceSolver, ...). network_admittance : numpy.ndarray ``Y_n`` matrix. Shape ``(n_nodes, n_nodes)``. Units: Siemens. earthing_impedance : numpy.ndarray ``Z_e`` diagonal matrix. Shape ``(n_nodes, n_nodes)``. Units: Ohms. thevenin_voltages : numpy.ndarray ``V_th`` per branch. Shape ``(n_branches,)`` or ``(n_times, n_branches)``. Units: Volts. Returns ------- SolverResult Node voltages and branch currents. """