# -*-shell-script-*-
# test the MEAM potential of Au-Si (TCL)
# run by meam-baskes
#------------------------------------------------------------

#*******************************************
# Definition of procedures
#*******************************************
proc initmd { } { MD++ {
setnolog
setoverwrite
dirname = runs/si-au-test
zipfiles = 0 writeall = 1
} }
#end of proc initmd

#--------------------------------------------
proc create_L12 { } { MD++ {
# Create Perfect Lattice Configuration
crystalstructure = L1_2  latticeconst = 3.96026 #(A) L1_2  structure
element0 = "Au"   element1 = "Si"  
atommass = [ 196.96655 28.0855 ] # Si, Au (g/mol)
latticesize = [ 1 0 0  4
                0 1 0  4
                0 0 1  4 ]
makecrystal finalcnfile = L12-au3si-2x2x2.cn writecn
incnfile = L12-au3si-2x2x2.cn writecn
} }        

#--------------------------------------------
proc create_FCC_Au { } { MD++ {
# Create Perfect Lattice Configuration
crystalstructure = face-centered-cubic  latticeconst = 4.07 #(A) FCC  structure
element0 = "Au"   element1 = "Si"  
atommass = [ 196.96655 28.0855 ] # Si, Au (g/mol)
latticesize = [ 1 0 0  4
                0 1 0  4
                0 0 1  4 ]
makecrystal finalcnfile = fcc-au-4x4x4.cn writecn
incnfile = fcc-au-4x4x4.cn writecn
} }        

#--------------------------------------------
proc create_AuSi4 { } { MD++ {
crystalstructure = zinc-blende latticeconst = 4.64 #5.19
latticesize = [ 1 0 0  6
                0 1 0  6
                0 0 1  6 ]
makecrystal
input = [ 1 0.1  10  -10 10 -10 10 ] fixatoms_by_position
input = [ 1 -10 -0.1 -10 10 -10 10 ] fixatoms_by_position
input = [ 1 -10  10  0.1 10 -10 10 ] fixatoms_by_position
input = [ 1 -10 10 -10 -0.1 -10 10 ] fixatoms_by_position
input = [ 1 -10 10 -10  10  0.1 10 ] fixatoms_by_position
input = [ 1 -10 10 -10 10 -10 -0.1 ] fixatoms_by_position
removefixedatoms
input = [ 12  0 2 4 5 6 8 9 10 11 13 14 15 ] fixatoms_by_ID
removefixedatoms
freeallatoms finalcnfile = AuSi4.cn writeall = 1 writecn
incnfile = AuSi4.cn readcn
} }        

#--------------------------------------------
proc create_Au2Si7 { } { MD++ {
crystalstructure = zinc-blende latticeconst = 5.19
latticesize = [ 1 0 0  6
                0 1 0  6
                0 0 1  6 ]
makecrystal
input = [ 1 0.05  10  -10 10 -10 10 ] fixatoms_by_position
input = [ 1 -10 -0.15 -10 10 -10 10 ] fixatoms_by_position
input = [ 1 -10  10  0.05 10 -10 10 ] fixatoms_by_position
input = [ 1 -10 10 -10 -0.15 -10 10 ] fixatoms_by_position
input = [ 1 -10 10 -10  10  0.1 10 ] fixatoms_by_position
input = [ 1 -10 10 -10 10 -10 -0.1 ] fixatoms_by_position
removefixedatoms
input = [ 6  5 7 8 9 11 12 ] fixatoms_by_ID
removefixedatoms
freeallatoms  finalcnfile = Au2Si7.cn writeall = 1 writecn
incnfile = Au2Si7.cn readcn
} }        

#------------------------------------------------------------
proc readmeam-baskes { } { MD++ {
#Read in MEAM potential (Baskes format)
meamfile = "/home/caiwei/Codes/MD++/Fortran/MEAM-Baskes/meamf"
meafile  = "/home/caiwei/Codes/MD++/Fortran/MEAM-Baskes/meafile_Au_Si"
ntypes = 2  ename0 = "Au2  " ename1 = "Si2  " #leave spaces to be compatible with fortran

#meamfile = "/home/caiwei/Codes/MD++/Fortran/MEAM-Baskes/meamf"
#ntypes = 1  ename0 = "Au   " #leave spaces to be compatible with fortran

rcut = 6.0  kode0 = "library"
readMEAM
NNM = 300
} }

#------------------------------------------------------------
proc readmeam-lammps { } { MD++ {
#Read in MEAM potential (Baskes format)
meamfile = "/home/caiwei/Codes/lammps-15Dec06/examples/meam/meamf"
meafile = "/home/caiwei/Codes/MD++/Fortran/MEAM-Baskes/meafile_Au_Si"
nspecies = 2  element0 = "Au2"  element1 = "Si2" rcut = 6.0  readMEAM
NNM = 300
} }

#-------------------------------------------------------------
proc openwindow { } { MD++ {
# Plot Configuration
#
atomradius = [ 0.67 0.34 ] bondradius = 0.3 bondlength = 2.8285 #for Si
atomcolor = orange bondcolor = red backgroundcolor = gray70 fixatomcolor = yellow
plotfreq = 100  rotateangles = [ 0 0 0 1.25 ]
openwin  alloccolors rotate saverot eval plot
} }
#end of proc openwindow

#--------------------------------------------
proc exitmd { } { MD++ quit }
#end of proc exitmd

#--------------------------------------------
proc relax_freebox { } { MD++ {
# Conjugate-Gradient relaxation
conj_ftol = 2e-6 conj_itmax = 1000 conj_fevalmax = 10000
conj_fixbox = 0  conj_fixboxvec = [ 0 1 1
                                    1 0 1
                                    1 1 0 ]
relax
} }
#end of proc relax_freebox
#--------------------------------------------
proc relax_fixbox { } { MD++ {
# Conjugate-Gradient relaxation
conj_ftol = 2e-6 conj_itmax = 1000 conj_fevalmax = 10000
conj_fixbox = 1  conj_fixboxvec = [ 0 1 1
                                    1 0 1
                                    1 1 0 ]
relax
} }
#end of proc relax_freebox

#--------------------------------------------
proc setup_md { } { MD++ {     
equilsteps = 0  timestep = 0.0001 # (ps)
atommass = [ 196.96655 28.0855 ] # Si, Au (g/mol)
DOUBLE_T = 0
saveprop = 1 savepropfreq = 100 openpropfile #run
savecn = 1 savecnfreq = 1000 openintercnfile
plotfreq = 100
vt2 = 2e28  #1e28 2e28 5e28
wallmass = 2e3     # atommass * NP = 14380
boxdamp = 1e-3     # optimal damping for 216 atoms and wallmass 1e-3
saveH # Use current H as reference (H0), needed for specifying stress
fixboxvec  = [ 0 1 1 
               1 0 1
               1 1 0 ]
stress = [ 0 0 0
           0 0 0
           0 0 0 ]
output_fmt = "curstep EPOT KATOM Tinst HELM HELMP TSTRESS_xx TSTRESS_yy TSTRESS_zz H_11 H_22 H_33" 
} }
#end of proc setup_md


#--------------------------------------------
# for diagnosis purposes
proc printfile {fname} { puts [read [open $fname r]] }

proc index3 { ID coord } {
    set ind.x 1; set ind.y 2; set ind.z 3
    expr { $ID * 3 + [set ind.$coord] - 1 }
}

proc MD++_GetVector { name ID coord } {
    MD++_Get $name [index3 $ID $coord]
}

proc MD++_PrintVar { name {unit \?} {fmt %11.4e} } {
    puts "$name\t= [format $fmt [MD++_Get  $name]] (in $unit)"
}

proc MD++_PrintMatrix { name {unit \?} {fmt %11.4e} } {
    puts "$name\t= [format $fmt [MD++_Get $name 0]] [format $fmt [MD++_Get $name 1]] [format $fmt [MD++_Get $name 2]]  (in $unit)"
    puts      "\t  [format $fmt [MD++_Get $name 3]] [format $fmt [MD++_Get $name 4]] [format $fmt [MD++_Get $name 5]]"
    puts      "\t  [format $fmt [MD++_Get $name 6]] [format $fmt [MD++_Get $name 7]] [format $fmt [MD++_Get $name 8]]"
}

proc MD++_PrintArray { name {unit \?} {i0 0} {i1 5} {fmt %11.4e} } {
    for {set ID $i0} {$ID < $i1} {incr ID 1} {
        puts "$name\($ID\)= [format $fmt [MD++_Get  $name $ID]] [expr {$ID==$i0?"(in $unit)":" "}]"
    }
}

proc MD++_PrintVectorArray { name {unit \}?} {i0 0} {i1 0} {fmt %11.4e} } {
    for {set ID $i0} {$ID < $i1} {incr ID 1} {
        puts "$name\($ID\)= ([format $fmt [MD++_GetVector $name $ID x]]\
                           [format $fmt [MD++_GetVector $name $ID y]]\
                           [format $fmt [MD++_GetVector $name $ID z]])\
                           [expr {$ID==$i0?"(in $unit)":" "}]"
    }
}
# end of diagnosis procs

