示例#1
0
def expand_linear_solver_parameters(linear_solver_parameters, default_linear_solver_parameters = {}):
    """
    Return an expanded dictionary of linear solver parameters with all defaults
    explicitly specified. The optional default_linear_solver_parameters argument
    can be used to override global defaults.
    """

    if not isinstance(linear_solver_parameters, dict):
        raise InvalidArgumentException("linear_solver_parameters must be a dictionary")
    if not isinstance(default_linear_solver_parameters, dict):
        raise InvalidArgumentException("default_linear_solver_parameters must be a dictionary")

    linear_solver_parameters = apply_default_parameters(linear_solver_parameters, default_linear_solver_parameters)
    linear_solver_parameters = apply_default_parameters(linear_solver_parameters,
      {"linear_solver":"default",
       "preconditioner":"default",
       "lu_solver":dolfin.parameters["lu_solver"].to_dict(),
       "krylov_solver":dolfin.parameters["krylov_solver"].to_dict()
      })

    if linear_solver_parameters["linear_solver"] in ["default", "lu"] or dolfin.has_lu_solver_method(linear_solver_parameters["linear_solver"]):
        del(linear_solver_parameters["preconditioner"])
        del(linear_solver_parameters["krylov_solver"])
    else:
        del(linear_solver_parameters["lu_solver"])

    return linear_solver_parameters
示例#2
0
def expand_linear_solver_parameters(linear_solver_parameters, default_linear_solver_parameters = {}):
    """
    Return an expanded dictionary of linear solver parameters with all defaults
    explicitly specified. The optional default_linear_solver_parameters argument
    can be used to override global defaults.
    """

    if not isinstance(linear_solver_parameters, dict):
        raise InvalidArgumentException("linear_solver_parameters must be a dictionary")
    if not isinstance(default_linear_solver_parameters, dict):
        raise InvalidArgumentException("default_linear_solver_parameters must be a dictionary")

    linear_solver_parameters = apply_default_parameters(linear_solver_parameters, default_linear_solver_parameters)
    linear_solver_parameters = apply_default_parameters(linear_solver_parameters,
      {"linear_solver":"default",
       "preconditioner":"default",
       "lu_solver":dolfin.parameters["lu_solver"].to_dict(),
       "krylov_solver":dolfin.parameters["krylov_solver"].to_dict()
      })

    if linear_solver_parameters["linear_solver"] in ["default", "lu"] or dolfin.has_lu_solver_method(linear_solver_parameters["linear_solver"]):
        del(linear_solver_parameters["preconditioner"])
        del(linear_solver_parameters["krylov_solver"])
    else:
        del(linear_solver_parameters["lu_solver"])

    return linear_solver_parameters
def LinearSolver(*args, **kwargs):
    """
    Return a linear solver.

    Arguments: One of:
      1. Arguments as accepted by the DOLFIN LinearSolver constructor.
    or:
      2. A dictionary of linear solver parameters.
    """

    if not len(args) == 1 or not len(kwargs) == 0 or not isinstance(
            args[0], dict):
        return _LinearSolver(*args, **kwargs)
    linear_solver_parameters = args[0]

    linear_solver = "lu"
    pc = None
    kp = {}
    lp = {}
    for key in linear_solver_parameters:
        if key == "linear_solver":
            linear_solver = linear_solver_parameters[key]
        elif key == "preconditioner":
            pc = linear_solver_parameters[key]
        elif key == "krylov_solver":
            kp = linear_solver_parameters[key]
        elif key == "lu_solver":
            lp = linear_solver_parameters[key]
        elif key in [
                "print_matrix", "print_rhs", "reset_jacobian", "symmetric"
        ]:
            raise NotImplementedException(
                "Unsupported linear solver parameter: %s" % key)
        else:
            raise InvalidArgumentException(
                "Unexpected linear solver parameter: %s" % key)

    if linear_solver in ["default", "direct", "lu"]:
        is_lu = True
        linear_solver = "default"
    elif linear_solver == "iterative":
        is_lu = False
        linear_solver = "gmres"
    else:
        is_lu = dolfin.has_lu_solver_method(linear_solver)

    if is_lu:
        linear_solver = _LUSolver(linear_solver)
        linear_solver.parameters.update(lp)
    else:
        if pc is None:
            linear_solver = _KrylovSolver(linear_solver)
        else:
            linear_solver = _KrylovSolver(linear_solver, pc)
        linear_solver.parameters.update(kp)

    return linear_solver
