The MATLAB Reservoir Simulation Toolbox (MRST) API

[ ].

在 MATLAB 中,数组后加点(. 是用于矩阵操作的符号。它通常出现在运算符或函数中,以指示逐元素操作(element-wise operation)。

A = [1, 2, 3];
B = [4, 5, 6];

% 逐元素相乘
C = A .* B; % [1*4, 2*5, 3*6] -> [4, 10, 18]

% 逐元素相除
D = A ./ B; % [1/4, 2/5, 3/6] -> [0.25, 0.4, 0.5]

% 逐元素幂
E = A .^ 2; % [1^2, 2^2, 3^2] -> [1, 4, 9]

 [a b c] & [a, b, c] & [a; b; c] 

两者都创建了一个 行向量,并将 abc 作为元素放入其中,在 MATLAB 中,空格和逗号都能作为更通用的分隔符来使用,分号分隔行向量。

>>>[1 2 3]

ans =

     1     2     3
>>>[1, 2, 3]

ans =

     1     2     3

>>>[1;2;3]
ans =

     1
     2
>>>[1 2 3; 4 5 6]
ans =

     1     2     3
     4     5     6
>>>[1,2,3; 4,5,6]

ans =

     1     2     3
     4     5     6

tic & top()

tic 与 toc 函数结合使用,可以测量经过的时间。tic 函数记录当前时间,toc 函数使用记录的值计算经过的时间。

>>>tSart = tic;
>>>tEnd = toc(tSart); % second
tEnd =

   16.7231

repmat(uvarargin)

注:repmat 是 MATLAB 的函数,用于重复数组

>>>repmat([1000, 100, 10].* milli*darcy(), [3, 1])
ans =

   1.0e-12 *

    0.9869    0.0987    0.0099
    0.9869    0.0987    0.0099
    0.9869    0.0987    0.0099

其中,milli * darcy(),MRST 中常用单位转换函数,darcy():表示渗透率的单位 达西 (Darcy),milli:表示1e-3的单位缩放。milli * darcy():将渗透率从达西单位转换到毫达西 (mD)。

ind2sub(size,idx)

注:在 MATLAB 中,ind2sub 是一个函数,用于将线性索引(linear index)转换为矩阵的子脚标(subscripts)。它常用在矩阵操作中,特别是在需要从线性索引定位到矩阵元素时。

输入参数:

  • siz:矩阵的大小shape,使用形如 [...,rows, cols] 的向量表示。
  • idx:线性索引,是指按照列优先顺序展开矩阵时的索引。

输出:根据1Dflatten元素获取执行shape矩阵的对应索引位置[...,i,j]

>>>A = [1 4;
        2 5;
        3 6];
>>>size(A)

ans =

     3     2
>>>[i,j] = ind2sub(size(A), 4)
i =

     1


j =

     2
>>>[i,j]=ind2sub(size(A), 1:4)
i =

     1     2     3     1


j =

     1     1     1     2

figure and clf

 注:figure,创建一个新的图窗,每次调用 figure 会生成一个新的图窗,默认编号会递增。clf清除当前活动图窗所有内容,但不会关闭图窗。

view(2 or 3)(za,el)

注:view(2)表示初始图像展示以二维视图 ,view(3)表示为三维视图,(Matlab)视图都是可以手动拖拽调整的,在 MATLAB 中view(za,el),view(30, 50) 是用来设置三维图形的观察角度的函数。

(za,el)输入参数:

  • az(azimuth):水平旋转角度(方位角),以角度表示,从 x 轴正方向逆时针测量,范围是 [0,360]。
  • el(elevation):垂直旋转角度(仰角),以角度表示,从 x-y 平面向上测量,范围是 [−90,90]。

initVariablesADI 

注:initVariablesADI 用于初始化自动微分的变量,并追踪它们的计算过程。它能够帮助你通过自动微分计算梯度(导数)信息。在 自动微分(Automatic Differentiation, AD)中,ADI 变量通常包含两个重要的属性:valjac,val 表示自动微分变量的 当前值,jac 是自动微分变量的 雅可比矩阵(Jacobian),它存储了该变量对其他变量的 偏导数。

>>>[x, y] = initVariablesADI(1, 2);  % 初始化变量 x 和 y
x = 

  ADI - 属性:

    val: 1
    jac: {[1]  [0]}


y = 

  ADI - 属性:

    val: 2
    jac: {[0]  [1]}
>>>x
x = 

  ADI - 属性:

    val: 1
    jac: {[1]  [0]}
>>>y
y = 

  ADI - 属性:

    val: 2
    jac: {[0]  [1]}
>>>z = 3 * exp(-x .* y)

z = 

  ADI - 属性:

    val: 0.4060
    jac: {[-0.8120]  [-0.4060]}

注: z_x其实就是jac{1},显示 z 对 x 的偏导数(雅可比矩阵的第一列),z_y其实就是jac{1},显示 z 对 y 的偏导数(雅可比矩阵的第二列),序号是根据initVariablesADI变量顺序确定

gradient 

gradient 是 MATLAB 自带的一个函数(数值计算工具),gradient 函数用于计算数值数据的梯度(差分),它可以对一个向量或矩阵进行梯度计算,返回该向量或矩阵沿着每个维度的导数(即梯度)。

>>>[1, 2, 3; 4, 5, 6; 7, 8, 9]
ans =

     1     2     3
     4     5     6
     7     8     9

>>>gradient([1, 2, 3; 4, 5, 6; 7, 8, 9])
ans =

     1     1     1
     1     1     1
     1     1     1

 gridProcessing

gridProcessing 是用于处理和操作油藏网格数据的工具集。油藏网格(grid)是油藏模拟中的核心部分,它将油藏空间离散化为若干个小单元格(grid cells),这些单元格用来模拟流体的流动、储存和分布。它提供了网格生成、网格几何计算、属性赋值、网格合并等一系列功能,帮助用户有效地处理油藏模型中的网格数据,并优化模拟的效率和精度。通过合理的网格处理,可以更好地支持油藏模拟、流体分析和油藏开发决策。

cartGrid(dims,phyDims)

注:生成笛卡尔网格(Cartesian Grid),physdim OPTIONAL. Default value == celldim,Core functionality — The Matlab Reservoir Simulation Toolbox 2019b documentation

phyDims表示物理尺度,单位一般为米,指定[lx,ly]按dims网格大小等分,每一个单元物理长度宽度表示为lx/nx,ly/ny。

return G struct包括cells、faces、nodes、cartDims、type、griddim等部分。

G.cells 存储网格中单元(cells)的几何和拓扑信息,G.cells为网格(网格单元是物理计算的基本单位,每个单元都表示一个离散区域),属性包括num、facePos、IndexMap、faces等部分,其中(num=nx*ny*nz)。

         G.cells.num:存储网格中单元的总数。

         G.cells.facePos:每个单元在 G.cells.faces 中的起始索引,用于快速查找单元与哪些面相关联。

   G.cells.indexMap存储网格单元索引的映射。通常用于从笛卡尔网格(或初始网格)映射到当前网格。

         G.cells.faces:每个单元关联的面信息,每一行表示一个面,列的格式为 [face_index, orientation],face_index 是面的索引,orientation 表示面相对于单元的朝向(+1 或 -1)。

G.faces 存储网格中面(faces)的几何和邻接关系信息。面是网格中连接单元或边界的部分。属性有num、nodePos、neighbors、tag、nodes等部分。

   G.faces.num:网格面的数量,网格面数量是网格中所有独立面(不重复的)总和,网格面分内部面和边界面,官方标识:网格中全局面的数量,例如,G.cartDims=[50,50];G.cells.num=2500,G.faces.num=5100,G.cells.faces.num=2500x4(2D网格)。

G.faces.nodePos:每个面的节点在 G.faces.nodes 中的起始索引

   G.faces.neighbors:每个面相邻的单元索引,格式为 [单元1, 单元2],如果是边界面,其中一个单元为 0

         G.faces.tag:用于标记面的属性或类别,常用于区分边界面类型(如流入边界、流出边界、封闭边界等)。

         G.faces.nodes:每个面相关的节点索引,按照 G.faces.nodePos 定义的范围分组。

 G.nodes:G.nodes 存储网格节点(nodes)的几何信息,节点是网格的基本几何点,定义了单元和面的形状。主要属性:G.nodes.num:网格节点的数量;G.nodes.coords:每个节点的坐标,维度为N_nodes × d。

G.cartDimsG.cartDims 是一个向量,表示笛卡尔网格的划分数量。对于规则笛卡尔网格,它的值为 [n_x, n_y, n_z],分别表示网格在 x、y、z 方向的划分数。

G.typeG.type 是一个字符串,表示网格的类型,"cartesian":规则笛卡尔网格,"triangular":三角形网格,"unstructured":非结构化网格。

总结,用于快速计算单元、节点和面的数量:

        单元数量,N_cells =nx × ny × nz

        节点数量,N_nodes=(nx + 1) × (ny + 1) × (nz + 1)

        面数量,N_faces取决于网格的边界条件和拓扑结构。

G.griddim:G.griddim 表示网格的几何维度;2:二维网格;3:三维网格。

>>>nx = 10; ny = 10; nz = 4;
>>>G = cartGrid([nx, ny, nz]);
>>>display(G);
G = 

  包含以下字段的 struct:

       cells: [1×1 struct]
       faces: [1×1 struct]
       nodes: [1×1 struct]
    cartDims: [10 10 4]
        type: {'tensorGrid'  'cartGrid'}
     griddim: 3
>>>plotGrid(G);

>>>plotGrid(G); view(3);

computeGeometry(G,varagin)

注:将几何信息(质心、体积、面积)添加到网格G中,Core functionality — The Matlab Reservoir Simulation Toolbox 2019b documentation

  • 计算网格单元的几何属性

    • 质心:为每个单元计算几何中心,存储在 G.cells.centroids 中。
    • 体积(二维为面积):为每个单元计算体积,存储在 G.cells.volumes 中。
  • 计算网格面的几何属性

    • 质心:为每个面计算几何中心,存储在 G.faces.centroids 中。
    • 法向量:为每个面计算法向量,存储在 G.faces.normals 中,表示面的朝向。
    • 面积:为每个面计算面积,存储在 G.faces.areas 中。
  • 拓扑结构更新

    • 更新网格的邻接信息。例如:
      • 每个面的相邻单元信息存储在 G.faces.neighbors 中。
      • 如果面是边界面,则对应的相邻单元索引为 0
  • 支持多种网格类型

    • 无论是笛卡尔网格、非结构化网格,还是复杂的三维网格,computeGeometry 都能够根据网格类型准确计算几何参数。

params.[rock & wells_and_bc]

 params 涉及井边界和岩石相关的函数主要包括定义岩石属性、井的边界条件、流体性质等。

这些参数和函数是进行油藏模拟时设置物理模型的关键部分。

rock:定义岩石的物理属性(如孔隙度、渗透率等),常见函数有定义岩石的物理属性(如孔隙度、渗透率等)makeRock(permeability, porosity)或创建岩石模型,指定渗透率、孔隙度等makeRock(permeability, porosity, capillaryPressure, saturation)。

wells_and_bc:井(Wells) 可以被视为一种特殊的 边界条件(Boundary Condition, BC),常见函数有:addWell、addBC、verticalWell、pside、fluxside等。

gravity

gravity 是影响流体流动的一个重要因素。它通常与流体的密度和油藏的倾斜角度有关。MRST 中通常通过设置 gravity 参数来考虑重力对流体流动的影响。

fluxside(bc, G, side, flux_value)

注:fluxside 可以代表与网格边界(faces 或 sides)相关的流量分布,可能用于,表示流体通过某些面(faces)的方向和速率,与边界条件(boundary conditions, BC)相关,定义流量的分布(例如注入、生产流量等)。

输入参数:

  • bc: 边界条件结构体。初始可以为空([]),用于定义新的边界条件。
  • G: 网格结构体,包含模拟网格信息(如单元、面和边界位置)。
  • side: 边界的方向,接受字符串值,例如 'LEFT', 'RIGHT', 'TOP', 'BOTTOM',定义流量所在的边界。
  • flux_value: 流量的大小,单位为体积流量(如 m^3/day),正值表示流入,负值表示流出。

输出:

bc: 更新后的边界条件结构体,用于后续求解器(如 incompTPFA)调用。

对于 v

  • []:

    表示初始化一个新的边界条件结构体,从空的条件开始设置。
  • G:

    网格结构体,必须已经通过 cartGridcomputeGeometry 定义好。
  • 'LEFT':

    表示流量边界条件施加在网格的左边界。
  • 1*meter^3/day():

    定义流量大小为 1 m^3/day,即每天通过左边界的流体体积。MRST 默认采用 SI 单位(m^3/day是常见的输入单位)。

>>>nx = 10; ny = 10; nz = 4;
>>>G = cartGrid([nx, ny, nz]);
>>>G = computeGeometry(G);
>>>fluxside([], G, 'LEFT',  1*meter^3/day())

ans = 

  包含以下字段的 struct:

     face: [40×1 double] % 左边界对应的面索引
     type: {1×40 cell}   % 边界条件类型
    value: [40×1 double] % 流量值(单位 SI,m³/s)
      sat: [40×1 double]

pside(bc, G, side, pressure_value)

注:用于为网格的指定边界设置一个指定压力值的边界条件。

输入参数:

  • bc: 边界条件结构体,表示已有的边界条件。如果初始为空,可以用 [] 传入。
  • G: 网格结构体,定义网格的几何形状和拓扑信息。
  • side: 表示施加边界条件的网格边界方向,可以是 'LEFT''RIGHT''TOP''BOTTOM'
  • pressure_value: 边界条件中指定的压力值,通常以 SI 单位帕(Pa)表示。

输入:

返回一个更新后的边界条件结构体 bc,包含施加的压力边界条件。(若bc不为[],则累加bc返回)


>>>nx = 10; ny = 10; nz = 4;
>>>G = cartGrid([nx, ny, nz]);
>>>G = computeGeometry(G);
>>>pside([], G, 'RIGHT', 0)
ans = 

  包含以下字段的 struct:

     face: [40×1 double]
     type: {1×40 cell}
    value: [40×1 double]
      sat: [40×1 double]

verticalWell(W, G, rock, i, j, varargin)

 注:verticalWell 是 MRST(MATLAB Reservoir Simulation Toolbox)中用于添加垂直井的工具函数,通常用于在模拟油藏时定义一口或多口垂直井。

W = verticalWell(W, G, rock, i, j, varargin)
输入参数:

  • W

    • 井结构数组(Well structure array)。
    • 如果添加第一口井,输入为空数组 []
  • G

    • 网格(Grid structure),定义油藏的几何形状和分割方式。
  • rock

    • 岩石属性,包含网格中渗透率(perm)等数据。
  • ij

    • 井在网格中的水平位置(以行和列的索引表示)。
  • varargin

    • 可选参数,用于设置井的属性,例如:
      • Type:井类型(如 bhp 表示井底压力控制,rate 表示流量控制)。
      • Val:控制值(如井底压力或流量)。
      • Radius:井的半径。
      • InnerProduct:使用的离散化方法(如 ip_tpf 表示两点流体流动方法)。

输出:

W

  • 包含井信息的结构体数组,其中每个元素代表一口井。字段包括:
    • cells:与井相交的网格单元。
    • type:井的类型,可以分别添加Type: rate,由流量(注入或生产速率)来决定。这种设置通常用于模拟特定流量条件下的油藏行为Type: bhpbottom hole pressure,表示井的操作受井底压力控制,流量控制),使用 bhp 控制的井适用于模拟井控压力条件下的流体流动,特别是在压力驱动为主要驱动力的场景(如水驱、气驱开发)。。
    • val:井的控制值,当井类型为'bhp':井的 Val 参数用来指定井口的目标压力,例如 1 * barsa(1 巴,约 101.3 千帕);当井类型为 'rate',井的 Val 参数表示注入或生产流量的大小,单位通常是立方米/天,正值表示注入流量,负值表示生产流量。
    • radius:井的半径。
    • 其他相关属性。

