kim-tools 0.3.11__py3-none-any.whl → 0.3.13__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.11"
1
+ __version__ = "0.3.13"
2
2
 
3
3
  from .aflow_util import *
4
4
  from .aflow_util import __all__ as aflow_all
kim_tools/ase/core.py CHANGED
@@ -34,7 +34,6 @@ Helper routines for KIM Tests and Verification Checks
34
34
  import itertools
35
35
  import logging
36
36
  import random
37
- from typing import Union
38
37
 
39
38
  import numpy as np
40
39
  from ase import Atoms
@@ -208,45 +207,137 @@ def randomize_positions(atoms, pert_amp, seed=None):
208
207
 
209
208
 
210
209
  ################################################################################
211
- def get_isolated_energy_per_atom(model: Union[str, Calculator], symbol: str) -> float:
210
+ def get_isolated_energy_per_atom(
211
+ model,
212
+ symbol,
213
+ initial_separation=1.0,
214
+ max_separation=15.0,
215
+ separation_neg_exponent=4,
216
+ quit_early_after_convergence=True,
217
+ energy_tolerance=1e-12,
218
+ ):
212
219
  """
213
220
  Construct a non-periodic cell containing a single atom and compute its energy.
221
+ It tries to iteratively finetune the atomic separation for a dimer up to a
222
+ specified precision (separation_neg_exponent). If between two successive phases
223
+ the energy difference is less than energy_tolerance, it stops early, i.e. if
224
+ 4.0x and 4.00x are within energy_tolerance, it stops at 4.00x.
225
+ All separations are in Angstroms.
214
226
 
215
227
  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
228
+ model: KIM model to use for calculations
229
+ symbol: Chemical symbol
230
+ initial_separation: Initial separation for dimer calculations
231
+ max_separation: maximum separation for dimer calculations
232
+ separation_neg_exponent: Number of decimal places to refine the separation
233
+ quit_early_after_convergence: Whether to stop early if energy converges
234
+ energy_tolerance: Energy difference tolerance for convergence check
223
235
  """
224
- single_atom = Atoms(
225
- symbol,
226
- positions=[(0.1, 0.1, 0.1)],
227
- cell=(20, 20, 20),
228
- pbc=(False, False, False),
229
- )
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)}."
236
+ try:
237
+ single_atom = Atoms(
238
+ symbol,
239
+ positions=[(0.1, 0.1, 0.1)],
240
+ cell=(20, 20, 20),
241
+ pbc=(False, False, False),
238
242
  )
239
- single_atom.calc = calc
240
- energy_per_atom = single_atom.get_potential_energy()
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):
243
+ if isinstance(model, str):
244
+ calc = KIM(model)
245
+ elif isinstance(model, Calculator):
246
+ calc = model
247
+
248
+ single_atom.calc = calc
249
+ energy_per_atom = single_atom.get_potential_energy()
250
+
251
+ # Clean up
244
252
  if hasattr(calc, "clean"):
245
253
  calc.clean()
246
254
  if hasattr(calc, "__del__"):
247
255
  calc.__del__()
248
- del single_atom
249
- return energy_per_atom
256
+ del single_atom
257
+
258
+ return energy_per_atom
259
+
260
+ except Exception:
261
+
262
+ def _try_dimer_energy(separation):
263
+ try:
264
+ dimer = Atoms(
265
+ [symbol, symbol],
266
+ positions=[(0.1, 0.1, 0.1), (0.1 + separation, 0.1, 0.1)],
267
+ cell=(max(20, separation + 10), 20, 20),
268
+ pbc=(False, False, False),
269
+ )
270
+ calc = KIM(model)
271
+ dimer.calc = calc
272
+
273
+ total_energy = dimer.get_potential_energy()
274
+ energy_per_atom = total_energy / 2.0
275
+
276
+ if hasattr(calc, "clean"):
277
+ calc.clean()
278
+ if hasattr(calc, "__del__"):
279
+ calc.__del__()
280
+ del dimer
281
+
282
+ return energy_per_atom
283
+
284
+ except Exception:
285
+ try:
286
+ if hasattr(calc, "clean"):
287
+ calc.clean()
288
+ if hasattr(calc, "__del__"):
289
+ calc.__del__()
290
+ if "dimer" in locals():
291
+ del dimer
292
+ except Exception:
293
+ pass
294
+ return None
295
+
296
+ # Start with integer separations: 1.0, 2.0, 3.0, 4.0, ...
297
+ last_successful_separation = None
298
+ last_successful_energy = None
299
+
300
+ separation = initial_separation
301
+ while separation <= max_separation:
302
+ energy = _try_dimer_energy(separation)
303
+ if energy is not None:
304
+ last_successful_separation = separation
305
+ last_successful_energy = energy
306
+ separation += 1.0
307
+ else:
308
+ break
309
+
310
+ if last_successful_separation is None:
311
+ raise RuntimeError(
312
+ f"Failed to obtain isolated energy for {symbol} - no separations worked"
313
+ )
314
+
315
+ # refine
316
+ current_separation = last_successful_separation
317
+ previous_phase_energy = last_successful_energy
318
+
319
+ for decimal_place in range(1, separation_neg_exponent + 1):
320
+
321
+ step_size = 10 ** (-decimal_place)
322
+
323
+ for i in range(1, 10):
324
+ test_sep = current_separation + step_size
325
+ energy = _try_dimer_energy(test_sep)
326
+
327
+ if energy is not None:
328
+ current_separation = test_sep
329
+ last_successful_energy = energy
330
+ else:
331
+ break
332
+
333
+ if quit_early_after_convergence:
334
+ energy_diff = abs(last_successful_energy - previous_phase_energy)
335
+ if energy_diff <= energy_tolerance:
336
+ return last_successful_energy
337
+
338
+ previous_phase_energy = last_successful_energy
339
+
340
+ return last_successful_energy
250
341
 
