I’m currently working on building a LCE for KRA barriers according to Van der Ven et al. (DOI: 10.1103/PhysRevB.64.184307) and Zhang and Sluiter (DOI: 10.1007/s11669-015-0427-x). My goal is to train two CEs (one for configurational (initial/final state) energies and one for KRA barriers) to calculate energy barriers for a kinetic Monte Carlo simulation in which I am modelling H diffusion on the tetrahedral interstitial sites in vacancy-free BCC Fe. I have used ICET to train a CE to predict configurational energies, but I’m currently struggling to figure out how to use a LocalOrbitListGenerator and generate_local_orbit_list to customize the cluster space to build an LCE (and I have not been able to find any tutorials besides ICET’s “Customizing cluster spaces” one, which doesn’t mention these classes/functions). I have labelled the “swapping pair” (H-occupied T site and empty adjacent T site) in the training configurations according to Zhang and Sluiter’s description (alternatively, I tried adding another sublattice whose sites are midpoints between adjacent T sites to represent transition states, but this made training the CE extremely slow), like so (partial code):
import numpy as np
from icet.core.structure import Structure
from icet.core.local_orbit_list_generator import LocalOrbitListGenerator
from icet.tools import Constraints
from icet import ClusterSpace, StructureContainer, ClusterExpansion
structure = Structure.from_atoms(TEMPLATE.atoms)
cs = ClusterSpace(TEMPLATE.atoms, cutoffs=[3.0,3.0,3.0,3.0], chemical_symbols=chemical_symbols)
lolg = LocalOrbitListGenerator(orbit_list=cs.orbit_list,structure=structure,fractional_position_tolerance=cs.fractional_position_tolerance)
offset = (np.floor(np.round(np.dot(MID_CART_POS, np.linalg.inv(cs.primitive_structure.cell[:])),6)).astype(int).tolist())
supercell_orbit_list = lolg.generate_local_orbit_list(offset=offset, self_contained=True)
But now I am unsure of how to proceed to creating constraints based on the included/excluded orbits (this is actually my question).
sc = StructureContainer(cs)
#populate sc with training configurations
constraints = Constraints(???)
x, y = sc.get_fit_data()
x_constrained = constraints.transform(x)
opt = CrossValidationEstimator(fit_data=(x_constrained, y), fit_method='ardr', max_iter=100000)
opt.validate()
opt.train()
print(opt)
params = constraints.inverse_transform(opt.parameters)
ce = ClusterExpansion(cs, params)
While stuck on this, my alternative approach to calculating the barriers involves training a CE on initial/final state energies, and then another CE on full transition state energies (which is not an LCE) with the swapping pair labelled (in both cases, the RMSE (~0.2 eV) is significantly larger than the barrier heights (~0.043 eV) I need to calculate). For additional context: all training configurations are cubic 5 x 5 x 5 BCC Fe supercells, with a lattice parameter of 2.867 A, 0% to 5% of tetrahedral interstitials occupied by H, generated using ASE’s “crystal()” with relaxation done using LAMMPS, LBFGS (fmax=1e-5, steps=2000), Ito’s ML IAP (DOI: 10.1016/j.ijhydene.2026.155600) with ZPE correction done using Vibrations (delta=0.01) on only the H atoms (for improved efficiency, given the large mass disparity between Fe and H, as justified by Jiang and Carter, DOI: 10.1103/PhysRevB.70.064102), and saddle point searches calculated using CI-NEB (first without climbing image, fmax=0.05 and steps=1000; then with climbing image, fmax=0.02 and steps=1000) and refined using Dimer (fmax=1e-5, steps=5000); configurations that did not converge were excluded from the training set). I’m hoping that an LCE for KRA barriers would exhibit better fitting stats. I have also tried using KMCpy, but sparse documentation made it difficult to figure out. Any advice/help would be appreciated ![]()