示例#4
0
        def expanded_linear_solver_parameters(form, linear_solver_parameters,
                                              static, bcs, symmetric_bcs):
            if static:
                default = {
                    "lu_solver": {
                        "reuse_factorization": True,
                        "same_nonzero_pattern": True
                    },
                    "krylov_solver": {
                        "preconditioner": {
                            "structure": "same"
                        }
                    }
                }
                if (len(bcs) == 0
                        or symmetric_bcs) and is_self_adjoint_form(form):
                    default["lu_solver"]["symmetric"] = True
                linear_solver_parameters = expand_linear_solver_parameters(
                    linear_solver_parameters,
                    default_linear_solver_parameters=default)
            else:
                default = {
                    "lu_solver": {
                        "reuse_factorization": False,
                        "same_nonzero_pattern": False
                    },
                    "krylov_solver": {
                        "preconditioner": {
                            "structure": "different_nonzero_pattern"
                        }
                    }
                }
                if (len(bcs) == 0
                        or symmetric_bcs) and is_self_adjoint_form(form):
                    default["lu_solver"]["symmetric"] = True
                linear_solver_parameters = expand_linear_solver_parameters(
                    linear_solver_parameters,
                    default_linear_solver_parameters=default)

                static_parameters = False
                if linear_solver_parameters["linear_solver"] in [
                        "direct", "lu"
                ] or dolfin.has_lu_solver_method(
                        linear_solver_parameters["linear_solver"]):
                    static_parameters = linear_solver_parameters["lu_solver"]["reuse_factorization"] or \
                                        linear_solver_parameters["lu_solver"]["same_nonzero_pattern"]
                else:
                    static_parameters = not linear_solver_parameters[
                        "krylov_solver"]["preconditioner"][
                            "structure"] == "different_nonzero_pattern"
                if static_parameters:
                    raise ParameterException(
                        "Non-static solve supplied with static linear solver parameters"
                    )

            return linear_solver_parameters
示例#5
0
    def _set_solver(self,operator,op_name=None):
        """
        Set the solver of an operator
        """
        if type(operator) is df.PETScMatrix:
            if df.__version__<='1.6.0':
                solver = df.PETScLUSolver('mumps' if df.has_lu_solver_method('mumps') else 'default')
                solver.set_operator(operator)
                solver.parameters['reuse_factorization']=True
            else:
                solver = df.PETScLUSolver(self.mpi_comm,operator,'mumps' if df.has_lu_solver_method('mumps') else 'default')
#             solver.set_operator(operator)
#             solver.parameters['reuse_factorization']=True
            if op_name == 'K':
                solver.parameters['symmetric']=True
        else:
            import scipy.sparse.linalg as spsla
            solver = spsla.splu(operator.tocsc(copy=True))
        return solver
def LinearSolver(*args, **kwargs):
    """
    Return a linear solver.

    Arguments: One of:
      1. Arguments as accepted by the DOLFIN LinearSolver constructor.
    or:
      2. A dictionary of linear solver parameters.
    """

    if not len(args) == 1 or not len(kwargs) == 0 or not isinstance(args[0], dict):
        return _LinearSolver(*args, **kwargs)
    linear_solver_parameters = args[0]

    linear_solver = "lu"
    pc = None
    kp = {}
    lp = {}
    for key in linear_solver_parameters:
        if key == "linear_solver":
            linear_solver = linear_solver_parameters[key]
        elif key == "preconditioner":
            pc = linear_solver_parameters[key]
        elif key == "krylov_solver":
            kp = linear_solver_parameters[key]
        elif key == "lu_solver":
            lp = linear_solver_parameters[key]
        elif key in ["print_matrix", "print_rhs", "reset_jacobian", "symmetric"]:
            raise NotImplementedException("Unsupported linear solver parameter: %s" % key)
        else:
            raise InvalidArgumentException("Unexpected linear solver parameter: %s" % key)

    if linear_solver in ["default", "direct", "lu"]:
        is_lu = True
        linear_solver = "default"
    elif linear_solver == "iterative":
        is_lu = False
        linear_solver = "gmres"
    else:
        is_lu = dolfin.has_lu_solver_method(linear_solver)

    if is_lu:
        linear_solver = _LUSolver(linear_solver)
        linear_solver.parameters.update(lp)
    else:
        if pc is None:
            linear_solver = _KrylovSolver(linear_solver)
        else:
            linear_solver = _KrylovSolver(linear_solver, pc)
        linear_solver.parameters.update(kp)

    return linear_solver
示例#7
0
def get_default_factor_solver_package(comm):
    """Return first available factor solver package name.
    This is implemened using DOLFIN now."""

    methods_parallel = ("mumps", "superlu_dist", "pastix")
    methods_sequential = ("mumps", "umfpack", "superlu",
                          "superlu_dist", "pastix")

    if MPI.size(comm) > 1:
        methods = methods_parallel
    else:
        methods = methods_sequential

    for method in methods:
        if has_lu_solver_method(method):
            return method

    raise RuntimeError("Did not find any suitable direct sparse solver in PETSc")
