kim-tools 0.3.4__py3-none-any.whl → 0.3.6__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 +1 -1
- kim_tools/aflow_util/core.py +26 -3
- kim_tools/ase/core.py +8 -5
- kim_tools/symmetry_util/core.py +90 -0
- kim_tools/test_driver/core.py +58 -17
- {kim_tools-0.3.4.dist-info → kim_tools-0.3.6.dist-info}/METADATA +1 -1
- {kim_tools-0.3.4.dist-info → kim_tools-0.3.6.dist-info}/RECORD +10 -10
- {kim_tools-0.3.4.dist-info → kim_tools-0.3.6.dist-info}/WHEEL +0 -0
- {kim_tools-0.3.4.dist-info → kim_tools-0.3.6.dist-info}/licenses/LICENSE.CDDL +0 -0
- {kim_tools-0.3.4.dist-info → kim_tools-0.3.6.dist-info}/top_level.txt +0 -0
kim_tools/__init__.py
CHANGED
kim_tools/aflow_util/core.py
CHANGED
@@ -392,6 +392,30 @@ def get_wyckoff_lists_from_prototype(prototype_label: str) -> List[str]:
|
|
392
392
|
return expanded_wyckoff_letters
|
393
393
|
|
394
394
|
|
395
|
+
def get_atom_indices_for_each_wyckoff_orb(prototype_label: str) -> List[Dict]:
|
396
|
+
"""
|
397
|
+
Get a list of dictionaries containing the atom indices of each Wyckoff
|
398
|
+
orbit.
|
399
|
+
|
400
|
+
Returns:
|
401
|
+
The information is in this format:
|
402
|
+
|
403
|
+
[{"letter":"a", "indices":[0,1]}, ... ]
|
404
|
+
"""
|
405
|
+
return_list = []
|
406
|
+
wyck_lists = get_wyckoff_lists_from_prototype(prototype_label)
|
407
|
+
sgnum = get_space_group_number_from_prototype(prototype_label)
|
408
|
+
range_start = 0
|
409
|
+
for letter in "".join(wyck_lists):
|
410
|
+
multiplicity = get_primitive_wyckoff_multiplicity(sgnum, letter)
|
411
|
+
range_end = range_start + multiplicity
|
412
|
+
return_list.append(
|
413
|
+
{"letter": letter, "indices": list(range(range_start, range_end))}
|
414
|
+
)
|
415
|
+
range_start = range_end
|
416
|
+
return return_list
|
417
|
+
|
418
|
+
|
395
419
|
def prototype_labels_are_equivalent(
|
396
420
|
prototype_label_1: str,
|
397
421
|
prototype_label_2: str,
|
@@ -841,9 +865,8 @@ class AFLOW:
|
|
841
865
|
"that the AFLOW executable was not found."
|
842
866
|
)
|
843
867
|
# I am fine with allowing prereleases
|
844
|
-
|
845
|
-
|
846
|
-
if aflow_ver_no_prerelease < Version.parse(REQUIRED_AFLOW):
|
868
|
+
aflow_ver = Version.parse(ver_str)
|
869
|
+
if aflow_ver.replace(prerelease=None) < Version.parse(REQUIRED_AFLOW):
|
847
870
|
raise self.AFLOWNotFoundException(
|
848
871
|
f"Your AFLOW version {ver_str} is less "
|
849
872
|
f"than the required {REQUIRED_AFLOW}"
|
kim_tools/ase/core.py
CHANGED
@@ -208,7 +208,7 @@ def randomize_positions(atoms, pert_amp, seed=None):
|
|
208
208
|
|
209
209
|
|
210
210
|
################################################################################
|
211
|
-
def get_isolated_energy_per_atom(model: Union[str, Calculator], symbol):
|
211
|
+
def get_isolated_energy_per_atom(model: Union[str, Calculator], symbol: str) -> float:
|
212
212
|
"""
|
213
213
|
Construct a non-periodic cell containing a single atom and compute its energy.
|
214
214
|
|
@@ -238,10 +238,13 @@ def get_isolated_energy_per_atom(model: Union[str, Calculator], symbol):
|
|
238
238
|
)
|
239
239
|
single_atom.calc = calc
|
240
240
|
energy_per_atom = single_atom.get_potential_energy()
|
241
|
-
if
|
242
|
-
|
243
|
-
if
|
244
|
-
calc
|
241
|
+
# if we are attaching an existing LAMMPS calculator to an atoms object,
|
242
|
+
# we can't delete it. Only do so if we are making a new one from a KIM ID.
|
243
|
+
if isinstance(model, str):
|
244
|
+
if hasattr(calc, "clean"):
|
245
|
+
calc.clean()
|
246
|
+
if hasattr(calc, "__del__"):
|
247
|
+
calc.__del__()
|
245
248
|
del single_atom
|
246
249
|
return energy_per_atom
|
247
250
|
|
kim_tools/symmetry_util/core.py
CHANGED
@@ -14,6 +14,7 @@ import numpy as np
|
|
14
14
|
import numpy.typing as npt
|
15
15
|
from ase import Atoms
|
16
16
|
from ase.cell import Cell
|
17
|
+
from ase.constraints import FixSymmetry
|
17
18
|
from ase.geometry import get_distances, get_duplicate_atoms
|
18
19
|
from matplotlib.backends.backend_pdf import PdfPages
|
19
20
|
from pymatgen.core.operations import SymmOp
|
@@ -617,6 +618,20 @@ def get_primitive_genpos_ops(sgnum: Union[int, str]) -> List[Dict]:
|
|
617
618
|
return np.asarray(json.load(f)[str(sgnum)])
|
618
619
|
|
619
620
|
|
621
|
+
def transform_atoms(atoms: Atoms, op: Dict) -> Atoms:
|
622
|
+
"""
|
623
|
+
Transform atoms by an operation defined by a dictionary containing a matrix 'W' and
|
624
|
+
translation 'w' defined as fractional operations in the unit cell. 'W' should be
|
625
|
+
oriented to operate on column vectors
|
626
|
+
"""
|
627
|
+
frac_pos_columns = atoms.get_scaled_positions().T
|
628
|
+
frac_pos_cols_xform = op["W"] @ frac_pos_columns + np.reshape(op["w"], (3, 1))
|
629
|
+
atoms_transformed = atoms.copy()
|
630
|
+
atoms_transformed.set_scaled_positions(frac_pos_cols_xform.T)
|
631
|
+
atoms_transformed.wrap()
|
632
|
+
return atoms_transformed
|
633
|
+
|
634
|
+
|
620
635
|
def reduce_and_avg(
|
621
636
|
atoms: Atoms, repeat: Tuple[int, int, int]
|
622
637
|
) -> Tuple[Atoms, npt.ArrayLike]:
|
@@ -832,3 +847,78 @@ def fit_voigt_tensor_to_cell_and_space_group(
|
|
832
847
|
t_symmetrized = sum(t_rotated_list) / len(t_rotated_list)
|
833
848
|
|
834
849
|
return t_symmetrized.voigt
|
850
|
+
|
851
|
+
|
852
|
+
class FixProvidedSymmetry(FixSymmetry):
|
853
|
+
"""
|
854
|
+
A modification of :obj:`~ase.constraints.FixSymmetry` that takes
|
855
|
+
a prescribed symmetry instead of analyzing the atoms object on the fly
|
856
|
+
"""
|
857
|
+
|
858
|
+
def __init__(
|
859
|
+
self,
|
860
|
+
atoms: Atoms,
|
861
|
+
symmetry: Union[str, int, List[Dict]],
|
862
|
+
adjust_positions=True,
|
863
|
+
adjust_cell=True,
|
864
|
+
):
|
865
|
+
"""
|
866
|
+
Args:
|
867
|
+
symmetry:
|
868
|
+
Either the space group number, or a list of operations
|
869
|
+
as dictionaries with keys "W": (fractional rotation matrix),
|
870
|
+
"w": (fractional translation). The space group number input
|
871
|
+
will not work correctly unless this contraint is applied to
|
872
|
+
a primitive unit cell as defined in
|
873
|
+
http://doi.org/10.1016/j.commatsci.2017.01.017
|
874
|
+
"""
|
875
|
+
self.atoms = atoms.copy()
|
876
|
+
self.symmetry = symmetry
|
877
|
+
|
878
|
+
if isinstance(symmetry, str) or isinstance(symmetry, int):
|
879
|
+
primitive_genpos_ops = get_primitive_genpos_ops(symmetry)
|
880
|
+
else:
|
881
|
+
try:
|
882
|
+
for op in symmetry:
|
883
|
+
assert np.asarray(op["W"]).shape == (3, 3)
|
884
|
+
assert np.asarray(op["w"]).shape == (3,)
|
885
|
+
primitive_genpos_ops = symmetry
|
886
|
+
except Exception:
|
887
|
+
raise RuntimeError("Incorrect input provided to FixProvidedSymmetry")
|
888
|
+
|
889
|
+
self.rotations = []
|
890
|
+
self.translations = []
|
891
|
+
for op in primitive_genpos_ops:
|
892
|
+
self.rotations.append(np.asarray(op["W"]))
|
893
|
+
self.translations.append(np.asarray(op["w"]))
|
894
|
+
self.prep_symm_map()
|
895
|
+
|
896
|
+
self.do_adjust_positions = adjust_positions
|
897
|
+
self.do_adjust_cell = adjust_cell
|
898
|
+
|
899
|
+
def prep_symm_map(self) -> None:
|
900
|
+
"""
|
901
|
+
Prepare self.symm_map using provided symmetries
|
902
|
+
"""
|
903
|
+
self.symm_map = []
|
904
|
+
scaled_pos = self.atoms.get_scaled_positions()
|
905
|
+
for rot, trans in zip(self.rotations, self.translations):
|
906
|
+
this_op_map = [-1] * len(self.atoms)
|
907
|
+
for i_at in range(len(self.atoms)):
|
908
|
+
new_p = rot @ scaled_pos[i_at, :] + trans
|
909
|
+
dp = scaled_pos - new_p
|
910
|
+
dp -= np.round(dp)
|
911
|
+
i_at_map = np.argmin(np.linalg.norm(dp, axis=1))
|
912
|
+
this_op_map[i_at] = i_at_map
|
913
|
+
self.symm_map.append(this_op_map)
|
914
|
+
|
915
|
+
def todict(self):
|
916
|
+
return {
|
917
|
+
"name": "FixProvidedSymmetry",
|
918
|
+
"kwargs": {
|
919
|
+
"atoms": self.atoms,
|
920
|
+
"symmetry": self.symmetry,
|
921
|
+
"adjust_positions": self.do_adjust_positions,
|
922
|
+
"adjust_cell": self.do_adjust_cell,
|
923
|
+
},
|
924
|
+
}
|
kim_tools/test_driver/core.py
CHANGED
@@ -65,7 +65,8 @@ from ..aflow_util import (
|
|
65
65
|
get_space_group_number_from_prototype,
|
66
66
|
prototype_labels_are_equivalent,
|
67
67
|
)
|
68
|
-
from ..aflow_util.core import AFLOW_EXECUTABLE
|
68
|
+
from ..aflow_util.core import AFLOW_EXECUTABLE, get_atom_indices_for_each_wyckoff_orb
|
69
|
+
from ..ase import get_isolated_energy_per_atom
|
69
70
|
from ..kimunits import convert_list, convert_units
|
70
71
|
from ..symmetry_util import (
|
71
72
|
cartesian_rotation_is_in_point_group,
|
@@ -138,7 +139,7 @@ def minimize_wrapper(
|
|
138
139
|
logfile: Optional[Union[str, IO]] = "kim-tools.log",
|
139
140
|
algorithm: Optimizer = LBFGSLineSearch,
|
140
141
|
cell_filter: UnitCellFilter = FrechetCellFilter,
|
141
|
-
fix_symmetry: bool = False,
|
142
|
+
fix_symmetry: Union[bool, FixSymmetry] = False,
|
142
143
|
opt_kwargs: Dict = {},
|
143
144
|
flt_kwargs: Dict = {},
|
144
145
|
) -> bool:
|
@@ -178,7 +179,8 @@ def minimize_wrapper(
|
|
178
179
|
CellFilter:
|
179
180
|
Filter to use if variable_cell is requested
|
180
181
|
fix_symmetry:
|
181
|
-
Whether to fix the crystallographic symmetry
|
182
|
+
Whether to fix the crystallographic symmetry. Can provide
|
183
|
+
a FixSymmetry class here instead of detecting it on the fly
|
182
184
|
opt_kwargs:
|
183
185
|
Dictionary of kwargs to pass to optimizer
|
184
186
|
flt_kwargs:
|
@@ -187,8 +189,11 @@ def minimize_wrapper(
|
|
187
189
|
Returns:
|
188
190
|
Whether the minimization succeeded
|
189
191
|
"""
|
190
|
-
if fix_symmetry:
|
191
|
-
|
192
|
+
if fix_symmetry is not False:
|
193
|
+
if fix_symmetry is True:
|
194
|
+
symmetry = FixSymmetry(atoms)
|
195
|
+
else:
|
196
|
+
symmetry = fix_symmetry
|
192
197
|
atoms.set_constraint(symmetry)
|
193
198
|
if variable_cell:
|
194
199
|
supercell_wrapped = cell_filter(atoms, **flt_kwargs)
|
@@ -224,11 +229,18 @@ def minimize_wrapper(
|
|
224
229
|
del atoms.constraints
|
225
230
|
|
226
231
|
if minimization_stalled or iteration_limits_reached:
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
+
try:
|
233
|
+
logger.info("Final forces:")
|
234
|
+
logger.info(atoms.get_forces())
|
235
|
+
logger.info("Final stress:")
|
236
|
+
logger.info(atoms.get_stress())
|
237
|
+
except Exception as e:
|
238
|
+
logger.info(
|
239
|
+
"The following exception was caught "
|
240
|
+
"trying to evaluate final forces and stress:"
|
241
|
+
)
|
242
|
+
logger.info(repr(e))
|
243
|
+
return False
|
232
244
|
else:
|
233
245
|
return True
|
234
246
|
|
@@ -746,6 +758,23 @@ class KIMTestDriver(ABC):
|
|
746
758
|
self.__output_property_instances, f
|
747
759
|
) # serialize the dictionary to string first
|
748
760
|
|
761
|
+
def get_isolated_energy_per_atom(self, symbol: str) -> float:
|
762
|
+
"""
|
763
|
+
Construct a non-periodic cell containing a single atom and compute its energy.
|
764
|
+
|
765
|
+
Args
|
766
|
+
symbol:
|
767
|
+
The chemical species
|
768
|
+
|
769
|
+
Returns:
|
770
|
+
The isolated energy of a single atom
|
771
|
+
"""
|
772
|
+
try:
|
773
|
+
model = self.kim_model_name
|
774
|
+
except self.NonKIMModelError:
|
775
|
+
model = self._calc
|
776
|
+
return get_isolated_energy_per_atom(model=model, symbol=symbol)
|
777
|
+
|
749
778
|
|
750
779
|
def _add_common_crystal_genome_keys_to_current_property_instance(
|
751
780
|
property_instances: str,
|
@@ -1289,7 +1318,7 @@ class SingleCrystalTestDriver(KIMTestDriver):
|
|
1289
1318
|
)
|
1290
1319
|
print(f"\nNOTE: {msg}\n")
|
1291
1320
|
logger.info(msg)
|
1292
|
-
if cell_cauchy_stress_eV_angstrom3
|
1321
|
+
if cell_cauchy_stress_eV_angstrom3 == [0, 0, 0, 0, 0, 0]:
|
1293
1322
|
stress_max = np.max(atoms_tmp.get_stress())
|
1294
1323
|
if stress_max > FMAX_INITIAL:
|
1295
1324
|
msg = (
|
@@ -1838,6 +1867,23 @@ class SingleCrystalTestDriver(KIMTestDriver):
|
|
1838
1867
|
atoms_tmp.calc = self._calc
|
1839
1868
|
return atoms_tmp
|
1840
1869
|
|
1870
|
+
def get_nominal_prototype_label(self) -> str:
|
1871
|
+
return self._get_nominal_crystal_structure_npt()["prototype-label"][
|
1872
|
+
"source-value"
|
1873
|
+
]
|
1874
|
+
|
1875
|
+
def get_atom_indices_for_each_wyckoff_orb(self) -> List[Dict]:
|
1876
|
+
"""
|
1877
|
+
Get a list of dictionaries containing the atom indices of each Wyckoff
|
1878
|
+
orbit.
|
1879
|
+
|
1880
|
+
Returns:
|
1881
|
+
The information is in this format:
|
1882
|
+
|
1883
|
+
[{"letter":"a", "indices":[0,1]}, ... ]
|
1884
|
+
"""
|
1885
|
+
return get_atom_indices_for_each_wyckoff_orb(self.get_nominal_prototype_label())
|
1886
|
+
|
1841
1887
|
|
1842
1888
|
def query_crystal_structures(
|
1843
1889
|
stoichiometric_species: List[str],
|
@@ -1937,7 +1983,7 @@ def query_crystal_structures(
|
|
1937
1983
|
logger.info(len_msg)
|
1938
1984
|
logger.debug(f"Query result (length={len(query_result)}):\n{query_result}")
|
1939
1985
|
|
1940
|
-
print(f"!!! {len_msg}
|
1986
|
+
print(f"\n!!! {len_msg} !!!\n")
|
1941
1987
|
|
1942
1988
|
return query_result
|
1943
1989
|
|
@@ -2190,8 +2236,3 @@ def get_deduplicated_property_instances(
|
|
2190
2236
|
property_instances_deduplicated.sort(key=lambda a: a["instance-id"])
|
2191
2237
|
|
2192
2238
|
return property_instances_deduplicated
|
2193
|
-
|
2194
|
-
|
2195
|
-
# If called directly, do nothing
|
2196
|
-
if __name__ == "__main__":
|
2197
|
-
pass
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: kim-tools
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.6
|
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=
|
1
|
+
kim_tools/__init__.py,sha256=kYbIfF9bmWajsk_oLkaGok3kpnHeo1rlLBUAranse8o,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=
|
4
|
+
kim_tools/aflow_util/core.py,sha256=YH1KCMQjXiKMqhT1TAuoafpsGqPlybsykRRMaa8wWqc,78219
|
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=
|
2005
|
+
kim_tools/ase/core.py,sha256=odRuHQGZl-pcRtkdYvG31_3kW6nt3qwHdKvAOJ-ifwM,31207
|
2006
2006
|
kim_tools/symmetry_util/__init__.py,sha256=uu-ZSUDUTe2P81rkAS3tXverx31s_uZ3wL4SD_dn5aI,86
|
2007
|
-
kim_tools/symmetry_util/core.py,sha256=
|
2007
|
+
kim_tools/symmetry_util/core.py,sha256=aDaeYmtwfkNlNDcYQ3mAkez7e9_Lk84xQxwQ24cir38,34231
|
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
|
@@ -2012,11 +2012,11 @@ kim_tools/symmetry_util/data/wyck_pos_xform_under_normalizer.json,sha256=6g1YuYh
|
|
2012
2012
|
kim_tools/symmetry_util/data/wyckoff_multiplicities.json,sha256=qG2RPBd_-ejDIfz-E4ZhkHyRpIboxRy7oiXkdDf5Eg8,32270
|
2013
2013
|
kim_tools/symmetry_util/data/wyckoff_sets.json,sha256=f5ZpHKDHo6_JWki1b7KUGoYLlhU-44Qikw_-PtbLssw,9248
|
2014
2014
|
kim_tools/test_driver/__init__.py,sha256=KOiceeZNqkfrgZ66CiRiUdniceDrCmmDXQkOw0wXaCQ,92
|
2015
|
-
kim_tools/test_driver/core.py,sha256=
|
2015
|
+
kim_tools/test_driver/core.py,sha256=DseMkfdb-b116rRQQR0N7HKhsMsZGq8ZxtKoCBlw8X8,91307
|
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.
|
2019
|
-
kim_tools-0.3.
|
2020
|
-
kim_tools-0.3.
|
2021
|
-
kim_tools-0.3.
|
2022
|
-
kim_tools-0.3.
|
2018
|
+
kim_tools-0.3.6.dist-info/licenses/LICENSE.CDDL,sha256=I2luEED_SHjuZ01B4rYG-AF_135amL24JpHvZ1Jhqe8,16373
|
2019
|
+
kim_tools-0.3.6.dist-info/METADATA,sha256=Q_aemQPU34z7rSPK04WnMP6WzUnS845Frlr3YWofcjw,2032
|
2020
|
+
kim_tools-0.3.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
2021
|
+
kim_tools-0.3.6.dist-info/top_level.txt,sha256=w_YCpJ5ERigj9te74ln7k64tqj1VumOzM_s9dsalIWY,10
|
2022
|
+
kim_tools-0.3.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|