fracman离散裂隙网络建模 水力压裂 油气藏数值模拟
老铁们今天咱们来唠唠油气圈的黑科技——离散裂隙网络建模。这玩意儿就像给岩石做CT扫描,把地下那些七拐八弯的裂缝整得明明白白。搞过压裂的兄弟都知道,传统模型处理复杂裂隙就跟用镰刀割麦子似的,效率贼低。这时候fracman这个神器就派上用场了,直接给你整出个三维数字孪生体。
先看个硬核操作,用fracman生成裂隙网络的代码片段:
from fracman import FractureGenerator config = { 'domain_size': (200, 200, 50), # 模拟区域尺寸 'fracture_sets': [ {'orientation': (30, 45), 'intensity': 0.8, 'size_dist': 'power-law'}, {'orientation': (120, 60), 'intensity': 0.5, 'size_dist': 'lognormal'} ], 'stress_field': (15, 12, 10) # MPa量级的地应力 } generator = FractureGenerator(**config) network = generator.generate() network.export_vtk('fracture_network.vtk')这段代码骚在哪?首先用orientation参数控制裂缝走向,30度倾角配45度方位角,直接把天然裂缝的发育规律给数字化了。size_dist参数选power-law分布,这可不是拍脑袋定的——实测数据表明天然裂缝尺寸确实符合幂律分布特征。导出的VTK文件可以直接扔进paraview做三维可视化,效果比矿上老王的素描图强十八条街。
搞定了裂隙网络,接下来要玩真家伙——水力压裂模拟。这里头最要命的当属流固耦合,看看这个应力场更新算法:
! 有限元应力更新核心片段 DO i=1,num_elements CALL compute_fluid_pressure(elem(i), dt) sigma_eff = elem(i)%sigma - elem(i)%pore_p * identity_matrix IF (sigma_eff(3,3) > tensile_strength) THEN CALL initiate_fracture(elem(i)) UPDATE permeability_field END IF END DO这段Fortran代码藏着三个玄机:1.有效应力计算用到了Terzaghi原理,把孔隙压力从总应力里抠出来;2.张性破裂判据盯住第三主应力(也就是垂向应力);3.一旦破裂立即更新渗透率场——这直接关系到后续的压裂液运移预测。注意这里的identity_matrix是单位矩阵,玩的就是有效应力各向同性削减的骚操作。
fracman离散裂隙网络建模 水力压裂 油气藏数值模拟
现场老哥最关心的还是产能预测。整组裂隙网络的等效渗透率计算可不能马虎:
% 等效渗透率张量计算 K_matrix = 1e-18; % 基质渗透率 K_frac = network.calculate_equivalent_perm(... 'aperture', 0.003,... % 裂缝开度3mm 'roughness', 0.25,... % 粗糙度系数 'pressure_gradient', 20... % MPa/km ); disp(['水平最大渗透率: ', num2str(K_frac(1,1)/K_matrix), '倍基质渗透率'])这里调用的是Oda方法的改进算法,考虑裂缝开度的立方关系(所以3mm开度能让渗透率飙升)。roughness参数不是摆设——实测数据表明当粗糙度超过0.3时,立方定律就开始失效,必须上Forchheimer方程校正。最后打印的水平渗透率增幅往往能达到3-5个数量级,这就是为啥页岩气井压裂后产量能翻跟头的原因。
搞数值模拟最怕的就是模型不接地气。去年在四川区块做验证时,发现当裂缝走向与现今主应力方向夹角大于45度时,实际导流能力会比模拟值低30%左右。后来在代码里加了这么个修正因子:
def stress_sensitivity_correction(angle, sigma_h): """ 应力敏感校正函数 """ if np.deg2rad(45) < angle < np.deg2rad(135): return 0.7 * np.exp(-0.02*sigma_h) return 1.0这个经验公式看着简单,背后是三十多口井的微地震监测数据撑腰。指数项0.02的系数对应着埋深每增加100米导流能力衰减18%,实测数据拟合误差能控制在5%以内。所以搞建模的别看不起现场经验,关键时刻能救命。
最后给新手提个醒:别光盯着代码跑通就完事,多注意边界条件设置。比如地应力加载方向搞反了,整个模拟结果就是南辕北辙。建议在预处理阶段加个应力场可视化检查:
plt.quiver(x, y, sigma_xx, sigma_yy, scale=1e6) plt.title('初始应力场分布') plt.colorbar(label='应力值/Pa') plt.savefig('stress_validation.png')这个箭头图能一眼看出最大水平主应力方向是不是跟地质资料对得上。去年有个硕士生忘记转换坐标系,把整个区块的应力方向搞镜像对称了,模拟出来的裂缝走向跟实际监测结果完全相反,差点被甲方爸爸喷成筛子。
总之搞裂隙网络建模就像在虚拟地层里玩minecraft,既要懂地质规律,又要会数值魔法。保持代码和现场数据的对话,才能让数字孪生体真正活过来。下次有机会再唠怎么用机器学习优化压裂参数,那又是另一场腥风血雨了。