什么是遍历呢?百度百科的解释是:沿着某条搜索路线,依次对树(或图)中每个节点均做一次访问。在FLAC3D中,遍历即为沿着某条搜索路线,依次对模型中的每个单元(zone)、网格点(gridpoint)、节点(node)或是接触面节点等做一次访问,并根据具体需要使用特定的函数进行相应的操作,如遍历单元时采用zone.stress()函数提取单元的应力。
在FLAC3D中进行遍历时,其搜索路线是从被遍历对象的头部开始访问直至访问到对象的尾部,示意图如下。以遍历单元(zone)为例,程序首先访问ID最小的单元(图中黑色箭头所指),然后箭头往右移动访问下一个ID相邻的单元,直至指定范围内的所有单元都被访问一遍。
图1 遍历示意图
指针获取共有三种情形:(1)已知ID号,想要获取具体某个对象的指针;(2)已知对象位置,想要获取具体坐标处的指针;(3)执行遍历操作时,连续获取对象指针。前两种获取方式已在zone.state()函数解析与塑性区单元操作中的非付费部分进行了说明,读者可点击链接阅读。
进行遍历操作时,FLAC3D提供了两种方法以连续获取指针,本文以获取单元指针为例进行讲解。
该方法的框架如下,其原理是首先利用zone.head获取单元头部指针并记为z(指针的名字可以随便更改,例如p_z = zone.head),然后判断该指针是否为空,若不为空则进行进入loop循环并执行相关操作,然后利用zone.next()函数将指针切换至相邻单元(因此被我称为手动挡),当遍历到最后一个单元时,该单元已处于搜索路线末端,此时zone.next()函数将返回空指针,由此循环结束,示意图见图2。
z = zone.head
loop while z # null
**********
**********
z = zone.next(z)
endloop
图2 zone.head与zone.next()组合获取指针示意图
1.2.2 自动挡——loop foreach
该方法的框架如下,该框架能自动获取头部单元指针、自动切换指针以及自动结束循环,因此被我称之为自动挡。
loop foreach z zone.list
******
endloop
本文以6*6*6的立方体为例进行讲解,对其单元进行遍历并输出被访问单元的ID号,模型及分组情况见图3。
model new
zone create brick size 6 6 6 group 'a'
zone group 'b' range position-z 3 6
图3 模型及分组情况
fish def method_1
z = zone.head
loop while z # null
msg = "The current zone's id is " + string(zone.id(z))
io.out(msg)
z = zone.next(z)
endloop
end
@method_1
2.1.2 基于自动挡的全局遍历
fish def method_2
loop foreach z zone.list
msg = "The current zone's id is " + string(zone.id(z))
io.out(msg)
endloop
end
@method_2
局部遍历的一般做法是获取非空指针后,通过判断该指针是否位于某一范围内从而进行相应操作。本节以遍历获取分组a的单元ID为例进行讲解。
2.2.1 基于手动挡的局部遍历
fish def method_3
z = zone.head
loop while z # null
if zone.isgroup(z,'a') = 1 then
msg = "The current zone's id is " + string(zone.id(z))
io.out(msg)
endif
z = zone.next(z)
endloop
end
@method_3
2.2.2 基于自动挡的局部遍历
fish def method_4
loop foreach z zone.list
if zone.isgroup(z,'a') = 1 then
msg = "The current zone's id is " + string(zone.id(z))
io.out(msg)
endif
endloop
end
@method_4
1、本文以遍历单元为例,介绍了FLAC3D中的遍历操作,其框架结构是通用的。对于网格点、节点的遍历,读者需要根据自己需要去查阅说明书获取相关函数。
2、关于网格点的遍历,可参考新手向——FLAC3D6.0如何输出节点位移一文。同时,读者可以通过对单元遍历与网格点遍历找出出内置函数的命名特点,(例如zone.list与gp.list),这样查找函数时也更有的放矢。