Common Neighbor Analysis (CNA)#
Common Neighbor Analysis identifies the local crystal structure around each atom. pyscal supports both standard CNA and adaptive CNA.
CNA classifies atoms as:
1 = FCC
2 = HCP
3 = BCC
0 = Other / disordered
import pyscal
from pyscal.structures import make_crystal
from ase.io import read
import numpy as np
Basic CNA#
common_neighbor_analysis finds neighbors internally (adaptive CNA by default), so you don’t need to call find_neighbors first. It returns a dict of counts.
fcc = make_crystal("fcc", lattice_constant=3.6, repetitions=(4, 4, 4))
cna = pyscal.common_neighbor_analysis(fcc)
print(f"CNA result: {cna}")
# Per-atom structure IDs are stored in atoms.arrays["pyscal_structure"]
print(f"Per-atom values (unique): {np.unique(fcc.arrays['pyscal_structure'])}")
CNA result: {'others': 0, 'fcc': 256, 'hcp': 0, 'bcc': 0, 'ico': 0}
Per-atom values (unique): [1]
Comparing Structures#
structures = {
"FCC": make_crystal("fcc", lattice_constant=3.6, repetitions=(4, 4, 4)),
"BCC": make_crystal("bcc", lattice_constant=2.87, repetitions=(4, 4, 4)),
"HCP": make_crystal("hcp", lattice_constant=3.2, repetitions=(4, 4, 4), ca_ratio=1.633),
}
for name, s in structures.items():
cna = pyscal.common_neighbor_analysis(s)
print(f"{name}: {cna}")
FCC: {'others': 0, 'fcc': 256, 'hcp': 0, 'bcc': 0, 'ico': 0}
BCC: {'others': 0, 'fcc': 0, 'hcp': 0, 'bcc': 128, 'ico': 0}
HCP: {'others': 0, 'fcc': 0, 'hcp': 256, 'bcc': 0, 'ico': 0}
Reading from File#
atoms = read("conf.fcc.dump", format="lammps-dump-text")
cna = pyscal.common_neighbor_analysis(atoms)
print(f"From file: {cna}")
From file: {'others': 439, 'fcc': 564, 'hcp': 0, 'bcc': 5, 'ico': 0}
Diamond Structure Identification#
diamond_structure identifies diamond cubic and diamond hexagonal structures.
Classification codes:
1 = Cubic diamond
2 = Cubic diamond (1st neighbor)
3 = Hexagonal diamond
4 = Hexagonal diamond (1st neighbor)
0 = Other
dia = make_crystal("diamond", lattice_constant=5.43, repetitions=(3, 3, 3))
result = pyscal.diamond_structure(dia)
print(f"Diamond: {result}")
Diamond: {'others': 0, 'cubic diamond': 216, 'cubic diamond 1NN': 0, 'cubic diamond 2NN': 0, 'hex diamond': 0, 'hex diamond 1NN': 0, 'hex diamond 2NN': 0}