Skip to content

Add support for charge atom style#269

Merged
jan-janssen merged 2 commits intomainfrom
charge
Nov 20, 2025
Merged

Add support for charge atom style#269
jan-janssen merged 2 commits intomainfrom
charge

Conversation

@jan-janssen
Copy link
Copy Markdown
Member

@jan-janssen jan-janssen commented Nov 20, 2025

Summary by CodeRabbit

  • New Features

    • Added support for charge-aware LAMMPS structure generation with configurable atom_type parameter, enabling selection between standard "atomic" mode and "charge" mode for per-atom charge handling.
  • Tests

    • Added test coverage for charge-aware structure generation.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Nov 20, 2025

Walkthrough

The PR introduces charge-aware structure generation to LammpsStructure by adding an optional atom_type parameter that controls which structure-building method is invoked. When atom_type is "charge", the structure setter calls the new structure_charge() method instead of the default structure_atomic(), enabling per-atom charges in LAMMPS input generation.

Changes

Cohort / File(s) Summary
LammpsStructure Enhancement
pyiron_lammps/structure.py
Added atom_type parameter to __init__ (default "atomic") and stored as _atom_type. Modified structure property setter to conditionally call structure_charge() or structure_atomic() based on atom_type value. Implemented new public method structure_charge() to generate LAMMPS atom data block with per-atom charges using species-to-id mapping and rotated coordinates.
Charge Structure Test
tests/test_structure.py
Added unit test test_structure_charge() validating charge-aware structure generation, verifying the output includes proper LAMMPS headers, masses section, and atom entries with charges.

Sequence Diagram

sequenceDiagram
    participant User
    participant LammpsStructure
    participant StructureBuilder

    User->>LammpsStructure: __init__(atom_type="charge")
    LammpsStructure->>LammpsStructure: Store _atom_type="charge"

    User->>LammpsStructure: structure = atoms
    LammpsStructure->>LammpsStructure: Check _atom_type

    rect rgb(200, 240, 255)
    Note over LammpsStructure: atom_type="charge" path
    LammpsStructure->>StructureBuilder: structure_charge()
    StructureBuilder->>StructureBuilder: Map species to IDs
    StructureBuilder->>StructureBuilder: Include per-atom charges
    StructureBuilder-->>LammpsStructure: Return charged atom data
    end

    rect rgb(240, 240, 200)
    Note over LammpsStructure: atom_type="atomic" path (default)
    LammpsStructure->>StructureBuilder: structure_atomic()
    StructureBuilder-->>LammpsStructure: Return atomic data
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Key areas requiring attention:
    • Logic in the structure property setter branching on _atom_type value to ensure both paths are correctly wired
    • Implementation of structure_charge() method—verify correctness of species-to-id mapping, charge handling, and coordinate rotation
    • Backward compatibility: confirm that default atom_type="atomic" preserves existing behavior
    • Test coverage adequacy for both charge and atomic paths

Possibly related PRs

  • Test write structure #199: Also modifies LammpsStructure.__init__ signature and the structure property setter logic, but implements units/velocity handling rather than charge support; potential interaction point if both PRs merge.

Poem

🐰 A charge upon the atoms fair,
With types now flowing here and there,
From "atomic" paths to "charge" so keen,
The finest LAMMPS input e'er seen!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Add support for charge atom style' directly and clearly describes the main change: introducing charge atom style support to LammpsStructure, which is the core purpose of the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch charge

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.

@codecov
Copy link
Copy Markdown

codecov bot commented Nov 20, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.85%. Comparing base (5c08e4b) to head (6c1b627).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #269      +/-   ##
==========================================
+ Coverage   95.76%   95.85%   +0.09%     
==========================================
  Files           5        5              
  Lines         637      652      +15     
==========================================
+ Hits          610      625      +15     
  Misses         27       27              

☔ 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.

