@@ -138,19 +138,19 @@ def eval(cls, *args):
138138
139139class FieldData:
140140 """
141- Metadata class passed to `LinearSolveExpr`. Encapsulates metadata for a single
142- `target` field needed to interface with PETSc SNES solvers.
141+ Metadata for a single `target` field passed to `LinearSolveExpr`.
142+ Used to interface with PETSc SNES solvers at the IET level .
143143
144144 Parameters
145145 ----------
146146
147147 target : Function-like
148148 The target field to solve into, which is a Function-like object.
149149 jacobian : Jacobian
150- Defines the matrix-vector product for the linear system, where the vector is
150+ Defines the matrix-vector product for the linear system, where the vector is
151151 the PETScArray representing the `target`.
152152 residual : Residual
153- Defines the nonlinear residual function F(target) = 0.
153+ Defines the residual function F(target) = 0.
154154 initialguess : InitialGuess
155155 Defines the initial guess for the solution, which satisfies
156156 essential boundary conditions.
@@ -212,7 +212,8 @@ def targets(self):
212212class MultipleFieldData(FieldData):
213213 """
214214 Metadata class passed to `LinearSolveExpr`, for mixed-field problems,
215- where the solution vector spans multiple `targets`.
215+ where the solution vector spans multiple `targets`. Used to interface
216+ with PETSc SNES solvers at the IET level.
216217
217218 Parameters
218219 ----------
@@ -221,7 +222,7 @@ class MultipleFieldData(FieldData):
221222 jacobian : MixedJacobian
222223 Defines the matrix-vector products for the full system Jacobian.
223224 residual : MixedResidual
224- Defines the nonlinear residual function F(targets) = 0.
225+ Defines the residual function F(targets) = 0.
225226 initialguess : InitialGuess
226227 Defines the initial guess metadata, which satisfies
227228 essential boundary conditions.
@@ -272,13 +273,17 @@ def space_order(self):
272273 def targets(self):
273274 return self._targets
274275
275-
276+
276277class BaseJacobian:
277278 def __init__(self, arrays, target=None):
278279 self.arrays = arrays
279280 self.target = target
280281
281282 def _scale_non_bcs(self, matvecs, target=None):
283+ """
284+ Scale the symbolic expressions `matvecs` by the grid cell volume,
285+ excluding EssentialBCs.
286+ """
282287 target = target or self.target
283288 vol = target.grid.symbolic_volume_cell
284289
@@ -287,8 +292,20 @@ def _scale_non_bcs(self, matvecs, target=None):
287292 for m in matvecs
288293 ]
289294
295+ def _scale_bcs(self, matvecs, scdiag):
296+ """
297+ Scale the EssentialBCs in `matvecs` by `scdiag`.
298+ """
299+ return [
300+ m._rebuild(rhs=m.rhs * scdiag) if isinstance(m, ZeroRow) else m
301+ for m in matvecs
302+ ]
303+
290304 def _compute_scdiag(self, matvecs, col_target=None):
291305 """
306+ Compute the diagonal scaling factor from the symbolic matrix-vector
307+ expressions in `matvecs`. If the centre stencil (i.e. the diagonal term of the
308+ matrix) is not unique, defaults to 1.0.
292309 """
293310 x = self.arrays[col_target or self.target]['x']
294311
@@ -298,15 +315,6 @@ def _compute_scdiag(self, matvecs, col_target=None):
298315 }
299316 return centres.pop() if len(centres) == 1 else 1.0
300317
301- def _scale_bcs(self, matvecs, scdiag):
302- """
303- Scale the essential BCs
304- """
305- return [
306- m._rebuild(rhs=m.rhs * scdiag) if isinstance(m, ZeroRow) else m
307- for m in matvecs
308- ]
309-
310318 def _build_matvec_expr(self, expr, **kwargs):
311319 col_target = kwargs.get('col_target', self.target)
312320 row_target = kwargs.get('row_target', self.target)
@@ -356,9 +364,9 @@ def __init__(self, target, exprs, arrays, time_mapper):
356364 def matvecs(self):
357365 # TODO: add shortcut explanation etc
358366 """
359- Stores the expressions used to generate the `MatMult`
360- callback generated at the IET level. This function is
361- passed to PETSc via `MatShellSetOperation(...,MATOP_MULT,(void (*)(void))MatMult)`.
367+ Stores the expressions used to generate the `MatMult` callback generated
368+ at the IET level. This function is passed to PETSc via
369+ `MatShellSetOperation(...,MATOP_MULT,(void (*)(void))MatMult)`.
362370 """
363371 return self._matvecs
364372
@@ -517,7 +525,7 @@ def __repr__(self):
517525
518526class Residual:
519527 """
520- Gennerates the metadata needed to define the nonlinear residual function
528+ Generates the metadata needed to define the nonlinear residual function
521529 F(target) = 0 for use with PETSc's SNES interface.
522530
523531 PETSc's SNES interface includes methods for solving nonlinear systems of
@@ -610,6 +618,8 @@ def _scale_bcs(self, eq, scdiag=None):
610618
611619class MixedResidual(Residual):
612620 """
621+ Generates the metadata needed to define the nonlinear residual function
622+ F(targets) = 0 for use with PETSc's SNES interface.
613623 """
614624 def __init__(self, target_exprs, arrays, time_mapper, scdiag):
615625 self.targets = tuple(target_exprs.keys())
@@ -621,6 +631,9 @@ def __init__(self, target_exprs, arrays, time_mapper, scdiag):
621631 @property
622632 def b_exprs(self):
623633 """
634+ For mixed solvers, a callback to form the RHS vector `b` is not generated,
635+ a single residual callback is generated to compute F(targets).
636+ TODO: Investigate if this is optimal.
624637 """
625638 return None
626639
@@ -629,10 +642,10 @@ def _build_exprs(self, target_exprs):
629642 for t, exprs in target_exprs.items():
630643
631644 residual_exprs.extend(
632- chain.from_iterable(self._build_residual(e, t)
633- for e in as_tuple(exprs)
634- ) )
635-
645+ chain.from_iterable(
646+ self._build_residual(e, t) for e in as_tuple(exprs)
647+ )
648+ )
636649 self._F_exprs = tuple(sorted(
637650 residual_exprs, key=lambda e: not isinstance(e, EssentialBC)
638651 ))
@@ -671,7 +684,9 @@ def _build_residual(self, expr, target):
671684
672685class InitialGuess:
673686 """
674- Enforce initial guess to satisfy essential BCs.
687+ Metadata passed to `LinearSolveExpr` to define the initial guess
688+ symbolic expressions, enforcing the initial guess to satisfy essential
689+ boundary conditions.
675690 """
676691 def __init__(self, target, exprs, arrays):
677692 self.target = target
@@ -680,13 +695,12 @@ def __init__(self, target, exprs, arrays):
680695
681696 @property
682697 def exprs(self):
683- """
684- """
685698 return self._exprs
686699
687700 def _build_exprs(self, exprs):
688701 """
689- Return a list of initial guess expressions.
702+ Return a list of initial guess symbolic expressions
703+ that satisfy essential boundary conditions.
690704 """
691705 self._exprs = tuple([
692706 eq for eq in
0 commit comments