In addition to the standard Tcl commands (modulo the safe Tcl restrictions outlined above), a number of additional commands are available in MIF 2.1 files: Specify, ClearSpec, DateSort, Destination, GetStateData, Ignore, OOMMFRootDir, Parameter, Random, RandomSeed, Report, ReadFile, RGlob, and Schedule.
An Oxs simulation is built as a collection of Oxs_Ext (Oxs Extension) objects. In general, Oxs_Ext objects are specified and initialized in the input MIF 2.1 file using the Specify command, making Specify blocks the primary component of the problem definition. The Specify command takes two arguments: the name of the Oxs_Ext object to create, and an initialization string that is passed to the Oxs_Ext object during its construction. The objects are created in the order in which they appear in the MIF file. Order is important in some cases; for example, if one Oxs_Ext object refers to another in its initialization string, then the referred to object must precede the referrer in the MIF file.
Here is a simple Specify block:
Specify Oxs_EulerEvolve:foo { alpha 0.5 start_dm 0.01 }
The name of the new Oxs_Ext object is “Oxs_EulerEvolve:foo.” The first part of this name, up to the colon, is the the C++ class name of the object. This must be a child of the Oxs_Ext class. Here, Oxs_EulerEvolve is a class that integrates the Landau-Lifshitz ODE using a simple forward Euler method. The second part of the name, i.e., the part following the colon, is the instance name for this particular instance of the object. In general, it is possible to have multiple instances of an Oxs_Ext child class in a simulation, but each instance must have a unique name. These names are used for identification by output routines, and to allow one Specify block to refer to another Specify block appearing earlier in the MIF file. If the second part of the name is not given, then as a default the empty string is appended. For example, if instead of “Oxs_EulerEvolve:foo” above the name was specified as just “Oxs_EulerEvolve”, then the effective full name of the created object would be “Oxs_EulerEvolve:”.
The second argument to the Specify command, here everything between the curly braces, is a string that is interpreted by the new Oxs_Ext (child) object in its constructor. The format of this string is up to the designer of the child class, but there are a number of conventions that designers are encouraged to follow. These conventions are described in Specify Conventions below.
This command is used to disable one or all preceding Specify commands. In particular, one could use ClearSpec to nullify a Specify block from a base MIF file that was imported using the ReadFile command. Sample usage is
ClearSpec Oxs_EulerEvolve:foo
where the parameter is the full name (here Oxs_EulerEvolve:foo) of the Specify block to remove. If no parameter is given, then all preceding Specify blocks are removed.
Given a list of filenames, returns the list sorted by modification time, with oldest first. The files must all exist. Sample usage is
set last_omf [lindex [DateSort [RGlob *omf]] end]
Here last_omf will be set to the *.omf file in the current directory with the most recent modification time.
The format for the Destination command is
Destination <desttag> <appname> [new]
This command associates a symbolic desttag with an application. The tags are used by the Schedule command (see below) to refer to specific application instances. The appname may either be an OOMMF application name, e.g., mmDisp, or else a specific application instance in the form application:nickname, such as mmDisp:Spock. In the first case, the tag is associated with the running instance of the requested application (here mmDisp) with the lowest OOMMF ID (OID) that has not yet been associated with another tag. If no running application can be found that meets these criteria, then a new instance of the application is launched.
If the appname refers to a specific application instance, then the tag is associated with the running instance of the application (say mmDisp) that has been assigned the specified nickname. Name matching is case insensitive. If there is no running copy of the application meeting this condition, then a new instance of the application is launched and it is assigned the specified nickname. The OOMMF account service directory guarantees that there is never more than one instance of an application with a given nickname. However, as with the object name in the Specify command, instances of two different applications, e.g., mmDisp and mmGraph, are allowed to share nicknames, because their full instance names, say mmDisp:Spock and mmGraph:Spock, are unique.
The Destination commands are processed in the order in which they appear in the the MIF file. No desttag may appear in more than one Destination command, and no two destination tags may refer to the same application instance. To insure the latter, the user is advised to place all Destination commands referring to specific instances (e.g., mmDisp:Spock) before any Destination commands using generic application references (e.g., mmDisp). Otherwise a generic reference might be associated to a running application holding a nickname that is referenced by a later Destination command.
The tag association by the Destination command is only known to the solver reading the MIF file. In contrast, assigned instance nicknames are recognized across applications. In particular, multiple solvers may reference the same running application by nickname. For example, several sequential solver runs could send stage output to the same mmGraph widget, to build up overlapping hysteresis loops.
The last parameter to the Destination command is the optional new keyword. If present, then a fresh copy of the requested application is always launched for association with the given tag. The new option can be safely used with any generic application reference, but caution must be taken when using this option with specific instance references, because an error is raised if the requested nickname is already in use.
The GetStateData command retrieves data attached to a specific magnetization state:
GetStateData [-glob|-exact|-regexp] [-pairs] [--] <state_id> \ [pattern ...]
The data associated with a state are stored as key-value pairs. If no patterns are specified then GetStateData returns the list of keys available for the given state. If one or more patterns are specified, then all values with keys matching some pattern are collected. If the -pairs option is specified then the return is an even length list of keys and values interleaved. If -pairs is not specified then the return is a list of just the values. The values are returned in key-match order. Key matching style is controlled by the first slate of options, with default being glob. Two hyphens may be used to denote the end of options.
The state_id is a positive integer identifying the state. This is generally obtained via a script_args option in the Specify block of a conforming Oxs_Ext object. For example,
proc SpinMag { stage_time state_id } { lassign [GetStateData $state_id *:Mx *:My *:Mz] Mx My Mz ... } Specify Oxs_ScriptUZeeman { script SpinMag script_args {stage_time base_state_id} }
Typically two states may be accessed this way: the step base state and a candidate (test) state. The former, accessed as base_state_id, corresponds to the last valid, accepted magnetization state. The latter, accessed as current_state_id, is the latest working state from the evolver object. In some cases these two states may coincide.
The keys associated with a state vary with the details of the simulation. The following keys are always available:
state_id previous_state_id iteration_count stage_number stage_iteration_count stage_start_time stage_elapsed_time total_elapsed_time last_timestep step_done stage_done run_done max_absMs
Times are in seconds, the step/stage/run_done values are one of 1 (done), 0 (not done) or -1 (not yet determined), and max_absMs is in A/m.
Additional key-value pairs may be attached to a state by Oxs_Ext objects. For example, Oxs_RungeKuttaEvolve adds the average magnetization -component under the key name Oxs_RungeKuttaEvolve:instance_name:Mx. (Here instance_name is the instance name of the object; this is typically an empty string or something like “evolver”.) See the documentation for the various Oxs_Ext objects for details.
Moreover, the keys available for a state may depend on the simulation status or processing step. In particular, the current state indexed by current_state_id typically only has the default keys from the table above available. For this reason, and additionally because the current_state_id is only a test state that may be rejected, user scripts should generally avoid using data tied to the current state in favor of data collected from the base state. Likewise, the available keys may be different for a state (even a base state) marking the start of a new stage as compared to states arising inside a stage. In case of problems, a Report command inside a script proc can be used to dump state information to the Oxsii console, for example,
proc SpinMag { stage_time state_id } { Report "State $state_id, Keys: [GetStateData $base_state_id]" lassign [GetStateData $state_id *:Mx *:My *:Mz] Mx My Mz ... }
or
proc SpinMag { stage_time state_id } { set report {} foreach {key value} [GetStateData $state_id *] { append report [format "%42s : $value\n" $key] } Report "--- State data ---\n$report" lassign [GetStateData $state_id *:Mx *:My *:Mz] Mx My Mz ... }
For example use of GetStateData, see the sample files spinmag.mif and spinmag2.mif in the directory oommf/app/oxs/examples/.
The Ignore command takes an arbitrary number of arguments, which are thrown away without being interpreted. The primary use of Ignore is to temporarily “comment out” (i.e., disable) Specify blocks.
This command takes no arguments, and returns the full directory path of the OOMMF root directory. This is useful in conjunction with the ReadFile command for locating files within the OOMMF hierarchy, and can also be used to place output files. File paths must be created directly since the Tcl file command is not accessible inside safe interpreters. For example
set outfile [OOMMFRootDir]/data/myoutput
In this context one should always use Tcl path conventions. In particular, use forward slashes, “/”, to separate directories.
The Oxs interfaces (Oxsii and Boxsi) allow specified variables in the MIF file to be set from the command line via the -parameters option. This functionality is enabled inside the MIF file via the Parameter command:
Parameter varname optional_default_value
Here varname is the name of a variable that may be set from the command line. If it is not set on the command line then the variable is set to the optional default value, if any, or otherwise an error is raised. An error is also raised if a variable set on the command line does not have a corresponding Parameter command in the MIF file. See also the notes on variable substitution below.
Returns a pseudo-random number in the interval , using a C-library random number generator. This random number generator is specified by the OMF_RANDOM macro in the ocport.h file found in the system-specific subdirectory of oommf/pkg/oc/. The standard Tcl expr rand() command is also available.
Initializes both the Tcl and the C-library random number generators. If no parameter is given, then a seed is drawn from the system clock. Otherwise, one integer parameter may be specified to be used as the seed.
Intended primarily as a MIF debugging aid, Report takes one string argument that is printed to the solver interface console and the Oxs log file. It is essentially a replacement for the standard Tcl puts command, which is not available in safe interpreters.
The Tcl read command is absent from safe interpreters. The ReadFile command is introduced as a replacement available in “custom” and “unsafe” interpreters. ReadFile takes two arguments, the file to be read and an optional translation specification. The file may either be specified with an absolute path, i.e., one including all its directory components, or with a relative path interpreted with respect to the directory containing the MIF file. The OOMMFRootDir command can be used to advantage to locate files in other parts of the OOMMF directory tree.
The translation specification should be one of binary, auto (the default), image or floatimage. The first two translation modes provide the functionality of the -translation option of the Tcl fconfigure command. Refer to the Tcl documentation for details. Specifying image causes the input file to be read as an image file. The file will be read directly if it in the PPM P3 (text), PPM P6 (binary), or uncompressed BMP formats; otherwise it is filtered through the OOMMF any2ppm program. (Note that any2ppm requires Tk, and Tk requires a display.) The input file is converted into a string that mimics a PPM P3 text file, minus the leading “P3”. In particular, after conversion the first 3 whitespace separated values are image width, height and maxvalue, followed by an array of 3 width height values, where each triplet corresponds to the red, green and blue components of an image pixel, sequenced in normal English reading order. Each component is in the range . This output contains no comments, and may be treated directly as a Tcl list. The floatimage option is very similar to the image option, except that the third value (i.e., maxvalue) in the resulting string is always “1”, and the succeeding red, green and blue values are floating point values in the range .
In all cases, the return value from the ReadFile command is a string corresponding to the contents of the (possibly translated) file. For example,
eval [ReadFile extra_mif_commands.tcl]
can be used to embed a separate Tcl file into a MIF 2.1 file.
Here’s a more complicated example that uses a color image file to create a vector field:
set colorimage [ReadFile mirror.ppm floatimage] set imagewidth [lindex $colorimage 0] set imageheight [lindex $colorimage 1] set imagedepth [lindex $colorimage 2] ;# Depth value should be 1 if {$imagedepth != 1} { Report "ReadFile returned unexpected list value." } proc ColorField { x y z } { global colorimage imagewidth imageheight set i [expr {int(floor(double($x)*$imagewidth))}] if {$i>=$imagewidth} {set i [expr {$imagewidth-1}]} set j [expr {int(floor(double(1-$y)*$imageheight))}] if {$j>=$imageheight} {set j [expr {$imageheight-1}]} set index [expr {3*($j*$imagewidth+$i)+3}] ;# +3 is to skip header set vx [expr {2*[lindex $colorimage $index]-1}] ; incr index ;# Red set vy [expr {2*[lindex $colorimage $index]-1}] ; incr index ;# Green set vz [expr {2*[lindex $colorimage $index]-1}] ; incr index ;# Blue return [list $vx $vy $vz] } Specify Oxs_ScriptVectorField:sample { atlas :atlas norm 1.0 script ColorField }
If the input image is large, then it is best to work with the image list (i.e., the variable colorimage in the preceding example) directly, as illustrated above. The image list as returned by ReadFile is in a packed format; if you make modifications to the list values then the memory footprint of the list can grow substantially.
The ReadFile command is not available if the MIFinterp safety option is set to safe in the options.tcl customization file.
This command is modeled on the Tcl glob command (q.v.), but is restricted to the current working directory, that is, the directory holding the MIF file. The syntax is
RGlob [-types typelist] [--] <pattern> [...]
The optional typelist restricts the match to files meeting the
typelist criteria. The optional --
switch marks the end of
options. The one or more pattern’s should be glob-style
patterns (strings containing asterisks and question marks) intended to
match filenames in the current working directory. See the Tcl glob documentation for details on the -types option and
glob pattern details.
One use of this command is to identify files created by earlier runs of Oxs. For example, suppose we wanted to use the mmArchive magnetization output from the third stage of a previous MIF file with basename “sample”. Output files are tagged by stage number (here “2” since stages are counted from 0) and iteration. The iteration is generally not known a priori, but assuming the output files are in the same directory as the current MIF file, we could use a command like
set file [RGlob sample-Oxs_MinDriver-Magnetization-02-???????.omf]
to determine the name of the magnetization file. If more than one magnetization state was saved for that stage, then the variable file will hold a list of filenames. In this case the Tcl lsort command can be used to select the one with the highest iteration number. The file variable can be used in conjunction with the Oxs_FileVectorField class to import the magnetization into the new simulation, for example to set the initial magnetization configuration.
The RGlob command is not available if the MIFinterp safety option is set to safe in the options.tcl customization file. If MIFinterp safety is set to unsafe, then the standard (and more capable) Tcl glob command will be available.
The Schedule command is used to setup outputs from the MIF file. This functionality is critical for solvers running in batch mode, but is also useful for setting up default connections in interactive mode.
The syntax for the Schedule command is
Schedule <outname> <desttag> <event> <frequency>
The Schedule command mirrors the interactive output scheduling provided by the Oxsii and Boxsi graphical interfaces (Ch. 7). The first parameter to the Schedule command is the name of the output being scheduled. These names are the same as those appearing in the “Outputs” list in the Oxs graphical interfaces, for example “DataTable” or “Oxs_CubicAnisotropy:Nickel:Field.” The name must be presented to the Schedule command as a single argument; if the name includes one or more spaces then use double quotes to protect the spaces. Aside from the DataTable output which is always present, the outname’s are MIF file dependent.
The second parameter to the Schedule command is a destination tag. This is a tag associated to a running application by a previous Destination command (see above). The symbolic destination tag replaces the application:OID nomenclature used in the graphical interface, because in general it is not possible to know the OOMMF ID for application instances at the time the MIF file is composed. In fact, some of the applications may be launched by Destination commands, and so don’t even have OID’s at the time the Destination command is processed.
The event parameter should be one of the keywords Step, Stage, or Done. For Step and Stage events the frequency parameter should be a non-negative integer, representing with what frequency of the specified event should output be dispatched. For example, if Step 5 is given, then on every fifth step of the solver (iterations 0, 5, 10, …) output of the indicated type will be sent to the selected destination. Set frequency to 1 to send output each time the event occurs. A value of 0 for frequency results in output on only the very first event of that type; in particular, Step 0 will output the simulation initial state, but will not fire on any subsequent Step events. The Done event occurs at the successful completion of a simulation; as such, there is at most one “Done” event per simulation. Accordingly, the frequency parameter for Done events is optional; if present it should be the value 1.
There are examples of scheduling with the Destination and Schedule commands in the sample MIF 2.1 file (Sec. 17.3.5, pages 17.3.5–17.2). There, three destinations are tagged. The first refers to a possibly already running instance of mmGraph, having nickname Hysteresis. The associated Schedule command sends DataTable output to this application at the end of each Stage, so hysteresis graphs can be produced. The second destination tag references a different copy of mmGraph that will be used for monitoring the run. To make sure that this output is rendered onto a blank slate, the new keyword is used to launch a fresh copy of mmGraph. The Schedule command for the monitor destination delivers output to the monitoring mmGraph every 5 iterations of the solver. The last Destination command tags an arbitrary mmArchive application, which is used for file storage of DataTable results at the end of each stage, and snapshots of the magnetization and total field at the end of every third stage. Note that double quotes enclose the “Oxs_EulerEvolve::Total field” output name. Without the quotes, the Schedule command would see five arguments, “Oxs_EulerEvolve::Total”, “field”, “archive”, “Stage”, and “3”.