Fix restrict=True for actions#5260
Conversation
connorjward
left a comment
There was a problem hiding this comment.
Seems to make sense.
|
What error were you getting? It should be possible still to assemble the original unrestricted F and then interpolate the result into the restricted space. This seems like a workaround |
An error in UFL for incompatible spaces in action.
I don't understand. Where are we assembling F? |
will break into My guess is that the error in UFL might be doing the checks wrong. |
|
Also another potential source of issues is the fact that |
|
We have In |
Sounds like one mathematically safe fix is to replace |
| self.F = replace(F, {F_arg: v_res, self.u: self.u_restrict}) | ||
| else: | ||
| self.F = interpolate(v_res, replace(F, {self.u: self.u_restrict})) | ||
| self.F = interpolate(v_res, replace(F, {u_arg: u_res, self.u: self.u_restrict})) |
There was a problem hiding this comment.
| self.F = interpolate(v_res, replace(F, {u_arg: u_res, self.u: self.u_restrict})) | |
| self.F = interpolate(v_res, replace(F, {self.u: interpolate(self.u_restrict, V)})) |
There was a problem hiding this comment.
There are many ways to "fix" this. Of course my suggestion is far from optimal because we need to generate code and incur extra flops. But I think this is the most robust solution. We can make it efficient if we intercept V_res->V in interpolate and replace the codegen with dof-permutation (i.e. assign)
| if isinstance(self.J, Form): | ||
| v_arg, u_arg = self.J.arguments() | ||
| self.J = replace(self.J, {v_arg: v_res, u_arg: u_res, self.u: self.u_restrict}) | ||
| else: | ||
| J_full = replace(self.J, {self.u: u_full}) | ||
| self.J = ufl_expr.action(Pstar, ufl_expr.action(J_full, P)) |
There was a problem hiding this comment.
Should we turn this into a reusable function? It might be good to generalize to any number of arguments
We need to replace the contracted argument