def solve(self, bounds=None): """Solve the variational problem. :arg bounds: Optional bounds on the solution (lower, upper). ``lower`` and ``upper`` must both be :class:`~.Function`\s. or :class:`~.Vector`\s. .. note:: If bounds are provided the ``snes_type`` must be set to ``vinewtonssls`` or ``vinewtonrsls``. """ # Make sure appcontext is attached to the DM before we solve. dm = self.snes.getDM() dmhooks.set_appctx(dm, self._ctx) # Apply the boundary conditions to the initial guess. for bc in self._problem.bcs: bc.apply(self._problem.u) if bounds is not None: lower, upper = bounds with lower.dat.vec_ro as lb, upper.dat.vec_ro as ub: self.snes.setVariableBounds(lb, ub) work = self._work.dat # Ensure options database has full set of options (so monitors work right) with self.inserted_options(): with work.vec as v: with self._problem.u.dat.vec as u: u.copy(v) self.snes.solve(None, v) v.copy(u) solving_utils.check_snes_convergence(self.snes)
def solve(self, bounds=None): r"""Solve the variational problem. :arg bounds: Optional bounds on the solution (lower, upper). ``lower`` and ``upper`` must both be :class:`~.Function`\s. or :class:`~.Vector`\s. .. note:: If bounds are provided the ``snes_type`` must be set to ``vinewtonssls`` or ``vinewtonrsls``. """ # Make sure appcontext is attached to the DM before we solve. dm = self.snes.getDM() for dbc in self._problem.dirichlet_bcs(): dbc.apply(self._problem.u) if bounds is not None: lower, upper = bounds with lower.dat.vec_ro as lb, upper.dat.vec_ro as ub: self.snes.setVariableBounds(lb, ub) work = self._work with self._problem.u.dat.vec as u: u.copy(work) with ExitStack() as stack: # Ensure options database has full set of options (so monitors # work right) for ctx in chain((self.inserted_options(), dmhooks.add_hooks(dm, self, appctx=self._ctx)), self._transfer_operators): stack.enter_context(ctx) self.snes.solve(None, work) work.copy(u) self._setup = True solving_utils.check_snes_convergence(self.snes)
def solve(self, bounds=None): r"""Solve the variational problem. :arg bounds: Optional bounds on the solution (lower, upper). ``lower`` and ``upper`` must both be :class:`~.Function`\s. or :class:`~.Vector`\s. .. note:: If bounds are provided the ``snes_type`` must be set to ``vinewtonssls`` or ``vinewtonrsls``. """ # Make sure appcontext is attached to the DM before we solve. dm = self.snes.getDM() for dbc in self._problem.dirichlet_bcs(): dbc.apply(self._problem.u) if bounds is not None: lower, upper = bounds with lower.dat.vec_ro as lb, upper.dat.vec_ro as ub: self.snes.setVariableBounds(lb, ub) work = self._work with self._problem.u.dat.vec as u: u.copy(work) with ExitStack() as stack: # Ensure options database has full set of options (so monitors # work right) for ctx in chain((self.inserted_options(), dmhooks.appctx(dm, self._ctx)), self._transfer_operators): stack.enter_context(ctx) self.snes.solve(None, work) work.copy(u) self._setup = True solving_utils.check_snes_convergence(self.snes)
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)