-
Notifications
You must be signed in to change notification settings - Fork 166
Clement interpolant #4244
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: master
Are you sure you want to change the base?
Clement interpolant #4244
Conversation
For arguments, see :class:`.Interpolator`. | ||
""" | ||
|
||
def __new__(cls, expr, V, **kwargs): |
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.
Should this check go to __init__
?
if rank != len(self.V.value_shape): | ||
raise ValueError(f"Rank-{rank} input inconsistent with target space.") | ||
mesh = self.V.mesh() | ||
dim = mesh.topological_dimension() |
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 dim
should be the number of copies of the element V.block_size
. I think a VectorFunctionSpace
and TensorFunctionSpace
could be indexed with a double index (flat_dof_id, component_id)
. So rank
could possibly be unrestricted and there wouldn't have to be special cases if you treat the rank-0 as the general case.
|
||
@pytest.mark.parametrize("rank", range(3)) | ||
@pytest.mark.parametrize("dim", range(1, 4)) | ||
def test_clement_interpolator_simplex(dim, rank): |
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.
We should test a vector with 3 components in a 2D mesh.
domain = "{[i]: 0 <= i < patch.dofs}" | ||
instructions = "patch[i] = patch[i] + vol[0]" | ||
keys = {"vol": (volume, op2.READ), "patch": (patch_volume, op2.RW)} | ||
parloops.par_loop((domain, instructions), dX, keys) |
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.
The patch volume here could become a cached_property so it is not recomputed every time. Maybe we could attach this property to the mesh, so it can be reused more widely across different Interpolators
.
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.
Good idea. I've addressed this in 34ceb67, using the cell_sizes
cached property as a template.
I've been meaning to upstream some functionality from Animate that might be useful for the wider Firedrake community, so am starting with this. Let me know if it's of interest!
This PR adds functionality for the Clément interpolant, which transfers fields from P1 space to P0 space via local volume averaging. We've found this particularly useful for gradient/Hessian recovery in P1 space (can upstream those later).
I've included tests on simplices in 1D, 2D, and 3D, and for scalar-, vector-, and matrix-valued functions.
A limitation of the approach is that the local averaging breaks down on the boundary, but it does a good job in the domain interior. I also have an implementation of local facet averaging on the boundary that I can provide, if it'd be of use.
http://www.numdam.org/item/M2AN_1975__9_2_77_0.pdf