Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
a2e7327
Migrate potential interface from atomistics to pyiron_lammps
jan-janssen Nov 8, 2025
5f29115
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 8, 2025
e8d3465
Add LAMMPS file interface function
jan-janssen Nov 8, 2025
381a624
Merge branch 'potential' into lammps_function
jan-janssen Nov 8, 2025
79c6cb3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 8, 2025
520f1ea
refactor
jan-janssen Nov 8, 2025
289123c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 8, 2025
2fcdedb
fix file interface
jan-janssen Nov 8, 2025
aa892fe
Add calc functions to init
jan-janssen Nov 8, 2025
7fc139f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 8, 2025
e946f96
Add potential to init
jan-janssen Nov 16, 2025
a2b6303
Add potential test
jan-janssen Nov 16, 2025
b48ebb1
Merge branch 'potential' into lammps_function
jan-janssen Nov 16, 2025
0196abb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 17, 2025
98cb97a
Merge remote-tracking branch 'origin/main' into lammps_function
jan-janssen Nov 19, 2025
8a53bd9
Add a first test
jan-janssen Nov 19, 2025
2a4e10c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 19, 2025
fd034b0
Add resource path
jan-janssen Nov 19, 2025
4d2101f
Merge remote-tracking branch 'origin/lammps_function' into lammps_fun…
jan-janssen Nov 19, 2025
8c91424
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 19, 2025
cc39ac5
fix resource path
jan-janssen Nov 19, 2025
47a1ee7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 19, 2025
c5ae8e3
move files
jan-janssen Nov 19, 2025
6cc5e0a
Delete tests/static/potentials_lammps.csv
jan-janssen Nov 19, 2025
601a76b
Delete tests/static/potential_LAMMPS/1999--Mishin-Y--Al--LAMMPS--ipr1…
jan-janssen Nov 19, 2025
0a2c502
add calc static test
jan-janssen Nov 20, 2025
232995e
Merge remote-tracking branch 'origin/lammps_function' into lammps_fun…
jan-janssen Nov 20, 2025
6a614f9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
5f32e2c
remove print
jan-janssen Nov 20, 2025
fdc415c
Merge branch 'lammps_function' of github.com:pyiron/pyiron_lammps int…
jan-janssen Nov 20, 2025
800c2d7
test missing ionic steps
jan-janssen Nov 20, 2025
abf5590
first minimize
jan-janssen Nov 20, 2025
8e9ebc0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
f3bda4c
pressure rotation
jan-janssen Nov 20, 2025
7adda1d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
37b2379
simplify tests
jan-janssen Nov 20, 2025
4dd26b2
remove argument
jan-janssen Nov 20, 2025
fc80c8e
feat: Increase test coverage for compatibility module (#268)
google-labs-jules[bot] Nov 20, 2025
81a583b
Delete .gitignore
jan-janssen Nov 20, 2025
98e73cd
fix tests
jan-janssen Nov 20, 2025
46ec6a0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
86da131
Add LammpsStructureCompatibility - work in progress
jan-janssen Nov 20, 2025
318f5a6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
38ba25d
minor changes
jan-janssen Nov 20, 2025
06c94af
Merge branch 'LammpsStructureCompatibility' of github.com:pyiron/pyir…
jan-janssen Nov 20, 2025
f82bb3d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
1587277
Fix water
jan-janssen Nov 20, 2025
ee4d7e5
Merge branch 'LammpsStructureCompatibility' of github.com:pyiron/pyir…
jan-janssen Nov 20, 2025
99512a1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
f376116
Merge remote-tracking branch 'origin/main' into lammps_function_water
jan-janssen Nov 20, 2025
dffaf72
Merge remote-tracking branch 'origin/LammpsStructureCompatibility' in…
jan-janssen Nov 20, 2025
c815c16
fix time step
jan-janssen Nov 21, 2025
6d0220a
Add support for atom_type selection
jan-janssen Nov 21, 2025
a263de3
fix ionic steps
jan-janssen Nov 21, 2025
c0a33c4
fix water structure
jan-janssen Nov 21, 2025
fcedda5
add support for full style
jan-janssen Nov 21, 2025
027a546
Format black
pyiron-runner Nov 21, 2025
fa9be4b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 21, 2025
b2ff359
Merge remote-tracking branch 'origin/main' into lammps_function_water
jan-janssen Nov 27, 2025
faa519c
Add structuretoolkit as dependencies
jan-janssen Nov 27, 2025
2906935
add empty lines
jan-janssen Nov 27, 2025
1c9cece
fix import
jan-janssen Nov 27, 2025
0374829
structuretoolkit for old test environment
jan-janssen Nov 27, 2025
abb0ae7
more recent version
jan-janssen Nov 27, 2025
1b4258e
fix water
jan-janssen Nov 27, 2025
c0eaf05
add very simple water test
jan-janssen Nov 27, 2025
68659e4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 27, 2025
9abb56f
Merge remote-tracking branch 'origin/main' into lammps_function_water
jan-janssen Nov 29, 2025
c09cc02
Add additional tests
jan-janssen Nov 29, 2025
296915e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 29, 2025
e1fcf8c
remove tests which do not work
jan-janssen Nov 29, 2025
a445649
Merge remote-tracking branch 'origin/lammps_function_water' into lamm…
jan-janssen Nov 29, 2025
cf8ac2b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .ci_support/environment-old.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ dependencies:
- numpy =1.26.0
- pandas =2.0.3
- scipy =1.11.1
- structuretoolkit =0.0.14
1 change: 1 addition & 0 deletions .ci_support/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ dependencies:
- numpy =2.3.5
- pandas =2.3.3
- scipy =1.16.3
- structuretoolkit =0.0.38
1 change: 1 addition & 0 deletions binder/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ dependencies:
- lammps =2024.08.29=*_mpi_openmpi_*
- hatchling =1.27.0
- hatch-vcs =0.4.0
- structuretoolkit =0.0.38
3 changes: 2 additions & 1 deletion pyiron_lammps/compatibility/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
calc_static,
)
from pyiron_lammps.compatibility.constraints import set_selective_dynamics
from pyiron_lammps.compatibility.structure import write_lammps_datafile
from pyiron_lammps.output import parse_lammps_output
from pyiron_lammps.potential import get_potential_by_name
from pyiron_lammps.structure import write_lammps_datafile


