Abort assembly loop when negative Jacobian determinant is detected#896
Abort assembly loop when negative Jacobian determinant is detected#896kmokstad wants to merge 5 commits into
Conversation
whenever the Jacobian determinant is non-positive. Also changed the existing MxFiniteElement methods to return false for negative determinant values.
There was a problem hiding this comment.
Pull request overview
This PR adds a Jacobian-checking path intended to stop element assembly early when a non-positive Jacobian determinant is detected (e.g., inverted/distorted elements), and to print the offending element/integration point information rather than failing later in the solver.
Changes:
- Introduces a
FiniteElement::Jacobian(...)helper (and updates mixed-element Jacobian routines) to detect and report non-positive Jacobians. - Updates several 1D/2D/3D assembly loops to call the new Jacobian routine and propagate failure via the
okflag. - Adjusts Piola gradient indexing logic and applies minor formatting cleanups in a few places.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ASM/FiniteElement.h | Declares the new FiniteElement::Jacobian(...) helper and minor signature formatting updates. |
| src/ASM/FiniteElement.C | Defines the new constructor and FiniteElement::Jacobian(...), and updates mixed-element Jacobian handling + Piola gradient indexing. |
| src/ASM/ASMs1D.C | Switches 1D integration to use fe.Jacobian(...) and changes loop/control-flow around ok. |
| src/ASM/ASMs2D.C | Switches 2D integration to use fe.Jacobian(...) and changes the failure-handling behavior. |
| src/ASM/ASMs3D.C | Switches 3D integration to use fe.Jacobian(...) and changes the failure-handling behavior. |
| src/ASM/ASMs2Dmx.C | Switches 2D mixed integration to treat Jacobian failure as element failure (instead of skipping points). |
| src/ASM/ASMs3Dmx.C | Switches 3D mixed integration to treat Jacobian failure as element failure (instead of skipping points) and adjusts debug macro formatting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
jenkins build this with downstreams please |
|
jenkins build this with downstreams ifem-elasticity=229 ifem-openfrac=108 please |
|
jenkins build this with downstreams ifem-elasticity=229 ifem-openfrac=108 please |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 8 comments.
Comments suppressed due to low confidence (3)
src/ASM/ASMs3Dmx.C:621
- After
fe.Jacobian(...)fails, the code still computes Hessians and other derived quantities for the same Gauss point usingJac. For singular points (det=0), this can make subsequent computations invalid. Mark failure andcontinue;to the next integration point once Jacobian setup fails.
// Compute Jacobian inverse of the coordinate mapping and
// basis function derivatives w.r.t. Cartesian coordinates
if (!fe.Jacobian(Jac,Xnod,itgBasis,bfs))
ok = false;
// Compute Hessian of coordinate mapping and 2nd order derivatives
if (use2ndDer && !fe.Hessian(Hess,Jac,Xnod,itgBasis,bfs))
ok = false;
src/ASM/ASMs2D.C:1944
- If
fe.Jacobian(...)fails, the loop still proceeds to the Hessian computation usingJacfor the same integration point. For singular points (det=0) this can be invalid and may cause downstream issues. Prefercontinue;after settingok = falsewhen the Jacobian fails.
// Compute Jacobian inverse of coordinate mapping and derivatives
if (!fe.Jacobian(Jac,Xnod,bfs.dNdu))
ok = false;
// Compute Hessian of coordinate mapping and 2nd order derivatives
if (use2ndDer)
{
if (!utl::Hessian(Hess,fe.d2NdX2,Jac,Xnod,bfs.d2Ndu2,fe.dNdX))
ok = false;
src/ASM/ASMs1D.C:1231
- In the main Gauss-point loop, a failed
fe.Jacobian(...)only flipsokbut the iteration still continues into Hessian/3rd-derivative computations usingJacfor the same point. For singular points (det=0) this can make those computations invalid. Skip the remainder of the iteration when Jacobian setup fails.
if (!dNdu.empty())
{
// Compute derivatives in terms of physical coordinates
dNdu.multiply(dL); // Derivatives w.r.t. xi=[-1,1]
ok &= fe.Jacobian(Jac,fe.Xn,dNdu);
fe.detJxW *= wg[i];
// Compute Hessian of coordinate mapping and 2nd order derivatives
if (integrand.getIntegrandType() & Integrand::SECOND_DERIVATIVES)
{
d2Ndu2.multiply(dL*dL); // 2nd derivatives w.r.t. xi=[-1,1]
if (!utl::Hessian(Hess,fe.d2NdX2,Jac,fe.Xn,d2Ndu2,fe.dNdX))
ok = false;
else if (fe.G.cols() == 2)
This will also make models with left-hand-side parametrization fail.
This is an indication that an element shape is distorted beyond 180 degrees angles, etc. Printing out the element index during assembly is more informative than letting the equation solver fail subsequently due to ill-conditioning.
Notice that this will also prevent solving models with left-hand-side parameterization (which also gives negative energy norms, etc.).
Also in this PR:
|J|*wmember in theFiniteElementclass for axi-symmetric problems (this used to be in the apps before, but belongs in the main library since it is a generic feature).