oommf核壳结构建模的一些问题

img

oommf建模结构如图

问题描述

1.用大小晶粒嵌套结构定义多个晶粒
2.在一个mif文件中同时设置不同区域不同各向异性能(未解决)
3.各项异性能如何使各易轴随机取向(未解决)
4.for循环定义666个晶胞

只写了一部分的代码
set pi [expr {4*atan(1.0)}]
set mu0 [expr {4*$pi*1e-7}]

Parameter cellsize 2set cellsize [expr {$cellsize*1e-9}];

Parameter RandomAnisotropy 0.0;

parameter length 24e-9
parameter grainsize1 24e-9
parameter grainsize2 21e-9
parameter boundarysize 1.5e-9

Specify Oxs_BoxAtlas:atlas {
  xrange {0 6*grainsize1}
  yrange {0 6*grainsize1}
  zrange {0 6*grainsize1}
  name grain1
}

for {set k 0} {$k<6} {incr k} {
  for {set j 0} {$j<6} {incr j} {
    for {set i 0} {$i<6} {incr i} {
        set atlas_string_grain2 [subst {Oxs_BoxAtlas {
              xrange {[expr {$i*$length+boundarysize}] 
                      [expr {$i*$length+$grainsize2+boundarysize}]}
              yrange {[expr {$j*$length+boundarysize}] 
                      [expr {$j*$length+$grainsize2+boundarysize}]}
              zrange {[expr {$k*$length+boundarysize}] 
                      [expr {$k*$length+$grainsize2+boundarysize}]}
              name   {grain2_$i$j$k}
         }}]
        lappend grain2_list "atlas" $atlas_string_grain2

Specify Oxs_MultiAtlas:boundary [subst {
  $grain2_list
  atlas grain1
  xrange {0 6*grainsize1}
  yrange {0 6*grainsize1}
  zrange {0 6*grainsize1}
}]




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

不知道自己的解决方案是不是有问题

您好!我们都知道在微磁模拟中,有限差分法会将整个空间容器(atlas)使用网格(mesh)划分为尺寸相同的单元格(单元格的中心位置表示空间坐标),接着根据单元格的空间坐标来划分不同的区域,于是可以方便的根据区域名称来为一个范围内的单元格分配磁性参数,注意,对于无磁性的单元格(即缺陷),只需将其饱和磁化强度(Ms)设置为0即可。对于初始磁化的设置也有讲究:在进行动态模拟之前,我们需要将磁体系弛豫到亚稳态,并将该状态保存成一个文件作为后续模拟时的基态磁化状态。

对于问题中的核壳模型来说,可以看到是由6X6X6个晶粒结构组成的微磁模型。
首先,假设这个模型中只有一个晶粒,想必题主对于划分单个晶粒的核壳区域是没有任何问题的,无非就是使用一个 if 语句去判断每一个单元格的空间坐标是属于核区域还是壳区域,由此所有单元格便分为了两类,接着便可以根据单元格所在的区域来整体分配磁性参数!
那么,对于这种单个晶粒重复排列多次的模型来说,只需利用一个 “ 取余 ” 的运算,便可以将其他晶粒中的单元格空间坐标换算到单个晶粒中,然后和上面情况一样处理即可,示例如下:


##########################划分模型的物理尺寸和单元格尺寸##########################

#容器的尺寸,即6*6*6个晶粒组成的微磁模型总尺寸:144*144*144nm
Parameter atlas_x 144
Parameter atlas_y 144
Parameter atlas_z 144
set atlas_x [expr {$atlas_x * 1e-9}]
set atlas_y [expr {$atlas_y * 1e-9}]
set atlas_z [expr {$atlas_z * 1e-9}]

#单个晶粒的尺寸:24*24*24nm
Parameter grain_x 24
Parameter grain_y 24
Parameter grain_z 24
set grain_x [expr {$grain_x * 1e-9}]
set grain_y [expr {$grain_y * 1e-9}]
set grain_z [expr {$grain_z * 1e-9}]

#晶粒的核尺寸:22.5*22.5*22.5nm
Parameter coreRegion_x 22.5
Parameter coreRegion_y 22.5
Parameter coreRegion_z 22.5
set coreRegion_x [expr {$coreRegion_x * 1e-9}]
set coreRegion_y [expr {$coreRegion_y * 1e-9}]
set coreRegion_z [expr {$coreRegion_z * 1e-9}]

#晶粒的壳厚度:1.5nm
Parameter shellRegion_thick 1.5
set shellRegion_thick [expr {$shellRegion_thick * 1e-9}]

#根据每一个单元格的坐标分配到核区域,和壳区域
proc setRegions { x y z } {
    global grain_x grain_y grain_z
    global coreRegion_x coreRegion_y coreRegion_z
    global shellRegion_thick
    
    #将整个微磁模型所有单元格的位置坐标都换算到相对于一个晶粒内的坐标
    #即rx,ry,rz的值都被限制在一个晶粒尺寸范围内
    #如此,只需按照单个晶粒的核壳分配规则,就可实现按规律将整个微磁模型所有单元格分配至所在的核或壳区域
    set rx [expr {fmod($x,$grain_x)}]
    set ry [expr {fmod($y,$grain_y)}]
    set rz [expr {fmod($z,$grain_z)}]
    
    #单元格在单个晶粒中核壳的分配规则
    if {$rx >= $shellRegion_thick && $rx <= ($shellRegion_thick + $coreRegion_x) &&
        $ry >= $shellRegion_thick && $ry <= ($shellRegion_thick + $coreRegion_y) &&
        $rz >= $shellRegion_thick && $rz <= ($shellRegion_thick + $coreRegion_z) 
    } {
    #分配属于核区域的单元格
    return 1
    } else {
    #分配壳的区域
    return 2
    }
    #其余位置点定义为universe
    return 0
}

#定义容器
Specify Oxs_ScriptAtlas:atlas [subst {
    comment "使用脚本函数定义模型"
    xrange { 0 $atlas_x }
    yrange { 0 $atlas_y }
    zrange { 0 $atlas_z }
    regions {coreRegion shellRegion}
    script_args rawpt
    script setRegions
}]

#单元格尺寸:1.5*1.5*1.5nm(单元格尺寸小于交换长度Lex)
Parameter cellsize_x 1.5
Parameter cellsize_y 1.5
Parameter cellsize_z 1.5
set cellsize_x [expr {$cellsize_x * 1e-9}]
set cellsize_y [expr {$cellsize_y * 1e-9}]
set cellsize_z [expr {$cellsize_z * 1e-9}]

#定义网格尺寸
Specify Oxs_RectangularMesh:mesh [subst {
    cellsize {$cellsize_x $cellsize_y $cellsize_z}
    atlas :atlas
}]

##########################划分模型的物理尺寸和单元格尺寸##########################

接着就是根据区域名称分配磁性参数的示例:


##########################指定材料的磁性参数和磁性能量##########################

#定义一个标量场对象来为不同区域分配交换系数
Specify Oxs_AtlasScalarField:exchange {
    atlas :atlas
    default_value 0
    values {
    coreRegion 13e-12
    shellRegion 13e-12
}
}
#定义交换能,其中的交换系数是逐单元格指定的
Specify Oxs_ExchangePtwise {
    A :exchange
}

#定义退磁能
Specify Oxs_Demag {}

#定义一个标量场对象来为不同区域分配标量值(单轴各向异性常数)
Specify Oxs_AtlasScalarField:anisotropy_K1 { 
    atlas :atlas
    default_value 0
    values {
    coreRegion 3.6e6 
    shellRegion 4.5e6
}
}
#定义一个矢量场对象来为不同区域分配矢量值(各向异性的方向)
Specify Oxs_AtlasVectorField:anisotropy_axis {
  atlas :atlas
    values {
    coreRegion {0 0 1}
    shellRegion {0 0 1}
}
}
#定义单轴各向异性能
Specify Oxs_UniaxialAnisotropy {
  K1 :anisotropy_K1
  axis :anisotropy_axis
}

#定义核区域的饱和磁化强度Ms(1.31T=1041450A/m)
Parameter coreRegion_Ms 1041450
#定义壳区域的饱和磁化强度Ms(0A/m)
Parameter shellRegion_Ms 1041450
#定义一个标量场对象来设置不同区域的饱和磁化强度
Specify Oxs_AtlasScalarField:regions_Ms [subst {
    atlas :atlas
    comment "只有核和壳有磁性,其他区域无磁性"
    default_value 0
    values {
    coreRegion $coreRegion_Ms
    shellRegion $shellRegion_Ms
    }
}]

#定义阻尼系数
proc setAlpha { x y z } {
    #####TODO#####
    return 0.1
}
#定义一个标量场对象来设置不同区域的阻尼系数
Specify Oxs_ScriptScalarField:regions_alpha {
    script setAlpha
    script_args rawpt 
    atlas :atlas
}

##########################指定材料的磁性参数和磁性能量##########################

后面省略外加磁场,演化器和驱动器,保存文件相关的设置。。。