简介:针对页岩储层压后裂缝复杂性评估问题,石油工程与地质工程技术人员可从这份PDF文档中系统学习G函数曲线分析方法。文档通过修正经典G函数理论建立压降模型,重点对比简单主裂缝、沟通单条及多条天然裂缝场景下的一阶导数、叠加导数与G函数曲线特征,并结合涪陵气田三口井的实例数据展示波动幅度与产量的相关性;其中简单主裂缝表现为常数型一阶导数,天然裂缝沟通越多则波动越强,叠加导数波峰数量可用于量化裂缝复杂性。资源附有完整的Python复现代码及中文解释,读者可依据代码模拟不同裂缝形态、计算叠加导数并绘制相关图表,掌握以低成本G函数分析替代微地震监测的实用技能,为优化压裂施工参数和开发部署提供技术依据。该PDF包仅含1个文件,大小469KB,现已有99人浏览学习,适合从事页岩气田开发、压裂优化研究的中高级专业人员作快速参考。
1. G函数曲线分析为什么是页岩压裂评估的入口
一口页岩气井压完,地面泵车还在收摊,地层里其实已经开始了另一场更慢的“考试”:停泵后的压力降。这段时间窗口往往只有两三个小时,但滤失机制、裂缝是否在闭合前继续扩展、闭合应力梯度是多少,全都写在这段压降曲线里。可真实时间坐标下的压降曲线前陡后平,直接读数基本读不出名堂。G函数曲线分析就是把这段数据换到无量纲G时间域,让原本非线性衰减的压力降变成可判读的直线、拐点和斜率变化,这也是压后裂缝复杂性评估里成本最低、见效最快的一步。
在页岩储层中,储层基质渗透率极低,压裂的目标是造出一个足够复杂的缝网,而缝网是否真的复杂,靠事后产量反推往往要等好几个月。G函数曲线分析能在压后当天给出一个初步定量答案:闭合点在哪、净压力还剩多少、滤失受不受压力影响,再把它们与水平应力差和天然裂缝条件拼接,就构成优化压裂施工参数和开发井网部署的依据。这篇文章面向完井工程师、油藏工程师和做压裂效果评价的研究人员,我们把原理、Python实现和决策逻辑一次走通。
2. G函数曲线形态与滤失机制判别的物理基础
2.1 为什么要用G时间而不是直接用真实时间
停泵后井底压力的衰减由滤失控制,而滤失过程对真实时间的依赖在早期极强、后期极弱。如果直接把压力对真实时间求导,前几百秒的数据会落入噪声区间,后期数据又因为斜率太小而失去分辨率。G函数的思路是把时间除以注入时长,做一个无量纲变换,再叠加上反映扩散特征的积分核,使得理想条件下压力降与G时间呈线性关系。
这个变换的物理出身是Nolte在恒排量注入、裂缝准静态扩展和Carter滤失假设下推导出来的。页岩压裂现场几乎不存在完全满足这三个假设的工况,天然裂缝、压力敏感滤失、裂缝延伸都会让曲线偏离理论基线。但恰恰是“偏离基线”这个性质,让G函数从计算工具变成了诊断工具:偏差方向、曲率变化和拐点位置,分别对应不同的储层响应。
2.2 三种典型形态的判别与闭合点特征
工程分析中习惯把dP/dG(压力对G的导数)作为主判读曲线。稳定滤失时它应该接近一条过原点的直线;当出现压力依赖滤失或裂缝延伸时,曲线会明显偏离这条理论基线。偏离方向需要结合现场泵注参数判断,不能孤立看形状。
| 曲线形态 | dP/dG对G的表现 | 可读取的工程信息 | 后续动作倾向 |
|---|---|---|---|
| 正常滤失 | 过原点直线或近似直线 | 基质控制滤失,闭合过程规律 | 直接读取闭合压力,结果可信度较高 |
| 压力依赖滤失 | 明显偏离基线,早期段曲率异常 | 天然裂缝或微裂隙受净压力开合控制 | 闭合压力可能偏移,需用净压力曲线二次确认 |
| 裂缝延伸 | 关井早期仍存在大幅斜率段,后期才转线性 | 停泵后裂缝仍受惯性延伸影响 | 不能按常规滤失方程外推缝长 |
| 多缝/邻井干扰 | 导数出现双峰、台阶或斜率反复 | 与既有缝网、层理弱面或邻井压降沟通 | 复杂性评价必须降级,单井解释不足 |
曲线形态判断完之后,闭合点的初选通常落在导数偏离直线最明显的转折位置。这个位置对应的井底压力就是裂缝闭合应力梯度。页岩气井的闭合应力梯度一般落在0.011到0.022 MPa/m区间,具体数值受垂深、构造挤压和泊松比影响。如果闭合应力梯度异常偏高,往往意味着井筒附近存在多缝竞争或近井复杂结构。
2.3 净压力与水平应力差决定裂缝能否复杂起来
G函数曲线里能挖出两个关键压力值:瞬时停泵压力(ISIP)和闭合点压力(Pc)。两者相减,得到的是裂缝闭合前的净压力。页岩储层中天然裂缝要想张开或错动,净压力必须接近甚至超过最小水平主应力与最大水平主应力之间的差值。差值越小,越容易被“撬开”;差值越大,压裂液再努力也只能沿着最大主应力方向形成一条窄缝。
以一口垂深3800米的井为例,Pc约62 MPa,ISIP约68 MPa,净压力约6 MPa。如果区域应力解释给出的水平应力差约5 MPa,那么这口井具备了激活次生缝的压力条件,G函数曲线若同时表现出压力依赖滤失特征,裂缝复杂性倾向就是中到高。反过来,净压力只有3 MPa而应力差高达8 MPa,曲线形态再平滑,缝网也只能以主缝为主。G函数提供的是压力侧证据,水平应力差和天然裂缝密度来自测井解释和区域模型,两边对齐之后才能给复杂性定级。
3. 用 Python 代码把 G 函数分析变成可复用流程
3.1 数据准备:从压降测试 CSV 出发
在写任何分析逻辑之前,先要确认手里有一份干净的原始数据。现场常见的压降测试记录至少包含时间、井口压力、泵注排量和井深信息;有井下压力计的话优先用井下压力数据,没有的话用井口压力折算井底压力。下面这段代码负责读入数据并做一个工程化的井底压力近似折算:
import pandas as pd import numpy as np from scipy.signal import savgol_filter # 现场导出的CSV,列名按实际文件调整 raw = pd.read_csv("frac_pt.csv", parse_dates=["time"]) raw.sort_values("time", inplace=True) raw["dt"] = (raw["time"] - raw["time"].iloc[0]).dt.total_seconds() # 井底压力折算:井口压力 + 液柱压力 - 摩阻 rho_kg_m3 = 1050.0 # 压裂液密度,视配方调整 md_m = 4200.0 # 井斜测量深度,单位m fric_pdrop_mpa = 0.0 # 停泵阶段摩阻取0;若在泵注段需要单独给 raw["p_bh"] = (raw["wh_pressure"] + rho_kg_m3 * 9.81 * md_m / 1e6 - fric_pdrop_mpa) # 用排量阈值切分主泵段与关井段 inject = raw[raw["pump_rate"] > 0.1].copy() shutin = raw[raw["pump_rate"] <= 0.1].copy() tp = inject["dt"].max() print(f"注入时长: {tp:.1f}s, 关井点数: {len(shutin)}")液柱压力计算里,密度取1050 kg/m3是因为滑溜水通常落在1000到1100之间;换成高粘压裂液时这个数要跟着变。摩阻在停泵后逐渐消失,如果直接把泵注段的井口压力折算成井底压力,需要引入泵注末期的摩阻估计,否则ISIP会被高估。排量阈值0.1 m3/min用来区分主泵和关井,现场存在轻微的泵车残余排量时,建议先看排量曲线再定阈值。
3.2 计算 G 时间与压力导数
G时间的计算是整个流程的核心。下面代码实现的是Nolte G函数的常见工程近似:保留积分核的主要项,省略常数项,因为dP/dG分析只关心相对变化,常数项在求导后不产生任何影响。
def gtime(theta): # Nolte G 时间工程近似:(4/3)[(1+theta)^1.5 - theta^1.5] # 不同软件脚本里可能带 -2/3、-1 等常数修正,不影响求导形态 return (4.0 / 3.0) * ((1.0 + theta) ** 1.5 - theta ** 1.5) # 截取关井段的前3倍注入时长,足以覆盖大部分闭合窗口 shut = shutin[(shutin["dt"] > tp) & (shutin["dt"] < tp + 3 * tp)].copy() shut["theta"] = (shut["dt"] - tp) / tp shut["G"] = gtime(shut["theta"]) # 先平滑再去差分,避免把噪声当成闭合特征 shut["p_smooth"] = savgol_filter(shut["p_bh"], window_length=101, polyorder=3) shut["dpdG"] = np.gradient(shut["p_smooth"], shut["G"])Savitzky-Golay滤波器的window_length需要根据采样频率调整:1秒采样的数据用101点,窗长约100秒,足够压制高频噪声;10秒采样的数据如果还用101点,等于把1000秒内的变化全部抹平,闭合点会被吃掉。此时window_length缩到11或21更合理。polyorder=3在大多数压降曲线上都能兼顾平滑和保形,不要轻易上到5以上。
代码里的数字参数都建议做成命令行参数或者放在脚本头部,而不是写死在函数里。现场批次处理几十口井时,每口井的注入时长、采样步长都不一样,把这些参数变成输入项是最省事的维护方式。
3.3 自动初选闭合点,再交给人工确认
闭合点的自动初选可以在一段有限的G区间内做。取G在0.2到1.2之间的数据,找dP/dG变化率最大的位置,这个位置就是导数转角最大的候选点。限制区间的原因很实际:关井极早期压力噪声大,极晚期导数尾巴会因量测误差出现虚假转折。
zone = shut[(shut["G"] >= 0.2) & (shut["G"] <= 1.2)].copy() zone["d2"] = np.gradient(zone["dpdG"], zone["G"]) cand_idx = zone["d2"].abs().idxmax() cand = zone.loc[cand_idx] # 闭合应力梯度 = 闭合压力 / 测量深度(垂直井用垂深) closure_gradient = cand["p_smooth"] / md_m print(f"候选闭合点: G={cand['G']:.3f}, " f"Pc={cand['p_smooth']:.2f} MPa, " f"闭合梯度={closure_gradient:.4f} MPa/m")自动初选的价值是把人工看图范围缩小到几十秒,而不是完全替代看图。把曲线画出来看一眼再定闭合点,是所有流程里最低成本的一次人工干预。
import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(8, 5)) ax.plot(shut["G"], shut["dpdG"], lw=1.2, label="dP/dG") ax.axvline(cand["G"], color="r", ls="--", label="candidate closure") ax.axhline(0, color="k", lw=0.6) ax.set_xlabel("G(t, tp)", fontsize=12) ax.set_ylabel("dP/dG (MPa)", fontsize=12) ax.legend() plt.savefig("g_function_check.png", dpi=150)把脚本保存成g_analysis.py之后,在终端里执行python3 g_analysis.py frac_pt.csv就能跑完整条链路。Windows环境下用户经常把文件存成.txt然后双击,没有任何输出,正确方式是先装Python解释器,再在cmd或VS Code终端里执行。习惯在WSL Ubuntu里写代码的话,把CSV放到/home目录下,用python3 g_analysis.py运行即可;字体建议换成JetBrains Mono一类等宽字体,井底压力和摩阻这类数字看久了也不会把0和O搞混。
3.4 为什么这段代码要保留人工确认口子
纯粹自动化提取闭合点会遇到一类高频问题:现场压力记录经常在关井后出现长达几秒的振荡,Savitzky-Golay滤波能压制一部分,但如果振荡周期和窗长接近,会在dP/dG上形成假拐点。自动初选程序会把假拐点当成候选闭合点,而人眼可以结合停泵瞬间的阶跃特征和曲线整体趋势把它排除。
更稳健的做法是两段式:第一遍用较宽的滤波窗扫出候选闭合区间,第二遍在候选区间内用窄窗重算,对比两个结果。误差在0.3 MPa以内就取平均值;误差超过0.3 MPa就把这段曲线标红,打回人工复核。G函数分析的可交付物不是一张图,而是一份带质量标记的压力特征表,后面所有复杂性和部署判断都建立在它的质量之上。
4. 从形态到裂缝复杂性评估:把 G 函数结果组装成一张打分卡
4.1 从 dP/dG 形态映射裂缝复杂倾向
单独一个dP/dG曲线形态不能给裂缝复杂性定案,但能给出倾向。页岩压裂中常见的四种形态和它们的解释方向如下。
| dP/dG形态 | 主要解释 | 裂缝复杂性倾向 | 对部署的影响方向 |
|---|---|---|---|
| 过原点直线 | 基质滤失为主,缝网简单 | 低 | 以长缝导流为主,井距可考虑减小 |
| 明显偏离基线 | 天然裂缝受压力开合 | 中到高 | 缝网范围大但滤失大,降滤失优先 |
| 关井后仍延伸 | 裂缝在停泵后继续扩展 | 中 | 有效缝长被低估,需要控制排量序列 |
| 双峰或多台阶 | 多缝竞争与复杂沟通 | 高 | 部署上重视缝间干扰 |
这张表的第一列来自G函数导数图,第二列来自物理机理,第三列和第四列是工程倾向。变形上有一个原则:任何一张G函数图都不能脱离闭合梯度和净压力单独解释,否则会把压力计噪声当成裂缝响应。
4.2 FCI 裂缝复杂性指数:一个可复算的加权模型
为了把多个证据归一化,工程实践里常做一个裂缝复杂性指数(Fracture Complexity Index,FCI)。FCI不是理论公式,而是一套可调整的加权评分。下面这个实现权重是我个人比较常用的版本,吸收了压力、测井和微地震三类信息。
import numpy as np def fci_score(dpdg_shape, net_press_mpa, stress_diff_mpa, natural_fracture_density, ms_event_density): # 形态分:线性=0.2,压力依赖滤失=0.6,延伸型=0.4,多峰型=0.8 shape_score = { "linear": 0.2, "pressure_dependent": 0.6, "extension": 0.4, "multi_peak": 0.8 }[dpdg_shape] # 净压力超过水平应力差越多,越容易激活弱面 net_score = np.clip((net_press_mpa - stress_diff_mpa) / 5.0, 0, 1) # 成像测井统计的天然裂缝线密度,单位条/m nf_score = np.clip(natural_fracture_density / 3.0, 0, 1) # 微地震事件密度,单位 个/簇,缺少时传0并在下面重新归一 ms_score = np.clip(ms_event_density / 20.0, 0, 1) fci = (0.35 * shape_score + 0.25 * net_score + 0.20 * nf_score + 0.20 * ms_score) return np.round(fci, 2)参数含义需要解释清楚。net_press_mpa是ISIP与Pc的差值,单位MPa;stress_diff_mpa来自地应力解释,单位MPa。这两项的差直接决定次级缝能否张开,所以权重给到0.25。natural_fracture_density来自成像测井统计的裂缝条数除以段长,3条/m对应接近满分的弱面发育条件;ms_event_density的单位是个/簇,20个/簇对应的微地震事件覆盖已经相当好。如果一口井没有布设微地震监测,ms_event_density传0会把FCI整体压低0.2,这种情况下应该把另外三项的权重等比例放大到和为1.0。
4.3 FCI 的边界:哪些情况会失效
FCI是一个证据汇总器,不是真理机器。井底压力折算误差大于1 MPa时,net_press_mpa本身不可信,FCI的分差会完全失真。微地震监测范围小于实际缝网范围时,ms_event_density偏低,FCI给出的复杂性会系统性偏小。页岩气井中常见的陡倾天然裂缝还容易在成像测井上漏统计,nf_score同样存在不确定性。
所以实际评估顺序必须固定为:先看G函数曲线形态,形态能接受再看闭合应力和净压力,与测井应力差对齐之后才组装FCI;如果FCI和G函数形态方向冲突,优先怀疑输入数据而不是数学模型。这个判断顺序保证了整个评估体系在数据质量参差不齐的现场仍然站得住。
5. 把评估结果落到压裂施工参数与开发部署
5.1 施工参数调整:先区分需要延缝还是需要扩缝
FCI和G函数特征点一旦落定,压裂施工参数就有了调整依据。关键思路不是“复杂就好”,而是根据缝网形态决定工艺目标:低复杂性井要扩大缝网规模,高复杂性井要控制近井净压力峰值,防止缝网局部过载。
| 评估结果 | 第一调整方向 | 可调参数 | 工程逻辑 |
|---|---|---|---|
| FCI < 0.35,直线滤失 | 提高规模、增加人工复杂程度 | 加大单段液量、提高排量、加密簇数 | 主缝为主,净压提升能压开更多弱面 |
| FCI 0.35~0.65,压力依赖滤失 | 先压滤失,再试规模 | 增加降滤失剂、降低前置液排量、小粒径支撑剂段塞 | 净压再升高会被天然裂缝大量吸走 |
| FCI > 0.65,多峰导数 | 控净压峰值、防砂堵 | 减少单段簇数、增加段间暂堵转向 | 多缝竞争下近井磨蚀风险最高 |
| 关井后裂缝延伸明显 | 延长低排量阶段 | 阶梯降排量、缩短高排量段 | 停泵后惯性扩展会导致早期砂液分布不均 |
以FCI > 0.65的井为例,我一般不会继续加高排量,而是把单段簇数从4簇降到3簇,并预留一次暂堵转向机会。高复杂性井的裂缝本来就有大量分支,4簇同时起裂时只有1到2簇真正进液,其余簇只是“陪跑”,暂堵转向能把液体重新分配给未起裂簇。低复杂性井则相反,主缝相对单一,多簇陪跑概率较低,加密簇数和提高排量的收益更直接。
5.2 开发部署:井距、簇距与平台顺序调整
G函数分析对开发部署的贡献,主要体现在井距和簇距的差异化设计上。常规页岩开发平台经常统一按固定井距布井,但压后评价一旦表明局部地应力区带裂缝复杂性差异明显,统一井距就会代价偏高。
我常用一套倾向性决策逻辑:FCI > 0.7的井区,裂缝复杂程度高,缝网范围更大,水平井距离宜从常规的400米放宽到600米左右,平台井排之间错位0.3倍井距,降低邻井压裂干扰;FCI < 0.35的井区,裂缝简单,簇间距可以压缩到15到20米,用多簇制造人工复杂度,同时保持井距在400米以内,避免留下未动用条带。中间段则维持设计井距,但把压裂顺序改为先压高FCI井,后压低FCI井,利用先压井的应力阴影改善后压井的裂缝转向。
重复压裂候选井排序也可以直接用到这些成果。老井是否值得重压,有三个指标最要紧:FCI是否偏低(说明第一次没造出复杂缝网)、剩余储量丰度、邻井压裂干扰历史。临时排序可以用fci + remaining_gas + interference_index简单打分,高者优先。这类排序不需要额外建模型,现场工程师用Excel或Python都能维护。
5.3 用一口井的数据反推一套井组试验设计
单井G函数分析的产出,不应只停留在“这口井复杂程度中高”这个结论上。更值得做的是把它变成一个井组对比试验的输入:同一平台选出两排井,一排按FCI调整压裂参数,另一排维持常规设计,然后对比三个月累积产气、微地震事件密度反演体积和压降曲线形态的差异。G函数每个月复查一次压裂井的压降段,形成的闭环数据比单纯依赖产量评价要快得多。
这个试验的成本主要在监测设计和数据采集一致性上。两排井必须使用相同规格的压力计和采样频率,地面压力、井下压力和排量字段统一命名,保存格式统一成CSV。这样后续跑G函数分析脚本时,唯一需要改的输入就是井名前缀。现场很多所谓的“参数优化”做不到位,就是因为对比组之间压力计精度不一致,导致G函数结果差异无法判断来自储层还是来自仪器。
6. 落地时最容易踩的 3 个 G 函数分析坑
6.1 关井时间不够长,导数尾巴还没进入线性段就收盘
G函数闭合点判断依赖关井后进入线性滤失的尾部段,但页岩基质滤失极慢,经常出现关井时间不足、导数曲线一直处于过渡带的情况。判别方法很简单:计算关井段的theta最大值,即(t_shut - tp) / tp,如果小于2.5,闭合点大概率没有暴露出来。此时程序会自动选出一个“候选闭合点”,但那只是过渡带的拐点,不是真正的裂缝闭合应力。
应对办法是把关井时间延长到至少2倍注入时长,复杂缝井建议3倍。如果现场因为钻机计划或井筒安全限制不能延关,就在报告里明确标记该井为“不完整G函数”,闭合应力梯度只能做参考,不能进入FCI评分。
6.2 把井口压力当成井底压力直接算
井口压力包含液柱和摩阻的贡献,页岩气井垂深通常在3500米以上,1050 kg/m3的压裂液柱压力就达到36到45 MPa。直接把井口压力当作井底压力用,闭合应力梯度会系统性偏高,FCI里的净压力项失真,后续所有判断跟着错。
现场快速核对的方法是停泵后取一个稳定点的井口压力,用密度折算公式P_bh = P_wh + rho * 9.81 * md / 1e6 - fric_pdrop手算一遍,和井下压力计读数对比。误差在1 MPa以内说明折算可用;误差超过2 MPa要检查是不是漏掉了停泵后摩阻项,或者井筒内残留砂液密度发生了变化。
6.3 不交叉验证就信导数形态
G函数导数形态最怕两种假象:压力计噪声带来的假双峰,和井筒漏失造成的假压力依赖滤失。这两个假象都能骗过自动识别算法,但骗不过多维交叉验证。当FCI显示高复杂性、而微地震事件密度明显偏低时,先怀疑G函数输入数据;当事件密度高、FCI反而低时,先怀疑微地震覆盖范围不够。
最终我习惯把微地震事件密度、示踪剂返排曲线和G函数分析结果放在同一时间轴上看。真正复杂裂缝井的示踪剂返排曲线会出现明显长尾,事件密度峰值应落在dP/dG曲线突变对应的深度段附近。两者一致,FCI才敢进部署决策;不一致,就回到原始压力数据重新排查。
本文还有配套的精品资源,点击获取