Skip to content

Commit

Permalink
Merge pull request #1272 from tlroy/thomasbranch
Browse files Browse the repository at this point in the history
* thomasbranch:
  removed white space
  Lawrence requested changes
  make lint
  Patrick changes
  Changes from Patrick
  fixed _assemble_pjac
  done make lint
  added get_appctx so PCBase works without matfree
  state given to context for all mat_type
  @cached_property assembly
  • Loading branch information
wence- committed Oct 3, 2018
2 parents 2936f46 + c78da12 commit 970d7f1
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 46 deletions.
13 changes: 4 additions & 9 deletions firedrake/dmhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,15 +327,10 @@ def create_field_decomposition(dm, *args, **kwargs):
ctx = get_appctx(dm)
coarsen = get_ctx_coarsener(dm)
if ctx is not None:
# DM from a hierarchy, so let's split apart in case we want to use it
# Inside a solve, ctx to split. If we're not from a
# hierarchy, this information is not used, so don't bother
# splitting, since it costs some time.
if dm.getRefineLevel() - dm.getCoarsenLevel() != 0:
ctxs = ctx.split([i for i in range(len(W))])
for d, c in zip(dms, ctxs):
push_appctx(d, c)
push_ctx_coarsener(d, coarsen)
ctxs = ctx.split([i for i in range(len(W))])
for d, c in zip(dms, ctxs):
push_appctx(d, c)
push_ctx_coarsener(d, coarsen)
return names, W._ises, dms


Expand Down
5 changes: 5 additions & 0 deletions firedrake/preconditioners/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,8 @@ def applyTranspose(self, pc, X, Y):
"""
pass

@staticmethod
def get_appctx(pc):
from firedrake.dmhooks import get_appctx
return get_appctx(pc.getDM()).appctx
83 changes: 46 additions & 37 deletions firedrake/solving_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from firedrake.exceptions import ConvergenceError
from firedrake.petsc import PETSc
from firedrake.formmanipulation import ExtractSubBlock
from firedrake.utils import cached_property


def _make_reasons(reasons):
Expand Down Expand Up @@ -69,11 +70,12 @@ class _SNESContext(object):
def __init__(self, problem, mat_type, pmat_type, appctx=None,
pre_jacobian_callback=None, pre_function_callback=None,
options_prefix=None):
from firedrake.assemble import allocate_matrix, create_assembly_callable
from firedrake.assemble import create_assembly_callable
if pmat_type is None:
pmat_type = mat_type
self.mat_type = mat_type
self.pmat_type = pmat_type
self.options_prefix = options_prefix

matfree = mat_type == 'matfree'
pmatfree = pmat_type == 'matfree'
Expand All @@ -82,67 +84,39 @@ def __init__(self, problem, mat_type, pmat_type, appctx=None,
self._pre_jacobian_callback = pre_jacobian_callback
self._pre_function_callback = pre_function_callback

fcp = problem.form_compiler_parameters
self.fcp = problem.form_compiler_parameters
# Function to hold current guess
self._x = problem.u

if appctx is None:
appctx = {}

if matfree or pmatfree:
# A split context will already get the full state.
# TODO, a better way of doing this.
# Now we don't have a temporary state inside the snes
# context we could just require the user to pass in the
# full state on the outside.
appctx.setdefault("state", self._x)
# A split context will already get the full state.
# TODO, a better way of doing this.
# Now we don't have a temporary state inside the snes
# context we could just require the user to pass in the
# full state on the outside.
appctx.setdefault("state", self._x)

self.appctx = appctx
self.matfree = matfree
self.pmatfree = pmatfree
self.F = problem.F
self.J = problem.J

self._jac = allocate_matrix(self.J, bcs=problem.bcs,
form_compiler_parameters=fcp,
mat_type=mat_type,
appctx=appctx,
options_prefix=options_prefix)
self._assemble_jac = create_assembly_callable(self.J,
tensor=self._jac,
bcs=problem.bcs,
form_compiler_parameters=fcp,
mat_type=mat_type)

self.is_mixed = self._jac.block_shape != (1, 1)

if mat_type != pmat_type or problem.Jp is not None:
# Need separate pmat if either Jp is different or we want
# a different pmat type to the mat type.
if problem.Jp is None:
self.Jp = self.J
else:
self.Jp = problem.Jp
self._pjac = allocate_matrix(self.Jp, bcs=problem.bcs,
form_compiler_parameters=fcp,
mat_type=pmat_type,
appctx=appctx,
options_prefix=options_prefix)

self._assemble_pjac = create_assembly_callable(self.Jp,
tensor=self._pjac,
bcs=problem.bcs,
form_compiler_parameters=fcp,
mat_type=pmat_type)
else:
# pmat_type == mat_type and Jp is None
self.Jp = None
self._pjac = self._jac

self._F = function.Function(self.F.arguments()[0].function_space())
self._assemble_residual = create_assembly_callable(self.F,
tensor=self._F,
form_compiler_parameters=fcp)
form_compiler_parameters=self.fcp)

self._jacobian_assembled = False
self._splits = {}
Expand Down Expand Up @@ -312,3 +286,38 @@ def compute_operators(ksp, J, P):
assert P.handle == ctx._pjac.petscmat.handle
ctx._assemble_pjac()
ctx._pjac.force_evaluation()

@cached_property
def _jac(self):
from firedrake.assemble import allocate_matrix
return allocate_matrix(self.J, bcs=self._problem.bcs,
form_compiler_parameters=self.fcp,
mat_type=self.mat_type,
appctx=self.appctx,
options_prefix=self.options_prefix)

@cached_property
def _assemble_jac(self):
from firedrake.assemble import create_assembly_callable
return create_assembly_callable(self.J, tensor=self._jac, bcs=self._problem.bcs, form_compiler_parameters=self.fcp, mat_type=self.mat_type)

@cached_property
def is_mixed(self):
return self._jac.block_shape != (1, 1)

@cached_property
def _pjac(self):
if self.mat_type != self.pmat_type or self._problem.Jp is not None:
from firedrake.assemble import allocate_matrix
return allocate_matrix(self.Jp, bcs=self._problem.bcs, form_compiler_parameters=self.fcp, mat_type=self.pmat_type, appctx=self.appctx, options_prefix=self.options_prefix)
else:
return self._jac

@cached_property
def _assemble_pjac(self):
from firedrake.assemble import create_assembly_callable
return create_assembly_callable(self.Jp, tensor=self._pjac, bcs=self._problem.bcs, form_compiler_parameters=self.fcp, mat_type=self.pmat_type)

@cached_property
def _F(self):
return function.Function(self.F.arguments()[0].function_space())

0 comments on commit 970d7f1

Please sign in to comment.