Skip to content

fix(dpa): handle NULL type properly in lammps plugin#5268

Open
link89 wants to merge 9 commits intodeepmodeling:masterfrom
link89:fix-lmp-null-type
Open

fix(dpa): handle NULL type properly in lammps plugin#5268
link89 wants to merge 9 commits intodeepmodeling:masterfrom
link89:fix-lmp-null-type

Conversation

@link89
Copy link
Contributor

@link89 link89 commented Feb 25, 2026

fix: #4749
related to: #4889

Summary by CodeRabbit

  • Bug Fixes

    • Standardized handling of NULL/placeholder atom types across DeepMD/DeepSpin pair styles so ghost/NULL types are represented consistently, reducing misclassification and improving simulation reliability.
  • Tests

    • Added tests covering NULL/placeholder type scenarios in DeepMD pair-style type-map configurations to prevent regressions and validate the updated behavior.

Copilot AI review requested due to automatic review settings February 25, 2026 08:53
@dosubot dosubot bot added the bug label Feb 25, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Map "NULL" atom types to sentinel -1 instead of type_map.size() in DeepMD-related pair/fix code; add unit tests exercising pair_coeff with NULL types.

Changes

Cohort / File(s) Summary
Pair style / fix updates
source/lmp/fix_dplr.cpp, source/lmp/pair_deepmd.cpp, source/lmp/pair_deepspin.cpp
When a coefficient type_name equals "NULL", code now records -1 in type index maps (ghost types) instead of type_map.size(). No other control flow or public signatures changed.
Test coverage
source/lmp/tests/test_lammps_dpa_pt.py, source/lmp/tests/test_lammps.py
Added test_pair_deepmd_type_map_with_null(lammps_type_map) to exercise DeepMD pair_coeff handling of NULL coefficients in type-map scenarios.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

C++

Suggested reviewers

  • wanghan-iapcm
  • njzjz
  • iProzd
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(dpa): handle NULL type properly in lammps plugin' clearly and specifically describes the main change: fixing NULL type handling in the LAMMPS DeepMD plugin.
Linked Issues check ✅ Passed The PR addresses the core objective of issue #4749 by changing how NULL atom types are represented (using sentinel value -1 instead of type_map.size()), enabling safe handling of NULL coefficients without crashes.
Out of Scope Changes check ✅ Passed All code changes are directly related to the NULL type handling objective: three source files implement the fix, and two test files provide regression test coverage for the NULL type scenario.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
source/lmp/tests/test_lammps_dpa_pt.py (1)

497-500: Consider adding a basic sanity assertion.

The test is a crash-regression smoke test (no assertions), which is acceptable given the bug being fixed (double-free). However, since run(0) with only H atoms active is a well-defined state, adding even a simple assert lammps_type_map.eval("pe") != 0 (or a pytest.approx against a known value) would make the test more meaningful and protect against silent incorrect behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@source/lmp/tests/test_lammps_dpa_pt.py` around lines 497 - 500, In
test_pair_deepmd_type_map_with_null, after calling lammps_type_map.run(0) add a
simple sanity assertion that checks the computed potential energy is sensible
(for example assert lammps_type_map.eval("pe") != 0 or use pytest.approx against
a known value); place the assertion immediately after lammps_type_map.run(0) to
ensure the test still guards against silent incorrect behavior while keeping it
as a smoke/regression test for the double-free fix.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@source/lmp/tests/test_lammps_dpa_pt.py`:
- Around line 495-502: Add the missing blank line separating top-level test
functions: ensure there are two blank lines between the function definitions
test_pair_deepmd_type_map_with_null and test_pair_deepmd_real by inserting one
more blank line after the end of test_pair_deepmd_type_map_with_null (the
lammps_type_map.run(0) line), then run ruff format/check to confirm PEP8 E302 is
satisfied.

---

Nitpick comments:
In `@source/lmp/tests/test_lammps_dpa_pt.py`:
- Around line 497-500: In test_pair_deepmd_type_map_with_null, after calling
lammps_type_map.run(0) add a simple sanity assertion that checks the computed
potential energy is sensible (for example assert lammps_type_map.eval("pe") != 0
or use pytest.approx against a known value); place the assertion immediately
after lammps_type_map.run(0) to ensure the test still guards against silent
incorrect behavior while keeping it as a smoke/regression test for the
double-free fix.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 65eea4b and 05d7bef.

📒 Files selected for processing (4)
  • source/lmp/fix_dplr.cpp
  • source/lmp/pair_deepmd.cpp
  • source/lmp/pair_deepspin.cpp
  • source/lmp/tests/test_lammps_dpa_pt.py

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes handling of NULL atom types in DeepMD-related LAMMPS plugins by using a sentinel mapping value, and adds a regression test to cover the NULL type-map case.

Changes:

  • Map NULL types to -1 instead of type_map.size() in multiple LAMMPS plugin components.
  • Add a LAMMPS Python test to ensure pair_coeff accepts a NULL type entry without crashing.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
