# MIF 2.2

Parameter seed 1
Parameter thickness 6e-9
Parameter stop 1e-2

RandomSeed $seed

# Texturing angle, phideg, in degrees, from 0 to 90; 0 is all z.
Parameter phideg 10;

###                               ROGUE GRAIN:                              ###
### If RoguePt is an empty string, then no rogue grain is selected.  OTOH,  ###
### If RoguePt is set to a three item list consisting of x, y, and z coords ###
###   in the problem coordinate system (i.e., in meters), then the grain    ###
###   containing that point is individually set as specified below.         ###
Parameter RoguePt {263.5e-9 174.5e-9 3e-9}


#######################
###### CONSTANTS #####
#######################

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

###################
###### PROCS ######
###################

### This Proc makes ellipses and circles  ###
#############################################
proc Ellipse { Ms x y z} {
   set x [expr {2*$x-1.}]
   set y [expr {2*$y-1.}]
   if {$x*$x+$y*$y<=1.0} {
      return $Ms
   }
   return 0.0
}

#######################
###### MATERIALS ######
#######################

### for Co ###

set Ms 1.40e6
set Ku 530e3
set A  8.1e-12

##########################
###### ATLAS & MESH ######
##########################

set xsize 400e-9
set ysize 400e-9

set xycellsize 1.0e-9
set zcellsize  3.0e-9

### Atlas ####
##############

set grain_count 260
set grain_map polycrystal-map-mif.ppm

set colormap {}
for {set i 0} {$i<$grain_count} {incr i} {
   lappend colormap [format "#%06x" $i]
   lappend colormap $i
}

Specify Oxs_ImageAtlas:world [subst {
   xrange {0 $xsize}
   yrange {0 $ysize}
   zrange {0 $thickness}
   viewplane xy
   image $grain_map
   colormap {
      $colormap
   }
   matcherror 0.0
}]

### Mesh ###
############

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


#################################
###### UNIAXIAL ANISOTROPY ######
#################################

### This Proc generates TEXTURED random unit vector  ###
########################################################

set phirange [expr {1-cos($phideg*$pi/180.)}]
proc Texture {} {
   global pi phirange

   set theta [expr {(2.*rand()-1.)*$pi}]
   set costheta [expr {cos($theta)}]
   set sintheta [expr {sin($theta)}]

   set cosphi [expr {1.-$phirange*rand()}]
   set sinphi [expr {1.0-$cosphi*$cosphi}]
   if {$sinphi>0.0} { set sinphi [expr {sqrt($sinphi)}] }

   set x [expr {$sinphi*$costheta}]
   set y [expr {$sinphi*$sintheta}]
   set z [expr {$cosphi}]

   return [list $x $y $z]
}


### This sets a random unit vector for each grain region ###
############################################################

set axes {}
for {set i 0} {$i<$grain_count} {incr i} {
   lappend axes $i
   lappend axes [Texture]
}

### This sets the rogue grain ($Rogue < $grain_count) ###
#########################################################


if {[llength $RoguePt] == 3} {
   # The :Regions field maps region name (which is a number)
   # to the corresponding number.
   set regionmap {}
   for {set i 0} {$i<$grain_count} {incr i} {lappend regionmap $i $i }
   Specify Oxs_AtlasScalarField:Regions [subst {
      atlas :world
      values [list $regionmap]
   }]
   foreach {x y z} $RoguePt { break }
   set Rogue [EvalScalarField :Regions $x $y $z]
   set item_number [expr {2*$Rogue+1}]
   set axes [lreplace $axes $item_number $item_number {1 0 0}]
}

Specify Oxs_AtlasVectorField:axes [subst {
   atlas :world
   norm 1.0
   values [list $axes]
}]

Specify Oxs_UniaxialAnisotropy [subst {
   K1 $Ku
   axis :axes
}]



######################
###### EXCHANGE ######
######################

set A_list {}
for {set i 0} {$i<$grain_count} {incr i} {
   lappend A_list $i $i $A
}

Specify Oxs_Exchange6Ngbr [subst {
   default_A $A
   atlas world
   A   [list $A_list]
}]


#####################################
###### ZEEMAN (applied field ) ######
#####################################


set field 10000		;# Maximum field (in Oe)

Specify Oxs_UZeeman [subst {
   multiplier [expr {(1./($mu0*1e4))*$field}]
   Hrange  {
      { 0 0 0   0 0 1   10}
   }
}]


##############################
###### DRIVER & EVOLVER ######
##############################

### File Handling ###
#####################

SetOptions [subst {
   basename "polyuniaxial_phi_$phideg"
}]

### Evolver ###
###############

Specify Oxs_CGEvolve:evolve {}

### Driver ###
##############

Specify Oxs_MinDriver [subst {
   evolver evolve
   stopping_mxHxm $stop
   mesh :mesh
   Ms { Oxs_ScriptScalarField {
      atlas :world
      script_args {relpt}
      script {Ellipse $Ms}
   } }
   m0 { 0 0 -1 }
}]
