Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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 docs/packages/matscipy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ versions:
- filename: matscipy-1.2.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl
sha256: edec7c83ef02d487442a94a3b4ad5f2f180d4f98ae927c6628eb0b54e2b6a8da
requires-python: '>=3.9.0'
- version: 1.3.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Thu, 01 Oct 2026 00:00:00 +0000
Subject: [PATCH] eam/io: index 1-element arrays before int()/float()

write_eam's "eam" (DYNAMO funcfl) branch calls int(atomic_numbers) and
float(atomic_masses)/float(lattice_parameters) directly on the
EAMParameters fields, which read_eam builds as 1-element numpy arrays
(np.array((int(words[0]),), dtype=int), etc.), not scalars - the
function's own "# FIXME: atomic numbers etc are now arrays, and not
scalars" comment already says as much. NumPy 2.x turned the implicit
conversion of a non-0-d array into a hard TypeError: "only
0-dimensional arrays can be converted to Python scalars", so
test_eam_io.py::test_eam_read_write's round-trip through this branch
fails outright. Indexing [0] before the int()/float() calls is what
the FIXME already describes as the fix; upstream made the same change
in 255201ab (released in 1.3.0).

Upstream-Status: Backport [https://github.com/libAtoms/matscipy/commit/255201aba4d827bb97dead8964c80e7276161603]

Signed-off-by: Ludovic Henry <git@ludovic.dev>
---
--- a/matscipy/calculators/eam/io.py
+++ b/matscipy/calculators/eam/io.py
@@ -548,7 +548,7 @@
# parameters unpacked
# FIXME: atomic numbers etc are now arrays, and not scalars
crystal_structures_str = ' '.join(s for s in crystal_structures)
- atline = f"{int(atomic_numbers)} {float(atomic_masses)} {float(lattice_parameters)} {crystal_structures_str}"
+ atline = f"{int(atomic_numbers[0])} {float(atomic_masses[0])} {float(lattice_parameters[0])} {crystal_structures_str}"
parameterline = f'{int(Nrho)}\t{float(drho):.16e}\t{int(Nr)}\t{float(dr):.16e}\t{float(cutoff):.10e}'
potheader = f"# EAM potential from : # {source} \n {atline} \n {parameterline}"
# --- Writing new EAM alloy pot file --- #
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Thu, 01 Oct 2026 00:00:00 +0000
Subject: [PATCH] cauchy_born: drop the removed sqrtm(disp=) keyword

SciPy 1.18 removed the deprecated disp= keyword of scipy.linalg.sqrtm,
so CubicCauchyBorn's two sqrtm(Usqr, disp=True) calls raise
"TypeError: sqrtm() got an unexpected keyword argument 'disp'" and all
nine test_cauchy_born_corrector.py::TestPredictCauchyBornShifts tests
fail. disp=True was the default, so sqrtm(Usqr) is unchanged on older
SciPy. Upstream made the same change in 75f077ff (released in 1.3.0).

Upstream-Status: Backport [https://github.com/libAtoms/matscipy/commit/75f077ff7de629fc65814b760d6ebd225b630d64]

Signed-off-by: Ludovic Henry <git@ludovic.dev>
---
diff --git a/matscipy/cauchy_born.py b/matscipy/cauchy_born.py
index c84a2534..ad973424 100644
--- a/matscipy/cauchy_born.py
+++ b/matscipy/cauchy_born.py
@@ -268,7 +268,7 @@ class CubicCauchyBorn:
# get U^2
Usqr = 2 * E + np.eye(3)
# square root matrix to get U
- U = sqrtm(Usqr, disp=True)
+ U = sqrtm(Usqr)

# this is just the symmetric stretch tensor, exactly what we need.
x = U
@@ -1330,7 +1330,7 @@ class CubicCauchyBorn:
# get U^2
Usqr = 2 * E + np.eye(3)
# square root matrix
- U = sqrtm(Usqr, disp=True)
+ U = sqrtm(Usqr)

# this is just the symmetric stretch tensor, exactly what we need.
x = U
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Thu, 01 Oct 2026 00:00:00 +0000
Subject: [PATCH] molecules, io/lammpsdata: replace ndarray.resize for Python 3.14

From NumPy 2.4 on, ndarray.resize(refcheck=True) on Python >= 3.14 uses
PyUnstable_Object_IsUniquelyReferenced, which an attribute-held array
never satisfies, so Molecules.__init__ and LAMMPSData's setter/reader
raise "ValueError: cannot resize an array that may be referenced by
another object" on cp314 only (test_newmb.py, test_neighbours.py,
test_io.py collection errors, test_manybody_molecules.py setup errors).
Upstream replaced every such resize with a fresh np.empty of the same
dtype in libAtoms/matscipy#312 (commits 1b006eb4 and 3a1ec1dc, released
in 1.3.0); this is those two hunks unchanged.

