ARTICLE · 1040772
AI 技能自动化标定:七种常见岩石的 PFC 参数
AI 技能自动化标定:七种常见岩石的 PFC 参数
结论先行:岩石的 PFC 参数标定这件事,现在可以交给 AI 了。我做了个技能:给它目标 c 和 φ,它自动生成算例、无头跑完、拟合包线、判断下一步调什么参数、再跑一轮——直到命中目标。用它把 砂岩、灰岩、煤岩、页岩、泥岩、千枚岩、花岗岩 七种常见岩石都标了一遍,21 项指标 19 项落在 ±5% 内。其中两种(泥岩、花岗岩)一轮就命中。换个目标值改个 json 就能重跑。
1. 一、为什么要自动化
岩石要做数值模拟,得先把微观参数对齐到真实力学性质。工程上描述岩石强度用的是 Mohr-Coulomb 包线的两个参数:内聚力 c 和内摩擦角 φ。让 PFC 模型跑出来的 c、φ 对上目标值,这套参数才算能用。
麻烦在于标定是个反复试错的过程:
估一组参数 → 跑 → 读结果 → 差多少? → 调参数 → 再跑 → ... 而现在单次"跑"的成本并不低。要定 c 和 φ 需要一条包线,一个试样就得跑三档围压(σ₃ = 5 / 10 / 20 MPa)才能拟合。加上调参迭代,一组岩石三五轮很正常。
七种岩石做下来就是几十次运行。 手工做的话,光是生成脚本、盯运行、扒数据、算包线这些机械劳动就够耗掉几天。
这些活儿全都可以自动化。
2. 二、技能长什么样
把流程拆开看,每一步都是明确的机械操作:
按目标生成三档围压的算例脚本 无头运行,抓日志判断有没有报错 从 history 文件里提取峰值应力,最小二乘拟合出 c、φ、R² 对照目标算偏差,算出下一组参数该调什么 重复直到命中,输出定稿参数
这套流程已经固化成了技能。整个技能做的事情,一张图说完:

输入是一个很短的 json,只写你想要岩石具有的宏观性质:
json{"lithology":"砂岩","target":{"E_GPa":15.0,"c_MPa":15.0,"phi_deg":35.0},"sigma3_MPa":[5,10,20],"strainRate_per_s":0.05}输出是可直接用于建模的微观参数:
json{"emod_Pa":9.491e9,"pb_emod_Pa":7.588e9,"pb_coh_Pa":17.18e6,"pb_ten_Pa":51.49e6,"pb_fa_deg":48.0,"fric":0.437}用法就是一句话:告诉它"把砂岩标到 c=15 MPa、φ=35°"。剩下的生成、运行、读数据、判断、再跑,都是自动的。
3. 三、技能里封装的核心规律:φ 只认 pb_fa
技能能做到"一两轮就收敛",关键不在自动化本身,而在它内置了一条实测得来的规律。
早先按常规经验,内摩擦角 φ 是跟着颗粒摩擦系数 fric 走的。按这个思路标了两组,都不对:
第一组是灰岩。目标 φ=40°,按 fric 插值取了 0.604,线性插值算出来应该是 40.1°,实测 43.13°,高了 3°。当时猜是胶结强度低造成的,没深究。
第二组是煤岩,它把这个猜测直接否掉了。煤岩是七个里最软的一组,胶结强度只有基准的六分之一——如果"胶结弱→φ高"成立,它的 φ 该高得离谱。实测 21.18°,是七种岩性里最低的。
把数据点摆在一起,真凶就露出来了:
fric | pb_fa | φ | |
|---|---|---|---|
| 灰岩 | 60.4 | 43.13° | |
| 煤岩 | 22.7 | 21.18° |
看灰岩和探测组第三行:fric 差了 0.1,但 pb_fa 只差 0.4,两行的 φ 几乎相同(43.13 vs 42.66)。而煤岩的 pb_fa 掉到 22.7,φ 就跟着掉到 21.18°。
φ 跟的是 pb_fa,不是 fric。
对探测数据做最小二乘,得到一条很干净的直线:
φ = 0.5305 · pb_fa + 10.79 反过来: pb_fa = (φ − 10.79) / 0.5305 三点验算的残差都在 0.1° 以内:

