# MIF 2.2
# MIF Example File: demagtensor.mif
# Description: This MIF file can be used to dump the demagnetization
#  tensor values computed by the Oxs_Demag module.  To use, set the
#  parameters xcellsize, ycellsize, and zcellsize to the desired cell
#  geometry, set xcount, ycount and zcount to the number of cells in
#  each dimension that you want to compute the tensor for, and set the
#  parameter tensor_column to either 1, 2, or 3 to select the
#  demagnetization tensor column.  Then load the problem and examine the
#  Oxs_Demag::Field output, either in mmDisp or by writing to a file via
#  mmArchive.
#    In mmDisp, a Ctrl-Shift-MouseClick will display the field values
#  and position for the vector under the mouse.  For mmArchive file
#  output, the OOMMF command line utility avf2odt can be used to create
#  plain text tabular output, for example:
#
#    tclsh oommf.tcl avf2odt -average point -numfmt %15.8g -onefile - \
#         demagtensor-column1-Oxs_Demag-Field-00-0000000.ohf
#
#  writes a 6 column table to stdout; the first three columns are the
#  tensor offset, and the next three are Nxx, Nxy, and Nxz.  To get Nyx,
#  Nyy, and Nyz run Oxsii with parameter tensor_column set to 2 and
#  process the demagtensor-column2-Oxs_Demag-Field-00-0000000.ohf output
#  file through avf2odt as above.  The Nz* terms are computed similarly.
#  See the documentation for avf2odt in the OOMMF User's Guide (OUG) for
#  information on the various options to avf2odt.
#    This file is configured to provide the tensor coefficients in the
#  first octant (positive offsets in x, y, and z) only.  The
#  coefficients in the other octants can be found through symmetry
#  relations.

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

Parameter xcellsize 1
Parameter ycellsize 1
Parameter zcellsize 1

Parameter xcount 20
Parameter ycount 10
Parameter zcount  3

Parameter tensor_column 1  ;# Should be either 1, 2 or 3.
if {![catch {expr {int($tensor_column)}} check]} {
   set tensor_column $check
}
switch -exact $tensor_column {
   1 { set m0 {-1  0  0} }
   2 { set m0 { 0 -1  0} }
   3 { set m0 { 0  0 -1} }
   default {
      error "Invalid setting for Parameter tensor_column:\
           \"$tensor_column\".  Should be one of 1, 2, or 3."
   }
}
SetOptions [subst {
   basename "demagtensor-column${tensor_column}"
}]


Parameter arad 32  ;# Default setting for asymptotic_radius is 32

Parameter Ms 1
Parameter celloffset {0 0 0}  ;# Non-empty cell location, in cell units

Parameter simple_demag 0 ;# Change to 1 to use Oxs_SimpleDemag

Parameter periodic {}  ;# One of {}, x, y, or z

Specify Oxs_BoxAtlas:atlas [subst {
   xrange {[expr {-0.5*$xcellsize}] [expr {($xcount-0.5)*$xcellsize}]}
   yrange {[expr {-0.5*$ycellsize}] [expr {($ycount-0.5)*$ycellsize}]}
   zrange {[expr {-0.5*$zcellsize}] [expr {($zcount-0.5)*$zcellsize}]}
}]

if {[string match {} $periodic]} {
   Specify Oxs_RectangularMesh:mesh [subst {
      cellsize {$xcellsize $ycellsize $zcellsize}
      atlas :atlas
   }]
} else {
  if {$simple_demag} {
     error "Simple demag does not support periodic boundaries."
  }
  Specify Oxs_PeriodicRectangularMesh:mesh [subst {
     cellsize {$xcellsize $ycellsize $zcellsize}
     atlas :atlas
     periodic $periodic
  }]
}

if {$simple_demag} {
   Specify Oxs_SimpleDemag {}
} else {
   Specify Oxs_Demag [subst {
      asymptotic_radius $arad
   }]
}

Specify Oxs_CGEvolve:evolve {}

proc OneCell { x y z } {
   global Ms celloffset xcellsize ycellsize zcellsize
   foreach {xcelloff ycelloff zcelloff} $celloffset break
   if {abs($x - $xcelloff*$xcellsize) > 0.5*$xcellsize \
          || abs($y - $ycelloff*$ycellsize) > 0.5*$ycellsize \
          || abs($z - $zcelloff*$zcellsize) > 0.5*$zcellsize} {
      return 0.0
   }
   return $Ms
}

# Note: Include a stopping_mxHxm record in the following Specify block
# as a sop to the regression test suite.
Specify Oxs_MinDriver [subst {
 evolver :evolve
 mesh :mesh
 Ms { Oxs_ScriptScalarField {
    script OneCell
    script_args rawpt
    atlas :atlas
 }}
 m0 [list $m0]
 total_iteration_limit 1
 stopping_mxHxm 0.01  
}]

#Destination archive mmArchive
#Schedule DataTable archive Step 1
