立即注册找回密码

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

手机动态码快速登录

手机号快速注册登录

搜索

图文播报

查看: 855|回复: 0

[分享] FISH 学习笔记(一)

[复制链接]
发表于 2024-9-29 11:34 | 显示全部楼层 |阅读模式

登陆有奖并可浏览互动!

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录 手机动态码快速登录

×
学前须知

本笔记基于FLAC3D 7.0,笔记中某些例子在低版本FLAC3D上运行可能会报错,有的命令是7.0版本所特有,使用前请查看对应版本的帮助文档。
本笔记是本人学习过程的纪录,由于时间和精力原因,无法囊括帮助文档中FISH的所有内容,错误在所难免。如果大家在学习过程中发现疏漏,非常欢迎大家在评论区反馈。
本笔记大部分内容都是基于自己的理解,小部分借助了Google翻译,某些专业内容可能翻译不到位,也欢迎大家与我反馈。
最后,欢迎大家将我的笔记与您周围的人分享!
您的分享,是我持续分享的动力!
FISH介绍

FISH是Itasca公司为其产品专门开发的一种嵌入式编程语言(类似与ANSYS的APDL)。除了本书中提到的FLAC3D,它还被集成到Itasca公司开发的其它软件,如UDEC、3DEC、PFC2D/3D。
正如其名,FISH语言对于程序进程的控制就如同鱼在水中一样灵活。FISH开发的初衷是为了扩充软件中现有的功能及简化或无法通过GUI界面操作实现的功能,例如,参数化模型、控制模型运行、创建模型输出、监控结果和后处理模型运行等。
与其它仿真软件相比,Itasca的软件GUI界面是极其简略的,甚至可以说是有点“丑”。但这完全不妨碍其成为岩土工程界主流的仿真软件,其强大的生命力正得益于FISH。
没有任何编程经验的用户也可以编写简单的FISH程序。学习完本教程后,新手用户即可开始尝试使用FISH驱动FLAC3D进行简单的计算分析。当然,随着学习的深入,用户也可以使用FISH程序完成复杂的分析任务。
利用FISH语言编程时应该遵循由简到繁的原则,即程序结构应该按增量方式构建。用户在执行复杂的程序前应确保先前编写的程序和预期结果相符。FLAC3D内置编译器对FISH的语法和编程逻辑检查较少。因此,在程序应用于大规模分析之前都应在简单模型上进行测试。
初涉FISH

本节适用于运行过 FLAC3D(至少了解软件简单的操作流程)但尚未使用 FISH 语言的用户。为了方便接下来的学习,强烈建议大家手动敲一下本章所有代码。个人以为,学习编程语言的最好方式就是写代码复现结果,让自己在不断试错过程中成长。
FISH文件中主要含有两种结构:1)独立成行的FISH语句(inline fish),这些语句必须包含在一对中括号内;2)函数(function),该结构以 fish define 开头,以 end 结尾。函数可以调用其它函数,被调用的函数还可以进一步调用其他函数,依此类推。定义函数的顺序无关紧要,只要它们都是在使用之前被定义即可。
为了方便读者验证代码,后续章节代码结构如下:
model new               ;清空内存,开始一个新的分析

fish define 函数名(形参) ;形参可选
    变量定义
    功能定义
end

[函数名(实参)]           ;执行函数

program return          ;立即返回控制权给用户,在进行代码调试时,也可以在相应的位置插入该语句
值得注意的是:model new命令会清空内存。因此,对于一个完整的分析(有可能包含好几个文件),只在主控文件中含有model new命令。
简单的FISH函数

FISH语言中,如不对变量或者函数进行显式声明,它们默认是全局变量。为了避免出错,本笔记中所有的变量都进行了显式声明,本人也强烈建议大家都这样做。
下面的代码片段中,包含一个函数fname和两个独立成行的FISH语句([fname]和[ab])。函数中显式声明了两个局部(local)变量a和b并对其进行赋值,以及一个全局变量ab。
若程序执行成功,执行[fname]后将返回0,表示调用成功。由于变量ab是全局变量,因此ab可在函数外被调用,执行[ab]后返回5(2+3)。如果在函数外调用局部变量,如执行[a]将报错,局部变量只能在所定义的函数快中被使用
model new

fish define fname
    local a=2, b=3
    global ab=a+b
end

[fname]      ; 0(没有返回值,自动返回0)
[ab]         ; 5

program return
进一步,上述函数可修改为带有形参输入。跟其他编程语言不同,形参是临时变量,函数运行结束后自动消失,无需显式声明。
model new

fish define fname(a,b)
    global ab=a+b
end

[fname(2,3)] ; 0
[ab]         ; 5

program return
已知的杨氏模量和泊松比可以计算体积模量和剪切模量,他们之间的相互关系如下:
G=E/(1+\nu)
K=E/3(1-2\nu)
model new

fish define derive(y_mod,p_ratio)
    global s_mod=y_mod/(2.0*(1.0+p_ratio))
    global b_mod=y_mod/(3.0*(1.0-2.0*p_ratio))
end

[derive(5e8,0.25)] ; 0
[b_mod]            ; 3.33333e+08
[s_mod]            ; 2e+08

program return
作为全局变量的s_mod和b_mod可以作为后续FLAC3D命令行中的参数(需要包含在中括号中),将上一个例子修改为
model new

fish define derive(y_mod,p_ratio)
    global s_mod=y_mod/(2.0*(1.0+p_ratio))
    global b_mod=y_mod/(3.0*(1.0-2.0*p_ratio))