这条反算式就是技能能一两轮收敛的原因——有了它,φ 不需要试错,直接按目标值反解 pb_fa 就行。早期的砂岩和灰岩各花了 3 轮,就是因为当时还不知道这个关系。
4. 四、自动化到了什么程度
判断一套标定流程是不是真的好用,得看它在没见过的目标值上表现如何。有两个极端案例。
一个是泥岩,目标 φ=28°,比探测组直接测到的下界(32°)还低。用反算式外推,pb_fa 取 32.5°,结果一轮命中:φ 实测 28.51°、c 实测 8.26 MPa、E 实测 8.04 GPa,三项全中。
另一个是花岗岩,目标 φ=50°,反解出来 pb_fa = 73.2°,比拟合区间的上界外推了 22°。这是相当激进的外推,我原本没底。
实测结果:
pb_fa | 实测 φ | ||
|---|---|---|---|
| 49.11° |
误差 0.51°,花岗岩同样一轮命中。
两个方向的外推都成立,说明这不是碰巧拟合了一条线,而是抓住了真实的控制关系。效果直接体现在轮数上:
| 1 | |||
| 1 |
这就是"知识固化"的价值:把踩坑得来的实测规律写进技能,后面每一组岩石都受益。前面两组各花 3 轮,后面两组一轮收工。
5. 五、技能还顺手处理了一个工程坑
除了力学规律,自动化还得处理"跑得动、跑得完"的问题。
双轴加载脚本原本有两条停机条件:轴向应变到上限停,或者偏应力跌破峰值的 30% 停。低围压试样脆,第二条触发得早,一例五六分钟就跑完。
但高围压试样更韧,偏应力跌不到峰值的 30%,第二条永远不触发,于是一路往 6% 应变的上限跑。而 PFC 在峰后破碎阶段会急剧变慢:

时间步长没变,纯粹是碎块和游离颗粒让邻居搜索变重了。实测一例跑到 ε₁=1.4% 时速率已经掉到 30 步/秒,按这个速度跑满要两个多小时。更麻烦的是它看起来像卡死——日志还在长,进程还活着,就是不结束。
技能里给加载脚本加了第三条停机规则:
if eps1 > eps1_peak + 0.004 stop_flag = 1 endif 偏应力越过峰值之后,再走 0.4% 应变就停。
这样改是安全的:标定只取峰值偏应力(定 c、φ)和弹性段斜率(定 E),两个量都在峰值前就决定了,跟什么时候停机无关。
补上之后单例耗时回到 5–13 分钟,七种岩性才跑得完。
6. 六、七种岩石的标定结果
最后跑完全部七组,21 项指标里 19 项落在 ±5% 内:
七条包线摆在一起是这样:

唯一超出 ±5% 的是煤岩的 c(+12.8%),这个结果值得说清楚。
试过降胶结强度去压 c:把 pb_coh 和 pb_ten 砍了 10%,UCS 只掉了 2.8%——弹性系数 0.28,而按强度公式应该是 0.944。也就是说,在煤岩这种胶结极弱的情况下,降胶结根本压不动强度。
原因不难理解:胶结弱到这个程度,试样已经接近纯摩擦材料,c 体现的是摩擦包线的截距,不再受胶结强度控制。这是弱胶结岩性的物理特性,不是标定的失误。煤岩的 φ 和 E 都达标了。
7. 七、怎么用
整套东西都在仓库的 岩石标定/ 目录下。要标一组新的岩石,改 target.json 里的目标值就行:
json"target":{"E_GPa":25.0,"c_MPa":18.0,"phi_deg":38.0}三个核心工具:
fit_envelope.py 由三档 .his 拟合 c、φ(含 R²) patch_halt.py 停机补丁,每个新生成的算例都要打 make_report.py 汇总出图 + 自包含 HTML 报告 注意口径必须统一:七种岩性全部用 60×120 mm 试样、孔隙率 0.12、应变率 0.05 /s、固定 seed——否则横向没法比。技能会按这套口径自动生成算例。
收敛判据:φ 和 E 进 ±1%、c 进 ±3% 就可以停手。这已经优于标定关系式自身的散布——继续迭代是在追噪声,不是追精度。
8. 最后说三句实话
一、这套参数是二维的。 所有结论都建立在 2D 模型上,不要直接拿去当三维用。
二、应变率用了 0.05 /s。 常规标定集用的是 0.01 /s,我为了提高速度统一提到了 0.05 /s(单例从 45–60 分钟压到 5–13 分钟)。代价是峰值强度会虚高,c、φ 与静态试验值之间存在速率偏差。因为标定是迭代到目标值的,这个偏差被微观参数自动补偿了——代价是标出来的参数在更慢的速率下会偏软。
三、层理和片理没建。 页岩、千枚岩的层理各向异性没有建模,按均质等效处理的。要研究各向异性得另做。
关于复现:脚本、逐轮实测记录、七种岩性的定稿参数都在仓库的 岩石标定/ 目录下,含标定规律的实测记录(CALIBRATION_NOTES.md)与自包含汇总报告。
VibePFC 社区 · 一起把 AI 玩进 PFC我成立了一个 VibePFC 社群,专门聊 AI 怎么落地到 PFC / 数值模拟——让大模型读懂模型、自己改脚本、自动排查"看不懂"的问题。收一个 50 元的门槛费。想进群的同学,加 QQ 763388012,备注"vibePFC"即可。
9. 参考资料
标定规律实测记录: 岩石标定/CALIBRATION_NOTES.md七种岩性定稿参数: 岩石标定/<岩性>/params_final.json汇总报告: 岩石标定/report/岩石标定汇总报告.html复现工具: fit_envelope.py、patch_halt.py、make_report.py