压裂模拟这个东西,圈外人一听觉得高大上,圈内人一听就知道是数值模拟里最烧脑的几个场景之一。我花了大把时间在 Comsol 里搭了一套"横观各向同性介质 + 水力压裂 + 相场法"的裂纹扩展模型,前前后后折腾了将近两个月,中间踩了无数个关于收敛性、网格尺寸、材料坐标系设置的坑。这篇就专门讲讲这个模型是怎么回事、为什么非要用相场、以及我在 Comsol 里一步步是怎么把它跑起来的。如果你想建一套类似的可压裂介质模型、又不想在基础理论里绕圈,这篇文章可以直接当参考。
这套模型解决的典型问题是:页岩、层状砂岩这类材料具有明显的层理面,裂缝在里面的扩展路径不是老老实实走直线,而是会顺着层理面偏移、分叉、甚至拐弯。传统方法做这种问题要么得显式追踪裂缝界面,要么得预置裂缝路径,工作量非常大。相场法用一套连续分布函数隐式描述裂缝,裂缝往哪里走、走多远、走多快,全部由方程自己算出来,特别适合这类复杂问题。这篇文章的受众是有一定有限元基础、想学相场法应用、或者正在被水力压裂模拟折磨的朋友,涉及的理论下面我都会尽量拆开讲。
1. 项目整体设计与思路拆解
1.1 问题的起点:横观各向同性介质里的裂缝难题
横观各向同性介质,这个名词乍一听很唬人,其实理解起来不难。我常说它是"一个方向特别,其余方向均等"的材料。页岩就是最典型的代表,垂直于层理面方向上的抗拉强度低、弹性模量小,平行于层理面的方向往往更"结实"。这种差异用五个独立弹性常数就能描述完全,比全各向异性简化和对称很多。
在压裂现场,工程师最关心的就是裂缝走向。因为埋深不同、地应力不同、层理面倾角不同,裂缝可能沿着最大主应力方向前进,也可能在接近层理面时发生转向或者被"锁"住。如果模型把材料简化成各向同性,裂缝路径的计算结果会明显偏离实际,所以认认真真把横观各向同性写进本构关系,是第一步。
有意思的是,加了各向异性之后,模型不只是材料属性变了,连裂纹扩展驱动力都变了。各向同性介质里,裂缝扩展方向通常由应力场唯一决定;在横观各向同性介质里,裂缝会"挑软柿子捏",优先找断裂韧性低的方向走。这种能量偏好会直接改变相场演化路径,如果材料参数设置不合理,整个模拟就等于白做。
1.2 为什么是相场法,而不是扩展有限元或离散裂纹法
我最初考虑过扩展有限元(XFEM)和黏聚区模型(CZM)。XFEM虽然不用重划网格,但处理多裂纹交叉、裂纹分叉的时候,需要额外定义富集函数和交互积分,每一条新裂纹都要手动维护一下拓扑信息,复杂度随着模拟步数增加。黏聚区模型倒是能把断裂过程区描述得很细,但裂缝路径通常要提前预设好,对于"裂缝顺层理走还是穿层理走"这种本质上是路径选择问题的情况,预设路径等于把答案提前告诉模型了。
相场法完全不同。它给材料定义了一个连续的相场变量d,取值范围 0 到 1,0 代表完整材料,1 代表完全破裂。断裂过程被平滑到一个宽度为l0的扩展区域里,裂缝萌生、扩展、分叉、合并不需要任何额外拓扑操作。你只需要把断裂能写成d和grad(d)的函数,求解偏微分方程组时自然就得到裂缝路径了。
对我来说,相场法最吸引人的地方在于它和流体流动耦合时非常自然。水力压裂本质上就是"固体弹性—断裂演化—裂缝流动"三者互相作用的问题,相场变量直接决定了裂缝区域的渗透率和孔隙度,而裂缝内的流体压力又会反过来驱动裂纹扩展。这种双向耦合用 XFEM 实现起来相当痛苦,在相场框架里就顺理成章。
1.3 水-力-断裂耦合的建模策略
水力压裂模拟的核心是求解一个耦合系统。我把它拆成三个部分:
- 横观各向同性弹性体在外力场作用下的变形与应力响应;
- 相场变量
d在断裂驱动力作用下的不可逆演化(d只能从 0 变到 1,不能倒退); - 裂缝内流体流动,裂缝开度(宽度)与局部压力之间的润滑方程关系。
这三个部分不是独立求解再拼接,而是在同一时间步内相互迭代。Comsol 里的典型做法是用"固体力学"接口承载弹性方程和相场方程,再用一个 PDE 接口定义相场演化方程。如果你想更自由,可以把流体压力也作为单独的变量写进去,我后面会专门讲这一步。
很多初学者容易把注意力放在相场方程书写上,其实忽略了一个关键点:横观各向同性材料里,断裂韧性Gc是一个随方向变化的量,不同面上的断裂能密度不一样,这直接影响d的演化方向。这部分内容后面我会专门展开。
2. 横观各向同性弹性理论与相场断裂模型的核心参数
2.1 五参数弹性本构的矩阵展开
横观各向同性材料在局部坐标系下有五个独立弹性常数。我习惯用工程常数来表示:E1(各向同性面内模量)、E3(垂直面方向的模量)、ν12(面内泊松比)、ν13(跨面泊松比)、G13(跨面剪切模量)。有了这五个数值,刚度矩阵的完整形式才能填满。
这里有一个特别容易踩的坑:在 Comsol 的弹性材料设置里,各向异性的工程常数输入顺序很严格。如果沿用平面应变假设,ν13和G13每个都必须对应到正确的坐标方向。我在最开始把E1和E3填反了,结果应力场分布完全失真,裂缝路径直接往反方向偏,排查了半天才意识到是坐标系搞错了。
所以在模型里我建议用矩阵形式先把刚度矩阵算出来,再对照 Comsol 的输入窗口逐项核对。下面是一个典型页岩参数集的矩阵示意:
弹性常数参考表 E1 = 32 GPa(平行层理面) E3 = 18 GPa(垂直层理面) ν12 = 0.21(面内) ν13 = 0.28(跨面) G13 = 7.4 GPa(跨面剪切)直接用这些工程常数写刚度矩阵很容易出错,我一般先在脚本里转换成柔度矩阵,再求逆得到刚度矩阵,确保正定性和对称性都满足。Comsol 的"材料"节点里可以逐项填入,也可以通过外部材料插件批量赋值。
2.2 材料坐标系与层理面角度的绑定
横观各向同性的核心是"有一个对称轴"。这个对称轴在模型里怎么放置,直接决定了裂缝往哪里走。如果目标研究层理面与最大主应力呈 30° 或 60° 夹角的情形,就必须在材料属性里定义一个旋转坐标系,让材料对称轴跟着层理面倾角走。
Comsol 里做材料坐标系旋转主要有两种方式。一是通过"坐标系"功能定义一个新的旋转坐标系,然后在材料设置中选定它;二是直接在变量的应力、应变分量上做旋转变换。第一种方式最直观,我推荐优先使用。设计模型时可以定义一个"层理面倾角"参数 θ,然后通过旋转矩阵把局部坐标系的刚度张量变换到全局坐标系下。
有一点不得不提醒:应力结果的后处理也要盯着局部坐标看。如果你在全局坐标下读取应力值,很容易误判裂缝面的法向应力,因为裂缝面本身是倾斜的。我习惯在后处理中额外定义一个旋转坐标系,把局部坐标系下的应力分量和相场分布叠在同一张图里,这样判断裂缝是张拉型还是剪切型更直观。
2.3 断裂韧性的方向性处理
横观各向同性材料里,断裂韧性不像弹性常数那样有现成的标准公式,需要根据经验或实验数据设定。印象里,垂直层理面的扩展阻力比平行层理面低不少,有些层状岩石相差超过 50%。这种差异在相场方程里会改变裂纹扩展的能量释放率判据。
在 Comsol 中,我常用的做法是让断裂能密度Gc按角度插值:
Gc(theta) = Gc_perp * (1 + anisotropy_ratio * sin(theta)^2)其中theta代表裂纹扩展方向与层理面的夹角。当夹角为零,也就是沿着层理面扩展时,Gc取最小值,裂缝更容易沿层理扩展;当夹角趋近于 90°,相当于垂直穿越层理,Gc达到最大值,形成“穿层”的天然阻力。这个插值公式不是唯一的,你也可以用傅里叶形式或直接查表,但核心思想是捕捉方向上的能量差异。
断裂韧性方向性对相场演化的影响,我后面单独拿一组算例来讲,这里先不展开。但你要有这个意识:相场法里裂纹扩展判据本质是能量最小化,方向性Gc就是给这个能量加上了一条“偏好路径”。
3. Comsol 模型搭建全过程:从几何到耦合方程
3.1 几何建模与网格策略
我的算例模型是一个二维截面,尺寸设置为 10 m × 10 m 的代表性区域,中间预留一条初始裂缝(长度 0.5 m,高度方向贴合层理面)。初始裂缝有两种引入方式:一种是在几何中直接画一条窄缝,另一种是用相场变量d=1的初始分布来"预埋"。后者更推荐,因为避免了网格奇异性,还能让裂缝光滑地增长。
网格划分是整个模拟里最需要耐心的一步。相场法有一个重要概念:正则化长度l0,它控制了断裂过程区的宽度。为了让裂缝路径光滑且网格无关性合理,裂缝区域附近的网格尺寸要小于l0/2。我常用l0=0.02 m,那么沿裂缝路径的网格尺寸就控制在 0.01 m 以下,而远处区域可以稀疏到 0.5 m。用细网格从裂缝端部向四周做渐变过渡,既保精度又控计算量。
3.2 物理场接口与方程实现
Comsol 里实现这套耦合模型,我通常用组合方式:固体力学接口 + 广义 PDE 接口 + Darcy 流接口。广义 PDE 用来求解相场演化方程。Comsol 5.x 版本都能很好地支持这类自定义 PDE,参数设置也不复杂,关键是写好方程的各项系数。
固体力学接口里启用"线弹性材料"作为基础底子,然后通过"外部应力"或"外部应变"节点引入相场引起的材料退化。经典的退化形式是:
C_eff = g(d) * C g(d) = (1 - d)^2 + kappakappa是残余刚度系数,用来避免完全断裂后刚度为零导致数值奇异,一般取 1e-6 或 1e-9。我用的取法是:kappa = 1e-9,这样裂缝两端的位移场不至于产生剧烈的伪振荡。
相场演化方程我采用如下形式:
(Gc/l0) * d - 2 * (1 - d) * psi_plus + l0 * Gc * laplacian(d) = 0其中psi_plus是拉伸部分能量密度。关键是要做拉伸-压缩能量分解,否则材料在压应力状态下也能“断裂”,这在力学上是不成立的。我用经典的 Miehe 各向异性分解,把应变能的正部用于驱动d增长,负部完全不参与,这样裂缝只会因为拉伸破坏而扩展,不会在高压压缩区形成虚假裂纹。
3.3 流体压力与固体变形的耦合实现
水力压裂的流体压力是过度简化的地方。裂缝内流体流动的驱动力来自注液压力和缝内压力梯度。我把裂缝区域等效成渗透率随相场突变的 Darcy 流区域,渗透率设置方式是通过变量表达式实现:
k(perm) = k_matrix + (k_fracture - k_matrix) * d^3d^3的选取是有讲究的。立方定律表明裂缝渗透率与裂缝开度的三次方成正比,而裂缝开度与d强相关。这样随着相场从 0 过渡到 1,渗透率从基质渗透率平滑过渡到裂缝渗透率,既保证了连续性,又符合物理直觉。
压力场和位移场双向耦合:压力会作为体积力作用到固相方程里,固相变形又会改变裂缝开度,从而改变渗透率。Comsol 里我用"全局方程"或"Darcy 接口的存储项"来控制压力更新,求解时采用全耦合迭代,位移、压力、相场三个变量在同一求解器里更新。不要贪图方便用分离式求解,我试过,在裂缝尖端这种强耦合区域,分离式求解极其容易发散。
4. 参数取值、加载方案与结果分析
4.1 模拟工况与边界条件设置
为了讲清楚整套流程,我给出一个典型的模拟工况表。所有值都可以根据实际工程换,但不妨作为起步点:
| 参数 | 取值 | 说明 |
|---|---|---|
| 模型尺寸 | 10 m × 10 m | 二维平面应变模型 |
| 层理面倾角 | 30° | 与水平方向夹角 |
| 初始地应力 σx | 15 MPa | 水平应力 |
| 初始地应力 σy | 20 MPa | 垂直应力,取稍大 |
| 注入流量 Q | 0.005 m²/s | 二维单位厚度流量 |
| 注入流体粘度 | 1e-3 Pa·s | 水 |
| 断裂韧性 Gc_perp | 300 J/m² | 垂直层理方向 |
| Gc_para | 120 J/m² | 平行层理方向 |
| 初始相场裂缝 | 0.5 m 长度 | 预设 d=1 区域 |
边界条件方面,四周设置应力加载或者位移约束。我习惯用应力加载模拟远场压力,在模型边界施加对等地应力,同时顶部边界加注液压力入口。注液点设置在初始裂缝中心位置,方便观察裂缝向两侧扩展的对称性。
4.2 初始裂缝的"弱种子"技巧
有不少人对初始裂缝设置犯愁,直接画一条缝会导致应力奇异性,对相场方程也不友好。我采用"弱种子"策略:初始裂纹通过一个较小的相场值分布(比如d=0.95)来定义,而不是硬性的 1.0,同时在其周围区域保持d=0。这样做有两方面好处:一是初始裂纹区域已经有了高渗透率和低刚度,流体注入后能快速起裂;二是避免了 1.0 区域形成刚度过低的强非线性区,收敛性能明显改善。
但“弱种子”要小心,初始裂纹端部必须设置成平滑过渡,不要在d=0.95和d=0之间留一个尖锐跳变,否则应力波会在过渡区发生伪反射,裂缝扩展路径也会出现锯齿状抖动。我通常在端部用一条衰减的三角函数过渡带,宽度跟l0匹配。
4.3 结果分析:裂缝路径、缝宽曲线和破裂压力
模拟完成后,最直观的输出是相场变量分布图。d=1的区域就是裂缝,其他区域是完整材料。我在后处理里设置等值面d=0.5当作裂缝轮廓线,再用“最大局部坐标”算子提取裂缝中心线,方便和实验或现场微地震成像对比。
除了裂缝路径,最常看的还有缝宽曲线。取垂直于裂缝中线的横截面,提取位移不连续量,就是裂缝开度。在横观各向同性介质中,裂缝开度沿裂缝长度方向往往不是均匀分布的,通常是中部最宽、两端收窄到零。流体注入压力随时间的变化曲线同样重要,曲线上的峰值就是破裂压力。
要注意的是,相场法给出的缝宽是"正则化宽度"上的积分结果,和真实缝宽存在一定误差。为减少误差,网格尺寸不能跟l0相差太多。实际操作中,我用l0=0.02 m时,缝宽曲线与理论解(KGD 模型解)对比偏差大约在 10% 以内,工程上够用了。
4.4 层理面角度对裂纹扩展方向的影响——对照算例
为了验证模型有效性,我设置了层理面倾角分别取 0°、30°、60° 的三组对照算例,材料和注入参数全部保持一致。结果非常直观:
- 倾角 0°:裂缝完全沿层理面水平扩展,路径平直,破裂压力最低。
- 倾角 30°:裂缝初始沿水平方向扩展,接近层理面时发生偏转,最终沿层理面方向拐弯,路径呈现"之"字形,破裂压力略高。
- 倾角 60°:裂缝沿最大主应力方向直接穿过层理,形成穿层裂缝,路径基本平直但断裂韧性高,破裂压力最高。
这三组算例说明,横观各向同性介质中裂纹扩展路径是"地应力方向"和"层理弱面方向"竞争的结果。相场法有能力捕捉这种竞争效应,这也是我用它而不是其他方法的关键原因。
5. 常见问题与排查技巧实录
5.1 方程不收敛:残差爆炸和负相场值
这是我遇到最多的问题。典型现象是求解几步后残差一直不下降或者直接报“找不到解”。究其根源,多半是相场变量的非线性太强,以及断裂能分解造成的刚度突变。我总结了几种很管用的缓解办法:
- 降低初始载荷步,最大时间步限制在 0.01 s 以下;
- 对相场方程单独加一点人工阻尼(即在小项上加
1e-8 * d/dt项); - 使用“恒定牛顿”或“阻尼牛顿”作为非线性求解器;
- 在刚性退化函数
g(d)里把kappa设置到 1e-7,而不是 1e-12,防止刚度矩阵奇异。
排查收敛性还有一个技巧:用d的初值检验法。如果初始模型在零压力下都不收敛,说明弹性部分就有问题;如果只加压力而不耦合相场能收敛,那问题出在耦合项;如果相场单独演化收敛而整体不收敛,多半是流体压力更新和位移更新之间的耦合参数设置有问题。把这三步拆开来测,定位很快。
5.2 相场变量扩散变形或"弥散"
另一个高频问题:相场变量不应该出现区域性的“扩散云”,只在裂缝附近才应该从 0 平滑过渡到 1。如果看到d在很大范围内变成 0.2、0.3 之类的中间值,这就是所谓“弥散裂缝”。
原因通常是拉伸能量分解没有做到位,或者断裂驱动力在低应力区也被激活了。我检查过几次后确认,解法是采用 Miehe 的正负应变能分解之后,还要在psi_plus表达式里排除纯体积应变能的正值部分。相场方程里必须确保源项在无拉伸条件下是负的,这样d会自然衰减到 0,不会蔓延。
5.3 裂缝闭合后渗透率异常
水力压裂模拟后期,压力下降过快时裂缝可能闭合。我一开始用d^3表示渗透率变化,但裂缝闭合后d可能依然接近 1,导致渗透率没变,流体可以继续在“闭合裂缝”里乱跑,物理上就失真了。
更稳妥的做法是让渗透率同时依赖缝宽。我在表达式里加入一个缝宽w因子,把渗透率写成:
k_fracture_eff = k_matrix + max(0, w)^3 * (k_ratio) * d^2这样即使相场还处于开裂状态,只要缝宽趋近零,高渗透率通道就自动关闭。这个修改看起来小,但对后期压力衰减曲线影响非常大。
5.4 网格依赖性与参数敏感性
相场法的网格尺寸敏感性不像其他方法那么尖锐,但也存在。如果网格比l0/2还要密,会显著增加计算开销;如果网格太粗,裂缝路径会以阶梯状折线形式出现,后处理里看着非常突兀。我在试算阶段用一粗一密两套网格做对比,验证裂缝路径差异不超过 3%,才算放心使用。
参数敏感性方面,最敏感的几个依次是:Gc_perp(垂直层理断裂韧性)、Gc_para/ Gc_perp比值、层理面倾角、地应力差值。l0本身对峰值压力有约 10% 的影响,所以对比算例必须保持同一个l0,否则结论混淆。
写在最后
这套模型从零搭建到稳定出结果,我最大的感受是:相场法并不是"开箱即用"的脚本工具,理论框架、材料描述、数值细节三者缺一不可。横观各向同性介质给模拟带来的不只是多填几个参数,而是从力学机理上改变了裂缝扩展的竞争机制,相场法恰恰能把这个机理自动地体现在裂缝路径里,这是我最喜欢它的地方。
最后再分享一个小技巧:做这类强非线性耦合模拟时,不要一上来就全参数、全耦合。先做一个无注液、无相场耦合的纯应力场测试,再逐步把断裂、压力加进去。每一层都能输出合理结果时,再合并成完整模型,这样你才能准确判断报错到底来自哪个物理过程。这种“逐级解锁”的操作方式,比一次性搭好整个系统再调试要省出至少一倍时间。希望这篇记录能帮你少走我走过的弯路。