Comsol多孔介质两相流模拟:水驱油过程建模与实战解析
2026/9/10 10:57:13 网站建设 项目流程

水驱油,这几个字在我们做油气田开发模拟的人眼里,其实就是把地层里那些靠天然能量已经采不出来的原油,用注入水一点一点顶出来。整个过程听起来简单,真正落到数值模拟层面就麻烦不少:水进到孔隙里不是均匀推进的,而是会沿着高渗条带形成指进,油水两相之间还有一个模糊的过渡带,再加上毛细压力和相对渗透率的非线性关系,这些物理机制叠在一起,用单一连续介质方程根本描述不清楚。所以我把目光放在了Comsol Multiphysics上,用多孔介质两相流框架去还原这个水驱油过程。

这篇内容适合两类人看:一类是刚开始接触多孔介质多相流、被一堆饱和度方程和相对渗透率模型劝退的研究生,另一类是在做储层/岩土/环境渗流相关项目、想快速搭一个可复现模型来验证自己方案的工程师。这里我不谈教科书上那种从零推导理论的过程,而是直接告诉你:Comsol里做水驱油模拟,需要关注哪几个物理量、怎么设置相场和Darcy接口、最容易出问题的网格和求解器配置在哪,以及我踩过的那些坑是怎么填平的。

整个模型我从搭建到出结果一共花了两天半,中间删掉重建了好几次,最后跑通的方案比最初设想的要稳很多。下面从头拆解。

1. 水驱油模拟的核心物理图景与Comsol方案选型

1.1 多孔介质多相流到底在算什么

先捋一下我们面对的对象。多孔介质粗略理解就是一块海绵或一块砂岩,里面有大量的微小孔隙和喉道,流体只能在连通的空间里流动。原油刚开始是均匀分布在孔隙里的,注入井以恒定压力或恒定流速往里面打水,水沿着孔隙通道推进,把油从生产井那端逼出来。

这里面有两个尺度的问题值得先说清楚。在我做的这个模型里,采用的是连续介质尺度,也就是把岩石骨架中的每个数学单元体看作包含孔隙和骨架的“等效体”,用孔隙度、渗透率、饱和度来宏观描述,而不是真的把某一条孔隙通道用三维几何画出来。这样做的好处是计算量可以接受,而且工程上最关心的是油、水两个相的推进前缘和压力剖面,而不是单个孔隙内部的流动细节。

多相流的核心方程,是基于Darcy定律扩展出来的两相流动方程,油相和水相各写一个动量方程和一个质量守恒方程。每个相都有一个独立的压力场,而两相之间的压差就是毛细压力,它是饱和度的函数。再加上相对渗透率,它也随饱和度变化。这几个变量之间互相耦合、互相制约,所以求解过程本质上是一个强非线性问题。

用大白话描述就是:水往前跑的时候,孔隙里含水饱和度升高,水的相对渗透率变大,油必须让出通道;反过来,某个位置油的饱和度越高,油越容易流动,水就越难往那边挤。这个“你争我让”的过程,就是水驱油模拟的底层逻辑。

1.2 为什么选Comsol而不是CFD工具

有人可能会问,水驱油用Fluent、OpenFOAM这类CFD工具不是也很常规吗?确实可以,但我选择Comsol的原因有三个。

第一,多相流Darcy模型在Comsol中被封装成了专门的物理接口,不需要像在CFD工具里那样自己耦合多孔介质动量源项和相输运方程。Comsol里有现成的“多孔介质多相流”多物理场耦合,底层帮你把Darcy定律、饱和度输运方程、毛细压力模型组合到一起。

第二,Comsol对各种材料属性和自定义方程支持非常方便。比如相对渗透率曲线,你可以用内置的Brooks-Corey或van Genuchten模型直接填参数,也可以自己写一个分段函数插入进来。这对于模拟不同岩心实验数据的情况非常友好。

