Skip to content

Commit

Permalink
Enable import fipy without any solver packages.
Browse files Browse the repository at this point in the history
Collect exceptions thrown by ``ImportError``s in
source:fipy/solver/__init__.py and throw a warning and the exceptions
as warnings in the case when no solvers are available.

 * Moved a number of solver imports inside the calling methods in term
   classes.
  • Loading branch information
wd15 committed Aug 30, 2012
1 parent 9784a7a commit 4b87817
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down Expand Up @@ -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)
Expand All @@ -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)

Expand Down
3 changes: 2 additions & 1 deletion fipy/models/levelSet/surfactant/surfactantEquation.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
43 changes: 30 additions & 13 deletions fipy/solvers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -35,15 +39,15 @@ 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
_MeshMatrix = _ScipyMeshMatrix

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
Expand All @@ -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__)
Expand 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

3 changes: 2 additions & 1 deletion fipy/terms/asymmetricConvectionTerm.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
__all__ = []

from fipy.terms.abstractConvectionTerm import _AbstractConvectionTerm
from fipy.solvers import DefaultAsymmetricSolver


class _AsymmetricConvectionTerm(_AbstractConvectionTerm):

Expand All @@ -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():
Expand Down
1 change: 0 additions & 1 deletion fipy/terms/centralDiffConvectionTerm.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

from fipy.terms.abstractConvectionTerm import _AbstractConvectionTerm
from fipy.variables.faceVariable import FaceVariable
from fipy.solvers import DefaultAsymmetricSolver

__all__ = ["CentralDifferenceConvectionTerm"]

Expand Down
2 changes: 1 addition & 1 deletion fipy/terms/term.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion fipy/terms/upwindConvectionTerm.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@

from fipy.terms.abstractUpwindConvectionTerm import _AbstractUpwindConvectionTerm
from fipy.variables.faceVariable import FaceVariable
from fipy.solvers import DefaultAsymmetricSolver

__all__ = ["UpwindConvectionTerm"]

Expand All @@ -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):
Expand Down

0 comments on commit 4b87817

Please sign in to comment.