import spglib as spg
import ase
import ase.io
import numpy as np
Mapping of DOFs to minimal set
procedures for mapping degrees of freedom in the supercell to the minimal set of DOFs in the primitive unit cell.
from ase import spacegroup as sg
from hecss.util import get_cell_data
# cryst = ase.io.read('/home/jochym/cryst/TiO2_hecss/PBE_2x2x4/uc/CONTCAR')
# cryst = ase.io.read('/home/jochym/cryst/TiO2_hecss/PBE_Tetra/uc/CONTCAR')*(2,2,4)
# cryst = ase.io.read('/home/pastukh/Czech.calculation/sc/CONTCAR')
= ase.io.read('example/VASP_3C-SiC_calculated/2x2x2/sc/CONTCAR') cryst
= spg.find_primitive(get_cell_data(cryst))
puc = ase.Atoms(cell=puc[0], scaled_positions=puc[1], numbers=puc[2], pbc=True)
cryst_pc = spg.get_symmetry(get_cell_data(cryst_pc))
sym = spg.get_symmetry_dataset(get_cell_data(cryst_pc))
symds spg.get_spacegroup(get_cell_data(cryst_pc))
'F-43m (216)'
= sg.get_spacegroup(cryst_pc)
SG SG
Spacegroup(216, setting=1)
sg.get_basis(cryst_pc)
array([[0.75, 0.75, 0.75],
[0. , 0. , 0. ]])
= 0.01
eps = eps*np.diag(np.ones(3))
dv = {n:v for n, v in zip((0,1,2),dv)}
uvec uvec
{0: array([0.01, 0. , 0. ]),
1: array([0. , 0.01, 0. ]),
2: array([0. , 0. , 0.01])}
def find_key(val, dic):
for k, v in dic.items():
if np.allclose(v, val):
return k
= {}
eqdir for sp in set(symds['equivalent_atoms']):
= symds['mapping_to_primitive'][sp]
pci print(sp, pci, puc[1][pci], puc[2][pci])
= puc[1][pci]
pos = {}
m for n, d in uvec.items():
= pos+d
v =set()
m[n]for elp in SG.equivalent_lattice_points([v]):
# if np.allclose(v, elp):
# continue
if np.any(elp - pos < 0):
continue
if np.all(np.abs(elp - pos) < 2*eps):
= v-pos
di = elp-pos
df |={find_key(elp-pos, uvec)}
m[n]# print(find_key(v-pos, uvec), '->', find_key(elp-pos, uvec))
# print(m)
for k, v in m.items():
print(k, '->', sorted(v)[0])
= np.array([sorted(v)[0] for k, v in sorted(m.items())])
eqdir[sp] print(eqdir)
# print(SG.tag_sites(cryst_pc.get_scaled_positions()))
0 0 [0.75 0.75 0.75] 6
0 -> 0
1 -> 0
2 -> 0
1 1 [0. 0. 0.] 14
0 -> 0
1 -> 0
2 -> 0
{0: array([0, 0, 0]), 1: array([0, 0, 0])}
= symds['equivalent_atoms'][spg.get_symmetry_dataset(get_cell_data(cryst))['mapping_to_primitive']] at_map
= cryst.copy()
dc dc.rattle()
= dc.get_positions() - cryst.get_positions() dx
= {ai:dx[at_map == ai] for ai in set(at_map)} d_avg
for ai, eqd in eqdir.items():
for di in set(eqd):
print(ai, di, d_avg[ai][:,eqd==di].shape, d_avg[ai][:,eqd==di].std())
0 0 (32, 3) 0.0009203960620541905
1 0 (32, 3) 0.0009473878538096573
64),dtype=int)].shape cryst.get_scaled_positions()[np.zeros((
(64, 3)
64,2)), dtype=int) np.array(np.zeros((
array([[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]])