第三,Comsol后处理高度集成,尤其是在观察油水前缘推进、动态调整监测点时,比把计算结果导出到其他软件里再画图省事很多。我后来还顺手用它做了Desktop高密度3D打印样件的热-力耦合扩展阅读,发现同一套多物理场框架确实能覆盖很多不同的物理过程,手感熟悉之后跨度很大也不慌。

1.3 物理接口与算法选择:两相流Darcy、相场、水平集

Comsol里处理多孔介质多相流,主要有三条路:两相流Darcy接口、相场接口、水平集接口。不少人第一次进入“模型向导”时看到一堆接口名字会懵,我用过之后给你一个直接的选择建议。

如果模拟的目标是油水两相在孔隙介质中的宏观推进,优先考虑“多孔介质多相流”下的两相流Darcy定律接口。这个接口是专门为饱和度方程设计的,计算的是Darcy速度场和压力场,同时输运水相饱和度。它不需要显式捕捉油水界面,适合地层尺度和岩心尺度。

如果是想把孔隙尺度上的油水界面边界层效应也模拟出来,或者你的模型几何本身是孔隙级微通道,那就用“两相流,相场”或“两相流,水平集”。这两个都是基于界面捕获方法,计算量明显更大,但能够得到更精细的界面形态,适用于数字岩心、微流控芯片这类场景。

我做的是长约1 m、高约0.2 m的二维模型,属于典型的宏观岩心尺度,所以果断选了两相流Darcy接口加Brooks-Corey相对渗透率模型。后面的所有设置都围绕这个方案来展开。

2. 模型搭建全流程:从几何到边界条件

2.1 几何建模与材料参数怎么填

打开Comsol后,建议直接选择二维模型。先在最左侧的组件节点下创建几何,用矩形画一个长1 m、高0.2 m的岩心区域。不需要画注入井孔洞,因为在这个尺度上,井筒细节没有意义,直接定义边界条件就能代表注采过程,这也是连续介质模型的常见处理方式。

材料块方面,我在多孔介质子节点下给整个矩形域赋予同一组多孔介质属性,主要包括孔隙度、渗透率和有效扩散张量(如果是等温不涉及组分扩散,扩散项可以不管)。

我用的参数组合是:孔隙度0.35,渗透率100 mD。这里要解释一下单位,100 mD换算成国际单位约为1e-13 平方米,这个值代表一个中等渗透率的砂岩岩心,比较有代表性。如果渗透率太低,注水压力就需要给得很大,早期算起来容易发散;如果太高,油相又很容易被一下子全部推出,缺乏“指进”效果,不方便观察现象。

流体的物性参数也很关键。水相密度设为998 kg/m^3,动力粘度1e-3 Pa·s;油相密度设定稍轻一点,800 kg/m^3,粘度设为50e-3 Pa·s。这组参数很好的模拟了一种典型的中质原油,粘度是水的50倍,这样的粘度差最容易在水驱过程中出现粘性指进现象,结果直观且具有代表性。

我建议你在第一次做的时候不要用太极端的参数,先保证容易收敛,模型跑通后再把粘度拉大、换渗透率做敏感性分析。

2.2 相对渗透率与毛细压力模型的计算

两相流Darcy接口里,水相和油相各自的流动方程是分开写的,但两相的相对渗透率和毛细压力都会统一挂在同一个液相属性节点下。Comsol里比较常用的是Brooks-Corey模型,它的数学形式是:

水相相对渗透率 k_rw = (S_e)^( (2 + 3λ)/λ )

油相相对渗透率 k_ro = (1 - S_e)^2 * (1 - S_e²)

其中S_e是有效水饱和度,S_e = (S_w - S_wr)/(1 - S_wr - S_or),S_wr是束缚水饱和度,S_or是残余油饱和度。

我在模型里给的束缚水饱和度S_wr是0.2,残余油饱和度S_or是0.15,孔径分布指数λ取2。这样算下来,当含水饱和度为0.2时,水相相对渗透率为0,即水完全不流动;饱和度为0.85时,油相相对渗透率为0,即油被锁住无法移动。