#---------------------------------------------
# Compute elastic constants for cubic crystal
proc compute_elast_const { datafile structname argv0 } {    
relax_freebox
MD++ finalcnfile = relaxed.cn writecn

set nx [MD++_Get latticesize  3]
set ny [MD++_Get latticesize  7]
set nz [MD++_Get latticesize 11]

set Lx [MD++_Get H 0]
set Ly [MD++_Get H 4]
set Lz [MD++_Get H 8]

set NP [MD++_Get NP]

set a0 [expr $Lx/$nx]

set nx0 [expr $Lx/$a0]
set ny0 [expr $Ly/$a0]
set nz0 [expr $Lz/$a0]

#-----------------------
# Compute bulk modulus
#-----------------------
MD++ saveH conj_fixbox = 1

set fileID [open $datafile w ]

puts $fileID "%This file is generated by MD++ ($argv0)\n\n"
puts $fileID "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
puts $fileID "% $structname "
puts $fileID "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
puts $fileID "$structname = struct();"
puts $fileID "$structname.N = $NP;"
puts $fileID "$structname.a0 = $a0;"
puts $fileID "$structname.C1 = \[ $nx0 0 0 \];"
puts $fileID "$structname.C2 = \[ 0 $ny0 0 \];"
puts $fileID "$structname.C3 = \[ 0 0 $nz0 \];"

puts $fileID "$structname.data = \[ %lattice_const.(A)  Epot(eV)"

for {set x 0.997} {$x<=1.003} {set x [expr $x+0.001]} {

    MD++ restoreH input = $x scaleH relax eval

    puts $fileID "[format %.3f%3d%24.13e $x 1 [MD++_Get EPOT]]"
}

puts $fileID "];"
puts $fileID "$structname.data(:,1) = $structname.data(:,1)*$structname.a0;\n%"
puts $fileID "$structname = fit_aEB($structname);\n%"
puts $fileID "%disp(sprintf('$structname: a0 = %.6f A, Ecoh = %.6f eV, B = %.6f GPa', ..."
puts $fileID "%             $structname.a0, $structname.Ecoh, $structname.B));\n"

#-----------------------
# Compute C11 C12
#-----------------------
puts $fileID "$structname.data = \[ %lattice_const.(A)  Epot(eV)"

for {set x -0.003} {$x<=0.003} {set x [expr $x+0.001]} {

    MD++ restoreH input = \[ 1 1 $x \] shiftbox relax eval

    puts $fileID "[format %.3f%3d%24.13e [expr $x+1] 1 [MD++_Get EPOT]]"
}

puts $fileID "];"
puts $fileID "$structname = fit_C11($structname);\n%"
puts $fileID "%disp(sprintf('$structname: B = %.6f GPa, C11 = %.6f GPa, C12 = %.6f GPa', ..."
puts $fileID "%             $structname.B, $structname.C11, $structname.C12));\n"



#-----------------------
# Compute C44
#-----------------------
# rotate crystal by 45 degrees around z axis
MD++  {
    restoreH relax
    finalcnfile = perf.cn writeall = 1 writecn
    incnfile = perf.cn input = [ 1 0 ] splicecn
    input = [ 2 1 0.5 ] redefinepbc
    input = [ 1 2 -1  ] redefinepbc  reorientH 
    relax eval saveH
    finalcnfile = perf2.cn writecn
    incnfile = perf2.cn readcn
}

puts $fileID "$structname.N = [expr $NP*2];"
puts $fileID "$structname.C1 = \[  $nx0 -$ny0 0 \];"
puts $fileID "$structname.C2 = \[  $nx0 $ny0 0 \];"
puts $fileID "$structname.C3 = \[  0 0 $nz0 \];"

puts $fileID "$structname.data = \[ %lattice_const.(A)  Epot(eV)"

MD++ fixallatoms  #Note: only for SC and BCC crystals!

for {set x -0.003} {$x<=0.003} {set x [expr $x+0.001]} {

    MD++ restoreH input = \[ 1 1 $x \] shiftbox relax eval

    puts $fileID "[format %.3f%3d%24.13e [expr $x+1] 1 [MD++_Get EPOT]]"
}

puts $fileID "];"
puts $fileID "$structname = fit_C44($structname);\n%"
puts $fileID "disp(sprintf('$structname: a0 = %.6f A, Ecoh = %.6f eV, B = %.6f GPa', ..."
puts $fileID "             $structname.a0, $structname.Ecoh, $structname.B));"
puts $fileID "disp(sprintf('        C11 = %.6f GPa, C12 = %.6f GPa, C44 = %.6f GPa', ..."
puts $fileID "             $structname.C11, $structname.C12, $structname.C44));\n"


close $fileID
}     



#*******************************************
# Main program starts here
#*******************************************
# read in status from command line argument
if { $argc == 0 } {
 set status 0
} elseif { $argc > 0 } {
 set status [lindex $argv 0]
}
puts "status = $status"

initmd
readmeam-baskes

if { $status == 0 } {
  create_L12
  #openwindow
  #relax_freebox

  set sysname    "L12_Au_Si"
  set datafile   "bulkmodulus_TCL_$sysname.m"
  set structname "MEAM_$sysname"

  compute_elast_const $datafile $structname $argv0
  
  #MD++ sleep
} elseif { $status == 1 } {
  create_FCC_Au
  #openwindow
  #relax_freebox

  set sysname    "FCC_Au"
  set datafile   "bulkmodulus_TCL_$sysname.m"
  set structname "MEAM_$sysname"

  compute_elast_const $datafile $structname $argv0
  
  #MD++ sleep
} elseif { $status == 2 } {
  create_AuSi4
  openwindow
  relax_fixbox

  MD++ sleep
} elseif { $status == 3 } {
  create_Au2Si7
  openwindow
  relax_fixbox
  setup_md
  MD++ T_OBJ = 1400 initvelocity ensemble_type = "NVE" integrator_type = "VVerlet" 
  MD++ totalsteps = 10000 run
  relax_fixbox
  MD++ sleep
}    
exitmd

