PFC 学习笔记-003
本文最后更新于:2022年9月15日 晚上
理解篇,PFC 6.0 编程
概述
上篇笔记说到PFC 5.0后的版本支持命令流、Fish和Python三种方式进行编程,这篇笔记就来谈谈我对PFC 6.0中这三种编程方式的理解。PFC建模其实就是通过编程建立不同类型的对象,这些对象有的是itasca系列软件通用的,如model,geometry,group等,有的则是PFC独有的,如ball,clump,contact等。通用的对象一般具有工具属性,用于辅助模型建立或者模型数据记录和导出等,PFC独有的对象则是我们建模的主体,它们的属性、行为和相互作用是我们编程的重点。
对于建模方式,通过在 PFC 默认的控制台console中一条一条地输入命令的方式显然不实际,一般是将命令按顺序写入文本文件(脚本)中,然后程序再自动按顺序运行;默认的控制台只能用于输入命令或者嵌入的Fish语句,对于python,PFC 6.0内置了ipython控制台,支持tab命令自动补全,使用起来很方便。
命令流建模
基本语法格式
命令流是PFC建模的核心方式,PFC中的通用对象和大部分独有对象只能通过命令流的方式来创建。PFC的命令在手册里都有详细的描述,使用时可以提前查阅。我个人认为这些命令可以粗略地分为两类,一类为操作类命令,即对一个对象进行某种操作,语法格式为 “对象 + 操作”,如:
1 | |
另一类为赋值类命令,即对对象的某一属性进行赋值,语法格式为 “对象 + 属性 + 值”,如:
1 | |
除此之外,PFC的大多数命令都具有层级结构,即一个命令下还有二级命令,典型的如:
1 | |
可以看到,model命令下有二级命令method和property,method又有二级命令deformability,二级命令还有自己的下一级命令,具体的层级关系可以查阅手册中的命令描述。这句命令可以这样理解:首先指定操作对象,即接触模型赋值表cmat的default槽,设置该槽的接触模型model;然后再将model作为操作对象,先对其defomability方法 (method) 进行设置,包括对emod和kratio进行赋值,接着对其fric属性 (property) 进行赋值。PFC 6.0支持行内代码提示,英文输入状态下,按下Ctrl+Space就会弹出命令提示。
在PFC中,命令流和Fish语言使用分号 “;” 进行注释;当一条命令用一行写不下时,可以在该行的末尾写上 “…” 或 “&”,然后在紧接着的下一行写该命令剩余的部分,也可以用这种方式来提升代码的可读性。
PFC代码中的符号必须是英文半角符号;”…” 或 “&” 只连接相邻的两行命令,不能跨越空行。
常用命令
group
为了方便操作和管理对象,通常会对具有某一共同性质的对象进行分组,这就是group命令的作用,group下还有二级命令slot,可以将同一组 (group) 中的部分对象分入不同的槽 (slot),进行更加细致的区分。
1 | |
range
在建模时,常常需要对一类对象中满足某一条件的对象进行操作,而不是对一类对象中的所有对象进行操作,仅限定要操作的对象范围,这就是range命令的作用,range命令在建模的过程中非常常用,使用时在需要限定范围的命令后加上range关键字和限定条件即可。range命令后的限定条件通常是某些属性范围,可以在手册中查看详细的描述,简单示例如下:
1 | |
history
为了观察模型的变化,我们需要在模型执行的过程中对我们关心的状态量进行监测,如颗粒或墙体的受力情况和位移情况等等。PFC除了提供通用的history命令外,还为每个对象提供了history命令,在监测时推荐后者,更加符合直觉,前者更适合用来对已有的history进行整体操作,简单示例如下:
1 | |
plot
plot是用于绘图的命令,但通过代码编写绘图程序比较繁琐,不直观,一般直接通过PFC的图形化界面来绘制history命令监测的数据的图像,plot命令通常用来导出数据。
1 | |
program
program命令用于控制程序的运行和调用:
1 | |
suppress关键字表示关闭命令回显,即被调用的文件内的代码不会在控制台中打印。
Fish 建模
Fish语言是PFC默认的脚本语言,可以与命令流进行相互嵌套,需要注意的是PFC中的这个Fish语言和命令行Fish Shell并不是一个东西,Fish语言的特点为:
- 1.大多数命令成对出现
- 2.变量声明无类型限制,且默认为全局变量
- 3.可以与命令流相互嵌套
- 4.无法创建
Itasca系列软件通用对象和大部分PFC独有对象,但基本可以读取和操作这些对象
基本语法
Fish语言的语法比较简单,容易上手,和Python有一点类似:
1 | |
Fish 方法调用
与常见的面向对象语言不同,Fish语言中某类对象调用其方法的方式为 “类名.方法(对象指针/id/name)”:
1 | |
Fish 语句与命令流嵌套
在PFC中,新建了一个Data file后,默认是写入命令流语句或者定义Fish函数,想要写入单独的Fish语句则需要将该语句用 “[]” 括起来;在Fish函数中使用命令流时,需要将命令流写在command ··· endcommand中。以下为简单的示例,仅作说明,实际使用时会复杂一些:
1 | |
此外,Fish函数中嵌套的命令不能是model restore或者model new,因为前者会用.sav文件中的Fish状态(函数、变量等)覆盖当前的Fish状态,后者则会清空模型内存,包括当前的Fish状态,两者都会和现有Fish状态产生冲突,因此不能在Fish函数中使用,这有点穿越到过去杀了自己的感觉 🤪。
不建议Fish语言与命令流多层嵌套,那样会降低程序的可读性和易维护性。
Fish 变量变化监测
前面说过可以用History命令监测PFC中对象的属性,但有时候我们需要用Fish函数来计算模型中的各种参数,最后得到结果也保存在Fish变量中,这时就需要对该变量进行监测,对此,PFC提供了fish history命令,简单示例如下:
1 | |
常用 Fish 方法
在PFC中,每一类对象都有自己的专属Fish方法,此外PFC还提供了一系列工具类库,如math、array、vector等,所有Fish函数在PFC的手册中都有详细的说明,使用时可以根据需求去查找参考。
1 | |
PFC独有对象的Fish函数大多是读写一致的,如ball.group()方法,它在等号左边就是写,即设置分组,在等号右边就是读,即读取分组。
Python 建模
PFC 6.0开始支持Python脚本,就个人使用经验来看,Python脚本适合用于程序的自动化运行以及程序运行结果数据的处理,对于模型的生成和模型的各种细节配置,还是得用命令流和Fish语言。和Fish语言一样,使用Python同样无法创建Itasca系列软件通用对象和大部分PFC独有对象,但基本可以读取和操作这些对象。
在 PFC 中使用 Python
Itasca 将其提供的对象和方法都封装在itasca这个包里,因此使用时需要先import这个包:
1 | |
当前的 Python 状态在执行了model restore或者model new命令后会被清空,要防止这种情况需要设置:
1 | |
这样就可以在使用model restore和model new命令的同时保留Python状态了,个人猜测Python状态可以通过以上命令独立于模型数据之外,而Fish状态始终和模型数据绑定,所以前者可以使用model restore和model new命令,后者则不行。
itasca 包中的类和方法
虽然Python不能创建大多数PFC中的对象,但itasca包中提供了一系列方法来获取和操作这些对象,这些方法可以分为类方法和对象方法,前者是对属于某个类的所有对象进行操作,后者则是对某个类的某个对象进行操作。
1 | |
与Fish不同,Python中提供的方法不是读写一致的,写命令通常以 “set” 开头。
Python 与命令流和 Fish 交互
在 PFC 中,Python 与命令流交互很简单,用一个command()方法就可以了,与Fish进行交互则通过fish这个类来实现:
1 | |
使用第三方库
Python 的强大除了语法简单外,还在于其丰富的第三方库,在ipython控制台中使用pip命令安装即可,如:
1 | |
PFC 6.0还内置了PySide2库,可以借助其编写图形化的交互窗口,自由度非常高。
Python 的使用场景
对于PFC提供的三种建模方式,个人认为命令流和Fish语言适合用来直接建模,而Python语言则适合对模型中的各种数据进行处理或者进行流程控制。我觉得典型的使用场景如下:
- 1.命令流或
Fish建模 - 2.
history/fish history监测数据 - 3.
plot export导出数据 - 4.
Python获取导出的数据并处理 - 5.根据处理的结果决定下一步操作
在PFC模拟中,通常是设定一组模拟参数,然后等这个模拟跑完后,再手动改另一组模拟参数,接着继续跑。两次模拟不是连续的,而且第一次模拟结束的时间是不确定的,这样在需要跑大量模拟时就比较费时间。
而通过Python就可以使用循环在一次模拟结束后根据设定的参数自动更改模拟参数,再接着跑,使不同的模拟过程连续。而且第二组模拟的参数也可以通过第一组模拟的结果数据来进行确定,这可以大大提高参数标定的效率。
总结
总的来说,PFC的三种建模方式各有优劣,需根据需要综合起来使用,比如生成位置随机的颗粒簇时,通过命令流就可以方便的实现,而通过Fish或者Python语言实现就比较麻烦;但对于需要一个一个地生成特定位置排列的颗粒时,使用命令的生成速度就远不如Fish或Python语言的生成速度了。
另外,学习这三种建模方式最好的方式就是阅读程序自带的手册,它是与软件配套的,一般不会出现命令不适配的情况,并且手册里提供了各种命令的详细用法,也有一些示例可以参考,这样上手会比上网找教程快很多,程序自带手册打开方式为点击软件菜单栏:
1 | |
默认是在软件内部打开手册,可以通过以下设置改为在浏览器中打开手册:
1 | |
最后,学习PFC建议参考官方在线手册[1]、关注一些技术博主[2]、购买相关的书籍[3]和加入相关的学习群[4],当然最推荐的还是学习官方的手册。
学习资料
- PFC 官方在线手册,如PFC 7.0 Documentation,注意版本对应 ↩
- 推荐微信公众号:超级大的 lobby ↩
- PFC 相关书籍:颗粒流(PFC5.0)数值模拟技术及应用 ↩
- QQ 学习群:
305143751、221013772↩