这些参数看着简单,但实际经验是:饱和度端点值设置不当,会导致某个相在边界面上的计算不收敛,尤其是初始时刻饱和度若接近残余油饱和度,那油相相对渗透率趋近于零,方程数值性质会变得很差。所以我建议把初始含水饱和度设在0.21左右,而不是正好等于束缚水饱和度,这样既接近实际情况,又不至于让油相流动性一开始就为零。

毛细压力我用的是van Genuchten形式,p_c = -p_0 * ((S_e)^(-1/m) - 1)^(1/n),其中p_0取5000 Pa,m和n由经验公式关联。毛细压力在宏观尺度上的具体值虽然比注水压差小不少,但它在饱和度前缘的玫瑰花状分布中起关键作用,不能直接设为0,否则前缘推进形态会产生偏差。

2.3 初始条件与边界条件的设置思路

初始条件设置很简单,把整个计算域初始水饱和度设为0.21,油饱和度是0.79。初始压力场我并没选择零压力开始,而是做了一个静水平衡式的估算,让注入压力从入口到出口线性分布,这样求解器在第一步迭代时就不会出现压力剧烈调整。

边界条件我分成左、右、上、下四个边界来处理。左边界是注入端,我给定一个速度型条件,也就是质量流量边界,让水以恒定速率注入,换算成Darcy速度大约为1e-4 m/s,这个值很小,确保渗流处于层流Darcy适用范围内。右边界是生产端,设为定压边界,压力为0,即表压为0的开放出口。上下边界做对称或者无流动边界。

有一个细节容易忽略,就是在地层/岩心出流边界上。如果直接使用“通量”边界而不限制流体回流,一旦局部压力反超出口压力,油或水可能会从外面回流进计算域,出现非物理震荡。我的做法是加了一个“仅流出”条件,这是Comsol提供的一个约束选项,相当于单向阀,只允许计算域里的流体流出去,不允许外部流体倒灌回来,效果很稳定。

3. 网格划分与求解器设置的实操要点

3.1 网格策略:粗网格为什么会让前缘糊掉

网格这件事,可以说是多相流模拟里最让人头疼的一环。我前后试过三种网格密度:100 × 20,200 × 40和400 × 80。对比下来,100 × 20这个极度粗糙的方案,算出来饱和度云图虽然也能看出大致的前缘推进,但过渡带特别宽,含水饱和度从0.2到0.8跨越了接近四分之一的模型长度,这种情况物理上不合理,属于典型数值弥散。

我最终用的是200 × 40的映射网格,在注水入口和出口附近做了局部加密。做法是先给上下左右边界定义好分布,点击“映射”生成矩形网格,然后用一个分布节点把左边界附近40%的网格密度提高一倍。这个做法其实就是在保证精度的同时不让计算量爆炸,因为前缘先从左端发育,那边的饱和度梯度最大。

对于Darcy模型,因为用不到边界层的壁面定律,不需要像CFD那样去画很薄的边界层网格。实际上,在宏观多孔介质Darcy求解中,边界处的速度满足的是无穿透条件,不存在速度梯度剧烈变化,所以强行加密边界层反而只会增加无意义的计算开销。

网格质量控制我是这么把握的:先跑一个200×40的网格,记录入口流量、出口采出量这些关键响应值,再加密到400×80,如果两次计算结果的采收率曲线偏差小于2%,说明网格已经收敛。如果偏差大,再回头调整。

3.2 求解器与时间步的控制

两相流Darcy问题是一个典型的瞬态强非线性问题,求解器用全耦合,线性解算器我用PARDISO。PARDISO这种直接求解器可以避免Krylov迭代方法在处理不对称系数矩阵时出现的收敛不稳,代价是内存占用较高,但对于二维中型规模模型(2万个自由度以内)完全没问题。

时间步进方式我建议选BDF,最大阶次设到2。BDF在刚性问题中表现比广义alpha更稳定,而水驱油前缘移动过程中饱和度方程经常会从平滑变剧烈,用BDF能减少振荡。

