Naming conventions: “solver” vs “algorithm”

This page explains how the terms solver and algorithm are used in LightSim2Grid, and how to read and build the names of the AlgorithmType enum values and the corresponding Python classes.

Three distinct meanings of “solver”

The word solver appears in three different contexts in LightSim2Grid, and they should not be confused:

  1. The linear solver — a numerical library that solves a sparse linear system \(Ax = b\) eg at each Newton-Raphson iteration. Examples: SparseLULinearSolver (Eigen built-in), KLU (SuiteSparse), NICSLU, CKTSO. These names end in LinearSolver in C++.

  2. The powerflow algorithm — the outer numerical method used to solve the power-flow equations. Examples: Newton-Raphson (NR), DC approximation, Fast-Decoupled Power Flow (FDPF), Gauss-Seidel. Each algorithm can use one linear solver internally (where applicable). This is what AlgorithmType enumerates, and what AlgorithmSelector dispatches.

  3. Solver bus numbering — the compact internal bus index used by the sparse matrices, which only includes connected buses (not disconnected ones). Methods like get_Ybus_solver(), get_pv_solver(), id_me_to_ac_solver() etc. use “solver” in this third sense. These are low-level diagnostic accessors; the naming is intentionally kept for clarity.

How AlgorithmType enum names are built

Each enum value encodes both the outer powerflow algorithm and the linear solver library used for its internal linear algebra. The naming pattern is:

{Algorithm}_{LinearSolver}

Where the algorithm prefix is:

Prefix

Meaning

NR_

Newton-Raphson with distributed (multi-) slack

NRSing_

Newton-Raphson with single slack (slightly faster when only one slack bus exists)

DC_

DC approximation (linearised power flow)

FDPF_XB_

Fast-Decoupled Power Flow, XB variant (fdxb in pypower / pandapower)

FDPF_BX_

Fast-Decoupled Power Flow, BX variant (fdbx in pypower / pandapower)

And the linear-solver suffix is:

Suffix

Library

_SparseLU

Eigen’s built-in sparse LU — always available, no extra dependency

_KLU

SuiteSparse KLU — available when lightsim2grid is compiled with KLU support

_NICSLU

NICSLU — requires a license and a source build

_CKTSO

CKTSO — requires a license and a source build

Special cases (no linear solver choice):

Complete table

AlgorithmType value

Python class

Description

NR_SparseLU

NR_SparseLU

NR multi-slack + SparseLU (default when KLU unavailable)

NRSing_SparseLU

NRSing_SparseLU

NR single-slack + SparseLU

DC_SparseLU

DC_SparseLU

DC + SparseLU

FDPF_XB_SparseLU

FDPF_XB_SparseLU

Fast-Decoupled XB + SparseLU

FDPF_BX_SparseLU

FDPF_BX_SparseLU

Fast-Decoupled BX + SparseLU

NR_KLU

NR_KLU

NR multi-slack + KLU (default when KLU available)

NRSing_KLU

NRSing_KLU

NR single-slack + KLU

DC_KLU

DC_KLU

DC + KLU

FDPF_XB_KLU

FDPF_XB_KLU

Fast-Decoupled XB + KLU

FDPF_BX_KLU

FDPF_BX_KLU

Fast-Decoupled BX + KLU

NR_NICSLU

NR_NICSLU

NR multi-slack + NICSLU (requires license)

NRSing_NICSLU

NRSing_NICSLU

NR single-slack + NICSLU (requires license)

DC_NICSLU

DC_NICSLU

DC + NICSLU (requires license)

FDPF_XB_NICSLU

FDPF_XB_NICSLU

Fast-Decoupled XB + NICSLU

FDPF_BX_NICSLU

FDPF_BX_NICSLU

Fast-Decoupled BX + NICSLU

NR_CKTSO

NR_CKTSO

NR multi-slack + CKTSO (requires license)

NRSing_CKTSO

NRSing_CKTSO

NR single-slack + CKTSO (requires license)

DC_CKTSO

DC_CKTSO

DC + CKTSO (requires license)

FDPF_XB_CKTSO

FDPF_XB_CKTSO

Fast-Decoupled XB + CKTSO

FDPF_BX_CKTSO

FDPF_BX_CKTSO

Fast-Decoupled BX + CKTSO

GaussSeidel

GaussSeidelAlgo

Gauss-Seidel iterative (no sparse factorisation)

GaussSeidelSynch

GaussSeidelSynchAlgo

Synchronous Gauss-Seidel iterative

Custom

–