示例#8
0
 def expanded_linear_solver_parameters(form, linear_solver_parameters, static, bcs, symmetric_bcs):
   if static:
     if dolfin_version() < (1, 3, 0):
       default = {"lu_solver":{"reuse_factorization":True, "same_nonzero_pattern":True},
                 "krylov_solver":{"preconditioner":{"reuse":True}}}
     else:
       default = {"lu_solver":{"reuse_factorization":True, "same_nonzero_pattern":True},
                 "krylov_solver":{"preconditioner":{"structure":"same"}}}
     if (len(bcs) == 0 or symmetric_bcs) and is_self_adjoint_form(form):
       if dolfin_version() < (1, 3, 0):
         default["lu_solver"]["symmetric_operator"] = True
       else:
         default["lu_solver"]["symmetric"] = True
     linear_solver_parameters = expand_linear_solver_parameters(linear_solver_parameters,
       default_linear_solver_parameters = default)
   else:
     if dolfin_version() < (1, 3, 0):
       default = {"lu_solver":{"reuse_factorization":False, "same_nonzero_pattern":False},
                 "krylov_solver":{"preconditioner":{"reuse":False}}}
     else:
       default = {"lu_solver":{"reuse_factorization":False, "same_nonzero_pattern":False},
                 "krylov_solver":{"preconditioner":{"structure":"different_nonzero_pattern"}}}
     if (len(bcs) == 0 or symmetric_bcs) and is_self_adjoint_form(form):
       if dolfin_version() < (1, 3, 0):
         default["lu_solver"]["symmetric_operator"] = True
       else:
         default["lu_solver"]["symmetric"] = True
     linear_solver_parameters = expand_linear_solver_parameters(linear_solver_parameters,
       default_linear_solver_parameters = default)
     
     static_parameters = False
     if linear_solver_parameters["linear_solver"] in ["direct", "lu"] or dolfin.has_lu_solver_method(linear_solver_parameters["linear_solver"]):
       static_parameters = linear_solver_parameters["lu_solver"]["reuse_factorization"] or \
                           linear_solver_parameters["lu_solver"]["same_nonzero_pattern"]
     else:
       if dolfin_version() < (1, 3, 0):
         static_parameters = linear_solver_parameters["krylov_solver"]["preconditioner"]["reuse"]
       else:
         static_parameters = not linear_solver_parameters["krylov_solver"]["preconditioner"]["structure"] == "different_nonzero_pattern"
     if static_parameters:
       raise ParameterException("Non-static solve supplied with static linear solver parameters")
     
   return linear_solver_parameters