时间步控制是最影响效率的地方。我最初直接用固定时间步长0.01 s,跑了一个小时后才推进到一半时间,效率实在太低。后来我改成自由时间步,并设置一个初始步长为1e-4 s、最大步长5 s,配合相对误差10^-4做自适应控制。这样前缘位置变化快时会自动加密时间步,前缘移动到中段后步长会逐渐放大,整体计算时间能缩短三分之二以上。

在后期油水前缘快到出口时,建议手动把最大时间步降低到1 s,不然采样点曲线会出现台阶状跳动。这个台阶状问题如果发生,不要怪物理模型,大概率是时间步太大导致饱和度前缘“跳跃”过了监测点位置。

3.3 如何判断计算结果已经收敛

判断收敛,不能只顾着看求解器有没有报错,还要观察几个关键量的曲线是否平滑。我主要看两个:出口含水率随时间变化曲线,以及整个模型区域内的平均油饱和度变化曲线。

如果出口含水率曲线出现毛刺、抖动,首先排查是不是时间步太大;如果含水率曲线根本没有上升趋势,大概率是初始条件设置时油和水饱和度给错了,导致油相一开始就不能流动。还有一次我碰到了高振荡警告,检查后发现是某些网格单元里的饱和度降到负值,此时需要在物理接口设置中开启饱和度下限限制,再把初始水饱和度从0.2调到0.21,问题就消失了。

4. 结果后处理与数据提取

4.1 观察油水前缘推进形态

计算完成后,最有成就感的一步就是点开“二维绘图组”,选“表面”,把表达式切换成水的饱和度sw,然后播放时间动画。可以看到水的饱和度从左边界开始一点一点向右侧推进,前缘形态不是一条直线,而是呈现出细长的指状凸起,这就是粘性指进现象。

细想为什么会形成指进:模型里油相粘度是水相粘度的50倍,高粘度油对水产生了很强的流动阻力,水更倾向于从已经形成水流的低阻力通道往前突进,这种不稳定推进在图上看就是一条条往前伸的“手指”。

这里有一个重要的后处理技巧:饱和度云图的默认色标范围是全局最小到全局最大,但在初始时刻全局最小可能显示成0.19左右,这不方便观察。我习惯把色标范围锁定在0.2到1之间,这样初期微小变化也能看得清楚。做法是在表面绘图节点的“范围”选项卡中手动设置最大值和最小值,才能让动画的颜色映射更稳定。

如果想把界面位置更清晰地提取出来,可以画一条等值线,在等值线表达式里填sw,设为0.5,这条线就是油水界面的大致位置。观察它在不同时间点的位置差异,可以直接看出推进速度是否均匀。

4.2 含水率与采出程度曲线怎么画

光看云图还不够,工程上总要用曲线做定量分析。我通常是定义几个全局计算表达式:出口水通量除以出口总通量就是产水率fw;平均初始油饱和度减当前平均油饱和度,再除以初始油饱和度,就是采出程度。

绘制这两个量的时间曲线时,Comsol的“派生值”菜单下的“全局计算”可以直接处理。先选中全部域,在表达式里写mean(sw),然后把它和时间关联起来,生成一个采出程度时间曲线。这个曲线倒U型关系很明显:刚开始一段时间水没到出口,产油量以较高水平持续输出;当前缘突破之后,产水率快速上升,采油速率迅速下降,采出程度曲线也随之变得平缓。

曲线里最能说明问题的指标是“见水时间”,也就是含水率开始上升的时间节点。它和模型里的注入速度、两相粘度比都有直接关系。我后来做了三组不同注入速度的对比模拟,明显看到注入速度越快,见水时间越早,但总采收率反而稍微下降,原因是高速驱替更容易把水从高渗通道短路掉,低渗区里的油没有足够时间被置换出来。这个结论在油田开发方案中很有参考价值。

4.3 残余油是怎么分布的

