# MIF 2.1
#
# Sample MIF file based on simulations in manuscript
#
#  "Excitations of Incoherent Spin-Waves due to Spin-Transfer Torque,"
#  K.J. Lee, A. Deac, O. Redon, J.P. Nozieres and B. Dieny,
#  Nature Materials 3, 877-881 (2004).
#
set pi [expr 4*atan(1.0)]
set mu0 [expr 4*$pi*1e-7]

set basename spinxfer

Parameter COMPUTE_INITIAL_M 0

Parameter total_current -0.004 ;# Current in amps

# Specify contact: if circle_contact is 1, then current flows through
# centered circular region of indicated diameter.  If circle_contact
# is 0, then circle_diameter is ignored, and current flows through
# entire elliptical shape.
Parameter circle_contact 1

set circle_diameter 50e-9   ;# in meters.  If you change this, then
## adjustments must also be made to the Oersted field.

Parameter Happ 0.0 ;# Field in kOe
set Happ [expr {$Happ*1e6/(4*$pi)}]  ;# Convert to A/m

Parameter Happ_angle 180.  ;# Direction of applied field, in degrees
set Happ_angle [expr {$Happ_angle*$pi/180.}]

Parameter Ms 1420e3
Parameter A    20e-12

Parameter Polarization  0.5669

Parameter Lambda 1.0

Parameter mp_theta 1.0 ;# Direction of mp, in degrees
set mp_theta [expr {$mp_theta*$pi/180.}]

set length 129.6e-9
set width   72.0e-9
set thick    3.0e-9

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

;# Compute cross-sectional area of current flow
if {$circle_contact} {
  set current_area [expr {$pi*$circle_diameter*$circle_diameter/4.}]
} else {
  set current_area [expr {$pi*$length*$width/4.}]
}
set current_density [expr {$total_current/$current_area}]

Parameter xycellsize 3.6e-9
Parameter zcellsize $thick

Specify Oxs_RectangularMesh:mesh [subst {
  cellsize {$xycellsize $xycellsize $zcellsize}
  atlas :atlas
}]

# Exchange
Specify Oxs_UniformExchange [subst {
  A   $A
}]

# Demag
Specify Oxs_Demag {}

# Applied field
Specify Oxs_FixedZeeman:Happ [subst {
    field {[expr {cos($Happ_angle)}] [expr {sin($Happ_angle)}] 0.0}
    multiplier $Happ
}]

