Skip to content

fix(hermite): keep the cached committed force across snapshot and restore - #46

Merged
SMI-Lab-Inha merged 1 commit into
devfrom
fix/restore-force-cache
Oct 23, 2026
Merged

SMI-Lab-Inha merged 1 commit into
devfrom
fix/restore-force-cache

Conversation

@SMI-Lab-Inha

Copy link
Copy Markdown
Owner

Summary

First item of the correctness backlog before 0.3.0.

The problem. The C API manual promises that a restore followed by a step is bit-identical to taking that step from the saved state (CableDyn_SaveState/RestoreState, used for CFD outer correctors). OpenFAST correction iterations rely on the same Snapshot/Restore pair. On a finite-EI cable with seabed friction, the promise could fail in the last bits:

  • Before a snapshot: each step caches the committed force F_n from its converged evaluation. The next step reuses it.
  • On restore: CD_HermiteCable_Dyn_Restore discarded that cache, so the restored model evaluated F_n afresh.
  • Why the two differ: when a node slides, the commit's friction return mapping moves its anchor to q - c*dxy. The spring force formed from q minus that anchor reproduces the capped force only to rounding. So the fresh F_n differs from the cached one in the last bits.
  • Where it showed: only on some trajectories. The controlled-cable snapshot test failed on the Linux Debug runner only, and fix: whole diagnostic messages; name causes and workarounds #27 worked around it by clearing the reference copy's cache too.
  • Comment: the type comment claimed that the cache "only ever replaces a bitwise-identical evaluation". That is not true.

What changes:

  • Snapshot keeps the cached force with the state: fc_R, its key and its validity.
  • Restore brings the cache back, unless the cache was invalidated since the snapshot. A new counter, fc_clears, is advanced at every invalidation: all 16 setter sites and the OpenFAST checkpoint reload. A restored model therefore takes the same path as one that was never rolled back.
  • The carried Newton factor is still dropped on restore. Restarts stay exact only with tangent reuse off, as before.
  • The cache comment now states what holds.
  • Test: the controlled-cable snapshot test asserts that restore brings back the snapshot's cached force. It no longer clears the reference's cache, so it checks the original, stronger claim: the restored model marches bit-identically to an untouched copy.

Runs without restores take the same path as before.

Verification

  • Not reproduced locally. The failure did not reproduce on Windows, in Release or Debug, so this PR's Linux Debug CI job is the real test of the restored claim.
  • Mechanism: confirmed by reading the code. assemble_contact forms the capped force from q - anchor_old, while commit_friction_anchors writes anchor_new = q - (cap/(k*dlen))*dxy.
  • Local suite (Windows, gfortran, Release, slow tier included): ctest 297/297; pytest 2052 passed; pre-commit run --all-files and the Sphinx -W build pass.
  • Snapshot/restart-related tests: also pass in a local Debug build (-O0 -fcheck=all).

Checklist

  • pre-commit run --all-files passes
  • ctest --test-dir build --output-on-failure passes
  • python -m pytest tests python/tests passes (if Python or validation records changed)
  • VALIDATION.md updated if a validation result changed (none changed)
  • CHANGELOG.md updated under [Unreleased] (heading added if missing) for user-visible changes
  • Documentation in doc/ updated for changed inputs, options, or outputs (no change: the documented behaviour now holds)
  • Conventional Commit title (feat:, fix:, docs:, ...)
  • Commits are signed off (git commit -s) under the
    Developer Certificate of Origin

…tore

A restore followed by a step must be bit-identical to taking that step from the saved state (CableDyn_RestoreState, OpenFAST correction iterations). Restore discarded the committed force cached from the previous step and evaluated it afresh. On a finite-EI cable with seabed friction the two differ in the last bits: the commit's return mapping moves a sliding node's anchor to q - c*dxy, and the spring force from q minus that anchor reproduces the capped force only to rounding. Whether it showed depended on the trajectory (the controlled-cable snapshot test failed on the Linux Debug runner only).

Snapshot now keeps the cache with the state, and Restore brings it back unless a setter invalidated the cache since the snapshot (fc_clears counts the invalidations, including the OpenFAST checkpoint reload). The control test asserts the restored cache again instead of clearing the reference's, and the cache comment states what holds. Runs without restores do not change.

Signed-off-by: Jae Hoon Seo <jaehoon.seo@inha.ac.kr>
@SMI-Lab-Inha

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-23T02:17:43.845705Z 4ced361 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 CableDyn | 🛠️ Build #35342172 | 📁 Comparing 4ced361 against latest (d3ddfeb)

  🔍 Preview build  

10 files changed · ± 10 modified

± Modified

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 4ced361f6f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@SMI-Lab-Inha
SMI-Lab-Inha merged commit ab7cdfc into dev Oct 23, 2026
15 checks passed
@SMI-Lab-Inha
SMI-Lab-Inha deleted the fix/restore-force-cache branch October 23, 2026 03:42
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.

1 participant