kim_tools.ase package

Submodules

kim_tools.ase.core module

Helper routines for KIM Tests and Verification Checks

exception kim_tools.ase.core.KIMASEError(msg)

Bases: Exception

kim_tools.ase.core.remove_species_not_supported_by_ASE(species)

Remove any species from the 'species' list that are not supported by ASE

kim_tools.ase.core.randomize_species(atoms, species, seed=13)

Given an ASE 'atoms' object, set random element for each atom selected from the list of available 'species' in a way that ensures all are represented with the same probabilities.

kim_tools.ase.core.fractional_coords_transformation(cell)

Given a set of cell vectors, this will return a transformation matrix T that can be used to multiply any arbitrary position to get its fractional coordinates in the basis of those cell vectors.

kim_tools.ase.core.atom_outside_cell_along_nonperiodic_dim(T, atom_coord, pbc, tol=1e-12)

Given a transformation matrix to apply to an atomic position to get its fractional position in the basis of some cell vectors and the corresponding boundary conditions, determine if the atom is outside of the cell along any non-periodic directions (measured using tolerance 'tol'). This is relevant when using an SM from a simulator such as LAMMPS that performs spatial decomposition -- atoms that leave the box along non-periodic dimensions are likely to become "lost."

kim_tools.ase.core.randomize_positions(atoms, pert_amp, seed=13)

