kim-tools 0.3.1__py3-none-any.whl → 0.3.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kim_tools/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.3.1"
1
+ __version__ = "0.3.3"
2
2
 
3
3
  from .aflow_util import *
4
4
  from .aflow_util import __all__ as aflow_all
@@ -396,6 +396,7 @@ def prototype_labels_are_equivalent(
396
396
  prototype_label_1: str,
397
397
  prototype_label_2: str,
398
398
  allow_enantiomorph: bool = False,
399
+ log: bool = True,
399
400
  ) -> bool:
400
401
  """
401
402
  Checks if two prototype labels are equivalent (species permutations not allowed)
@@ -403,6 +404,8 @@ def prototype_labels_are_equivalent(
403
404
  Args:
404
405
  allow_enantiomorph:
405
406
  Whether to consider enantiomorphic pairs of space groups to be equivalent
407
+ log:
408
+ Whether to log results
406
409
  """
407
410
 
408
411
  if prototype_label_1 == prototype_label_2:
@@ -414,20 +417,22 @@ def prototype_labels_are_equivalent(
414
417
  if not stoich_reduced_list_1 == get_stoich_reduced_list_from_prototype(
415
418
  prototype_label_2
416
419
  ):
417
- logger.info(
418
- "Found non-matching stoichiometry in labels "
419
- f"{prototype_label_1} and {prototype_label_2}"
420
- )
420
+ if log:
421
+ logger.info(
422
+ "Found non-matching stoichiometry in labels "
423
+ f"{prototype_label_1} and {prototype_label_2}"
424
+ )
421
425
  return False
422
426
 
423
427
  # Check Pearson symbol
424
428
  if not get_pearson_symbol_from_prototype(
425
429
  prototype_label_1
426
430
  ) == get_pearson_symbol_from_prototype(prototype_label_2):
427
- logger.info(
428
- "Found non-matching Pearson symbol in labels "
429
- f"{prototype_label_1} and {prototype_label_2}"
430
- )
431
+ if log:
432
+ logger.info(
433
+ "Found non-matching Pearson symbol in labels "
434
+ f"{prototype_label_1} and {prototype_label_2}"
435
+ )
431
436
  return False
432
437
 
433
438
  # Check space group number
@@ -436,16 +441,18 @@ def prototype_labels_are_equivalent(
436
441
  if allow_enantiomorph and not space_group_numbers_are_enantiomorphic(
437
442
  sg_num_2, sg_num_1
438
443
  ):
439
- logger.info(
440
- "Found non-matching Space group in labels "
441
- f"{prototype_label_1} and {prototype_label_2}"
442
- )
444
+ if log:
445
+ logger.info(
446
+ "Found non-matching Space group in labels "
447
+ f"{prototype_label_1} and {prototype_label_2}"
448
+ )
443
449
  return False
444
450
  elif sg_num_2 != sg_num_1:
445
- logger.info(
446
- "Found non-matching Space group in labels "
447
- f"{prototype_label_1} and {prototype_label_2}"
448
- )
451
+ if log:
452
+ logger.info(
453
+ "Found non-matching Space group in labels "
454
+ f"{prototype_label_1} and {prototype_label_2}"
455
+ )
449
456
  return False
450
457
 
451
458
  # OK, so far everything matches, now check the Wyckoff letters
@@ -487,16 +494,18 @@ def prototype_labels_are_equivalent(
487
494
  wyckoff_lists_match_for_each_species = False
488
495
  break
489
496
  if wyckoff_lists_match_for_each_species:
490
- logger.warning(
491
- f"Labels {prototype_label_1} and {prototype_label_2} were found to "
492
- "be equivalent despite being non-identical. "
493
- "This indicates a failure to find the lowest Wyckoff enumeration."
494
- )
497
+ if log:
498
+ logger.warning(
499
+ f"Labels {prototype_label_1} and {prototype_label_2} were found"
500
+ " to be equivalent despite being non-identical. This indicates "
501
+ "a failure to find the lowest Wyckoff enumeration."
502
+ )
495
503
  return True
496
- logger.info(
497
- f"Labels {prototype_label_1} and {prototype_label_2} were not found to be "
498
- "equivalent under any permutations allowable by the normalizer."
499
- )
504
+ if log:
505
+ logger.info(
506
+ f"Labels {prototype_label_1} and {prototype_label_2} were not found to "
507
+ "be equivalent under any permutations allowable by the normalizer."
508
+ )
500
509
  return False
501
510
  else:
502
511
  for wyckoff_list_1, wyckoff_list_2 in zip(wyckoff_lists_1, wyckoff_lists_2):
@@ -505,17 +514,19 @@ def prototype_labels_are_equivalent(
505
514
  # need to re-sort anything.
506
515
  # This is NOT true for all SGs (e.g. #200, Wyckoff set eh )
507
516
  if not are_in_same_wyckoff_set(letter_1, letter_2, sg_num_1):
508
- logger.info(
509
- f"Labels {prototype_label_1} and {prototype_label_2} have "
510
- f"corresponding letters {letter_1} and {letter_2} that are not "
511
- "in the same Wyckoff set"
512
- )
517
+ if log:
518
+ logger.info(
519
+ f"Labels {prototype_label_1} and {prototype_label_2} have "
520
+ f"corresponding letters {letter_1} and {letter_2} that are "
521
+ "not in the same Wyckoff set"
522
+ )
513
523
  return False
514
- logger.info(
515
- f"Labels {prototype_label_1} and {prototype_label_2} were found to be "
516
- "equivalent despite being non-identical. This is a normal occurrence for "
517
- "triclinic and monoclinic space groups such as this."
518
- )
524
+ if log:
525
+ logger.info(
526
+ f"Labels {prototype_label_1} and {prototype_label_2} were found to be "
527
+ "equivalent despite being non-identical. This is a normal occurrence "
528
+ "for triclinic and monoclinic space groups such as this."
529
+ )
519
530
  return True
520
531
 
521
532
 
@@ -523,6 +534,7 @@ def find_species_permutation_between_prototype_labels(
523
534
  prototype_label_1: str,
524
535
  prototype_label_2: str,
525
536
  allow_enantiomorph: bool = False,
537
+ log: bool = True,
526
538
  ) -> Optional[Tuple[int]]:
527
539
  """
528
540
  Find the permutation of species required to match two prototype labels
@@ -530,6 +542,8 @@ def find_species_permutation_between_prototype_labels(
530
542
  Args:
531
543
  allow_enantiomorph:
532
544
  Whether to consider enantiomorphic pairs of space groups to be equivalent
545
+ log:
546
+ Whether to log results
533
547
 
534
548
  Returns:
535
549
  The permutation of species of ``prototype_label_1`` required to match
@@ -538,12 +552,32 @@ def find_species_permutation_between_prototype_labels(
538
552
  # Disassemble prototype_label_1
539
553
  stoich_reduced_list_1 = get_stoich_reduced_list_from_prototype(prototype_label_1)
540
554
  pearson_1 = get_pearson_symbol_from_prototype(prototype_label_1)
541
- space_group_1 = str(get_space_group_number_from_prototype(prototype_label_1))
555
+ space_group_1 = get_space_group_number_from_prototype(prototype_label_1)
556
+ space_group_1_str = str(space_group_1)
542
557
  species_wyckoff_sections_1 = prototype_label_1.split("-")[0].split("_")[3:]
543
558
 
544
559
  nspecies = len(stoich_reduced_list_1)
545
560
  assert nspecies == len(species_wyckoff_sections_1)
546
561
 
562
+ # For crystals with many species, it takes forever to loop through all permutations,
563
+ # so do some basic checks first to reject
564
+ stoich_reduced_list_2 = get_stoich_reduced_list_from_prototype(prototype_label_2)
565
+ pearson_2 = get_pearson_symbol_from_prototype(prototype_label_2)
566
+ space_group_2 = get_space_group_number_from_prototype(prototype_label_2)
567
+ if (
568
+ len(stoich_reduced_list_1) != len(stoich_reduced_list_2)
569
+ or sum(stoich_reduced_list_1) != sum(stoich_reduced_list_2)
570
+ or pearson_1 != pearson_2
571
+ ):
572
+ return None
573
+
574
+ if allow_enantiomorph:
575
+ if not space_group_numbers_are_enantiomorphic(space_group_1, space_group_2):
576
+ return None
577
+ else:
578
+ if space_group_1 != space_group_2:
579
+ return None
580
+
547
581
  permutation_candidates = permutations(tuple(range(nspecies)))
548
582
  for permutation in permutation_candidates:
549
583
  # Permute the species
@@ -559,13 +593,14 @@ def find_species_permutation_between_prototype_labels(
559
593
  prototype_label_1_permuted_list = [
560
594
  abstract_formula_1_permuted,
561
595
  pearson_1,
562
- space_group_1,
596
+ space_group_1_str,
563
597
  ] + species_wyckoff_sections_1_permuted
564
598
  prototype_label_1_permuted = "_".join(prototype_label_1_permuted_list)
565
599
  if prototype_labels_are_equivalent(
566
600
  prototype_label_1=prototype_label_1_permuted,
567
601
  prototype_label_2=prototype_label_2,
568
602
  allow_enantiomorph=allow_enantiomorph,
603
+ log=log,
569
604
  ):
570
605
  return permutation
571
606
  return None
@@ -604,6 +639,23 @@ def read_shortnames(
604
639
  with open(info_file) as f:
605
640
  info = json.load(f)
606
641
  shortnames[libproto] = info["title"]
642
+
643
+ ##################################################
644
+ # CUSTOM MODIFICATIONS TO SHORTNAME DICT
645
+ ##################################################
646
+ # For some reason, CsCl is AB_cP2_221_a_b-002,
647
+ # while AB_cP2_221_a_b-001 is Ammonium Nitrate,
648
+ # where the atoms represent molecular ions
649
+ shortnames.pop("AB_cP2_221_a_b-001")
650
+
651
+ # I am making an executive decision to include
652
+ # only one identical cubic prototype with no
653
+ # free parameters. Here I am choosing to keep
654
+ # 'A7B_cF32_225_ad_b-001': 'Ca₇Ge Structure'
655
+ # and remove
656
+ # 'AB7_cF32_225_a_bd-001': '𝐿1ₐ (disputed CuPt₃ Structure)'
657
+ shortnames.pop("AB7_cF32_225_a_bd-001")
658
+
607
659
  return shortnames
608
660
 
609
661
 
kim_tools/ase/core.py CHANGED
@@ -32,13 +32,20 @@ Helper routines for KIM Tests and Verification Checks
32
32
  """
33
33
 
34
34
  import itertools
35
+ import logging
35
36
  import random
37
+ from typing import Union
36
38
 
37
39
  import numpy as np
38
40
  from ase import Atoms
41
+ from ase.calculators.calculator import Calculator
39
42
  from ase.calculators.kim.kim import KIM
40
43
  from ase.data import chemical_symbols
41
44
 
45
+ logger = logging.getLogger(__name__)
46
+ logging.basicConfig(filename="kim-tools.log", level=logging.INFO, force=True)
47
+
48
+
42
49
  __all__ = [
43
50
  "KIMASEError",
44
51
  "atom_outside_cell_along_nonperiodic_dim",
@@ -201,9 +208,18 @@ def randomize_positions(atoms, pert_amp, seed=None):
201
208
 
202
209
 
203
210
  ################################################################################
204
- def get_isolated_energy_per_atom(model, symbol):
211
+ def get_isolated_energy_per_atom(model: Union[str, Calculator], symbol):
205
212
  """
206
213
  Construct a non-periodic cell containing a single atom and compute its energy.
214
+
215
+ Args:
216
+ model:
217
+ A KIM model ID or an ASE calculator for computing the energy
218
+ symbol:
219
+ The chemical species
220
+
221
+ Returns:
222
+ The isolated energy of a single atom
207
223
  """
208
224
  single_atom = Atoms(
209
225
  symbol,
@@ -211,15 +227,33 @@ def get_isolated_energy_per_atom(model, symbol):
211
227
  cell=(20, 20, 20),
212
228
  pbc=(False, False, False),
213
229
  )
214
- calc = KIM(model)
230
+ if isinstance(model, str):
231
+ calc = KIM(model)
232
+ elif isinstance(model, Calculator):
233
+ calc = model
234
+ else:
235
+ raise KIMASEError(
236
+ "`model` argument must be a string indicating a KIM model "
237
+ f"or an ASE Calculator. Instead got an object of type {type(model)}."
238
+ )
215
239
  single_atom.calc = calc
216
- energy_per_atom = single_atom.get_potential_energy()
217
- if hasattr(calc, "clean"):
218
- calc.clean()
219
- if hasattr(calc, "__del__"):
220
- calc.__del__()
221
- del single_atom
222
- return energy_per_atom
240
+ try:
241
+ energy_per_atom = single_atom.get_potential_energy()
242
+ except Exception as e:
243
+ msg = (
244
+ "Energy evaluation for isolated atom raised the following error:\n"
245
+ f"{repr(e)}\nAssuming zero isolated atom energy."
246
+ )
247
+ logger.warning(msg)
248
+ print(msg)
249
+ energy_per_atom = 0.0
250
+ finally:
251
+ if hasattr(calc, "clean"):
252
+ calc.clean()
253
+ if hasattr(calc, "__del__"):
254
+ calc.__del__()
255
+ del single_atom
256
+ return energy_per_atom
223
257
 
224
258
 
225
259
  ################################################################################
@@ -289,8 +289,11 @@ def space_group_numbers_are_enantiomorphic(sg_1: int, sg_2: int) -> bool:
289
289
  }
290
290
  enantiomorph_conversion_2 = {v: k for k, v in enantiomorph_conversion.items()}
291
291
  enantiomorph_conversion.update(enantiomorph_conversion_2)
292
- if enantiomorph_conversion[sg_1] == sg_2:
293
- return True
292
+ if sg_1 in enantiomorph_conversion:
293
+ if enantiomorph_conversion[sg_1] == sg_2:
294
+ return True
295
+ else:
296
+ return False
294
297
  else:
295
298
  return False
296
299
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kim-tools
3
- Version: 0.3.1
3
+ Version: 0.3.3
4
4
  Summary: Base classes and helper routines for writing KIM Tests
5
5
  Author-email: ilia Nikiforov <nikif002@umn.edu>, Ellad Tadmor <tadmor@umn.edu>, Claire Waters <bwaters@umn.edu>, "Daniel S. Karls" <karl0100umn@gmail.com>, Matt Bierbaum <matt.bierbaum@gmail.com>, Eric Fuemmeler <efuemmel@umn.edu>, Philipp Hoellmer <ph2484@nyu.edu>, Guanming Zhang <gz2241@nyu.edu>, Tom Egg <tje3676@nyu.edu>
6
6
  Maintainer-email: ilia Nikiforov <nikif002@umn.edu>
@@ -1,7 +1,7 @@
1
- kim_tools/__init__.py,sha256=dOQsrWeoyK-9Fr4gPNLzdouLMm0J0hhh6qd86cPECns,433
1
+ kim_tools/__init__.py,sha256=pnnfC__2WcTkgaE8RZU5AfDIx6PQOR9Dst7oBvYsMYI,433
2
2
  kim_tools/kimunits.py,sha256=jOxBv9gRVhxPE6ygAIUxOzCAfPI6tT6sBaF_FNl9m-M,5387
3
3
  kim_tools/aflow_util/__init__.py,sha256=lJnQ8fZCma80QVRQeKvY4MQ87oCWu-9KATV3dKJfpDc,80
4
- kim_tools/aflow_util/core.py,sha256=NULg8zJG4B5lh4p-Q7yPsJvgzPG_BgSRjgrLpyX3UUI,75526
4
+ kim_tools/aflow_util/core.py,sha256=zi69wMcgkcYBTKbc-OvKlMIzUtgphO57yBA8LB7_5wc,77484
5
5
  kim_tools/aflow_util/aflow_prototype_encyclopedia/data/A108B24C11D24_cP334_222_h4i_i_bf_i-001/info.json,sha256=IsFiO9X2Ko7yoq2QkDurUVP7k1BE4WFgblu7oxl6iZs,2013
6
6
  kim_tools/aflow_util/aflow_prototype_encyclopedia/data/A10B11_tI84_139_dehim_eh2n-001/info.json,sha256=f1EdtouuSL2y9NNw40Rvz2J9ZZcsqQBcyEmlHj6XoW8,1186
7
7
  kim_tools/aflow_util/aflow_prototype_encyclopedia/data/A10B2C_hP39_171_5c_c_a-001/info.json,sha256=vD1xjZKWShL0E6XNsSlmIhilGcGNefl56oQDLQlHO1M,1596
@@ -2002,9 +2002,9 @@ kim_tools/aflow_util/aflow_prototype_encyclopedia/data/A_tP4_129_ac-001/info.jso
2002
2002
  kim_tools/aflow_util/aflow_prototype_encyclopedia/data/A_tP4_136_f-001/info.json,sha256=5_xlFGOov7VoFwzhp7JtltRnWiAFfgpwF5qc3kMSAjQ,1278
2003
2003
  kim_tools/aflow_util/aflow_prototype_encyclopedia/data/A_tP50_134_a2m2n-001/info.json,sha256=K601zsKLpvPLIaK17bEiNGIQJYJDvIby1lIJ3P9Ze6E,1258
2004
2004
  kim_tools/ase/__init__.py,sha256=1i6ko5tNr0VZC3T7hoEzq4fnSU0DdxNpxXcSaWMcJWc,76
2005
- kim_tools/ase/core.py,sha256=d6eOu_HSxVr-ae0TSEbY4HKdePxhNu3yv8NN9VDl-BA,30256
2005
+ kim_tools/ase/core.py,sha256=KRtcNYcJLlP-WiEMOOmR-DhYw5IN5MoOCtKWJJzRkhM,31313
2006
2006
  kim_tools/symmetry_util/__init__.py,sha256=uu-ZSUDUTe2P81rkAS3tXverx31s_uZ3wL4SD_dn5aI,86
2007
- kim_tools/symmetry_util/core.py,sha256=RVvKisrNxHKq36ceIorc06cnX3la3WoWNPVV0hKnptM,30789
2007
+ kim_tools/symmetry_util/core.py,sha256=HfDy1CwNWUZIkb4cs3ebUDgWjtt4jRSkBKgGEnlkjuI,30888
2008
2008
  kim_tools/symmetry_util/data/possible_primitive_shifts.json,sha256=4OVNgn3NnykgGlYiAcecERmVWiIZFrmP2LZI3ml_Sh0,25010
2009
2009
  kim_tools/symmetry_util/data/primitive_GENPOS_ops.json,sha256=FDu4H4PosOpK9yKwOPy3SxbH7xLMOmZfKZ4ItKPMjoQ,224498
2010
2010
  kim_tools/symmetry_util/data/space_groups_for_each_bravais_lattice.json,sha256=wSNu6d5pH72lJ6Zj5MZ64qzwS_6Fn5WOs0ts7E9uPC4,2507
@@ -2015,8 +2015,8 @@ kim_tools/test_driver/__init__.py,sha256=KOiceeZNqkfrgZ66CiRiUdniceDrCmmDXQkOw0w
2015
2015
  kim_tools/test_driver/core.py,sha256=r4hiZcV-PkWcOo0uEqfqeP1-YGGpPepaAjmR4LJog0w,89208
2016
2016
  kim_tools/vc/__init__.py,sha256=zXjhxXCKVMLBMXXWYG3if7VOpBnsFrn_RjVpnohDm5c,74
2017
2017
  kim_tools/vc/core.py,sha256=BIjzEExnQAL2S90a_npptRm3ACqAo4fZBtvTDBMWMdw,13963
2018
- kim_tools-0.3.1.dist-info/licenses/LICENSE.CDDL,sha256=I2luEED_SHjuZ01B4rYG-AF_135amL24JpHvZ1Jhqe8,16373
2019
- kim_tools-0.3.1.dist-info/METADATA,sha256=scnOzhP0hy9JNn5NS6W9lSESU6G0PS2rPoCdkwIIVSE,1962
2020
- kim_tools-0.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
2021
- kim_tools-0.3.1.dist-info/top_level.txt,sha256=w_YCpJ5ERigj9te74ln7k64tqj1VumOzM_s9dsalIWY,10
2022
- kim_tools-0.3.1.dist-info/RECORD,,
2018
+ kim_tools-0.3.3.dist-info/licenses/LICENSE.CDDL,sha256=I2luEED_SHjuZ01B4rYG-AF_135amL24JpHvZ1Jhqe8,16373
2019
+ kim_tools-0.3.3.dist-info/METADATA,sha256=d5yobjRNvHpCLftHbue8GmC0xsvD8FSOpCksGnRoxC8,1962
2020
+ kim_tools-0.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
2021
+ kim_tools-0.3.3.dist-info/top_level.txt,sha256=w_YCpJ5ERigj9te74ln7k64tqj1VumOzM_s9dsalIWY,10
2022
+ kim_tools-0.3.3.dist-info/RECORD,,