end

[derive(5e8,0.25)]

;全局变量s_mod和b_mod作为后续FLAC3D命令行中的参数
zone create brick size (2,2,2)            ;建立模型,创建一个2X2X2的网格
zone cmodel assign elastic                ;指定材料本构模型
zone property bulk [b_mod] shear [s_mod]  ;赋予材料参数
;未完待续

program return
带返回值的函数

如果调用函数后需要返回值,可通过以下两种方式:1)利用return语句;2)对函数名直接赋值
model new

;利用return语句
fish define fname(a,b)
    return a+b
end
[fname(2,3)] ; 5

;对函数名直接赋值
fish define fname(a,b)
    global fname=a+b
end
[fname(2,3)] ; 5

program return
如果表达式过长,为了方便阅读,除了可以设置中间变量外,还可以利用续行符“...” 。
model new

fish define long_sum
    local a1=1,a2=2,a3=3,a4=4,a5=5,a6=6,a7=7,a8=8,a9=9,a10=10

    ;设置中间变量temp
    local temp = a1+a2+a3+a4+a5
    global long_sum = temp+a6+a7+a8+a9+a10

    ;利用续航符 “...”
    global long_sum = a1+a2+a3+a4+a5+...
               a6+a7+a8+a9+a10
end

[long_sum]

program return
FLAC3D命令和FISH命令的联合使用

在上述计算体积模量和剪切模量代码中,是在FLAC3D的命令行中简单的嵌入了FISH函数。实际上,FISH函数中同样可以嵌入FLAC3D命令。为了实现这一目的,需将FLAC3D命令包含在command...endcommand代码块中。下面的例子就是通过简单的函数调用,创建了一个2X2X2的网格。当然,配合FISH的循环和控制命令,可实现更加复杂的建模和分析。
model new

fish define fname
    command
        zone create brick size 2 2 2
    endcommand
end

[fname]

program return
输入和输出

在FISH代码中可利用内置函数io.out(a)输出变量a中的内容到控制台。如果变量不是字符串,则会强制进行变量转换。如第一个代码
model new

fish define fname
    local a=2, b=3
    global ab=a+b
    io.out(ab) ; 5
end

[fname]        ; 0(没有返回值,自动返回0)

program return
控制台将输出5和0。配合下一章的字符串,输出的内容可更加丰富。
还可以利用内置函数http://io.in(s)在控制台进行参数输入。变量s是字符串变量,可用于提示输入的内容。如果输入的内容可被编译器解析成一数值(整数或实数),则函数返回相应的数值。如果输入的内容无法被解析成数值型(如字符或字符串),则输入的内容会以字符串的形式返回。可以借助内置的type()函数查看函数返回内容的类型。
model new

fish define fname
    local a=io.in("input a ")
    local b=io.in("input b ")
    global ab=a+b
    io.out(ab)
end

[fname]        ; 0(没有返回值,自动返回0)

program return
多文件管理

对于复杂分析,往往按照代码功能将代码拆分成若干独立文件,比如上述计算体积模量和剪切模量代码可以分成三个独立文件:1)主控文件main(一个完整的分析一般只含一个主控文件);2)专门存储fish命令的文件,一般包含所有的函数和全局变量申明。全局变量的申明可以通过函数结构,也可以是通过独立成行的FISH语句;3)和模型计算相关的文件,按功能可以分为模型的初始化(网格导入、指定材料,初始边界条件,全过程监控变量等)、各分析步中相关的操作(如开挖,堆载、施加支护等)、后处理等。
;主文件 main.f3dat
model new

program call "fish"
program call "initial"

program return
;fish文件 fish.f3dat
fish define derive(y_mod,p_ratio)
    global s_mod=y_mod/(2.0*(1.0+p_ratio))
    global b_mod=y_mod/(3.0*(1.0-2.0*p_ratio))
end
[derive(5e8,0.25)]
;initial.f3dat
zone create brick size (2,2,2)            ;建立模型,创建一个2X2X2的网格
zone cmodel assign elastic                ;指定材料
zone property bulk [b_mod] shear [s_mod]  ;赋予材料参数
;未完待续
再谈变量作用域

默认情况下,变量名和函数名都是全局变量。全局变量可以通过在控制台输入“fish list symbols”命令查看,或者在GUI界面的“FISH Global Symbols”面板查看。
全局变量可以在一个函数定义,然后在另一个函数中被使用。甚至,全局变量可以在一个文件中定义,然后在另一个文件中被使用,如本章的最后一个例子。局部变量的作用域仅限于定义它的那个函数。当函数被执行后,局部变量自动消失。
鉴于FLAC3D的编译器对于变量的检查有限,为了防止变量误用(默认情况下,当遇到未定义的变量时,编译器会自动创建一个全局变量而不报错)和方便调试,FLAC3D建议将软件自动创建全局变量的功能取消(可通过在主控文件中“model new”后添加“fish automatic-create off”实现)。这样,所有的变量名和函数名在使用时都需要进行显式的声明。
本文使用 Zhihu On VSCode 创作并发布

原文地址:https://zhuanlan.zhihu.com/p/583935058
楼主热帖
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册 微信登录 手机动态码快速登录

本版积分规则

关闭

官方推荐 上一条 /3 下一条

快速回复 返回列表 客服中心 搜索 官方QQ群 洽谈合作
快速回复返回顶部 返回列表