solvers

基础 solvers 模块提供了多种功能来处理油藏模拟中的流体计算和状态初始化等操作。下面详细介绍几个常用函数,computeTransinitResSolinitStateinitWellSol,以及它们在油藏模拟中的作用。

initResSol(G, initial_pressure)

initResSol 函数用于初始化油藏模拟的状态变量,例如压力、饱和度和流速.

输入参数,G:网络结构体,initial_pressure:初始压力值,设置为整个油藏中的统一初始压力。

输出参数,state:一个结构体,包含模拟初始条件的以下字段:

  • state.pressure:油藏中每个网格单元的初始压力。
  • state.s:油藏中每相流体的初始饱和度(默认为单相流模型)。
  • state.flux:网格面上的流量(默认为零)。
>>>nx = 10; ny = 10; nz = 4;
>>>G = cartGrid([nx, ny, nz]);
>>>G = computeGeometry(G);
>>>initResSol(G, 0.0)
ans = 

  包含以下字段的 struct:

    pressure: [400×1 double]
        flux: [1380×1 double]
           s: [400×1 double]

 initState(G, flux, pressure, s)

注:在 MRST(MATLAB Reservoir Simulation Toolbox)中,initState 是用于初始化模拟状态的函数。它定义了网格(grid)中的初始压力、通量、饱和度等变量,以便为后续的数值模拟提供基础。

输入参数:

  • G

    • 网格结构,表示计算区域。
    • 由网格生成函数(如 cartGridcomputeGeometry)定义。
  • flux

    • (可选)网格面上的初始通量,默认值为零。
    • 这是一个向量,其长度与网格的面数一致。
  • pressure

    • 初始压力值,可以是标量或网格中每个单元的一个向量。
    • 如果是标量,所有网格单元的压力都会设置为同一值。
  • s

    • (可选)初始饱和度,表示每个网格单元中各相的初始占比。
    • 通常是一个矩阵,每一列对应一个流体相,每一行对应一个网格单元。

输出:

state

  • 返回一个结构体,表示模拟的初始状态。
  • 包含以下字段:
    • pressure:网格单元中的初始压力值。
    • flux:网格面上的初始通量(如果定义了)。
    • s:初始饱和度,按相定义。

定义单向流初始状态:

% 定义网格
G = cartGrid([5, 5]);    % 创建 5x5 网格
G = computeGeometry(G);  % 计算几何信息

% 初始化状态
state = initState(G, [], 0, []); % 压力为 0,无通量

定义多相流初始状态:

% 定义网格
G = cartGrid([5, 5]);    % 创建 5x5 网格
G = computeGeometry(G);  % 计算几何信息

% 定义初始状态
% 初始压力为 100,饱和度:[1, 0](水相完全占据)
state = initState(G, [], 100, [1, 0]);

  • 定义多相流初始条件
    对于多相流模拟(如水驱油或气驱油),需要为每一相定义初始饱和度。

  • 为数值求解器提供初始状态
    如在调用 incompTPFAincompMimetic 时,initState 的输出用于存储求解的中间或最终结果。

computeTrans(G, rock)

注:在 MRST(Matlab Reservoir Simulation Toolbox)中,computeTrans 是一个非常重要的函数,用于计算网格模型的传输系数矩阵(transmissibility matrix),它是模拟流体流动的核心部分。computeTrans 函数通过网格的几何信息(如网格体积和面面积)以及岩石属性(如渗透率)来计算传输系数矩阵。这些系数反映了不同网格单元之间流体的可流动性(flow potential),对模拟流体流动非常关键。

输入参数:

  • G:
    • 网格结构体,包含网格的几何信息(如 cells, faces, nodes 等),需要通过 cartGridcomputeGeometry 初始化。
  • rock:
    • 岩石属性结构体,至少需要包括以下字段:
      • rock.perm: 单元格的绝对渗透率(Permeability),单位通常为 m^2 或 Darcy。
      • 可选:poro(孔隙度)等。

输出:

T: 一个稀疏矩阵,表示单元之间或与边界之间的传输系数,大小为G.cells.num × neighbors,在2D网格中,每个单元与4个单元链接,有4个neighbors3D网格中,则有6个neighbors

传输系数(Transmissibility):

表示两个相邻网格单元之间流体流动的能力,传输系数的计算公式基于达西定律,并取决于以下因素,网格单元的几何属性(面积、距离);单元间渗透率(rock.perm);单元的相对位置和网络拓扑。对于两个相邻单元i和j,传输系数可以近似为

T_{ij}=\frac{k_{ij}\cdot A_{ij}}{\mu \cdot d_{ij}}

其中k_ij表示两单元之间的有效渗透率;A_ij表示相邻单元间的交界面积;mu:表示流体粘度;d_ij表示两单元间的几何距离。

达西定律描述了多孔介质中流体流动的物理规律,定义为:

q=-T(p_{1}-p_2)

其中:

  • q:通过界面的流体流量,单位时间内通过网格单元或边界的体积流量(volumetric flow rate),它的单位通常为m^3/s。
  • T:传输系数,表示流体从一个单元流向另一个单元的可流动性(取决于渗透率、几何和流体粘度)。
  • p_1​ 和 p_2​:相邻单元的压力值。
  • 负号 (-):表示流动方向与压力梯度相反(流体从高压流向低压)。

plotting

 plotting 模块专门用于各种绘图功能,帮助用户可视化油藏模型、流体流动、井位等信息。这里是 plotting 模块中一些常用的绘图函数。常见绘画函数plotGrid、plotCellData、plotWell、plotGridVolumes等。

plotGrid

plotCellData

plotWell

plotGridVolumes(G, data)

注:绘制一组值的部分透明等值面,Keyword Arguments:‘basealpha’:设置为小于 1 的值可提高透明度,设置为较大的值可降低透明度。

显示饱和度数据时,实际上是在将每个网格单元的体积作为基础,按饱和度值对网格进行着色。尽管它主要用于显示网格单元的体积,但如果你将饱和度数据作为输入,可能会产生一种类似波动或扩散的效果,尤其是在模拟过程中,饱和度随时间的变化呈现扩散或波动的趋势

  • 网格体积与饱和度结合:在油藏模拟中,饱和度代表了某一相(如水或油)在某个网格单元中的占据程度。通过将饱和度与网格体积结合显示,plotGridVolumes 使得你能够看到不同大小的单元在模拟过程中的变化。
  • 空间分布:使用 plotGridVolumes 显示饱和度时,网格单元的颜色变化将体现出饱和度在空间上的分布。如果饱和度变化较快或存在波动,这种方式能够帮助你直观地看到饱和度在不同单元之间的差异。

plotGridVolumes 中,如果显示的是每个时间步骤的饱和度数据,那么你将能够看到这种扩散效果:从一个注入井(如水注井)或多个注水井向周围区域扩展

为什么会产生波形扩散的效果?

  1. 流体的传播:在水驱油或其他类型的流体驱替模拟中,注水井的水注入会在压力差的作用下推动油相或气相流动,改变相的分布,饱和度随之变化。这种变化可以呈现为扩散波动,在某些情况下,流体前沿可以呈现明显的波形扩展。

  2. 多相流的相互作用:在多相流(如油水系统)中,水相和油相之间的相互作用使得流动呈现复杂的动态特征。随着时间的推移,饱和度前沿从一个井口到另一个井口的传播过程,可能会表现为波动或扩散的趋势,尤其在非均质油藏中更加明显。

 

modules

丰富的模块集,可以帮助用户从油藏模拟的基础网格生成、流体流动、井建模、到高级优化与增强油气采收等一系列功能

注:modules模块集中具体模块使用需要mrstModule add [incomp,ad-core,ad-blackoild,....]操作。其他gridprocess、utils部分同modules目录在同级,启动mrst工具,functions默认可以直接调用。

 modules.incomp