if {!$COMPUTE_INITIAL_M} {

if {$circle_contact} {
   # Evolver
   Specify Oxs_SpinXferEvolve:evolve [subst {
     alpha 0.014
     start_dm 0.01
     mp {[expr {cos($mp_theta)}] [expr {sin($mp_theta)}] 0}
     J { Oxs_ScriptScalarField {
         atlas :atlas
         script {Circle $current_density \
                     [expr {$circle_diameter*$circle_diameter/4.0}]}
         script_args {relpt span}
     }}
     P $Polarization
     Lambda $Lambda
   }]

   # Oersted field.  topwire-oerstedfield contains an
   # approximation of the field generated by a circular
   # wire or radius 50 nm centered at (1000 nm, 1250 nm)
   # carrying 1 amp of current, uniformly distributed
   # across the wire.
   set wirefieldfile topwire-oerstedfield.ohf
   # set wirefieldfile spinxfer-50nm_circlefield.ohf
} else {
   # Evolver
   Specify Oxs_SpinXferEvolve:evolve [subst {
     alpha 0.014
     start_dm 0.01
     mp {[expr {cos($mp_theta)}] [expr {sin($mp_theta)}] 0}
     J { Oxs_ScriptScalarField {
       atlas :atlas
       script {Ellipse $current_density}
     }}
     P $Polarization
     Lambda $Lambda
   }]

   # Oersted field
   set wirefieldfile spinxfer-ellipsefield.ohf
}

Specify Oxs_FixedZeeman:WireField [subst {
   field { Oxs_FileVectorField {
      atlas :atlas
      file [list $wirefieldfile]
   }}
   multiplier $total_current
}]

Specify Oxs_ScriptScalarField:Middle [subst {
    atlas :atlas
    script MiddleCube
    script_args rawpt
}]


set cx [expr {129.6e-9/2.}]
set cy [expr  {72.0e-9/2.}]
set cz [expr   {3.0e-9/2.}]
set cube_edge 10e-9
proc MiddleCube { x y z } {
    global cx cy cz cube_edge
    if {abs($x-$cx)>$cube_edge/2
        || abs($y-$cy)>$cube_edge/2
        || abs($z-$cz)>$cube_edge/2} {
        return 0.0
    }
    return 1.0
}

# Driver
Specify Oxs_TimeDriver [subst {
 basename [list $basename]
 evolver :evolve
 stopping_time { 0.2e-9 0.1e-9 1.2e-9 0.05e-9 1.65e-9 1.1e-9 0.7e-9 2e-9 }
 mesh :mesh
 Ms { Oxs_ScriptScalarField {
    atlas :atlas
    script {Ellipse $Ms}
 } }
 comment {m0 { 1 0 0 }}
 m0 { Oxs_FileVectorField {
    atlas :atlas
    file [list ${basename}-start.omf]
    norm 1.0
 }}
 projection_outputs {
    "mx middle" { Oxs_MaskVectorField {
        field {1 0 0}
        mask :Middle
    }}
    "my middle" { Oxs_MaskVectorField {
        field {0 1 0}
        mask :Middle
    }}
    my_left { Oxs_ScriptVectorField {
       atlas :atlas
       script {LeftHalfField 0. 1. 0.}
    }}
    my_right { Oxs_ScriptVectorField {
       atlas :atlas
       script {RightHalfField 0. 1. 0.}
    }}
 }
 projection_options {
    my_right { scaling -1.0 }
 }
}]

} else {

Specify Oxs_CGEvolve:evolve {}

Specify Oxs_MinDriver [subst {
 evolver :evolve
 stopping_mxHxm 1e-3
 mesh :mesh
 Ms { Oxs_ScriptScalarField {
    atlas :atlas
    script {Ellipse $Ms}
 } }
 m0 { Oxs_ScriptVectorField {
    atlas :atlas
    script C_State
    norm 1.0
 }}
}]

}

proc Ellipse { Ms x y z } {
    set xrad [expr {2.*$x - 1.}]
    set yrad [expr {2.*$y - 1.}]
    set test [expr {$xrad*$xrad+$yrad*$yrad}]
    if {$test>1.0} {return 0.0}
    return $Ms
}

proc Circle { J radsq rx ry rz xspan yspan zspan} {
    set xoff [expr {($rx - 0.5)*$xspan}]
    set yoff [expr {($ry - 0.5)*$yspan}]
    if {$xoff*$xoff+$yoff*$yoff>$radsq} {return 0.0}
    return $J
}

proc C_State { x y z } {
    if {$x<0.25} { return [list 0.  -1.  -0.1] }
    if {$x>0.75} { return [list 0.  -1.  -0.1] }
    return [list 1. 0. 0.]
}

proc CircleField { vx vy vz radsq rx ry rz xspan yspan zspan} {
    set xoff [expr {($rx - 0.5)*$xspan}]
    set yoff [expr {($ry - 0.5)*$yspan}]
    if {$xoff*$xoff+$yoff*$yoff>$radsq} {return [list 0. 0. 0.]}
    return [list $vx $vy $vz]
}

proc LeftHalfField { vx vy vz rx ry rz } {
     if {$rx>0.5} { return [list 0. 0. 0.] }
     return [list $vx $vy $vz]
}

proc RightHalfField { vx vy vz rx ry rz } {
     if {$rx<0.5} { return [list 0. 0. 0.] }
     return [list $vx $vy $vz]
}
