# -*-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-core-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  20  -1   1   0  40  -1  -1   2   4"
   set supercell(-85.96) "   7   7   6   2  -1   1   0  40  -3  -3   7   2"
   set supercell(-74.21) "   2   2   1   5  -1   1   0  20  -1  -1   4   3"
   set supercell(-54.74) "   1   1   0  12  -1   1   0  20   0   0   1   8"
   set supercell(-35.26) "   2   2  -1   5  -1   1   0  20   1   1   4   2"
   set supercell(-31.75) "   5   5  -3   2  -1   1   0  20   3   3  10   1"
   set supercell(-29.5)  "   3   3  -2   5  -1   1   0  25   1   1   3   3"
   set supercell(-25.24) "   5   5  -4   2  -1   1   0  20   2   2   5   2"
   set supercell(-22.58) "   9   9  -8   1  -1   1   0  20   4   4   9   1"
   set supercell(-19.47) "   1   1  -1   8  -1   1   0  20   1   1   2   4"
   set supercell(-14.42) "   5   5  -6   2  -1   1   0  20   3   3   5   2"
   set supercell(-3.238) "   9   9 -16   1  -1   1   0  25   8   8   9   1"
   set supercell(0)      "   1   1  -2  20  -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   1  -1   1   0  30   7   7 -13   1"
   set supercell(85.74) "  -6  -6  -7   2  -1   1   0  30   7   7 -12   1"
   set supercell(81.95) "  -3  -3  -4   3  -1   1   0  25   2   2  -3   3"
   set supercell(77.54) "  -9  -9 -14   1  -1   1   0  25   7   7  -9   1"
   set supercell(75.58) "  -3  -3  -5   3  -1   1   0  25   5   5  -6   1"
   set supercell(70.53) "  -1  -1  -2   6  -1   1   0  20   1   1  -1   5"
   set supercell(63.2)  "  -3  -3  -8   2  -1   1   0  25   4   4  -3   2"
   set supercell(54.74) "  -1  -1  -4   4  -1   1   0  20   2   2  -1   4"
   set supercell(48.53) "  -1  -1  -6   3  -1   1   0  25   3   3  -1   3"
   set supercell(43.31) "  -1  -1 -10   2  -1   1   0  25   5   5  -1   2"
   set supercell(39.31) "  -1  -1 -20   1  -1   1   0  25  10  10  -1   1"
   set supercell(35.26) "   0   0  -1  16  -1   1   0  20   1   1   0   8"
   set supercell(31.22) "   1   1 -20   1  -1   1   0  25  10  10   1   1"
   set supercell(27.21) "   1   1 -10   2  -1   1   0  20   5   5   1   1"
   set supercell(15.79) "   1   1  -4   4  -1   1   0  20   2   2   1   4"
   set supercell(3.113) "   4   4  -9   2  -1   1   0  26   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 expan } {
    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

    MD++ latticesize(3) = [expr $expan * [MD++_Get latticesize(3)]]
    MD++ latticesize(7) = [expr $expan * [MD++_Get latticesize(7)]]

    puts "latticesize(3)= [MD++_Get latticesize(3)]"
    puts "latticesize(7)= [MD++_Get latticesize(7)]"
}

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 expan } { 
    global supercell

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

    # (setting for Peierls stress calculation)
    # 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.2596 ]
    #set y0 [expr -0.25+0.111/[MD++_Get latticesize(7)] ]
    #set y0 [expr -0.25-0.385/[MD++_Get latticesize(7)] ]
    #set x0 0.01
    #set y0 -0.2596
    # (setting for Peierls stress calculation)
    #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]

    set c1x [MD++_Get latticesize(0)]
    set c1y [MD++_Get latticesize(1)]
    set c1z [MD++_Get latticesize(2)]
    set n1  [MD++_Get latticesize(3)]
    set c2x [MD++_Get latticesize(4)]
    set c2y [MD++_Get latticesize(5)]
    set c2z [MD++_Get latticesize(6)]
    set n2  [MD++_Get latticesize(7)]

    set Lx [expr sqrt($c1x*$c1x+$c1y*$c1y+$c1z*$c1z)*$n1 ]
    set Ly [expr sqrt($c2x*$c2x+$c2y*$c2y+$c2z*$c2z)*$n2 ]

    set rep1 [format "%.0f" [expr ceil(1000.0/$Lx) ] ]
    set rep2 [format "%.0f" [expr ceil(1000.0/$Ly) ] ]

    if { $rep1 > 10 } { set rep1 10 }
    if { $rep2 > 10 } { set rep2 10 }

    #reduce the number of images for big cells
    puts "repeat image dipoles rep1 = $rep1 x rep2 = $rep2"
    MD++ input = \[ 3 2 $a 0 $b  $x0 $y0 $y1 0.305 -$rep1 $rep1 -$rep2 $rep2 1 0 0 0 0 \]

    #MD++ input = \[ 3 2 $a 0 $b  $x0 $y0 $y1 0.305 -10 10 -10 10 1 0 0 0 0 \]
    #MD++_PrintMatrix H "(A)"
    #MD++ sleepseconds = 3 sleep

    MD++ makedipole    

    #MD++_PrintMatrix H "(A)"

    MD++ eval 
    set maxnnm [MD++_Get "current_NNM"]
    puts "maximum number of neighbors per atom is $maxnnm"
}

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 write_madsum_matlab_file { datafile structname openmode tilt expan } {
    global supercell

    #TO DO: (implemented, now testing...)
    # box shrinkage modifies simulation volume -> residual elastic energy
    # compare with Keonwook's earlier results for edge and screw cases
    # correct calculation of Lx and Lz for non-orthogonal boxes
    # correct coordinate system for non-orthogonal boxes
    
    #Material constants for Mo
    set Ecoh 6.82000233284684
    set C11 46.47e4
    set C12 16.15e4
    set C44 10.89e4
    set rc_over_b 1

    puts "write_madsum_matlab_file datafile = $datafile structname = $structname openmode = $openmode tilt = $tilt expan = $expan"
    
    set fileID [open $datafile $openmode ]

    set a1 [MD++_Get latticesize  0]
    set a2 [MD++_Get latticesize  1]
    set a3 [MD++_Get latticesize  2]    
    set nx [MD++_Get latticesize  3]
    
    set b1 [MD++_Get latticesize  4]
    set b2 [MD++_Get latticesize  5]
    set b3 [MD++_Get latticesize  6]    
    set ny [MD++_Get latticesize  7]

    set c1 [MD++_Get latticesize  8]
    set c2 [MD++_Get latticesize  9]
    set c3 [MD++_Get latticesize 10]    
    set nz [MD++_Get latticesize 11]

    set a0 [MD++_Get "latticeconst"]

    set NP [MD++_Get "NP"]

    set EPOT [MD++_Get "EPOT"]

    set sig_xx [MD++_Get "TSTRESSinMPa_xx"]
    set sig_xy [MD++_Get "TSTRESSinMPa_xy"]
    set sig_xz [MD++_Get "TSTRESSinMPa_xz"]
    set sig_yx [MD++_Get "TSTRESSinMPa_yx"]
    set sig_yy [MD++_Get "TSTRESSinMPa_yy"]
    set sig_yz [MD++_Get "TSTRESSinMPa_yz"]
    set sig_zx [MD++_Get "TSTRESSinMPa_zx"]
    set sig_zy [MD++_Get "TSTRESSinMPa_zy"]
    set sig_zz [MD++_Get "TSTRESSinMPa_zz"]

    puts $fileID "%This file is generated by MD++"
    puts $fileID "%"
    puts $fileID "% You can run it in command line as"
    puts $fileID "%   octave -q $datafile"
    puts $fileID "%"
    puts $fileID "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
    puts $fileID "% $structname "
    puts $fileID "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
    puts $fileID "$structname = struct();"
    puts $fileID "$structname.tilt = $tilt; %in degrees"
    puts $fileID "$structname.expan = $expan; %no unit"
    puts $fileID "$structname.N = $NP;"
    puts $fileID "$structname.a0 = $a0; %in A"
    puts $fileID "$structname.C11 = $C11; %in MPa"
    puts $fileID "$structname.C12 = $C12; %in MPa"
    puts $fileID "$structname.C44 = $C44; %in MPa"
    puts $fileID "$structname.C1 = \[ $a1 $a2 $a3 $nx \]; %no unit"
    puts $fileID "$structname.C2 = \[ $b1 $b2 $b3 $ny \];"
    puts $fileID "$structname.C3 = \[ $c1 $c2 $c3 $nz \];"
    puts $fileID "$structname.Ecoh = $Ecoh; %in eV"
    puts $fileID "$structname.rc_over_b = $rc_over_b;"
    puts $fileID "$structname.E1 = $EPOT; %in eV"
    puts $fileID "$structname.stress = \[ $sig_xx $sig_xy $sig_xz"
    puts $fileID "               $sig_yx $sig_yy $sig_yz"
    puts $fileID "               $sig_zx $sig_zy $sig_zz ]; %in MPa"
    puts $fileID " "
    puts $fileID "% compute simulation volume"
    puts $fileID "$structname.V = dot(cross($structname.C1(1:3),$structname.C2(1:3)),$structname.C3(1:3));"
    puts $fileID "%$structname.V = $structname.V*$structname.a0^3*$structname.C1(4)*$structname.C2(4)*$structname.C3(4);"
    puts $fileID " "
    puts $fileID "% convert stress into vector form"
    puts $fileID "$structname.sigma = \[ $sig_xx ; $sig_yy ; $sig_zz ; $sig_yz ; $sig_zx ; $sig_xy \];"
    puts $fileID " "
    puts $fileID "% construct elastic stiffness and compliance tensors for cubic materials"
    puts $fileID "$structname.C0 = \[$structname.C11 $structname.C12 $structname.C12 0    0    0;"
    puts $fileID "                   $structname.C12 $structname.C11 $structname.C12 0    0    0;"
    puts $fileID "                   $structname.C12 $structname.C12 $structname.C11 0    0    0;"
    puts $fileID "                   0    0    0    $structname.C44  0                0;"
    puts $fileID "                   0    0    0    0                $structname.C44  0;"
    puts $fileID "                   0    0    0    0                0                $structname.C44\];"
    puts $fileID " "    
    puts $fileID "$structname.S0 = inv($structname.C0);"
    puts $fileID " "
    puts $fileID "% construct unit vectors along C1, C2, C3 (atomistic coordinate, for residual strain energy calculation)"
    puts $fileID "$structname.ex = $structname.C1(1:3)' / norm($structname.C1(1:3));"
    puts $fileID "$structname.ey = $structname.C2(1:3)' / norm($structname.C2(1:3));"
    puts $fileID "$structname.ez = cross($structname.ex, $structname.ey);"
    puts $fileID " "
    puts $fileID "$structname.va = $structname.C1(1:3)*$structname.C1(4)*$structname.a0;"
    puts $fileID "$structname.vb = $structname.C2(1:3)*$structname.C2(4)*$structname.a0;"
    puts $fileID "$structname.vc = $structname.C3(1:3)*$structname.C3(4)*$structname.a0;"
    puts $fileID " "
    puts $fileID "% Burgers vector"
    puts $fileID "$structname.b0 = \[1 1 1\]/2 *$structname.a0;"
    puts $fileID " "
    puts $fileID "% account for the shrinkage of box when atoms are removed"    
    puts $fileID "if ( dot($structname.va, $structname.b0) > 0 )"
    puts $fileID "    $structname.va = $structname.va - 0.5 * $structname.b0;"
    puts $fileID "else"
    puts $fileID "    $structname.va = $structname.va + 0.5 * $structname.b0;"
    puts $fileID "end"
    puts $fileID "$structname.V  = dot(cross($structname.va, $structname.vb), $structname.vc);"
    puts $fileID " "
    puts $fileID "% construct unit vectors for MadSum calculation coordinate system"
    puts $fileID "$structname.vap = $structname.va - $structname.vc*dot($structname.va,$structname.vc)/dot($structname.vc,$structname.vc);"
    puts $fileID "$structname.vbp = $structname.vb;"
    puts $fileID "$structname.vcp = $structname.vc;"
    puts $fileID " "
    puts $fileID "$structname.exp = $structname.vap' / norm($structname.vap);"
    puts $fileID "$structname.eyp = $structname.vbp' / norm($structname.vbp);"
    puts $fileID "$structname.ezp = cross($structname.exp, $structname.eyp);"
    puts $fileID " "
    puts $fileID "% for MadSum calculation "
    puts $fileID "$structname.Lx = norm($structname.vap);"
    puts $fileID "$structname.Ly = norm($structname.vbp);"
    puts $fileID "$structname.Lz = norm($structname.vcp);"
    puts $fileID " "
    puts $fileID "% transformation matrix for change of basis for residual strain energy calculation"
    puts $fileID "$structname.A = \[$structname.ex,  $structname.ey,  $structname.ez\];"
    puts $fileID " "
    puts $fileID "% transformation matrix for change of basis for residual strain energy calculation"
    puts $fileID "$structname.M = \[$structname.exp, $structname.eyp, $structname.ezp\];"
    puts $fileID " "    
    puts $fileID "% Omega is the inverse matrix of A (which is the same as transpose)"
    puts $fileID "Omega = $structname.A';"
    puts $fileID " "
    puts $fileID "% tranformation following Tom Ting "
    puts $fileID "$structname.K1 = Omega.^2;"
    puts $fileID "$structname.K2 = \[Omega(1,2)*Omega(1,3) Omega(1,3)*Omega(1,1) Omega(1,1)*Omega(1,2);"
    puts $fileID "      Omega(2,2)*Omega(2,3) Omega(2,3)*Omega(2,1) Omega(2,1)*Omega(2,2);"
    puts $fileID "      Omega(3,2)*Omega(3,3) Omega(3,3)*Omega(3,1) Omega(3,1)*Omega(3,2)\];"
    puts $fileID "$structname.K3 = \[Omega(2,1)*Omega(3,1) Omega(2,2)*Omega(3,2) Omega(2,3)*Omega(3,3);"
    puts $fileID "      Omega(3,1)*Omega(1,1) Omega(3,2)*Omega(1,2) Omega(3,3)*Omega(1,3);"
    puts $fileID "      Omega(1,1)*Omega(2,1) Omega(1,2)*Omega(2,2) Omega(1,3)*Omega(2,3)\];"
    puts $fileID "$structname.K4 = \[Omega(2,2)*Omega(3,3)+Omega(2,3)*Omega(3,2) Omega(2,3)*Omega(3,1)+Omega(2,1)*Omega(3,3) Omega(2,1)*Omega(3,2)+Omega(2,2)*Omega(3,1);"
    puts $fileID "            Omega(3,2)*Omega(1,3)+Omega(3,3)*Omega(1,2) Omega(3,3)*Omega(1,1)+Omega(3,1)*Omega(1,3) Omega(3,1)*Omega(1,2)+Omega(3,2)*Omega(1,1);"
    puts $fileID "            Omega(1,2)*Omega(2,3)+Omega(1,3)*Omega(2,2) Omega(1,3)*Omega(2,1)+Omega(1,1)*Omega(2,3) Omega(1,1)*Omega(2,2)+Omega(1,2)*Omega(2,1)\];"
    puts $fileID "$structname.K = \[$structname.K1 2*$structname.K2; $structname.K3 $structname.K4\];"
    puts $fileID "$structname.K_inv = inv($structname.K);"
    puts $fileID "clear Omega; %clear temporary matrix Omega for clarity"
    puts $fileID " "
    puts $fileID "% transform elastic stiffness tensor"
    puts $fileID "$structname.C = $structname.K*$structname.C0*$structname.K';"
    puts $fileID "$structname.S = $structname.K_inv'*$structname.S0*$structname.K_inv;"
    puts $fileID " "
    puts $fileID "% compute strain energy per unit volume in MPa"
    puts $fileID "$structname.W_den_in_MPa = 1/2 * $structname.sigma' * $structname.S * $structname.sigma;"
    puts $fileID "% compute total strain energy in simulation volume in eV"
    puts $fileID "$structname.W_tot_in_eV = $structname.W_den_in_MPa*$structname.V*1e-24*(6.241506e18);"
    puts $fileID " "
    puts $fileID "% compute MadSum elastic energy"
    puts $fileID "% elastic constants (in eV/A^3)"
    puts $fileID "$structname.C_in_eV_over_A3 = \[ $structname.C11 $structname.C12 $structname.C44 \] / 1.6022e5;"
    puts $fileID "% dipole and cell geometry"
    puts $fileID "$structname.coord = \[$structname.Lx 0 $structname.Ly 0 0.5\];"
    puts $fileID "$structname.cut = \[20 20\];"
    puts $fileID "% compute MadSum Elastic Energy"
    puts $fileID "\[$structname.Eel, $structname.Eprm, $structname.Eimg, $structname.Esum\] = madsum_cubic($structname.C_in_eV_over_A3, $structname.b0, $structname.M, norm($structname.b0)*$structname.rc_over_b, $structname.coord, $structname.cut);"
    puts $fileID " "
    puts $fileID "% compute atomistic excess energy for dipole in PBC in eV/A "
    puts $fileID "$structname.Eatm = ($structname.E1 + $structname.N*$structname.Ecoh - $structname.W_tot_in_eV) / $structname.Lz;"
    puts $fileID "% compute core energy in eV/A "
    puts $fileID "$structname.Ecore = ($structname.Eatm - $structname.Eel) / 2;"
    puts $fileID " "
    puts $fileID "% print out total elastic strain energy in eV"
    puts $fileID "%disp(sprintf('W_tot = %25.12e (eV)',$structname.W_tot_in_eV));"
    puts $fileID " "
    puts $fileID "% print out excess atomistic energy in eV/A"
    puts $fileID "%disp(sprintf('Eatm  = %25.12e (eV/A)',$structname.Eatm));"
    puts $fileID " "
    puts $fileID "% print out MadSum elastic strain energy in eV/A"
    puts $fileID "%disp(sprintf('Eel   = %25.12e (eV/A)   \[aniso\]',$structname.Eel));"
    puts $fileID "%disp(sprintf('Eimg  = %25.12e (eV/A)   \[aniso\]',$structname.Eimg));"
    puts $fileID "%disp(sprintf('Eprm  = %25.12e (eV/A)   \[aniso\]',$structname.Eprm));"
    puts $fileID " "
    puts $fileID "% print out core energy in eV/A"
    puts $fileID "%disp(sprintf('Ecore = %25.12e (eV/A)   \[aniso\]',$structname.Ecore));"
    puts $fileID " "
    
    close $fileID
}
#end of proc residual_force

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: create dislocation dipole, relax, write matlab file for core energy calculation
#        1: visualization
#
# 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

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

  create_datebase
  MD++ NNM = 40  SAVEMEMORY = 7

  set tilt $n

  for { set expan 1 } { $expan <= 10 } { incr expan 1 } {
  
      make_dislocation $tilt $expan
      #MD++ finalcnfile = "mo-expan$expan.cn" writecn
      #MD++ incnfile = "mo-expan$expan.cn" readcn
      #MD++ finalcnfile = "ro-expan$expan.cn" writecn
      #MD++ incnfile = "ro-expan$expan.cn" readcn
      
      MD++ conj_ftol = 1e-4 conj_fixbox = 1 conj_fevalmax = 10000
      MD++ eval
      MD++ relax

      # re-run CG-relax if residual gradient is too large
      set g2res_min 1e-7
      set NP [MD++_Get "NP"]
      for { set iter 1 } { $iter <= 3 } { incr iter } {
          set g2res [ MD++_Get "conj_g2res" ]
          set g2res_per_atom [ expr $g2res / $NP ]
          puts "residual gradient: g2res = $g2res  g2res_per_atom = $g2res_per_atom"  
          
          if { $g2res_per_atom < $g2res_min } {
              break;
          } else {
              MD++ eval
              MD++ relax
          }
      }
      MD++ finalcnfile = "mo-tilt$tilt-expan$expan.cn" writecn
      MD++ eval
      
      if { $expan == 1 } {
          set openmode "w"
      } else {
          set openmode "a"
      }
      write_madsum_matlab_file "cal_core_eng.m" "disl_expan${expan}" $openmode $tilt $expan
  }
  
  #MD++ sleep
  exitmd
  
} elseif { $status == 1 } {
  # visualization
  MD++ setnolog
  initmd "view"
  readpot

  create_datebase
  MD++ NNM = 40  SAVEMEMORY = 7

  #test
#  make_dislocation -90 2
#  openwindow
#  MD++ conj_ftol = 1e-4 conj_fixbox = 1 conj_fevalmax = 10000
#  MD++ relax
#  MD++ finalcnfile = "relaxed.cn" writecn
#  MD++ eval sleep 
  
  
  set tilt_list  { -90 }
  set expan_list { 2 }
  
  for { set i 0 } { $i < [llength $tilt_list] } { incr i 1 } {
    for { set j 0 } { $j < [llength $expan_list] } { incr j 1 } {
      set tilt  [lindex $tilt_list  $i]
      set expan [lindex $expan_list $j]

      #for write_madsum_matlab_file   
      choose_supercell $tilt $expan
      
      MD++ incnfile = "../mo-core-tilt$tilt/mo-tilt$tilt-expan$expan.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

      set openmode "w"
      write_madsum_matlab_file "cal_core_eng.m" "disl_expan$expan" $openmode $tilt $expan
      
      after 8000
    }
  }

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

} elseif { $status == 2 } {
  # compute cohesive energy Ecoh
  MD++ setnolog
  initmd "test"
  readpot

  MD++ NNM = 40  SAVEMEMORY = 7

  if { 0 } {
  MD++ {
  latticestructure = body-centered-cubic latticeconst = 3.1472 #(A) for Mo
  latticesize = [ 1 0 0   5
                  0 1 0   5
                  0 0 1   5 ] 
  makecrystal finalcnfile = perf.cn writecn                
  }
  } else {  
  MD++ {
  latticestructure = body-centered-cubic latticeconst = 3.1472 #(A) for Mo
  latticesize = [  1   1  -2   8    #for screw [111]
                   1  -1   0   19
                   0.5   0.5   0.5   5 ]
  makecrystal finalcnfile = perf.cn writecn                
  mkdipole = [ 3 2 #z(dislocation line), y(dipole direction)
               0 0 0.2 #(burgers vector relative to box)
               0 -0.2632  0.2368 #Y=18 d=0.5  (b)
               0.305 #\nu
               -10 10 -10 10 1  #number of images
               0 0 0 0 ]
  makedipole finalcnfile = makedp.cn writecn
  }
  }
  #openwindow
  MD++ conj_ftol = 1e-4 conj_fixbox = 1 conj_fevalmax = 10000
  MD++ relax
  MD++ finalcnfile = "relaxed.cn" writecn
  MD++ eval 

  set NP [MD++_Get "NP"]
  set E0 [MD++_Get "EPOT"]
  set Ecoh [format "%25.16e" [expr -$E0 / $NP]]
  set maxnnm [MD++_Get "current_NNM"]

  puts "maximum number of neighbors per atom is $maxnnm"
  puts "NP = $NP  E0 = $E0 (eV)"
  puts "Ecoh = $Ecoh (eV)"

  #MD++ sleep 

  exitmd

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

} 

