1 引言
Itasca软件引入了Python的多线程处理(multi-thread processing)概念,可以使用多线程的FISH(Multi-threaded FISH-Splittling),它通过使用list, splitting和operators来实现多线程处理,任何list(zones, gridpoints等)的循环被split成不同的块,然后把它分配到计算机上所有可得到的处理器来并行运算,因而增加了整体的运行速度。下面简要讨论了这些概念。
2 Splitting
传统的循环方法是使用list:
def list_method
loop foreach zp zonelist
zone.prop(zp,'shear') = zone.prop(zp,'shear')*0.5
end_loop
end
如果使用多线程方法,则可以表示为:
[zone.prop(::zone.list, 'shear') *=0.5]
这行代码与上面使用loop循环语句的作用是相同的,意思是对zone.list内的每一个单元的‘shear'值在原来值的基础上乘以0.5。操作符"::"在Python语言中称为“切片”,前一个冒号表示"开始",后一个冒号表示"结尾"。"*= 0.5"是Python的乘法运算符,意思是把原来的值乘以0.5然后赋值给新的变量。下面演示的例子首先给出了模型的材料参数值,接着使用旧的FISH语言改变模型的剪切模量值,最后使用新的FISH语言再次改变模型的剪切模量值。整个过程封装在Python中,完整的代码如下所示:
import itasca as it
it.command ("python-reset-state false")
it.command("""
model new
model large-strain off
zone create brick size 10 10 10
zone cmodel assign mohr-coulomb
zone property bulk 65000 shear 30000 density 2.0
zone property cohesion 10 friction 34 tension 1.0
""")
z = it.zone.find(1)
print( '模型初始的剪切模量:' + str(z.props()['shear']))
# 使用list方法
it.command("""
define old_way
loop foreach zp zone.list
zone.prop(zp,'shear') = zone.prop(zp,'shear')*0.5
end_loop
end
[old_way]
"""
print('模型第一次改变剪切模量:' + str(z.props()['shear']))
# 使用多线程方法
it.command("""
[zone.prop(::zone.list, 'shear') *=0.5]
""")
print('模型第二次改变剪切模量:' + str(z.props()['shear']))
上述代码的运行结果就象期望的那样:
(a) 模型初始的剪切模量:30000.0
(b) 模型第一次改变剪切模量:15000.0
(c) 模型第二次改变剪切模量:7500.0
3 Operators
operator是一个能被splitting的多线程FISH函数,通过fish operator,用户可以自定义一个函数,然后这个函数就可以使用多线程的优点。
(1) 下面的代码初始化模型的有效应力:
fish operator ini_stress(z, modelname)
if zone.model(z) == modelname then
local pp = zone.pp(z)
zone.prop(z,'stress-xx-initial') = zone.stress.xx(z) + pp
zone.prop(z,'stress-yy-initial') = zone.stress.yy(z) + pp
zone.prop(z,'stress-zz-initial') = zone.stress.zz(z) + pp
zone.prop(z,'stress-xy-initial') = zone.stress.xy(z)
zone.prop(z,'stress-yz-initial') = zone.stress.yz(z)
zone.prop(z,'stress-xz-initial') = zone.stress.xz(z)
endif
end
[ini_stress(::zone.list, 'p2psand')]
(2) 下面的代码设置块体之间的粘结力:
fish operator set_cohesion(cx)
if block.subcontact.prop(cx,'tension') < 0
block.subcontact.prop(cx,'tension') = 0.0
endif
block.subcontact.prop(cx,'cohesion') = block.subcontact.prop(cx,'tension')*_coh_ten_ratio
end
[ ]
4 threads
除了上面的用于循环的多线程外,program threads命令可用于计算和绘图的多线程。默认情形下是automatic,手册中说,“如果超线程处于激活状态,这可能是实际可用处理器和内核数量的两倍”,不太确切理解这句话的含义,由于这个命令没有返回值,因此不知道如何检查实际可应用的线程。此外,如果引入multiprocessing模块,使用Process是否能加速块体(BBM)的生成速度。
import multiprocessing
from multiprocessing import Process
max_cores = multiprocessing.cpu_count()
[global cores = {max_cores}]
program threads [cores]