Given an ASE 'atoms' object, displace all atomic coordinates by a random amount in the range [-pert_amp, pert_amp] along each dimension. Note that all atomic coordinates must be inside of the corresponding cell along non-periodic dimensions. As each atom is looped over, we continue generating perturbations until the displaced position is inside of the cell along any non-periodic directions (displacing outside the cell along periodic dimensions is allowed, although it's up to the calling function to wrap the positions if they need to be).

kim_tools.ase.core.get_isolated_energy_per_atom(model, symbol, initial_separation=1.0, max_separation=15.0, separation_neg_exponent=4, quit_early_after_convergence=True, energy_tolerance=1e-12)

Construct a non-periodic cell containing a single atom and compute its energy. It tries to iteratively finetune the atomic separation for a dimer up to a specified precision (separation_neg_exponent). If between two successive phases the energy difference is less than energy_tolerance, it stops early, i.e. if 4.0x and 4.00x are within energy_tolerance, it stops at 4.00x. All separations are in Angstroms.

Parameters:
  • model (Union[str, Calculator]) -- KIM model or ASE calculator to use for calculations

  • symbol (str) -- Chemical symbol

  • initial_separation (float) -- Initial separation for dimer calculations

  • max_separation (float) -- maximum separation for dimer calculations

  • separation_neg_exponent (float) -- Number of decimal places to refine the separation

  • quit_early_after_convergence (bool) -- Whether to stop early if energy converges

  • energy_tolerance (float) -- Energy difference tolerance for convergence check

Return type:

float

Returns:

The isolated energy per atom for the requested chemical symbol

kim_tools.ase.core.rescale_to_get_nonzero_energy(atoms, isolated_energy_per_atom, etol)

If the given configuration has a potential energy, relative to the sum of the isolated energy corresponding to each atom present, smaller in magnitude than 'etol' (presumably because the distance between atoms is too large), rescale it making it smaller. The 'isolated_energy_per_atom' arg should be a dict containing an entry for each atomic species present in the atoms object (additional entries are ignored).

kim_tools.ase.core.check_if_atoms_interacting_energy(model, symbols, etol)

First, get the energy of a single isolated atom of each species given in 'symbols'. Then, construct a dimer consisting of these two species and try to decrease its bond length until a discernible difference in the energy (from the sum of the isolated energy of each species) is detected. The 'symbols' arg should be a list or tuple of length 2 indicating which species pair to check, e.g. to check if Al interacts with Al, one should specify ['Al', 'Al'].

kim_tools.ase.core.check_if_atoms_interacting_force(model, symbols, ftol)

Construct a dimer and try to decrease its bond length until the force acting on each atom is larger than 'ftol' in magnitude. The 'symbols' arg should be a list or tuple of length 2 indicating which species pair to check, e.g. to check if Al interacts with Al, one should specify ['Al', 'Al'].

kim_tools.ase.core.check_if_atoms_interacting(model, symbols, check_energy=True, etol=1e-06, check_force=True, ftol=0.001)

Check to see whether non-trivial energy and/or forces can be detected using the current model. The 'symbols' arg should be a list or tuple of length 2 indicating which species pair to check, e.g. to check if Al interacts with Al, one should specify ['Al', 'Al'].

kim_tools.ase.core.rescale_to_get_nonzero_forces(atoms, ftol)

If the given configuration has force components which are all smaller in absolute value than 'ftol' (presumably because the distance between atoms is too large), rescale it to be smaller until the largest force component in absolute value is greater than or equal to 'ftol'. In a perfect crystal, the crystal is rescaled until the atoms on the surface reach the minimum value (internal atoms padded with another atoms around them will have zero force). Note that any periodicity is turned off for the rescaling and then restored at the end.

kim_tools.ase.core.perturb_until_all_forces_sizeable(atoms, pert_amp, minfact=0.1, maxfact=5.0, max_iter=1000)

Keep perturbing atoms in the ASE 'atoms' object until all force components on each atom have an absolute value of least 'minfact' times the largest (in absolute value) component across all force vectors coming in. Note that all atomic coordinates must be inside of the corresponding cell along non-periodic dimensions. Perturbations leading to a force component on any atom that is larger than 'maxfact' times the largest force component coming in are rejected. Perturbations leading to atoms outside of the span across x, y, and z of the atomic positions coming in or outside of the simulation cell along non-periodic directions are also rejected. The process repeats until max_iter iterations have been reached, at which point an exception is raised.

kim_tools.ase.core.get_model_species_minimum_cutoff(model, species, xtol=1e-08, etol_coarse=1e-06, etol_fine=1e-15, max_bisect_iters=1000, max_upper_cutoff_bracket=20.0)

Given a model and a list of species, construct all permutations of dimers and compute their energy-cutoff i.e the distance at which their interaction becomes non-trivial. Return the smallest such distance among all pairs of species. This method calls get_model_energy_cutoff

Return type:

float

kim_tools.ase.core.get_model_energy_cutoff(model, symbols, xtol=1e-08, etol_coarse=1e-06, etol_fine=1e-15, max_bisect_iters=1000, max_upper_cutoff_bracket=20.0)

Compute the distance at which energy interactions become non-trival for a given model and a species pair it supports. This is done by constructing a dimer composed of these species in a large finite box, increasing the separation if necessary until the total potential energy is within 'etol_fine' of the sum of the corresponding isolated energies, and then shrinking the separation until the energy differs from that value by more than 'etol_coarse'. Using these two separations to bound the search range, bisection is used to refine in order to locate the cutoff. The 'symbols' arg should be a list or tuple of length 2 indicating which species pair to check, e.g. to get the energy cutoff of Al with Al, one should specify ['Al', 'Al'].

This function is based on the content of the DimerContinuityC1__VC_303890932454_002 Verification Check in OpenKIM [1-3].

Return type:

float

[1] Tadmor E. Verification Check of Dimer C1 Continuity v002. OpenKIM; 2018.

doi:10.25950/43d2c6d5

[2] Tadmor EB, Elliott RS, Sethna JP, Miller RE, Becker CA. The potential of

atomistic simulations and the Knowledgebase of Interatomic Models. JOM. 2011;63(7):17. doi:10.1007/s11837-011-0102-6

[3] Elliott RS, Tadmor EB. Knowledgebase of Interatomic Models (KIM) Application

Programming Interface (API). OpenKIM; 2011. doi:10.25950/ff8f563a

kim_tools.ase.core._species_label(species_list)
Return type:

str

kim_tools.ase.core._round_alat(alat)
Return type:

float

kim_tools.ase.core.fcc_atoms_in_supercell(ncells_per_side)

Calculate the total number of atoms in an FCC supercell.

Parameters:

ncells_per_side (int) -- The number of primitive unit cells aligned along a single axis of the supercell box.

Return type:

int

Returns:

The total count of atom sites within the specified supercell as an integer.

kim_tools.ase.core.make_fcc_template(species_list, ncells_per_side=1)

Create a generic FCC template large enough to contain at least len(species_list) atoms. The actual species are assigned later.

Parameters:
  • species_list (list[str]) -- Chemical symbols of the target elements to be added later, used here strictly to determine the minimum required atom count.

  • ncells_per_side (int) -- Initial number of unit cells along each axis to define the supercell size. Dynamically increments if the resulting supercell is too small. Defaults to DEFAULT_FCC_NCELLS_PER_SIDE.

Returns:

  • atoms: An ASE Atoms object representing the generated hydrogen-based Face-Centered Cubic supercell template.

  • ncells_per_side: The final integer number of unit cells per side used to satisfy the atom count constraint.

Return type:

A tuple containing

kim_tools.ase.core.make_fcc_reference_config(species_list, ncells_per_side=1, seed=13)

Create one fixed FCC reference configuration.

All later energy evaluations use this same atom ordering, same species assignment, same scaled positions, and same number of unit cells. Only the lattice constant changes.

Parameters:
  • species_list (list[str]) -- Chemical symbols of the elements to assign to the lattice sites.

  • ncells_per_side (int) -- Number of unit cells along each axis to define the supercell dimensions. Defaults to DEFAULT_FCC_NCELLS_PER_SIDE.

  • seed (int) -- Random seed used to determine reproducible chemical species ordering and fractional atom site placements. Defaults to 13.

Return type:

dict

Returns:

A dictionary representation of the reference configuration, specifying atom positions, species mappings, and structural configuration bounds.

kim_tools.ase.core.generate_fcc_compute_energy_from_reference(model_name, reference_config, alat)

Return (total_energy, ncells_per_side) for the same FCC reference configuration scaled to the requested lattice constant.

Parameters:
  • model_name (str) -- Name of interatomic potential model

  • reference_config (dict) -- The baseline crystal structure configuration used as the scaling template.

  • alat (float) -- The target lattice parameter 'a' (in Angstroms) to scale the reference cell configuration to.

Return type:

Optional[Tuple[float, int]]

Returns:

A tuple containing the calculated total potential energy (float) and the number of unit cells per side (int) for the scaled system, or None if the energy calculation fails or encounters invalid state constraints.

kim_tools.ase.core._coarse_scan_worker(model_name, reference_config, a_start, a_stop, del_a, result_queue)

Child process for reverse coarse scan.

Scans from a_start down to a_stop. Each successful point is sent to the parent immediately. If this child segfaults, the parent keeps all points already sent.

Parameters:
  • model_name (str) -- Name of interatomic potential model

  • reference_config (dict) -- The baseline crystal structure configuration used as the starting template.

  • a_start (float) -- Starting lattice parameter 'a' (in Angstroms) for the reverse scan.

  • a_stop (float) -- Ending lattice parameter 'a' (in Angstroms) for the reverse scan.

  • del_a (float) -- Step size decrement used to step through the lattice parameters.

  • result_queue -- A multiprocessing.Queue object used to stream successful energy-lattice points back to the parent process immediately upon evaluation.

kim_tools.ase.core._format_child_exit_reason(exitcode)
Return type:

str

kim_tools.ase.core.coarse_scan_reverse_safe(model_name, reference_config, a_start=12.0, a_stop=1.5, del_a=0.1, timeout=600.0)

Run a reverse coarse scan in one child process.

If the child crashes or segfaults, do not restart it. Return all successful energy-alat points collected before the crash.

Parameters:
  • model_name (str) -- Name of interatomic potential model

  • reference_config (dict) -- The baseline crystal structure configuration used as the starting template.

  • a_start (float) -- Starting lattice parameter 'a' (in Angstroms) for the scan. Defaults to 12.0.

  • a_stop (float) -- Ending lattice parameter 'a' (in Angstroms) for the scan. Defaults to 1.5.

  • del_a (float) -- Absolute step size decrement for the lattice parameter grid points. Defaults to 0.1.

  • timeout (float) -- Maximum execution time in seconds for the entire subprocess run before forcing termination. Defaults to 600.0.

Return type:

dict

Returns:

A dictionary containing partial or complete results up until process exit, including successful lattice parameters ('alats') and matched energy steps.

kim_tools.ase.core._local_minima_indices(energies_per_atom)

Find the array indices of local energy minima using peak detection.

Inverts the energy values to transform local minima into local maxima peaks, then locates them using SciPy's peak finder while discarding any non-finite results.

Parameters:

energies_per_atom (list[float]) -- A sequence of calculated energy values per atom over the scan grid.

Return type:

list[int]

Returns:

A list of integer indices pinpointing the locations of valid local minima within the input sequence.

kim_tools.ase.core._energy_is_within_bounds(energy_per_atom, energy_bound)

Check if the magnitude of the given energy value falls within specific bounds.

Ensures that the parsed energy value is a finite numerical value before comparing its absolute magnitude against the minimum and maximum limits.

Parameters:
  • energy_per_atom (float) -- The calculated energy value per atom to evaluate.

  • energy_bound (tuple[float, float]) -- A tuple containing the (minimum, maximum) acceptable absolute energy thresholds.

Return type:

bool

Returns:

True if the absolute energy magnitude is finite and within the bounds, otherwise False.

kim_tools.ase.core._starting_points_from_scan(scan, max_starting_points, energy_bound)

Identify and sort viable starting points for optimization from a coarse scan.

Finds local energy minima from scan data, filters them by energy limits, and ranks them from lowest to highest energy to prioritize the most stable configurations.

Parameters:
  • scan (dict) -- Dictionary containing lists of lattice parameters ('alats') and corresponding 'energies_per_atom' from the coarse sweep.

  • max_starting_points (int) -- Maximum number of candidate minima to return after sorting.

  • energy_bound (tuple[float, float]) -- Valid range (min, max) for acceptable configuration energies per atom.

Return type:

list[dict]

Returns:

A list of dictionaries, where each item contains the original index, lattice parameter ('alat'), and energy value of a valid starting point.

kim_tools.ase.core._nelder_mead_worker(model_name, reference_config, start_alat, a_min, a_max, energy_bound, queue)

Run Nelder-Mead in a child process using the same reference FCC configuration as the coarse scan.

Parameters:
  • model_name (str) -- Name of interatomic potential model

  • reference_config (dict) -- The baseline crystal structure configuration used as the starting template.

  • start_alat (float) -- Initial lattice parameter 'a' value (in Angstroms) to begin the optimization.

  • a_min (float) -- Minimum allowable bounding value for the lattice parameter 'a'.

  • a_max (float) -- Maximum allowable bounding value for the lattice parameter 'a'.

  • energy_bound (tuple[float, float]) -- Valid range (min, max) for acceptable configuration energies.

  • queue -- A multiprocessing.Queue object used to safely pass the optimization results back to the parent process.

kim_tools.ase.core.scipy_nelder_mead_safe(model_name, reference_config, start_alat, a_min, a_max, energy_bound, timeout=600.0)

Run Nelder-Mead in a child process.

This isolates crashes/segfaults from the parent process.

Parameters:
  • model_name (str) -- Name of the interatomic potential model

  • reference_config (dict) -- The baseline crystal structure configuration used as the starting template.

  • start_alat (float) -- Initial lattice parameter 'a' value (in Angstroms) to begin the optimization.

  • a_min (float) -- Minimum allowable bounding value for the lattice parameter 'a'.

  • a_max (float) -- Maximum allowable bounding value for the lattice parameter 'a'.

  • energy_bound (tuple[float, float]) -- Valid range (min, max) for acceptable configuration energies.

  • timeout (float) -- Maximum execution time in seconds before terminating the child process worker. Defaults to 600.0.

Return type:

dict

Returns:

A dictionary containing the optimization outcome status, evaluations, and the refined equilibrium lattice coordinates if successful.

kim_tools.ase.core._failure_config_result(species_list, configuration_type, reference_config, scan, starting_points, attempts, reason, bounds)

Generate a uniform dictionary summary for a failed configuration search.

Populates default error indicators like negative dimensions or None values for missing measurements while preserving logs, boundaries, and historical attempts for later diagnosis.

Parameters:
  • species_list (list[str]) -- Chemical symbols of the elements included in the system

  • configuration_type (str) -- A label indicating the structural type

  • reference_config (Optional[dict]) -- The generated baseline crystal structure, or None if generation failed.

  • scan (Optional[dict]) -- Historical trace of the initial energy-versus-lattice coarse scan, or None if skipped.

  • starting_points (list[dict]) -- Local energy minima detected during the coarse scan to be used for optimization.

  • attempts (list[dict]) -- List of optimization traces produced by downstream Nelder-Mead subprocess workers.

  • reason (str) -- A string identifier explaining why the search workflow halted.

  • bounds (dict) -- Dictionary defining coordinate search window ranges and step delta sizes.

Return type:

dict

Returns:

A dictionary containing error statuses, tracking identifiers, and any partial execution traces collected before the failure occurred.

kim_tools.ase.core._equilibrate_one_config(model_name, species_list, configuration_type, energy_bound, coarse_del_a, coarse_timeout, nelder_mead_timeout, max_starting_points, ncells_per_side=1, seed=13, coarse_a_start=12.0, coarse_a_stop=1.5)

Equilibrate a single FCC atomic configuration using a sequential protocol.

Executes a high-level orchestration that generates a reference crystal, scans lattice constants to find energy minima, and applies a Nelder-Mead simplex search to optimize structure bounds.

Parameters:
  • model_name (str) -- Name of the interatomic potential model

  • species_list (list[str]) -- Chemical symbols of the elements to include in the system

  • configuration_type (str) -- A label indicating the structural type

  • energy_bound (tuple[float, float]) -- Valid range (min, max) for acceptable configuration energies.

  • coarse_del_a (float) -- Step size for the lattice parameter 'a' during coarse scans.

  • coarse_timeout (float) -- Maximum execution time in seconds for the coarse scan subprocess.

  • nelder_mead_timeout (float) -- Maximum execution time in seconds for each Nelder-Mead optimization subprocess.

  • max_starting_points (int) -- Maximum number of local minima to evaluate using Nelder-Mead relaxation.

  • ncells_per_side (int) -- Number of unit cells along each axis to define the supercell size.

  • seed (int) -- Random seed for reproducible structure generation and atom placement.

  • coarse_a_start (float) -- Starting lattice parameter 'a' (in Angstroms) for the reverse scan.

  • coarse_a_stop (float) -- Ending lattice parameter 'a' (in Angstroms) for the reverse scan.

Return type:

dict

Returns:

A dictionary containing the metadata, execution history, and details of either a successful equilibrium search or a recorded failure.

kim_tools.ase.core._finite_positive_mean(values)

Calculate the mean of finite, positive numbers in a list.

Filters out non-finite numbers (NaN, Inf) and values less than or equal to zero before computing the average.

Parameters:

values (list[float]) -- A list of floats to be filtered and averaged.

Return type:

float

Returns:

The arithmetic mean of the remaining valid values as a float, or -1.0 if no values survive the filtering process.

kim_tools.ase.core._minimal_success_result(full_result)

Extract a minimal summary from a successful full result dictionary.

Parameters:

full_result (dict) -- The complete dictionary of results containing metadata, scan details, and final optimization outputs.

Return type:

dict

Returns:

A dictionary containing parsed information about the equilibrium configuration, including energy values, cell parameters, and structural metadata.

kim_tools.ase.core.find_equilibrium_config_FCC(model_name, species_list, energy_bound=(0.05, 500.0), coarse_del_a=0.1, mixed_coarse_del_a=0.1, coarse_timeout=600.0, nelder_mead_timeout=600.0, max_starting_points=6, ncells_per_side=1, seed=13, coarse_a_start=12.0, coarse_a_stop=1.5)

Find an FCC equilibrium configuration.

Protocol:
  1. For each mono species, create one fixed FCC reference configuration.

  2. Run one reverse coarse scan subprocess from coarse_a_start to coarse_a_stop.

  3. Keep all energy-alat points collected before any child crash.

  4. Find local minima using scipy.signal.find_peaks(-E).

  5. Run Nelder-Mead subprocesses from minima sorted by coarse energy.

  6. Return after the first successful Nelder-Mead result.

  7. For mixed species, repeat the same protocol using one fixed mixed reference configuration.

Parameters:
  • model_name (str) -- Name of interatomic potential model.

  • species_list (list[str]) -- Chemical symbols of the elements to include in the system

  • energy_bound (tuple[float, float]) -- Valid range (min, max) for configuration energies.

  • coarse_del_a (float) -- Step size for the lattice parameter 'a' for monospecies coarse scans.

  • mixed_coarse_del_a (float) -- Step size for the lattice parameter 'a' for mixed-species coarse scans.

  • coarse_timeout (float) -- Maximum execution time in seconds for the coarse scan subprocess.

  • nelder_mead_timeout (float) -- Maximum execution time in seconds for each Nelder-Mead optimization subprocess.

  • max_starting_points (int) -- Maximum number of local minima to evaluate using Nelder-Mead relaxation.

  • ncells_per_side (int) -- Number of unit cells along each axis to define the supercell size.

  • seed (int) -- Random seed for reproducible structure generation and atom placement.

  • coarse_a_start (float) -- Starting lattice parameter 'a' (in Angstroms) for the reverse scan.

  • coarse_a_stop (float) -- Ending lattice parameter 'a' (in Angstroms) for the reverse scan.

Return type:

dict

Returns:

A dictionary containing the successful equilibrium configuration results and metadata.

Module contents