先说结论:同一份 PFC 数据,换个画法——从"一堆球"变成"一整块裂开的材料"。单轴压缩、巴西劈裂、直剪三个算例的破坏形态,现在都能第一眼读出来。产物是一个零依赖的 HTML 文件,双击打开就能缩放、切图层、导出任意分辨率的高清图。
先看图。这是三个算例的加载终态,都是 PFC2D 的平行粘结试样。
图1 单轴压缩。两条主裂缝从端部斜着贯穿,中间夹一条交叉的破坏带。
图2 巴西劈裂。圆盘正中一条竖直劈裂缝,从顶到底贯通,试样裂成两半。
图3 直剪。一条水平剪切带贯穿试样中部,上下两个剪切盒的错动在图上直接看得见。
三张图有个共同点:画面里没有颗粒。
下面把做法拆开讲。核心其实只有一个问题——怎么让一万个圆盘看起来不像一万个圆盘。
做离散元的人对自己算的东西很熟:这是 9303 个圆盘,那是两万多个接触。但把图拿给别人看的时候,对方不熟,他看到的只是一堆球。
我想要的观感很明确:一整块材料,和它是怎么裂的。
最直觉的做法是"把球画出来,断键的地方自然就裂开了"。这个想法很自然,但是错的。我拿真实数据核了一下——算每个接触两端球心的距离,减去两个半径之和,得到"重叠量":
看第三行。断掉的键,两端的两颗球仍然是互相压进去的,重叠量和完好键几乎一模一样。
原因不难想:密实堆积本来就是靠颗粒互相咬合撑起来的。加载之前它们就压在一起,断了之后,周围的颗粒还把它们夹在中间,位置几乎没动。
所以,只要把一万个圆盘摞起来,它永远是一整块无缝的实体,断键的地方根本不会裂开。想让裂缝出现,就必须换一套完全不同的做法。
图4 同一个算例,把"颗粒"图层打开的样子——立刻又变回一堆球。默认是关掉的。
既然"缝"不会自己出现,那就得自己决定哪里是缝。
怎么决定?看胶结。如果两颗球之间还有一条完好的键,它们就算"连在一起"。把所有完好的键想成一根根绳子,绳子两头拴着球——顺着绳子走,能互相走到的球,就归为同一块。
这在图论里叫连通分量,实现上用一个并查集,两万条键扫一遍就出来了。单轴算例最后切出 300 块。
切开之后,每一块整体填成一个实心区域——块内部不画球、不画颗粒,就是一整块材料。块与块之间才留缝。
图5 只留下"材料碎块"图层的样子。深浅不同的区域就是不同的块,中间黑色的就是裂缝。右下方那一大片是最大的块,占了全试样 45%;左侧那片黑色破碎区,是几百个小块挤在一起。
图5 这张,其实就是整个方法的核心。试样不再是一堆球,而是一块被切成若干块的料。
切块只是第一步。真正磨人的是下一件事——每一块内部必须绝对无缝。
这话听起来是废话,但做不到的话,材料表面会布满针尖大的黑点,整体读起来还是"一堆颗粒",前面切块的功夫全白费。为了做到无缝,有三道工序。
第一道:把同一块内相邻的球"桥"起来。
球是圆的,两个圆相接的地方总会留一个凹口。做法是在相邻球之间填一个有面积的四边形,把凹口补上。判据是"同块 + 几何近邻",而不是"有完好键"——这一点很关键:一条键断了,两头的球仍然可能通过别的路径连在同一块里,它俩之间如果没有接触,就会露出一道细缝,在画面上就是一个小黑点。
按这个判据铺桥,单轴算例的桥从 19353 条增加到 21546 条。
第二道:近邻的判定范围要放宽。
这道更隐蔽。实测发现,有 1712 条完好键的两端球心距离,竟然大于两球半径之和——键还连着,球已经被拉开了,最远的拉到了 1.177 倍。如果近邻的判定卡得太紧,这批球对就会被漏掉,那些地方照样露缝。
第三道:用三角剖分把孔隙填掉。
颗粒堆积本身就有约 10% 的孔隙。这些孔隙是真实存在的,但画面上它们会直接透出背景色——一堆黑洞。做法是对每一块内所有球心做一次 Delaunay 三角剖分,把三角形的并集和圆一起填。三角形的边长还做了筛选,太长的不要,这样它不会跨过块的凹口、把本该分开的地方连起来。
三道工序做完,块内部才是干净的一整片。
块切好了,裂缝自然就有了——但只对了一半。
断裂的球对分成两种:
这两种加起来才是一张完整的破坏图。只画第一种,会漏掉将近一半的损伤——而且漏掉的恰好是张开最明显的那一批。
再叠上 DFN 记录的微裂纹。这里有个容易踩的取舍:破坏信号要用裂纹文件,不能用接触的键状态。同一个单轴算例,接触表里能查到的断裂键只有 1711 条,而 DFN 里有 3859 条——差的那些,是因为球已经分开、PFC 不再把它们算作接触了。
裂纹按类型分了两色:拉裂的用浓一点的橙红,剪裂的用淡一点的橙黄。直剪算例里剪切裂纹的数量是拉伸的 4 倍多,两种颜色分开之后,破坏的走向一眼就能读。
图6 只留下 DFN 裂纹图层的样子。橙色短划就是每一条记录下来的微裂纹,密度高的地方连成带——也就是图1里那些裂缝的所在。
上面几步对应到画面上,是从下往上这么叠的:
每一层都可以单独开关,这也是为什么调参很快——颜色不对就关掉纹理层看纯色,缝太粗就只留裂纹层看损伤分布。
顺带一提,图里的"材质"全部是程序化生成的,不依赖任何外部图片:加载板是各向异性的拉丝钢,球面用逐像素的法线做朗伯光照,岩石表面则是多个随机方向的平面波叠加出来的斑驳。最后这一项要保证能无缝平铺——波的方向必须是整数格点,否则纹理拼接的地方会出现一道突兀的直边。
一个 HTML 文件,双击就开,不联网、不依赖任何东西。可以缩放、平移、悬停查任意一颗颗粒,可以单独开关每一个图层,也可以一键导出 1600 到 4K 任意分辨率的图,比例尺会跟着一起缩放。
三个算例的文件都在 700 KB 左右,直接发给别人就能看。
这套东西已经整理成了一个技能(pfc-scene-render)。换个算例,只要指一下算例目录,三个命令跑完就出图——单轴、巴西、直剪这三个都是同一套代码,没有为任何一个算例写过特例。
范围说明:三个算例都是 PFC 2D 的平行粘结试样,二维平面应变、单位厚度口径。画面里的配色与纹理是为了观感做的艺术处理,不携带定量信息;要读数请用后处理技能出的云图与曲线。
fracture)与接触状态量的定义pfc-crack-export 等)—— 本文用到的裂纹 CSV 即由其导出