Source code for dolfinx.la.superlu_dist

# Copyright (C) 2026 Jack S. Hale, Chris N. Richardson
#
# This file is part of DOLFINx (https://www.fenicsproject.org)
#
# SPDX-License-Identifier:    LGPL-3.0-or-later
"""SuperLU_DIST linear solver support.

This module provides support for parallel solution of linear systems
assembled into :class:`dolfinx.la.MatrixCSR` using SuperLU_DIST.

Note:
  Users with advanced linear solver requirements should use PETSc/petsc4py.
"""

from typing import Generic, TypeVar

import numpy as np
import numpy.typing as npt

import dolfinx
import dolfinx.cpp as _cpp

if not dolfinx.has_superlu_dist:
    raise RuntimeError("DOLFINx was not built with SuperLU_DIST support.")

__all__ = ["SuperLUDistMatrix", "SuperLUDistSolver", "superlu_dist_matrix", "superlu_dist_solver"]

# As of 2026, SuperLU_DIST only supports these types, so the general Scalar
# type including np.complex64 cannot be used.
_T = TypeVar("_T", np.float32, np.float64, np.complex128)


[docs] class SuperLUDistMatrix(Generic[_T]): """SuperLU_DIST matrix.""" _cpp_object: ( _cpp.la.SuperLUDistMatrix_float32 | _cpp.la.SuperLUDistMatrix_float64 | _cpp.la.SuperLUDistMatrix_complex128 ) def __init__(self, matrix): """Create a SuperLU_DIST matrix. Args: matrix: C++ SuperLUDistMatrix object. Note: This initialiser is intended for internal library use only. User code should call :func:`superlu_dist_matrix` to create a :class:`SuperLUDistMatrix` object. """ self._cpp_object = matrix @property def dtype(self) -> npt.DTypeLike: """Dtype of matrix values.""" return self._cpp_object.dtype
[docs] def superlu_dist_matrix(A: dolfinx.la.MatrixCSR[_T]) -> SuperLUDistMatrix[_T]: """Create a SuperLU_DIST matrix. Deep copies all required data from ``A``. Args: A: Assembled matrix. Returns: A SuperLU_DIST matrix. """ dtype = A.data.dtype if np.issubdtype(dtype, np.float32): stype = _cpp.la.SuperLUDistMatrix_float32 elif np.issubdtype(dtype, np.float64): stype = _cpp.la.SuperLUDistMatrix_float64 elif np.issubdtype(dtype, np.complex128): stype = _cpp.la.SuperLUDistMatrix_complex128 else: raise NotImplementedError(f"Type {dtype} not supported.") return SuperLUDistMatrix(stype(A._cpp_object))
[docs] class SuperLUDistSolver(Generic[_T]): """SuperLU_DIST solver.""" _cpp_object: ( _cpp.la.SuperLUDistSolver_float32 | _cpp.la.SuperLUDistSolver_float64 | _cpp.la.SuperLUDistSolver_complex128 ) def __init__(self, solver): """Create a SuperLU_DIST solver. Args: solver: C++ SuperLUDistSolver object. Note: This initialiser is intended for internal library use only. User code should call :func:`superlu_dist_solver` to create a :class:`SuperLUDistSolver` object. """ self._cpp_object = solver
[docs] def set_option(self, name: str, value: str): """Set SuperLU_DIST option for solve. See SuperLU_DIST User's Guide for option names and values. Example:: solver.set_option("SymmetricMode", "YES") solver.set_option("Trans", "NOTRANS") Args: name: Option name. value: Option value. """ self._cpp_object.set_option(name, value)
[docs] def set_A(self, A: SuperLUDistMatrix[_T]): """Set assembled left-hand side matrix. For advanced use with SuperLU_DIST option `Factor` allowing use of previously computed permutations when solving with new matrix A. Args: A: Assembled left-hand side matrix :math:`A`. """ self._cpp_object.set_A(A._cpp_object)
[docs] def solve(self, b: dolfinx.la.Vector[_T], u: dolfinx.la.Vector[_T]) -> int: """Solve linear system :math:`Au = b`. Note: Vectors must have size and parallel layout compatible with ``A``. Note: The caller must check the return integer for success ``(== 0)``. Note: The caller must ``u.scatter_forward()`` after the solve. Note: The values of ``A`` are modified in-place during the solve. Note: To solve with successive right-hand sides `b` the caller must ``solver.set_option("Factor", "FACTORED")`` after the first solve. Args: b: Right-hand side vector :math:`b`. u: Solution vector :math:`u`, overwritten during solve. Returns: SuperLU_DIST return integer from ``p*gssvx`` routine. """ return self._cpp_object.solve(b._cpp_object, u._cpp_object)
[docs] def superlu_dist_solver(A: SuperLUDistMatrix[_T]) -> SuperLUDistSolver[_T]: """Create a SuperLU_DIST linear solver. Solve linear system :math:`Au = b` via LU decomposition. The SuperLU_DIST solver has options set to upstream defaults, except PrintStat (verbose solver output) set to NO. Args: A: Assembled left-hand side matrix :math:`A`. Returns: A SuperLU_DIST solver. """ dtype = A.dtype if np.issubdtype(dtype, np.float32): stype = _cpp.la.SuperLUDistSolver_float32 elif np.issubdtype(dtype, np.float64): stype = _cpp.la.SuperLUDistSolver_float64 elif np.issubdtype(dtype, np.complex128): stype = _cpp.la.SuperLUDistSolver_complex128 else: raise NotImplementedError(f"Type {dtype} not supported.") return SuperLUDistSolver(stype(A._cpp_object))