# MIF 2.1
# MIF Example File: manyregions-multiatlas.mif
# Description: Tcl script used to algorithmically defined Oxs_MultiAtlas
#              with a large number of regions.  This example is
#              otherwise identical to manyregions-scriptatlas.mif.

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

RandomSeed 1

Parameter cellsize 5e-9
Parameter region_width   60e-9
Parameter region_period  70e-9
Parameter region_count   20

set xmax [expr {($region_count-1)*$region_period + $region_width}]
set ymax 60e-9
set zmax 10e-9

# Use a Tcl for-loop to construct a string representing list of regions.
# This string is imported into the Oxs_MultiAtlas Specify block to
# define the regions.
for {set i 0} {$i<$region_count} {incr i} {
    set atlas_string [subst {Oxs_BoxAtlas {
          xrange {[expr {$i*$region_period}] 
                  [expr {$i*$region_period+$region_width}]}
          yrange {0 $ymax}
          zrange {0 $zmax}
          name   {region_$i}
     }}]
     lappend regions_list "atlas" $atlas_string
}

Specify Oxs_MultiAtlas:atlas [subst {
  $regions_list
  xrange {0 $xmax}
  yrange {0 $ymax}
  zrange {0 $zmax}
}]

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

# Define an Oxs_AtlasVectorField object to define anisotropy directions.
# Again, a Tcl for-loop is used to construct a string that is imported
# into the Specify block.
for {set i 0} {$i<$region_count} {incr i} {
   set theta [expr {$pi*$i/$region_count}]
   set value_string [list 0 [expr {cos($theta)}] [expr {sin($theta)}]]
   lappend anisaxis_value_list "region_$i" $value_string
}
Specify Oxs_AtlasVectorField:anisotropy_directions [subst {
   atlas :atlas
   norm 1.0
   default_value {1 0 0}  comment {Dummy value for non-magnetic matrix}
   values { $anisaxis_value_list }
}]

Specify Oxs_UniaxialAnisotropy {
  K1  1.5e3
  axis :anisotropy_directions
}

# Exchange is automatically 0 at locations where Ms=0.
# Oxs_UniformExchange does not allow more general variation of A.  If
# more control is needed, use Oxs_Exchange6Ngbr.
Specify Oxs_UniformExchange {
   A  13e-12  comment {A here is a single scalar, not a scalar field}
}

Specify Oxs_UZeeman [subst {
  multiplier [expr {0.001/$mu0}]
  Hrange {
     {   0   0   0   100   1   0   2 }
     { 100   1   0  -100   0   0   2 }
     {   0   0   0     0 100   0   4 }
     {  10  10  10    50  50  50   1 }
     {   0   0   0     0   0   0   0 }
  }
}]

Specify Oxs_Demag {}

Specify Oxs_CGEvolve:evolve {}

# Define an Oxs_AtlasVectorField object to define initial magnetization.
for {set i 0} {$i<$region_count} {incr i} {
   set value_string [list 0 [expr {1 - 2*($i%2)}] 0]
   lappend m0_value_list "region_$i" $value_string
}
Specify Oxs_AtlasVectorField:m0 [subst {
   atlas :atlas
   norm 1.0
   default_value {1 0 0}
   values { $m0_value_list }
}]


Specify Oxs_MinDriver [subst {
 evolver :evolve
 stopping_mxHxm 0.1
 mesh :mesh
 Ms { Oxs_AtlasScalarField {
    atlas :atlas
    default_value 8e5
    values {
       universe 0.0
    }
 }}
 m0 :m0
}]
