-
Notifications
You must be signed in to change notification settings - Fork 160
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
Error when taking the derivative of a form which includes the cell-normals of a manifold. #2595
Comments
I have recreated the issue. Based on what @tommbendall said about last week's UFL update being the cause, I reset UFL back to 1dddf46eb5d011e7144d8780ac008dc2a87a2ce6 and ran the script without trouble. So it seems that either something that got added to FEniCS UFL since then, or indeed @rckirby 's accidental PR merge to Firedrake UFL is to blame. I think we ought to be able to find the culprit by looking at the diff for firedrakeproject/ufl#30? |
This is the culprit: Previously the default was that a geometric quantity was considered to be That merge brings in a fix for
? |
See FEniCS/ufl#119. There was a bug in UFL which incorrectly simplified all CellNormal derivatives to 0. |
import ufl
mesh = ufl.Mesh(ufl.VectorElement("CG", ufl.triangle, 2, dim=3))
cn = ufl.algorithms.apply_geometry_lowering.apply_geometry_lowering(ufl.CellNormal(mesh))
gcn = ufl.grad(cn) |
@wence-, thanks for finding that. Your simpler form does result in the same error too. Full script:
@michalhabera, thanks for the workaround, I'll see if we can use it for our form for the time being. |
(That workaround appears not to help :() Here's a minimal example that only uses UFL to demonstrate the issue: from ufl import (Cell, CellNormal, Coefficient, FunctionSpace, Mesh,
VectorElement, derivative, dx, grad, inner)
from ufl.algorithms import compute_form_data
from ufl.algorithms.apply_geometry_lowering import apply_geometry_lowering
mesh = Mesh(VectorElement("P", Cell("triangle", 3), 2))
try_workaround = False
if try_workaround:
n = apply_geometry_lowering(CellNormal(mesh))
else:
n = CellNormal(mesh)
V = FunctionSpace(mesh, VectorElement("P", mesh.ufl_cell(), 2))
u = Coefficient(V)
phi = grad(inner(u, n))[0]*dx
fd = compute_form_data(
derivative(phi, u),
do_apply_function_pullbacks=True,
do_apply_geometry_lowering=True,
) |
Indeed. I now remember in all manifold codes we first interpolate the normal field into a conforming VectorFunction space, this avoids the Alternatively, and dangerously, you could make coefficient derivatives of ReferenceGrad = 0 by monkey-patching UFL, from ufl.algorithms.apply_derivatives import GateauxDerivativeRuleset, GenericDerivativeRuleset
def myrule(self, o):
print(f"D({o})/D({self._w}) simplified to 0")
return GenericDerivativeRuleset.independent_terminal(self, o)
GateauxDerivativeRuleset.reference_grad = myrule |
The comments in |
Could I ask for an update on this issue please - I'm afraid I got rather confused trying to follow the discussions referenced above. I'm really hoping to be able to run the vector invariant form of the shallow water equations on the sphere again! |
Correct fix: handle derivatives of referencegrad correctly in UFL. Workaround:
|
Note that the same issue is seen for a facet normal of a higher-order cell, thus not depending on manifolds, see #3313. |
When trying to create a
LinearVariationalProblem
from the derivative of a form, UFL throws an error if:MFE:
Error message:
This seems to have only started happening since the UFL update, although I'm not sure of exactly when.
The text was updated successfully, but these errors were encountered: