# MIF 2.1
# MIF Example File: pulse.mif
# Description: Gaussian applied field pulse

set pi [expr {4*atan(1.0)}]
set mu0 [expr {4*$pi*1e-7}]

RandomSeed 1

Parameter cellsize 5e-9

Parameter pamp  200   ;# Maximum amplitude of the applied field pulse, in mT
Parameter pwidth 10   ;# Pulse width at half height, in ps
Parameter pwait  1.0  ;# Location in time of pulse peak, in ns

# Convert pulse amplitude from mT to A/m
set pamp [expr {$pamp*0.001/$mu0}]

# Convert pwait to seconds
set pwait [expr {$pwait*1e-9}]

# Compute exponential factor, in 1/sec^2.  Field formula is
# pamp.exp(pfac.(t-pwait)^2), with t in seconds.
set pfac [expr {-log(2.)/(($pwidth*0.5*1e-12)*($pwidth*0.5*1e-12))}]

Specify Oxs_BoxAtlas:atlas {
  xrange {0 200e-9}
  yrange {0 100e-9}
  zrange {0  20e-9}
}

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

Specify Oxs_CubicAnisotropy {
  K1  -4.5e3
  axis1 {1 0 0}
  axis2 {0 1 0}
}

Specify Oxs_UniformExchange {
  A  9e-12
}

Specify Oxs_ScriptUZeeman {
   script_args total_time
   script GaussianPulse
}

proc GaussianPulse { total_time } {
   global pamp pfac pwait
   set t [expr {$total_time-$pwait}]
   set Hy [expr {$pamp*exp($pfac*$t*$t)}]
   set dHy [expr {2*$pfac*$t*$Hy}]
   return [list 0 $Hy 0 0 $dHy 0]
}


# Add biasing field, 100 mT
Specify Oxs_FixedZeeman [subst {
   field { 100 0 0}
   multiplier [expr {0.001/$mu0}]
}]


Specify Oxs_Demag {}

Specify Oxs_RungeKuttaEvolve:evolve {
  alpha 0.02
}

proc CornerChunk { vx vy vz x y z } {
   # Return projection for corner of block nearest origin;
   # corner dimensions are 20 nm on each edge.
   if {$x<20e-9 && $y<20e-9 && $z<20e-9} {
      return [list $vx $vy $vz]
   }
   return [list 0. 0. 0.]
}

Specify Oxs_TimeDriver [subst {
 basename pulse
 evolver :evolve
 comment {run for 5 ns total, with a stage event triggered every 0.2 ns
          inside the first ns, and then every 0.05 ns for the next 4 ns.}
 stopping_time {{0.2e-9 5} {0.05e-9 80} :expand:}
 mesh :mesh
 Ms 800e3
 m0 { 1 0.02 0.01 }
 projection_outputs {
    mx_corner {Oxs_ScriptVectorField {
       atlas :atlas
       script {CornerChunk 1 0 0}
       script_args rawpt
    }}
    my_corner {Oxs_ScriptVectorField {
       atlas :atlas
       script {CornerChunk 0 1 0}
       script_args rawpt
    }}
    mz_corner {Oxs_ScriptVectorField {
       atlas :atlas
       script {CornerChunk 0 0 1}
       script_args rawpt
    }}
 }
}]
