# -*-shell-script-*-
# dislocation Peierls stress in Molybdenum
# make fs build=R SYS=intel

source "scripts/Examples/Tcl/startup.tcl"

#*******************************************
# Definition of procedures
#*******************************************
proc initmd { n } {
#MD++ setnolog
MD++ setoverwrite
MD++ dirname = runs/mo-peierls-tilt$n
MD++ NNM = 200
}

proc readpot { } { MD++ {
#--------------------------------------------
#Read in potential file
#
potfile = ~/Codes/MD++/potentials/mo_pot readpot
} }

proc create_datebase { } {
    global supercell
    
   set supercell(-90)    "   1   1   1  24  -1   1   0  40  -1  -1   2   3"
   set supercell(-85.96) "   7   7   6   8  -1   1   0 160  -3  -3   7   2"
   set supercell(-74.21) "   2   2   1  25  -1   1   0 100  -1  -1   4   3"
   set supercell(-54.74) "   1   1   0  48  -1   1   0  40   0   0   1   8"
   set supercell(-35.26) "   2   2  -1  20  -1   1   0  80   1   1   4   2"
   set supercell(-31.75) "   5   5  -3  10  -1   1   0 100   3   3  10   1"
   set supercell(-29.5)  "   3   3  -2  20  -1   1   0 100   1   1   3   3"
   set supercell(-25.24) "   5   5  -4   8  -1   1   0  80   2   2   5   2"
   set supercell(-22.58) "   9   9  -8   4  -1   1   0  80   4   4   9   1"
   set supercell(-19.47) "   1   1  -1  36  -1   1   0  80   1   1   2   4"
   set supercell(-14.42) "   5   5  -6  10  -1   1   0 100   3   3   5   2"
   set supercell(-3.238) "   9   9 -16   4  -1   1   0 100   8   8   9   1"
   set supercell(0)      "   1   1  -2  16  -1   1   0  40   1   1   1   4"

   set supercell(-11.42) "   3   3  -4   9  -1   1   0  65   2   2   3   4"
   set supercell(-8.049) "   2   2  -3  12  -1   1   0  65   3   3   4   3"
   set supercell(-6.209) "   5   5  -8   5  -1   1   0  65   4   4   5   2"
   set supercell(-5.051) "   3   3  -5   8  -1   1   0  65   5   5   6   2"
   set supercell(-4.257) "   7   7 -12   3  -1   1   0  65   6   6   7   1"
   set supercell(-3.678) "   4   4  -7   6  -1   1   0  65   7   7   8   1"
  #set supercell(-3.238) "   9   9 -16   2  -1   1   0  65   8   8   9   1"
   set supercell(-2.891) "   5   5  -9   4  -1   1   0  65   9   9  10   1"
   set supercell(-2.612) "  11  11 -20   2  -1   1   0  65  10  10  11   1"
   set supercell(-1.761) "   8   8 -15   3  -1   1   0  65  15  15  16   1"
   
   set supercell(87.98) " -13 -13 -14   4  -1   1   0 120   7   7 -13   1"
   set supercell(85.74) "  -6  -6  -7   8  -1   1   0 120   7   7 -12   1"
   set supercell(81.95) "  -3  -3  -4  15  -1   1   0 125   2   2  -3   3"
   set supercell(77.54) "  -9  -9 -14   5  -1   1   0 125   7   7  -9   1"
   set supercell(75.58) "  -3  -3  -5  15  -1   1   0 125   5   5  -6   1"
   set supercell(70.53) "  -1  -1  -2  24  -1   1   0  40   1   1  -1   5"
   set supercell(63.2)  "  -3  -3  -8   8  -1   1   0 100   4   4  -3   2"
   set supercell(54.74) "  -1  -1  -4  16  -1   1   0  80   2   2  -1   4"
   set supercell(48.53) "  -1  -1  -6  12  -1   1   0 100   3   3  -1   3"
   set supercell(43.31) "  -1  -1 -10   8  -1   1   0 100   5   5  -1   2"
   set supercell(39.31) "  -1  -1 -20   4  -1   1   0 100  10  10  -1   1"
   set supercell(35.26) "   0   0  -1  50  -1   1   0  40   1   1   0   8"
   set supercell(31.22) "   1   1 -20   4  -1   1   0 100  10  10   1   1"
   set supercell(27.21) "   1   1 -10   8  -1   1   0  80   5   5   1   1"
   set supercell(15.79) "   1   1  -4  12  -1   1   0  80   2   2   1   4"
   set supercell(3.113) "   4   4  -9   5  -1   1   0  65   9   9   8   1"

   set supercell(10.02) "   1   1  -3  15  -1   1   0  65   3   3   2   3"
   set supercell(7.326) "   3   3  -8   6  -1   1   0  65   4   4   3   2"
   set supercell(5.768) "   2   2  -5   9  -1   1   0  65   5   5   4   2"
   set supercell(4.755) "   5   5 -12   4  -1   1   0  65   6   6   5   2"
   set supercell(4.045) "   3   3  -7   6  -1   1   0  65   7   7   6   1"
   set supercell(3.519) "   7   7 -16   3  -1   1   0  65   8   8   7   1"
  #set supercell(3.113) "   4   4  -9   5  -1   1   0  65   9   9   8   1"
   set supercell(1.62)  "   8   8 -17   2  -1   1   0  65  17  17  16   1"

# vicinal to [1 1 -1]
   set supercell(74.79) "  -7  -7 -12   3  -1   1   0  65   6   6  -7   1"
   set supercell(74.21) "  -4  -4  -7   6  -1   1   0  65   7   7  -8   1"
   set supercell(73.77) "  -9  -9 -16   2  -1   1   0  65   8   8  -9   1"
   set supercell(73.42) "  -5  -5  -9   4  -1   1   0  65   9   9 -10   1"
   set supercell(72.09) "  -9  -9 -17   2  -1   1   0  65  17  17 -18   1"

   set supercell(65.77) "  -5  -5 -12   4  -1   1   0  65   6   6  -5   2"
   set supercell(66.48) "  -3  -3  -7   6  -1   1   0  65   7   7  -6   1"
   set supercell(67.01) "  -7  -7 -16   3  -1   1   0  65   8   8  -7   1"
   set supercell(67.42) "  -4  -4  -9   5  -1   1   0  65   9   9  -8   1"
   set supercell(68.91) "  -8  -8 -17   2  -1   1   0  65  17  17 -16   1"

# vicinal to [1 1 0]
   set supercell(37.96) "  -1  -1 -30   2  -1   1   0  65  15  15  -1   1"
   set supercell(37.29) "  -1  -1 -40   1  -1   1   0  65  20  20  -1   1"
   set supercell(36.88) "  -1  -1 -50   1  -1   1   0  65  25  25  -1   1"
 
   set supercell(32.57) "   1   1 -30   2  -1   1   0  65  15  15   1   1"
   set supercell(33.24) "   1   1 -40   1  -1   1   0  65  20  20   1   1"
   set supercell(33.64) "   1   1 -50   1  -1   1   0  65  25  25   1   1"

# vicinal to [0 0 1]
   set supercell(-68) "   3   3   1  11  -1   1   0  65  -1  -1   6   2"
   set supercell(-64.76) "   4   4   1   9  -1   1   0  65  -1  -1   8   2"
   set supercell(-60.94) "  13  13   2   3  -1   1   0  65  -1  -1  13   1"
   set supercell(-59.49) "  17  17   2   2  -1   1   0  65  -1  -1  17   1"
   set supercell(-57.35) "  31  31   2   1  -1   1   0  65  -1  -1  31   1"
   set supercell(-56.71) "  41  41   2   1  -1   1   0  65  -1  -1  41   1"

   set supercell(-41.47) "   3   3  -1  11  -1   1   0  65   1   1   6   2"
   set supercell(-44.71) "   4   4  -1   9  -1   1   0  65   1   1   8   2"
   set supercell(-48.53) "  13  13  -2   3  -1   1   0  65   1   1  13   1"
   set supercell(-49.98) "  17  17  -2   2  -1   1   0  65   1   1  17   1"
   set supercell(-52.12) "  31  31  -2   1  -1   1   0  65   1   1  31   1"
   set supercell(-52.76) "  41  41  -2   1  -1   1   0  65   1   1  41   1"

}

