Skip to content

Fix numerical residues in symmetry-expanded elastic strains - #1534

Open
xhuang-lila wants to merge 2 commits into
materialsproject:mainfrom
xhuang-lila:fix/normalize-expanded-strain-zeros
Open

Fix numerical residues in symmetry-expanded elastic strains#1534
xhuang-lila wants to merge 2 commits into
materialsproject:mainfrom
xhuang-lila:fix/normalize-expanded-strain-zeros

Conversation

@xhuang-lila

Copy link
Copy Markdown

Summary

  • zero strain components at or below the existing expand_strains tolerance before handing them to pymatgen fitting
  • use the same caller-provided tolerance for both classification and stored values
  • validate that the tolerance is positive and smaller than the applied strain components
  • preserve the original, unsanitized strains in TensorMapping, so symmetry acceptance and deduplication select the same entries as before
  • leave calculated stresses unchanged

Why

expand_strains accepts a rotated strain as single-component with a default 1e-3 threshold, but previously stored that strain with numerical residues around 1e-9 to 1e-8. Pymatgen fitting uses a tighter default threshold and can interpret those residues as mixed strain states, producing an ill-conditioned order-2 fit.

Validation

  • targeted elastic schema/job tests: 32 passed in an isolated environment
  • Ruff checks passed
  • regression covers a slightly perturbed high-symmetry cell and asserts that every stored expanded component is either exactly zero or above tol
  • archived replay evidence kept the expanded strain counts unchanged across all records; the largest unchanged-case specific-stiffness difference was 2e-5 GPa cm^3/g, while the pathological high-value BPC4 population was removed

The immediate downstream benchmark workaround uses sym_reduce=False, so benchmark correctness does not depend on this PR merging or releasing.

@xhuang-lila

Copy link
Copy Markdown
Author

@jmmshn Hui suggested I ask for your view because of your atomate2 elasticity experience. I would especially value a check on two API-boundary choices here: using tol itself to zero components already classified as numerical zero, while retaining the unsanitized values only for TensorMapping identity/deduplication; and failing early when tol is not below an applied strain component. The downstream benchmark is using sym_reduce=False as the immediate safe path, so there is no pressure to merge before those semantics are reviewed.

@JaGeo

JaGeo commented Aug 24, 2026

Copy link
Copy Markdown
Member

For info, @computron

Comment thread src/atomate2/common/schemas/elastic.py Outdated
raise ValueError(f"tol must be positive, got {tol}")
for strain in strains:
applied_components = np.abs(strain.voigt)
nonzero_components = applied_components[applied_components != 0]

@esoteric-ephemera esoteric-ephemera Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could this block be simplified with

if len(applied_components[applied_components > tol]) == 0:
    raise ...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes, that is sufficient under the function’s documented single-component input assumption. Thanks for the suggestion!

@esoteric-ephemera

Copy link
Copy Markdown
Collaborator

Thanks @xhuang-lila, just to clarify: This is basically to remove small numerical noise in the elastic tensor fitting? Generally I'm supportive of this as poor elastic tensor fitting has been a persistent problem in our workflows

@xhuang-lila

Copy link
Copy Markdown
Author

Yes—more specifically, this sets numerical residues in the symmetry-expanded strain inputs to exact zero before fitting; it does not modify the calculated stresses or the fitted elastic tensor. atomate2 already classifies those components as zero using tol, but passing the residual values through can cause pymatgen to treat them as real strain components and destabilize the fit.

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.

3 participants