-
Notifications
You must be signed in to change notification settings - Fork 191
BCs for cross-mesh interpolation #5165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7015df6
a8ff5b2
8640deb
8a387e0
d86f838
117c0ec
9e8314d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -563,10 +563,28 @@ def _interpolate_from_quadrature(self) -> Interpolate: | |||||
| elif self.ufl_interpolate.is_adjoint: | ||||||
| return interpolate(TestFunction(self.target_space), self.dual_arg) | ||||||
|
|
||||||
| def _bc_mask(self, space: WithGeometry, bcs: Iterable[DirichletBC]) -> Function: | ||||||
| """Return a 0/1 mask over `space` which is zero at boundary condition nodes | ||||||
| """ | ||||||
| space = space.dual() if is_dual(space) else space | ||||||
| f = Function(space).assign(1.0) | ||||||
| for bc in bcs: | ||||||
| if bc.function_space() == space: | ||||||
| bc.zero(f) | ||||||
| return f | ||||||
|
|
||||||
| def apply_bcs(self, mat: PETSc.Mat, bcs: Iterable[DirichletBC]) -> PETSc.Mat: | ||||||
| """Zero the rows and columns of `mat` associated with boundary condition nodes. | ||||||
| """ | ||||||
| row_arg, col_arg = self.ufl_interpolate.arguments() | ||||||
| row_mask = self._bc_mask(row_arg.function_space(), bcs) | ||||||
| col_mask = self._bc_mask(col_arg.function_space(), bcs) | ||||||
| with row_mask.dat.vec_ro as r, col_mask.dat.vec_ro as c: | ||||||
| mat.diagonalScale(r, c) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||||||
| return mat | ||||||
|
|
||||||
| def _get_callable(self, tensor=None, bcs=None, mat_type=None, sub_mat_type=None): | ||||||
| from firedrake.assemble import assemble | ||||||
| if bcs: | ||||||
| raise NotImplementedError("bcs not implemented for cross-mesh interpolation.") | ||||||
| mat_type = mat_type or "aij" | ||||||
|
|
||||||
| if self.into_quadrature_space: | ||||||
|
|
@@ -593,12 +611,13 @@ def callable() -> PETSc.Mat: | |||||
| source_space = self.operand.function_space() | ||||||
| if self.ufl_interpolate.is_adjoint: | ||||||
| I = Matrix(interpolate(TestFunction(source_space), self.target_space), res) | ||||||
| return assemble(action(I, self._interpolate_from_quadrature)).petscmat | ||||||
| res = assemble(action(I, self._interpolate_from_quadrature)).petscmat | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't the right thing be to reuse the support that assemble has for bcs?
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But the BCs that the user provided are not defined on a VOM FunctionSpace. Why do we need to support BCs for VomOntoVom?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I do
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like a bug, we should only set BCs on the final matrix-matrix product |
||||||
| else: | ||||||
| I = Matrix(interpolate(TrialFunction(source_space), self.target_space), res) | ||||||
| return assemble(action(self._interpolate_from_quadrature, I)).petscmat | ||||||
| else: | ||||||
| return res | ||||||
| res = assemble(action(self._interpolate_from_quadrature, I)).petscmat | ||||||
| if bcs: | ||||||
| res = self.apply_bcs(res, bcs) | ||||||
| return res | ||||||
|
|
||||||
| elif self.ufl_interpolate.is_adjoint: | ||||||
| assert self.rank == 1 | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is reinventing the wheel. We have some functions that do similar things scattered all over the place. My recommendation is to move
bcdofsfrom preconditioners/patch.py to bcs.py and use it instead.