@@ -220,14 +220,7 @@ def closest_site_info(
220
220
)
221
221
222
222
if element_list is None :
223
- element_list = [el .symbol for el in defect .structure .composition .elements ] # host elements
224
- element_list += sorted (
225
- [ # extrinsic elements, sorted alphabetically for deterministic ordering in output:
226
- el .symbol
227
- for el in defect .defect_structure .composition .elements
228
- if el .symbol not in element_list
229
- ]
230
- )
223
+ element_list = _get_element_list (defect )
231
224
232
225
site_distances = sorted (
233
226
[
@@ -1453,18 +1446,22 @@ class (such as ``clustering_tol``, ``stol``, ``min_dist`` etc), or to
1453
1446
extrinsic_elements = list (set (extrinsic_elements )) # get only unique elements
1454
1447
else :
1455
1448
extrinsic_elements = []
1449
+
1456
1450
host_element_list = [el .symbol for el in self .primitive_structure .composition .elements ]
1457
- # if any "extrinsic" elements are actually host elements, remove them from the list and warn
1458
- # user:
1451
+ # if any "extrinsic" elements are actually host elements, remove them and warn user:
1459
1452
if any (el in host_element_list for el in extrinsic_elements ):
1460
1453
warnings .warn (
1461
1454
f"\n Specified 'extrinsic' elements "
1462
1455
f"{ [el for el in extrinsic_elements if el in host_element_list ]} are present in "
1463
1456
f"the host structure, so do not need to be specified as 'extrinsic' in "
1464
1457
f"DefectsGenerator(). These will be ignored."
1465
1458
)
1466
- # sort extrinsic elements alphabetically for deterministic ordering in output:
1467
- extrinsic_elements = sorted ([el for el in extrinsic_elements if el not in host_element_list ])
1459
+
1460
+ # sort extrinsic elements by periodic group and atomic number for deterministic ordering:
1461
+ extrinsic_elements = sorted (
1462
+ [el for el in extrinsic_elements if el not in host_element_list ],
1463
+ key = _element_sort_func ,
1464
+ )
1468
1465
1469
1466
substitution_generator_obj = SubstitutionGenerator ()
1470
1467
if isinstance (self .extrinsic , (str , list )): # substitute all host elements:
@@ -2227,6 +2224,52 @@ def __repr__(self):
2227
2224
)
2228
2225
2229
2226
2227
+ def _get_element_list (defect : Union [Defect , DefectEntry , dict , list ]) -> list [str ]:
2228
+ """
2229
+ Given an input ``Defect`` or ``DefectEntry``, or dictionary/list of these,
2230
+ return a (non-duplicated) list of elements present in the defect
2231
+ structures.
2232
+ """
2233
+
2234
+ def _get_single_defect_element_list (single_defect ):
2235
+ element_list = [el .symbol for el in single_defect .structure .composition .elements ]
2236
+ element_list += sorted (
2237
+ [ # extrinsic elements, sorted by periodic group and atomic number for deterministic ordering
2238
+ el .symbol
2239
+ for el in single_defect .defect_structure .composition .elements
2240
+ if el .symbol not in element_list
2241
+ ],
2242
+ key = _element_sort_func ,
2243
+ )
2244
+ return element_list
2245
+
2246
+ if isinstance (defect , (Defect , DefectEntry )):
2247
+ return _get_single_defect_element_list (defect if isinstance (defect , Defect ) else defect .defect )
2248
+
2249
+ # else is dict/list
2250
+ defect_list = defect if isinstance (defect , list ) else list (defect .values ())
2251
+ defect_list = [
2252
+ entry_or_defect .defect if isinstance (entry_or_defect , DefectEntry ) else entry_or_defect
2253
+ for entry_or_defect in defect_list
2254
+ ]
2255
+ host_element_list = [el .symbol for el in next (iter (defect_list )).structure .composition .elements ]
2256
+ extrinsic_element_list : list [str ] = []
2257
+ for single_defect in defect_list :
2258
+ extrinsic_element_list .extend (
2259
+ [
2260
+ el .symbol
2261
+ for el in single_defect .defect_structure .composition .elements
2262
+ if el .symbol not in host_element_list
2263
+ ]
2264
+ )
2265
+ # sort extrinsic elements by periodic group and atomic number for deterministic ordering:
2266
+ extrinsic_element_list = sorted (
2267
+ set (extrinsic_element_list ),
2268
+ key = _element_sort_func ,
2269
+ )
2270
+ return host_element_list + extrinsic_element_list
2271
+
2272
+
2230
2273
def _first_and_second_element (defect_name : str ) -> tuple [str , str ]:
2231
2274
"""
2232
2275
Return a tuple of the first and second element in the defect name.
@@ -2292,27 +2335,7 @@ def _sort_defect_entries(
2292
2335
state (from positive to negative).
2293
2336
"""
2294
2337
if element_list is None :
2295
- host_element_list = [
2296
- el .symbol
2297
- for el in next (iter (defect_entries_dict .values ())).defect .structure .composition .elements
2298
- ]
2299
- extrinsic_element_list : list [str ] = []
2300
- for defect_entry in defect_entries_dict .values ():
2301
- extrinsic_element_list .extend (
2302
- el .symbol
2303
- for el in [
2304
- * defect_entry .defect .structure .composition .elements ,
2305
- * defect_entry .defect .site .species .elements ,
2306
- ]
2307
- if el .symbol not in host_element_list
2308
- )
2309
-
2310
- # sort extrinsic elements by periodic group and atomic number for deterministic ordering in output:
2311
- extrinsic_element_list = sorted (
2312
- [el for el in extrinsic_element_list if el not in host_element_list ],
2313
- key = _element_sort_func ,
2314
- )
2315
- element_list = host_element_list + extrinsic_element_list
2338
+ element_list = _get_element_list (defect_entries_dict )
2316
2339
2317
2340
try :
2318
2341
return dict (
@@ -2373,24 +2396,11 @@ def _sort_defects(defects_dict: dict, element_list: Optional[list[str]] = None):
2373
2396
2374
2397
Sorts defects by defect type (vacancies, substitutions, interstitials),
2375
2398
then by order of appearance of elements in the composition, then
2376
- alphabetically, then according to symmetry._frac_coords_sort_func.
2399
+ by periodic group (main groups 1, 2, 13-18 first, then TMs), then by
2400
+ atomic number, then according to ``symmetry._frac_coords_sort_func``.
2377
2401
"""
2378
2402
if element_list is None :
2379
- all_elements : list [str ] = []
2380
- host_element_list = [
2381
- el .symbol for el in next (iter (defects_dict .values ())).structure .composition .elements
2382
- ]
2383
-
2384
- for _defect_type , defect_list in defects_dict .items ():
2385
- for defect in defect_list :
2386
- all_elements .extend (el .symbol for el in defect .defect_structure .composition .elements )
2387
- extrinsic_element_list = list (set (all_elements ) - set (host_element_list ))
2388
-
2389
- # sort extrinsic elements alphabetically for deterministic ordering in output:
2390
- extrinsic_element_list = sorted (
2391
- [el for el in extrinsic_element_list if el not in host_element_list ]
2392
- )
2393
- element_list = host_element_list + extrinsic_element_list
2403
+ element_list = _get_element_list (defects_dict )
2394
2404
2395
2405
return {
2396
2406
defect_type : sorted (
0 commit comments