Upstream-Status: Backport [https://github.com/libAtoms/matscipy/pull/312]

Signed-off-by: Ludovic Henry <git@ludovic.dev>
---
diff --git a/matscipy/io/lammpsdata.py b/matscipy/io/lammpsdata.py
index 4525a786..e7200f0a 100644
--- a/matscipy/io/lammpsdata.py
+++ b/matscipy/io/lammpsdata.py
@@ -193,10 +193,15 @@ class LAMMPSData:
"""Set data component."""
if name in self._type_names:
name = self._type_names[name]
- self.__data[name].resize(len(value))
+ old = self.__data[name]
+ new_arr = np.empty(len(value), dtype=self._dtypes[name])
+ n = min(len(old), len(value))
+ if n > 0:
+ new_arr[:n] = old[:n]
+ self.__data[name] = new_arr
self.__data[name]['type'] = value
elif name in self._data_names:
- self.__data[name].resize(len(value))
+ self.__data[name] = np.empty(len(value), dtype=self._dtypes[name])
data = self.__data[name]
try:
data[data.dtype.names[-1]] = np.array(value)
@@ -309,16 +314,15 @@ class LAMMPSData:
for linum, line in enumerate(fd):
if 'Masses' in line:
ntypes = type_counts['atom types']
- self['masses'].resize(ntypes)
- self['masses'][:] = \
+ self.__data['masses'] = \
np.genfromtxt(fd, skip_header=1,
- max_rows=ntypes, usecols=(1,))
+ max_rows=ntypes, usecols=(1,), dtype=self._dtypes['masses'])

else:
for label in self._data_names:
if self.__headers[label] in line:
nlines = data_counts[label]
- self[label].resize(nlines)
+ self.__data[label] = np.empty(nlines, dtype=self._dtypes[label])
dtype = self[label].dtype

raw_dtype = np.dtype([('num', np.int32)] + [
diff --git a/matscipy/molecules.py b/matscipy/molecules.py
index 4657da62..d9a88996 100644
--- a/matscipy/molecules.py
+++ b/matscipy/molecules.py
@@ -72,19 +72,19 @@ class Molecules:
self.__dict__[data] = np.array([], dtype=dtype)

if bonds_connectivity is not None:
- self.bonds.resize(len(bonds_connectivity))
+ self.bonds = np.empty(len(bonds_connectivity), dtype=self._dtypes["bonds"])
self.bonds["atoms"][:] = bonds_connectivity
self.bonds["type"][:] = bonds_types \
if bonds_types is not None else default_type

if angles_connectivity is not None:
- self.angles.resize(len(angles_connectivity))
+ self.angles = np.empty(len(angles_connectivity), dtype=self._dtypes["angles"])
self.angles["atoms"][:] = angles_connectivity
self.angles["type"][:] = angles_types \
if angles_types is not None else default_type

if dihedrals_connectivity is not None:
- self.dihedrals.resize(len(dihedrals_connectivity))
+ self.dihedrals = np.empty(len(dihedrals_connectivity), dtype=self._dtypes["dihedrals"])
self.dihedrals["atoms"][:] = dihedrals_connectivity
self.dihedrals["type"][:] = dihedrals_types \
if dihedrals_types is not None else default_type
Loading