# MIF 2.1
# Convergence test; one spin in fixed applied field.

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

Parameter timestep 10e-12

Parameter solver rkf54

set basename "onespinconv-$solver"

Parameter alpha 0.001

Parameter H 10  ;# Applied field, in mT

Parameter runtime 100e-12  ;# Run time in seconds

set gamma 2.21e5  ;# Assumed positive

RandomSeed 1

if {$timestep>0.0} {
   set time_control "min_timestep $timestep max_timestep $timestep"
} else {
   set time_control "max_timestep 1e-12 error_rate 0.01 energy_precision 1e-8"
}


Specify Oxs_BoxAtlas:atlas {
  xrange {0 10e-9}
  yrange {0 10e-9}
  zrange {0 10e-9}
}

Parameter cellsize 10e-9

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

set Ham [expr {$H*0.001/$mu0}]  ;# Applied field, in A/m

Specify Oxs_UZeeman [subst {
  Hrange {
     {  0  0  $Ham   0  0  0   0 }
  }
}]

if {[string match rk* $solver]} {
   Specify Oxs_RungeKuttaEvolve:evolver [subst {
      alpha $alpha
      gamma_LL $gamma
      method $solver
      $time_control
   }]
} elseif {[string match srk* $solver]} {
   set solvertype [string range $solver 1 end]
   Specify Oxs_SpinXferEvolve:evolver [subst {
      alpha $alpha
      gamma_LL $gamma
      method $solvertype
      J 0
      mp {1 0 0}
      $time_control
   }]
} else {
   Specify Oxs_EulerEvolve:evolver [subst {
      alpha $alpha
      gamma_LL $gamma
      $time_control
   }]
}

Specify Oxs_TimeDriver [subst {
 basename $basename
 checkpoint_interval -1
 evolver :evolver
 stopping_time $runtime
 comment {stopping_dm_dt 0.01}
 mesh :mesh
 Ms 8e5
 m0 {1 0 0}
}]

# Default output
Destination archive mmarchive
Schedule DataTable archive stage 1




# The following proc can be used to test results.  See
# NOTES III 25-Nov-2002 p15, or NOTES IV 1-Jul-2005 p47.
proc AnalyticSolution { t } {
    global alpha Ham gamma
    set phi_0 0.0
    set ct 1.0 ;# This is tan(theta_0/2.0), with theta_0 = pi/2
    set theta [expr {2*atan($ct*exp(-1*$alpha*$gamma*$Ham*$t))}]
    set phi [expr {$Ham*$gamma*$t + $phi_0}]
    set sintheta [expr {sin($theta)}]
    set mx [expr {cos($phi)*$sintheta}]
    set my [expr {sin($phi)*$sintheta}]
    set mz [expr {cos($theta)}]
    return [list $theta $phi $mx $my $mz]
}

set analsol [AnalyticSolution $runtime]
Report [format "Analytic solution, (mx,my,mz) = (%#.16g,%#.16g,%#.16g)" \
           [lindex $analsol 2]  [lindex $analsol 3]  [lindex $analsol 4]]