source/lmp/tests/test_lammps_dpa_pt.py Adds a regression test for NULL in the DeepMD type map.
source/lmp/pair_deepspin.cpp Changes NULL type index mapping to -1 sentinel.
source/lmp/pair_deepmd.cpp Changes NULL type index mapping to -1 sentinel.
source/lmp/fix_dplr.cpp Changes NULL type index mapping to -1 sentinel.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@source/lmp/tests/test_lammps_dpa_pt.py`:
- Around line 498-501: The current test test_pair_deepmd_type_map_with_null only
uses pair_style("deepmd ...") and doesn't exercise the hybrid/scaled + NULL
combination reported in Issue `#4749`; update or add a test that sets pair_style
to a hybrid/scaled form that includes deepmd (e.g., pair_style("hybrid/scaled
deepmd ...")) and then call pair_coeff with the same NULL mapping
(lammps_type_map.pair_coeff("* * H O NULL")) and run(0) to ensure the
hybrid/scaled + NULL path is exercised and does not crash; locate the test
function test_pair_deepmd_type_map_with_null and modify its pair_style
invocation (or create a new test with a distinct name) to use the hybrid/scaled
variant so the exact failing configuration is covered.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d61ffbb and dc6b163.

📒 Files selected for processing (1)
  • source/lmp/tests/test_lammps_dpa_pt.py

Signed-off-by: link89 <xuweihong.cn@gmail.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
source/lmp/tests/test_lammps.py (1)

520-524: Smoke test has no assertions — consider verifying forces on non-NULL atoms or zero forces on NULL atoms.

The test correctly exercises the NULL type code path (type-2 atoms in data_type_map_file are mapped to NULL), making it an effective crash-regression guard for issue #4749. However, without any assertion, a silent wrong-result regression (e.g., non-zero forces being computed for NULL atoms) would go undetected.

A lightweight addition would be to assert that atoms of the NULL type receive zero force:

💡 Suggested assertion for NULL-type atoms
 def test_pair_deepmd_type_map_with_null(lammps_type_map) -> None:
     lammps_type_map.pair_style(f"deepmd {pb_file.resolve()}")
     lammps_type_map.pair_coeff("* * H NULL")
     lammps_type_map.run(0)
+    # type_HO maps type 2 → NULL; atoms at 0-based indices 0 and 3 are type 2
+    null_atom_ids = [
+        i for i, t in enumerate(type_HO) if t == 2
+    ]  # 0-based positions of NULL atoms
+    for ii in range(len(lammps_type_map.atoms)):
+        atom = lammps_type_map.atoms[ii]
+        if (atom.id - 1) in null_atom_ids:
+            assert atom.force == pytest.approx([0.0, 0.0, 0.0])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@source/lmp/tests/test_lammps.py` around lines 520 - 524, The test function
test_pair_deepmd_type_map_with_null currently only runs LAMMPS without
assertions; update it to fetch the computed forces after lammps_type_map.run(0)
and assert that atoms mapped to NULL (type-2 in the data_type_map_file) have
zero force (or that non-NULL atoms have non-zero forces) to prevent silent
regressions — locate the test by function name and add a small check using the
LAMMPS wrapper's force-accessor (or API used elsewhere in tests) after calling
lammps_type_map.run(0) to verify per-atom forces for NULL vs non-NULL types.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@source/lmp/tests/test_lammps.py`:
- Around line 520-524: The test function test_pair_deepmd_type_map_with_null
currently only runs LAMMPS without assertions; update it to fetch the computed
forces after lammps_type_map.run(0) and assert that atoms mapped to NULL (type-2
in the data_type_map_file) have zero force (or that non-NULL atoms have non-zero
forces) to prevent silent regressions — locate the test by function name and add
a small check using the LAMMPS wrapper's force-accessor (or API used elsewhere
in tests) after calling lammps_type_map.run(0) to verify per-atom forces for
NULL vs non-NULL types.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc6b163 and ef8b152.

📒 Files selected for processing (1)
  • source/lmp/tests/test_lammps.py

@codecov
Copy link

codecov bot commented Feb 25, 2026

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.06%. Comparing base (65eea4b) to head (7adaf83).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
source/lmp/fix_dplr.cpp 0.00% 1 Missing ⚠️
source/lmp/pair_deepmd.cpp 0.00% 1 Missing ⚠️
source/lmp/pair_deepspin.cpp 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5268      +/-   ##
==========================================
- Coverage   82.00%   80.06%   -1.94%     
==========================================
  Files         750      750              
  Lines       75082    75173      +91     
  Branches     3615     3611       -4     
==========================================
- Hits        61571    60190    -1381     
- Misses      12347    13996    +1649     
+ Partials     1164      987     -177     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Signed-off-by: link89 <xuweihong.cn@gmail.com>
Signed-off-by: link89 <xuweihong.cn@gmail.com>
Signed-off-by: link89 <xuweihong.cn@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NULL atom type can not be used with deepmd 3.1.0a0 pth

2 participants