diff --git a/fipy/models/levelSet/surfactant/adsorbingSurfactantEquation.py b/fipy/models/levelSet/surfactant/adsorbingSurfactantEquation.py index 268b090c22..e8629c399e 100755 --- a/fipy/models/levelSet/surfactant/adsorbingSurfactantEquation.py +++ b/fipy/models/levelSet/surfactant/adsorbingSurfactantEquation.py @@ -39,7 +39,6 @@ from fipy.variables.cellVariable import CellVariable from fipy.models.levelSet.surfactant.surfactantEquation import SurfactantEquation from fipy.terms.implicitSourceTerm import ImplicitSourceTerm -from fipy.solvers import DefaultAsymmetricSolver, LinearPCGSolver __all__ = ["AdsorbingSurfactantEquation"] @@ -368,6 +367,7 @@ def solve(self, var, boundaryConditions=(), solver=None, dt=None): from fipy.solvers.pyAMG.linearGeneralSolver import LinearGeneralSolver solver = LinearGeneralSolver(tolerance=1e-15, iterations=2000) else: + from fipy.solvers import LinearPCGSolver solver = LinearPCGSolver() SurfactantEquation.solve(self, var, boundaryConditions=boundaryConditions, solver=solver, dt=dt) @@ -390,6 +390,7 @@ def sweep(self, var, solver=None, boundaryConditions=(), dt=None, underRelaxatio for coeff in self.coeffs: coeff._updateDt(dt) if solver is None: + from fipy.solvers import DefaultAsymmetricSolver solver = DefaultAsymmetricSolver() return SurfactantEquation.sweep(self, var, solver=solver, boundaryConditions=boundaryConditions, dt=dt, underRelaxation=underRelaxation, residualFn=residualFn) diff --git a/fipy/models/levelSet/surfactant/surfactantEquation.py b/fipy/models/levelSet/surfactant/surfactantEquation.py index 8d6af1cb52..22a5082757 100644 --- a/fipy/models/levelSet/surfactant/surfactantEquation.py +++ b/fipy/models/levelSet/surfactant/surfactantEquation.py @@ -37,7 +37,6 @@ from fipy.terms.transientTerm import TransientTerm from fipy.terms.explicitUpwindConvectionTerm import ExplicitUpwindConvectionTerm -from fipy.solvers import DefaultAsymmetricSolver from fipy.models.levelSet.surfactant.convectionCoeff import _ConvectionCoeff @@ -83,6 +82,7 @@ def solve(self, var, boundaryConditions = (), solver=None, dt=None): if type(boundaryConditions) not in (type(()), type([])): boundaryConditions = (boundaryConditions,) if solver is None: + from fipy.solvers import DefaultAsymmetricSolver solver=DefaultAsymmetricSolver() var.constrain(0, var.mesh.exteriorFaces) @@ -111,6 +111,7 @@ def sweep(self, var, solver=None, boundaryConditions=(), dt=None, underRelaxatio if type(boundaryConditions) not in (type(()), type([])): boundaryConditions = (boundaryConditions,) if solver is None: + from fipy.solvers import DefaultAsymmetricSolver solver=DefaultAsymmetricSolver() var.constrain(0, var.mesh.exteriorFaces) diff --git a/fipy/solvers/__init__.py b/fipy/solvers/__init__.py index d526669b88..7902da867f 100644 --- a/fipy/solvers/__init__.py +++ b/fipy/solvers/__init__.py @@ -14,9 +14,13 @@ def _envSolver(solver): solver = _envSolver(solver) +class SerialSolverError(Exception): + def __init__(self, solver): + super(SerialSolverError, self).__init__(solver + ' does not run in parallel') + if solver == "pysparse": if _parallel.Nproc > 1: - raise Exception('pysparse solvers do not run in parallel') + raise SerialSolverError('pysparse') from fipy.solvers.pysparse import * __all__.extend(pysparse.__all__) from fipy.matrices.pysparseMatrix import _PysparseMeshMatrix @@ -35,7 +39,7 @@ def _envSolver(solver): elif solver == "scipy": if _parallel.Nproc > 1: - raise Exception('scipy solvers do not run in parallel') + raise SerialSolverError('scipy') from fipy.solvers.scipy import * __all__.extend(scipy.__all__) from fipy.matrices.scipyMatrix import _ScipyMeshMatrix @@ -43,7 +47,7 @@ def _envSolver(solver): elif solver == "pyamg": if _parallel.Nproc > 1: - raise Exception('pyamg solvers do not run in parallel') + raise SerialSolverError('pyamg') from fipy.solvers.pyAMG import * __all__.extend(pyAMG.__all__) from fipy.matrices.scipyMatrix import _ScipyMeshMatrix @@ -58,18 +62,21 @@ def _envSolver(solver): elif solver is None: # If no argument or environment variable, try importing them and seeing # what works - - + exceptions = [] + try: if _parallel.Nproc > 1: - raise Exception('pysparse solvers do not run in parallel') + raise SerialSolverError('pysparse solvers do not run in parallel') from fipy.solvers.pysparse import * __all__.extend(pysparse.__all__) solver = "pysparse" from fipy.matrices.pysparseMatrix import _PysparseMeshMatrix _MeshMatrix = _PysparseMeshMatrix - except: + + except (ImportError, SerialSolverError) as inst: + exceptions.append(inst) + try: from fipy.solvers.trilinos import * __all__.extend(trilinos.__all__) @@ -81,26 +88,36 @@ def _envSolver(solver): solver = "no-pysparse" from fipy.matrices.trilinosMatrix import _TrilinosMeshMatrix _MeshMatrix = _TrilinosMeshMatrix - except: + except ImportError as inst: + exceptions.append(inst) + try: if _parallel.Nproc > 1: - raise Exception('pyamg solvers do not run in parallel') + raise SerialSolverError('pyamg') from fipy.solvers.pyAMG import * __all__.extend(pyAMG.__all__) solver = "pyamg" from fipy.matrices.scipyMatrix import _ScipyMeshMatrix _MeshMatrix = _ScipyMeshMatrix - except: + except (ImportError, SerialSolverError) as inst: + exceptions.append(inst) + try: if _parallel.Nproc > 1: - raise Exception('scipy solvers do not run in parallel') + raise SerialSolverError('scipy') from fipy.solvers.scipy import * __all__.extend(scipy.__all__) solver = "scipy" from fipy.matrices.scipyMatrix import _ScipyMeshMatrix _MeshMatrix = _ScipyMeshMatrix - except: - raise ImportError, "Could not import any solver package. If you are using Trilinos, make sure you have all of the necessary Trilinos packages installed - Epetra, EpetraExt, AztecOO, Amesos, ML, and IFPACK." + except (ImportError, SerialSolverError) as inst: + exceptions.append(inst) + import warnings + warnings.warn("Could not import any solver package. If you are using Trilinos, make sure you have all of the necessary Trilinos packages installed - Epetra, EpetraExt, AztecOO, Amesos, ML, and IFPACK.") + for inst in exceptions: + warnings.warn(inst.__class__.__name__ + ': ' + inst.message) + + else: raise ImportError, 'Unknown solver package %s' % solver diff --git a/fipy/terms/asymmetricConvectionTerm.py b/fipy/terms/asymmetricConvectionTerm.py index 35908bdc2d..a489b0d085 100644 --- a/fipy/terms/asymmetricConvectionTerm.py +++ b/fipy/terms/asymmetricConvectionTerm.py @@ -37,7 +37,7 @@ __all__ = [] from fipy.terms.abstractConvectionTerm import _AbstractConvectionTerm -from fipy.solvers import DefaultAsymmetricSolver + class _AsymmetricConvectionTerm(_AbstractConvectionTerm): @@ -51,6 +51,7 @@ def _getDefaultSolver(self, var, solver, *args, **kwargs): if solver and not solver._canSolveAsymmetric(): import warnings warnings.warn("%s cannot solve assymetric matrices" % solver) + from fipy.solvers import DefaultAsymmetricSolver return solver or DefaultAsymmetricSolver(*args, **kwargs) def _test(): diff --git a/fipy/terms/centralDiffConvectionTerm.py b/fipy/terms/centralDiffConvectionTerm.py index e8be8ac011..63fbf7f1d2 100644 --- a/fipy/terms/centralDiffConvectionTerm.py +++ b/fipy/terms/centralDiffConvectionTerm.py @@ -38,7 +38,6 @@ from fipy.terms.abstractConvectionTerm import _AbstractConvectionTerm from fipy.variables.faceVariable import FaceVariable -from fipy.solvers import DefaultAsymmetricSolver __all__ = ["CentralDifferenceConvectionTerm"] diff --git a/fipy/terms/term.py b/fipy/terms/term.py index 5858290d6c..a565067b92 100644 --- a/fipy/terms/term.py +++ b/fipy/terms/term.py @@ -37,7 +37,6 @@ import os from fipy.tools import numerix -from fipy.solvers import DefaultSolver, DummySolver from fipy.terms import AbstractBaseClassError from fipy.terms import SolutionVariableRequiredError from fipy.tools.decorators import getsetDeprecated @@ -397,6 +396,7 @@ def _getDefaultSolver(self, var, solver, *args, **kwargs): return NotImplementedError def getDefaultSolver(self, var=None, solver=None, *args, **kwargs): + from fipy.solvers import DefaultSolver return solver or self._getDefaultSolver(var, solver, *args, **kwargs) or DefaultSolver(*args, **kwargs) def __add__(self, other): diff --git a/fipy/terms/upwindConvectionTerm.py b/fipy/terms/upwindConvectionTerm.py index 0797dfcab3..01e8b6000a 100644 --- a/fipy/terms/upwindConvectionTerm.py +++ b/fipy/terms/upwindConvectionTerm.py @@ -37,7 +37,6 @@ from fipy.terms.abstractUpwindConvectionTerm import _AbstractUpwindConvectionTerm from fipy.variables.faceVariable import FaceVariable -from fipy.solvers import DefaultAsymmetricSolver __all__ = ["UpwindConvectionTerm"] @@ -60,6 +59,7 @@ def _getDefaultSolver(self, var, solver, *args, **kwargs): if solver and not solver._canSolveAsymmetric(): import warnings warnings.warn("%s cannot solve assymetric matrices" % solver) + from fipy.solvers import DefaultAsymmetricSolver return solver or DefaultAsymmetricSolver(*args, **kwargs) def _testPecletSign(self):