incomp 模块主要用于处理 不可压缩流体模型,通常是针对 单相流二相流 系统的模拟。这个模块不直接支持 三相流 或更复杂的多相流模型(如油、水、气三相流)的模拟。离散化和求解器(不可压缩流,Incompressible flow)

该模块实现了表示不可压缩两相流所需的基本流体对象。为了求解这些流动方程,该模块为压力以及使用单点上游迁移率加权的显式隐式传输求解器提供了标准两点通量近似 (TPFA) 方法,可以将其组合在顺序求解过程中。 incomp 模块最初是核心模块的一部分,但在软件开始为更高级的流体模型提供求解器后,它被移至单独的模块。

 In MRST: mrstModule add incomp

incomp 模块采用的求解方法是 完全隐式方法(Fully Implicit Method),这种方法是油藏模拟中最常见的一种方法。完全隐式方法(也称为 隐式时间积分法)通过构造一个时间步的耦合方程组来进行求解。每一个时间步的状态都涉及到未来时刻的变量,需要在每个时间步解一个非线性方程组。通过这种方式,可以处理较大的时间步长和非线性问题,并保证数值稳定性。解决基本方程:

达西流动方程(Darcy's law)

v=-k\cdot \frac{\bigtriangledown p}{\mu }

其中,v是流体速度,k是渗透率,p是压力,\mu是流体粘度。

质量守恒方程(不可压缩流体):

\frac{\partial S}{\partial t}+\bigtriangledown \cdot v=0

其中,S是饱和度,v是流速。

压力方程

\bigtriangledown \cdot (k\cdot \bigtriangledown p)=\frac{1}{\mu}\cdot q

其中,q是注入或生产的流量,源汇相。

incomp 模块应用示例:

例如,在处理一个水驱油的油藏模型时,我们可以利用 incomp 模块模拟水和油的流动,并且通过求解压力场和饱和度场,预测水驱过程中油藏的响应。

mrstModule add incomp;
% 设置网格和物性
G = cartGrid([10, 10, 3], [500, 500, 100]);  % 创建网格
rock.perm = repmat(100 * milli*darcy, [G.cells.num, 1]);  % 均匀渗透率
rock.poro = repmat(0.3, [G.cells.num, 1]);  % 均匀孔隙度

% 设置流体模型(假设是两相流:水和油)
fluid = initSimpleFluid('mu', [1, 10] * centi*poise, 'rho', [1000, 800] * kilogram/meter^3, 'n', [2, 2]);

% 设置井(注水井和生产井)
W = verticalWell([], G, rock, 1, 1, [], 'Type', 'bhp', 'Val', 1 * barsa(), 'Radius', 0.1, 'InnerProduct', 'ip_tpf', 'Comp_i', [0, 1]);
W = verticalWell(W, G, rock, 10, 10, [], 'Type', 'bhp', 'Val', 0 * barsa(), 'Radius', 0.1, 'InnerProduct', 'ip_tpf', 'Comp_i', [1, 0]);

% 初始化状态
sol = initState(G, [], 0, [1, 0]);

% 计算传输系数
T = computeTrans(G, rock);

% 采用完全隐式方法求解
psolve = @(state) incompTPFA(state, G, T, fluid, 'wells', W);
sol = psolve(sol);

% 可视化
plotCellData(G, sol.s(:, 2)); % 显示油相饱和度
colorbar;

initSingleFluid(‘mu', viscosity, 'rho', density)

注:在 MRST(Matlab Reservoir Simulation Toolbox)中,initSingleFluid 是一个用于初始化单相流体性质的函数。它为单相流体(如水或油)定义其物理特性,供后续模拟中使用。

输入参数,'mu':流体的动力粘度(单位为 Pa·s 或 centipoise (cp)),'rho':流体的密度(单位为 kg/m³)。

输出,fluid:一个包含流体性质的结构体,包含模拟单相流体所需的各种属性,生成的 fluid 结构体通常包括以下字段:

  • viscosity:流体的动力粘度。
  • density:流体的密度。
  • properties:一个函数句柄,用于动态计算与压力或温度相关的流体性质
>>>initSingleFluid('mu' ,  1*centi*poise , 'rho', 1014*kilogram/meter^3)
rhoWS: 1014
         rhoOS: []
         rhoGS: []
            bW: @(p)1+0*p
            bO: @(p)[]
            bG: @(p)[]
           krW: @(s)1+0*s
           krO: @(s)[]
           krG: @(s)[]
           muW: @(p)opt.mu+0*p
           muO: @(p)[]
           muG: @(p)[]
    properties: @(varargin)properties(opt,varargin{:})
    saturation: @(x,varargin)x.s
       relperm: @(s,varargin)relperm(s,opt,varargin{:})

 initSimpleFluid(mu,rho,n)

注: 用于初始化简单的流体模型,支持二相流(例如油、水、气的两者组合),并提供基本的流体属性。

输入参数:

  • mu:粘度向量,每个相对应一个值(单位:Pa·s)。
  • rho:密度向量,每个相对应一个值(单位:kg/m³)。
  • n(可选):相对渗透率的指数。
  • 相对渗透率:基于简单幂函数 kr=Snk_{r} = S^nkr​=Sn,其中 S 是相的饱和度。

输出:

state结构体

  包含以下字段的 struct:

         rhoWS: 1014
         rhoOS: 859
            bW: @(p)1+0*p
            bO: @(p)1+0*p
           krW: @(s)s.^opt.n(1)
           krO: @(s)s.^opt.n(2)
           muW: @(p)opt.mu(1)+0*p
           muO: @(p)opt.mu(2)+0*p
    properties: @(varargin)properties(opt,varargin{:})
    saturation: @(x,varargin)x.s
       relperm: @(s,varargin)relperm(s,opt,varargin{:})

fluid = initSimpleFluid('mu', [1, 10]*centi*poise, ...
                        'rho', [1000, 700]*kilogram/meter^3, ...
                        'n', [2, 2]);
  •  定义一个油-水系统,油的粘度为 10 cP,水的粘度为 1 cP。
  • 油的密度为 700kg/m^3,水的密度为 1000 kg/m^3。
  • 相对渗透率采用S^2的模型。

implicitTransport (state, G, dT, rock, fluid, varargin)

注:implicitTransport 是 MRST(MATLAB Reservoir Simulation Toolbox)中的一个函数,用于隐式求解多相流中的传输方程。它的目标是模拟油藏中各相的饱和度演化,通常与压力求解器(如 incompTPFA 或其他方法)配合使用。

implicitTransport 解决了如下形式的传输方程(流体是不可压缩的,可以不用考虑密度,多相达西流Darcy flows):

\phi \frac{\partial S}{\partial t}+\triangledown \cdot (F(S))=q

其中:

  • S:相饱和度。
  • \phi(phi):孔隙度,表示多孔介质中可储存流体的比例。
  • F(S):传输通量,依赖于速度场、相对渗透率和饱和度。
  • q:源项(如井的注入或生产速率)。
  • 时间离散采用隐式格式,这意味着方程的所有项在当前时间步均被考虑。

F(S),流体通相,依赖速度场u,饱和度分布S,流体的相对渗透率。

F(S)=u\cdot k _{r}(S)\\ u=-\frac{k}{\mu }\triangledown P

其中,u为达西流速,k为绝对渗透率,mu为流体粘度,\triangledownP表示压力梯度,k _{r}(S)为相对渗透率函数,算通常基于经验公式或实验数据,例如简单的二次关系S. ^ 2, 水相相对渗透率为二次关系,那么油相则(1-s). ^2

在多相流中达西流速u可以进一步分解为各相的速度,例如:

u_{a}=-\frac{kk_{r.a}}{\mu ^{_{a}}}\triangledown P

其中,a表示某一相,k_r,a表示某一相的相对渗透率。

[state, report] = implicitTransport(state, G, dT, rock, fluid, varargin)

输入参数:

  • state:包含初始状态信息的结构体,包括压力、流量、饱和度等。
  • G:网格结构体。
  • dT:时间步长。
  • rock:描述岩石性质的结构体(如渗透率和孔隙度)。
  • fluid:描述流体性质的结构体(如黏度、密度、相对渗透率等)。
  • varargin:可选参数,如井的描述 (wells)、边界条件等。

输出:

  • state:更新后的状态,包括当前时间步的饱和度等信息。
  • report:包含迭代次数和收敛信息的结构体。

incompTPFA

注:incompTPFA 解决的是油藏模拟中的不可压缩流动问题。其目标是根据给定的岩石属性、传输系数矩阵、边界条件和初始状态来计算压力分布和流量。

输入参数:

  • state:

    • 表示当前流体的状态,至少包含 pressureflux 两个字段。
    • 可以通过 initResSol 初始化。
  • G:

    • 网格结构,包含几何信息(如单元、面、体积等)。
  • T:

    • 传输系数矩阵,通常通过 computeTrans 计算。
  • fluid:

    • 流体属性结构体,通常使用 initSingleFluid 定义。
  • 可选参数

    • source:源项,定义网格单元内的注入或生产速率。
    • bc:边界条件,用于指定压力或流量的边界约束。

输出:

state:

  • 更新后的流体状态,包含压力场(pressure)和面流量(flux),s、facePressure

pressure

  • 含义:每个网格单元的压力值。
  • 单位:通常为 Pa(帕斯卡)或 bar。
  • 来源:通过求解不可压缩流动的离散方程得到。
  • 用途
    • 描述压力场分布。
    • 用于后续计算面流量和其他二次变量。

flux

  • 含义:每个网格面的体积流量(通过网格面的流体速率)。
  • 单位:通常为 m3/s
  • 来源:根据压力梯度和传输系数计算:

q=-T\triangledown p

        其中T是传输系数, \triangledown p是压力梯度

s

  • 含义:每个单元的饱和度。
  • 单位:无量纲(0 到 1 的比例值)。
  • 来源:对于单相流模拟,通常初始化为单一值,如 s = 1(完全饱和)。
  • 用途
    • 多相流模拟中用于追踪不同相的分布。
    • 单相流模拟中常用作占位字段(非必须)。

facePressure

  • 含义:每个网格面的压力值。
  • 单位:与 pressure 相同。
  • 来源:通过插值或直接计算得出,用于提高流量计算的精度。
  • 用途
    • 用于验证面间压力的连续性。
    • 某些后处理步骤中需要此信息。

字段间的关系

  1. pressureflux

    • flux 通过达西定律从压力梯度计算得出。
    • flux∝−∇p。
  2. pressurefacePressure

    • facePressure 是单元压力的插值结果或在边界条件计算中的辅助变量。
  3. s 与其他字段

    • 单相流中,s 通常是恒定值,对流动计算无直接影响。
    • 多相流中,s 会动态变化,并反过来影响压力场和流量

modules.deckformat

工具(Utilities,Deck Reader)

 

该模块支持 ECLIPSE 油藏仿真软件数据格式的完整模拟平台的输入,包括输入读取、转换为 SI 单位以及构建网格、流体、岩石特性和油井的 MRST 对象。因此,该模块的功能对于在 ad-blackoil 和 ad-eor 模块中开发的完全隐式模拟器至关重要,但也用于大量 MRST 示例和教程中。

In MRST: mrstModule add deckformat

该模块实现了两种类型的初始化模拟设置的功能:从输入面板或从输出面板(重新启动文件)。后者并不完全完整。

输入面板:2012a 之前的版本具有“readGRDECL”功能,用于输入主要描述网格和基于单元格的属性的一系列关键字。新的输入支持由两个主要函数组成:“readEclipseDeck”和“convertDeckUnits”。前者执行实际数据读取,而后者将各种测量单位(例如渗透率值)转换为 MRST 严格的仅 SI 单位约定。除了输入读取之外,我们还添加了几个函数来根据特定模拟平台的描述构建基本 MRST 对象(例如网格、流体、岩石特性或井)。

重新启动文件:最近,我们还提供了读取和处理 ECLIPSE 无格式输出文件的功能。然后可以使用它们来设置新的模拟或从现有的模拟继续。

readEclipseDeck(fn)

注:读取的数据内容涉及油藏模型的多个方面,包括网格(GRID)、岩石属性(ROCK)、流体状态(STATES)、PVT表(TABLES)以及井信息(WELLS)

>>>current_dir = fileparts(mfilename('fullpath'));

>>>fn = fullfile(current_dir, 'data', 'SPE1CASE1.DATA');

>>>deck = readEclipseDeck(fn);


>>>disp(deck)
              RUNSPEC: [1×1 struct]
                 GRID: [1×1 struct]
                PROPS: [1×1 struct]
              REGIONS: [1×1 struct]
             SOLUTION: [1×1 struct]
              SUMMARY: [1×1 struct]
             SCHEDULE: [1×1 struct]
    UnhandledKeywords: [1×1 struct]
               PCUNIT: 6.8948e+03

1. RUNSPEC

这个部分包含了模型的基本设置和运行参数。它描述了油藏的总体信息,如网格尺寸、流体类型、时间步长等。

2. GRID

该部分包含网格的几何和拓扑结构,包括网格单元、网格坐标、连接关系等。它定义了油藏的物理网格。

3. PROPS

这个部分包含岩石和流体的属性。它包括孔隙度、渗透率、相对渗透率、流体PVT表等。

4. REGIONS

该部分定义了油藏模型中的区域,可能涉及区域划分、各区域的物理性质、不同区域的参数设置等。

5. SOLUTION

包含初始条件和求解相关的数据。包括初始压力、饱和度、温度等。

EQUIL (Equilibrium)

在油藏模拟中,EQUIL 表示流体的平衡状态,通常指的是油藏中各相的流体饱和度、压力、温度等达到了一个稳定的状态。例如,在水驱油或气驱油过程中的某一时刻,油气水三相可能已经达到了流体的平衡状态。

RSVD (Relative Saturation or Saturation Value Distribution)

RSVD 通常指的是油藏中各个网格单元的饱和度分布,或者相对饱和度值。它表示了油气水三相(或更多相)的分布情况。具体来说,在油气水系统中,RSVD 可能用于描述以下内容:

6. SUMMARY

汇总信息部分,通常包括模型的概述、参数设置、以及仿真结果的摘要信息。

8. UNHANDLEDKeywords

该部分包含未处理的关键字。在某些情况下,Eclipse 文件中可能存在 MRST 没有直接支持的字段或设置,这些字段将会被归类到 UNHANDLEDKeyword 中。

9. PCUNT

这个部分定义了控制油藏模型运行的参数,可能包含一些调度参数或者压力控制等数据。

initEclipseRock(deck)

注:这个函数与初始化岩石模型有关。deck 通常表示模型的输入数据结构(如岩石参数、物理属性等),这个函数可能通过加载或配置岩石的属性来初始化模拟。

compressRock(rock, G.cells.indexMap)

这个函数可能涉及到压缩岩石数据的操作。rock 可能是包含岩石物理特性(如孔隙度、渗透性等)的数据结构,而 G.cells.indexMap 则可能代表网格或单元格的索引映射,函数的作用可能是压缩这些岩石数据,优化存储或计算效率

initDeckADIFluid(deck)

用途: initDeckADIFluid 用于初始化一个符合 ADI (Adaptive Discretization Integration) 方法要求的流体模型。它是一个更通用的函数,可以支持更复杂的流体模型,通常用于需要与 Eclipse 格式输入数据 兼容的模拟。它可以从油藏的输入数据中自动提取流体的属性(如粘度、密度、相行为等),并为油藏模型生成一个适当的流体模型。

  • 输入要求: 它通常需要更多的输入,例如流体的状态方程、经验公式或具体的流体属性数据。initDeckADIFluid 可能会从指定的 Eclipse Deck 文件(如 .DATA 文件)中读取流体属性。
  • 功能特点:
    • 支持更复杂的相行为模型(如 多相流、气溶胶、溶解气体等),相比initSimpleFluid 需要提供流体的粘度、密度、以及相对渗透率指数(通常是常数或简单的函数)等基础参数,initSimpleFluid 适用于不需要考虑复杂的流体相行为或状态方程的情况。
    • 通常支持 相态变化压力-温度依赖性
    • 更加适用于大型或真实油藏模拟,需要从外部文件(如Eclipse数据)加载流体信息。
    • 它的输出通常是一个结构体,包含了复杂的流体属性,如相对渗透率(kr)、油水比(S_w)、密度、粘度等。

GenericBlackOilModel(G, rock, fluid)

注:生成一个黑油模型(Black-Oil Model),这个模型简化了油藏模拟中石油、气体和水的相互作用,是油藏模拟的标准模型之一。

输入参数:

  • G:可能代表网格(Grid),通常是油藏或模拟空间的离散化表示。在油藏模拟中,网格分割了油藏区域为多个单元格(cell),每个单元格包含相关的物理量(如压力、饱和度等)。
  • rock:代表岩石的物理属性,如孔隙度、渗透性等,这些属性通常会影响流体在油藏中的流动和分布。
  • fluid:代表流体的物理属性,通常包括油、气和水三种流体的性质。这可能包括流体的密度、黏度、饱和度等。

黑油模型:这是油藏模拟中常用的简化模型,用于描述石油、气体和水的三相流动。它通过考虑油、气、水三种流体的相对渗透性、相态关系(如饱和度)等,来模拟流体在油藏中的流动。

processWells(G, rock, deck.SCHEDULE.control)

注:通常用于处理油藏模型中的井控条件。processWells 函数会根据提供的井控条件(如注入井、生产井的流量、压力等控制条件)来更新井的操作状态,并将这些条件整合进油藏模拟的计算中。

参数解释:

  • G: 网格对象,表示油藏的几何结构。通常是通过 cartGridtriangulatedGrid 等函数生成的网格对象。
  • rock: 岩石属性结构,包含岩石的渗透率、孔隙度等信息。通常是通过设置 rock.permrock.poro 来定义的。
  • deck.SCHEDULE.control(1): 这是通过 readEclipseDeck 读取的调度控制信息。deck.SCHEDULE.control 存储了 ECLIPSE 输入文件中的调度控制数据,例如井的操作类型、注水量、注气量、井的压力等。在这里,(1) 表示选择调度控制中的第一个控制器。

井控(control)可以是多种类型,比如:

  • 注入井(Injection wells),如水、气的注入。
  • 生产井(Production wells),如油、气、水的生产。
  • BHP(Bottom-hole Pressure):井的底部压力控制。
  • Rate:井的生产率或注入率控制。

modules.[ad-core & ad-blackoil]

该广告核心模块包含一个面向对象的框架,用于模拟行业标准复杂性的模型。该框架使用自动微分来计算雅可比矩阵,这使得新模型的原型设计速度更快。当与 ad-blackoil 模块结合使用时,该框架提供了各种用于两相和三相可压缩流的黑油类型模型,包括溶解和汽化效应。

Fully implicit solvers with automatic differentiation

该模块包含一组基于自动微分的完全隐式求解器。这使得能够快速建立地下流动新模型的原型,而无需在繁琐的过程中手动计算雅可比行列式。该框架包括一个标准的三相黑油求解器,其中轻烃和重烃组分可以存在于任一相(气体溶解和油蒸发)以及更简单的两相模型中。

所有求解器还能够使用伴随公式计算某些目标函数的解析导数。

 注:在油藏模拟中,完全隐式求解(Fully Implicit Solution) 和其他求解方法(如显式方法半隐式方法)主要的区别在于其时间离散化方式、计算稳定性、效率以及计算复杂度。下面详细解释这些方法的区别:

1. 完全隐式求解(Fully Implicit Solution)

        在完全隐式方法中,油藏模拟中的时间步长是通过对未来时间的状态进行求解来计算的。具体来说,对于给定的时间步,求解器会同时解决所有的物理方程(如流体流动质量守恒压力饱和度等)在当前时间和未来时间的状态。这意味着所有的变量(如压力、饱和度、流量等)都在当前时间和下一时间步之间通过一个隐式的方程组求解

  • 时间离散化:对于每个时间步,所有的变量(如压力、饱和度等)都是隐式的,即它们依赖于下一时间步的状态。此时,方程组在时间上是耦合的,必须通过求解线性或非线性方程来找到所有变量的值。

  • 稳定性:完全隐式方法在处理油藏模拟中的大尺度差异、快速变化的物理现象(如水驱或气驱过程)时,比显式方法更稳定。它不会受到时间步长的限制,可以使用较大的时间步长而不牺牲数值稳定性。

  • 计算复杂度:由于隐式方法涉及求解多个耦合方程,计算量通常较大,尤其是在高维度的情况下。每个时间步需要解一个大型的线性方程组,通常需要迭代求解器如GMRES(广义最小残差法)或直接求解器来计算。

  • 优缺点

    • 优点:更稳定,适用于大规模复杂的油藏模型大时间步长模拟
    • 缺点:计算量大,求解过程较为耗时,尤其是需要对多个变量(如压力、饱和度等)进行耦合求解时。

2. 显式求解(Explicit Solution)

在显式方法中,未来的状态(例如,下一时刻的压力、饱和度等)是通过已知的当前状态(如当前时刻的压力、饱和度)直接计算得到的。显式方法将时间导数显式地表达出来。

  • 时间离散化:显式方法的时间步长依赖于当前时刻的变量,通过一阶有限差分等方法来求解下一时刻的状态。通常,它们遵循以下格式:

u^{n+1}=u^{n}+\Delta t\cdot f(u^{n})

        其中,u^{n}是当前时刻变量,u^{n+1}是下一时刻的变量。

  • 稳定性:显式方法对于时间步长较为敏感,若时间步长太大,可能导致数值不稳定。因此,通常显式方法的时间步长需要满足某些稳定性条件(例如 CFL 条件)。在油藏模拟中,显式方法通常只适用于时间尺度较短、物理过程变化不剧烈的情况。

  • 计算复杂度:显式方法的计算量较小,因为它们没有复杂的方程组需要求解。每个时间步的计算复杂度通常较低,适合于实时或较小规模的模拟。

  • 优缺点

    • 优点:计算速度较快,适用于较小的模型和时间步长。
    • 缺点:稳定性较差,可能需要极小的时间步长,因此不适用于大规模、长时间的模拟。

3. 半隐式求解(Semi-Implicit Solution)

半隐式方法结合了显式和隐式方法的特点。通常,半隐式方法将一些物理过程(如流体流动)离散化显式方式,而将其他物理过程(如压缩性效应、相间传输等)离散化隐式方式

  • 时间离散化:半隐式方法对部分变量使用显式方法对其他变量使用隐式方法。例如,在油藏模拟中,压力通常是隐式的,而饱和度可能是显式的。

  • 稳定性:相比显式方法,半隐式方法具有更好的稳定性,能够在一定范围内使用较大的时间步长,而不至于导致数值不稳定。

  • 计算复杂度:半隐式方法的计算复杂度介于显式和完全隐式方法之间。它比显式方法的计算量稍大,但通常比完全隐式方法要小。

  • 优缺点

    • 优点:在计算效率和稳定性之间提供了折衷,适用于多相流模拟。
    • 缺点:需要对不同物理过程使用不同的离散化方式,可能需要较复杂的编程和调试。

4. 完全隐式和其他求解方法的比较

5. 总结

  • 完全隐式求解:适用于稳定性要求高、大规模的油藏模拟,但计算量大。
  • 显式求解:计算量小,适用于小规模和快速模拟,但时间步长受限制,容易不稳定。
  • 半隐式求解:提供稳定性和效率之间的折衷,适用于复杂的多相流模拟。

完全隐式方法通常是油藏模拟中最常用的方法,尤其是在长时间、复杂流体流动和大规模油藏模拟中。

NoneLinearSolver()

NonLinearSolver 类是基于牛顿法的通用非线性求解器。它能够根据收敛速度进行时间步长选择和切割,并且可以通过子类化或模块化线性求解器和时间步长类进行扩展。

收敛由PhysicalModel 类处理。 NonLinearSolver 只是根据模型在收敛方面报告的内容进行响应,以确保某种程度的封装。

eg:

nls = NonLinearSolver('useLinesearch', true); % enable line-search in residual残留相

注:结合simulateScheduleAD使用。

simulateScheduleAD(initState, model, schedule,[varargin])

使用自动微分运行非线性物理模型的计划,此函数接受有效的计划文件(请参阅所需参数),并针对给定模型和初始状态对所有时间步运行模拟。

输入参数

        initState : 初始储层/模型状态。它应该具有与物理模型相关的任何字段,并具有合理的值。用户有责任确保状态正确初始化。
        model :确定问题的雅可比/收敛性的物理模型。这必须是 PhysicalModel 基类的子类。
        Schedule:计划,包含字段step和control,定义如下: Schedule.control,井控 是一个结构体数组,其中包含模型知道如何处理的字段。通常,这将是诸如 W 代表井或 bc 代表边界条件的字段。 Schedule.step 包含两个大小相等的数组,分别名为 val 和 control。Schedule.control 数组的索引,指示哪个控制将用于时间步。`schedule.step.val` 是用于该控制步骤的时间步。

输出:

        wellSols :每个控制步骤(或时间步,如果启用“OutputMinisteps”)的井解。
        states : 每个控制步骤(或时间步,如果启用“OutputMinisteps”)的状态。
        Schedulereport : 模拟报告。包含整个计划运行的详细信息,以及包含模拟期间调用的整个例程堆栈的报告的数组。

eg:

nls = NonLinearSolver('useLinesearch', true);

[wellSols, states, report] = simulateScheduleAD(state, model, schedule, 'nonlinearsolver', nls);

注:指定求解器使用基于牛顿法的通用非线性求解器。

wellSols(井的解)

wellSols 包含关于井的数据,通常是与井流量、井控、井产等相关的结果,wellSols 结果集shape为(stepNums,1)。单步井解wellSol主要的属性包括:

  • wellSol.bhp:井的底hole压力(Bottom Hole Pressure)。
  • wellSol.q:井的流量,包括注入井和生产井的流量。可以包括不同相的流量(如水、油、气等),qWs、qGs、qOs分别表示水、气、油流量。
  • wellSol.cdpcdp 代表从井的参考深度到第一个射孔之间的压力降(Pressure drop from reference depth to first perforation)。压降是由于流体在井筒内流动时,受到摩擦、流体动力学效应等因素的影响,导致的压力损失。这个值有助于了解井筒中的压力分布,特别是在考虑井的生产性能时。压降通常是与流体流动有关的重要参数,反映了流体通过井筒时的流动阻力。
  • wellSol.sign:通常用来表示井的流量方向。它通常包含 +1-1 的值,用于指示流体流动的方向,+1表示为生产井,-1表示为注入井
  • wellSol.type:井控制类型(常见,oratratebhp):orat (Oil Rate),表示油井的 油流量,通常是以体积或质量单位表示(如桶/天或立方米/天)。这个控制参数用于模拟油井的生产速率;rate 是一种通用的流量控制参数,通常用于表示井的 流量控制。它可以是 生产井注入井 的流量控制参数,控制的可能是液体、气体或者其他流体的流量;bhp (Bottom Hole Pressure)定义bhp 代表 井底压力,即控制井的底部压力。控制井底压力时,井的流动行为由底部压力来决定,而不是流量。
  • wellSol.val:通常表示井的控制变量的具体值,取决于模拟的场景。
  • wellSol.flux:通过井的流体数据(也可能包含各相流量)。
states(状态)

states 是模拟过程中整个油藏状态的记录,包含每个时间步的压力、饱和度等信息,states 结果集shape为(stepNums,1)。单步state主要的属性包括:

  • state.pressure:油藏中每个单元的压力分布。
  • state.s:每个单元的饱和度,包括不同相的饱和度(例如水相、油相、气相)。
  • state.rs:每个单元的油相和气相的溶解度。
  • state.rv:每个单元的气相的体积或压力。
  • state.sMax:表示油藏中单元格或区域的 最大饱和度 的字段,它帮助控制每个单元格中流体的最大分布量,并确保模拟中流体的分布在合理范围内,它描述了每个单元格中能够容纳某种流体的最大比率。
  • state.wellSol:井的解决方案,包括井底的压力、流量等信息,关联wellSols对应step结果。
  • states.status:通常会包含模拟过程中的系统状态,可能包括是否正常运行、是否收敛等信息。
  • states.FlowProps:流体属性,可能包括流速、压降、流体的种类等。其中ComponentTotalMass表示组分相质量,ComponentTotalMass 通常包含三个值分别对应于模拟中不同的流体组分。具体来说,这些组分通常是 ,用于描述油气藏中常见的三种主要流体成分。每个值代表了相应组分的 总质量,即在整个模拟过程中,这些流体组分的累计质量。
  • states.PVTProps:压力、体积、温度(PVT)相关的属性,可能用于描述物理模型中的流体状态。PVTProps 中的 Density(密度)通常表示流体的密度,并且它会随着模拟条件的变化而变化。注:在 SPE1 模型中,通常模拟的是油气水的流动和生产过程。密度通常是 压力温度 的函数。在大多数油藏模拟中,流体的密度会随着压力和温度的变化而变化。
scheduleReport(调度报告)

scheduleReport 记录了模拟过程中每个调度步骤的关键数据,每个属性的结果集shape为(stepNums,1)。主要的属性包括:

  • scheduleReport .ControlstepReports:通常记录了每个控制步骤(或计算步骤)中的关键信息,可能包括某些变量的更新情况、调整的参数以及模拟的进展。例如,控制步骤可能指代了每次时间步长的计算过程或者某些模拟条件的调整。

  • scheduleReport .ReservoirTime:表示模拟中的油藏时间。这通常是指自模拟开始以来,经过的时间,通常与生产或注入等操作有关。它可能表示为天数、小时或其他时间单位。

  • scheduleReport .Converged:通常表示模拟是否已经收敛。模拟收敛意味着模拟结果的误差已经在可接受的范围内,或者系统状态已达到预期的平衡状态。如果没有收敛,模拟可能会提示需要更多的迭代或调整参数。

  • scheduleReport .Iterations:表示模拟中完成的迭代次数。这个字段通常反映了求解器在每个控制步骤中执行的计算循环次数,可能会影响模拟的精度和时间。对应步长索引的ControlstepReport中的Iteration。

  • scheduleReport .SimulationTime:模拟的总运行时间。这个字段表示从模拟开始到完成的时间,通常是以秒、分钟、小时等单位来表示的。它有助于评估模拟的效率。

  • scheduleReport .Failure:表示是否发生了失败或错误。这个字段可能包括模拟过程中遇到的问题,例如数值计算错误、收敛失败等。如果发生了失败,可能需要检查模型的参数设置或初始条件。

plotWellSols(wellSols,report.ReservoirTime)

绘制井的生产或注入数据(如流量、压力等),通常用于展示时间序列数据。

modules.mrst-gui

可视化模拟结果(例如压力场、饱和度分布),需要加载 GUI 模块,带控制按钮的可视化过程。

pltToolbar(G,states)

这是 MRST GUI 模块中的函数,通常用于图形用户界面中绘制和交互式操作的工具栏。

modules.test-suite

test-suite 模块是一个用于自动化测试和验证 MRST 功能的工具。它通过编写一系列测试用例,帮助开发者和用户检查 MRST 中的各种功能是否按预期工作,尤其是在不同的油藏模拟模型和方法中。通过这种方式,用户可以确保他们的模拟工作在代码更新或参数变化后的正确性。

 datasetfunctions 是与测试数据集相关的函数集合,通常用于处理、生成、或者验证在 MRST 中使用的数据集。test-suite 模块中,dataset-functions 目录下包含了多个经典的油藏模拟测试案例(如 EGG, Norne, SPE1, SPE9 等)。每个案例都包含特定的数据集,这些数据集描述了油藏的网格、岩石特性、流体特性、井调度等。其中,EGG“蛋模型”是一个合成油藏模型,由 101 个相对较小的三维实现的通道化油藏模型组成,这些模型是在水驱条件下使用 8 个注水器和 4 个生产井生产的;Norne是挪威国家石油公司运营的挪威海 Norne 油田的模拟模型;SPE1是第一个 SPE 基准测试,SPE1油藏它是一种活油/干气黑油模型,水几乎不流动;SPE9是第九个 SPE 基准,由单个注水器和 25 个生产器生产的浸渍油藏组成。

setupSPE1()

注:使用setupSPE1()函数设置数据,需要本地已下载SPE1数据BENCH_SPE1.DATA,使用downloadDataset(’BENCH_SPE1.DATA‘)默认下载到MRST工具目录下examples/data/SPE1目录下。SPE 1基准测试。它是一种活油/干气黑油模型,水几乎不流动。有一个由井底压力控制的单个生产井,以及一个将气体注入最初充满不饱和油的储层的单个注入器。设置:三相、黑油和油相气体、具有 300 个单元的笛卡尔网格模型 模型包含:网格、岩石和流体。SPE3具有324个网格,SPE9具有9000个网格,SPE10具有1122000(百万)网格。 具有其他MRST开放数据集链接:MRST: Public data sets。此外还可以通过mrstDatasetGUI()接口打开可视化面板。

[G, rock, fluid, deck, state] = setupSPE1()

Source Code:

function [G, rock, fluid, deck, state] = setupSPE1()
%Setup the SPE1 benchmark case for simulation
    mrstModule add deckformat ad-props
    % Read and process file.
    pth = getDatasetPath('spe1');
    fn  = fullfile(pth, 'BENCH_SPE1.DATA');

    deck = readEclipseDeck(fn);

    % The deck is given in field units, MRST uses metric.
    deck = convertDeckUnits(deck);

    G = initEclipseGrid(deck);
    G = computeGeometry(G);

    rock  = initEclipseRock(deck);
    rock  = compressRock(rock, G.cells.indexMap);

    % Create a special ADI fluid which can produce differentiated fluid
    % properties.
    fluid = initDeckADIFluid(deck);

    % The case includes gravity
    gravity reset on;


    % The initial state is a pressure field that is constant in each layer, a
    % uniform mixture of water (Sw=0.12) and oil (So=0.88) with no initial free
    % gas (Sg=0.0) and a constant dissolved gas/oil ratio ("Rs") throughout the
    % model.
    %
    % The pressure and Rs values are derived through external means.
    clear prod
    [k, k] = ind2sub([prod(G.cartDims(1:2)), G.cartDims(3)], ...
                      G.cells.indexMap);  %#ok

    p0    = [ 329.7832774859256 ; ...  % Top layer
              330.2313357125603 ; ...  % Middle layer
              330.9483500720813 ];     % Bottom layer

    p0    = convertFrom(p0(k), barsa);
    s0    = repmat([ 0.12, 0.88, 0.0 ], [G.cells.num, 1]);
    rs0   = repmat( 226.1966570852417 , [G.cells.num, 1]);
    rv0   = 0; % dry gas

    state = struct('s', s0, 'rs', rs0, 'rv', rv0, 'pressure', p0);   clear k p0 s0 rs0

end

 utils

utils 是 MRST 中的一个基础模块,包含一些辅助工具函数(如文件操作、数据处理、常用计算等)。这个模块一般在 MRST 启动时就会加载,并且不需要手动使用 mrstModule add 来加载。

downloadDataset(datasetName, targetDir);

 downloadDataset 函数用于从网络下载油藏模拟数据集(通常是来自 MRST 官方或其他公开数据源的标准数据集)。这个函数通常用来快速获取标准测试数据集,例如 SPE1SPE10 等油藏模拟数据集,供用户进行模型测试和学习使用。

convertFrom

单位转换工具

<think>好的,我现在需要帮助用户查找关于MRSTMATLAB Reservoir Simulation Toolbox)的资料,包括文档、教程和下载方式。首先,我得回忆一下MRST的基本信息。MRST是由挪威科技大学开发的开源工具箱,主要用于油藏模拟。用户提到的引用内容中,引用了model = TwoPhaseOilWaterModel(G, rock, fluid);这样的代码,这可能与油水两相流模型有关,说明用户可能在参考相关模型的使用[^3]。另外,用户提到安装路径,比如将工具箱粘贴到MATLABtoolbox目录下,如F:\ProgramFiles\Matlab2016b\toolbox[^2],这可能涉及到如何正确安装MRST的步骤。 接下来,我需要确保回答符合用户的要求,即提供文档、教程和下载链接。首先,官方网站应该是主要的资料来源,所以应该指导用户访问MRST的官网,并说明如何下载。然后,文档部分需要详细说明,比如用户指南、模块文档和API参考,这些内容通常会在官网提供。教程方面,可能需要分入门和进阶,包括示例模型和视频教程,这样用户可以根据自己的水平选择。下载和安装步骤需要具体,特别是如何通过GitHub获取最新版本,以及如何添加到MATLAB路径中,引用用户提到的安装路径作为例子[^2]。 另外,用户可能遇到的问题,比如依赖项或兼容性,也需要提前提醒。例如,MRST可能需要特定的MATLAB版本或其他工具箱支持。此外,引用中提到的simulateScheduleAD函数[^1],这可能属于MRST的高级功能,用户可能需要相关示例,可以建议查阅文档中的对应部分。 最后,生成相关问题时要考虑用户可能的后续需求,比如具体模块的使用、与其他工具集成、常见错误处理等。确保回答结构清晰,步骤明确,并且引用正确,如涉及安装路径和函数使用的地方添加引用标识[^1]。 需要检查所有技术细节是否正确,比如下载链接是否有效,安装步骤是否准确,避免误导用户。同时,确保使用中文回答,数学公式和代码块符合格式要求。可能还需要确认MRST的最新版本是否有变化,但考虑到用户提供的引用可能来自较旧的版本(如Matlab2016b),需要建议用户查看官网获取最新信息。 总结步骤: 1. 介绍MRST基本信息。 2. 提供官方资源链接(官网、GitHub)。 3. 分点说明文档、教程、下载安装方法。 4. 提示常见问题,如依赖项和兼容性。 5. 生成相关问题,涵盖使用、安装、模块等方面。 6. 确保引用正确,格式符合要求。</think>### MRSTMATLAB Reservoir Simulation Toolbox)相关资料指南 #### 1. **官方资源** - **官网与文档** MRST的官方文档和教程可通过其官网访问:[MRST官网](https://www.sintef.no/projectweb/mrst/)。文档包含用户指南、模块说明及API参考,涵盖从基础到高级应用的详细内容。 - **GitHub仓库** 最新版本的源代码可在GitHub获取:[MRST GitHub](https://github.com/OPM/mrst)。通过`git clone`或直接下载ZIP文件安装。 #### 2. **文档与教程** - **入门教程** 官网提供快速入门指南,例如单相流模拟、网格生成(如`GRDECL`格式)和结果可视化。示例代码: ```matlab % 创建网格和岩石属性 G = computeGeometry(cartGrid([10, 10, 5])); rock = makeRock(G, 100*milli*darcy, 0.2); ``` - **进阶内容** - 两相流模型(如`TwoPhaseOilWaterModel`)的使用[^3]。 - 自动微分工具(`simulateScheduleAD`函数)在历史匹配中的应用[^1]。 - **视频教程** 部分高校或开发者社区提供MRST操作演示视频,可通过官网链接或YouTube搜索。 #### 3. **下载与安装** 1. **从GitHub下载** ```bash git clone https://github.com/OPM/mrst.git ``` 或直接下载ZIP文件并解压至MATLAB的`toolbox`目录,例如`F:\ProgramFiles\Matlab2016b\toolbox`。 2. **添加MATLAB路径** 在MATLAB中运行: ```matlab addpath(genpath('F:\ProgramFiles\Matlab2016b\toolbox\mrst')); mrstModule add ad-core ad-blackoil ``` #### 4. **常见问题** - **依赖项** MRSTMATLAB R2014b及以上版本,部分模块依赖`Optimization Toolbox`。 - **兼容性** 若安装后报错,检查路径是否包含所有子目录(使用`genpath`)[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值