Source code for clease.montecarlo.constraints.constrain_element_insert_by_basis

import numpy as np
from clease.datastructures import SystemChanges
from .mc_constraint import MCConstraint


[docs]class ConstrainElementInserts(MCConstraint): """ Constrain inserting the elements by basis. This constraint is intended to be used together with SGCMonteCarlo atoms: Atoms object ASE Atoms object used in the MC simulation index_by_basis: list Indices ordered by basis (same as `index_by_basis` parameter in `ClusterExpansionSettings`). If an Atoms object has 10 sites where the first 4 belongs to the first basis, the next 3 belongs to the next basis and the last 3 belongs to the last basis, the `index_by_basis` would be [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]] element_by_basis: list List specifying which elements are allowed in each basis. If there are two basis where Si and O are allowed in the fist basis while Si and C are allowed in the second basis, the argument would be [['Si', 'O'], ['Si', 'C']] """ def __init__(self, atoms, index_by_basis, element_by_basis): self.basis = np.zeros(len(atoms), dtype=int) for i, indices in enumerate(index_by_basis): for x in indices: self.basis[x] = i num_basis = len(element_by_basis) unique_elem = set(x for item in element_by_basis for x in item) self.element_allowed = {x: np.zeros(num_basis, dtype=np.uint8) for x in unique_elem} # Initialize the element lookup for i, elements in enumerate(element_by_basis): for elem in elements: self.element_allowed[elem][i] = 1 def __call__(self, system_changes: SystemChanges): for change in system_changes: indx = change.index new_elem = change.new_symb basis = self.basis[indx] if self.element_allowed[new_elem][basis] == 0: return False return True