Source code for VeraGridEngine.Utils.NumericalMethods.emt_sparse_solver_registry

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0

from __future__ import annotations

from typing import Dict

from VeraGridEngine.Utils.NumericalMethods.emt_sparse_solver_loader import load_sparse_solver_backend_provider
from VeraGridEngine.Utils.NumericalMethods.emt_sparse_superlu_backend import SuperLUSparseBackendProvider
from VeraGridEngine.Utils.NumericalMethods.external_sparse_solver_interface import SparseLinearSolverBackendProvider
from VeraGridEngine.enumerations import SparseSolver


[docs] def build_internal_sparse_solver_provider_map() -> Dict[SparseSolver, SparseLinearSolverBackendProvider]: """ Build the map of built-in EMT sparse solver providers. :return: Built-in provider map. :rtype: Dict[SparseSolver, SparseLinearSolverBackendProvider] """ provider_map: Dict[SparseSolver, SparseLinearSolverBackendProvider] = dict() provider_map[SparseSolver.SuperLU] = SuperLUSparseBackendProvider() return provider_map
[docs] def resolve_emt_sparse_solver_backend_provider( solver_type: SparseSolver, external_plugin_name: str, external_plugin_directory: str, allow_internal_fallback: bool, ) -> SparseLinearSolverBackendProvider: """ Resolve the EMT sparse solver backend provider. :param solver_type: Requested sparse solver type. :type solver_type: SparseSolver :param external_plugin_name: External plugin name. :type external_plugin_name: str :param external_plugin_directory: External plugin directory override. :type external_plugin_directory: str :param allow_internal_fallback: Whether internal fallback is allowed. :type allow_internal_fallback: bool :return: Resolved backend provider. :rtype: SparseLinearSolverBackendProvider """ internal_provider_map: Dict[SparseSolver, SparseLinearSolverBackendProvider] = build_internal_sparse_solver_provider_map() if len(external_plugin_name) > 0: plugin_provider: SparseLinearSolverBackendProvider try: plugin_provider = load_sparse_solver_backend_provider( plugin_name=external_plugin_name, plugin_directory_override=external_plugin_directory, ) except (FileNotFoundError, RuntimeError, AttributeError, TypeError, ValueError): if allow_internal_fallback: if solver_type in internal_provider_map: return internal_provider_map[solver_type] elif SparseSolver.SuperLU in internal_provider_map: return internal_provider_map[SparseSolver.SuperLU] else: raise RuntimeError( f"External sparse solver plugin '{external_plugin_name}' could not be loaded and no internal fallback is available" ) else: raise if plugin_provider.get_solver_type() == solver_type: if plugin_provider.is_available(): return plugin_provider elif allow_internal_fallback: if solver_type in internal_provider_map: return internal_provider_map[solver_type] elif SparseSolver.SuperLU in internal_provider_map: return internal_provider_map[SparseSolver.SuperLU] else: raise RuntimeError( f"External sparse solver plugin '{external_plugin_name}' is unavailable and no internal fallback exists for {solver_type}" ) else: raise RuntimeError( f"External sparse solver plugin '{external_plugin_name}' is unavailable and fallback is disabled" ) else: raise ValueError( f"External sparse solver plugin '{external_plugin_name}' exposes {plugin_provider.get_solver_type()} instead of requested {solver_type}" ) else: pass if solver_type in internal_provider_map: return internal_provider_map[solver_type] elif allow_internal_fallback and SparseSolver.SuperLU in internal_provider_map: return internal_provider_map[SparseSolver.SuperLU] else: raise RuntimeError(f"No EMT sparse solver backend provider available for {solver_type}")