精感石没羽,岂云惮险艰。——李白《豫章行》
# 前言
这是oommf软件教程《OOMMF User’s Guide》的中文翻译文章,由于本人水平有限,有些翻译可能有错误,望见谅。
目录
######
本文链接:https://blog.csdn.net/qq_43572058/article/details/123241806
CSDN@搬砖工人_0803号
######
17 微磁问题文件格式(MIF)
微磁模拟是通过为OOMMF求解器指定微磁输入格式(Micromagnetic Input Format,MIF)的文件来运行的。MIF有四种不同版本的格式,最老的1.1版本的格式被mmSolve 2D求解器(mmSolve2D和batchsolve)和mmProbEd问题编辑器使用。强大的MIF 2.1和MIF 2.2被Oxs 3D求解器使用。MIF 1.2在1.1格式的基础上进行了小的修改,可被功能受限的Oxs求解器使用。在所有版本中,数值均以国际单位制为单位。命令行程序mifconvert可以将MIF 1.1转换为MIF 2.1格式。无论什么版本的格式,都建议把MIF文件的扩展名设置为.mif。
17.1 MIF 1.1。
MIF 1.1格式是提供给mmSolve 2D求解器使用的较旧的微磁问题格式,它与Oxs 3D求解器使用的MIF 2.1格式不兼容。然而,mifconvert程序可以用作转换工具,当向Oxs求解器输入MIF 1.X文件时,它会自动调用mifconvert程序。
# MIF 1.1
#
# Example from the OOMMF User's Guide.
#
# All units are SI.
#
################# MATERIAL PARAMETERS ######################
Ms: 800e3 # Saturation magnetization in A/m.
A: 13e-12 # Exchange stiffness in J/m.
K1: 0.5e3 # Anisotropy constant in J/m^3.
Anisotropy Type: uniaxial # One of <uniaxial|cubic>.
Anisotropy Dir1: 1 0 0 # Directional cosines wrt to
# coordinate axes
################# DEMAG SPECIFICATION ######################
Demag Type: ConstMag # One of <ConstMag|3dSlab|2dSlab
# |3dCharge|FastPipe|None>.
#################### PART GEOMETRY #########################
Part Width: 0.25e-6 # Nominal part width in m
Part Height: 1.0e-6 # Nominal part height in m
Part Thickness: 1e-9 # Part thickness in m.
Cell Size: 7.8125e-9 # Cell size in m.
#Part Shape: # One of <Rectangle|Ellipse|Oval|Mask>.
# Optional.
################ INITIAL MAGNETIZATION #####################
Init Mag: Uniform 90 45 # Initial magnetization routine
# and parameters
################ EXPERIMENT PARAMETERS #####################
# Field Range: Start_field Stop_field Steps
Field Range: -.05 -.01 0. .05 .01 0. 100
Field Range: .05 .01 0. -.05 -.01 0. 100
Field Type: Multi 4 \
7 Ribbon 1 0 1.0e-6 0.25e-6 1.0e-6 1e-9 \
7 Ribbon 1 0 0 0.25e-6 0 1e-9 \
9 Tie 100 0 0 0.12e-6 0.5e-6 0.13e-6 0.5e-6 8e-9 \
1 Uniform
# The above positions ribbons of positive charge along the
# upper and lower edges with strength Ms, applies a large
# (100 Ms) field to the center cells, and also applies a
# uniform field across the sample stepped from
# (-.05,-.01,0.) to (.05,.01,0.) (Tesla), and back, in
# approximately 0.001 T steps.
Default Control Point Spec: -torque 1e-6
# Assume equilibrium has been reached, and step the applied
# field, when the reduced torque |mxh| drops below 1e-6.
################ OUTPUT SPECIFICATIONS #####################
Base Output Filename: samplerun
Magnetization Output Format: binary 8 # Save magnetization
# states in binary format with full (8-byte) precision.
#################### MISCELLANEOUS #########################
Randomizer Seed: 1 # Random number generator seed.
User Comment: Example MIF 1.1 file, with lots of comments.
Figure 17.1: Example MIF 1.1file.
MIF 1.1文件的示例如图17.1所示。MIF文件的第一行必须为“# MIF x.y”,其中x.y代表MIF版本。(早期的MIF 1.0未被包含在任何OOMMF发布版本中。)
在格式标识符行之后,任何以反斜杠“\”(译者注:通常称之为“续行符”)结尾的行在处理之前会连接下一行,从而合并为一行。以“#”字符开头的行是注释行,将被OOMMF忽略。空行也会被忽略。
其他行是由一个Record Identifier(记录标识符)和一个参数列表组成,记录标识符与参数列表之间用一个或多个“:”或“=”分隔,并且会忽略记录标识符中的空格和大小写。
参数列表必须是合适的Tcl列表,这些参数按照普通的Tcl规则进行解析(列表分解为单独的元素),列表中的参数之间用空格分隔,但用双引号和花括号分组的参数除外。花括号和引号的开始部分必须使用空格与前面文本分开的。分组字符在解析过程中会被删除。在分组之外的任何“#”字符都被解释为注释的开始字符,“#”和该行上的所有后续字符都被解释为注释。
在MIF 1.1文件中,记录标识符的先后顺序并不重要,但特殊情况如下所说。如果两行或多行都包含相同的记录标识符,则优先使用最后一行的记录标识符,但Field Range除外,因为按照它的格式本身就可以定义多项Field Range。通常所有的记录标识符都是必选的,除了那些在MIF1.1中明确说明为可选的记录标识符。若mmProbEd不支持其中的一些记录标识符,则用户可以使用纯文本编辑器修改MIF 1.1文件,并使用FileSource将其传递给mmSolve2D。
为了方便起见,记录标识符被分成了几个组,这些组对应于mmProbEd界面中的按钮。如下所述。
17.1.1 材料参数。
•# Material Name: 在mmProbEd中可以简单的编辑该条目,该条目在MIF 1.1文件中是一个注释行,会被求解器忽略。它表示把材料的名称(如Iron)与下面4项的值联系起来。
•Ms:饱和磁化强度,单位为A/m。
•A:交换系数,单位为J/m.
•K1:晶体各向异性常数,单位为 。如果K1>0,则各向异性轴(或多个轴)为易轴;如果K1<0,则各向异性轴为难轴。
•Anisotropy Type:晶体各向异性类型;值为<uniaxial|cubic>中的一个。
•Anisotropy Dir1:第一个晶体各向异性轴的方向余弦(相对于坐标轴),值为3个数字。该条目是可选的;默认值为1 0 0(即x轴)。
•Anisotropy Dir2:第二个晶体各向异性轴的方向余弦(相对于坐标轴),值为3个数字。该条目是可选的;默认值为0 1 0(即y轴)。
对于uniaxial单轴类型的材料,只需指定Anisotropy Dir1即可。对于cubic立方各向异性类型的材料,还必须指定Anisotropy Dir2,它的第三个轴的方向是前两个轴的叉积。根据需要,会自动归一化各向异性方向,例如有效的输入是1 1 1(将被自动转化为 .5774 .5774 .5774)。对于cubic类型的材料,Dir2将被调整为垂直于Dir1(通过减去平行于Dir1的分量)。
•Anisotropy Init:根据空间位置设置各向异性轴方向的方法,该条目用于进一步控制Anisotropy Dir1/2,此条目的值为<Constant|UniformXY|UniformS2>中的一个。Constant表示直接使用Anisotropy Dir1和Anisotropy Dir2指定的值,不进行变换。UniformXY表示忽略Anisotropy Dir1和Anisotropy Dir2指定的值,并在xy平面上均匀地随机改变各向异性方向。UniformS2是类似,但它是在单位球体()上均匀地随机改变各向异性方向。此条目是可选的,默认值为Constant。
•Edge K1:此处的各向异性常数类似于上述晶体各向异性常数K1,但该条目仅适用于样品零件的边缘表面。Edge K1是单轴各向异性,它沿着边界表面的法线方向,单位为 。Edge K1若为正值则表示零件的边缘表面的法线是易轴,负值表示零件的边缘表面是易平面。Edge K1的默认值为0,表示禁用该条目。
•Do Precess:如果为1,表示启用Landau-Lifshitz ODE中的进动项。如果为0,则表示仅做纯阻尼运动。(该条目是可选的;默认值为1。)
•Gyratio:朗道-利夫希茨旋磁比,单位为m/(A.s)。该条目是可选的,默认值为 。参考Damp Coef条目中关于Landau-Lifshitz ODE的讨论。
•Damp Coef:OOMMF中的ODE求解器集成了Landau-Lifshitz方程,即
是朗道-利夫希兹旋磁比(m/(A·s)),α是阻尼系数(无量纲)。
(与方程(7.2)相比)阻尼系数α由MIF 1.1文件中的“Damp Coef”条目指定。如果未指定Damp Coef的值,则使用默认值0.5,以便求解器在合理的迭代次数内快速收敛。物理材料的阻尼系数通常在0.004到0.15之间。2D求解引擎mmSolve要求阻尼系数非零。
17.1.2 退磁描述。
•Demag Type:指定用于计算自静磁(退磁)场的算法和退磁内核。取值必须是下面中的一个:
– ConstMag:使用参考文献[23]中的公式,在假设每个单元格中的磁化强度是恒定的情况下,计算每个单元格中的平均磁场。(其他demag类型是计算每个单元格中心的场。)
– 3dSlab:使用恒定(体积)磁荷的偏移块计算平面内磁场分量。查阅参考文献[3]了解详细信息。平行于z轴的磁场分量是使用样品上下表面上恒定(表面)磁荷的平方来计算的。
– 3dCharge:使用每个单元格上恒定(表面)磁荷的矩形计算平面内磁场分量。这相当于假设每个单元格中都有恒定的磁化强度。磁场的z分量的计算方法和3dSlab相同。
– FastPipe:适用于零件在z方向上具有无限范围的算法。这是3dSlab算法的2D版本。
– None:没有退磁场。这是最快但最不准确的方法。
除了FastPipe和None之外,其他算法都要设置Part Thickness样品零件厚度(参见零件几何形状)。OOMMF使用了快速傅立叶变换(FFT)技术来加速计算。
17.1.3 零件几何形状。
•Part Width:以米为单位的零件宽度(x方向的尺寸),值应该是Cell Size单元格大小的整数倍。
•Part Height:以米为单位的零件高度(y方向的尺寸),值应该是Cell Size单元格大小的整数倍。
•Part Thickness:以米为单位的零件厚度(z方向的尺寸),除了FastPipe和None外,其他demag类型都需要设置该条目。
•Cell Size:基本计算单元的面内(xy平面)边长尺寸。基本计算单元的形状是一方块,其横截面是方形,厚度由Part Thickness给出。注意:Part Width和Part Height应该是Cell Size的整数倍。Part Width和Part Height会自动轻微调整(最多0.01%),以满足此条件(对微磁问题的影响很小),但如果调整幅度太大,则会被视为无效的微磁问题,求解器将发出错误信号。
•Part Shape:该条目是可选的,表示零件在xy平面内的形状,取值必须是以下之一:
– Rectangle(默认值。)
即Part Width和Part Height指定的矩形区域。
– Ellipse
零件形状(或零件的磁活性成分)在xy平面内是一个椭圆,该椭圆内接于Part Width和Part Height指定的矩形区域内。
– Ellipsoid
类似于Ellipse,但它的零件厚度可以不同,用于模拟一个椭球,椭球的轴长由Part Width、Part Height和Part Thickness决定。
– Oval r
表示的形状为一个圆角矩形,矩形的每个角由半径为r的四分之一圆代替,其中0≤r≤1是相对矩形的半宽长的相对长度(即r=1表示矩形宽度的一半长度)。
– Pyramid overhang
表示的形状为四棱锥的横截面,斜高(overhang)以米为单位。
– Mask filename
表示由位图文件确定零件的形状和厚度,filename是位图文件的名称。模拟的总体大小仍然由Part Width和Part Height决定,在空间上缩放位图来适应指定的总体大小。注意,如果零件的纵横比与位图的纵横比不同,则不会按照方形比例来缩放。
求解器程序必须有访问filename文件的权限。目前,位图文件的格式必须是PPM(portable pixmap)、GIF或BMP。(除了PPM P3(文本)格式之外的其他格式可以通过传给any2ppm程序来转换。)
位图的白色区域被解释为没有磁性的(或零件厚度为0),并假设其他所有区域均是由“材料参数”部分中指定的材料组成的。零件厚度是由位图中像素的相对暗度决定的。黑色像素表示整个标称厚度(由上面的“Part Thickness”参数指定),灰色像素被线性映射到0和标称厚度之间。通常,把位图像素值转换为相对厚度(相对于标称厚度)的公式为 1-(R+G+B)/(3M),其中R、G和B分别是红色、绿色和蓝色分量的大小,M是允许的最大颜色分量的大小。例如,黑色为R=G=B=0,则表示的相对厚度为1,白色为R=G=B=M,表示的相对厚度为0。
代码不会计算零件在3D空间的实际厚度,而是使用参考文献[24]中讨论的近似值来计算模拟。
17.1.4 初始磁化。
•Init Mag:如何设置模拟中初始磁化方向(它是关于位置的函数)的例程(译者注:即OOMMF已经实现了的设置初始磁化的方法),以及例程的参数(如果有的话)。该条目是可选的,默认值为Random。这里有很多个例程都是可用的,若要添加新的例程也很容易,查阅oommf/app/mmsolve/maginit.cc文件了解详细信息。以下是一些常用的例程:
– Random
表示初始磁化方向为单位球体上的随机磁化方向。这有点像淬火的热退磁状态。
– Uniform θ φ
表示在θ和φ两个参数指示的方向上的均匀磁化,其中θ是与z轴的角度(以度为单位),φ是投影到xy平面上后与x轴的角度(以度为单位)。
– Vortex
表示与样品中心匹配的理想磁涡旋。
– avfFile filename
filename是用于设置初始磁化的OVF/VIO(即“任意”的矢量场)文件。输入文件中的网格将根据需要进行缩放,以适应当前模拟中的网格。求解器程序必须有访问filename文件的权限。
17.1.5 实验参数。
下面的记录标识符用于指定外加磁场:
•Field Range:表示以线性方式步进的外加磁场范围。参数列表由7个数字,和可选的控制点(停止标准)参数构成的。7个数字分别代表初始磁场的Bx By Bz分量(单位为特斯拉),最终磁场的Bx By Bz分量(单位为特斯拉),以及初始和最终磁场之间的整数步进(即间隔)数目。根据需要使用多个Field Range记录标识符,外加磁场会按照这些记录标识符的出现顺序来依次步进。如果步进数目为0,则忽略最终磁场,磁场范围仅包括初始磁场。如果步长数目大于0,则当且仅当上一个磁场范围的最终磁场和当前磁场范围的初始磁场相同时,会跳过该初始磁场。
可选的控制点参数用于确定外加磁场步进的条件,或者更准确地说,结束使用当前外加磁场来进行演化。控制点参数通过“–type value”形式的“参数对”来设置,有三种可识别的控制点类型:–torque,–time,和–iteration。如果设置为一个 –torque参数对,则当模拟中所有自旋的||m x h||(即 )小于指定的转矩值(value,无量纲)时,使用当前外加磁场来进行的演化就会结束。如果设置为一个 –time参数对,则当使用当前外加磁场的模拟时间达到指定的时间值(以秒为单位)时,使用当前外加磁场来进行的演化就会结束。类似地,当使用当前外加磁场的迭代次数达到 –iteration的值时,也会导致外加磁场的步进。如果给定了多个控制点参数,则当满足其中任何一个条件时,外加磁场都会向前步进。如果没有给出控制点参数,则使用默认的Default Control Point Spec。
例如,考虑以下Field Range行:
Field Range: 0 0 0 .05 0 0 5 -torque 1e-5 -time 1e-9
表示指定外加磁场的6个值:(0,0,0), (0.01,0,0), (0.02,0,0), . . . , (0.05,0,0)(单位为特斯拉),在使用当前外加磁场的模拟中,当所有自旋的||m x h||小于1e-5时,或者经过1纳秒的模拟时间时,外加磁场就会在这6个值内依次步进。(如果未使用 -torque,则外加磁场将在模拟时间的1、2、3、4和5 ns时步进。)
Field Range条目是可选的,默认值为0 0 0 0 0 0 0。
•Default Control Point Spec:–type value形式的控制点列表,表示在Field Range中没有设置控制点时使用的默认步进条件。它是Converge |mxh| Value条目的推广和替代。该条目是可选的,默认为“-torque 1e-5”。
•Field Type:外加磁场的例程和参数(如果有的话)。该条目是可选的,默认为Uniform类型,Uniform类型最多作用于一个外加磁场,但Multi类型可作用于一系列场。标称外加磁场(NAF)通过上述的Field Ranges来步进,外加磁场的例程可以视情况使用或忽略它。
Field Type可用的例程如下:
– Uniform
外加磁场与NAF的值相同。
– Ribbon relcharge x0 y0 x1 y1 height
领带状磁荷“Ribbon”,垂直于xy平面,relcharge它是相对于Ms的磁荷强度,(x0,y0),(x1,y1)是条带的端点(以米为单位)。领带状在计算平面上下各延伸1/2的高度。这个例程忽略了NAF。
– Tie rfx rfy rfz x0 y0 x1 y1 ribwidth
点(x0,y0)和(x1,y1)定义(以米为单位)位于xy平面上的宽度为ribwidth的矩形领带中脊的端点。位于该矩形内的单元格的外加磁场为(rfx、rfy、rfz),单位为相对于Ms的相对单位(如果磁场较大,则矩形中的磁化强度将“绑定”到该磁场的方向)。该例程忽略了NAF。
– OneFile filename multiplier
从文件中读取B场(单位为特斯拉),并把文件中的每个B值都乘以“multiplier”。这将很容易实现翻转磁场的方向(multiplier为-1)或将H场转换为B场(multiplier为1.256637e-6)。输入文件可以是mmDisp可识别的任何矢量场文件。从文件中读取的尺寸将根据需要进行缩放,以适应模拟网格,并根据需要进行零阶插值。这个例程忽略了NAF。
– FileSeq filename procname multiplier
这是OneFile例程的升级版,该例程从一系列文件中读取磁场。“filename”是一个文件名,它包含问题初始化期间要解析的Tcl代码,“procname”是一个Tcl函数的名称,该函数定义在filename文件中,该函数将标称B场的分量(以特斯拉为单位)和磁场的步进数目作为输入(总共4个值),并返回矢量场文件的名称,表示此步进磁场的B场。矢量场文件中B场的单位为特斯拉。
– Multi routinecount \
param1count name1 param1 param2 . . . \
param2count name2 param1 param2 . . . \
. . .
允许多个场类型的例程组合使用。由于所有条目都必须在同一行上,故需要在行末尾加上“\”续行符。这里routinecount是例程的数量,param1count是第一个例程所需参数的数量(数量包括name1),等等。
注意,所有长度均以米为单位。模拟中的坐标都位于第一象限内,即在(0,0,0)到(Part Width, Part Height, Part Thickness)内。
17.1.6 输出描述。
•Base Output Filename:用于构造输出文件名称的默认基本名称。
•Magnetization Output Format:磁化文件中OVF数据块使用的格式。取值为“binary 4”(默认)、“binary 8”或“text format-spec”中的一种,其中format-spec是用C语言的printf样式的格式化代码,例如“%# .17g”。该条目是可选的。
•Total Field Output Format:与上面的Magnetization Output Format类似,但该条目用于输出总磁场的文件。该条目是可选的,默认为“binary 4”。
•Data Table Output Format:在生成数据表样式的标量输出时使用的格式,例如发送到mmDataTable,mmGraph和mmArchive的标量数据。需指定C语言的printf样式的格式化代码,例如默认的“%.16g”。该条目是可选的。
17.1.7 杂项。
•Converge |mxh| Value:用作停止标准的值:当模拟中所有自旋的||m x h||(即 )小于该值时,则假设在当前外加磁场的情况下已达到平衡状态。取值是一个无量纲的数值。注意:此记录标识符已弃用,改用Default Control Point Spec。
•Randomizer Seed:随机数发生器种子的值。该条目是可选的,默认值为0,表示使用利用系统时钟生成伪随机种子。
•Max Time Step:限制ODE的最大步长不大于此值(以秒为单位)。该条目是可选的。
•Min Time Step:限制ODE的最小步长不小于此值(以秒为单位)。该条目是可选的。
•User Comment:用于描述问题的不限格式的注释字符串。该条目是可选的。
17.2 MIF 1.2。
MIF 1.2格式在MIF 1.1的基础上进行了小的修改,该格式支持功能受限的3D微磁问题。MIF 1.2格式的文件可以被Oxs 3D求解器读取,在某些限制条件下,也可以被mmSolve 2D求解器读取。问题编辑器mmProbEd可以读写这种格式。mifconvert程序可用于在MIF 1.1和MIF 1.2格式之间转换,以及把MIF 1.x格式转换为MIF 2.1格式。当向Oxs求解器输入MIF 1.X文件时,Oxs求解器也会自动调用mifconvert程序来转换格式,因此,有关Oxs解析MIF 1.X文件遇到的问题,可以对输入的MIF 1.X文件单独运行mifconvert程序来解决。
MIF 1.1和1.2格式之间有四个不同的地方,在MIF 1.2格式中:
1.第一行是:# MIF 1.2
2.CellSize有三个参数:x方向、y方向和z方向的尺寸(以米为单位)。
3.DemagType的3dSlab、2dSlab、3dCharge和FastPipe已被弃用。
4.引入了新的记录标识符SolverType,可取值为Euler、RK2、RK4、RKF54和CG,分别表示使用一阶Euler、二阶Runge-Kutta(龙格-库塔)、四阶Runge-Kutta、五阶(+四阶)Runge-Kutta-Fehlberg和Conjugate-Gradient(共轭梯度)求解器。该条目是可选的,默认值为RKF54。
如果CellSize只指定了一个参数,则其解释方式与MIF 1.1相同,即该参数被视为计算单元的x和y方向的尺寸,z方向的尺寸表示零件厚度。
mmSolve 2D求解器可以接受MIF 1.2格式的文件,前提是CellSize满足以下限制,即x和y方向的尺寸必须相同,z方向的尺寸必须等于零件厚度。并且mmSolve 2D求解器会忽略SolverType记录标识符(如果有的话)。
Oxs 3D求解器可以读取MIF 1.2格式的文件,但只支持退磁内核为ConstMag和None,其他所有DemagType都会自动转换为ConstMag。SolverType将转换为相应的solver+driver对。
17.3 MIF 2.1。
MIF 2.x格式是在Oxs 3D求解器中引入的,但它并不兼容MIF 1.x格式,可以使用mifconvert程序将MIF 1.x转换为MIF 2.1格式。
17.3.1 MIF 2.1文件概述。
MIF文件的第一行必须是“# MIF x.y”的形式,其中x.y代表格式版本,此处为2.1。与MIF 1.1不同,MIF 2.1的文件结构需要满足Tcl脚本的格式要求,但MIF 2.1也允许有一些额外的扩展部分。这些文件在Tcl解释器中进行解析,该解释器可以工作在“安全”模式下,即禁止访问磁盘和其他系统。(有关安全解释器的详细信息,请参考Tcl的interp命令文档。)安全级别由options.tcl的MIFinterp选项控制,该选项的默认设置为:
Oc_Option Add Oxs* MIFinterp safety custom
表示解释器支持第17.3.2节中描述的所有的MIF 2.1扩展命令,但解释器运行在标准Tcl的安全模式下。上面的关键字custom可以替换为safe或unsafe。safe与custom类似,只是该模式下的解释器不支持ReadFile和RGlob扩展命令,从而限制了在MIF脚本级别的所有磁盘访问。unsafe表示Tcl解释器运行在不受限制的模式下,用户应谨慎的使用此关键字,尤其是在从未知或不受信任的来源读取MIF文件。
在MIF 2.1文件的第一行后面,可以灵活的调整文件的布局。通常在文件顶部附近,可以根据需要放置任意的OOMMFRootDir、Parameter和RandomSeed语句。
接下来是MIF 2.1文件的主要内容,即用于初始化各种Oxs_Ext对象的Specify指定块:
• Atlas (一个或多个)
• Mesh (一个)
• Energy terms (一个或多个)
• Evolver (一个)
• Driver(一个)
Specify指定块是按顺序处理的,因此被其他Specify块引用的对象都必须定义在文件的前面。因此,通常被其他Specify块引用的atlas容器对象会定义在文件的开头部分。atlas容器对象定义了模拟的空间范围,并可以选择声明模拟空间中的子区域。
mesh网格对象详细描述了模拟空间的离散化。通常,其Specify指定块紧跟在atlas对象的Specify指定块的下面。网格被driver驱动器引用,因此在任何情况下,网格的Specify指定块都需要在驱动器的Specify指定块之前。
energy能量项描述了决定模拟演化的典型微磁能量和场,如交换能、静磁场和各向异性能。材料的参数,如各向异性常数K1和交换常数A,通常在相关能量的Specify指定块内设置,如Oxs_UniaxialAnisotropy或Oxs_Exchange6Ngbr。但有些特殊的参数,如饱和磁化强度Ms,它是在driver驱动器的Specify指定块中设置的。初始磁化配置m0也在是driver驱动器的Specify指定块中设置的。在大部分情况下,这些材料参数值可能是随空间变化的,那么则可以使用标量场或矢量场对象来设置。正如第17.3.3节文档中所述,标量场和矢量场等辅助的对象可以内联定义(内联或内嵌,即在引用的Specify指定块内定义对象),也可以在自己的独立顶级Specify指定块中定义。在后一种情况下,场对象必须定义在引用的Specify指定块的前面。
给定了能量和场,演化器和驱动器会形成匹配对,遵循Landau-Lifshitz-Gilbert(LLG)动力学方程或能量最小化,将从初始磁化配置向前演化磁化状态。对于能量最小化,驱动器必须是Oxs_MinDriver对象,演化器必须是最小化演化器。在撰写本文时,随OOMMF打包的唯一最小化演化器是Oxs_CGEvolve共轭梯度演化器。对于时间演化(LLG)模拟,驱动器必须是Oxs_TimeDriver对象,演化器必须是时间演化器,例如Oxs_RungeKuttaEvolve。要使用的演化器会被驱动器的Specify块引用,因此在MIF 2.1文件中,演化器必须定义在驱动器的前面。如上所述,逐点饱和磁化强度Ms和初始磁化配置m0也在驱动器的Specify指定块内声明。
通过零个或多个Destination和Schedule命令指定的预输出,通常放置在Specify指定块之后。输出选项也可以在Oxsii或Boxsi运行时的交互界面中手动修改。
Tcl的辅助函数可以放在文件中的任何位置,但通常放在使用地点的附近或MIF文件的底部。如果只在Specify指定块内部引用函数,则可以将其放置在文件中的任何位置。另一方面,如果在MIF文件的顶层使用proc,例如要在运行时“动态地”创建微磁问题的一部分,那么在使用前就必须按Tcl的格式对其进行定义。
MIF 2.1文件示例如第17.3.5节的图17.2所示。有关单个Oxs_Ext对象的详细信息,参考第7.3节标准Oxs_Ext子类部分。
17.3.2 MIF 2.1扩展命令。
除了标准的Tcl命令(在Tcl安全模式下),MIF 2.1文件中还提供了许多其他扩展命令:Specify、ClearSpec、Destination、GetStateData、Ignore、OOMMFRootDir、Parameter、Random、RandomSeed、Report、ReadFile、RGlob和Schedule。
Specify
MIF 2.1文件的主体就是由一系列的Oxs_Ext对象构建的。通常,在输入MIF 2.1文件中是通过使用Specify命令创建和初始化Oxs_Ext对象的,因此Specify指定块是定义微磁问题的主要组件。Specify命令接受两个参数:要创建的Oxs_Ext对象的名称,以及在构造Oxs_Ext对象时传递给该对象的初始化字符串。MIF文件中的对象是按照它们在文件中出现的顺序创建的,在某些情况下,它们的顺序很重要,例如,如果一个Oxs_Ext对象(即引用对象)在其初始化字符串中引用了另一个Oxs_Ext对象(即被引用对象),则MIF文件中的被引用的对象必须定义在引用对象的前面。下面是一个简单的Specify指定块:
Specify Oxs_EulerEvolve:foo {
alpha 0.5
start_dm 0.01
}
新的Oxs_Ext对象的名称是“Oxs_EulerEvolve:foo”,名称中第一部分是从开始到冒号的部分,它是这个对象的C++类名,它必须是Oxs_Ext的子类。这里的Oxs_EulerEvolve是集成了Landau-Lifshitz ODE(算法为简单一阶前向欧拉法)的类。名称中第二部分是冒号后面的部分,它是该类的实例对象名称。通常,一个模拟中可以有Oxs_Ext一个子类的多个实例对象,但每个实例对象必须有唯一的名称。输出例程利用实例对象的名称来识别对象,借助实例对象的名称,一个Specify指定块可以引用文件中前面出现的另一个Specify指定块。如果未给出名称的第二部分(即实例对象的名称),则默认情况下会设为空字符串。例如,如果上面的名称不是设置为“Oxs_EulerEvolve:foo”,而是设置为“Oxs_EulerEvolve”,那么创建的实例对象的有效全名称是“Oxs_EulerEvolve:”。
Specify命令的第二个参数(即大括号之间的所有内容)是一个字符串,表示新建的Oxs_Ext(子)对象的构造函数。字符串的格式由子类的设计者决定,鼓励设计者遵循一些格式惯例,这些格式惯例见下文的第17.3.3节。
ClearSpec
此命令用于禁用该命令之前的一个或所有Specify命令。特别是,可以使用ClearSpec命令删除从使用ReadFile命令导入的基础MIF文件中Specify指定块。示例用法如下:
ClearSpec Oxs_EulerEvolve:foo
此命令的参数是要删除的Specify块的全名称(此处为Oxs_EulerEvolve:foo)。如果未设置任何参数,则表示删除此命令之前的所有Specify指定块。
DateSort
给定一个文件名称列表(列表中的文件必须全部存在),将返回按修改时间排序(最旧的排最前面)的列表。示例用法为:
set last_omf [lindex [DateSort [RGlob *omf]] end]
此处的last_omf将被设置为当前目录中具有最新修改时间的*.omf文件。
Destination
Destination命令的格式为:
Destination <desttag> <appname> [new]
此命令使用符号标记desttag与一个OOMMF子程序关联起来,Schedule命令使用这些标记来引用特定的程序实例。appname可以是OOMMF子程序的名称,例如mmDisp,也可以是application:nickname形式的特定子程序的实例,例如mmDisp:Spock。在第一种情况下,该标记与请求的子程序(此处为mmDisp)的运行实例关联起来,该子程序的实例是尚未与另一个标记关联的,且有最小OOMMF ID(OID)。如果找不到正在运行且符合这些条件的子程序实例,则会启动该子程序的一个新的实例。
如果appname设置为子程序的特定实例,那么该标记将和正在运行的指定昵称的子程序实例关联起来。名称匹配不区分大小写。如果没有运行的子程序实例满足此条件,则会启动子程序的新实例,并为其分配指定的昵称。OOMMF帐户服务目录会保证一个子程序具有指定昵称的实例不会超过一个,但是,与Specify命令中对象的名称一样,两个不同子程序的实例(例如mmDisp和mmGraph)可以使用相同的昵称,但是它们完整的实例名称mmDisp:Spock和mmGraph:Spock,是不同的。
多个Destination命令会按照在MIF文件中出现的顺序进行处理。同一个desttag不能出现在多个Destination命令中,两个desttag不能引用同一个子程序实例。为了确保后者,建议用户把所有引用特定实例的Destination命令(例如mmDisp:Spock)放置在引用通用程序(例如mmDisp)的所有Destination命令之前。否则,一个通用引用可能会和一个正在运行的子程序关联起来,但该子程序却有一个由后面的Destination命令引用的昵称。
只有读取MIF文件的求解器才知道Destination命令的标记关联的是那个子程序实例。相比之下,在子程序实例中可以获取分配给自己的昵称。特别是,多个求解器可以通过昵称引用正在运行的同一个子程序。例如,几个连续运行的求解器可以将阶段输出发送到同一个mmGraph,以生成重叠的磁滞回路。
Destination命令的最后一个参数是可选的关键字new。如果指定了new,则表示始终启动请求子程序的新实例,以便和给定标记关联起来。关键字new可以安全地与任何引用通用程序的Destination命令一起使用,但在把它与引用特定实例的Destination命令一起使用时需要小心,因为如果请求的指定昵称的子程序已经被关联了的话,则会引发错误。
GetStateData
GetStateData命令会检索特定磁化状态的数据:
GetStateData [-glob|-exact|-regexp] [-pairs] [--] <state_id> \
[pattern ...]
与磁化状态关联的数据的存储形式为键值对。如果没有指定模式(译者注:即pattern,就是一个字符串,意义类似正则表达式的pattern),则GetStateData返回给定磁化状态可用的键构成的列表。如果指定了一个或多个pattern,则会获取所有与这些pattern匹配的键对应的值。如果指定了-pairs选项,那么返回的是键和值的构成的列表(偶数长度)。如果未指定-pairs,则返回的是仅包含值的列表,这些值按照键的匹配顺序返回。键的匹配样式由第一组选项控制,默认为glob样式。两个连字符可以用来表示选项的结尾。
state_id是标识磁化状态的正整数,它通常是通过相关Oxs_Ext对象的Specify块中的script_args选项获得的。例如:
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}
}
通常可以通过以上方式访问两种磁化状态:步进的基本磁化状态和候选(测试)磁化状态。前者通过base_state_id访问,对应最后一个有效的、可接受的磁化状态。后者通过current_state_id访问,是演化器对象的最新演化状态。在某些情况下,这两种磁化状态可能会重合。
与磁化状态关联的键会随模拟而变化,但以下键是始终可用的:
时间以秒为单位,step/stage/run_done值为1(完成)、0(未完成)或-1(尚未确定)中的一个,max_absMs以A/m为单位。
Oxs_Ext对象可以将其他键值对添加到磁化状态。例如,Oxs_RungeKuttaEvolve可以通过键Oxs_RungeKuttaEvolve:<instance_name>:Mx添加平均磁化强度的x分量。(这里的<instance_name>是实例对象的名称,它通常是一个空的或“evolver”字符串。)查阅有关文档了解各种Oxs_Ext对象的详细信息。
此外,磁化状态可用的键取决于模拟的状态或当前的步进,特别是,current_state_id表示的当前磁化状态通常只有上表中的(即默认的)键可用,而且由于current_state_id是一个可能被拒绝的测试状态,因此用户在脚本中应该避免使用与当前磁化状态相关的数据,而使用从基本状态收集的数据。同样,与阶段内的磁化状态相比,新阶段开始的磁化状态(甚至是基本磁化状态)的可用键也可能不同。可以在脚本中的函数内使用Report命令将磁化状态信息发送到Oxsii控制台,例如:
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
...
}
或者
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
...
}
要了解使用GetStateData命令的实例,请查阅目录oommf/app/oxs/examples/中的spinmag.mif和spinmag2.mif示例文件。
Ignore
Ignore命令接受任意数量的参数,这些参数将被忽略而不被解析。Ignore的主要用途是临时注释(即禁用)Specify指定块。
OOMMFRootDir
这个命令不带任何参数,它会返回OOMMF根目录的完整目录路径。这对于需要在OOMMF层次的目录中查找文件的ReadFile命令非常有用,也可用于放置输出文件。文件路径必须可以被直接创建,因为解释器在安全模式下无法使用Tcl的file命令。例如:
set outfile [OOMMFRootDir]/data/myoutput
在此处,应使用Tcl的路径规范:使用正斜杠“/”来分隔目录。
Parameter
Oxs(Oxsii和Boxsi)允许在命令行中通过-parameters选项设置MIF文件中的指定变量。在MIF文件中通过Parameter命令设置:
Parameter varname optional_default_value
这里varname是可以在命令行设置的变量名称,如果用户未在命令行上设置该变量的值,则将变量值设置为可选的默认值optional_default_value(如果有的话),否则将会引发错误。如果命令行上设置的变量在MIF文件中没有对应的Parameter命令,也会引发错误。另参考下文关于变量替换的文档。
Random
使用C语言库中的随机数生成器,并返回[0,1]区间内的伪随机数。此随机数生成器由ocport.h文件中的宏OMF_RANDOM指定,ocport.h在oommf/pkg/oc/的子目录中。也可以使用标准Tcl的expr rand()命令生成伪随机数。
RandomSeed
初始化Tcl和C库的随机数生成器。可以指定一个整数作为随机种子。如果没有指定参数,则从系统时钟中生成随机种子。
Report
主要作为MIF文件中代码的调试辅助工具,Report接受一个字符串参数,并将字符串打印到求解器的控制台和Oxs的日志文件。它是标准Tcl的puts命令的替代品,puts命令在安全模式下不可用。
ReadFile
安全模式的解释器没有Tcl的read命令,ReadFile命令是“custom”和“unsafe”模式的解释器可使用的替代品。ReadFile接受两个参数,一个是要读取的文件,另一个是可选的传输格式。文件可以使用绝对路径(即包含其所有目录的路径)指定,也可以使用相对于包含该MIF文件的目录的相对路径指定。OOMMFRootDir命令可用于在OOMMF目录树中查找文件。
传输格式是binary、auto(默认)、image或floatimage中的一种。前两项的功能和它们在Tcl的fconfigure命令的-translation选项中的功能相同,有关详细信息,请参考Tcl文档。image表示将输入文件作为图像文件读取。如果文件是PPM P3(文本)、PPM P6(二进制)或未压缩的BMP格式,则会直接读取该文件,否则将通过any2ppm程序进行转换。(注意,any2ppm需要Tk的支持,而Tk需要有效的显示程序。)输入文件被转换为一个字符串,该字符串是在PPM P3文本文件的基础上,删除掉了文件开头的“P3”(即表示文件格式类型的魔数)。在转换后,字符串的前3个用空格分隔的值分别是图像的宽度(width)、高度(height)和最大像素值(maxvalue),接着是一个长度为3×宽度值×高度值的数组,其中每个三元组对应于图像像素的红色、绿色和蓝色分量,数组中的三元组按正常的英语阅读顺序排列,数组中的每个数值都在[0,maxvalue]范围内。该字符串不包含注释,可以直接作为Tcl列表进行处理。floatimage选项与image选项非常相似,不同之处在于字符串中的第三个值(即maxvalue)始终为“1”,随后的红色、绿色和蓝色分量的值是[0,1]范围内的浮点值。
在所有情况下,ReadFile命令的返回值都是与文件(可能是已转换的文件)的内容相对应的字符串。例如以下命令可用于在MIF 2.1文件中嵌入一个单独的Tcl文件:
eval [ReadFile extra_mif_commands.tcl]
下面是一个更复杂的示例,表示使用彩色图像文件来创建矢量场:
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
}
如果输入图像较大,则最好直接使用图像列表(即示例中的colorimage变量),如上所示。ReadFile返回的图像列表的格式是已经压缩过的,如果对列表值进行修改,则列表占用的内存会大幅增加。
如果options.tcl文件中的MIFinterp safety选项设置为safe,则ReadFile命令不可用。
RGlob
该命令的原型是Tcl的glob命令,但RGlob命令仅作用在当前工作目录,即保存MIF文件的目录。RGlob命令的语法是:
RGlob [-types typelist] [--] <pattern> [...]
可选的“typelist”表示文件需要匹配的类型。可选的“--”表示选项的结束。一个或多个“pattern”(译者注:即模式,意义类似正则表达式的pattern)是全局样式的模式(即一个包含星号和问号的字符串),用于匹配当前工作目录中的文件名称。有关-types选项和glob模式详细信息,请查阅Tcl的glob文档。
该命令的一个用途是识别先前创建的文件。例如,假设用户想查找mmArchive保存的MIF文件中(basename为“sample”)第三阶段的磁化输出,输出文件按照阶段编号(此处为“2”,阶段从0开始计数)和迭代数进行命名,但迭代数通常是未知的,假设输出文件与当前MIF文件位于同一目录中,则可以使用如下命令来确定磁化文件的名称:
set file [RGlob sample-Oxs_MinDriver-Magnetization-02-???????.omf]
如果该阶段保存了多个磁化状态,则变量file会是匹配的文件名称的列表。在这种情况下,可以使用Tcl的lsort命令选择迭代数最大的一个文件名称。file变量可以与Oxs_FileVectorField类结合使用,用于把磁化状态导入新的模拟中,例如设置初始磁化配置。
如果options.tcl文件中的MIFinterp safety选项设置为safe,则RGlob命令不可用,如果设置为unsafe,那么标准Tcl的glob命令(功能更强大)将可用。
Schedule
Schedule命令用于设置MIF文件的输出。此功能对于在批处理模式下运行的求解器至关重要,对于在手动模式下设置的默认输出也很有用。Schedule命令的语法是:
Schedule <outname> <desttag> <event> <frequency>
Schedule命令对应Oxsii和Boxsi图形界面中手动的输出计划。Schedule命令的第一个参数是输出项名称,这些输出名称和Oxs图形界面中“Outputs”列表中显示的名称相同,例如“DataTable”或“Oxs_CubicAnisotropy:Nickel:Field”。输出名称必须作为单个参数传给Schedule命令,如果输出的名称中包含一个或多个空格,则需要使用双引号保护空格。除了DataTable输出始终存在外,其他outname还依赖MIF文件内容。
Schedule命令的第二个参数是目标标记,它是一个通过前一个Destination命令与正在运行的子程序实例关联起来的标记。目标标记取代了在图形界面中使用的application:OID的命名方法,因为用户在编写MIF文件时通常不知道运行的子程序的OOMMF ID。事实上,有些子程序可能是通过Destination命令启动的,因此在处理Destination命令时,这些子程序甚至没有OID。
event参数应该是关键字Step、Stage或Done之一。对于Step和Stage事件,frequency参数应为非负整数,表示在事件发生次数达到指定的频率时输出outname表示的输出。例如,如果设置为Step 5,则在求解器的每五个步进(迭代0、5、10,…),会把指定类型的输出将发送到所选的目标子程序。将frequency设置为1,表示在每次事件发生时发送输出到所选的目标子程序。frequency为0时,表示只会在该事件第一次发生时输出,特别是,Step 0将输出模拟的初始状态,但不会在任何后续步进事件中触发输出。Done事件发生在微磁模拟成功完成时,故每个模拟最多有一个“Done”事件。相应的,Done事件的频率参数是可选的,且只能设为1。
图17.2所示的MIF 2.1示例文件中有Destination和Schedule命令的使用示例。其中,有三个目标子程序被标记。第一个标记(hystgraph)引用一个可能已经运行的mmGraph程序实例,程序的昵称为Hysteresis,在每个阶段结束时,关联的Schedule命令会把DataTable输出发送到此程序,从而生成磁滞回线的图像。第二个标记(monitor)引用作为监视mmGraph运行的不同实例,为了确保在一块白板上绘制此输出,使用关键字new来启动mmGraph的全新实例。该标记的Schedule命令表示,在求解器的每5次迭代时,就向和monitor标记关联的mmGraph程序实例发送一次输出。最后一个Destination命令的标记(archive)引用一个任意的mmArchive程序,该程序用于在每个阶段结束时存储数据表内容,并在每三个阶段结束时存储磁化状态和总磁场。注意,对“Oxs_EulerEvolve::Totalfield”使用双引号,若没有双引号,Schedule命令将得到五个参数:“Oxs_EulerEvolve::Total”,“field”,“archive”,“Stage”和“3”。
17.3.3 Specify的使用惯例。
输入MIF文件中的Specify指定块描述了Oxs模拟的一系列Oxs_Ext对象。如上所述,Specify命令接受两个参数,即要创建的Oxs_Ext对象的名称和一个初始化字符串。初始化字符串的格式可以是任意的,但它是由Oxs_Ext类的作者决定的。本节介绍了建议Oxs_Ext类的作者遵循的一些使用惯例,任何不遵循这些使用惯例的Oxs_Ext类都应该在它的文档中明确的说明。有关OOMMF中包含的标准Oxs_Ext类的详细信息,查阅第7章Oxs文档。
17.3.3.1 初始化字符串的格式
再次思考上面给出的简单Specify指定块:
Specify Oxs_EulerEvolve:foo {
alpha 0.5
start_dm 0.01
}
第一个使用惯例是,初始化字符串被构造为一个包含偶数个元素的Tcl列表,列表中的每个元素由一个“标签+值”对组成。在上面的示例中,初始化字符串由两个“标签+值”对(“alpha 0.5”和“start_dm 0.01”)组成。第一个参数表示Landau-Lifshitz ODE中的阻尼参数α为0.5。第二个参数指定计算引擎的初始步长。参考Tcl编程指南(例如,参考文献[32])了解有关Tcl列表的详细信息。简而言之,标签和值之间使用空格分隔,并用双引号或大括号(“{”和“}”)分组。大括号和引号的开始部分必须使用空格与前面文本分开。分组字符在解析过程中被删除。在本例中,列表是用大括号包围的一个整体,单个元素用空格分隔。通常,初始化字符串中“标签+值”对的顺序是不重要的,即start_dm 0.01可以在alpha 0.5的前面。
有时,“标签+值”对的值本身也是一个列表,如下例所示:
Specify Oxs_BoxAtlas:myatlas {
...
}
Specify Oxs_RectangularMesh:mymesh {
cellsize { 5e-9 5e-9 5e-9 }
atlas Oxs_BoxAtlas:myatlas
}
此处的标签“cellsize”的值是一个由3个元素组成的列表,这些以米为单位的元素表示沿每个坐标轴的采样率。(Oxs_BoxAtlas是Oxs_Atlas的特殊子类。“. . .”表示Oxs_BoxAtlas的初始化字符串,由于它与当前讨论无关,因此文中省略该字符串。)
17.3.3.2 Oxs_Ext对象的引用
上例网格的Specify指定块中的“atlas”引用了前面定义的Oxs_Ext对象,即“Oxs_BoxAtlas:myatlas”。一个Oxs_Ext对象经常需要访问另一个Oxs_Ext对象,在本例中,网格对象 :mymesh 需要访问atlas对象 :myatlas,以获取需要网格化的空间范围。atlas容器对象通过独立的顶级Specify指定块定义在MIF文件的前面部分,网格对象通过指定容器对象的名称来引用它,它使用的是容器对象的全名称,不过也可以使用容器对象的简称 :myatlas,前提是没有相同的简称的其他Oxs_Ext对象。
Oxs_RectangularMesh对象也可以内联定义一个Oxs_BoxAtlas对象(内联或内嵌,即inline):
Specify Oxs_RectangularMesh:mymesh {
atlas {
Oxs_BoxAtlas {
...
}
}
cellsize { 5e-9 5e-9 5e-9 }
}
atlas引用了一个内联的容器对象。内联的对象是由对象类型(此处为Oxs_BoxAtlas)和相应的初始化字符串组成的列表,初始化字符串作为子列表,其格式与在单独的Specify指定块中使用的格式相同。
更常见的用法是,使用内联的Oxs_Ext对象去初始化空间变化的量。例如:
Specify Oxs_UniaxialAnisotropy {
axis { Oxs_RandomVectorField {
min_norm 1
max_norm 1
}}
K1 { Oxs_UniformScalarField { value 530e3 } }
}
代表磁晶各向异性的类Oxs_UniaxialAnisotropy支持随单元格而变化的K1和各向异性轴方向。在本例中,各向异性轴方向是随机分布的,为了设置其内部的随机数据,Oxs_UniaxialAnisotropy创建了一个局部的Oxs_RandomVectorField对象,该对象也是Oxs_Ext层次的子类对象,Oxs_Ext层次的子类对象允许使用Specify命令来构造。但在本例中,局部的Oxs_RandomVectorField对象只能被外层的Oxs_UniaxialAnisotropy对象访问,而不能在其他Specify指定块中引用它,甚至不能在同一初始化字符串内的其他地方引用它。由于无法引用该对象,因此该对象不需要实例名,但必须为该对象指定一个初始化字符串,本例中的初始化字符串是4元组“min_norm 1 max_norm 1”。需要注意大括号的嵌套,于是这个4元组就作为单个参数项传递给Oxs_RandomVectorField,而Oxs_RandomVectorField和它的初始化字符串则被包装在最外层的Tcl列表中,于是最外层的Tcl列表就作为单个参数项被“axis”引用。
“K1”引用的是另一个内联的Oxs_Ext对象。在这个例子中,假设K1在整个模拟区域内是均匀的(所有单元格拥有相同值),因此可以使用简单的Oxs_UniformScalarField类来初始化K1(值为)。对于均匀的(标量或矢量)场,还可以使用一种简写方法来隐式构造这些均匀的Oxs_Ext子类对象:
Specify Oxs_UniaxialAnisotropy {
axis { 1 0 0 }
K1 530e3
}
等效于:
Specify Oxs_UniaxialAnisotropy {
axis { Oxs_UniformVectorField {
vector { 1 0 0 }
}}
K1 { Oxs_UniformScalarField { value 530e3 } }
}
虽然在Specify指定块使用内联的Oxs_Ext对象很方便,但要记住,内联的对象不能被其他的Oxs_Ext对象引用,在别的Specify指定块内只能引用通过顶级Specify指定块定义的对象。此外,内联的Oxs_Ext对象无法直接提供输出。此外,能量和场计算中包含的Oxs_Energy能量对象是通过顶级Specify指定块定义的对象,因此,Oxs_Energy类的对象总是通过顶级Specify指定块创建的,而不能作为内联对象来创建。
17.3.3.3 分组列表
如前所述,有时“标签+值”对的值是一个列表。一些Oxs对象支持分组列表,分组列表为列表提供了动态长度的编码方法。示例列表:
{ 1.1 1.2 1.2 1.2 1.2 1.3 }
在分组列表中,中间的1.2可以表示为重复次数为4的子列表,如下所示:
{ 1.1 { 1.2 4 } 1.3 :expand: }
此处的 :expand: 关键字作为最外层列表的最后一个元素,表示启用组扩展机制。前面的任何元素,如{1.2 4},若它是正确的子列表且最后一个元素是一个正整数,则将它视为分组子列表,且它的最后一个元素表示重复次数,最外层列表中的任何元素都不会被解释为重复计数。例如,列表:
{ 1e-9 1e-9 1e-9 1e-9 1e-9 1e-9 }
的简短形式是:
{ { 1e-9 6 } :expand: }
注意分组使用的括号在列表中的位置。分组列表也可以嵌套,如:
{ 5.0 { 5.1 { 5.2 3 } 5.3 2 } :expand: }
相当于
{ 5.0 5.1 5.2 5.2 5.2 5.3 5.1 5.2 5.2 5.2 5.3 }
当列表元素是包含空格的字符串(如文件名)时,用户在使用列表分组时会有一些困难。例如,列表为:
{ "file 3" "file 3" "5 file" }
如果用户试着把它写成:
{ { "file 3" 2 } "5 file" :expand: }
则会发现,由于嵌套的分组规则,这个分组列表被扩展为:
{ file file file file file file "5 file" }
这里的“file 3”末尾的“3”被解释为重复次数。按照普通Tcl的规则,在分组机制中,双引号会等同于大括号。但是,用户可以使用 :noexpand: 关键字禁用这种扩展机制,如下所示:
{ { {"file 3" :noexpand:} 2 } "5 file" :expand: }
放在列表末尾的 :noexpand: 关键字会禁用该列表中的所有组扩展。虽然几乎不会遇到这个例子,但如果恰好有一个非分组列表的最后一个元素为“:expand:”,则必须禁用分组机制,即在列表中追加 :noexpand: 。由程序生成的普通列表,建议追加 :noexpand: 确保列表不扩展。
就语法而言,标准(即普通)列表和单个值也会被视为分组列表。任何在其Specify指定块中接受分组列表的Oxs对象,都应该在其文档中明确说明这一点。
17.3.3.4 注释
标准Tcl的注释机制为:从#符号开始,直到行尾的所有文本都视为注释。在上面的示例中可以看到,在Specify大括号内的初始化字符串中,换行符与空格是等效的。由于这一点和其他一些原因,导致在Specify指定块内不能使用Tcl语法的注释。按照Specify的使用惯例,标签为“comment”的任何“标签+值”对都会被视为注释并丢弃。例如:
Specify Oxs_UniaxialAnisotropy {
axis { 1 0 0 }
comment {K1 4500e3}
K1 530e3
comment { 530e3 J/m^3 is nominal for Co }
}
注意此处 “标签+值”对中的标签“comment”与在Specify指定块之外使用的MIF扩展命令“Ignore”之间的区别。Ignore接受任意数量的参数,但标签“comment”的值必须是单个参数。
17.3.3.5 Attributes(属性)
有时,可以很方便地在特定的Specify指定块之外定义一些“标签+值”对,然后在Specify指定块中使用标签“attributes”导入它们。例如:
Specify Oxs_LabelValue:probdata {
alpha 0.5
start_dm 0.01
}
Specify Oxs_EulerEvolve {
attributes :probdata
}
Oxs_LabelValue对象是一个Oxs_Ext子类对象,只用于保存“标签+值”对。“attributes”标签相当于include语句,会把指定的Oxs_LabelValue对象中包含的“标签+值”对嵌入到Specify初始化字符串中。若需要在多个Specify指定块中使用Oxs_LabelValue对象中的“标签+值”对,则推荐使用此方法,这些指定块可以位于同一MIF文件中,也可以位于多个MIF文件中(使用MIF扩展命令ReadFile把Oxs_LabelValue块导入到多个MIF文件中)。
17.3.3.6 用户的自定义函数
许多Oxs_Ext类利用用户的自定义Tcl函数(译者注:proc,即procedure的缩写,等效于其他语言中的函数或方法,本手册中称之为大家熟知的函数)来提供运行时的扩展功能。最常见的例子是在变化场的初始化脚本中,会对离散化网格中的每个位置点调用用户定义的Tcl函数,该函数返回一个标量或矢量值,代表空间中该位置点的某些属性,例如饱和磁化强度、各向异性或外加磁场等。
以下是一个示例函数,可用于将初始磁化配置设置为近似涡旋状态,中心区域的自旋指向正z方向:
proc Vortex { x_rel y_rel z_rel } {
set xrad [expr {$x_rel-0.5}]
set yrad [expr {$y_rel-0.5}]
set normsq [expr {$xrad*$xrad+$yrad*$yrad}]
if {$normsq <= 0.0125} {return "0 0 1"}
return [list [expr {-1*$yrad}] $xrad 0]
}
本例的返回值是一个矢量,表示该点(x_rel,y_rel,z_rel)的自旋方向。用于设置标量属性(例如饱和磁化强度Ms)的函数将返回标量值。在这两种情况下,都需要在函数的输入参数列表中指定模拟网格中一个位置点。
在上面的示例中,函数的输入参数列表中是模拟网格范围中的相对位置点。例如,若x_rel为0.1,则表示该位置点的实际x坐标位于模拟中最小x值和最大x值之间的十分之一处。任何情况下,x_rel的值都在0到1之间。
在大多数函数示例中,相对坐标的表示形式是最灵活、最简单的。当然,按照使用惯例,Oxs_Ext类也支持绝对坐标的表示形式,在Oxs_Ext对象的Specify指定块中,通过可选的script_args脚本参数选择所需的坐标表示形式,script标签用于指定Tcl函数本身,如本例所示:
proc SatMag { x y z } {
if {$z < 20e-9} {return 8e5}
return 5e5
}
Specify ScriptScalarField:Ms {
atlas :atlas
script_args { rawpt }
script SatMag
}
在本例中,标签script_args的值应该是{relpt rawpt minpt maxpt span scalars vectors}的子列表,如前文Oxs_ScriptScalarField文档所述。其中,rawpt表示以微磁问题的坐标为参考提供位置点的绝对坐标,即以米为单位。有些Oxs_Ext对象的script_args支持不同的子列表,有关详细信息,参见相关Oxs_Ext对象的文档。注意,示例函数的输入参数列表中使用的参数名称仅为了方便解释,用户可以将参数名称重命名为其他名称,这是因为重要的是参数的顺序,而不是参数的名称。此外,在解析Specify指定块之前,会先对MIF 2.1文件进行整体解析,因此函数可以放置在MIF 2.1文件中的任意位置,而不用管引用的Specify指定块位于何处。但是,MIF 2.2文件只进行一次解析,即在读取MIF 2.2文件时就解析其中的Specify指定块。因此,对于MIF 2.2文件来说,通常将自定义的函数放在引用它们的Specify指定块之前。
Tcl函数的调用命令实际上是在标签script的值后面附加script_args的值来构造的。因此可以在script的值里面添加函数的额外参数(译者注:即在函数名之后添加这些额外参数),在这种情况下,这些额外参数在函数的输入参数列表中的位置是在script_args的值的前面。以下程序等效于上一个示例:
proc SatMag { zheight Ms1 Ms2 x y z } {
if {$z < $zheight} {return $Ms1}
return $Ms2
}
Specify ScriptScalarField:Ms {
script_args { rawpt }
script {SatMag 20e-9 8e5 5e5}
}
注意,在本例中,标签script的值是用大括号括起来的,因此字符串“SatMag 20e-9 8e5 5e5”将被视为该标签的单个值。
正如前例使用的Vortex函数所示,在MIF 2.1文件内的函数中,经常会用到Tcl的expr命令。如果用户使用的是Tcl 8.0或更高的版本,那么通过把expr命令的参数分组到大括号中(如Vortex函数所示),可以很大程度上减少多次调用该函数所需的cpu时间。大括号有助于Tcl字节码编译器的运行,但在涉及多次替换变量的情况下,这种大括号就无法使用了。有关expr命令的详细信息,参考Tcl文档了解。
有时,在Tcl函数之外定义数据可能有奇效,如本例所示:
# Lay out a 6 x 16 mask, at global scope.
set mask {
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1
}
proc MyShape { xrel yrel znotused } {
global mask ;# Make mask accessible inside proc
set Ms 8e5 ;# Saturation magnetization of element
set xindex [expr {int(floor($xrel*16))}]
set yindex [expr {5 - int(floor($yrel*6))}]
set index [expr {$yindex*16+$xindex}]
# index references point in mask corresponding
# to (xrel,yrel)
return [expr {[lindex $mask $index]*$Ms}]
}
变量mask持有定义样品零件形状的“0,1”Tcl列表,通过Tcl的global命令将mask包含在MyShape函数内部。相对x和y坐标被转换为列表的索引,函数的返回值为0或8e5,分别取决于mask中的对应点是0还是1。它的原理基本上与上述第17.3.2节MIF扩展命令中ReadFile文档里面的ColorField函数相同,但ColorField的数据是从单独的图像文件获取的,而不是MIF文件中嵌入的数据。
17.3.3.7 用户自定义的标量输出
OOMMF支持使用一种通用方法,允许用户从Oxs_Ext对象的矢量场输出中(译者注:查阅第7章回顾哪些Oxs_Ext子类对象可以提供矢量场输出或标量输出)导出所需的标量(DataTable)输出。通过Specify指定块内的“user_output”子块来定义这些标量输出,user_output子块的格式为:
user_output {
name output_name
source_field source
select_field weighting
normalize norm_request
exclude_0_Ms novacuum
user_scaling scale
units units
}
第一个参数name指定该标量输出的标签,标签的全名称是Specify指定块定义的对象全称加上 :output_name。设置name标签时必须遵循ODT列标签的规则,尤其是不允许嵌入换行符和回车符。
第二个参数source_field指定从哪个矢量场输出导出标量输出。source应与Oxsii或Boxsi交互界面的“Output”面板中显示的源(矢量)场输出的标签匹配,源场输出的标签可以在有关Oxs_Ext类的文档中找到。如果源场与用户定义的标量输出来自同一个类,则source可以为缩写的矢量场输出的标签(即标签的全名称的最后一个“:”后面的部分),否则必须为标签的全名称。
第三个参数select_field引用一个矢量场,表示对源场加权以创建标量输出,标量输出是根据以下公式计算得到的:
其中求和是基于模拟中所有单元格来计算的,Wselect[i]是select_field在单元格i处的矢量值,Vsource[i]是source_field在单元格i处的矢量值,“·”表示标量(点)积。
前三个参数是必需设置的,但其余参数是可选的。第一个可选参数normalize影响(17.1)中的分母,如果norm_request为1(默认值),则使用(17.1)所示的公式计算标量输出,如果norm_request为0,那么分母将替换为模拟中的单元格数量,即 (i个1相加)。
第二个可选参数exclude_0_Ms是一个便捷的运算符号,如果novacuum为1,则select_field将被重置,以便在模拟中的所有饱和磁化强度为零的单元格中,select_field的值都为零矢量。当用户想计算一个某形状的零件的平均磁化强度时,该参数是很有用的。对select_field的更改操作是在计算(17.1)中的分母之前进行的,因此将exclude_0_Ms设置为1,就相当于在Ms为零的地方将select_field的矢量值设置为零。此参数的默认值为0,表示select_field完全按照它自身的定义来使用。
user_scaling(默认值1.0)表示一个与(17.1)的计算结果相乘的常数因子。例如,它可以与参数units结合使用,以实现单位转换。units的值是放置在数据表输出中的任意字符串(例如,A/m)。设置units标签必须遵循ODT单位标签的规则,尤其是不允许嵌入换行符和回车符。如果未设置units,则单位字符串默认为源场的单位。
以下是一个简单的示例,里面有基于退磁场的两个user_output:
Specify Oxs_BoxAtlas:atlas [subst {
xrange {0 $cube_edge}
yrange {0 $cube_edge}
zrange {0 $cube_edge}
}]
Specify Oxs_BoxAtlas:octant [subst {
xrange {0 [expr {$cube_edge/2.}]}
yrange {0 [expr {$cube_edge/2.}]}
zrange {0 [expr {$cube_edge/2.}]}
}]
Specify Oxs_AtlasVectorField:octant_field_y {
atlas :octant
default_value {0 0 0}
values {
octant {0 1 0}
}
}
Specify Oxs_Demag {
user_output {
name "Hdemag_x"
source_field Field
select_field {1 0 0}
}
user_output {
name "octant Hdemag_y"
source_field Field
select_field :octant_field_y
}
}
第一个输出“Hdemag_x”返回在整个模拟空间中的平均退磁场的x分量。该输出在数据表输出中的标签为标签“Oxs_Demag::Hdemag_x”。source_field参数的值“Field”引用的是外围Oxs_Ext对象的场输出,在本例中,它是Oxs_Demag::Field。把select_field设置为(1,0,0),表示select_field在整个模拟空间中的矢量值是相同的。第二个输出“octant Hdemag_y”是类似,但它只返回在第一个八分之一模拟空间中的平均退磁场的y分量,它求平均的空间范围和坐标分量是由 :octant_field_y 对象定义的,该对象在第一个八分之一模拟空间中的矢量值为(0, 1, 0),其他地方为(0, 0, 0)。
用户定义的标量输出的源代码参考oommf/app/oxs/base/目录中的ext.h和ext.cc,MIF示例文件参考oommf/app/oxs/examples/目录中的cube.mif, pbcbrick.mif以及stdprob2.mif。
17.3.4 变量替换。
MIF 2.1文件的一个强大功能是能够定义和使用变量。例如,Oxs(Oxsii和Boxsi)将命令行选项-parameter与MIF的Parameter命令结合使用,若在命令行上设置变量的值,那么在MIF输入文件中可以获取该变量的值。在Tcl语法中,通过在变量名的前面加上“$”符号来获取该变量的值。例如,如果cellsize是一个值为5e-9的变量,则使用$cellsize可以获取它的值(5e-9)。
不过,在Specify指定块中使用变量需要注意一些特殊情况。考虑一个简单的例子:
Parameter cellsize 5e-9
Specify Oxs_RectangularMesh:BadExample {
comment {NOTE: THIS DOESN'T WORK!!!}
cellsize {$cellsize $cellsize $cellsize}
atlas :atlas
}
它会和用户预想的运行情况不一样,因为用于设置Specify初始化字符串的大括号会禁止变量的替换。不过有几种方法可以解决这个问题,但最简单的方法是将初始化字符串嵌入subst (substitution)命令中:
Parameter cellsize 5e-9
Specify Oxs_RectangularMesh:GoodExample [subst {
comment {NOTE: This works.}
cellsize {$cellsize $cellsize $cellsize}
atlas :atlas
}]
其中的方括号“[”和“]”表示Tcl执行命令替换,即,将方括号内的字符串作为Tcl命令来执行,在本例中是subst命令。有关subst命令的详细信息,参考Tcl文档。上面演示的是subst命令的默认用法:对参数字符串执行变量替换、命令替换和反斜杠替换。
下面的例子包含变量替换和命令替换:
set pi [expr {4*atan(1.0)}]
set mu0 [expr {4*$pi*1e-7}]
Specify Oxs_UZeeman [subst {
comment {Set units to mT}
Hscale [expr {0.001/$mu0}]
Hrange {
{ 0 0 0 10 0 0 2 }
{ 10 0 0 -10 0 0 2 }
}
}]
注意,subst命令的作用范围是全局范围的,因此在subst命令的参数字符串中可以直接访问全局变量mu0。
17.3.5 MIF 2.1文件示例。
# MIF 2.1
#
# All units are SI.
#
# This file must be a valid Tcl script.
#
# Initialize random number generators with seed=1
RandomSeed 1
# Individual Oxs_Ext objects are loaded and initialized via
# Specify command blocks. The following block defines the
# extents (in meters) of the volume to be modeled. The
# prefix "Oxs_BoxAtlas" specifies the type of Oxs_Ext object
# to create, and the suffix ":WorldAtlas" is the name
# assigned to this particular instance. Each object created
# by a Specify command must have a unique full name (here
# "Oxs_BoxAtlas:WorldAtlas"). If the suffix is not
# explicitly given, then the default ":" is automatically
# assigned. References may be made to either the full name,
# or the shorter suffix instance name (here ":WorldAtlas")
# if the latter is unique. See the Oxs_TimeDriver block for
# some reference examples.
Specify Oxs_BoxAtlas:WorldAtlas {
xrange {0 500e-9}
yrange {0 250e-9}
zrange {0 10e-9}
}
# The Oxs_RectangularMesh object is initialized with the
# discretization cell size (in meters).
Specify Oxs_RectangularMesh:mesh {
cellsize {5e-9 5e-9 5e-9}
atlas :WorldAtlas
}
# Magnetocrystalline anisotropy block. The setting for
# K1 (500e3 J/m^3) implicitly creates an embedded
# Oxs_UniformScalarField object. Oxs_RandomVectorField
# is an explicit embedded Oxs_Ext object.
Specify Oxs_UniaxialAnisotropy {
K1 530e3
axis { Oxs_RandomVectorField {
min_norm 1
max_norm 1
} }
}
# Homogeneous exchange energy, in J/m. This may be set
# from the command line with an option like
# -parameters "A 10e-12"
# If not set from the command line, then the default value
# specified here (13e-12) is used.
Parameter A 13e-12
Specify Oxs_UniformExchange:NiFe [subst {
A $A
}]
# Define a couple of constants for later use.
set PI [expr {4*atan(1.)}]
set MU0 [expr {4*$PI*1e-7}]
# The Oxs_UZeeman class is initialized with field ranges in A/m.
# The following block uses the multiplier option to allow ranges
# to be specified in mT. Use the Tcl "subst" command to enable
# variable and command substitution inside a Specify block.
Specify Oxs_UZeeman:AppliedField [subst {
multiplier [expr 0.001/$MU0]
Hrange {
{ 0 0 0 10 0 0 2 }
{ 10 0 0 -10 0 0 2 }
{ 0 0 0 0 10 0 4 }
{ 1 1 1 5 5 5 0 }
}
}]
# Enable demagnetization (self-magnetostatic) field
# computation. This block takes no parameters.
Specify Oxs_Demag {}
# Runge-Kutta-Fehlberg ODE solver, with default parameter values.
Specify Oxs_RungeKuttaEvolve {}
# The following procedure is used to set the initial spin
# configuration in the Oxs_TimeDriver block. The arguments
# x, y, and z are coordinates relative to the min and max
# range of each dimension, e.g., 0<=x<=1, where x==0
# corresponds to xmin, x==1 corresponds to xmax.
proc UpDownSpin { x y z } {
if { $x < 0.45 } {
return "0 1 0"
} elseif { $x > 0.55 } {
return "0 -1 0"
} else {
return "0 0 1"
}
}
Specify Oxs_TimeDriver {
evolver Oxs_RungeKuttaEvolve
stopping_dm_dt 0.01
mesh :mesh
Ms 8e5 comment {implicit Oxs_UniformScalarField object}
m0 { Oxs_ScriptVectorField {
script {UpDownSpin}
norm 1
atlas :WorldAtlas
} }
basename example
comment {If you don't specify basename, then the default
is taken from the MIF filename.}
}
# Default outputs
Destination hystgraph mmGraph:Hysteresis
Destination monitor mmGraph new
Destination archive mmArchive
Schedule DataTable hystgraph Stage 1
Schedule DataTable monitor Step 5
Schedule DataTable archive Stage 1
Schedule Oxs_TimeDriver::Magnetization archive Stage 3
Schedule "Oxs_RungeKuttaEvolve::Total field" archive Stage 3
Figure 17.2: Example MIF 2.1file.