ICME-QM2

From EVOCD
Jump to: navigation, search

< Homework 1

Author(s): Laalitha Liyanage

Contents

License

By using the codes provided here you accept the the Mississippi State University's license agreement. Please read the agreement carefully before usage.

Abstract

This is a tutorial to calculate intrinsic and extrinsic stacking fault energies of fcc (111) surface using VASP .

Overview

Using the following scripts intrinsic stacking fault energy and extrinsic stacking fault energy of fcc (111) surface can be calculated. The figure illustrates the different stacking fault configurations. To calculate the stacking fault energy the following equation can be used.

Sfe eq.gif

Where ESFE is the stacking fault energy, Etot is the energy of the system with the stacking fault, N is the number of atoms, \epsilon is energy per atom in bulk structure, and A is the area of the surface perpendicular to the stacking fault.

Fcc (111) surface structures. (a)Perfect crystal, (b) with intrinsic stacking fault and (c) with extrinsic stacking fault.[1]

Crystal structure generation

Save the following script as
<name>.py 
and give permissions as executable
chmod u+x <name>.py 
#!/usr/local/bin/python

usage = """
        Usage: gen_datafile_fcc.py a nx ny type p/d
        a - Lattice parameter
        nx,ny - periodicity in x and y
        type - Stacking fault type I(intrinsic)/E(extrinsic)
        p/d - output file format type p(POSCAR)/d (LAMMPS)
"""
       
import os
import re
import sys
import math

# Default setting
a=4.05

def gen_data_for_stacking_fault(a,nx=1,ny=1,type="I"):
  """ Generate datafile of FCC surface: 110:x, 112:y, 111:z """
  xa=[]; ya=[]; za=[]
  ax = a*math.sqrt(2)/2
  ay = a*math.sqrt(6)/2
  az = a*math.sqrt(3)
  x0 = 0.0
  x2 = math.sqrt(2)/4 * a
  y2 = math.sqrt(6)/4 * a
  y3 = math.sqrt(6)/6 * a
  y4 = math.sqrt(6)*5/12 * a
  y5 = math.sqrt(6)*2/6 * a
  y6 = math.sqrt(6)/12 * a
  if type == "I":
    nlayer = 11
    nfaults = 1
  elif type == "E":
    nlayer = 13
    nfaults = 1
  bx,by,bz = ax*nx, ay*ny, az/3.0*nlayer
  for i in range(nx):
    for j in range(ny):
      layer = 0
      for k in range(2):
        xa.append(x0+i*ax); ya.append(x0+j*ay); za.append(layer/3.0*az)
        xa.append(x2+i*ax); ya.append(y2+j*ay); za.append(layer/3.0*az); layer += 1
        xa.append(x0+i*ax); ya.append(y3+j*ay); za.append(layer/3.0*az)
        xa.append(x2+i*ax); ya.append(y4+j*ay); za.append(layer/3.0*az); layer += 1
        xa.append(x0+i*ax); ya.append(y5+j*ay); za.append(layer/3.0*az)
        xa.append(x2+i*ax); ya.append(y6+j*ay); za.append(layer/3.0*az); layer += 1
      if type == "I":
        xa.append(x0+i*ax); ya.append(y3+j*ay); za.append(layer/3.0*az)
        xa.append(x2+i*ax); ya.append(y4+j*ay); za.append(layer/3.0*az); layer += 1
        xa.append(x0+i*ax); ya.append(y5+j*ay); za.append(layer/3.0*az)
        xa.append(x2+i*ax); ya.append(y6+j*ay); za.append(layer/3.0*az); layer += 1
        xa.append(x0+i*ax); ya.append(x0+j*ay); za.append(layer/3.0*az)
        xa.append(x2+i*ax); ya.append(y2+j*ay); za.append(layer/3.0*az); layer += 1
        xa.append(x0+i*ax); ya.append(y3+j*ay); za.append(layer/3.0*az)
        xa.append(x2+i*ax); ya.append(y4+j*ay); za.append(layer/3.0*az); layer += 1
        xa.append(x0+i*ax); ya.append(y5+j*ay); za.append(layer/3.0*az)
        xa.append(x2+i*ax); ya.append(y6+j*ay); za.append(layer/3.0*az); layer += 1
      elif type == "E":
        xa.append(x0+i*ax); ya.append(y3+j*ay); za.append(layer/3.0*az)
        xa.append(x2+i*ax); ya.append(y4+j*ay); za.append(layer/3.0*az); layer += 1
        for k in range(2):
          xa.append(x0+i*ax); ya.append(x0+j*ay); za.append(layer/3.0*az)
          xa.append(x2+i*ax); ya.append(y2+j*ay); za.append(layer/3.0*az); layer += 1
          xa.append(x0+i*ax); ya.append(y3+j*ay); za.append(layer/3.0*az)
          xa.append(x2+i*ax); ya.append(y4+j*ay); za.append(layer/3.0*az); layer += 1
          xa.append(x0+i*ax); ya.append(y5+j*ay); za.append(layer/3.0*az)
          xa.append(x2+i*ax); ya.append(y6+j*ay); za.append(layer/3.0*az); layer += 1
      
  return xa,ya,za,bx,by,bz,nfaults

