From 89642ceb55336876cb2568f252504facfc2d075e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sun, 23 Feb 2025 21:38:54 +0100 Subject: [PATCH 1/8] Add test for output --- pyiron_lammps/output.py | 17 +++-------------- tests/test_output.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 tests/test_output.py diff --git a/pyiron_lammps/output.py b/pyiron_lammps/output.py index 9f301c4d..d6599cce 100644 --- a/pyiron_lammps/output.py +++ b/pyiron_lammps/output.py @@ -182,7 +182,7 @@ def _collect_dump_from_text( df = pd.read_csv( buf, nrows=n, - sep="\s+", + sep="\\s+", header=None, names=columns, engine="c", @@ -331,7 +331,7 @@ def _collect_output_log( if l.startswith("Loop") or l.startswith("ERROR"): read_thermo = False dfs.append( - pd.read_csv(StringIO(thermo_lines), sep="\s+", engine="c") + pd.read_csv(StringIO(thermo_lines), sep="\\s+", engine="c") ) elif l.startswith("WARNING:"): @@ -514,19 +514,8 @@ def remap_indices( """ lammps_symbol_order = np.array(potential_elements) - # If new Lammps indices are present for which we have no species, extend the species list - unique_lammps_indices = np.unique(lammps_indices) - if len(unique_lammps_indices) > len(np.unique(structure.indices)): - unique_lammps_indices -= ( - 1 # Convert from Lammps start counting at 1 to python start counting at 0 - ) - new_lammps_symbols = lammps_symbol_order[unique_lammps_indices] - structure.set_species( - [structure.convert_element(el) for el in new_lammps_symbols] - ) - # Create a map between the lammps indices and structure indices to preserve species - structure_symbol_order = np.array([el.Abbreviation for el in structure.species]) + structure_symbol_order = np.unique(structure.get_chemical_symbols()) map_ = np.array( [ int(np.argwhere(lammps_symbol_order == symbol)[0]) + 1 diff --git a/tests/test_output.py b/tests/test_output.py new file mode 100644 index 00000000..8660da4b --- /dev/null +++ b/tests/test_output.py @@ -0,0 +1,34 @@ +from ase.build import bulk +import unittest +from pyiron_lammps.output import remap_indices + + +class TestLammpsOutput(unittest.TestCase): + def test_remap_indices(self): + structure = bulk("Ag", cubic=True).repeat([2,2,2]) + structure.set_chemical_symbols([ + "Ag", "Ag", "Ag", "Ag", "Au", "Au", "Au", "Au", "Cu", "Cu", "Cu", "Cu", "Ag", "Ag", "Ag", "Ag", + "Ag", "Ag", "Ag", "Ag", "Au", "Au", "Au", "Au", "Cu", "Cu", "Cu", "Cu", "Ag", "Ag", "Ag", "Ag", + ]) + ind = remap_indices( + lammps_indices=[ + 1, 1, 1, 1, 5, 5, 5, 5, 3, 3, 3, 3, 1, 1, 1, 1, + 1, 1, 1, 1, 5, 5, 5, 5, 3, 3, 3, 3, 1, 1, 1, 1, + ], + potential_elements=["Ag", "Al", "Cu", "Co", "Au"], + structure=structure + ) + self.assertEqual(sum(ind), 24) + ind = remap_indices( + lammps_indices=[2, 2, 2, 2], + potential_elements=["Ag", "Al", "Cu", "Co", "Au"], + structure=structure + ) + self.assertEqual(sum(ind), 8) + ind = remap_indices( + lammps_indices=[2, 2, 2, 2], + potential_elements=["Au", "Ag", "Cu"], + structure=structure + ) + self.assertEqual(sum(ind), 0) + From d80ebe2161257faaf5f24e6d3d721204cd2b9d23 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 23 Feb 2025 20:39:24 +0000 Subject: [PATCH 2/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_output.py | 83 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/tests/test_output.py b/tests/test_output.py index 8660da4b..1cb6c8a6 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -5,30 +5,91 @@ class TestLammpsOutput(unittest.TestCase): def test_remap_indices(self): - structure = bulk("Ag", cubic=True).repeat([2,2,2]) - structure.set_chemical_symbols([ - "Ag", "Ag", "Ag", "Ag", "Au", "Au", "Au", "Au", "Cu", "Cu", "Cu", "Cu", "Ag", "Ag", "Ag", "Ag", - "Ag", "Ag", "Ag", "Ag", "Au", "Au", "Au", "Au", "Cu", "Cu", "Cu", "Cu", "Ag", "Ag", "Ag", "Ag", - ]) + structure = bulk("Ag", cubic=True).repeat([2, 2, 2]) + structure.set_chemical_symbols( + [ + "Ag", + "Ag", + "Ag", + "Ag", + "Au", + "Au", + "Au", + "Au", + "Cu", + "Cu", + "Cu", + "Cu", + "Ag", + "Ag", + "Ag", + "Ag", + "Ag", + "Ag", + "Ag", + "Ag", + "Au", + "Au", + "Au", + "Au", + "Cu", + "Cu", + "Cu", + "Cu", + "Ag", + "Ag", + "Ag", + "Ag", + ] + ) ind = remap_indices( lammps_indices=[ - 1, 1, 1, 1, 5, 5, 5, 5, 3, 3, 3, 3, 1, 1, 1, 1, - 1, 1, 1, 1, 5, 5, 5, 5, 3, 3, 3, 3, 1, 1, 1, 1, + 1, + 1, + 1, + 1, + 5, + 5, + 5, + 5, + 3, + 3, + 3, + 3, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 5, + 5, + 5, + 5, + 3, + 3, + 3, + 3, + 1, + 1, + 1, + 1, ], potential_elements=["Ag", "Al", "Cu", "Co", "Au"], - structure=structure + structure=structure, ) self.assertEqual(sum(ind), 24) ind = remap_indices( lammps_indices=[2, 2, 2, 2], potential_elements=["Ag", "Al", "Cu", "Co", "Au"], - structure=structure + structure=structure, ) self.assertEqual(sum(ind), 8) ind = remap_indices( lammps_indices=[2, 2, 2, 2], potential_elements=["Au", "Ag", "Cu"], - structure=structure + structure=structure, ) self.assertEqual(sum(ind), 0) - From 8d329b8fd3a0c0efd879e1a3b634eb7ca4aa1ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Mon, 24 Feb 2025 08:58:39 +0100 Subject: [PATCH 3/8] Add tests for chemical diversity --- tests/static/dump_chemical/dump_AlH.out | 13 ++++++++ tests/static/dump_chemical/dump_NiAlH.out | 13 ++++++++ tests/static/dump_chemical/dump_NiH.out | 13 ++++++++ tests/test_output.py | 39 ++++++++++++++++++++++- 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 tests/static/dump_chemical/dump_AlH.out create mode 100644 tests/static/dump_chemical/dump_NiAlH.out create mode 100644 tests/static/dump_chemical/dump_NiH.out diff --git a/tests/static/dump_chemical/dump_AlH.out b/tests/static/dump_chemical/dump_AlH.out new file mode 100644 index 00000000..72f01af6 --- /dev/null +++ b/tests/static/dump_chemical/dump_AlH.out @@ -0,0 +1,13 @@ +ITEM: TIMESTEP +0 +ITEM: NUMBER OF ATOMS +4 +ITEM: BOX BOUNDS pp pp pp +0.0000000000000000e+00 4.0499999999999998e+00 +0.0000000000000000e+00 4.0499999999999998e+00 +0.0000000000000000e+00 4.0499999999999998e+00 +ITEM: ATOMS id type xsu ysu zsu fx fy fz vx vy vz +1 3 0 0 0 -2.77555756156289e-17 -1.38777878078145e-17 0 0 0 0 +2 2 0 0.5 0.5 0 6.93889390390723e-17 -1.11022302462516e-16 0 0 0 +3 2 0.5 0 0.5 0 6.93889390390723e-18 -8.32667268468867e-17 0 0 0 +4 2 0.5 0.5 0 -5.55111512312578e-17 -1.66533453693773e-16 6.93889390390723e-17 0 0 0 diff --git a/tests/static/dump_chemical/dump_NiAlH.out b/tests/static/dump_chemical/dump_NiAlH.out new file mode 100644 index 00000000..09572516 --- /dev/null +++ b/tests/static/dump_chemical/dump_NiAlH.out @@ -0,0 +1,13 @@ +ITEM: TIMESTEP +0 +ITEM: NUMBER OF ATOMS +4 +ITEM: BOX BOUNDS pp pp pp +0.0000000000000000e+00 4.0499999999999998e+00 +0.0000000000000000e+00 4.0499999999999998e+00 +0.0000000000000000e+00 4.0499999999999998e+00 +ITEM: ATOMS id type xsu ysu zsu fx fy fz vx vy vz +1 2 0 0 0 0 6.93889390390723e-18 2.77555756156289e-17 0 0 0 +2 2 0 0.5 0.5 5.55111512312578e-17 2.77555756156289e-17 -5.55111512312578e-17 0 0 0 +3 3 0.5 0 0.5 0 6.93889390390723e-18 6.07153216591882e-18 0 0 0 +4 1 0.5 0.5 0 2.77555756156289e-17 -8.32667268468867e-17 -5.55111512312578e-17 0 0 0 diff --git a/tests/static/dump_chemical/dump_NiH.out b/tests/static/dump_chemical/dump_NiH.out new file mode 100644 index 00000000..17dbe1af --- /dev/null +++ b/tests/static/dump_chemical/dump_NiH.out @@ -0,0 +1,13 @@ +ITEM: TIMESTEP +0 +ITEM: NUMBER OF ATOMS +4 +ITEM: BOX BOUNDS pp pp pp +0.0000000000000000e+00 3.5200000000000000e+00 +0.0000000000000000e+00 3.5200000000000000e+00 +0.0000000000000000e+00 3.5200000000000000e+00 +ITEM: ATOMS id type xsu ysu zsu fx fy fz vx vy vz +1 3 0 0 0 2.77555756156289e-17 -1.73472347597681e-18 0 0 0 0 +2 1 0 0.5 0.5 -2.77555756156289e-17 -2.4980018054066e-16 1.11022302462516e-16 0 0 0 +3 1 0.5 0 0.5 -1.11022302462516e-16 -9.0205620750794e-17 8.32667268468867e-17 0 0 0 +4 1 0.5 0.5 0 1.11022302462516e-16 2.77555756156289e-16 -1.2490009027033e-16 0 0 0 diff --git a/tests/test_output.py b/tests/test_output.py index 8660da4b..9ae81f8c 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -1,9 +1,15 @@ from ase.build import bulk +import numpy as np +import os import unittest -from pyiron_lammps.output import remap_indices +from pyiron_lammps.output import remap_indices, _parse_dump +from pyiron_lammps.structure import UnfoldingPrism class TestLammpsOutput(unittest.TestCase): + def setUp(self): + self.static_folder = os.path.abspath(os.path.join(__file__, "..", "static")) + def test_remap_indices(self): structure = bulk("Ag", cubic=True).repeat([2,2,2]) structure.set_chemical_symbols([ @@ -32,3 +38,34 @@ def test_remap_indices(self): ) self.assertEqual(sum(ind), 0) + def test_dump_chemical(self): + test_folder = os.path.join(self.static_folder, "dump_chemical") + structure_ni = bulk("Ni", cubic=True) + structure_al = bulk("Ni", cubic=True) + structure_all = bulk("Ni", cubic=True) + structure_ni.set_chemical_symbols(["H", "Ni", "Ni", "Ni"]) + structure_al.set_chemical_symbols(["H", "Al", "Al", "Al"]) + structure_all.set_chemical_symbols(["Al", "Al", "Ni", "H"]) + for l, s, ind in zip( + ["dump_NiH.out", "dump_AlH.out", "dump_NiAlH.out"], + [structure_ni, structure_al, structure_all], + [np.array([0, 1, 1, 1]), np.array([1, 0, 0, 0]), np.array([0, 0, 1, 2])] + ): + output = _parse_dump( + dump_h5_full_file_name="", + dump_out_full_file_name=os.path.join(test_folder, l), + prism=UnfoldingPrism(s.cell), + structure=s, + potential_elements=["Ni", "Al", "H"], + ) + self.assertEqual(output["steps"], [0]) + self.assertEqual(output["natoms"], [4]) + self.assertTrue(np.all(np.equal(output['indices'][0], ind))) + self.assertTrue(np.all(np.isclose( + output["forces"], + [np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])] + ))) + self.assertTrue(np.all(np.isclose( + output["velocities"], + [np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])] + ))) From f8935eaed98deb3ef4771bf9aac0320988efbf76 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 08:02:34 +0000 Subject: [PATCH 4/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_output.py | 46 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/tests/test_output.py b/tests/test_output.py index 45f694b4..32169a0c 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -111,7 +111,7 @@ def test_dump_chemical(self): for l, s, ind in zip( ["dump_NiH.out", "dump_AlH.out", "dump_NiAlH.out"], [structure_ni, structure_al, structure_all], - [np.array([0, 1, 1, 1]), np.array([1, 0, 0, 0]), np.array([0, 0, 1, 2])] + [np.array([0, 1, 1, 1]), np.array([1, 0, 0, 0]), np.array([0, 0, 1, 2])], ): output = _parse_dump( dump_h5_full_file_name="", @@ -122,12 +122,38 @@ def test_dump_chemical(self): ) self.assertEqual(output["steps"], [0]) self.assertEqual(output["natoms"], [4]) - self.assertTrue(np.all(np.equal(output['indices'][0], ind))) - self.assertTrue(np.all(np.isclose( - output["forces"], - [np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])] - ))) - self.assertTrue(np.all(np.isclose( - output["velocities"], - [np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])] - ))) + self.assertTrue(np.all(np.equal(output["indices"][0], ind))) + self.assertTrue( + np.all( + np.isclose( + output["forces"], + [ + np.array( + [ + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + ] + ) + ], + ) + ) + ) + self.assertTrue( + np.all( + np.isclose( + output["velocities"], + [ + np.array( + [ + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + ] + ) + ], + ) + ) + ) From 477a8b8c804dc53a9133026c6d41b77694fc54ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Mon, 24 Feb 2025 09:08:17 +0100 Subject: [PATCH 5/8] try fix --- pyiron_lammps/structure.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyiron_lammps/structure.py b/pyiron_lammps/structure.py index 5f5f72a0..94732601 100644 --- a/pyiron_lammps/structure.py +++ b/pyiron_lammps/structure.py @@ -169,10 +169,10 @@ def pos_to_lammps(self, position): return tuple([x for x in np.dot(position, self.R)]) def f2qdec(self, f): - return dec.Decimal(repr(f)).quantize(self.car_prec, dec.ROUND_DOWN) + return dec.Decimal(str(f)).quantize(self.car_prec, dec.ROUND_DOWN) def f2s(self, f): - return str(dec.Decimal(repr(f)).quantize(self.car_prec, dec.ROUND_HALF_EVEN)) + return str(dec.Decimal(str(f)).quantize(self.car_prec, dec.ROUND_HALF_EVEN)) def get_lammps_prism_str(self): """Return a tuple of strings""" From a7449811a9c274b152d6766f43114740760df274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Mon, 24 Feb 2025 09:15:29 +0100 Subject: [PATCH 6/8] refactor --- pyiron_lammps/output.py | 165 +++++++++++++++++++++------------------- tests/test_output.py | 9 ++- 2 files changed, 90 insertions(+), 84 deletions(-) diff --git a/pyiron_lammps/output.py b/pyiron_lammps/output.py index d6599cce..d3b522f1 100644 --- a/pyiron_lammps/output.py +++ b/pyiron_lammps/output.py @@ -31,6 +31,46 @@ class DumpData: computes: Dict = field(default_factory=lambda: {}) +def remap_indices_ase( + lammps_indices: Union[np.ndarray, List], + potential_elements: Union[np.ndarray, List], + structure: Atoms, +) -> np.ndarray: + """ + Give the Lammps-dumped indices, re-maps these back onto the structure's indices to preserve the species. + + The issue is that for an N-element potential, Lammps dumps the chemical index from 1 to N based on the order + that these species are written in the Lammps input file. But the indices for a given structure are based on the + order in which chemical species were added to that structure, and run from 0 up to the number of species + currently in that structure. Therefore we need to be a little careful with mapping. + + Args: + lammps_indices (numpy.ndarray/list): The Lammps-dumped integers. + potential_elements (numpy.ndarray/list): + structure (pyiron_atomistics.atomistics.structure.Atoms): + + Returns: + numpy.ndarray: Those integers mapped onto the structure. + """ + lammps_symbol_order = np.array(potential_elements) + + # Create a map between the lammps indices and structure indices to preserve species + structure_symbol_order = np.unique(structure.get_chemical_symbols()) + map_ = np.array( + [ + int(np.argwhere(lammps_symbol_order == symbol)[0]) + 1 + for symbol in structure_symbol_order + ] + ) + + structure_indices = np.array(lammps_indices) + for i_struct, i_lammps in enumerate(map_): + np.place(structure_indices, lammps_indices == i_lammps, i_struct) + # TODO: Vectorize this for-loop for computational efficiency + + return structure_indices + + def parse_lammps_output( working_directory: str, structure: Atoms, @@ -40,6 +80,7 @@ def parse_lammps_output( dump_h5_file_name: str = "dump.h5", dump_out_file_name: str = "dump.out", log_lammps_file_name: str = "log.lammps", + remap_indices_funct: callable = remap_indices_ase, ) -> Dict: if prism is None: prism = UnfoldingPrism(structure.cell) @@ -49,6 +90,7 @@ def parse_lammps_output( prism=prism, structure=structure, potential_elements=potential_elements, + remap_indices_funct=remap_indices_funct, ) generic_keys_lst, pressure_dict, df = _parse_log( @@ -94,12 +136,52 @@ def parse_lammps_output( return hdf_output +def to_amat(l_list: Union[np.ndarray, List]) -> List: + lst = np.reshape(l_list, -1) + if len(lst) == 9: + ( + xlo_bound, + xhi_bound, + xy, + ylo_bound, + yhi_bound, + xz, + zlo_bound, + zhi_bound, + yz, + ) = lst + + elif len(lst) == 6: + xlo_bound, xhi_bound, ylo_bound, yhi_bound, zlo_bound, zhi_bound = lst + xy, xz, yz = 0.0, 0.0, 0.0 + else: + raise ValueError("This format for amat not yet implemented: " + str(len(lst))) + + # > xhi_bound - xlo_bound = xhi -xlo + MAX(0.0, xy, xz, xy + xz) - MIN(0.0, xy, xz, xy + xz) + # > xhili = xhi -xlo = xhi_bound - xlo_bound - MAX(0.0, xy, xz, xy + xz) + MIN(0.0, xy, xz, xy + xz) + xhilo = ( + (xhi_bound - xlo_bound) + - max([0.0, xy, xz, xy + xz]) + + min([0.0, xy, xz, xy + xz]) + ) + + # > yhilo = yhi -ylo = yhi_bound -ylo_bound - MAX(0.0, yz) + MIN(0.0, yz) + yhilo = (yhi_bound - ylo_bound) - max([0.0, yz]) + min([0.0, yz]) + + # > zhi - zlo = zhi_bound- zlo_bound + zhilo = zhi_bound - zlo_bound + + cell = [[xhilo, 0, 0], [xy, yhilo, 0], [xz, yz, zhilo]] + return cell + + def _parse_dump( dump_h5_full_file_name: str, dump_out_full_file_name: str, prism: UnfoldingPrism, structure: Atoms, potential_elements: Union[np.ndarray, List], + remap_indices_funct: callable = remap_indices_ase, ) -> Dict: if os.path.isfile(dump_h5_full_file_name): return _collect_dump_from_h5md( @@ -112,6 +194,7 @@ def _parse_dump( prism=prism, structure=structure, potential_elements=potential_elements, + remap_indices_funct=remap_indices_funct, ) else: return {} @@ -144,6 +227,7 @@ def _collect_dump_from_text( prism: UnfoldingPrism, structure: Atoms, potential_elements: Union[np.ndarray, List], + remap_indices_funct: callable = remap_indices_ase ) -> Dict: """ general purpose routine to extract static from a lammps dump file @@ -190,7 +274,7 @@ def _collect_dump_from_text( df.sort_values(by="id", ignore_index=True, inplace=True) # Coordinate transform lammps->pyiron dump.indices.append( - remap_indices( + remap_indices_funct( lammps_indices=df["type"].array.astype(int), potential_elements=potential_elements, structure=structure, @@ -450,82 +534,3 @@ def _check_ortho_prism( boolean: True or False """ return np.isclose(prism.R, np.eye(3), rtol=rtol, atol=atol).all() - - -def to_amat(l_list: Union[np.ndarray, List]) -> List: - lst = np.reshape(l_list, -1) - if len(lst) == 9: - ( - xlo_bound, - xhi_bound, - xy, - ylo_bound, - yhi_bound, - xz, - zlo_bound, - zhi_bound, - yz, - ) = lst - - elif len(lst) == 6: - xlo_bound, xhi_bound, ylo_bound, yhi_bound, zlo_bound, zhi_bound = lst - xy, xz, yz = 0.0, 0.0, 0.0 - else: - raise ValueError("This format for amat not yet implemented: " + str(len(lst))) - - # > xhi_bound - xlo_bound = xhi -xlo + MAX(0.0, xy, xz, xy + xz) - MIN(0.0, xy, xz, xy + xz) - # > xhili = xhi -xlo = xhi_bound - xlo_bound - MAX(0.0, xy, xz, xy + xz) + MIN(0.0, xy, xz, xy + xz) - xhilo = ( - (xhi_bound - xlo_bound) - - max([0.0, xy, xz, xy + xz]) - + min([0.0, xy, xz, xy + xz]) - ) - - # > yhilo = yhi -ylo = yhi_bound -ylo_bound - MAX(0.0, yz) + MIN(0.0, yz) - yhilo = (yhi_bound - ylo_bound) - max([0.0, yz]) + min([0.0, yz]) - - # > zhi - zlo = zhi_bound- zlo_bound - zhilo = zhi_bound - zlo_bound - - cell = [[xhilo, 0, 0], [xy, yhilo, 0], [xz, yz, zhilo]] - return cell - - -def remap_indices( - lammps_indices: Union[np.ndarray, List], - potential_elements: Union[np.ndarray, List], - structure: Atoms, -) -> np.ndarray: - """ - Give the Lammps-dumped indices, re-maps these back onto the structure's indices to preserve the species. - - The issue is that for an N-element potential, Lammps dumps the chemical index from 1 to N based on the order - that these species are written in the Lammps input file. But the indices for a given structure are based on the - order in which chemical species were added to that structure, and run from 0 up to the number of species - currently in that structure. Therefore we need to be a little careful with mapping. - - Args: - lammps_indices (numpy.ndarray/list): The Lammps-dumped integers. - potential_elements (numpy.ndarray/list): - structure (pyiron_atomistics.atomistics.structure.Atoms): - - Returns: - numpy.ndarray: Those integers mapped onto the structure. - """ - lammps_symbol_order = np.array(potential_elements) - - # Create a map between the lammps indices and structure indices to preserve species - structure_symbol_order = np.unique(structure.get_chemical_symbols()) - map_ = np.array( - [ - int(np.argwhere(lammps_symbol_order == symbol)[0]) + 1 - for symbol in structure_symbol_order - ] - ) - - structure_indices = np.array(lammps_indices) - for i_struct, i_lammps in enumerate(map_): - np.place(structure_indices, lammps_indices == i_lammps, i_struct) - # TODO: Vectorize this for-loop for computational efficiency - - return structure_indices diff --git a/tests/test_output.py b/tests/test_output.py index 32169a0c..7b5c47db 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -2,7 +2,7 @@ import numpy as np import os import unittest -from pyiron_lammps.output import remap_indices, _parse_dump +from pyiron_lammps.output import remap_indices_ase, _parse_dump from pyiron_lammps.structure import UnfoldingPrism @@ -48,7 +48,7 @@ def test_remap_indices(self): "Ag", ] ) - ind = remap_indices( + ind = remap_indices_ase( lammps_indices=[ 1, 1, @@ -87,13 +87,13 @@ def test_remap_indices(self): structure=structure, ) self.assertEqual(sum(ind), 24) - ind = remap_indices( + ind = remap_indices_ase( lammps_indices=[2, 2, 2, 2], potential_elements=["Ag", "Al", "Cu", "Co", "Au"], structure=structure, ) self.assertEqual(sum(ind), 8) - ind = remap_indices( + ind = remap_indices_ase( lammps_indices=[2, 2, 2, 2], potential_elements=["Au", "Ag", "Cu"], structure=structure, @@ -119,6 +119,7 @@ def test_dump_chemical(self): prism=UnfoldingPrism(s.cell), structure=s, potential_elements=["Ni", "Al", "H"], + remap_indices_funct=remap_indices_ase, ) self.assertEqual(output["steps"], [0]) self.assertEqual(output["natoms"], [4]) From 3173f772f60b455e40b8c277406edfb4c894b49d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 08:15:41 +0000 Subject: [PATCH 7/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyiron_lammps/output.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyiron_lammps/output.py b/pyiron_lammps/output.py index d3b522f1..29f74fe2 100644 --- a/pyiron_lammps/output.py +++ b/pyiron_lammps/output.py @@ -227,7 +227,7 @@ def _collect_dump_from_text( prism: UnfoldingPrism, structure: Atoms, potential_elements: Union[np.ndarray, List], - remap_indices_funct: callable = remap_indices_ase + remap_indices_funct: callable = remap_indices_ase, ) -> Dict: """ general purpose routine to extract static from a lammps dump file From cba36291861d136dd102dc3ee04b03802379a710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Mon, 24 Feb 2025 09:18:33 +0100 Subject: [PATCH 8/8] exclude version from coverage --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 8aee68d7..604280b5 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -64,7 +64,7 @@ jobs: run: | pip install versioneer[toml]==0.29 pip install . --no-deps --no-build-isolation - coverage run --omit="atomistics/_version.py,tests/*" -m unittest discover tests + coverage run --omit="pyiron_lammps/_version.py,tests/*" -m unittest discover tests coverage xml - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v5