示例#9
0
文件: utils.py 项目: blechta/fenapack
def get_default_factor_solver_type(comm):
    """Return first available factor solver type name.
    This is implemened using DOLFIN now."""

    methods_parallel = ("mumps", "superlu_dist", "pastix")
    methods_sequential = ("mumps", "umfpack", "superlu",
                          "superlu_dist", "pastix")

    if isinstance(comm, PETSc.Comm):
        comm = comm.tompi4py()

    if MPI.size(comm) > 1:
        methods = methods_parallel
    else:
        methods = methods_sequential

    for method in methods:
        if has_lu_solver_method(method):
            return method

    raise RuntimeError("Did not find any suitable direct sparse solver in PETSc")
    def __init__(self, *args, **kwargs):
        args, kwargs = copy.copy(args), copy.copy(kwargs)

        # Process arguments not to be passed to _extract_args
        if "initial_guess" in kwargs:
            if not kwargs["initial_guess"] is None and not isinstance(kwargs["initial_guess"], dolfin.Function):
                raise InvalidArgumentException("initial_guess must be a Function")
            initial_guess = kwargs["initial_guess"]
            del(kwargs["initial_guess"])
        else:
            initial_guess = None
        if "adjoint_solver_parameters" in kwargs:
            if not kwargs["adjoint_solver_parameters"] is None and not isinstance(kwargs["adjoint_solver_parameters"], dict):
                raise InvalidArgumentException("adjoint_solver_parameters must be a dictionary")
            adjoint_solver_parameters = kwargs["adjoint_solver_parameters"]
            del(kwargs["adjoint_solver_parameters"])
        else:
            adjoint_solver_parameters = None
        if "pre_assembly_parameters" in kwargs:
            pre_assembly_parameters = kwargs["pre_assembly_parameters"]
            del(kwargs["pre_assembly_parameters"])
        else:
            pre_assembly_parameters = {}

        # Process remaining arguments
        if "form_compiler_parameters" in kwargs:
            raise NotImplementedException("form_compiler_parameters argument not supported")
        eq, x, bcs, J, tol, goal, form_parameters, solver_parameters = dolfin.fem.solving._extract_args(*args, **kwargs)

        # Relax requirements on equation syntax
        eq_lhs_rank = form_rank(eq.lhs)
        if eq_lhs_rank == 1:
            form = eq.lhs
            if not is_zero_rhs(eq.rhs):
                form -= eq.rhs
            if x in ufl.algorithms.extract_coefficients(form):
                if J is None:
                    J = derivative(form, x)
                if x in ufl.algorithms.extract_coefficients(J):
                    # Non-linear solve
                    is_linear = False
                else:
                    # Linear solve, rank 2 LHS
                    cache_info("Detected that solve for %s is linear" % x.name())
                    form = replace(form, {x:dolfin.TrialFunction(x.function_space())})
                    eq = lhs(form) == rhs(form)
                    eq_lhs_rank = form_rank(eq.lhs)
                    assert(eq_lhs_rank == 2)
                    is_linear = True
            else:
                # Linear solve, rank 1 LHS
                is_linear = True
        elif eq_lhs_rank == 2:
            form = eq.lhs
            if not is_zero_rhs(eq.rhs):
                form -= eq.rhs
            if not x in ufl.algorithms.extract_coefficients(form):
                # Linear solve, rank 2 LHS
                eq = lhs(form) == rhs(form)
                eq_lhs_rank = form_rank(eq.lhs)
                assert(eq_lhs_rank == 2)
                is_linear = True
            else:
                # ??
                raise InvalidArgumentException("Invalid equation")

        # Initial guess sanity checking
        if is_linear:
            if not "krylov_solver" in solver_parameters:
                solver_parameters["krylov_solver"] = {}
            def initial_guess_enabled():
                return solver_parameters["krylov_solver"].get("nonzero_initial_guess", False)
            def initial_guess_disabled():
                return not solver_parameters["krylov_solver"].get("nonzero_initial_guess", True)
            def enable_initial_guess():
                solver_parameters["krylov_solver"]["nonzero_initial_guess"] = True
                return

            if initial_guess is None:
                if initial_guess_enabled():
                    initial_guess = x
            elif eq_lhs_rank == 1:
                # Supplied an initial guess for a linear solve with a rank 1 LHS -
                # ignore it
                initial_guess = None
            elif "linear_solver" in solver_parameters and not solver_parameters["linear_solver"] in ["direct", "lu"] and not dolfin.has_lu_solver_method(solver_parameters["linear_solver"]):
                # Supplied an initial guess with a Krylov solver - check the
                # initial_guess solver parameter
                if initial_guess_disabled():
                    raise ParameterException("initial_guess cannot be set if nonzero_initial_guess solver parameter is False")
                enable_initial_guess()
            elif is_linear:
                # Supplied an initial guess for a linear solve with an LU solver -
                # ignore it
                initial_guess = None

        # Initialise
        EquationSolver.__init__(self, eq, x, bcs,
          solver_parameters = solver_parameters,
          adjoint_solver_parameters = adjoint_solver_parameters,
          pre_assembly_parameters = pre_assembly_parameters)
        self.__args = args
        self.__kwargs = kwargs
        self.__J = J
        self.__tol = tol
        self.__goal = goal
        self.__form_parameters = form_parameters
        self.__initial_guess = initial_guess

        # Assemble
        self.reassemble()

        return
示例#11
0
# -*- coding: utf-8 -*-
"""
Checks that this version of FEniCS/DOLFIN was compiled with parallel HDF5 and
a few extra preconditoners and solvers.
"""

import dolfin as df

assert df.has_hdf5_parallel()

assert df.has_krylov_solver_preconditioner('hypre_amg')
assert df.has_krylov_solver_preconditioner('hypre_euclid')
assert df.has_krylov_solver_preconditioner('hypre_parasails')

assert df.has_lu_solver_method('mumps')

assert df.has_petsc()
assert df.has_petsc4py()
示例#12
0
from dolfin import has_lu_solver_method

lusolver = "superlu_dist" if has_lu_solver_method("superlu_dist") else "default"

direct = dict(
    reuse = False,
    iterative = False,
    lusolver = lusolver,
)
direct_reuse = dict(
    reuse = True,
    iterative = False,
    lusolver = lusolver,
    luparams = dict(
        symmetric = False,
        same_nonzero_pattern = True,
        reuse_factorization = True,),
)

bicgstab = dict(
    reuse = False,
    iterative = True,
    lusolver = ("superlu_dist" if has_lu_solver_method("superlu_dist") else "default"),
    luparams = dict(
        symmetric = False,
        same_nonzero_pattern = True,
        reuse_factorization = False,),
    ks = "bicgstab",
    kp = "hypre_euclid",
    kparams = dict(
        maximum_iterations = 600,