Skip to content

Commit b76ebb8

Browse files
authored
Deprecate Structure.ntypesp replaced by Structure.n_elems (#3562)
* deprecate Structure.ntypesp replaced by Structure.n_elems * fix structure_to_abivars() for non-hexagonal structures not calling structure.lattice.is_hexagonal()
1 parent 7da8d0a commit b76ebb8

File tree

9 files changed

+45
-40
lines changed

9 files changed

+45
-40
lines changed

pymatgen/core/lattice.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,7 @@ def is_hexagonal(self, hex_angle_tol: float = 5, hex_length_tol: float = 0.01) -
15171517
angles = self.angles
15181518
right_angles = [i for i in range(3) if abs(angles[i] - 90) < hex_angle_tol]
15191519
hex_angles = [
1520-
i for i in range(3) if abs(angles[i] - 60) < hex_angle_tol or abs(angles[i] - 120) < hex_angle_tol
1520+
idx for idx in range(3) if abs(angles[idx] - 60) < hex_angle_tol or abs(angles[idx] - 120) < hex_angle_tol
15211521
]
15221522

15231523
return (

pymatgen/core/structure.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,16 @@ def species_and_occu(self) -> list[Composition]:
262262
return [site.species for site in self]
263263

264264
@property
265+
@deprecated(message="Use n_type_sp instead.")
265266
def ntypesp(self) -> int:
266267
"""Number of types of atoms."""
267268
return len(self.types_of_species)
268269

270+
@property
271+
def n_elems(self) -> int:
272+
"""Number of types of atoms."""
273+
return len(self.types_of_species)
274+
269275
@property
270276
def types_of_species(self) -> tuple[Element | Species | DummySpecies]:
271277
"""List of types of specie."""

pymatgen/io/abinit/abiobjects.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -185,16 +185,17 @@ def species_by_znucl(structure: Structure) -> list[Species]:
185185
return types
186186

187187

188-
def structure_to_abivars(structure, enforce_znucl=None, enforce_typat=None, **kwargs):
188+
def structure_to_abivars(
189+
structure: Structure, enforce_znucl: list | None = None, enforce_typat: list | None = None, **kwargs
190+
):
189191
"""
190192
Receives a structure and returns a dictionary with ABINIT variables.
191193
192194
Args:
193-
enforce_znucl: List of ntypat entries with the value of Z for each type of atom.
194-
Used to change the default ordering.
195-
enforce_typat: List with natom entries with the type index.
196-
Fortran conventions: start to count from 1.
197-
Used to change the default ordering.
195+
enforce_znucl (list): ntypat entries with the value of Z for each type of atom.
196+
Used to change the default ordering. Defaults to None.
197+
enforce_typat (list): natom entries with the type index.
198+
Fortran conventions: start to count from 1. Used to change the default ordering.
198199
"""
199200
if not structure.is_ordered:
200201
raise ValueError(
@@ -205,7 +206,6 @@ def structure_to_abivars(structure, enforce_znucl=None, enforce_typat=None, **kw
205206
)
206207

207208
n_atoms = len(structure)
208-
n_types_atom = structure.ntypesp
209209
enforce_order = False
210210

211211
if enforce_znucl is not None or enforce_typat is not None:
@@ -219,19 +219,21 @@ def structure_to_abivars(structure, enforce_znucl=None, enforce_typat=None, **kw
219219
f"enforce_typat contains {len(enforce_typat)} entries while it should be {len(structure)=}"
220220
)
221221

222-
if len(enforce_znucl) != n_types_atom:
223-
raise ValueError(f"enforce_znucl contains {len(enforce_znucl)} entries while it should be {n_types_atom=}")
222+
if len(enforce_znucl) != structure.n_elems:
223+
raise ValueError(
224+
f"enforce_znucl contains {len(enforce_znucl)} entries while it should be {structure.n_elems=}"
225+
)
224226

225-
if not enforce_order:
227+
if enforce_order:
228+
znucl_type = enforce_znucl
229+
typat = enforce_typat or [] # or [] added for mypy
230+
else:
226231
types_of_specie = species_by_znucl(structure)
227232

228233
znucl_type = [specie.number for specie in types_of_specie]
229234
typat = np.zeros(n_atoms, int)
230235
for atm_idx, site in enumerate(structure):
231236
typat[atm_idx] = types_of_specie.index(site.specie) + 1
232-
else:
233-
znucl_type = enforce_znucl
234-
typat = enforce_typat
235237

236238
r_prim = ArrayWithUnit(structure.lattice.matrix, "ang").to("bohr")
237239
ang_deg = structure.lattice.angles
@@ -245,19 +247,19 @@ def structure_to_abivars(structure, enforce_znucl=None, enforce_typat=None, **kw
245247
# Info on atoms.
246248
dct = {
247249
"natom": n_atoms,
248-
"ntypat": n_types_atom,
250+
"ntypat": structure.n_elems,
249251
"typat": typat,
250252
"znucl": znucl_type,
251253
"xred": x_red,
252254
"properties": structure.properties,
253255
}
254256

255257
# Add info on the lattice.
256-
# Should we use (rprim, acell) or (angdeg, acell) to specify the lattice?
258+
# Should we use (rprim, acell) or (ang_deg, acell) to specify the lattice?
257259
geo_mode = kwargs.pop("geomode", "rprim")
258260
if geo_mode == "automatic":
259261
geo_mode = "rprim"
260-
if structure.lattice.is_hexagonal: # or structure.lattice.is_rhombohedral
262+
if structure.lattice.is_hexagonal(): # or structure.lattice.is_rhombohedral
261263
geo_mode = "angdeg"
262264
ang_deg = structure.lattice.angles
263265
# Here one could polish a bit the numerical values if they are not exact.
@@ -281,15 +283,15 @@ def structure_to_abivars(structure, enforce_znucl=None, enforce_typat=None, **kw
281283
return dct
282284

283285

284-
def contract(s):
286+
def contract(string):
285287
"""
286288
assert contract("1 1 1 2 2 3") == "3*1 2*2 1*3"
287289
assert contract("1 1 3 2 3") == "2*1 1*3 1*2 1*3"
288290
"""
289-
if not s:
290-
return s
291+
if not string:
292+
return string
291293

292-
tokens = s.split()
294+
tokens = string.split()
293295
old = tokens[0]
294296
count = [[1, old]]
295297

pymatgen/io/cp2k/sets.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,12 +1230,9 @@ def create_subsys(self, structure: Structure | Molecule) -> None:
12301230
if isinstance(structure, Structure):
12311231
subsys.insert(Cell(structure.lattice))
12321232
else:
1233-
x = max(structure.cart_coords[:, 0])
1234-
y = max(structure.cart_coords[:, 1])
1235-
z = max(structure.cart_coords[:, 2])
1236-
x = x if x else 1
1237-
y = y if y else 1
1238-
z = z if z else 1
1233+
x = max(*structure.cart_coords[:, 0], 1)
1234+
y = max(*structure.cart_coords[:, 1], 1)
1235+
z = max(*structure.cart_coords[:, 2], 1)
12391236
cell = Cell(lattice=Lattice([[10 * x, 0, 0], [0, 10 * y, 0], [0, 0, 10 * z]]))
12401237
cell.add(Keyword("PERIODIC", "NONE"))
12411238
subsys.insert(cell)

pymatgen/io/shengbte.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def from_structure(cls, structure: Structure, reciprocal_density: int | None = 5
216216
types = [types_dict[i] + 1 for i in structure.atomic_numbers]
217217

218218
control_dict = {
219-
"nelements": structure.ntypesp,
219+
"nelements": structure.n_elems,
220220
"natoms": len(structure),
221221
"norientations": 0,
222222
"lfactor": 0.1,

pymatgen/io/vasp/sets.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2759,7 +2759,7 @@ def incar(self) -> Incar:
27592759
defaults = {
27602760
"ALGO": "Fast",
27612761
"ISIF": 3,
2762-
"LANGEVIN_GAMMA": [10] * self.structure.ntypesp,
2762+
"LANGEVIN_GAMMA": [10] * self.structure.n_elems,
27632763
"LANGEVIN_GAMMA_L": 1,
27642764
"MDALGO": 3,
27652765
"PMASS": 10,
@@ -2771,7 +2771,7 @@ def incar(self) -> Incar:
27712771
self.user_incar_settings = defaults
27722772

27732773
# Set NPT-AIMD ENCUT = 1.5 * VASP_default
2774-
enmax = [self.potcar[i].keywords["ENMAX"] for i in range(self.structure.ntypesp)]
2774+
enmax = [self.potcar[idx].keywords["ENMAX"] for idx in range(self.structure.n_elems)]
27752775
encut = max(enmax) * 1.5
27762776
self._config_dict["INCAR"]["ENCUT"] = encut
27772777

tests/core/test_structure.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def setUp(self):
7171
self.struct = IStructure(self.lattice, ["Si"] * 2, coords)
7272
assert len(self.struct) == 2, "Wrong number of sites in structure!"
7373
assert self.struct.is_ordered
74-
assert self.struct.ntypesp == 1
74+
assert self.struct.n_elems == 1
7575
coords = [[0, 0, 0], [0.0, 0, 0.0000001]]
7676
with pytest.raises(
7777
StructureError, match=f"sites are less than {self.struct.DISTANCE_TOLERANCE} Angstrom apart"
@@ -967,7 +967,7 @@ def test_append_insert_remove_replace_substitute(self):
967967
struct = self.struct
968968
struct.insert(1, "O", [0.5, 0.5, 0.5])
969969
assert struct.formula == "Si2 O1"
970-
assert struct.ntypesp == 2
970+
assert struct.n_elems == 2
971971
assert struct.symbol_set == ("O", "Si")
972972
assert struct.indices_from_symbol("Si") == (0, 2)
973973
assert struct.indices_from_symbol("O") == (1,)
@@ -977,7 +977,7 @@ def test_append_insert_remove_replace_substitute(self):
977977
assert struct.indices_from_symbol("O") == (1,)
978978
struct.append("N", [0.25, 0.25, 0.25])
979979
assert struct.formula == "Si1 N1 O1"
980-
assert struct.ntypesp == 3
980+
assert struct.n_elems == 3
981981
assert struct.symbol_set == ("N", "O", "Si")
982982
assert struct.indices_from_symbol("Si") == (0,)
983983
assert struct.indices_from_symbol("O") == (1,)
@@ -987,15 +987,15 @@ def test_append_insert_remove_replace_substitute(self):
987987
assert struct.symbol_set == ("Ge", "N", "O")
988988
struct.replace_species({"Ge": "Si"})
989989
assert struct.formula == "Si1 N1 O1"
990-
assert struct.ntypesp == 3
990+
assert struct.n_elems == 3
991991

992992
struct.replace_species({"Si": {"Ge": 0.5, "Si": 0.5}})
993993
assert struct.formula == "Si0.5 Ge0.5 N1 O1"
994994
# this should change the .5Si .5Ge sites to .75Si .25Ge
995995
struct.replace_species({"Ge": {"Ge": 0.5, "Si": 0.5}})
996996
assert struct.formula == "Si0.75 Ge0.25 N1 O1"
997997

998-
assert struct.ntypesp == 4
998+
assert struct.n_elems == 4
999999

10001000
struct.replace_species({"Ge": "Si"})
10011001
struct.substitute(1, "hydroxyl")

tests/io/abinit/test_inputs.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ def test_api(self):
5151

5252
inp = BasicAbinitInput(structure=unit_cell, pseudos=abiref_file("14si.pspnc"))
5353

54-
shiftk = [[0.5, 0.5, 0.5], [0.5, 0.0, 0.0], [0.0, 0.5, 0.0], [0.0, 0.0, 0.5]]
55-
assert_array_equal(calc_shiftk(inp.structure), shiftk)
54+
shift_k = [[0.5, 0.5, 0.5], [0.5, 0.0, 0.0], [0.0, 0.5, 0.0], [0.0, 0.0, 0.5]]
55+
assert_array_equal(calc_shiftk(inp.structure), shift_k)
5656
assert num_valence_electrons(inp.structure, inp.pseudos) == 8
5757

5858
repr(inp), str(inp)
@@ -81,8 +81,8 @@ def test_api(self):
8181
inp.set_vars_ifnotin(ecut=-10)
8282
assert inp["ecut"] == 5
8383

84-
_, tmpname = tempfile.mkstemp(text=True)
85-
inp.write(filepath=tmpname)
84+
_, tmp_name = tempfile.mkstemp(text=True)
85+
inp.write(filepath=tmp_name)
8686

8787
# Cannot change structure variables directly.
8888
with pytest.raises(inp.Error):

tests/io/vasp/test_sets.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ def test_incar(self):
10881088
assert incar["EDIFF"] == approx(1e-5)
10891089
assert incar["LANGEVIN_GAMMA_L"] == 1
10901090
assert incar["LANGEVIN_GAMMA"] == [10, 10, 10]
1091-
enmax = max(npt_set.potcar[i].keywords["ENMAX"] for i in range(self.struct.ntypesp))
1091+
enmax = max(npt_set.potcar[idx].keywords["ENMAX"] for idx in range(self.struct.n_elems))
10921092
assert incar["ENCUT"] == approx(1.5 * enmax)
10931093
assert incar["ALGO"] == "Fast"
10941094
assert incar["ISIF"] == 3

0 commit comments

Comments
 (0)