
做PFC模拟的同行应该都有同感PFC2D这软件第一眼看上去就像“一堆圆球在乱碰”可真正拿它干正事——比如模拟岩体、做边坡、看河谷下切引起的卸荷破坏——才发现每一步都是细节。这次分享的就是一个PFC2D 5.0下的人工合成岩体河谷下切算例。算例本身不复杂核心是用平行黏结模型生成一块“岩体”然后分级移除河谷部位颗粒模拟河流下切的卸荷过程观察应力重分布、边坡位移和裂隙发育。这个算例的意义在于它把离散元建模的完整链路走了一遍颗粒体系生成、微观参数标定、初始地应力平衡、分步开挖、动态监测和结果后处理。原案例备注“可以自行修改参数”我会把每一类参数改动后会发生什么也一并写清楚。适合正在入门PFC2D的岩土方向研究生也适合想用离散元做开挖卸荷类问题、但还没找到合适起点的工程师。1. 算例设计思路拆解1.1 “河谷下切”到底在模拟什么物理过程先别急着写命令把物理过程想清楚比什么都重要。河谷下切往工程地质上说就是河流在漫长地质时期里不断向下侵蚀把原本完整的地表削出深谷。这个过程在数值模拟里被抽象成一个已经处于重力平衡状态的岩体模型其上部一部分颗粒被“移除”或“弱化”模拟河谷不断加深的侵蚀作用。对岩体工程来说河谷下切真正关心三件事第一河谷两侧边坡会不会因为卸荷而开裂甚至失稳第二应力场怎么调整特别是谷底容易出现应力集中、坡肩出现拉应力和卸荷带第三位移发展到什么程度裂缝往哪个方向扩展。这三个问题在PFC里都直接可见因为离散元天生适合研究破裂问题不需要预先假定破坏面的位置这是有限元、有限差分软件很难替代的优势。河谷下切算例虽然是基础算例但它几乎覆盖了岩体开挖卸荷类的所有核心环节把这个算例吃透后面做边坡开挖、隧道进洞、基坑卸荷都顺了。1.2 为什么用PFC2D而不是有限元或有限差分我在实际项目中经常被问河谷下切用FLAC或者ABAQUS不就行了吗为什么非要上颗粒流答案是看你想回答什么问题。如果只需要知道宏观应力场怎么分布、位移大概多少量级连续介质软件完全够而且参数标定速度快得多。但一旦涉及“边坡会不会开裂”“裂缝从哪里起裂、往哪里扩展”“岩桥是怎么被剪断的”连续介质模拟就吃力了。有限元里裂缝要么靠单元删除要么靠内聚单元这些都是预设路径或者依赖网格PFC则没有这个限制颗粒之间的胶结是天然的材料属性应力超限就断开断开了就是真实的裂隙随机、自然、无需预设。再一个河谷下切本身就是断续的卸荷过程岩体的响应是非线性的存在大量不可逆变形和局部破坏。PFC2D用颗粒和黏结模拟岩体天生就能体现这种高度非线性的特征。当然代价也很直接计算慢、标定烦、结果离散性大。所以我一般建议能用FLAC快速摸清趋势的问题不必上PFC但要做破坏模式、裂隙扩展这类问题PFC2D 5.0就是性价比很高的选择。1.3 算例的整体技术路线这个算例的路线很清晰一共四步生成符合目标孔隙率和级配的圆形颗粒放在一个边界明确的模型区域里施加重力先不赋胶结让颗粒在摩擦作用下“沉降固结”得到一个无胶结但有初始应力的颗粒体系。在已经平衡的颗粒体系上赋予平行黏结模型相当于给颗粒之间“上胶”把散粒体变成人工合成岩体。在黏结模型下再次平衡确保初始地应力没有被胶结过程搞乱。这一步很多人会跳过实际上一跳就有问题后面详细说。分级删除河谷范围内的颗粒每删一层跑一段时间步让系统重新达到准静态记录位移、接触力、裂隙数等监测量。最后把河谷边坡的位移云图、裂隙分布、力链图导出来结合应力路径说明卸荷机制。整个流程用PFC2D 5.0操作配合少量FISH代码半天到一天内可以完成一个基准算例。下面我把每一步的关键细节拆开讲。2. 模型构建从零搭建人工合成岩体2.1 几何范围、颗粒级配和孔隙率怎么定模型几何范围直接决定计算量。河谷下切算例不需要太大范围几十米尺度足够反映边坡破坏模式。我这个算例里模型取值范围设为长60m、高40m左右颗粒半径0.3~0.5m半径比1.67这个级配既不会让颗粒数量爆炸又能保证破坏带有一定分辨率。颗粒数量大概在几千到一万出头PFC2D 5.0单机运行完全没压力。孔隙率是PFC2D里的关键参数。目标孔隙率设置过低颗粒几乎不能动弹生成时非常慢设置过高宏观力学参数明显偏软。我自己通常取0.12~0.15这个区间。要注意一点命令里写的目标孔隙率是基于颗粒面积占区域面积的比例实际生成后的统计孔隙率会和目标值略有偏差尤其是经过重力固结之后孔隙率会略微降低。所以生成完颗粒不要直接开始标定先用measure统计一下真实的孔隙率。颗粒半径的选择还有一层考虑黏结颗粒模型的宏观强度与颗粒直径有尺度关系。颗粒越大同等微观强度下模型宏观强度越低抗拉强度尤其敏感。这个性质在做参数标定时必须心里有数。2.2 接触模型与微观参数初选在PFC2D 5.0里颗粒之间有两种基础接触机制要区分清楚一种是线弹性接触模型只有力和位移关系没有抗拉能力用来模拟颗粒堆积体的挤压接触另一种是平行黏结模型接触处有有限尺寸的胶结“圆盘”能同时传递力和弯矩能承受拉力和剪力这就是我们用来模拟岩体胶结的关键。河谷下切算例里我用的标准组合先全模型使用linear接触模型做重力固结固结完成后再赋平行黏结参数。微观参数的初选参考值给一张表参数参考取值对应物理含义颗粒密度2600~2700 kg/m³岩体密度颗粒接触模量 emod200~500 MPa颗粒压密刚度法向/切向刚度比 kratio1.0~2.5控制泊松比摩擦系数 fric0.5~0.7颗粒表面摩擦平行黏结模量 pb_emod5~15 GPa量级近似岩体弹性模量pb_kratio1.0~3.0平行黏结剪切/法向刚度比pb_ten3~8 MPa抗拉强度pb_coh8~20 MPa粘聚力pb_fa25~35°胶结内摩擦角需要反复强调的是这张表给的是初筛值不是标定终值。PFC里的微观胶结强度不等于宏观抗压强度因为破坏不是所有胶结同时断开的而是渐进式的局部破坏引起的。宏观单轴抗压强度往往只有pb_coh的1/4到1/2具体比例取决于颗粒尺寸、孔隙率和胶结性质。所以严谨的做法是先按初值跑一个双轴压缩标定试验或者至少单轴试验对照目标岩体的弹模、泊松比、抗压强度、抗拉强度反调微观参数。原算例里如果没有附带标定文件我建议自己补一个否则后面河谷下切的破坏模式可能跟真实岩体对不上。接触模型的参数赋值在5.0里可以这样组织; 全模型默认接触类型 contactmodel linear property emod 3.0e8 kratio 1.5 fric 0.6 ; 赋予平行黏结 contactmodel parallelbond property pb_emod 8.0e9 pb_kratio 2.0 pb_ten 5.0e6 pb_coh 1.2e7 pb_fa 30这里我直接用emod方式给刚度比手动给kn、ks直观得多也方便做参数敏感性分析。2.3 初始地应力平衡最容易翻车的环节初始地应力平衡做得不好后面所有结果都是废的。河谷下切是个典型的卸荷问题卸荷前的地应力场必须合理否则你模拟的不是“下切”而是“在一个根本不存在的初始状态下瞎折腾”。标准的做法是两阶段平衡。第一阶段只有线性接触没有胶结施加重力后颗粒会互相挤压滑移形成一个密实稳定的颗粒堆积体系。第二阶段给所有接触赋予平行黏结把散粒体“冻住”变成岩体再继续循环到不平衡力收敛。第一阶段有个常见的坑如果直接用目标刚度和高摩擦系数去跑重力固结颗粒之间会产生巨大接触力可能导致模型“弹开”或者很难收敛。我的习惯是先给较小的摩擦系数如0.2跑几百步让颗粒落稳再把摩擦改成目标值继续循环。这个过程类似实际土体的自重固结需要耐心。第二阶段更要小心。给颗粒体系赋上平行黏结时接触位置如果有残余滑移趋势或者颗粒重叠量偏大胶结就会立刻承受较大剪力甚至一上来就断裂。判断标准很简单赋黏结前记录一下系统的最大不平衡力赋完黏结后它的量级不应该有突变。如果突变严重说明初始颗粒体系还没有真正稳定需要把第一阶段的收敛条件设得更严。收敛标准我一般看最大不平衡力与平均接触力的比值降到1e-3这个量级可认为准静态平衡。河谷下切过程中每一步开挖后也是这样判断的。3. 河谷下切核心实操3.1 下切方式直接删除颗粒与强度折减对比河谷下切在PFC里本质上是把河谷范围的颗粒从模型中移除。但“移除”的方式有讲究直接一条命令删掉一大片颗粒物理上等价于瞬间从模型中挖掉一块这在地质时间尺度上是不真实的因为河流下切是渐进的。瞬时删除会在开挖边界造成强烈的冲击效应表现为删除区域周围的颗粒瞬间获得很大速度甚至出现虚假的“爆裂”破坏。所以建议用分级下切把河谷下切过程分为若干步每步只删除一小层颗粒然后运行一定步数让系统重新平衡。这样既模拟了渐进的卸荷过程又避免了冲击效应。除了直接删除颗粒还有一种更细腻的做法把河谷范围内颗粒的平行黏结参数逐步折减从原始强度逐步降到接近零同时保持颗粒实体存在。这种“强度折减式下切”可以模拟风化、侵蚀、溶蚀等渐进弱化过程更接近岩体在河谷下切过程中遇水软化、卸荷损伤耦合的真实状态。代价是计算量大一些而且结果解释起来不如直接删除醒目。两种方式在工程意义上的差异是直接删除适合快速评估极限卸荷状态强度折减适合研究渐进破坏机制。原算例用的应该是前一种因为它的核心目的是给你一套完整的参考流程。我建议把两种都试一遍对比一下破坏位置和裂隙数量的差异这会让你对下切过程的力学本质理解更深。3.2 分步下切的FISH实现与命令流下面给出一段我常用的分步下切FISH代码框架。河谷宽度设为10m从地表高程20m向下切20m分5步每步切4m; 恢复已平衡的人工合成岩体模型 model restore synthetic_rock.sav ; 开启局部阻尼5.0默认开启这里显式声明 model damping local 0.7 ; 记录监测量 history name unbalanced add unbalanced history name crack_num add crack count ; 定义分步下切函数 fish define incise_valley local i 1 loop i (1,5) local ytop 20.0 - (i-1)*4.0 local ybot 20.0 - i*4.0 command ball delete range x -5.0,5.0 y [ybot],[ytop] cycle 3000 endcommand ; 每一步下切后暂停几步观察平衡进程 endloop end incise_valley ; 保存开挖后模型 model save valley_cut.sav这段代码有几个细节值得展开。第一河谷边界用坐标范围定义颗粒直径有一定随机性所以删除后河谷壁是锯齿状的这其实更接近天然岩体的粗糙边界不必刻意磨平。第二每步循环3000步不是拍脑袋。PFC2D 5.0里的时步是自动计算的几千步对应的时间很短但足以让局部冲击波传递出去。如果3000步后不平衡力还没有降到收敛标准就要增加步数。我的经验是把每步开挖后的循环时间设为同样长度最后看总的unbalance曲线如果每个台阶之间有明显的尖峰然后回落就说明节奏是合理的。第三如果想让下切方向更贴合真实河谷形态可以在范围定义里加入倾斜边界的判断条件比如河谷V字形的斜坡区域。这个稍微进阶一点用FISH遍历每个颗粒的坐标去判断是否在河谷多边形范围内即可。另外删除颗粒前一定要保存一个存档。不是开玩笑我在实际调算例中至少有三回因为删除范围写错把半个模型给删了没有存档就只能从头生成颗粒重新来一遍。3.3 监测与后处理要点河谷下切算例里最值得盯的监测量是这几项最大不平衡力历史判断每一步开挖后是否达到准静态裂隙总数历史看裂隙是开挖后一次性爆发还是逐步累积关键点位的位移历史比如河谷底部中心点、两侧坡肩点接触法向力分布观察谷底的应力集中PFC2D 5.0里直接内置了history命令记录这些量后处理则主要通过图形界面。位移云图选ball displacement用颜色标度看位移梯度裂隙使用crack显示可以直观看到裂隙是集中在坡肩还是坡脚破裂带大致角度多少接触力链图看力链粗细分布重点观察河谷底部有没有明显变粗的力链。一个技巧为了看清河谷边坡的破坏模式可以在模型上划分若干监测区域用FISH统计区域内裂隙数量。这比全模型crack count更有说服力因为你能定量说“坡肩区域50%的裂隙是在下切第3步之后出现的”这就是论文里需要的量化数据。后处理时最容易忽略的是坐标和比例尺。PFC默认输出的是颗粒中心位置的量位移云图实际上是颗粒位移的离散显示视觉上会显得“碎”这是正常的。不要认为是bug也不要试图把云图平滑得跟有限元一样——颗粒级的离散感本身就是离散元方法的特点反而能从里面看到真实的破裂局部化过程。4. 参数敏感性、常见问题与扩展思路4.1 不同参数改动后会发生什么原算例说“可以自行修改参数”这确实不是客套话。河谷下切算例的结果对参数非常敏感改一个量破坏模式就可能变一个样子。修改参数观察到的典型结果变化增大pb_ten坡肩更难开裂整体破坏滞后增大pb_coh剪切破坏减少倾向出现张拉破坏增大pb_emod弹性模量变大位移整体减小卸荷响应更“刚”增大kratio泊松比增大谷底更容易形成塑性区提高摩擦系数fric颗粒间残余强度提高大变形后残余承载力增加改变河谷坡比陡坡更容易出现坡肩张拉裂隙缓坡以剪切滑移为主增大颗粒半径裂隙带宽度变宽破坏模式可能从细密裂隙变成粗大破裂面最值得说的是颗粒半径的影响。同样的参数、同样的计算流程颗粒半径从0.3m改成0.6m裂隙的分布密度和扩展路径会明显不同。这是因为颗粒越大单个胶结断裂释放的能量越大局部化越明显。所以在对标真实工程时建议保持颗粒尺寸与关心区域的尺度关系恰当比如要研究2m宽的破裂带颗粒直径就不宜超过0.5m否则一个颗粒就能横跨整个破裂带。另一个容易忽略的是pb_fa胶结内摩擦角。PFC平行黏结的破坏准则是基于摩尔库伦的pb_fa控制胶结破坏后在剪切面上的摩擦分量。它主要是受过大剪切的“残余强度”影响对峰值强度影响不大但会显著改变破坏面和破坏深度。如果你模拟的岩体有明确的剪切破坏特征这个参数是最该去标定的。4.2 常见问题与排查技巧实录我把自己和身边同事在这些算例里踩过的坑整理成了一张速查表现象可能原因处理办法生成颗粒时粉末飞出、速度暴涨颗粒初始重叠过大或孔隙率过低调整目标孔隙率或增大颗粒半径范围先小步数释放多余重叠重力固结后不平衡力迟迟不收敛摩擦系数设得过高导致颗粒无法滑移到稳定位置先在低摩擦下固结再逐渐升高摩擦系数赋予平行黏结后立刻大量断裂赋黏结前系统有较高残余接触力延长第一阶段平衡时间检查unbalance量级删除颗粒后模型剧烈“爆炸”删除范围过大、一步到位分小步删除每步删除后循环足够步数河谷壁位移反向向谷内隆起可能是未模拟完应力重分布或阻尼不够导致惯性振荡增加循环步数检查阻尼设置裂隙满天飞、没有明显主破裂面pb_ten/pb_coh相对过高适当降低胶结强度让破裂趋于局部化模拟结果对随机种子非常敏感颗粒生成方式不同导致的随机性固定随机种子或多建几个模型做统计平均后处理看不到crack没有在绘图选项里启用裂隙显示plot item设置中勾选crack确保不为空集还有一个真实案例值得写出来有一次我帮一个学生调试河谷下切她那边单步删除河谷范围后边坡发生了大规模“溃坝式”破坏裂隙数量瞬间暴增几千条。我让她检查unbalance曲线发现删除前系统并没有真正达到准静态之前只是跑了固定步数就草草认为平衡了。把第一阶段和赋黏结后的循环步数分别增加到收敛标准再开挖破坏模式立刻变得合理。这个案例提醒我判断模型是否平衡要看不平衡力曲线而不是看“跑了多少步”。4.3 如何改成你自己的算例原算例给出的最大价值其实是参考框架真正要迁移到自己项目上通常需要改这几个地方一是河谷形态。改河谷宽度、下切深度、坡比只要修改ball delete的range范围就能实现。比如改成非对称河谷左侧缓坡右侧陡坡可以定义为一个梯形区域用两段矩形范围组合删除。这个改动十分钟就能完成但破坏模式会有本质不同。二是加入节理。人工合成岩体是完整的均质岩体但实际岩体里都是有结构面的。最简单的做法是生成颗粒后删除某个多边形区域内的平行黏结只保留线性接触相当于预设了一条无胶结的节理面。这个技巧非常实用可以用它研究节理产状对河谷边坡破坏模式的控制作用。三是模拟降雨或地下水弱化。通过FISH在特定深度范围内按比例降低pb_ten和pb_coh模拟水位上升导致岩体强度弱化这对工程非常贴合。四是做参数敏感性批量计算。把pb_ten、pb_coh、颗粒半径各设3个水平跑一组正交试验统计裂隙数量、最大位移、破坏模式画参数影响曲线。这也是写论文时最常用的套路原算例天然适合做这个。关于修改参数我的经验是每次只改一个量记录完整的档案名和修改内容否则三五次试算之后你根本分不清哪个模型对应哪组参数。这个习惯听起来很基础但实际项目里因为档案管理混乱重跑模型的案例太多了。写在最后的一个经验我个人真正从这个算例里收获到的不是某组参数能跑出一个漂亮结果而是对“卸荷响应”有了直观感受。河谷下切的本质不是加载是卸载岩体的响应和加载完全不一样。用PFC跑完这个算例你会亲眼看到下切之前坡体完整性很好每下切一层坡肩的裂隙就往深部多扩展一点谷底的应力集中越来越明显最终在某个下切深度出现贯通性破裂带。这种过程是弹塑性有限元很难直观呈现的。最后再分享一个小技巧跑这类算例时把模型保存频率调高一点每完成一个下切步骤存一个档。一方面方便回溯是哪一步出了问题另一方面你往往会在后处理时突然想回到第三步看看当时的应力场有档在手就完全不用重新跑。PFC的模型文件并不大多存几个不吃亏。