FISH是随ITASCA岩土工程数值分析全系软件发布的二次开发环境,FISH最先随FLAC系列程序一同发布,因此其名称起源于对“FLAC-ISH”的缩写。
FISH首先可视为是一款与Python、Matlab等解释性语言类似的开发语言,其基本特点是易于掌握,适用于简单意图的程序化实现,此外更是对ITASCA数值模型各类别构成进行访问、编辑、可视化等用户自定义需求提供系统完善的内置函数库。由此,FISH在很大程度上拓展了用户对数值模型的干预能力,同时也成为ITASCA软件区别于其他专业化岩土工程分析产品的优势性技术之一。目前而言,参数化网格模型创建、自定义模型可视化、力学参数动态调整等是较为常见的代表性FISH应用。
FISH研发意图和技术特点也同时决定其具有特定的局限性,具体表现在与其他开发平台或APP应用程序缺乏兼容条件,因此FISH开发环境具有较为封闭、开放性相对不足的缺陷。近年来,ITASCA数值分析程序在工程信息化建设与技术进步趋势驱动下进一步纳入了Python、C++等开发环境,丰富了对多层次专业应用需求的兼容解决能力,程序开放性也得到较大程度的拓展,如综合数值分析和人工智能技术在岩体力学特性及稳定性分析评价方面的应用。尽管如此,作为ITASCA软件原生二次开发环境,FISH与数值模型始终维持着最为密切的整合关系,因此依旧具有很强的生命力。
运算效率显然也是衡量开发语言优势性的基本指标之一。除语言自身特点外,目前运算效率评价还涉及到对计算机硬件资源特别是多线程并行运算的支持能力。早期FISH环境中内置的模型变量均依据单线程运算设计形成,或者说不支持多线程并行运算。因此,针对大规模分析模型条件下的FISH应用,无法充分发挥硬件多核并行计算资源应有的能力。现行版本FISH开发环境则通过优化数据多线程安全性,新增切片遍历(Splitting)以及多线程并行运算符(Operator)功能实现提升运算效率特别是对多线程并行计算的支持能力,相应的FLAC3D、3DEC、PFC版本分别为7.0、7.0和6.0。
本期内容将简单介绍几个相关概念:
1. 数据多线程安全性(Thread-Safe)
2. 切片遍历(Splitting)功能简介
3. 多线程并行运算符(Operator)简介
1、 数据多线程安全性
多核并行的实现难点在于难以保证数据参与并行计算时的精度,现行版本FISH为此对内置函数库特别是数值模型变量函数进行了并行安全设计。支持多线程运算的内置函数在程序应用手册中规范为如下格式:
a := zone.prop(z,s)
上述内置函数说明式中,放置于“=”号前的“:”符号指示了内置函数zone. prop ()支持多线程并行计算,属于多线程安全性变量。反之,若内置函数说明式中“=”前无“:”符号,则说明该内置函数不支持并行计算。
2、 切片遍历功能
ITASCA数值分析技术普遍采用数组、列表、容器等聚合类数据结构来管理模型中的模型对象,并提供序列编号或头指针用于访问其中的个体信息,典型如网格节点列表、单元列表等。
由数据结构决定,遍历操作也是利用FISH开发环境进行模型访问、控制的重要应用操作类型之一。新版FISH提供的切片遍历(Splitting)功能简化了对上述聚合类数据进行遍历操作的使用方式,同时在遍历运算过程中支持多线程并行运算,提高执行效率。
以下代码示例了采用以往遍历方式修改模型中所有单元的剪切模量:
def old_way
loop foreach zp zone.list
zone.prop(zp, 'shear') = zone.prop(zp,'shear') * 0.5
endloop
end
其中,zone.list为模型中的单元列表,zp则为指向单元列表的头指针。
采用切片遍历功能可将上述代码简写为:
;new way
[zone.prop(::zone.list, ‘shear’) *= 0.5]
其中,切片(Splitting)符号“::”表示对单元列表进行遍历访问,并利用多线程安全模型变量zone.prop()实现对每一单元剪切模量的修改操作。
切片(Splitting)遍历操作是FISH利用多线性并行运算提升计算效率的方式之一,适用于模型干预较为简单的情形。
3、 多线程并行运算符
采用FISH对模型进行复杂干预的情形,可综合采用多线性并行运算符operator同时结合切片功能实现提升效率。
多线性并行运算符operator的用途在于定义支持多线性并行运算符(operator)函数,语法规则为:
fish operator function(参数列表…)
可见,多线性并行运算符函数(operator)与普遍函数定义语法基本一致,区别在于采用运算符operator替代了define。此外,运算符函数还具有如下特点:
l 必须为运算符函数提供输入参数。或者说,在运算符函数定义时,必须声明一个或以上的参数;
l 不支持在运算符函数体中调用由fish define命令定义的普通函数,但允许调用其他的运算符函数;
l 运算符函数仅支持调用多线程安全性变量(如前述说明);
l 运算符函数体中要访问的模型对象需通过参数声明进行预定义。或者说,在运算符函数体中,模型对象无法被直接被访问。
以下通过案例示意运算符函数的定义与应用:
l 问题简述:利用FLAC3D程序模拟某物理介质的冻结过程;
l 分析条件:物理介质初始温度为50度,冻结温度温度为-200度;
l 冻结过程模拟:在热传导迭代计算过程中,调用运算符函数ground_freezing判断模型中单元的温度,若温度<=0,则对该单元的物理力学特性及其应力状态进行人为干预调整。
以下给出主要代码段:
fish operator ground_freezing(zone)
if zone.isgroup(zone,'frozen','state') then return 0
if zone.temp(zone) > 0.0 then return 0
freeze_zone(zone)
end
fish operator freeze_zone(zone)
local porosity = zone.fluid.prop(zone,'porosity')
local expansion = porosity * 0.09 * 1.0
local bulk = zone.prop(zone,'bulk')
local stress_inc = bulk * expansion ; Amount to increment stress
local bulk_inc = (8.96/2.16) * porosity ; Ratio of ice/water bulk * porosity
zone.prop(zone,'bulk') = bulk + bulk_inc
zone.stress.xx(zone) -= stress_inc ; Compressive negative!
zone.stress.yy(zone) -= stress_inc
zone.stress.zz(zone) -= stress_inc
zone.group(zone,'state') = 'frozen'
end
model solve time-total [360*24*60*60] ... ; 1 year (360 days) of heating.
mech ratio 1e-3 ... ; Relax mech solve requirements a bit for speed.
fish-call -100 ground_freezing([::zone.list]) ; Call ground freezing
其中,ground_freezing、freeze_zone为用户自定义运算符函数,在利用model solve命令执行迭代时动态调用运算符函数ground_freezing遍历模型中所有单元,同时依据冻结状态及温度条件对单元性质进行编辑修改。
完整代码可通过百度网盘下载:
链接:https://pan.baidu.com/s/1mvKOdufugG7hcEk8a0ZL0w
提取码:kzqi
图1基于FLAC3D的冻结工法模拟
参考文献:
[1] FLAC3D 7.0 Manual. Itasca Consulting Group, Inc.