clear
mrstModule add ad-core ad-blackoil ad-props mrst-gui deckformat diagnostics
mrstModule add ad-eor
%%
N = 10;
N1 = 2*N;
N2 = 3*ceil(N/2)-2;
[X, Y] = meshgrid(0:1:N1, 0:1:N2);
X = sqrt(3) / 2 * X;
Y(:,2:2:end)=Y(:,2:2:end)+0.5;
p = [X(:), Y(:)];
t = delaunayn(p);
G = triangleGrid(p, t);
G = pebi(G);
G = computeGeometry(G);
figure, plotGrid(G)
%%
rock = makeRock(G, 0.5*darcy, 0.3);
%%
fluid = initSimpleADIFluid('phases', 'OW', ...
'mu', [8, 1]*centi*poise, ...
'rho', [650, 1000]*kilogram/meter^3 , ...
'n', [2, 2], ...
'pRef', 100*barsa, ...
'c', [1e-5, 1e-4]/barsa, ...
'cR', 1e-5/barsa);
%%
gravity reset on
model = TwoPhaseOilWaterModel(G, rock, fluid);
%%
W = [];
injRate = 2 * (meter^3/day);
wc = 30;
W = addWell(W, G, rock, wc, 'Name', 'I1',...
'sign', 1, 'comp_i', [1, 0], 'Val', injRate, 'Type', 'rate', 'dir','Z');
bhp = 10 * (mega*Pascal);
wc = 180;
W = addWell(W, G, rock, wc, 'Name', 'P1',...
'sign', -1, 'comp_i', [0.5, 0.5], 'Val', bhp, 'Type', 'bhp', 'dir','Z');
bhp = 10 * (mega*Pascal);
wc = 250;
W = addWell(W, G, rock, wc, 'Name', 'P2',...
'sign', -1, 'comp_i', [0.5, 0.5], 'Val', bhp, 'Type', 'bhp', 'dir','Z');
% figure, hold on
% plotGrid(G, 'facecolor', 'n')
% plotGrid(G, vertcat(W.cells))
timesteps = [ones(10,1)*1*day; ones(10,1)*10*day];
schedule = simpleSchedule(timesteps, 'W', W);
%%
initState = initResSol(G, 30*(mega*Pascal), [0, 1]);
%%
fn = getPlotAfterStep(initState, model, schedule, 'plotReservoir',false, 'plotWell', false);
model.fluid.alpha = 0;
model.fluid.tpg = 0;
[wellSols1, states1, report1] = ...
simulateScheduleAD(initState, model, schedule,'afterStepFn',fn);
model.fluid.alpha = 0;
model.fluid.tpg = 1e3;
[wellSols2, states2, report2] = ...
simulateScheduleAD(initState, model, schedule,'afterStepFn',fn);
%%
plotWellSols({wellSols1, wellSols2})
%%
figure
subplot(1,2,1)
plotCellData(G, states1{end-1}.perm/(milli*darcy))
axis equal off
colorbar('location', 'south')
subplot(1,2,2)
plotCellData(G, states2{end-1}.perm/(milli*darcy))
axis equal off
colorbar('location', 'south')
%%
figure
subplot(1,2,1)
plotCellData(G, states1{end-1}.pressure)
axis equal off
colorbar('location', 'south')
subplot(1,2,2)
plotCellData(G, states2{end-1}.pressure)
axis equal off
colorbar('location', 'south')
运行结果是:
代码用MATLAB编写的,主要是进行油水两相流的模拟。以下是对代码中每个部分的逐句解释:
-
mrstModule add ...
: 引入MATLAB Reservoir Simulation Toolbox (MRST) 的模块,包括核心模块、黑油模块、物性模块等。 -
N = 10; N1 = 2*N; N2 = 3*ceil(N/2)-2; ...
: 定义了一些网格的参数和生成网格的坐标。 -
[X, Y] = meshgrid(0:1:N1, 0:1:N2); X = sqrt(3) / 2 * X; Y(:,2:2:end)=Y(:,2:2:end)+0.5; p = [X(:), Y(:)]; t = delaunayn(p); G = triangleGrid(p, t); G = pebi(G); G = computeGeometry(G);
: 创建了一个三角形网格,并进行了一些几何处理。 -
figure, plotGrid(G)
: 绘制了创建的网格。 -
rock = makeRock(G, 0.5*darcy, 0.3);
: 创建了岩石的属性,包括渗透率和孔隙度。 -
fluid = initSimpleADIFluid('phases', 'OW', ...
: 初始化了两相流体的属性,包括黏度、密度、相对渗透率等。 -
gravity reset on
: 开启了重力效应。 -
model = TwoPhaseOilWaterModel(G, rock, fluid);
: 创建了油水两相流的模型。 -
W = []; ...
: 定义了注入井和产油井的一些属性,包括位置、流量、压力等。 -
timesteps = [ones(10,1)*1*day; ones(10,1)*10*day]; schedule = simpleSchedule(timesteps, 'W', W);
: 定义了模拟的时间步长和生产注入井的调度。 -
initState = initResSol(G, 30*(mega*Pascal), [0, 1]);
: 初始化了初始的储层状态。 -
fn = getPlotAfterStep(initState, model, schedule, 'plotReservoir',false, 'plotWell', false);
: 定义了在每个时间步后绘制的函数。 -
模拟了两种情况下的油水两相流,分别为无相变和相变状态。
-
plotWellSols({wellSols1, wellSols2})
: 绘制了两种情况下井口的生产曲线。 -
绘制了两种情况下储层渗透率和压力的空间分布。
clear
mrstModule add ad-core ad-blackoil ad-props mrst-gui deckformat diagnostics
%%
fn = 'demo.DATA';
deck = readEclipseDeck(fn);
deck = convertDeckUnits(deck);
%%
G = initEclipseGrid(deck);
G = computeGeometry(G);
% figure;plotGrid(G)
%%
rock = initEclipseRock(deck);
rock = compressRock(rock, G.cells.indexMap);
figure;
plotCellData(G, rock.perm(:,1), 'FaceAlpha', 1, 'EdgeAlpha', 1, 'EdgeColor', 'k');
axis tight
%%
fluid = initDeckADIFluid(deck);
%%
gravity reset on
model = TwoPhaseOilWaterModel(G, rock, fluid);
%%
initState = initStateDeck(model, deck);
%%
schedule = convertDeckScheduleToMRST(model, deck);
%%
fn = getPlotAfterStep(initState, model, schedule, 'plotReservoir',false, 'plotWell', false);
[wellSols, states, report] = ...
simulateScheduleAD(initState, model, schedule,'afterStepFn',fn);
%%
figure
plotToolbar(G, states)
%%
plotWellSols(wellSols)
%%
state = states{end};
interactiveDiagnostics(G, rock, schedule.control(1).W, 'state', state, 'computeFlux', false, 'name', 'model');
-
clear
: 清空 MATLAB 工作区的所有变量。 -
mrstModule add ad-core ad-blackoil ad-props mrst-gui deckformat diagnostics
: 添加 MRST(MATLAB Reservoir Simulation Toolbox) 的模块,包括 ad-core、ad-blackoil、ad-props、mrst-gui、deckformat 和 diagnostics。 -
fn = 'demo.DATA'; deck = readEclipseDeck(fn); deck = convertDeckUnits(deck);
: 从名为 'demo.DATA' 的 Eclipse deck 文件中读取数据,然后进行单位转换。 -
G = initEclipseGrid(deck); G = computeGeometry(G);
: 使用 Eclipse deck 数据初始化油藏网格,并计算网格的几何信息。 -
rock = initEclipseRock(deck); rock = compressRock(rock, G.cells.indexMap);
: 使用 Eclipse deck 数据初始化岩石属性,并对岩石进行压缩。 -
figure; plotCellData(G, rock.perm(:,1), 'FaceAlpha', 1, 'EdgeAlpha', 1, 'EdgeColor', 'k'); axis tight
: 绘制岩石的渗透率分布。 -
fluid = initDeckADIFluid(deck);
: 使用 Eclipse deck 数据初始化两相流体的属性。 -
gravity reset on
: 开启重力效应。 -
model = TwoPhaseOilWaterModel(G, rock, fluid);
: 创建油水两相流模型。 -
initState = initStateDeck(model, deck);
: 使用 Eclipse deck 数据初始化初始状态。 -
schedule = convertDeckScheduleToMRST(model, deck);
: 将 Eclipse deck 数据中的调度信息转换为 MRST 中的调度格式。 -
fn = getPlotAfterStep(initState, model, schedule, 'plotReservoir',false, 'plotWell', false);
: 定义在每个时间步后绘制的函数。 -
模拟了油藏的生产过程,并获取模拟结果。
-
figure plotToolbar(G, states)
: 绘制工具栏,显示模拟过程中的状态。 -
plotWellSols(wellSols)
: 绘制井口的生产曲线。 -
state = states{end}; interactiveDiagnostics(G, rock, schedule.control(1).W, 'state', state, 'computeFlux', false, 'name', 'model');
: 获取模拟结束时的状态,并进行交互式诊断,显示模型的一些属性。
实验