diff --git a/docs/packages/matscipy.yaml b/docs/packages/matscipy.yaml index 84d81baef9c..effcfa8bcd7 100644 --- a/docs/packages/matscipy.yaml +++ b/docs/packages/matscipy.yaml @@ -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 diff --git a/patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch b/patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch new file mode 100644 index 00000000000..2095d3a1252 --- /dev/null +++ b/patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +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 +--- +--- 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 --- # diff --git a/patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch b/patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch new file mode 100644 index 00000000000..e65d73032a3 --- /dev/null +++ b/patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +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 +--- +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 diff --git a/patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch b/patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch new file mode 100644 index 00000000000..930360d3d63 --- /dev/null +++ b/patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch @@ -0,0 +1,88 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +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 +--- +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