def solve(self, x, b): if not isinstance(x, function.Function): raise TypeError("Provided solution is a '%s', not a Function" % 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) # User may have updated parameters solving_utils.update_parameters(self, self.ksp) 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 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 RuntimeError("LinearSolver failed to converge after %d iterations with reason: %s", self.ksp.getIterationNumber(), solving_utils.KSPReasons[r])
def solve(self, x, b): if not isinstance(x, function.Function): raise TypeError("Provided solution is a '%s', not a Function" % 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) # User may have updated parameters solving_utils.update_parameters(self, self.ksp) 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 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 RuntimeError( "LinearSolver failed to converge after %d iterations with reason: %s", self.ksp.getIterationNumber(), solving_utils.KSPReasons[r])
def solve(self): dm = self.snes.getDM() dm.setAppCtx(weakref.proxy(self._ctx)) dm.setCreateMatrix(self._ctx.create_matrix) # Apply the boundary conditions to the initial guess. for bc in self._problem.bcs: bc.apply(self._problem.u) # User might have updated parameters dict before calling # solve, ensure these are passed through to the snes. solving_utils.update_parameters(self, self.snes) with self._problem.u.dat.vec as v: self.snes.solve(None, v) solving_utils.check_snes_convergence(self.snes)
def __init__(self, *args, **kwargs): """ :arg problem: A :class:`LinearVariationalProblem` to solve. :kwarg solver_parameters: Solver parameters to pass to PETSc. This should be a dict mapping PETSc options to values. :kwarg nullspace: an optional :class:`.VectorSpaceBasis` (or :class:`.MixedVectorSpaceBasis`) spanning the null space of the operator. :kwarg options_prefix: an optional prefix used to distinguish PETSc options. If not provided a unique prefix will be created. Use this option if you want to pass options to the solver from the command line in addition to through the ``solver_parameters`` dict. """ super(LinearVariationalSolver, self).__init__(*args, **kwargs) self.parameters.setdefault('snes_type', 'ksponly') self.parameters.setdefault('ksp_rtol', 1.0e-7) solving_utils.update_parameters(self, self.snes)
def parameters(self, val): assert isinstance(val, dict), 'Must pass a dict to set parameters' self._parameters = val solving_utils.update_parameters(self, self.snes)