@jan-janssen jan-janssen merged commit bd54e9e into main Nov 20, 2025
20 of 21 checks passed
@jan-janssen jan-janssen deleted the charge branch November 20, 2025 19:02
Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pyiron_lammps/structure.py (1)

201-217: Confusing dual atom_type attributes confirmed.

Verification shows self.atom_type (line 211) is initialized to None but never used in actual code—only in a comment on line 249. The active logic uses self._atom_type (line 217), making the public attribute unused legacy code that should be removed to reduce confusion.

🧹 Nitpick comments (2)
pyiron_lammps/structure.py (2)

394-431: Consider refactoring to reduce duplication with structure_atomic().

The methods structure_charge() and structure_atomic() (lines 360-392) share ~80% identical logic. Consider extracting common logic into a helper method that accepts a format callback or charge list parameter to reduce maintenance burden.


409-409: Minor inconsistency in dimension access.

Line 409 uses self._structure.positions.shape[1] while the equivalent line in structure_atomic() (line 375) uses len(self._structure.positions[0]). Both are correct, but consistency would improve readability.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c08e4b and 6c1b627.

📒 Files selected for processing (2)
  • pyiron_lammps/structure.py (4 hunks)
  • tests/test_structure.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/test_structure.py (1)
pyiron_lammps/structure.py (3)
  • LammpsStructure (194-478)
  • structure (228-234)
  • structure (237-251)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: unittest_matrix (windows-latest, 3.14)
🔇 Additional comments (2)
tests/test_structure.py (1)

230-257: LGTM! Charge-aware structure generation is properly tested.

The test correctly validates that LammpsStructure with atom_type="charge" generates LAMMPS input including per-atom charges in the expected format.

pyiron_lammps/structure.py (1)

247-250: LGTM! Branching logic correctly routes to charge-aware or atomic structure generation.

The conditional logic appropriately selects structure_charge() when atom_type="charge" is specified, preserving backward compatibility with the default atomic mode.

Comment on lines +394 to +431
def structure_charge(self):
"""
Create atom structure including the atom charges.

By convention the LAMMPS atom type numbers are chose alphabetically for the chemical species.

Returns: LAMMPS readable structure.

"""
species_lammps_id_dict = self.get_lammps_id_dict(self.el_eam_lst)
atoms = "Atoms\n\n"
coords = self.rotate_positions(self._structure)
el_charge_lst = self._structure.get_initial_charges()
el_lst = self._structure.get_chemical_symbols()
for id_atom, (el, coord) in enumerate(zip(el_lst, coords)):
dim = self._structure.positions.shape[1]
c = np.zeros(3)
c[:dim] = coord
atoms += (
"{0:d} {1:d} {2:f} {3:.15f} {4:.15f} {5:.15f}".format(
id_atom + 1,
species_lammps_id_dict[el],
el_charge_lst[id_atom],
c[0],
c[1],
c[2],
)
+ "\n"
)
return (
self.lammps_header(
structure=self.structure,
cell_dimensions=self.simulation_cell(),
species_lammps_id_dict=species_lammps_id_dict,
)
+ atoms
+ "\n"
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Missing structure validation check.

Unlike structure_atomic() (lines 367-368), this method doesn't check if self._structure is None before accessing it, which could cause an AttributeError.

Apply this diff to add the validation:

 def structure_charge(self):
     """
     Create atom structure including the atom charges.

     By convention the LAMMPS atom type numbers are chose alphabetically for the chemical species.

     Returns: LAMMPS readable structure.

     """
+    if self._structure is None:
+        raise ValueError("Structure not set")
     species_lammps_id_dict = self.get_lammps_id_dict(self.el_eam_lst)
🤖 Prompt for AI Agents
In pyiron_lammps/structure.py around lines 394 to 431, add the same validation
present in structure_atomic (around lines 367-368): check if self._structure is
None at the start of structure_charge and raise a clear exception (or otherwise
handle the missing structure) before any access to self._structure to prevent
AttributeError; ensure the new check mirrors the project’s existing error
type/message used in structure_atomic.

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