251
342
 
252
343
  ################################################################################
@@ -434,9 +525,7 @@ def check_if_atoms_interacting(
434
525
  atoms_interacting_energy = check_if_atoms_interacting_energy(
435
526
  model, symbols, etol
436
527
  )
437
- atoms_interacting_force = check_if_atoms_interacting_energy(
438
- model, symbols, ftol
439
- )
528
+ atoms_interacting_force = check_if_atoms_interacting_force(model, symbols, ftol)
440
529
  return atoms_interacting_energy, atoms_interacting_force
441
530
 
442
531
 
@@ -46,7 +46,9 @@ import kim_edn
46
46
  import numpy as np
47
47
  import numpy.typing as npt
48
48
  from ase import Atoms
49
+ from ase.build import bulk
49
50
  from ase.calculators.calculator import Calculator
51
+ from ase.calculators.kim import get_model_supported_species
50
52
  from ase.constraints import FixSymmetry
51
53
  from ase.data import atomic_masses
52
54
  from ase.filters import FrechetCellFilter, UnitCellFilter
@@ -95,6 +97,7 @@ __all__ = [
95
97
  "get_deduplicated_property_instances",
96
98
  "minimize_wrapper",
97
99
  "crystal_input_from_test_generator_line",
100
+ "get_supported_lammps_atom_style",
98
101
  ]
99
102
 
100
103
  # Force tolerance for the optional initial relaxation of the provided cell
@@ -108,6 +111,48 @@ PROP_SEARCH_PATHS_INFO = (
108
111
  )
109
112
 
110
113
 
114
+ def get_supported_lammps_atom_style(model: str) -> str:
115
+ """
116
+ Get the supported LAMMPS atom_style of a KIM model
117
+ """
118
+ from lammps import lammps
119
+
120
+ candidate_atom_styles = ("atomic", "charge", "full")
121
+ banned_species = "electron" # Species in KIM models not understood by ASE
122
+ supported_species = get_model_supported_species(model)
123
+ test_species = None
124
+ for species in supported_species:
125
+ if species not in banned_species:
126
+ test_species = species
127
+ break
128
+ if test_species is None:
129
+ raise RuntimeError(
130
+ "Model appears to only support species not understood by ASE:\n"
131
+ + str(supported_species)
132
+ )
133
+ atoms = bulk(test_species, "fcc", 10.0) # Very low-density FCC lattice
134
+ for atom_style in candidate_atom_styles:
135
+ with lammps(cmdargs=["-sc", "none"]) as lmp, NamedTemporaryFile() as f:
136
+ lmp.command(f"kim init {model} metal unit_conversion_mode")
137
+ atoms.write(f.name, format="lammps-data", atom_style=atom_style)
138
+ try:
139
+ lmp.command(f"read_data {f.name}")
140
+ return atom_style
141
+ except Exception as e:
142
+ if str(e).startswith(
143
+ "ERROR: Incorrect format in Atoms section of data file:"
144
+ ):
145
+ continue
146
+ else:
147
+ msg = (
148
+ "The following unexpected exception was encountered when trying"
149
+ " to determine atom_style:\n" + repr(e)
150
+ )
151
+ print(msg)
152
+ raise e
153
+ raise RuntimeError("Unable to determine supported atom type")
154
+
155
+
111
156
  def _get_optional_source_value(property_instance: Dict, key: str) -> Any:
112
157
  """
113
158
  Function for getting an optional key's source-value, or None if the key
@@ -718,6 +763,14 @@ class KIMTestDriver(ABC):
718
763
  name, os.path.relpath(final_path, output_path)
719
764
  )
720
765
 
766
+ def _get_supported_lammps_atom_style(self) -> str:
767
+ """
768
+ Return the atom_style that should be used when writing LAMMPS data files.
769
+ This atom_style will be compatible with the KIM model this object
770
+ was instantiated with.
771
+ """
772
+ return get_supported_lammps_atom_style(self.kim_model_name)
773
+
721
774
  @property
722
775
  def kim_model_name(self) -> Optional[str]:
723
776
  """
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kim-tools
3
- Version: 0.3.11
3
+ Version: 0.3.13
4
4
  Summary: Base classes and helper routines for writing KIM Tests
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>
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>, Navaneeth Mohan <mohan227@umn.edu>
6
6
  Maintainer-email: ilia Nikiforov <nikif002@umn.edu>
7
7
  Project-URL: Homepage, https://kim-tools.readthedocs.io
8
8
  Project-URL: Issues, https://github.com/openkim/kim-tools/issues
@@ -1,4 +1,4 @@
1
- kim_tools/__init__.py,sha256=YZdzUiZNlEczGQLTPVRxzz5-jGxgJTEaeAK_p-oJu4o,434
1
+ kim_tools/__init__.py,sha256=z9M4HWOpT0qCOUbGIKeUY-Oskrw_ZG6xeXli9iLTyzo,434
2
2
  kim_tools/kimunits.py,sha256=jOxBv9gRVhxPE6ygAIUxOzCAfPI6tT6sBaF_FNl9m-M,5387
3
3
  kim_tools/aflow_util/__init__.py,sha256=lJnQ8fZCma80QVRQeKvY4MQ87oCWu-9KATV3dKJfpDc,80
4
4
  kim_tools/aflow_util/core.py,sha256=mMS2r9ayJJ6ApOFTAIkCZ72Dg3g1EnREbrqe2YEipMo,81273
@@ -2002,7 +2002,7 @@ 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=odRuHQGZl-pcRtkdYvG31_3kW6nt3qwHdKvAOJ-ifwM,31207
2005
+ kim_tools/ase/core.py,sha256=umJY0LV3_zrEZLOXAFoz6AFigxA69sAOBzAGoBTDzxA,34335
2006
2006
  kim_tools/symmetry_util/__init__.py,sha256=uu-ZSUDUTe2P81rkAS3tXverx31s_uZ3wL4SD_dn5aI,86
2007
2007
  kim_tools/symmetry_util/core.py,sha256=eMGgVt9MPcaLi_8jVMJ5UyQHvYbiiAFQ4HdJotnp8dk,43277
2008
2008
  kim_tools/symmetry_util/elasticity.py,sha256=VxJ8wUcsSOPyJ8id6OpKmVlRAbIUIWxtzYJtkvVJIVs,13328
@@ -2023,11 +2023,11 @@ kim_tools/symmetry_util/data/wyck_pos_xform_under_normalizer.json,sha256=6g1YuYh
2023
2023
  kim_tools/symmetry_util/data/wyckoff_multiplicities.json,sha256=qG2RPBd_-ejDIfz-E4ZhkHyRpIboxRy7oiXkdDf5Eg8,32270
2024
2024
  kim_tools/symmetry_util/data/wyckoff_sets.json,sha256=f5ZpHKDHo6_JWki1b7KUGoYLlhU-44Qikw_-PtbLssw,9248
2025
2025
  kim_tools/test_driver/__init__.py,sha256=KOiceeZNqkfrgZ66CiRiUdniceDrCmmDXQkOw0wXaCQ,92
2026
- kim_tools/test_driver/core.py,sha256=ZHS26S8-HxCPTDhv6h6WZ2x7pDQMTu6G1bWD4rPvoz8,99107
2026
+ kim_tools/test_driver/core.py,sha256=vHmhSWix5t95SCmJEapdpZXfJS0ZlbG-8bcmV9O9v9M,101261
2027
2027
  kim_tools/vc/__init__.py,sha256=zXjhxXCKVMLBMXXWYG3if7VOpBnsFrn_RjVpnohDm5c,74
2028
2028
  kim_tools/vc/core.py,sha256=BIjzEExnQAL2S90a_npptRm3ACqAo4fZBtvTDBMWMdw,13963
2029
- kim_tools-0.3.11.dist-info/licenses/LICENSE.CDDL,sha256=I2luEED_SHjuZ01B4rYG-AF_135amL24JpHvZ1Jhqe8,16373
2030
- kim_tools-0.3.11.dist-info/METADATA,sha256=AdNljYaTm6fqCc8eaRcIFX0oeMcsqDTcMPdmqvBPAcs,2033
2031
- kim_tools-0.3.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
2032
- kim_tools-0.3.11.dist-info/top_level.txt,sha256=w_YCpJ5ERigj9te74ln7k64tqj1VumOzM_s9dsalIWY,10
2033
- kim_tools-0.3.11.dist-info/RECORD,,
2029
+ kim_tools-0.3.13.dist-info/licenses/LICENSE.CDDL,sha256=I2luEED_SHjuZ01B4rYG-AF_135amL24JpHvZ1Jhqe8,16373
2030
+ kim_tools-0.3.13.dist-info/METADATA,sha256=7ldqSmsLFyzrEtIeV-wJacw1BEJoj55DgMOupJlycIs,2069
2031
+ kim_tools-0.3.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
2032
+ kim_tools-0.3.13.dist-info/top_level.txt,sha256=w_YCpJ5ERigj9te74ln7k64tqj1VumOzM_s9dsalIWY,10
2033
+ kim_tools-0.3.13.dist-info/RECORD,,