import numpy as np
from EPWpy.utilities.constants import *
ibrav_to_matrix = {
1: lambda a, *_: np.array([[a,0,0],[0,a,0],[0,0,a]]), # cubic P
2: lambda a, *_: (a/2)*np.array([[-1,0,1],[0,1,1],[-1,1,0]]), # fcc
3: lambda a, *_: (a/2)*np.array([[1,1,1],[-1,1,1],[-1,-1,1]]), # bcc
4: lambda a,c, *_: np.array([[a,0,0],[0,a,0],[0,0,c]]), # tetragonal P
6: lambda a,c, *_: (a/2)*np.array([[1,-1,0],[1,1,0],[0,0,2*c/a]]), # tetragonal I
8: lambda a,c, *_: np.array([[a,0,0],[0,a,0],[0,0,c]]), # orthorhombic P
9: lambda a,b,c, *_: np.array([[a,0,0],[0,b,0],[0,0,c]]), # orthorhombic P (a≠b≠c)
}
[docs]
def atom_pos_lat_crystal(Data):
"""
Returns atomic_positions in crystal and cartesian co-ordinates
"""
ibrav = Data['ibrav']
celldm = Data['celldm']
atom_pos = Data['atom_pos']
cell_parameters = Data['cell_parameters']
cell_type = Data['cell_type']
atom_type = Data['atom_pos_type']
if (cell_type == 'bohr'):
lattice_vec = cell_parameters*Bohr2Ang
if (ibrav == 0):
lattice_vec = cell_parameters
else:
a0 = float(celldm['1'])#(1,1.0)
alat = a0*Bohr2Ang # Bohr → Å
if ibrav in [1,2,3]:
# print(alat,celldm)
lattice_vec = ibrav_to_matrix[ibrav](alat)
elif ibrav in [4,6,8]:
c_over_a = float(celldm['3'])#,1.0)
c_len = c_over_a*alat
lattice_vec = ibrav_to_matrix[ibrav](alat,c_len)
elif ibrav == 9:
b_over_a = float(celldm['2'])#,1.0)
c_over_a = float(celldm['3'])#,1.0)
b_len = b_over_a*alat
c_len = c_over_a*alat
lattice_vec = ibrav_to_matrix[ibrav](alat,b_len,c_len)
else:
raise NotImplementedError(f"ibrav={ibrav} not implemented")
if (atom_type == 'bohr'):
atom_pos2 = atom_pos*Bohr2Ang
elif (atom_type == 'angstrom'):
atom_pos2 = atom_pos
else:
atom_pos2=np.zeros((len(atom_pos[:,0]),len(atom_pos[0,:])),dtype=float)
for j in range(len(atom_pos[:,0])):
atom_pos2[j,:]=atom_pos[j,0]*lattice_vec[0,:]+atom_pos[j,1]*lattice_vec[1,:]+atom_pos[j,2]*lattice_vec[2,:]
#atom_pos2 = atom_pos @ lattice_vec.T
return(atom_pos2,lattice_vec)