FCC (111) Surface Generation Script

From EVOCD
Jump to: navigation, search

< Back to GSFE Curve

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

Personal tools
Namespaces

Variants
Actions
home
Materials
Material Models
Design
Resources
Projects
Education
Toolbox