Skip to content

Abort assembly loop when negative Jacobian determinant is detected#896

Open
kmokstad wants to merge 5 commits into
OPM:masterfrom
kmokstad:master
Open

Abort assembly loop when negative Jacobian determinant is detected#896
kmokstad wants to merge 5 commits into
OPM:masterfrom
kmokstad:master

Conversation

@kmokstad

@kmokstad kmokstad commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

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:

  • Optional ramp-up time for gravity forces.
  • Update the |J|*w member in the FiniteElement class for axi-symmetric problems (this used to be in the apps before, but belongs in the main library since it is a generic feature).
  • Option to update the control point locations instead of assigning (a large) initial displacement elements, when activating elements in an already deformed model.

whenever the Jacobian determinant is non-positive. Also changed
the existing MxFiniteElement methods to return false for
negative determinant values.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ok flag.
  • 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.

Comment thread src/ASM/ASMs1D.C
Comment thread src/ASM/ASMs1D.C
Comment thread src/ASM/ASMs1D.C Outdated
Comment thread src/ASM/ASMs2D.C
Comment thread src/ASM/ASMs2D.C
Comment thread src/ASM/ASMs3D.C
Comment thread src/ASM/ASMs3D.C
Comment thread src/ASM/ASMs2Dmx.C
Comment thread src/ASM/ASMs3Dmx.C
@kmokstad

kmokstad commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator Author

jenkins build this with downstreams please

@kmokstad

kmokstad commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

jenkins build this with downstreams ifem-elasticity=229 ifem-openfrac=108 please

@kmokstad

kmokstad commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

jenkins build this with downstreams ifem-elasticity=229 ifem-openfrac=108 please

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 using Jac. For singular points (det=0), this can make subsequent computations invalid. Mark failure and continue; 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 using Jac for the same integration point. For singular points (det=0) this can be invalid and may cause downstream issues. Prefer continue; after setting ok = false when 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 flips ok but the iteration still continues into Hessian/3rd-derivative computations using Jac for 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)

Comment thread src/SIM/NonLinSIM.C
Comment thread src/ASM/HasGravityBase.C
Comment thread src/SIM/SIMbase.C
Comment thread src/SIM/SIMbase.C
Comment thread src/SIM/SIMbase.C Outdated
Comment thread src/ASM/ASMs2Dmx.C
Comment thread src/ASM/ASMs2Dmx.C Outdated
Comment thread src/ASM/ASMs2DTri.C
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants