Skip to content

Pass through failure of compressible material failure. - #35

Open
hverhelst wants to merge 1 commit into
mainfrom
hotfix/compressible_convergence
Open

Pass through failure of compressible material failure.#35
hverhelst wants to merge 1 commit into
mainfrom
hotfix/compressible_convergence

Conversation

@hverhelst

Copy link
Copy Markdown
Member

Signal compressible plane-stress material failure as data, and fix pstretch packing

The through-thickness Newton solve for the compressible plane-stress condition S33(c33)=0 could not report failure: it raised GISMO_ENSURE from inside gsExprAssembler's OpenMP region, where no handler above the parallel construct can catch it, so a material failure terminated the process.

Failure is now signalled as data - a quiet NaN that propagates through the material tensors into the assembled system, detected after the parallel region and surfaced as ThinShellAssemblerStatus::AssemblyError, which the existing arc-length recovery path already handles by reducing the step.

  • _eval3D_Compressible_C33 (both overloads): on itmax exhaustion write quiet_NaN() instead of throwing, with a latched warning.
  • gsMaterialMatrixBaseDim::_getMetric: the ratio guard is negated so that a NaN determinant ratio enters the failure branch as well as a negative one; the real trigger is det(Gcov_def) = -nan, not a negative value.
  • A non-finite Newton initial guess (m_J0_sq == 0 gives pow(0,-1) = +inf) is rejected before the iteration starts.
  • The convergence test additionally requires an admissible iterate, c(2,2) > 0, so a damped step that leaves the admissible region cannot satisfy it.
  • The four inlined allFinite() status checks in gsThinShellAssembler are folded into two _isSystemFinite overloads.

The last two are hardening rather than bug fixes: a bounded sweep found no reachable state in which either changes a returned value, and their tests are labelled contract tests and pass with and without them. They are kept because the state they exclude IS reached - the exhausted-backtracking path drives c(2,2) to large negative values - and only a separate guard currently prevents the convergence test from accepting one.

Separately, eval3D_pstretch read C33s at the in-plane index k rather than at the packed index colIdx = j*u.cols()+k, so every through-thickness station received station j=0's value. This CHANGES NUMERICAL OUTPUT for callers evaluating principal stretches at more than one station, reached through gsMaterialMatrixEval (MaterialOutput::Stretch) and gsMaterialMatrixTFT. computePrincipalStretches passes a single station and was unaffected.

New suite gsMaterialMatrixNonlinear_test covers the failure path at material level and through the assembler status, plus a multi-station regression gate for the packing fix, observed to fail before it.

…tretch packing

The through-thickness Newton solve for the compressible plane-stress
condition S33(c33)=0 could not report failure: it raised GISMO_ENSURE from
inside gsExprAssembler's OpenMP region, where no handler above the parallel
construct can catch it, so a material failure terminated the process.

Failure is now signalled as data - a quiet NaN that propagates through the
material tensors into the assembled system, detected after the parallel
region and surfaced as ThinShellAssemblerStatus::AssemblyError, which the
existing arc-length recovery path already handles by reducing the step.

  * _eval3D_Compressible_C33 (both overloads): on itmax exhaustion write
    quiet_NaN() instead of throwing, with a latched warning.
  * gsMaterialMatrixBaseDim::_getMetric: the ratio guard is negated so that
    a NaN determinant ratio enters the failure branch as well as a negative
    one; the real trigger is det(Gcov_def) = -nan, not a negative value.
  * A non-finite Newton initial guess (m_J0_sq == 0 gives pow(0,-1) = +inf)
    is rejected before the iteration starts.
  * The convergence test additionally requires an admissible iterate,
    c(2,2) > 0, so a damped step that leaves the admissible region cannot
    satisfy it.
  * The four inlined allFinite() status checks in gsThinShellAssembler are
    folded into two _isSystemFinite overloads.

The last two are hardening rather than bug fixes: a bounded sweep found no
reachable state in which either changes a returned value, and their tests
are labelled contract tests and pass with and without them. They are kept
because the state they exclude IS reached - the exhausted-backtracking path
drives c(2,2) to large negative values - and only a separate guard currently
prevents the convergence test from accepting one.

Separately, eval3D_pstretch read C33s at the in-plane index k rather than at
the packed index colIdx = j*u.cols()+k, so every through-thickness station
received station j=0's value. This CHANGES NUMERICAL OUTPUT for callers
evaluating principal stretches at more than one station, reached through
gsMaterialMatrixEval (MaterialOutput::Stretch) and gsMaterialMatrixTFT.
computePrincipalStretches passes a single station and was unaffected.

New suite gsMaterialMatrixNonlinear_test covers the failure path at material
level and through the assembler status, plus a multi-station regression gate
for the packing fix, observed to fail before it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WuXKeJKcGFGedAq56Gn9za
Copilot AI lite review requested due to automatic review settings September 7, 2026 05:42

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.

🟡 Changes recommended

The new Newton-iteration “non-finite dc33” branch logs “iterate held” but still applies the non-finite increment, which can immediately corrupt the iterate and contradict the intended behavior.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR changes the compressible plane-stress through-thickness Newton solve failure mode from “throw inside OpenMP region” to “signal failure as data (NaN) that propagates into the assembled system”, so assemblers can detect the failure after the parallel region and return ThinShellAssemblerStatus::AssemblyError. It also fixes an indexing/packing bug in eval3D_pstretch for multi-station evaluation and adds a targeted unit test suite covering both behaviors.

Changes:

  • Replace exception-based plane-stress failure signaling with quiet-NaN propagation (material + metric computation), and detect non-finite assembled systems in gsThinShellAssembler.
  • Fix eval3D_pstretch to read per-station C33 using the packed column index (colIdx = j*u.cols() + k).
  • Add gsMaterialMatrixNonlinear_test to cover non-convergence/failure propagation and multi-station pstretch regression.
File summaries
File Description
unittests/gsMaterialMatrixNonlinear_test.cpp New unit tests covering plane-stress Newton failure propagation and multi-station pstretch packing regression.
src/gsThinShellAssembler.hpp Adds _isSystemFinite helpers and uses them to convert NaN-propagated failures into AssemblyError status.
src/gsThinShellAssembler.h Declares the new _isSystemFinite overloads.
src/gsMaterialMatrixNonlinear.hpp Fixes pstretch packing index; updates plane-stress Newton solve to return NaN on failure and adds extra guards/warnings.
src/gsMaterialMatrixBaseDim.hpp Treats negative or NaN determinant ratios as failure by setting m_J0_sq to NaN (and warning once).
Review details

Suppressed comments (1)

src/gsMaterialMatrixNonlinear.hpp:2118

  • Same issue as the geometry overload: the non-finite dc33 branch reports the iterate is held, but dc33 is still applied immediately after the branch (c(2,2) += dc33). This can force c(2,2) to become NaN/Inf and makes the warning misleading; set dc33=0 whenever it is non-finite and warn once.
                else if (!warnedNonFinite)
                {
                    warnedNonFinite = true;
                    gsWarn<<"_eval3D_Compressible_C33 (Cmat): non-finite Newton increment dc33, iterate held (it="<<it<<", c(2,2)="<<c(2,2)<<", dc33="<<dc33<<", m_J0_sq="<<m_data.mine().m_J0_sq<<")\n";
                }
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +1966 to +1970
else if (!warnedNonFinite)
{
warnedNonFinite = true;
gsWarn<<"_eval3D_Compressible_C33: non-finite Newton increment dc33, iterate held (it="<<it<<", c(2,2)="<<c(2,2)<<", dc33="<<dc33<<", m_J0_sq="<<m_data.mine().m_J0_sq<<")\n";
}
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