def gen_datafile(xa,ya,za,box):
  fout = open("datafile","w")
  fout.write("FCC 111 surface in Z\n\n")
  fout.write("%d atoms\n"%len(xa))
  fout.write("1 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 1 %3d %22.16f %22.16f %22.16f\n"%(i+1,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) > 5:
  a=float(sys.argv[1])
  nx=int(sys.argv[2])
  ny=int(sys.argv[3])
  type=sys.argv[4]
  option=sys.argv[5]

  xa,ya,za,bx,by,bz,nfaults = gen_data_for_stacking_fault(a,nx,ny,type)

  if option == "d":
    gen_datafile(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

Running the calculation

Once you generate a POSCAR file from the above script, make an INCAR and a KPOINTS file and copy the POTCAR file relevant to your group to the same directory. After that make a pbs command script and submit the calculation to a cluster (Raptor). Example files are given below.

INCAR

LWAVE = .FALSE.
LCHARG = .FALSE.
LREAL = Auto
ISMEAR = -5
ENCUT = 240.3
EDIFF = 1e-6
NSW=100
ISIF=2
IBRION=2

KPOINTS

Convergence of k-point grid should be tested. A single k-point should be sufficient in the direction perpendicular to the stacking fault.

Automatic mesh
0              ! number of k-points = 0 ->automatic generation scheme 
Monkhorst-Pack ! Use Monkhorst-Pack scheme
4  4  1        ! only need one k-point in the direction perpendicular to the surface
0. 0. 0.       ! optional shift of the mesh 

Submitting job to cluster

Two files are needed to submit to the cluster. One is the pbs command script and the other is a job.sh shell script to invoke ulimit command on all allocated processors. They are presented below.Both files should be in your work directory with the rest of the VASP input files.

Pbs command script

#PBS -N <name of output files>
#PBS -l nodes=4:ppn=4 
#PBS -l walltime=48:00:00
#PBS -q q64p48h@raptor
#PBS -mea
#PBS -r n
#PBS -V
cd $PBS_O_WORKDIR

mpiexec -np 16 ./job.sh

Job.sh script

#!/bin/bash
ulimit -s unlimited
<Absolute path of VASP exe>
Make the file and make it executable by
chmod u+x job.sh

Extracting Data

Once the calculation is complete you will see some output files. CONTCAR gives the final geometry of the system. You could visualize CONTCAR using OVITO to make sure the structure and surface are stable. OSZICAR gives data of each electronic and ionic step. The final energy of the system (Etot) is in the OSZICAR file as well. To get the final energy execute the following command

tail -n1 OSZICAR|awk '{print $5}'

Convergence

  • The curve should be converged in terms of k-point grid. Therefore try different k-point grids. Remember that the ratio of k-points should be inversely proportional to the lengths of the lattice vectors (in this case the edges of the simulation box). Since the supercell is elongated only one k-point is needed in the elongated direction.

References

  1. M. Muzyk, Z. Pakiela, K.J. Kurzydlowski, Ab initio calculations of the generalized stacking fault energy in aluminium alloys, Scripta Materialia, Volume 64, Issue 9, May
Personal tools
Namespaces

Variants
Actions
home
Materials
Material Models
Design
Resources
Projects
Education
Toolbox