def lammps_file_interface_function(
Expand Down Expand Up @@ -173,6 +173,7 @@ def lammps_file_interface_function(
file_name="lammps.data",
working_directory=working_directory,
atom_type=atom_type,
potential_lst=potential_lst,
)

shell = subprocess.check_output(
Expand Down
153 changes: 120 additions & 33 deletions pyiron_lammps/compatibility/structure.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections import OrderedDict
from typing import Dict, Optional
from typing import Dict, Optional, Union

import numpy as np
from ase.atoms import Atoms
Expand All @@ -15,9 +15,11 @@ def __init__(
bond_dict: Optional[Dict] = None,
units: str = "metal",
atom_type: str = "atomic",
q_dict: Optional[Dict] = None,
):
super().__init__(bond_dict=bond_dict, units=units, atom_type=atom_type)
self._molecule_ids = []
self.q_dict = q_dict

@property
def structure(self) -> Optional[Atoms]:
Expand All @@ -39,11 +41,12 @@ def structure(self, structure):

"""
self._structure = structure
if self.atom_type == "full":
self._molecule_ids = np.ones(len(self.structure), dtype=int)
if self._atom_type == "full":
input_str = self.structure_full()
elif self.atom_type == "bond":
elif self._atom_type == "bond":
input_str = self.structure_bond()
elif self.atom_type == "charge":
elif self._atom_type == "charge":
input_str = self.structure_charge()
else: # self.atom_type == 'atomic'
input_str = self.structure_atomic()
Expand All @@ -57,7 +60,6 @@ def structure_bond(self):

"""
species_lammps_id_dict = self.get_lammps_id_dict(self.el_eam_lst)
self.molecule_ids = None
# analyze structure to get molecule_ids, bonds, angles etc
coords = self.rotate_positions(self._structure)

Expand All @@ -70,7 +72,7 @@ def structure_bond(self):
format_str = "{0:d} {1:d} {2:d} {3:f} {4:f} {5:f} "
if len(self._structure.positions[0]) == 3:
for id_atom, (x, y, z) in enumerate(coords):
id_mol = self.molecule_ids[id_atom]
id_mol = self._molecule_ids[id_atom]
atoms += (
format_str.format(
id_atom + 1,
Expand All @@ -84,7 +86,7 @@ def structure_bond(self):
)
elif len(self._structure.positions[0]) == 2:
for id_atom, (x, y) in enumerate(coords):
id_mol = self.molecule_ids[id_atom]
id_mol = self._molecule_ids[id_atom]
atoms += (
format_str.format(
id_atom + 1,
Expand Down Expand Up @@ -115,26 +117,22 @@ def structure_bond(self):
bond_type[i, j] = count
bond_type[j, i] = count

if self.structure.bonds is None:
if self.cutoff_radius is None:
bonds_lst = get_bonds(structure=self.structure, max_shells=1)
else:
bonds_lst = get_bonds(
structure=self.structure, radius=self.cutoff_radius
)
bonds = []
if self.cutoff_radius is None:
bonds_lst = get_bonds(structure=self.structure, max_shells=1)
else:
bonds_lst = get_bonds(structure=self.structure, radius=self.cutoff_radius)
bonds = []

for ia, i_bonds in enumerate(bonds_lst):
el_i = el_dict[elements[ia]]
for el_j, b_lst in i_bonds.items():
b_type = bond_type[el_i][el_dict[el_j]]
for i_shell, ib_shell_lst in enumerate(b_lst):
for ib in np.unique(ib_shell_lst):
if ia < ib: # avoid double counting of bonds
bonds.append([ia + 1, ib + 1, b_type])
for ia, i_bonds in enumerate(bonds_lst):
el_i = el_dict[elements[ia]]
for el_j, b_lst in i_bonds.items():
b_type = bond_type[el_i][el_dict[el_j]]
for i_shell, ib_shell_lst in enumerate(b_lst):
for ib in np.unique(ib_shell_lst):
if ia < ib: # avoid double counting of bonds
bonds.append([ia + 1, ib + 1, b_type])

self.structure.bonds = np.array(bonds)
bonds = self.structure.bonds
bonds = np.array(bonds)

bonds_str = "Bonds \n\n"
for i_bond, (i_a, i_b, b_type) in enumerate(bonds):
Expand Down Expand Up @@ -165,15 +163,9 @@ def structure_full(self):

"""
species_lammps_id_dict = self.get_lammps_id_dict(self.el_eam_lst)
self.molecule_ids = None
coords = self.rotate_positions(self._structure)

# extract electric charges from potential file
q_dict = {
species_name: self.potential.get_charge(species_name)
for species_name in set(self.structure.get_chemical_symbols())
}

bonds_lst, angles_lst = [], []
bond_type_lst, angle_type_lst = [], []
# Using a cutoff distance to draw the bonds instead of the number of neighbors
Expand Down Expand Up @@ -250,9 +242,9 @@ def structure_full(self):
atoms += (
format_str.format(
id_atom + 1,
self.molecule_ids[id_atom],
self._molecule_ids[id_atom],
species_lammps_id_dict[el],
q_dict[el],
self.q_dict[el],
coord[0],
coord[1],
coord[2],
Expand Down Expand Up @@ -334,3 +326,98 @@ def get_bonds(
norm_order=2,
)
return neighbors.get_bonds(radius=radius, max_shells=max_shells, prec=prec)


def write_lammps_datafile(
structure: Atoms,
potential_elements: Union[np.ndarray, list],
bond_dict: Optional[Dict] = None,
units: str = "metal",
file_name: str = "lammps.data",
working_directory: Optional[str] = None,
atom_type: str = "atomic",
potential_lst: list[str] = [],
) -> None:
if atom_type == "full":
q_dict = {
el: get_charge(potential_line_lst=potential_lst, element_symbol=el)
for el in set(structure.get_chemical_symbols())
}
bond_dict = {
"O": {
"element_list": ["H"],
"cutoff_list": [2.0],
"max_bond_list": [2],
"bond_type_list": [1],
"angle_type_list": [1],
}
}
else:
q_dict = {}
lammps_str = LammpsStructureCompatibility(
bond_dict=bond_dict,
units=units,
atom_type=atom_type,
q_dict=q_dict,
)
lammps_str.el_eam_lst = potential_elements
lammps_str.structure = structure
lammps_str.write_file(file_name=file_name, cwd=working_directory)


def _find_line_by_prefix(potential_line_lst, prefix):
"""
Find a line that starts with the given prefix. Differences in white
space are ignored. Raises a ValueError if not line matches the prefix.

Args:
prefix (str): line prefix to search for

Returns:
list: words of the matching line

Raises:
ValueError: if not matching line was found
"""

def isprefix(prefix, lst):
if len(prefix) > len(lst):
return False
return all(n == l for n, l in zip(prefix, lst))

# compare the line word by word to also match lines that differ only in
# whitespace
prefix = prefix.split()
for l in potential_line_lst:
words = l.strip().split()
if isprefix(prefix, words):
return words

raise ValueError('No line with prefix "{}" found.'.format(" ".join(prefix)))


def get_charge(potential_line_lst, element_symbol):
"""
Return charge for element. If potential does not specify a charge,
raise a :class:NameError. Only makes sense for potentials
with pair_style "full".

Args:
element_symbol (str): short symbol for element

Returns:
float: charge speicified for the given element

Raises:
NameError: if potential does not specify charge for this element
"""

try:
line = "set group {} charge".format(element_symbol)
return float(
_find_line_by_prefix(potential_line_lst=potential_line_lst, prefix=line)[4]
)

except ValueError:
msg = "potential does not specify charge for element {}".format(element_symbol)
raise NameError(msg) from None
Loading
Loading