# MIF 2.1
# MIF Example File: stdprob2.mif
# Description: Sample problem description for muMAG Standard Problem #2
#
# Running this example produces one-half of a hysteresis loop, with the
# applied field running from (Ha,Ha,Ha) to (Hc,Hc,Hc).  The sample is a
# soft magnetic strip having dimensions 5d x d x d/10, where length "d",
# measured in exchange lengths, is set as a Parameter when the MIF file
# is loaded.  Output is directed through mmArchive to one or more files
# with file names determined by the "basename" variable (see below).
# The remanent magnetization and an estimate of the coercivity can be
# extracted from the .odt "DataTable" output.
#
# No default value for d is specified.  To use this MIF file you *must*
# include a Parameter value for d at run time, either on the command
# line with Boxsi or in the "Params" box in the "Load Problem" dialog of
# Oxsii.
#
# To create a full Standard Problem #2 submission, this MIF file would
# need to be run many times with different values of d.  Ideally, for
# each d severals runs should be performed at various cellsizes so
# results can be extrapolated to zero cellsize.  Applied field
# parameters Hb, Hc and Hstep_small can be adjusted to improve
# estimation of the coercive field.
#
# Note that the external field is applied along the (1,1,1) direction,
# so applied field magnitudes are sqrt(3) times larger than the
# coordinate field component values.  The Bapplied and m_dot_u DataTable
# outputs provide averaged values projected onto the (1,1,1) direction,
# i.e., B * (1,1,1)/sqrt(3) and m * (1,1,1)/sqrt(3), respectively.

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

set lex 5e-9
set Ms [expr {1.0/$mu0}]  ;# = 1 Tesla
set A [expr {0.5*$mu0*$lex*$lex*$Ms*$Ms}]

########################################################################
# Simulation parameters

Parameter d  ;# Strip width, in units of lex. *** REQUIRED ***
Parameter cellsize 0.5 ;# Cellsize, in units of lex

Parameter stop 0.1 ;# Torque topping criteria, in A/m

Parameter Ha  100.   ;# Start field component, in mT
Parameter Hb  -15.   ;# Middle field component, in mT
Parameter Hc -100.   ;# Stop field component, in mT
# Note: Field is applied along (1,1,1) direction, so field
# magnitude is |field_component|*sqrt(3).

Parameter Hstep_large 5  ;# Large component step size, in mT
Parameter Hstep_small 1  ;# Small component step size, in mT

Parameter m0_file {}  ;# Initial magnetization; if {}, then use
                      ## uniform (1,1,1) field.

########################################################################
# Auxiliary variables and adjustments

set ysize [expr {$d*$lex}]
set xsize [expr {5.0*$ysize}]
set zsize [expr {$ysize/10.}]

set csize [expr {$cellsize*$lex}]
set xcellsize [expr {$xsize/ceil($xsize/$csize)}]
set ycellsize [expr {$ysize/ceil($ysize/$csize)}]
set zcellsize [expr {$zsize/ceil($zsize/$csize)}]

set basename [format "stdprob2-d%05.2f-cs%3.2f-stop%g" $d $cellsize $stop]

# Adjust Ha, Hb and Hc so an integral number of steps lies between
# each endpoint.
set Ha_steps [expr {int(round(abs($Ha)/$Hstep_large))}]
set Ha [expr {$Ha_steps * $Hstep_large}]

set Hb_steps [expr {int(round($Hb/$Hstep_large))}]
set Hb [expr {$Hb_steps * $Hstep_large}]
set Hb_steps [expr {abs($Hb_steps)}]

set Hc_steps [expr {int(round(($Hc-$Hb)/$Hstep_small))}]
set Hc [expr {$Hb + $Hc_steps * $Hstep_small}]
set Hc_steps [expr {abs($Hc_steps)}]

if {[string match {} $m0_file]} {
   set m0 [list 1. 1. 1.]
} else {
   set m0 [subst { Oxs_FileVectorField {
         file  [list $m0_file]
         atlas :atlas
         norm  1
   }}]
}

########################################################################


Specify Oxs_BoxAtlas:atlas [subst {
  xrange {0 $xsize}
  yrange {0 $ysize}
  zrange {0 $zsize}
}]

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

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

# Demag
Specify Oxs_Demag {}

Specify Oxs_UZeeman [subst {
  multiplier [expr {0.001/$mu0}]
  Hrange {
     { $Ha $Ha $Ha     0   0   0  $Ha_steps }
     {   0   0   0   $Hb $Hb $Hb  $Hb_steps }
     { $Hb $Hb $Hb   $Hc $Hc $Hc  $Hc_steps }
  }
  user_output {
     name Bapplied
     source_field Field
     select_field {1 1 1}
     normalize 1
     exclude_0_Ms 1
     user_scaling [expr {1000.*$mu0}]
     units mT
  }
}]


# Evolver
Specify Oxs_CGEvolve {}

# Driver
Specify Oxs_MinDriver [subst {
   basename [list $basename]
   evolver Oxs_CGEvolve
   stopping_mxHxm $stop
   mesh :mesh
   Ms $Ms
   m0 [list $m0]
   user_output {
      name m_dot_u
      source_field Magnetization
      select_field {1 1 1}
      normalize 1
      exclude_0_Ms 1
      user_scaling [expr {1.0/$Ms}]
      units {}
   }
}]

Destination archive mmArchive
Schedule DataTable archive Stage 1

# Optionally, may want to save some magnetization states
# Schedule Oxs_MinDriver::Magnetization archive Stage 10
