Skip to content

Add cumulative strain guard to FixSymmetry to prevent phase transitions#445

Open
janosh wants to merge 2 commits intoTorchSim:mainfrom
janosh:fix-symmetry-cumulative-strain
Open

Add cumulative strain guard to FixSymmetry to prevent phase transitions#445
janosh wants to merge 2 commits intoTorchSim:mainfrom
janosh:fix-symmetry-cumulative-strain

Conversation

@janosh
Copy link
Collaborator

@janosh janosh commented Feb 6, 2026

Summary

Builds on #438 (FixSymmetry constraint). Adds a cumulative strain guard that prevents phase transitions in structures with extreme aspect ratios.

Problem

The existing per-step deformation check (max_delta <= 0.25) catches large single-step cell changes but not slow cumulative drift across many steps.

Fix

  • Store initial refined cells as reference_cells in from_state()
  • In adjust_cell(), compute cumulative strain from the reference cell (not just the per-step delta)
  • When cumulative strain exceeds max_cumulative_strain (default 0.5), scale the cell update proportionally to stay within the strain envelope
  • Propagate reference_cells through reindex(), merge(), select_constraint(), and select_sub_constraint()

The 0.5 default allows substantial legitimate relaxation (50% strain from the initial cell) while blocking Bravais lattice changes.

Test

Adds a regression test with an elongated hexagonal cell (c/a ≈ 70, SG #191 P6/mmm) under heavy compression (0.7x). Verifies:

  1. Symmetry is preserved after FIRE optimization
  2. Cumulative strain stays within the configured limit

Note

This is complementary to #443 which fixes L-BFGS history contamination from unsymmetrized forces. That PR addresses the force-direction drift; this PR addresses the cell-deformation drift. Both failure modes can cause symmetry loss on pathological structures.

@janosh janosh force-pushed the fix-symmetry-cumulative-strain branch 3 times, most recently from 1aa6711 to 89496fe Compare February 6, 2026 21:49
The per-step deformation check (max_delta <= 0.25) is necessary but not
sufficient: many small steps can accumulate into a Bravais lattice change
(e.g. hexagonal → tetragonal) that breaks the symmetry constraint.

This was observed in production on a Sc-Nb-B structure with c/a ≈ 70
(c = 209.6 Å). During NequIP OAM-L relaxation, the c-axis collapsed to
6.2 Å through individually small steps, losing all hexagonal rotations.

The fix stores the initial refined cell as a reference in from_state()
and checks the total deformation from that reference in adjust_cell().
When cumulative strain exceeds max_cumulative_strain (default 0.5), the
cell update is scaled down proportionally to stay within the envelope.

The per-step deformation check is also softened from a hard RuntimeError
to a clamp (scaling the step to max 0.25), since the cumulative guard is
now the real safety net. This fixes test failures where rotated structures
with noisy forces occasionally produced single steps just over the 0.25
threshold (e.g. 0.2581).

- Add reference_cells and max_cumulative_strain to FixSymmetry.__init__
- Store refined cells in from_state() for cumulative tracking
- Clamp per-step deformation > 0.25 instead of raising RuntimeError
- Clamp cumulative strain in adjust_cell() when limit exceeded
- Propagate reference_cells through reindex/merge/select
- Add regression test with direct adjust_cell loop verifying clamping
- Update test_large_deformation to verify clamp behavior (not raise)

Co-authored-by: Cursor <cursoragent@cursor.com>
@janosh janosh force-pushed the fix-symmetry-cumulative-strain branch from 89496fe to 5f78e2d Compare February 6, 2026 21:54
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