FCC (111) Surface Generation Script
From EVOCD
Purpose
This python script generates a FCC generalized stacking fault structure in the form of a POSCAR file for use in VASP density functional theory calculations.
Implementation
- Copy the source code and save it in a new blank text file with a memorable name and a ".py" extension.
- To run the script open a command terminal and navigate to it's location. Then use the following command
<name>.py <a> <nx> <ny> <nz> <t> <p/d>
to generate the POSCAR file. The arguments (input parameters) are equilibrium lattice constant (a), periodicity in x,y and z (nx,ny,nz), displacement of top half of the simulation box (t), and output file type (p/d).
Source Code
#!/usr/bin/env python
# Description: generate coordinate file for generalized stacking fault energy calculation in FCC
# Change Log:
# 1. Sungho Kim created gen_gsf_all.py on Mon Feb 23, 2009 09:07:51 CST.
# 2. Laalitha Liyanage made minor changes and named as fcc_111_gsfe_curve.py in 2012(?)
# 3. Sungho Kim modified to generate two peak in the curve on Thu Mar 05, 2015 22:06:37 CST
usage="""
Usage: fcc_111_gsfe_curve.py a nx ny nz t p/d
a - equilibrium lattice parameter
nx,ny,nz - periodicity in x,y and z
t - displacement of top block of atoms
p/d - output filetype p(POSCAR)/d(LAMMPS datafile)
Example: fcc_111_gsfe_curve.py 4.05 1 4 1 0.1 p
"""
import os
import re
import sys
import math
# Default setting
a = 4.0
nx = 1
ny = 4
nz = 1
def get_fcc(a,t,nx=1,ny=1,nz=1):
""" fcc burger vector = 1/3*[112] slip plane = (111): [112]:x, [111]:y, [110]:z """
xa = []; ya = []; za = [];ty = [];ly=[]
ax = a*math.sqrt(6)/2.
ay = a*math.sqrt(3)
az = a*math.sqrt(2)/2.
bx,by,bz = ax*nx,ay*ny,az*nz
ux = ax*t
layer=0
for j in range(ny/2):
for i in range(nx):
for k in range(nz):
xa.append((0/6.+i)*ax); ya.append((0/3.+j)*ay); za.append((0/2.+k)*az);ty.append(1);ly.append(layer)
xa.append((3/6.+i)*ax); ya.append((0/3.+j)*ay); za.append((1/2.+k)*az);ty.append(1);ly.append(layer);layer+=1
xa.append((2/6.+i)*ax); ya.append((1/3.+j)*ay); za.append((0/2.+k)*az);ty.append(1);ly.append(layer)
xa.append((5/6.+i)*ax); ya.append((1/3.+j)*ay); za.append((1/2.+k)*az);ty.append(1);ly.append(layer);layer+=1
xa.append((4/6.+i)*ax); ya.append((2/3.+j)*ay); za.append((0/2.+k)*az);ty.append(1);ly.append(layer)
xa.append((1/6.+i)*ax); ya.append((2/3.+j)*ay); za.append((1/2.+k)*az);ty.append(1);ly.append(layer);layer+=1
for j in range(ny/2,ny):
for i in range(nx):
for k in range(nz):
xa.append((0/6.+i)*ax + ux ); ya.append((0/3.+j)*ay); za.append((0/2.+k)*az);ty.append(1);ly.append(layer)
xa.append((3/6.+i)*ax + ux ); ya.append((0/3.+j)*ay); za.append((1/2.+k)*az);ty.append(1);ly.append(layer);layer+=1
xa.append((2/6.+i)*ax + ux ); ya.append((1/3.+j)*ay); za.append((0/2.+k)*az);ty.append(1);ly.append(layer)
xa.append((5/6.+i)*ax + ux ); ya.append((1/3.+j)*ay); za.append((1/2.+k)*az);ty.append(1);ly.append(layer);layer+=1
xa.append((4/6.+i)*ax + ux ); ya.append((2/3.+j)*ay); za.append((0/2.+k)*az);ty.append(1);ly.append(layer)
xa.append((1/6.+i)*ax + ux ); ya.append((2/3.+j)*ay); za.append((1/2.+k)*az);ty.append(1);ly.append(layer);layer+=1
vacuum = 8.0
for i in range(len(xa)):
xa[i] = ( (xa[i] + bx)/bx - int((xa[i] + bx)/bx) )* bx
ya[i] += vacuum/2.0
za[i] = ( (za[i] + bz)/bz - int((za[i] + bz)/bz) )* bz
by += vacuum
print layer
return ty,xa,ya,za,bx,by,bz,ly
def shift(a,ly,xa,step=1.0):
ux = a*math.sqrt(6)/2.*step
for i in range(len(ly)):
if ly[i]>ly[len(ly)-1]/2:
xa[i] += ux
return xa
def gen_datafile(ty,xa,ya,za,box):
fout = open("datafile","w")
fout.write("Atomic locations\n\n")
fout.write("%d atoms\n"%len(xa))
fout.write("2 atom types\n")
fout.write(" 0.0 %22.16f xlo xhi\n"%box[0])
fout.write(" 0.0 %22.16f ylo yhi\n"%box[1])
fout.write(" 0.0 %22.16f zlo zhi\n"%box[2])
fout.write("\nAtoms\n\n")
for i in range(len(xa)):
fout.write("%4d %3d %22.16f %22.16f %22.16f\n"%(i+1,ty[i],xa[i],ya[i],za[i]))
fout.close()
return len(xa)
def gen_poscar(xa,ya,za,box):
fout = open("POSCAR","w")
fout.write("Al fcc (111)\n")
fout.write("1.0\n")
fout.write(" %22.16f %22.16f %22.16f\n"%(box[0],0,0))
fout.write(" %22.16f %22.16f %22.16f\n"%(0,box[1],0))
fout.write(" %22.16f %22.16f %22.16f\n"%(0,0,box[2]))
fout.write("%d\n"%len(xa))
fout.write("Selective Dynamics\n")
fout.write("Cart\n")
for i in range(len(xa)):
fout.write("%22.16f %22.16f %22.16f F F T\n"%(xa[i],ya[i],za[i]))
fout.close()
return len(xa)
# Main Program
if len(sys.argv) > 6:
a=float(sys.argv[1])
nx=int(sys.argv[2])
ny=int(sys.argv[3])
nz=int(sys.argv[4])
t=float(sys.argv[5])
option=sys.argv[6]
ty,xa,ya,za,bx,by,bz,ly = get_fcc(a,t,nx,ny,nz)
#xa = shift(a,ly,xa,t)
if option == "d":
gen_datafile(ty,xa,ya,za,[bx,by,bz])
elif option == "p":
gen_poscar(xa,ya,za,[bx,by,bz])
else:
print "Error: wrong number of arguments!!!"
print usage