Source code for EPWpy.structure.position_atoms

import numpy as np
#import matplotlib.pyplot as plt
import argparse
import math
import cmath
import sys
import warnings

if not sys.warnoptions:
    warnings.simplefilter("ignore")

[docs] def shuffle_ar(atom_pos,natoms,ntot): import random N=int(natoms[-1]) aa=[] for i in range(N): aa.append(i+int(ntot)-N) aa=np.array(aa) aa=random.sample(aa,len(aa)) atom_pos2=np.zeros((len(aa),3),dtype=float) for i in range(len(aa)): l=i+ntot-N atom_pos2[i,:]=atom_pos[aa[i],:] atom_pos[ntot-N:ntot,:]=atom_pos2[:,:] return(atom_pos)
[docs] def unit2prim(lattice_vec): a = np.sqrt(lattice_vec[0,0]**2 + lattice_vec[0,1]**2 + lattice_vec[0,2]**2) return(a,lattice_vec[:,:]/a)
[docs] def add_atoms(atom_pos,pos_new): pos_new=pos_new.astype('int') N=len(atom_pos[:,0]) atom_pos2=np.zeros((N,3),dtype=float) for i in range(N): atom_pos2[i,:]=atom_pos[i,:] for i in range(len(pos_new)): T=atom_pos[N-i-1,:] B=atom_pos[pos_new[i]-1,:] atom_pos2[pos_new[i]-1,:]=T atom_pos2[N-i-1,:]=B return atom_pos2
[docs] def gen_POSCAR(lattice_vec,atom_pos,natoms,material,tag='1'): with open(f'POSCAR_new_{tag}.vasp','w') as f: f.write(' system\n') f.write(' 1\n') f.write(' '+str(lattice_vec[0,0])+' '+str(lattice_vec[0,1])+' '+str(lattice_vec[0,2])+'\n') f.write(' '+str(lattice_vec[1,0])+' '+str(lattice_vec[1,1])+' '+str(lattice_vec[1,2])+'\n') f.write(' '+str(lattice_vec[2,0])+' '+str(lattice_vec[2,1])+' '+str(lattice_vec[2,2])+'\n') for mat in material: f.write(f' {mat}') f.write('\n') for atom in natoms: f.write(f' {atom}') f.write('\n') f.write(' Direct\n') for i in range(len(atom_pos[:,0])): f.write(' '+str(atom_pos[i,0])+' '+str(atom_pos[i,1])+' '+str(atom_pos[i,2])+'\n')
[docs] def gen_xyz(atom_pos,natoms,mat): with open('xyz','w') as f: f.write(str(sum(natoms))+'\n') f.write('Molecule (in Angstrom)\n') for i in range(len(atom_pos[:,0])): f.write(str(mat[i])+' '+str(atom_pos[i,0])+' '+str(atom_pos[i,1])+' '+str(atom_pos[i,2])+'\n')
[docs] def dist(A,B): d=math.sqrt((A[0]-B[0])**2+(A[1]-B[1])**2+(A[2]-B[2])**2) return d
[docs] def anglecalc(Bx,By,x_pos,y_pos): X=(Bx-x_pos) Y=(By-y_pos) if ((Y>=0)&(X<0)): angle=-math.atan((-Y/X))+math.radians(180) elif((Y<=0)&(X<0)): angle=math.atan(((-Y)/(-X)))+math.radians(180) elif((Y<=0)&(X>0)): angle=-math.atan(-Y/X)+math.radians(360) else: try: angle=math.atan(Y/X) except RuntimeWarning: angle=0 if(np.isnan(angle)==True): angle=math.radians(90) return(angle)
[docs] def angle(A,B): D=math.sqrt((A[0]-B[0])**2+(A[1]-B[1])**2) if((A[0]**2+A[1]**2)>(B[0]**2+B[1]**2)): phi_xz=anglecalc(0,B[2],D,A[2]) else: phi_xz=anglecalc(D,B[2],0,A[2]) phi_xy=anglecalc(B[0],B[1],A[0],A[1]) phi_yz=anglecalc(B[1],B[2],A[1],A[2]) return([phi_xy,phi_xz,phi_yz])
[docs] def mat_calc(atom_pos,natoms,materials): near_neigh=[] mat=[] l=0 prev=0 for i in range(len(atom_pos[:,0])): B=[] if(i>=natoms[l]+prev): prev=prev+natoms[l] l=l+1 if(i<(natoms[l]+prev)): mat.append(materials[l]) return(mat)
[docs] def N_near_neigh_calc(atom_pos,atom_pos2,lattice_vec,a,min_bond,min_bond2,control): #from .globvar import Repeat_vec as L L=np.array([[0,0,0],[0,1,0],[1,0,0],[-1,0,0],[0,-1,0],[1,1,0],[1,-1,0],[-1,1,0],[-1,-1,0] ,[0,0,1],[0,1,1],[1,0,1],[-1,0,1],[0,-1,1],[1,1,1],[1,-1,1],[-1,1,1],[-1,-1,1] ,[0,0,-1],[0,1,-1],[1,0,-1],[-1,0,-1],[0,-1,-1],[1,1,-1],[1,-1,-1],[-1,1,-1],[-1,-1,-1]]) N_near_neigh=[] N_bond=[] N_angle=[] N_occ=[] l=0 prev=0 for i in range(len(atom_pos2[:,0])): B=[] Bd=[] angle2=[] occ=[] van_der=[] for j in range(len(atom_pos2[:,0])): t=0 for m in range(len(L[:,0])): blength=dist(atom_pos2[i,:],atom_pos2[j,:]+L[m,0]*lattice_vec[0,:]*a+L[m,1]*lattice_vec[1,:]*a+L[m,2]*lattice_vec[2,:]*a) angle3=angle(atom_pos2[i,:],atom_pos2[j,:]+L[m,0]*lattice_vec[0,:]*a+L[m,1]*lattice_vec[1,:]*a+L[m,2]*lattice_vec[2,:]*a) if((blength<min_bond2)&(blength>min_bond)): #&(j!=i)): last_change t=t+1 if j not in B: B.append(j) Bd.append(blength) angle2.append(angle3) occ.append(t) N_near_neigh.append(B) N_bond.append(Bd) N_angle.append(angle2) N_occ.append(occ) if control==1: return(N_near_neigh) elif control==2: return(N_bond) elif control==3: return(N_angle) elif control==4: return(N_occ) elif control==5: return(N_near_neigh,N_bond,N_angle,N_occ)
[docs] def main_extract(min_bond,file_POSCAR,T=1,direc_1=0,direc_2=1): natoms2=0 lattice_vec=np.zeros((3,3),dtype=float) with open(file_POSCAR) as f: j=0 for line in f: if(j==1): a=float(line.split()[0]) elif((j>1)&(j<5)): lattice_vec[j-2,0]=float(line.split()[0]) lattice_vec[j-2,1]=float(line.split()[1]) lattice_vec[j-2,2]=float(line.split()[2]) elif(j==5): materials=np.array(line.split()) elif(j==6): natoms=np.array(line.split()).astype('int') for i in range(len(natoms)): natoms2=natoms[i]+natoms2 atom_pos=np.zeros((natoms2,3),dtype=float) # TODO: What if at j == 7, the file says "Cartesian" instead of "Direct"? # The current code assumes the latter; add code to handle the former elif((j>7)&(j<8+natoms2)): atom_pos[j-8,0]=float(line.split()[0]) atom_pos[j-8,1]=float(line.split()[1]) atom_pos[j-8,2]=float(line.split()[2]) j=j+1 mat_typ=int(len(materials)) atom_pos2=np.zeros((len(atom_pos[:,0]),len(atom_pos[0,:])),dtype=float) ### Convert Direct to Cartesian for j in range(len(atom_pos[:,0])): atom_pos2[j,:]=atom_pos[j,0]*lattice_vec[0,:]*a+atom_pos[j,1]*lattice_vec[1,:]*a+atom_pos[j,2]*lattice_vec[2,:]*a mat=mat_calc(atom_pos,natoms,materials) near_neigh=[] near_bond=[] near_angle=[] near_occ=[] for i in range(len(min_bond)-1): # Here we obtain all near-neighbor mappings ########## N1,N2,N3,N4=N_near_neigh_calc(atom_pos,atom_pos2,lattice_vec,a,min_bond[i],min_bond[i+1],5) near_neigh.append(N1) near_bond.append(N2) near_angle.append(N3) near_occ.append(N4) near_neigh=np.array(near_neigh) near_bond=np.array(near_bond) near_angle=np.array(near_angle) near_occ=np.array(near_occ) if(T==5): print(materials) N_plot_calc(atom_pos,atom_pos2,lattice_vec,a,min_bond[0],min_bond[1],1,materials,mat,direc_1,direc_2) if(T==2): return(atom_pos2,mat,near_neigh,near_bond,near_angle,materials,natoms,near_occ,lattice_vec,a) elif(T==3): return(near_occ) elif(T==1): return(atom_pos,atom_pos2,lattice_vec,mat,materials,natoms,a)
[docs] def main_extract_co_opt(structure,min_bond,T=1): natoms2=0 lattice_vec=np.zeros((3,3),dtype=float) with open(str(structure)+'/POSCAR') as f: j=0 for line in f: if(j==1): a=float(line.split()[0]) elif((j>1)&(j<5)): lattice_vec[j-2,0]=float(line.split()[0]) lattice_vec[j-2,1]=float(line.split()[1]) lattice_vec[j-2,2]=float(line.split()[2]) elif(j==5): materials=np.array(line.split()) elif(j==6): natoms=np.array(line.split()).astype('int') for i in range(len(natoms)): natoms2=natoms[i]+natoms2 atom_pos=np.zeros((natoms2,3),dtype=float) elif((j>7)&(j<8+natoms2)): atom_pos[j-8,0]=float(line.split()[0]) atom_pos[j-8,1]=float(line.split()[1]) atom_pos[j-8,2]=float(line.split()[2]) j=j+1 mat_typ=int(len(materials)) 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,:]*a+atom_pos[j,1]*lattice_vec[1,:]*a+atom_pos[j,2]*lattice_vec[2,:]*a mat=mat_calc(atom_pos,natoms,materials) near_neigh=[] near_bond=[] near_angle=[] near_occ=[] # Nearest neighbour calculation for i in range(len(min_bond)-1): near_neigh.append(N_near_neigh_calc(atom_pos,atom_pos2,lattice_vec,a,min_bond[i],min_bond[i+1],1)) near_bond.append(N_near_neigh_calc(atom_pos,atom_pos2,lattice_vec,a,min_bond[i],min_bond[i+1],2)) near_angle.append(N_near_neigh_calc(atom_pos,atom_pos2,lattice_vec,a,min_bond[i],min_bond[i+1],3)) near_occ.append(N_near_neigh_calc(atom_pos,atom_pos2,lattice_vec,a,min_bond[i],min_bond[i+1],4)) near_neigh=np.array(near_neigh) near_bond=np.array(near_bond) near_angle=np.array(near_angle) near_occ=np.array(near_occ) if(T==5): print(materials) N_plot_calc(atom_pos,atom_pos2,lattice_vec,a,min_bond[0],min_bond[1],1,materials,mat,direc_1,direc_2) if(T==2): return(atom_pos2,mat,near_neigh,near_bond,near_angle,materials,natoms,near_occ,lattice_vec,a) elif(T==3): return(near_occ) elif(T==1): return(atom_pos2,mat,near_neigh,near_bond,near_angle,materials,natoms)