Пример #1
0
    def solve(self, x, b):
        if not isinstance(x, (function.Function, vector.Vector)):
            raise TypeError("Provided solution is a '%s', not a Function or Vector" % type(x).__name__)
        if isinstance(b, vector.Vector):
            b = b.function
        if not isinstance(b, function.Function):
            raise TypeError("Provided RHS is a '%s', not a Function" % type(b).__name__)

        if len(self.trial_space) > 1 and self.nullspace is not None:
            self.nullspace._apply(self.trial_space.dof_dset.field_ises)
        if len(self.test_space) > 1 and self.transpose_nullspace is not None:
            self.transpose_nullspace._apply(self.test_space.dof_dset.field_ises,
                                            transpose=True)
        if len(self.trial_space) > 1 and self.near_nullspace is not None:
            self.near_nullspace._apply(self.trial_space.dof_dset.field_ises, near=True)

        if self.A.has_bcs:
            b = self._lifted(b)

        if self.ksp.getInitialGuessNonzero():
            acc = x.dat.vec
        else:
            acc = x.dat.vec_wo

        with self.inserted_options(), b.dat.vec_ro as rhs, acc as solution, dmhooks.add_hooks(self.ksp.dm, self):
            self.ksp.solve(rhs, solution)

        r = self.ksp.getConvergedReason()
        if r < 0:
            raise ConvergenceError("LinearSolver failed to converge after %d iterations with reason: %s", self.ksp.getIterationNumber(), solving_utils.KSPReasons[r])
Пример #2
0
    def solve(self, x, b):
        if not isinstance(x, (function.Function, vector.Vector)):
            raise TypeError("Provided solution is a '%s', not a Function or Vector" % type(x).__name__)
        if not isinstance(b, function.Function):
            raise TypeError("Provided RHS is a '%s', not a Function" % type(b).__name__)

        if len(self._W) > 1 and self.nullspace is not None:
            self.nullspace._apply(self._W.dof_dset.field_ises)
        if len(self._W) > 1 and self.transpose_nullspace is not None:
            self.transpose_nullspace._apply(self._W.dof_dset.field_ises, transpose=True)
        if len(self._W) > 1 and self.near_nullspace is not None:
            self.near_nullspace._apply(self._W.dof_dset.field_ises, near=True)
        if self.A.has_bcs:
            b_bc = self._b
            # rhs = b - action(A, zero_function_with_bcs_applied)
            b_bc.assign(b - self._Abcs)
            # Now we need to apply the boundary conditions to the "RHS"
            for bc in self.A.bcs:
                bc.apply(b_bc)
            # don't want to write into b itself, because that would confuse user
            b = b_bc
        with self.inserted_options():
            with b.dat.vec_ro as rhs:
                with x.dat.vec as solution:
                    self.ksp.solve(rhs, solution)

        r = self.ksp.getConvergedReason()
        if r < 0:
            raise ConvergenceError("LinearSolver failed to converge after %d iterations with reason: %s", self.ksp.getIterationNumber(), solving_utils.KSPReasons[r])
Пример #3
0
def check_ts_convergence(ts):
    r = ts.getConvergedReason()
    # TODO: submit PR to petsc4py to add the following reasons
    # TSFORWARD_DIVERGED_LINEAR_SOLVE = -3,
    # TSADJOINT_DIVERGED_LINEAR_SOLVE = -4
    if r == -3:
        raise ConvergenceError(
            f"TS solve failed to converge. Reason: TSFORWARD_DIVERGED_LINEAR_SOLVE"
        )
    if r == -4:
        raise ConvergenceError(
            f"TS solve failed to converge. Reason: TSADJOINT_DIVERGED_LINEAR_SOLVE"
        )
    reason = TSReasons[r]
    if r < 0:
        raise ConvergenceError(
            f"TS solve failed to converge after {ts.getStepNumber()} iterations. Reason: {reason}"
        )
Пример #4
0
def check_snes_convergence(snes):
    r = snes.getConvergedReason()
    try:
        reason = SNESReasons[r]
        inner = False
    except KeyError:
        r = snes.getKSP().getConvergedReason()
        try:
            inner = True
            reason = KSPReasons[r]
        except KeyError:
            reason = "unknown reason (petsc4py enum incomplete?), try with -snes_converged_reason and -ksp_converged_reason"
    if r < 0:
        if inner:
            msg = "Inner linear solve failed to converge after %d iterations with reason: %s" % \
                  (snes.getKSP().getIterationNumber(), reason)
        else:
            msg = reason
        raise ConvergenceError(r"""Nonlinear solve failed to converge after %d nonlinear iterations.
Reason:
   %s""" % (snes.getIterationNumber(), msg))