Skip to content

Feat: lematrho, populate forces, stress_tensor, energy from static DFT runs. - #50

Open
speckhard wants to merge 2 commits into
mainfrom
feat/lematrho-forces-energy
Open

Feat: lematrho, populate forces, stress_tensor, energy from static DFT runs.#50
speckhard wants to merge 2 commits into
mainfrom
feat/lematrho-forces-energy

Conversation

@speckhard

Copy link
Copy Markdown
Collaborator

Summary

  • Source fix: vasprun is now sourced from LeMatRhoStaticMaker (NSW=0,
    already-relaxed geometry) instead of LeMatRhoRelaxMaker_1. Forces/stress
    from the static run are the physically meaningful residual forces at the
    relaxed geometry.
  • New fields populated: forces (nsites×3, eV/Å), stress_tensor (3×3, kBar),
    energy (eV), and energy_corrected (eV — equals energy for R2SCAN since
    the MP 2020 correction is PBE-only).
  • Functional fix: changed from Functional.PBE to Functional.r2SCAN,
    confirmed from INCAR files in S3 (METAGGA = R2scan).
  • Single download loop: vasprun.xml.gz merged into the existing STATIC_FILES
    loop, removing a separate relax-vasprun download step.

Test plan

  • 46 unit tests pass, 2 integration tests skipped (require .env.integration)
  • Smoke test on 3 real S3 materials: functional=r2scan, non-null forces,
    stress_tensor, energy, energy_corrected == energy
  • TestVasprunForces added covering parse_vasprun_output and end-to-end
    pass-through into the Parquet row

…sprun

- Add vasprun.xml.gz to STATIC_FILES so it downloads in the same loop
  as charge density files; remove the now-redundant separate relax
  vasprun download
- Replace parse_vasprun_structure (returned only Structure) with
  parse_vasprun_output (returns structure, forces, stress_tensor, energy)
  by parsing ionic_steps[-1] and vasprun.final_energy
- Wire forces, stress_tensor, and energy into the OptimadeStructure
  constructor; energy_corrected is auto-computed (equals energy for
  R2SCAN since the MP 2020 correction is PBE-only)
- Fix functional from Functional.PBE to Functional.r2SCAN (confirmed
  from INCAR: METAGGA = R2scan)
- Update all test patches and mock return values accordingly; add
  TestVasprunForces covering parse_vasprun_output and end-to-end
  pass-through of forces/stress/energy into the Parquet row
@speckhard
speckhard requested review from Ramlaoui and mfranckel April 13, 2026 12:04
@speckhard
speckhard force-pushed the feat/lematrho-forces-energy branch from eaa67e8 to 926a715 Compare May 12, 2026 14:35
@Ramlaoui

Copy link
Copy Markdown
Collaborator

Just realized that the entire pipeline only extracts the last structure of all the trajectories. Is that also only what the final dataset contains? If that's a case, would a LeMatRho-Traj dataset be too expensive to store? I think it would also be interesting to have this dataset I can take care of writing a PR if the data is already available in the S3 bucket to support this.

@Ramlaoui Ramlaoui left a comment

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.

Thanks @speckhard this looks great!

xx, yy, zz, xy, yz, xz = (float(x) for x in s.flat[:6])
stress_out = [[xx, xy, xz], [xy, yy, yz], [xz, yz, zz]]

try:

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.

Silent failure, do we not have energy and forces on all structures?

forces_out = np.asarray(frc, dtype=float).reshape(-1, 3).tolist()

strs = final.get("stress") # Stress tensor in 3 × 3 (kBar)
if strs is not None:

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.

Seems surprising that vasp outputs might have different shapes for stress, shouldn't we only expect one in that case. Also from what I remember, vasp stress is in kBar and ML datasets are in eV/A^3, LeMat-Bulk also keeps kBar but will be worth mentioning in the dataset card to avoid confusion.

# Determine which raw files to keep
need_raw = set()
# Determine which raw files to keep (use .gz names, matching STATIC_FILES).
# vasprun.xml.gz is always needed for structure, forces, stress, and energy.

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.

Isn't that a required file for every structure or can it not be present in the bucket?

if tool_paths["can_run_ddec6"]:
need_raw |= _DDEC6_FILES

for filename in STATIC_FILES:

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.

Nitpick: the branching would be simpler if the loop was done on all the files except for vasprun.xml.gz which would be handled outside and not be part of STATIC_FILES. But not important at all.

@Ramlaoui

Copy link
Copy Markdown
Collaborator

Just realized that the entire pipeline only extracts the last structure of all the trajectories. Is that also only what the final dataset contains? If that's a case, would a LeMatRho-Traj dataset be too expensive to store? I think it would also be interesting to have this dataset I can take care of writing a PR if the data is already available in the S3 bucket to support this.

After talking to @mfranckel, the reason for this is clear now structures are already in equilibrium because they come from LeMat-Bulk :).

@speckhard

Copy link
Copy Markdown
Collaborator Author

Just realized that the entire pipeline only extracts the last structure of all the trajectories. Is that also only what the final dataset contains? If that's a case, would a LeMatRho-Traj dataset be too expensive to store? I think it would also be interesting to have this dataset I can take care of writing a PR if the data is already available in the S3 bucket to support this.

Hmm good point, but we relax with R2SCAN structures from LeMatBulk that were often relaxed with PBE so maybe we should save the trajectory even a few points of minimally different forces/energies would be useful

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