diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 5733ec8512..ef09baea79 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -36,6 +36,7 @@ jobs: pip install \ -r requirements.txt \ -r requirements/tests.txt + pip install pypardiso - name: Running tests run: diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 9836cacdac..7fa2f7c6c8 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -36,6 +36,7 @@ jobs: run: | pip install -r requirements.txt pip install -r requirements/docs.txt + pip install pypardiso - name: Build the documentation run: | diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c071f0208f..6519f77a14 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -49,6 +49,11 @@ jobs: -r requirements.txt \ -r requirements/tests.txt + - name: Install pypardiso on non-macOS + if: (matrix.os != 'macos-latest') + run: | + pip install pypardiso + - name: Running tests run: pytest . --color=yes diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c454fd257c..e5692c8820 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -46,6 +46,11 @@ jobs: -r requirements.txt \ -r requirements/tests.txt + - name: Install pypardiso on non-macOS + if: (matrix.os != 'macos-latest') + run: | + pip install pypardiso + - name: Disable numba JIT for codecov to include jitted methods if: (matrix.python-version == 3.9) && (matrix.os == 'ubuntu-latest') run: | diff --git a/openpnm/__init__.py b/openpnm/__init__.py index a479b00f96..a27477e9c5 100644 --- a/openpnm/__init__.py +++ b/openpnm/__init__.py @@ -8,25 +8,34 @@ """ -from . import _skgraph -from . import utils -from . import core -from . import models -from . import topotools -from . import network -from . import phase -from . import algorithms -from . import solvers -from . import integrators -from . import io -from . import contrib -from . import visualization - -from .utils import Workspace, Project +import logging + +from rich.logging import RichHandler + +FORMAT = "%(message)s" +logging.basicConfig( + format=FORMAT, datefmt="[%X]", handlers=[RichHandler(rich_tracebacks=True)] +) import numpy as _np + +from . import ( + _skgraph, + algorithms, + contrib, + core, + integrators, + io, + models, + network, + phase, + solvers, + topotools, + utils, + visualization, +) +from .utils import Project, Workspace + _np.seterr(divide='ignore', invalid='ignore') __version__ = utils._get_version() - -utils._setup_logger_rich() diff --git a/openpnm/solvers/_pardiso.py b/openpnm/solvers/_pardiso.py index 67652dba8f..6dd3cbb595 100644 --- a/openpnm/solvers/_pardiso.py +++ b/openpnm/solvers/_pardiso.py @@ -1,6 +1,6 @@ -from pypardiso import spsolve +from scipy.sparse import csc_matrix, csr_matrix + from openpnm.solvers import DirectSolver -from scipy.sparse import csr_matrix, csc_matrix __all__ = ['PardisoSpsolve'] @@ -10,6 +10,8 @@ class PardisoSpsolve(DirectSolver): def solve(self, A, b, **kwargs): """Solves the given linear system of equations Ax=b.""" + from pypardiso import spsolve + if not isinstance(A, (csr_matrix, csc_matrix)): A = A.tocsr() return (spsolve(A, b), 0) diff --git a/openpnm/utils/_workspace.py b/openpnm/utils/_workspace.py index 28f4d783d2..92a41d188a 100644 --- a/openpnm/utils/_workspace.py +++ b/openpnm/utils/_workspace.py @@ -1,6 +1,7 @@ import logging import pickle import re +import sys from datetime import datetime from uuid import uuid4 @@ -39,7 +40,20 @@ class WorkspaceSettings(SettingsAttr): may be unable to continue running. ======= ============================================================== """ - default_solver = 'PardisoSpsolve' + # Pardiso requires MKL, which is not available on new Apple chips + if sys.platform == 'darwin': + default_solver = 'ScipySpsolve' + else: + try: + import pypardiso + default_solver = 'PardisoSpsolve' + except ImportError: + default_solver = 'ScipySpsolve' + msg = ( + 'PARDISO solver not installed, run `pip install pypardiso`. ' + 'Otherwise, simulations will be slow. Apple M chips not supported.' + ) + logger.error(msg) @property def loglevel(self): diff --git a/setup.py b/setup.py index 007b1f219b..3d997519c3 100644 --- a/setup.py +++ b/setup.py @@ -1,9 +1,10 @@ -import os -import sys import codecs +import os import os.path +import sys from distutils.util import convert_path -from setuptools import setup, find_packages + +from setuptools import find_packages, setup sys.path.append(os.getcwd()) ver_path = convert_path('openpnm/__version__.py') @@ -59,7 +60,6 @@ def get_version(rel_path): 'numpy', 'pandas', 'pyamg', - 'pypardiso', 'rich', 'scikit-image', 'scipy', diff --git a/tests/unit/algorithms/SolversTest.py b/tests/unit/algorithms/SolversTest.py index cadcb21ea8..b0568d82ad 100644 --- a/tests/unit/algorithms/SolversTest.py +++ b/tests/unit/algorithms/SolversTest.py @@ -1,5 +1,9 @@ +import sys + import numpy as np import numpy.testing as nt +import pytest + import openpnm as op @@ -25,6 +29,7 @@ def test_scipy_spsolve(self): x = self.alg['pore.x'] nt.assert_allclose(x.mean(), 0.624134, rtol=1e-5) + @pytest.mark.skipif(sys.platform == 'darwin', reason="Pardiso not available on arm64") def test_pardiso_spsolve(self): solver = op.solvers.PardisoSpsolve() self.alg.run(solver=solver) diff --git a/tests/unit/algorithms/TransientMultiPhysicsTest.py b/tests/unit/algorithms/TransientMultiPhysicsTest.py index 59d4ad5f21..d7fd6ddb5d 100644 --- a/tests/unit/algorithms/TransientMultiPhysicsTest.py +++ b/tests/unit/algorithms/TransientMultiPhysicsTest.py @@ -1,5 +1,6 @@ import numpy as np import numpy.testing as nt + import openpnm as op import openpnm.models.geometry.diffusive_size_factors as gd import openpnm.models.physics as pm @@ -48,7 +49,6 @@ def setup_class(self): "cache_A": False, "cache_b": False } - self.pardiso = op.solvers.PardisoSpsolve() self.rk45 = op.integrators.ScipyRK45(verbose=True) # First algorithm, transient fourier conduction