Sentinel value reported by get_algo_types() / get_algo_type() for any solver loaded through the plugin mechanism (see External Algorithm Plugins). It is also, incidentally, what the three built-in NRRefactorRetry_* solvers below report, since they were never given their own enum value either.

String-only built-in solvers: NRRefactorRetry_*

NRRefactorRetry_KLU, NRRefactorRetry_NICSLU and NRRefactorRetry_CKTSO are built-in solvers that never got their own AlgorithmType enum value, so unlike everything in the table above they can only be selected by their string name, not by an AlgorithmType.NRRefactorRetry_* attribute (which does not exist). Since lightsim2grid 1.0, set_algo_type() accepts such a string directly, and – unlike changing the algorithm through the private env.backend._grid.change_algorithm(...) – remembers the choice so it is re-applied after every env.reset() and preserved by backend.copy():

env.backend.set_algo_type("NRRefactorRetry_KLU")

Each is the same algorithm as its NR_* counterpart (Newton-Raphson, distributed slack), except that when a Jacobian refactorize() fails it falls back to a full factorize() (reusing the existing symbolic factorization) before giving up, instead of reporting an error immediately. Use get_linear_solver_stats() on the solver to see how often the fallback fires. Because they have no dedicated enum value, get_algo_type() reports AlgorithmType.Custom while one of them is active – the same value reported for an actual plugin solver.

Warning

env.backend._grid.change_algorithm(...) acts directly on the underlying C++ grid model and does not survive env.reset() / backend.copy(): use the persistent set_algo_type() shown above instead (it works the same for a plain AlgorithmType or a string-only / plugin name).

Usage example

import grid2op
import lightsim2grid
from lightsim2grid.algorithm import AlgorithmType

env = grid2op.make("l2rpn_case14_sandbox", backend=lightsim2grid.LightSimBackend())

# switch to NR with KLU (if available)
env.backend.set_algo_type(AlgorithmType.NR_KLU)

# inspect what algorithm is currently active
print(env.backend.get_algo_types())
# >>> (<AlgorithmType.NR_KLU: 1>, <AlgorithmType.DC_KLU: 9>)

# list all algorithms available in this build
env.backend._grid.available_algorithm_names()

Note

The method is called change_algorithm(type) in the C++ LSGrid Python binding (env.backend._grid.change_algorithm(AlgorithmType.NR_KLU)), consistent with pandapower’s algorithm= parameter and MATPOWER’s pf.alg option.

Migration from old names

Before version 1.0.0, the enum values and class names used shorter names that did not make the algorithm component explicit (KLU, SparseLU, DC, etc.). These old names are kept as deprecated aliases in the Python enum so that existing code continues to work, but they will be removed in a future release:

Old name (deprecated)

New canonical name

AlgorithmType.SparseLU

AlgorithmType.NR_SparseLU

AlgorithmType.SparseLUSingleSlack

AlgorithmType.NRSing_SparseLU

AlgorithmType.DC

AlgorithmType.DC_SparseLU

AlgorithmType.KLU

AlgorithmType.NR_KLU

AlgorithmType.KLUSingleSlack

AlgorithmType.NRSing_KLU

AlgorithmType.KLUDC

AlgorithmType.DC_KLU

AlgorithmType.NICSLU

AlgorithmType.NR_NICSLU

AlgorithmType.NICSLUSingleSlack

AlgorithmType.NRSing_NICSLU

AlgorithmType.NICSLUDC

AlgorithmType.DC_NICSLU

AlgorithmType.CKTSO

AlgorithmType.NR_CKTSO

AlgorithmType.CKTSOSingleSlack

AlgorithmType.NRSing_CKTSO

AlgorithmType.CKTSODC

AlgorithmType.DC_CKTSO

The same renaming affects two other places that predate this convention:

  • the lightsim2grid.solver module (with its own, older SolverType enum, e.g. SolverType.KLU) is deprecated in favour of lightsim2grid.algorithm / AlgorithmType. A SolverType value is still accepted wherever an AlgorithmType is expected (it is converted automatically, with a DeprecationWarning);

  • LightSimBackend’s solver_type constructor keyword (and its set_solver_type method) are deprecated in favour of algo_type / set_algo_type, for the same reason: solver_type reads as if it selected the linear solver, when it in fact selects the powerflow algorithm (combined with a linear solver). solver_type is still accepted and mapped to algo_type; passing both with different values raises a BackendError.

See also

Available powerflow algorithms for performance comparisons and practical guidance on choosing an algorithm.