def _la_solve(A, x, b, **kwargs): """Solve a linear algebra problem. :arg A: the assembled bilinear form, a :class:`.Matrix`. :arg x: the :class:`.Function` to write the solution into. :arg b: the :class:`.Function` defining the right hand side values. :kwarg bcs: an optional list of :class:`.DirichletBC`\s to apply. :kwarg solver_parameters: optional solver parameters. :kwarg nullspace: an optional :class:`.VectorSpaceBasis` (or :class:`.MixedVectorSpaceBasis`) spanning the null space of the operator. :kwarg transpose_nullspace: as for the nullspace, but used to make the right hand side consistent. :kwarg near_nullspace: as for the nullspace, but used to add the near nullspace. :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. .. note:: Any boundary conditions passed in as an argument here override the boundary conditions set when the bilinear form was assembled. That is, in the following example: .. code-block:: python A = assemble(a, bcs=[bc1]) solve(A, x, b, bcs=[bc2]) the boundary conditions in `bc2` will be applied to the problem while `bc1` will be ignored. Example usage: .. code-block:: python _la_solve(A, x, b, solver_parameters=parameters_dict).""" bcs, solver_parameters, nullspace, nullspace_T, near_nullspace, \ options_prefix = _extract_linear_solver_args(A, x, b, **kwargs) if bcs is not None: A.bcs = bcs solver = ls.LinearSolver(A, solver_parameters=solver_parameters, nullspace=nullspace, transpose_nullspace=nullspace_T, near_nullspace=near_nullspace, options_prefix=options_prefix) solver.solve(x, b)
def _la_solve(A, x, b, **kwargs): r"""Solve a linear algebra problem. :arg A: the assembled bilinear form, a :class:`.Matrix`. :arg x: the :class:`.Function` to write the solution into. :arg b: the :class:`.Function` defining the right hand side values. :kwarg solver_parameters: optional solver parameters. :kwarg nullspace: an optional :class:`.VectorSpaceBasis` (or :class:`.MixedVectorSpaceBasis`) spanning the null space of the operator. :kwarg transpose_nullspace: as for the nullspace, but used to make the right hand side consistent. :kwarg near_nullspace: as for the nullspace, but used to add the near nullspace. :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. .. note:: This function no longer accepts :class:`.DirichletBC`\s or :class:`.EquationBC`\s as arguments. Any boundary conditions must be applied when assembling the bilinear form as: .. code-block:: python A = assemble(a, bcs=[bc1]) solve(A, x, b) Example usage: .. code-block:: python _la_solve(A, x, b, solver_parameters=parameters_dict).""" bcs, solver_parameters, nullspace, nullspace_T, near_nullspace, \ options_prefix = _extract_linear_solver_args(A, x, b, **kwargs) if bcs is not None: raise RuntimeError( "It is no longer possible to apply or change boundary conditions after assembling the matrix `A`; pass any necessary boundary conditions to `assemble` when assembling `A`." ) solver = ls.LinearSolver(A, solver_parameters=solver_parameters, nullspace=nullspace, transpose_nullspace=nullspace_T, near_nullspace=near_nullspace, options_prefix=options_prefix) if isinstance(x, firedrake.Vector): x = x.function # linear MG doesn't need RHS, supply zero. lvp = vs.LinearVariationalProblem(a=A.a, L=0, u=x, bcs=A.bcs) mat_type = A.mat_type appctx = solver_parameters.get("appctx", {}) ctx = solving_utils._SNESContext(lvp, mat_type=mat_type, pmat_type=mat_type, appctx=appctx, options_prefix=options_prefix) dm = solver.ksp.dm with dmhooks.add_hooks(dm, solver, appctx=ctx): solver.solve(x, b)
def _la_solve(A, x, b, **kwargs): r"""Solve a linear algebra problem. :arg A: the assembled bilinear form, a :class:`.Matrix`. :arg x: the :class:`.Function` to write the solution into. :arg b: the :class:`.Function` defining the right hand side values. :kwarg bcs: an optional list of :class:`.DirichletBC`\s to apply. :kwarg solver_parameters: optional solver parameters. :kwarg nullspace: an optional :class:`.VectorSpaceBasis` (or :class:`.MixedVectorSpaceBasis`) spanning the null space of the operator. :kwarg transpose_nullspace: as for the nullspace, but used to make the right hand side consistent. :kwarg near_nullspace: as for the nullspace, but used to add the near nullspace. :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. .. note:: Any boundary conditions passed in as an argument here override the boundary conditions set when the bilinear form was assembled. That is, in the following example: .. code-block:: python A = assemble(a, bcs=[bc1]) solve(A, x, b, bcs=[bc2]) the boundary conditions in `bc2` will be applied to the problem while `bc1` will be ignored. Example usage: .. code-block:: python _la_solve(A, x, b, solver_parameters=parameters_dict).""" bcs, solver_parameters, nullspace, nullspace_T, near_nullspace, \ options_prefix = _extract_linear_solver_args(A, x, b, **kwargs) if bcs is not None: A.bcs = bcs solver = ls.LinearSolver(A, solver_parameters=solver_parameters, nullspace=nullspace, transpose_nullspace=nullspace_T, near_nullspace=near_nullspace, options_prefix=options_prefix) if isinstance(x, firedrake.Vector): x = x.function # linear MG doesn't need RHS, supply zero. lvp = vs.LinearVariationalProblem(a=A.a, L=0, u=x, bcs=bcs) mat_type = A.mat_type appctx = solver_parameters.get("appctx", {}) ctx = solving_utils._SNESContext(lvp, mat_type=mat_type, pmat_type=mat_type, appctx=appctx, options_prefix=options_prefix) dm = solver.ksp.dm with dmhooks.appctx(dm, ctx): solver.solve(x, b)