最后再分析一下残余油的分布。查看油相饱和度so(等于1-sw)的云图,可以看到在经过长时间水驱后,模型的左下角和右下角区域仍然保留着较高油饱和度。左下角靠近入口的是由于水的推进主要从中央通道通过,角落处流速极低,油大部分被绕流截留;右下角则是靠近出口末端,水驱的波及系数有限,油无法被动用。

为了量化残余油,我在整个域内用积分算子算了一遍油饱和度对面积的积分,得到残余油体积分数,我把这个数据做成柱状图,分配到不同分区,就能清楚看到主流通道和被绕过区域的残余油占比差异。这些信息对指导后续的“调剖堵水”措施很有帮助,知道油主要被截留在哪个区域,才能决定是注聚合物调整粘度比,还是细化注采井网。

5. 常见问题与排查技巧实录

5.1 典型报错与解决方法

我在做这个模拟时前后遇到了几个典型问题,挑有代表性的列出来,给你排查时做个参考。

求解器报“找不到初始解”是最常见的。我第一次遇到时第一反应是模型方程写错了,实际上检查后发现是材料属性的单位没对上。分子级渗透率有mD和m^2两套单位,我一开始顺手填了100 m^2,这直接让Darcy方程快溢出。把渗透率改成1e-13 m^2后,模型立刻正常。

第二种情况是收敛迭代次数过多,每步都要迭代几十次才能满足容差。这时候先看相对渗透率曲线端值。如果初始饱和度正好设在束缚水饱和度0.2,那么水的相对渗透率为0,方程雅可比矩阵出现退化特征,导致每步迭代都很艰难。解决方法是把初始水饱和度改为0.21,让方程水相部分保有正梯度,收敛速度明显加快。

还有一种情况是在饱和度前缘位置的网格单元上出现振荡,表现为云图上有一条条带状噪声。这通常是因为局部时间步太大,或者网格太粗。我会优先回到网格设置,把前缘可能经过的区域细分,然后把BDF阶次降为1,时间步最大限制收紧,基本可以消除。

5.2 排查思路的优先级

如果你遇到水驱油模拟不收敛,我建议按这个顺序排查:先看材料属性和单位,再看初始条件,然后看边界条件,最后才调网格和求解器。很多新手一上来就改网格,其实往往问题出在最基本的单位换算上。

单位问题用Comsol的“单位检查”工具可以直接排查;初始条件则看饱和度是否落在合理区间,尤其是油相饱和度必须留出流动空间;边界条件重点检查出口是否可能倒流,用之前提到的“仅流出”条件可以一劳永逸解决。

网格方面我建议用“网格统计”查看最小单元质量,如果最小质量低于0.3,哪怕是拉格朗日型Darcy方程也会开始出问题。在二维矩形几何下,映射网格的单元质量一般能保持在0.9以上,如果哪些区域单元质量过低,直接局部重画即可。

5.3 几个额外的实用细节

最后分享三个容易被忽略但很务实的小细节。

第一,多物理场接口中如果开启了“自动开启一致稳定化”,在Darcy类的多孔介质流动中一般不要关闭。这个选项会添加流线扩散和侧风扩散,对抑制前缘震荡非常有帮助。有些CFD背景的用户习惯把稳定化关掉,但在多孔介质Darcy框架下这会导致解出现严重振荡。

第二,采样点时不要直接选网格节点。我用点监测功能在整个区域布置了若干监测点后,发现位置稍微偏离网格节点时,曲线会抖动得很厉害。后来我把监测点全部放在几何顶点或边线上的均匀位置,数据就平滑了,其实底层原因是插值失真。

第三,模型跑完后记得多保存几个状态。我通常会在时间推进过半时存一个中间结果文件,即处理不同敏感性参数时可以直接以这个状态为初始值继续跑,不用从头算起。这个习惯在后来的多工况对比中为我节省了大量时间。

做实操类仿真的乐趣就在于,从“方程写出来”到“图像动起来”的这段距离里,每一个参数的选择背后都有它的理由。水驱油这个经典问题,恰好把这些关键环节密集地串在了一起。有了这套思路和排查经验,相信你也能顺利完成自己的模拟实验。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询