proc choose_supercell { tilt } {
    global supercell

    # create perfect crystal
    MD++ crystalstructure = body-centered-cubic
    MD++ latticeconst = 3.1472
    MD++ latticesize = \[ $supercell($tilt) \]
    # overwrite simulation cell height (Ly)        
    MD++ latticesize(7) = 40
}

proc find_burgers_coord { tilt } {
    # compute Burgers vector in scaled coordinate
    set c1x [expr [MD++_Get latticesize(0)] * [MD++_Get latticesize(3)]]
    set c1y [expr [MD++_Get latticesize(1)] * [MD++_Get latticesize(3)]]
    set c1z [expr [MD++_Get latticesize(2)] * [MD++_Get latticesize(3)]]

    set c3x [expr [MD++_Get latticesize(8)] * [MD++_Get latticesize(11)]]
    set c3y [expr [MD++_Get latticesize(9)] * [MD++_Get latticesize(11)]]
    set c3z [expr [MD++_Get latticesize(10)]* [MD++_Get latticesize(11)]]

    set det [expr $c1x*$c3y-$c1y*$c3x]
    #puts "$c1x $c1y $c1z  $c3x $c3y $c3z"
    #puts "det = $det"
    if  { $det != 0 } {
            set a [expr 0.5*($c3y-$c3x) / $det ]
            set b [expr 0.5*($c1x-$c1y) / $det ]
    } else {
            set det [expr $c1z*$c3y-$c1y*$c3z ]
            if { $det == 0 } { exitmd }
            set a [expr 0.5*($c3y-$c3z)/$det ] 
            set b [expr 0.5*($c1z-$c1y)/$det ]
    }

    #make sure always remove atom, not insert atom
    if {$tilt > 0} {
        set a [expr -$a]
        set b [expr -$b]
        set bx0 -0.5
        set by0 -0.5
        set bz0 -0.5
    } else {
        set bx0  0.5
        set by0  0.5
        set bz0  0.5
    }            
    set bx [expr $a*$c1x+$b*$c3x]
    set by [expr $a*$c1y+$b*$c3y]
    set bz [expr $a*$c1z+$b*$c3z]

    puts "a=$a b=$b"
    puts "Burgers vector = ([format "%g %g %g" $bx $by $bz])"
    
    if { [expr abs($bx-$bx0)] > 1e-4 } { exitmd }
    if { [expr abs($by-$bx0)] > 1e-4 } { exitmd }
    if { [expr abs($bz-$bx0)] > 1e-4 } { exitmd }

    set coord [list $a $b $bx $by $bz]
    return $coord
}

proc make_dislocation { tilt  } { 
    global supercell

    # create perfect crystal
    choose_supercell $tilt
    MD++ makecrystal #finalcnfile = perf.cn writecn #eval

    # remove top and bottom layers of atoms
    MD++ input = \[ 1 -1 1 -1 -0.37 -1 1 \] fixatoms_by_position
    MD++ input = \[ 1 -1 1  0.37  1 -1 1 \] fixatoms_by_position
    MD++ removefixedatoms    
        
    # insert dislocation dipole
    set coord [ find_burgers_coord $tilt ]
    set a [lindex $coord 0]
    set b [lindex $coord 1]
    
    # dislocation position
    set x0 [expr 0.111 /   [MD++_Get latticesize(3)] ]
    set y0 [expr -0.5+0.125/[MD++_Get latticesize(7)] ]
    #set x0 0.01
    #set y0 -0.4996
    set y1 [expr $y0 + 0.5]
    MD++ input = \[ 3 2 $a 0 $b  $x0 $y0 $y1 0.305 -10 10 -10 10 1 0 0 0 0 \]
    MD++ makedipole    
}

proc mark_groups { } {
  MD++ NCS = 8 eval calcentralsymmetry freeallatoms
  
  #identify top surface atom
  MD++ input = \[ 1 -10 10 0 10 -10 10 10 20 \] fixatoms_by_pos_topol
  set  ntop     [MD++_Get NPfixed]
  MD++ input = 1 setfixedatomsgroup freeallatoms
  
  #identify bottom surface atom
  MD++ input = \[ 1 -10 10 -10 0 -10 10 10 20 \] fixatoms_by_pos_topol
  set  nbot     [MD++_Get NPfixed]
  MD++ input = 2 setfixedatomsgroup freeallatoms

  set natoms [list $ntop $nbot]
  return $natoms
}

#--------------------------------------------
proc relax_fixbox { } { MD++ {
# Conjugate-Gradient relaxation
conj_ftol = 1e-4 conj_itmax = 1000 conj_fevalmax = 1000
conj_fixbox = 1
relax
} }
#end of proc relax_fixbox

proc setup_window { } { MD++ {
#------------------------------------------------------------
#colors for Central symmetry view
color00 = "red" color01 = "blue" color02 = "green"
color03 = "magenta" color04 = "cyan" color05 = "purple"
color06 = "gray80" color07 = "white" color08 = "orange"
#--------------------------------------------
# Plot Configuration
#
atomradius = [1.0 0.78] bondradius = 0.3 bondlength = 0 #2.8285 #for Si
win_width=600 win_height=400
#atomradius = 0.9 bondradius = 0.3 bondlength = 0 #2.8285 #for Si
atomcolor = cyan highlightcolor = purple  bondcolor = red
fixatomcolor = yellow backgroundcolor = gray70
#atomcolor = lightgrey highlightcolor = purple  bondcolor = darkgrey
#plot_color_windows = [ 5
#                 -5   -4   0
#                 -5.5 -5   8   #color00 = red
#                 -6  -5.5  1
#               -6.55 -6    2
#               -6.72 -6.55 3
#                 -6.5 -6   6   #color06 = gray80
#                 -7.5 -6.5 4
#                ]
plot_color_axis = 2
plot_color_windows = [ 4
                       0.6 6   1  
                       6  10   5
                       10 20   6
                       20 50   8
                     ]
#plot_atom_info = 1 # reduced coordinates of atoms
#plot_atom_info = 2 # real coordinates of atoms
plot_atom_info = 3 # energy of atoms
#plot_highlight = [ 0 0 1 2 3 4 5 6 7 8 9 ]
plotfreq = 10
#
rotateangles = [ 0 0 0 1.2 ]
#openwin alloccolors rotate saverot plot
#plot_color_axis = 0 input = [ -8 -3 10] GnuPlotHistogram
#plot_color_axis = 2 input = [ 0.6 50 50 ] GnuPlotHistogram
} }

proc openwindow { } { 
setup_window
MD++ openwin alloccolors rotate saverot eval plot
}

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

#--------------------------------------------
proc setup_md { } { MD++ {     
equilsteps = 0  timestep = 0.001 # (ps)
atommass = 95.94 # (g/mol)
DOUBLE_T = 1
saveprop = 1 savepropfreq = 100 openpropfile #run
savecn = 1 savecnfreq = 1000 openintercnfile
savecfg = 1 savecfgfreq = 50
plotfreq = 100 printfreq = 100
vt2 = 1e28  #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


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

if { $argc <= 1 } {
 set n 0
} elseif { $argc > 1 } {
 set n [lindex $argv 1]
}
puts "n = $n"

set n0 0

#for debugging I12potential (reference potential 2)
#MD++ refpotential = 2  RLIST = 4.2 SKIN = 0.4
#MD++ I12_rc = 3.771   I12_sigma = 2.0951   I12_epsilon = 2.1675 

if { $status == 0 } {
  # prepare and relax dislocation structure
  initmd $n
  readpot

  create_datebase

  #screw
  #set tilt 0

  #[001]
  #set tilt -3
  
  #[11-1]
  #set tilt 4

  set tilt $n
  
  make_dislocation $tilt
  
  #openwindow
  
  MD++ conj_ftol = 1e-4 conj_fixbox = 1 conj_fevalmax = 10000
  MD++ relax

  MD++ finalcnfile = "mo-tilt$tilt.cn" writecn
  MD++ eval

  MD++ sleep
  exitmd
  
} elseif { $status == 1 } {
  # visualization
  MD++ setnolog
  initmd "view"
  readpot
  
  #set tilt_list {-90 -4.54 -4 -3 -2 -1.75 -1.5 -1.25 -1.125 -1 -0.75 -0.2 0 4.8 4.7 4.5 4.3 4.2 4 3.5 3 2.7 2.5 2.4 2 1.75 1.5 1 0.2}
  #set tilt_list { -11.42 -8.049 -6.209 -5.051 -4.257 -3.678  -2.891 -2.612 -1.761 10.02  7.326  5.768  4.755  4.045  3.519  3.113   1.62 }
  #set tilt_list { 74.79  74.21  73.77  73.42  72.09   65.77  66.48  67.01  67.42  68.91   37.96  37.29  36.88  32.57  33.24  33.64    -68 -64.76 -60.94 -59.49 -57.35 -56.71    -41.47 -44.71 -48.53 -49.98 -52.12 -52.76 }

  #set tilt_list {-1.25-stress10 -1.25-stress8 -1.25stress10 }
  #set tilt_list {0-stress2100 0-stress2200 0-stress2240 0-stress2250 }
  set cell 33.64
  set tilt_list [list $cell-stress1 $cell-stress2 $cell-stress3 $cell-stress4 $cell-stress5 $cell-stress6 $cell-stress7 $cell-stress8 $cell-stress9 ]

  for { set i 0 } { $i < [llength $tilt_list] } { incr i 1 } {
      set tilt [lindex $tilt_list $i]
      #MD++ incnfile = "../mo-peierls-tilt$tilt/mo-tilt$tilt.cn" readcn
      MD++ incnfile = "../mo-peierls-tilt$cell/mo-tilt$tilt.cn" readcn
      #MD++ incnfile = "../mo-peierls-tilt0-reverse/mo-tilt$tilt.cn" readcn
      MD++ NCS = 8 eval calcentralsymmetry 
      if { $i == 0 } { openwindow }
      if { $i >  0 } { MD++ eval plot }
      MD++ finalcnfile = "view-[format %04d $i].cfg" writeatomeyecfg
      after 8000
  }

  #MD++ conj_ftol = 1e-4 conj_fixbox = 1 conj_fevalmax = 1000
  #MD++ relax
  
  MD++ sleep
  exitmd

} elseif { $status == 2 } {
  # measuring Peierls barrier
  #MD++ setnolog

  set reverse_force 0
  set tilt $n  

  if { $tilt == 0 } {
     set reverse_force 1
  }

  if { $reverse_force == 1 } {
     initmd "$n-reverse"
  } else {
     initmd $n
  }

  readpot

  create_datebase
  choose_supercell $tilt

  MD++ incnfile = "mo-tilt$tilt.cn" readcn setconfig1
  set natoms [ mark_groups ]
  set ntop [lindex $natoms 0]
  set nbot [lindex $natoms 1]
  puts "ntop = $ntop  nbot = $nbot"

  #obtain cross section area
  set Lx [MD++_Get H_11]
  set Ly [MD++_Get H_22]
  set Lz [MD++_Get H_33]
  set A  [expr $Lx*$Lz ]
  
  puts "Lx = $Lx  Lz = $Lz  A = $A"

  # find Burgers vector direction, set as Fext direction
  set coord [ find_burgers_coord $tilt ]
  set a [lindex $coord 0]
  set b [lindex $coord 1]
  set Fx [expr $a*$Lx]
  set Fz [expr $b*$Lz]
  if { $reverse_force == 1 } {
      set Fx [expr -$Fx]
      set Fz [expr -$Fz]
  }

  # normalize Fext to correspond to 1 MPa
  set F  [expr sqrt($Fx*$Fx+$Fz*$Fz)]
  set F0 [expr $A / 160.2e3]
  set Fx [expr $Fx/$F*$F0]
  set Fz [expr $Fz/$F*$F0]
   
  MD++ conj_ftol = 1e-4 conj_fixbox = 1 conj_fevalmax = 10000
  MD++ relax
  set E0 [MD++_Get EPOT]

  set datafile "EPOT.dat"
  set fileID [open $datafile w ]
  puts $fileID "0 $E0 0 0"
  flush $fileID

  set minsigma 1 
  set dsigma   1
  set maxsigma 600
  
#  if { $tilt == -3 } { set minsigma 560  }
#  if { $tilt == 0  } { set minsigma 2240 }
#  if { $tilt == 4  } { set minsigma 390  }
#  if { $tilt == 0.2} { set minsigma 350  }
  
  if { $minsigma != $dsigma } {
       MD++ incnfile = "mo-tilt$tilt-stress$minsigma.cn" readcn
       mark_groups
  }

  MD++ applyFext = 1
  for { set stress $minsigma } { $stress <= $maxsigma } { incr stress $dsigma } {
          
      set fx_top [expr  $Fx*$stress/$ntop]
      set fz_top [expr  $Fz*$stress/$ntop]
      set fx_bot [expr -$Fx*$stress/$nbot]
      set fz_bot [expr -$Fz*$stress/$nbot]
      puts "fx_top = $fx_top fz_top = $fz_top fx_bot = $fx_bot fz_bot = $fz_bot"

      MD++ clearFext
      MD++ input = \[ 1 $fx_top 0 $fz_top \] addFext_to_group 
      MD++ input = \[ 2 $fx_bot 0 $fz_bot \] addFext_to_group 
  
      MD++ relax
      MD++ finalcnfile = "mo-tilt$tilt-stress$stress.cn" writecn

      set E [MD++_Get EPOT]
      set dE [expr $E-$E0 ]
      set dr [expr -0.5*$dE/($F0*$stress)]
      puts $fileID "$stress $E $dE $dr"
      flush $fileID

      if { [expr abs($dr)] > 10 } {
          break
      }
  }
  close $fileID 
  exitmd

} else {
        
 puts "unknown status = $status"
 exitmd 

} 

