You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the Ad operator framework, the classes SubdomainProjection, MortarProjection, Trace and InvTrace all represent mappings betweeen grid entities of various kinds. These are all implemented as projection matrices that, during parsing of an operator tree, are left multiplied with arrays and matrices. This is unsatisfactory for two reasons:
Constructing the projection matrices is slow and adds significantly to the computational cost of working with the Ad operators. As a partial remedy, some if not all of the projection classes construct the projection matrices during initializationof the projection object, but this to a large degree just moves the computational burden. The ahead-of-time construction will also be hard to make compatible with the caching outlined in Implement an Ad parser class #1181.
Projection operations are in reality slicing (for a global-to-local restriction) or filling in of selected rows in large arrays and matrices (for local-to-global prolongation). Representing this as matrix-matrix / matrix-vector products likely adds significantly to the computational cost.
Suggested change
The projection methods, say SubdomainProjection.face_restriction(), now return pp.ad.SparseArrayss. Instead, it should return a new slicer-object that roughly looks like this:
classRestrictionSlicer:
self._target_indices: np.ndarray# EK note to self: In the future, this may also be a PETSc IS objectdef__init__(self, int: dim, mdg: MixedDimensionalGrid, domain: list[pp.Grid]) ->None:
# self._target_indices is computed here.# What to do with mortar projections is not clear, but similar logic should applydef__matmul__(self, other: pp.ad.AdArray|np.ndarray) ->pp.ad.AdArray|np.ndarray:
returnother[self._target_ind]
classProjectionSlicer:
self._target_indices: np.ndarrayself._target_num_rows: intdef__init__(self, int: dim, mdg: MixedDimensionalGrid, domain: list[pp.Grid]) ->None:
# self._target_indices and self._target_num_rows are computed heredef__matmul__(self, other: pp.ad.AdArray|np.ndarray) ->pp.ad.AdArray|np.ndarray:
ifisinstance(other, np.ndarray):
result=np.ndarray(self._target_size, dtype=other.dtype)
result[self._target_ind] =otherelse: # pp.ad.AdArrayres_val=np.ndarray([self._target_size, dtype=other.val.dtype)
res_jac=sps.csr_matrix((self._target_size, other.jac.shape[1]))
res_val[self._target_ind] =other.valres_jac[self._target_ind] =other.jacreturnpp.ad.AdArray(res_val, res_jac)
Comments:
It is not clear whether we need one slicer each for SubdomainProjection, MortarProjection etc.
Similar thoughts may apply to the geometry basis functions pp.models.geometry.basis, research is needed.
The implementation should change the Ad backend only, no changes in the computational grid.
Testing will be needed.
Regarding the divergence class
The class pp.ad.Divergence represents a differential operator rather than a mapping. This cannot readily be implemented as slicing, and although improvements should be possible there as well, it will not be part of this issue.
Dependencies
This can be done independently of #1179, #1181, but should not be done in parallel.
The content you are editing has changed. Please copy your edits and refresh the page.
Background
In the Ad operator framework, the classes
SubdomainProjection
,MortarProjection
,Trace
andInvTrace
all represent mappings betweeen grid entities of various kinds. These are all implemented as projection matrices that, during parsing of an operator tree, are left multiplied with arrays and matrices. This is unsatisfactory for two reasons:Suggested change
The projection methods, say
SubdomainProjection.face_restriction()
, now returnpp.ad.SparseArrays
s. Instead, it should return a new slicer-object that roughly looks like this:Comments:
SubdomainProjection
,MortarProjection
etc.pp.models.geometry.basis
, research is needed.Regarding the divergence class
The class
pp.ad.Divergence
represents a differential operator rather than a mapping. This cannot readily be implemented as slicing, and although improvements should be possible there as well, it will not be part of this issue.Dependencies
This can be done independently of #1179, #1181, but should not be done in parallel.
Task (in roughly prioritized order)
The text was updated successfully, but these errors were encountered: