# MIF 2.1

## Constant temperature simulation
## Free layer dimensions: 30nm x 10nm x 1nm (x-by-y-by-z)
## Free layer is partitioned into three parts in the x-direction
## Current will be injected into the right-most third (20nm <= x <= 30nm)
## mp is -z in the left most third (0nm <= x <= 10nm)
## mp is +z in the right most third
## Polarization is different in the left most third and the right most third

set basename xf_stt_example

set pi [expr 4*atan(1.0)]
set mu0 [expr 4*$pi*1e-7]
set kB 1.380650424e-23
set T 300

Parameter I 1.5e-4   ;# in A

Parameter Ms  800e3

Parameter theta 179.9  ;# Polarization direction,
Parameter phi   0.1  ;# in spherical coordinates
Parameter theta_tilt [expr 0*$pi/180];
Parameter phi_tilt [expr 0*$pi/180];

Parameter length 30e-9
Parameter width  10e-9
Parameter thick    1.0e-9

set Jcurr [expr {$I/($width*$width)}]

Parameter P_left 0.5
Parameter P_fixed 0.8
Parameter P_free 0.2
Parameter Lambda_fixed 1.145
Parameter Lambda_free 1.145
Parameter Lambda_left 1.0001

proc Jwrite { Jcurr xrel yrel zrel } {
     if [expr {$xrel >= [expr {2.0/3.0}]}] { return $Jcurr }
     return 0.0
}

proc dualPinnedLayers { xrel yrel zrel } {
     if {$xrel >= 0.5} { return "0 0 1" }
     return "0 0 -1"
}

proc rightParams { param param_left xrel yrel zrel } {
     if [expr {$xrel >= [expr {2.0/3.0}]}] { return $param }
     return $param_left
}

Specify Oxs_BoxAtlas:atlas [subst {
  xrange {0 $length}
  yrange {0 $width}
  zrange {0 $thick}
}]

Parameter xyCellDim [expr {$width/128.0}]
set zlength [subst $thick]

Specify Oxs_RectangularMesh:mesh [subst {
  cellsize {$xyCellDim $xyCellDim $zlength}
  atlas :atlas
}]

Specify Oxs_UniaxialAnisotropy [subst {
  K1 [expr {56*$kB*$T/($length*$width*$thick)}]
  axis {0 0 1}
}]

Specify Oxs_UniformExchange {
  A 13e-12
}

# Spin transfer torque class
set theta_init [expr {$theta*$pi/180.}]
set phi_init   [expr {$phi*$pi/180.}]

Specify Xf_STT:PL0 [subst {
  mp { Oxs_ScriptVectorField {
     script dualPinnedLayers
     script_args { relpt }
     norm 1
     atlas :atlas
  } }
  J { Oxs_ScriptScalarField {
    script {Jwrite $Jcurr}
    script_args { relpt }
    atlas :atlas
  } }
  P_fixed { Oxs_ScriptScalarField {
    script {rightParams $P_fixed $P_left}
    script_args { relpt }
    atlas :atlas
  } }
  P_free { Oxs_ScriptScalarField {
    script {rightParams $P_free $P_left}
    script_args { relpt }
    atlas :atlas
  } }
  Lambda_fixed { Oxs_ScriptScalarField {
    script {rightParams $Lambda_fixed $Lambda_left}
    script_args { relpt }
    atlas :atlas
  } }
  Lambda_free { Oxs_ScriptScalarField {
    script {rightParams $Lambda_free $Lambda_left}
    script_args { relpt }
    atlas :atlas
  } }
}]

# Evolver
Specify Oxs_RungeKuttaEvolve:evolve [subst {
  alpha 0.01
  start_dm 0.01
  energy_precision -1
}]

# Driver
Specify Oxs_TimeDriver [subst {
 basename $basename
 evolver :evolve
 stopping_time {40e-9}
 mesh :mesh
 Ms $Ms
 m0 { [expr {sin($theta_init)*cos($phi_init)}] [expr {sin($theta_init)*sin($phi_init)}] [expr {cos($theta_init)}]}
}]
