Currently, EdgeAvgNodalNormal computes nodal normals using current coordinates for the numerator but reference coordinates for normalization:
- numerator depends on current coordinates x
- denominator depends on reference coordinates xref
Smith now registers shape-displaced reference coordinates with Tribol, so the evaluated normal uses xref = X + shape. That improves value consistency, but the Enzyme Jacobian path treats xref as constant in ElementEdgeAvgNodalNormalJacobian(). As a result, derivatives through the reference-normalization factor are not included.
This means shape derivatives can include the path through current coordinates but miss the path through the reference-coordinate normalization:
x = X + shape + u
xref = X + shape
n = n(x, xref)
The current derivative effectively captures dn/dx, but not dn/dxref.
Simplest fix I can think of is to let nodal normals use current coordinates in the denominator, so d/d(shape) matches d/du, but this will be inconsistent with Puso and Laursen (2004).
Currently,
EdgeAvgNodalNormalcomputes nodal normals using current coordinates for the numerator but reference coordinates for normalization:Smith now registers shape-displaced reference coordinates with Tribol, so the evaluated normal uses xref = X + shape. That improves value consistency, but the Enzyme Jacobian path treats xref as constant in
ElementEdgeAvgNodalNormalJacobian(). As a result, derivatives through the reference-normalization factor are not included.This means shape derivatives can include the path through current coordinates but miss the path through the reference-coordinate normalization:
x = X + shape + u
xref = X + shape
n = n(x, xref)
The current derivative effectively captures dn/dx, but not dn/dxref.
Simplest fix I can think of is to let nodal normals use current coordinates in the denominator, so d/d(shape) matches d/du, but this will be inconsistent with Puso and Laursen (2004).