init
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
function h = Bo_ow(p, BO, Ppr)
|
||||
h = interptable(Ppr, BO, p);
|
||||
end
|
||||
@@ -0,0 +1,2 @@
|
||||
function h = Bw_ow(p, Bwi, prw, cw)
|
||||
h = Bwi * (1 - cw * (p - prw));
|
||||
@@ -0,0 +1,112 @@
|
||||
function [Awell, qwell] = WellEquation_oil_water_flow(r, f, p, sw, Wellc, Weladd, pwf, WelChg, well_schedules_k)
|
||||
nWel = size(Wellc, 1);%井的总数
|
||||
% Wellcpara: welltype(1) nperf(2) index(3) Tr(j)ans(4) protype(5) value(6) consTr(j)ain(7) Wellc(nWel, 6)
|
||||
% welltype = 1 prod, welltype = 2 inj
|
||||
% protype = 1 const flowrate, protype = 2 const pwf
|
||||
nmatr = 2 * r.nc + Weladd;%加上定产井的数量,结果为未知数的总数,压力、饱和度和井底流压
|
||||
nzw = 10 * nWel;
|
||||
% Awell = spalloc(nmatr,nmatr,nzw);
|
||||
Awell = spalloc(nmatr,nmatr,nzw);
|
||||
qwell = spalloc(nmatr,1,nzw);
|
||||
% Dimensionless_wellflow=[];
|
||||
if Weladd == 0 %%定产井的数量为0
|
||||
[p, sw] = intADI_oil_water_flow(p, sw);
|
||||
else
|
||||
[p, sw, pwf] = intADI2_oil_water_flow(p, sw, pwf);
|
||||
end
|
||||
BW = f.Bw(p);
|
||||
muW = f.muw(p);
|
||||
krW = f.krw(sw);
|
||||
BO = f.Bo(p);
|
||||
muO = f.muo(p);
|
||||
krO = f.kro(sw);
|
||||
Yot = krO ./ (muO .* BO);
|
||||
Ywt = krW ./ (muW .* BW);
|
||||
Yoj = krO ./ muO;
|
||||
Ywj = krW ./ muW;
|
||||
pcOW = 0;
|
||||
if f.ifpcow%若为0,则毛管力为0
|
||||
pcOW = f.pcow(sw);
|
||||
end
|
||||
pw = p - pcOW;
|
||||
ipwf = 0;
|
||||
for i = 1 : nWel
|
||||
if strcmp(well_schedules_k{i,2},'open')
|
||||
jperfall = Wellc{i,3};%该井射孔点所在网格或单元序号
|
||||
if strcmp(well_schedules_k{i,3},'pro') % prod
|
||||
if strcmp(well_schedules_k{i,4},'const_q') % const flowrate
|
||||
ipwf = ipwf + 1;
|
||||
Tr = Wellc{i,4};
|
||||
for j = 1 : Wellc{i,2}
|
||||
jperf = jperfall(j);
|
||||
Yo = Yot(jperf);
|
||||
Yw = Ywt(jperf);
|
||||
qo = -Tr(j) .* Yo .*(p(jperf) - pwf(ipwf));
|
||||
qw = -Tr(j) .* Yw .*(pw(jperf) - pwf(ipwf));
|
||||
%前nc行是水相方程
|
||||
Awell(jperf, :) = [qw.jac{1} qw.jac{2} qw.jac{3}];
|
||||
qwell(jperf) = qw.val;
|
||||
%后nc行是水相方程
|
||||
Awell(r.nc + jperf, :) = [qo.jac{1} qo.jac{2} qo.jac{3}];
|
||||
qwell(r.nc + jperf) = qo.val;
|
||||
%把该井所有射孔点的产油、产水累加起来
|
||||
% 在定流量情况下,为了使得能够适用于更一般情况,比如气井流量较大,导致该方程MR迭代收敛条件过高,因此需要无因次化
|
||||
Awell(2*r.nc + ipwf, :) = Awell(2*r.nc + ipwf, :) + ...
|
||||
[qw.jac{1} qw.jac{2} qw.jac{3}] + [qo.jac{1} qo.jac{2} qo.jac{3}];
|
||||
qwell(2*r.nc + ipwf) = qwell(2*r.nc + ipwf) + qw.val + qo.val;
|
||||
end
|
||||
qwell(2*r.nc + ipwf) = (qwell(2*r.nc + ipwf) + well_schedules_k{i,5}/86.4);
|
||||
else % const pwf 定压生产
|
||||
if ~WelChg(i)
|
||||
pwfc = well_schedules_k{i,5};
|
||||
else
|
||||
pwfc = well_schedules_k{i,6};
|
||||
end
|
||||
Tr = Wellc{i,4};
|
||||
for j = 1 : Wellc{i,2}
|
||||
jperf = jperfall(j);
|
||||
Yo = Yot(jperf);
|
||||
Yw = Ywt(jperf);
|
||||
qo = -Tr(j) .* Yo .*(p(jperf) - pwfc);
|
||||
qw = -Tr(j) .* Yw .*(pw(jperf) - pwfc);
|
||||
Awell(jperf, 1 : 2 * r.nc) = [qw.jac{1} qw.jac{2}];
|
||||
qwell(jperf) = qw.val;
|
||||
Awell(r.nc + jperf, 1 : 2 * r.nc) = [qo.jac{1} qo.jac{2}];
|
||||
qwell(r.nc + jperf) = qo.val;
|
||||
end
|
||||
end
|
||||
else %注入井
|
||||
if strcmp(well_schedules_k{i,4},'const_q') % const flowrate
|
||||
ipwf = ipwf + 1;
|
||||
Tr = Wellc{i,4};
|
||||
for j = 1 : Wellc{i,2}
|
||||
jperf = jperfall(j);
|
||||
Yo = Yoj(jperf);
|
||||
Yw = Ywj(jperf);
|
||||
qw = -Tr(j) ./ BW(jperf) .* (Yo + Yw) .* (pw(jperf) - pwf(ipwf));
|
||||
Awell(jperf, :) = [qw.jac{1} qw.jac{2} qw.jac{3}];
|
||||
qwell(jperf) = qw.val;
|
||||
Awell(2*r.nc + ipwf, :) = Awell(2*r.nc + ipwf, :) + ...
|
||||
[qw.jac{1} qw.jac{2} qw.jac{3}];
|
||||
qwell(2*r.nc + ipwf) = qwell(2*r.nc + ipwf) + qw.val;
|
||||
end
|
||||
qwell(2*r.nc + ipwf) = qwell(2*r.nc + ipwf) - well_schedules_k{i,5}/86.4;
|
||||
else %定压注入
|
||||
if ~WelChg(i)
|
||||
pwfc = well_schedules_k{i,5};
|
||||
else
|
||||
pwfc = well_schedules_k{i,6};
|
||||
end
|
||||
Tr = Wellc{i,4};
|
||||
for j = 1 : Wellc{i,2}
|
||||
jperf = jperfall(j);
|
||||
Yo = Yoj(jperf);
|
||||
Yw = Ywj(jperf);
|
||||
qw =- Tr(j) ./ BW(jperf) .* (Yo + Yw) .* (pw(jperf) - pwfc);
|
||||
Awell(jperf, 1 : 2 * r.nc) = [qw.jac{1} qw.jac{2}];
|
||||
qwell(jperf) = qw.val;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
function [Ppr,BG,MUG] = cal_oil_prop(prg,Bgi,cg,vgi,cvg)
|
||||
Ppr = (0.1:0.1:100)';
|
||||
BG = Bgi * (1 - cg * (Ppr - prg));
|
||||
MUG = vgi + cvg * (Ppr - prg);
|
||||
end
|
||||
@@ -0,0 +1,98 @@
|
||||
function [Wellpara, WelChg, Weladd] = calcWellequation_oil_water_flow(Weladd, Wellc, WelChg, well_schedules_k, nc, qwell, state)
|
||||
%Weladd表示定流量井的数量,Wellc表示井参数
|
||||
% Wellcpara: welltype(1) nperf(2) index(3) Tr(j)ans(4) protype(5) value(6) consTr(j)ain(7) Wellc(nWel, 6)
|
||||
% welltype = 1 prod, welltype = 2 inj
|
||||
% protype = 1 const flowrate, protype = 2 const pwf
|
||||
nWel = size(Wellc, 1);%井数
|
||||
Wellpara = cell(1, nWel);
|
||||
if Weladd > 0 %存在定流量井
|
||||
pwf = state.pwf;
|
||||
end
|
||||
ipwf = 0;
|
||||
for i = 1 : nWel
|
||||
if strcmp(well_schedules_k{i,2},'open')
|
||||
qot = 0;
|
||||
qwt = 0;
|
||||
jperfall = Wellc{i,3};
|
||||
if strcmp(well_schedules_k{i,3},'pro') % prod
|
||||
if strcmp(well_schedules_k{i,4},'const_q') % const flowrate
|
||||
ipwf = ipwf + 1;
|
||||
for j = 1 : Wellc{i,2}
|
||||
jperf = jperfall(j);
|
||||
%井筒内无限导流,流量等于各个射孔点流量之和
|
||||
qwt = qwt + qwell(jperf);
|
||||
qot = qot + qwell(nc + jperf);
|
||||
end
|
||||
if well_schedules_k{i,5} ~= 0
|
||||
Wellpara{1,i}.wellname = Wellc{i,1};
|
||||
Wellpara{1,i}.qw = abs(qwt)*86.4;
|
||||
Wellpara{1,i}.qo = abs(qot)*86.4;
|
||||
Wellpara{1,i}.pwf = pwf(ipwf);
|
||||
else
|
||||
Wellpara{1,i}.wellname = Wellc{i,1};
|
||||
Wellpara{1,i}.qw = 0;
|
||||
Wellpara{1,i}.qo = 0;
|
||||
Wellpara{1,i}.pwf = pwf(ipwf);
|
||||
end
|
||||
% if pwf(ipwf)<= Wellc{i,7} %当井底流压低于这个限制,流量会很大
|
||||
% WelChg(i) = 1;
|
||||
% Weladd = Weladd - 1;
|
||||
% else
|
||||
% WelChg(i) = 0;
|
||||
% end
|
||||
else % const pwf 生产
|
||||
if ~WelChg(i)
|
||||
Wellpara{1,i}.pwf = well_schedules_k{i,5};
|
||||
else
|
||||
Wellpara{1,i}.pwf = well_schedules_k{i,6};
|
||||
end
|
||||
for j = 1 : Wellc{i,2}
|
||||
jperf = jperfall(j);
|
||||
qwt = qwt + qwell(jperf);
|
||||
qot = qot + qwell(nc + jperf);
|
||||
end
|
||||
Wellpara{1,i}.wellname = Wellc{i,1};
|
||||
Wellpara{1,i}.qw = abs(qwt)*86.4;
|
||||
Wellpara{1,i}.qo = abs(qot)*86.4;
|
||||
end
|
||||
else %注入井
|
||||
if strcmp(well_schedules_k{i,4},'const_q') % const flowrate
|
||||
ipwf = ipwf + 1;
|
||||
for j = 1 : Wellc{i,2}
|
||||
jperf = jperfall(j);
|
||||
qwt = qwt + qwell(jperf);
|
||||
end
|
||||
if well_schedules_k{i,5} ~= 0
|
||||
Wellpara{1,i}.wellname = Wellc{i,1};
|
||||
Wellpara{1,i}.qw = abs(qwt)*86.4;
|
||||
Wellpara{1,i}.pwf = pwf(ipwf);
|
||||
Wellpara{1,i}.qo = 0;
|
||||
else
|
||||
Wellpara{1,i}.wellname = Wellc{i,1};
|
||||
Wellpara{1,i}.qw = 0;
|
||||
Wellpara{1,i}.pwf = pwf(ipwf);
|
||||
Wellpara{1,i}.qo = 0;
|
||||
end
|
||||
% if pwf(ipwf) >= Wellc{i,7} %高于这个限制压力后,则井的流量很高
|
||||
% WelChg(i) = 1;
|
||||
% Weladd = Weladd - 1;
|
||||
% else
|
||||
% WelChg(i) = 0;
|
||||
% end
|
||||
else
|
||||
if ~WelChg(i)
|
||||
Wellpara{1,i}.pwf = well_schedules_k{i,5};
|
||||
else
|
||||
Wellpara{1,i}.pwf = well_schedules_k{i,6};
|
||||
end
|
||||
for j = 1 : Wellc{i,2}
|
||||
jperf = jperfall(j);
|
||||
qwt = qwt + qwell(jperf);
|
||||
end
|
||||
Wellpara{1,i}.wellname = Wellc{i,1};
|
||||
Wellpara{1,i}.qw = abs(qwt)*86.4;
|
||||
Wellpara{1,i}.qo = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,155 @@
|
||||
function [eqs, Awell, qwell,PVv, Bga, Bwa] = eqsOW_MB_oil_water_flow(state, state0, dt, r, f, os, Wellc, Weladd, pwf, WelChg, well_schedules_k)
|
||||
|
||||
p = state.p;
|
||||
sw = state.sw;
|
||||
p0 = state0.p;
|
||||
sw0 = state0.sw;
|
||||
[p, sw] = intADI_oil_water_flow(p, sw);
|
||||
|
||||
% z方向上的位势
|
||||
% 由于当深度发生变化时,流体的密度也会发生变化,因此不能简单得处理成折算压力的情况计算
|
||||
%对位势z进行处理
|
||||
z=r.z;
|
||||
z = intADIz(z);
|
||||
% Dosi是地面标况下测得的油相密度,Dwsi是地面标况下测得的水相密度
|
||||
|
||||
% % % % 应力敏感系数
|
||||
% % % exp_paramter_1 = -0.04;
|
||||
% % % reference_pressure = 20;
|
||||
% % % stress_factor = exp(exp_paramter_1*(p-reference_pressure));
|
||||
|
||||
% Water Props
|
||||
BW = f.Bw(p);
|
||||
muW = f.muw(p);
|
||||
krW = f.krw(sw);
|
||||
pcOW = 0;
|
||||
if f.ifpcow
|
||||
pcOW = f.pcow(sw);
|
||||
end
|
||||
pw = p - pcOW;
|
||||
dpW = os.grad(pw);
|
||||
% dzw=1e-6*9.8*f.Dwsi*os.grad(z./BW); %水相位势梯度
|
||||
dzw=0;
|
||||
upc = (double(dpW+dzw)<=0);%一定要是折算压力!
|
||||
mobW = os.faceUpstr(upc, krW) .* os.faceAvg(1./(BW.*muW));
|
||||
% mobW = os.faceUpstr(upc, krW) .* os.faceAvg(1./(BW.*muW)) .* os.faceAvg(stress_factor);
|
||||
% 针对启动压力梯度的平滑处理
|
||||
if f.p_grad_threshold ~= 0
|
||||
pcOW0 = f.pcgl(sw0);
|
||||
pw0 = p0 - pcOW0;
|
||||
dpW0 = os.grad(pw0);
|
||||
dzw0=0;
|
||||
dpW0 = dpW0+dzw0;
|
||||
pW_grad0 = r.T_diff./r.flowArea.*dpW0;
|
||||
ratioW = smooth_relu_stable(pW_grad0, f.p_grad_threshold);
|
||||
else
|
||||
ratioW = 1;
|
||||
end
|
||||
bWvW = -r.T .* mobW .* (dpW).*ratioW;
|
||||
% bWvW = -r.T .* mobW .* dpW;
|
||||
|
||||
% gas Props
|
||||
BO = f.Bo(p);
|
||||
muO = f.muo(p);
|
||||
krO = f.kro(sw);
|
||||
dpO = os.grad(p);
|
||||
% dzg=1e-6*9.8*f.Dgsi*os.grad(z./BG); %油相位势梯度
|
||||
dzo=0;
|
||||
upc = (double(dpO+dzo)<=0);%一定要是折算压力,否则出错!
|
||||
mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO));
|
||||
% mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO)).* os.faceAvg(stress_factor);
|
||||
% 针对启动压力梯度的平滑处理
|
||||
if f.p_grad_threshold ~= 0
|
||||
dpO0 = os.grad(p0);
|
||||
dzo0=0;
|
||||
dpO0 = dpO0+dzo0;
|
||||
pO_grad0 = r.T_diff./r.flowArea.*dpO0;
|
||||
ratioO = smooth_relu_stable(pO_grad0, f.p_grad_threshold);
|
||||
else
|
||||
ratioO = 1;
|
||||
end
|
||||
% Knudsen 扩散影响
|
||||
bOvO = -r.matrixflag.*r.T .* mobO .* dpO.*ratioO ...
|
||||
-(1-r.matrixflag).*r.T .* mobO .* dpO.*ratioO;
|
||||
% Knudsen 扩散影响
|
||||
% bGvG = -r.matrixflag.*f.gas_prop.Kn_modified_factor.*r.T .* mgbG .* dpG ...
|
||||
% -(1-r.matrixflag).*r.T .* mgbG .* dpG;
|
||||
|
||||
% 非达西流发生仅发生在裂缝网格内
|
||||
% Forchheimer_factor = 1/(1+kf/mug*beta*density_g*v_gf)
|
||||
BO0 = f.Bo(p0);muO0 = f.muo(p0);krO0 = f.kro(sw0);dpO0 = os.grad(p0);
|
||||
dzo0=0;
|
||||
upc0 = (double(dpO0+dzo0)<=0);%一定要是折算压力,否则出错!
|
||||
mobO0 = os.faceUpstr(upc0, krO0) .* os.faceAvg(1./(BO0.*muO0));
|
||||
% mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO)).* os.faceAvg(stress_factor);
|
||||
v_of = -(1-r.matrixflag).*r.T .* mobO0 .* dpO0./r.flowArea;
|
||||
density_o = f.density_o_sc./BO0;
|
||||
Forchheimer_factor = 1./(1+(1-r.matrixflag).*r.perm./os.faceAvg(muO0).*f.beta_non_Darcy_flow.*os.faceAvg(density_o).*abs(v_of));
|
||||
|
||||
% 分别有基质系统的应力敏感系数 和 裂缝系统的应力敏感系数
|
||||
stress_factor = r.matrixflag.*exp(r.stress_factor_matrix*(os.faceAvg(p0)-r.stress_factor_ref_pressure))...
|
||||
+(1-r.matrixflag).*exp(r.stress_factor_fracture*(os.faceAvg(p0)-r.stress_factor_ref_pressure));
|
||||
|
||||
% 采用简单的叠加处理
|
||||
bWvW = bWvW.*stress_factor.*Forchheimer_factor;
|
||||
bOvO = bOvO.*stress_factor.*Forchheimer_factor;
|
||||
% z方向上的位势
|
||||
% 由于当深度发生变化时,流体的密度也会发生变化,因此不能简单得处理成折算压力的情况计算
|
||||
%对位势z进行处理
|
||||
% z=r.z;
|
||||
% z = intADIz(z);
|
||||
% Dosi是地面标况下测得的油相密度,Dwsi是地面标况下测得的水相密度
|
||||
% dzo=0.01*os.grad(z./BO); %油相位势梯度
|
||||
% dzw=0.01*os.grad(z./BW); %水相位势梯度
|
||||
% bOvO = -r.T .* mobO .* (dpO+dzo);
|
||||
% bWvW=-r.T .* mobW .* (dpW+dzw);
|
||||
|
||||
% transfer function (OW)
|
||||
% [qomf, qofm, qwmf, qwfm] = transFunc(r, krO, krW, BO, muO, BW, muW, p, pw);
|
||||
|
||||
% well equation
|
||||
[Awell, qwell] = WellEquation_oil_water_flow(r, f, p.val, sw.val, Wellc, Weladd, pwf, WelChg, well_schedules_k);
|
||||
% Awell=dt*Awell;
|
||||
% qwell=dt*qwell;
|
||||
|
||||
% Accumulation term
|
||||
PV = r.V .* r.por(p);
|
||||
PV0 = r.V .* r.por(p0);
|
||||
Ar_w = 1/dt*(PV .* (sw ./ BW) - PV0 .* (sw0 ./ f.Bw(p0)));
|
||||
Ar_o = 1/dt*(PV .* ((1 - sw) ./ BO) - PV0 .* ((1 - sw0) ./ f.Bo(p0)));
|
||||
|
||||
% Water Equation
|
||||
eqs{1} = (-os.div(bWvW) - Ar_w);
|
||||
% 使基质考虑重力,裂缝不考虑重力
|
||||
% eqs{1} = (-os.div(-r.T .* mobW .* dpW)-r.rpt.*os.div(-r.T .* mobW .* dzw) - Ar_w)*dt;
|
||||
% eqs{1} = (-os.div(-r.T .* mobW .* dpW) - Ar_w)*dt;
|
||||
% eqs{1} = -os.div(bWvW) - Ar_w;
|
||||
% Oil Equation
|
||||
eqs{2} = (-os.div(bOvO) - Ar_o);
|
||||
% eqs{2} = (-os.div(-r.T .* mobO .* dpO)-r.rpt.*os.div(-r.T .* mobO .* dzo) - Ar_o)*dt;
|
||||
% eqs{2} = (-os.div(-r.T .* mobO .* dpO) - Ar_o)*dt;
|
||||
PVv = PV.val;
|
||||
Bwa = BW.val;
|
||||
Bga = BO.val;
|
||||
% eqs{2} = -os.div(bOvO) - Ar_o;
|
||||
|
||||
|
||||
% Rw = Ar_w.val - qwell(1 : r.nc);
|
||||
% Ro = Ar_o.val - qwell(r.nc+1 : 2*r.nc);
|
||||
% PVv = PV.val;
|
||||
% % PV_all = sum(PVv);
|
||||
% Bwa = mean(BW.val);
|
||||
% Boa = mean(BO.val);
|
||||
|
||||
% MBw = abs(Bwa * dt * (sum(Rw)/PV_all));
|
||||
% MBo = abs(Boa * dt * (sum(Ro)/PV_all));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
function f = fluidPVT_oil_water_flow(Ppr, BO, MUO, Bwi, prw, cw, vwi, cvw, SW, KRO, KRW, PCOW, SWF, KROF, KRWF, PCOWF, density_o_sc, ifpcow, rpt)
|
||||
% f = fluidPVT(Bopb, pb, co, Bwi, prw, cw, vwi, cvw, visopb, cvo, SW, KRO, KRW, PCOW, ifpcow, SWF, KROF, KRWF, PCOWF, rpt,Dosi,Dwsi)
|
||||
f.Bw = @(p) Bw_ow(p, Bwi, prw, cw);
|
||||
f.Bo = @(p) Bo_ow(p, BO, Ppr);
|
||||
f.muw = @(p) muw_ow(p, vwi, prw, cvw);
|
||||
f.muo = @(p) muo_ow(p, MUO, Ppr);
|
||||
f.kro = @(sw) kro_ow(sw, SW, KRO, SWF, KROF, rpt);
|
||||
f.krw = @(sw) krw_ow(sw, SW, KRW, SWF, KRWF, rpt);
|
||||
f.pcow = @(sw) pcow(sw, SW, PCOW, SWF, PCOWF, rpt);
|
||||
f.density_o_sc = density_o_sc;
|
||||
f.ifpcow = ifpcow;
|
||||
% f.Dosi=Dosi;
|
||||
% f.Dwsi=Dwsi;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
function [Weladd, pwf] = initalSchedule_oil_water_flow(p, sw, Wellc, f, well_schedules_k)
|
||||
nWel = size(Wellc, 1);%井数
|
||||
Weladd = 0;
|
||||
pwf = zeros(1);
|
||||
BW = f.Bw(p);
|
||||
muW = f.muw(p);
|
||||
krW = f.krw(sw);
|
||||
BO = f.Bo(p);
|
||||
muO = f.muo(p);
|
||||
krO = f.kro(sw);
|
||||
Yot = krO ./ (muO .* BO);%mu代表黏度
|
||||
Yoj = krO ./ muO;
|
||||
Ywt = krW ./ (muW .* BW);%mu代表黏度
|
||||
Ywj = krW ./ muW;
|
||||
|
||||
for i = 1 : nWel
|
||||
if strcmp(well_schedules_k{i,2},'open')
|
||||
if strcmp(well_schedules_k{i,3},'pro') && strcmp(well_schedules_k{i,4},'const_q') %该井是生产井并定产生产
|
||||
Weladd = Weladd + 1;
|
||||
nper = Wellc{i,2}; %该井的射孔数量
|
||||
jperf = zeros(nper,1);
|
||||
Trans = zeros(nper,1);
|
||||
Tnp = 0;
|
||||
Tn = 0;
|
||||
for j = 1 : nper
|
||||
jperf(j) = Wellc{i,3}(j);%该射孔点在基质网格和裂缝单元全体中的序号
|
||||
Tr = Wellc{i,4}(j);%该射孔点对应的生产指数(缺流度)
|
||||
Trans(j) = Tr * (Yot(jperf(j)) + Ywt(jperf(j)));%生产指数
|
||||
Tnp = Tnp + Trans(j)*p(jperf(j));
|
||||
Tn = Tn + Trans(j);
|
||||
end
|
||||
pwf(Weladd) = (Tnp - well_schedules_k{i,5}/86.4) / Tn;%说明井筒无限导流,压力为一个值
|
||||
elseif strcmp(well_schedules_k{i,3},'inj') && strcmp(well_schedules_k{i,4},'const_q') %注入井,恒定注入量
|
||||
Weladd = Weladd + 1;
|
||||
nper = Wellc{i,2};
|
||||
jperf = zeros(nper,1);
|
||||
Trans = zeros(nper,1);
|
||||
Tnp = 0;
|
||||
Tn = 0;
|
||||
for j = 1 : nper
|
||||
jperf(j) = Wellc{i,3}(j);
|
||||
Tr = Wellc{i,4}(j);
|
||||
Trans(j) = Tr / BW(jperf(j)) * (Yoj(jperf(j)) + Ywj(jperf(j)));%多相流注入方程
|
||||
Tnp = Tnp + Trans(j)*p(jperf(j));
|
||||
Tn = Tn + Trans(j);
|
||||
end
|
||||
pwf(Weladd) = (Tnp + well_schedules_k{i,5}/86.4) / Tn;%与生产井正好反过来
|
||||
else
|
||||
continue
|
||||
end
|
||||
end
|
||||
end
|
||||
pwf = pwf';
|
||||
@@ -0,0 +1,3 @@
|
||||
function state = initialRS_oil_water_flow(P, Sw)
|
||||
state.p = P;
|
||||
state.sw = Sw;
|
||||
@@ -0,0 +1,18 @@
|
||||
function [P, Sw, Pwf] = intADI2_oil_water_flow(p, sw, pwf)
|
||||
n = length(p);
|
||||
npwf = length(pwf);
|
||||
Jp = cell(1,3);
|
||||
Jsw = cell(1,3);
|
||||
Jpwf = cell(1,3);
|
||||
Jp{1} = sparse(1:n, 1:n, ones(n,1), n, n);
|
||||
Jp{2} = sparse(n,n);
|
||||
Jp{3} = sparse(n,npwf);
|
||||
Jsw{1} = sparse(n,n);
|
||||
Jsw{2} = sparse(1:n, 1:n, ones(n,1), n, n);
|
||||
Jsw{3} = sparse(n,npwf);
|
||||
Jpwf{1} = sparse(npwf,n);
|
||||
Jpwf{2} = sparse(npwf,n);
|
||||
Jpwf{3} = sparse(1:npwf, 1:npwf, ones(npwf,1), npwf, npwf);
|
||||
P = ADI(p, Jp);
|
||||
Sw = ADI(sw, Jsw);
|
||||
Pwf = ADI(pwf, Jpwf);
|
||||
@@ -0,0 +1,10 @@
|
||||
function [P, Sw] = intADI_oil_water_flow(p, sw)
|
||||
n = length(p);
|
||||
Jp = cell(1,2);
|
||||
Jsw = cell(1,2);
|
||||
Jp{1} = sparse(1:n, 1:n, ones(n,1), n, n);
|
||||
Jp{2} = sparse(n,n);
|
||||
Jsw{1} = sparse(n,n);
|
||||
Jsw{2} = sparse(1:n, 1:n, ones(n,1), n, n);
|
||||
P = ADI(p, Jp);
|
||||
Sw = ADI(sw, Jsw);
|
||||
@@ -0,0 +1,14 @@
|
||||
function h = kro_ow(sw, SW, KRO, varargin)
|
||||
n = numel(varargin);%表示没有输入裂缝参数
|
||||
if n == 0
|
||||
h = interptable(SW, KRO, sw);
|
||||
else
|
||||
SWF = varargin{1};
|
||||
KROF = varargin{2};
|
||||
rpt = varargin{3};
|
||||
hm = interptable(SW, KRO, sw);
|
||||
hf = interptable(SWF, KROF, sw);
|
||||
h = rpt .* hm + ~rpt .* hf;%分别为裂缝与基质
|
||||
end
|
||||
% h=sw+(1-sw);
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
function h = krw_ow(sw, SW, KRW, varargin)
|
||||
n = numel(varargin);
|
||||
if n == 0
|
||||
h = interptable(SW, KRW, sw);
|
||||
else
|
||||
SWF = varargin{1};
|
||||
KRWF = varargin{2};
|
||||
rpt = varargin{3};
|
||||
hm = interptable(SW, KRW, sw);
|
||||
hf = interptable(SWF, KRWF, sw);
|
||||
h = rpt .* hm + ~rpt .* hf;
|
||||
end
|
||||
% h=sw-sw;
|
||||
end
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
function [Times, OutputRs, Wellpara, trun] = mainRS_MB_oil_water_flow(r, f, os, w, state0)
|
||||
t_start = clock;
|
||||
dtmin = w.dtmin;
|
||||
dtmax = w.dtmax;
|
||||
Nmax = w.Nmax;
|
||||
epsave = w.epsave;
|
||||
epsmax = w.epsmax;
|
||||
yitap = w.yitap;
|
||||
yitas = w.yitas;
|
||||
omega = w.omega;
|
||||
Wellc = w.Wellc;
|
||||
time = w.time;
|
||||
well_schedules = w.well_schedules;
|
||||
% WelChg = w.WelChg;
|
||||
% tend = w.tend;
|
||||
count = 0;
|
||||
t = 0;
|
||||
state = state0;
|
||||
OutputRs = cell(2,1);
|
||||
Wellpara = cell(2,1);
|
||||
Times = zeros(2,1);
|
||||
% h0 = waitbar(0,'Please wait...');
|
||||
for k = 1:size(well_schedules,1)
|
||||
dt=dtmin(k);
|
||||
[Weladd, pwf] = initalSchedule_oil_water_flow(state0.p, state0.sw, Wellc, f, well_schedules{k,1});
|
||||
% [Weladd, pwf] = initalSchedule(state0.p, state0.sw, Wellc, f);
|
||||
WelChg = zeros(size(well_schedules{k,1},1),1); % 后续有用,先不用
|
||||
repi = 0;
|
||||
Newton_step = 0;
|
||||
cons_Jacob = 0;
|
||||
leqs_solve_time = 0;
|
||||
Newtons_vs_time = [0, 0];
|
||||
tend = sum(time(1:k),1);
|
||||
while t < tend
|
||||
for i = 1 : Nmax
|
||||
dtc = dt * 86.4;
|
||||
tic;
|
||||
[eqs, Awell, qwell, Pvv, Boa, Bwa] = ...
|
||||
eqsOW_MB_oil_water_flow(state, state0, dtc, r, f, os, Wellc, Weladd, pwf, WelChg, well_schedules{k,1});
|
||||
Jacob = Awell;
|
||||
Ris = qwell;
|
||||
Jacob(1 : r.nc,1 : 2 * r.nc) = Jacob(1 : r.nc,1 : 2 * r.nc) + [eqs{1}.jac{1} eqs{1}.jac{2}];
|
||||
Jacob(r.nc + 1 : 2 * r.nc,1 : 2 * r.nc) = Jacob(r.nc + 1 : 2 * r.nc,1 : 2 * r.nc) + [eqs{2}.jac{1} eqs{2}.jac{2}];
|
||||
Ris(1 : r.nc) = Ris(1 : r.nc) + eqs{1}.val ;
|
||||
Ris(r.nc + 1: 2 * r.nc) = Ris(r.nc + 1: 2 * r.nc) + eqs{2}.val ;
|
||||
% 将误差无因次化,用以判断是否收敛
|
||||
Dimensionless_Ris = Ris(1: 2 * r.nc)./ [Pvv;Pvv] .* [Bwa;Boa] .* dtc;
|
||||
cons_Jacob_lo=toc;
|
||||
cons_Jacob=cons_Jacob+cons_Jacob_lo;
|
||||
% PVall = sum(Pvv);
|
||||
% MBw = Bwa*dtc*abs(sum(Ris(1:r.nc))/PVall);
|
||||
% MBo = Boa*dtc*abs(sum(Ris(r.nc+1:2*r.nc))/PVall);
|
||||
% CNVw = max(Bwa*dtc*abs(Ris(1:r.nc)./Pvv));
|
||||
% CNVo = max(Boa*dtc*abs(Ris(r.nc+1:2*r.nc)./Pvv));
|
||||
% [L,U] = ilu(-Jacob);
|
||||
% tol = 1e-6;
|
||||
% maxit = 50;
|
||||
% [X, ~] = bicgstab(-Jacob,Ris,tol,maxit,L,U);
|
||||
tic;
|
||||
% tol = 1e-12;
|
||||
% maxit = 200;
|
||||
% [X0,fl0,rr0,it0,rv0] = gmres(-Jacob,Ris,[],tol,maxit);
|
||||
% [L,U] = ilu(-Jacob,struct('type','ilutp','droptol',1e-6));
|
||||
% [X1,fl1,rr1,it1,rv1] = gmres(-Jacob,Ris,[],tol,maxit,L,U);
|
||||
X = -Jacob \ Ris;
|
||||
leqs_time=toc;
|
||||
leqs_solve_time=leqs_solve_time+leqs_time;
|
||||
Newton_step=Newton_step+1;
|
||||
dsw = X(r.nc + 1 : 2*r.nc);
|
||||
dp = X(1 : r.nc);
|
||||
state.p = state.p + dp;
|
||||
state.sw = state.sw + dsw;
|
||||
% deltp=state.p-state0.p;
|
||||
% deltsw=state.sw-state0.sw;
|
||||
if Weladd > 0
|
||||
dpwf = X(2 * r.nc + 1 : end);
|
||||
pwf = pwf + dpwf;
|
||||
state.pwf = pwf;
|
||||
end
|
||||
% if MBw <= epsave && MBo <= epsave && CNVw <= epsmax && CNVo <=epsmax && max(dsw)<=0.02 && max(dp)<=1
|
||||
% break
|
||||
% end
|
||||
% 为适应更一般的情况,将Ris无因次化
|
||||
|
||||
if mean(abs(Dimensionless_Ris)) <= epsave && max(abs(Dimensionless_Ris)) <=epsmax
|
||||
break
|
||||
end
|
||||
|
||||
% [L,U] = ilu(-Jacob);
|
||||
% tol = 1e-6;
|
||||
% maxit = 50;
|
||||
% [X, ~] = bicgstab(-Jacob,Ris,tol,maxit,L,U);
|
||||
% raodai=condest(Jacob);
|
||||
% if condest(Jacob)>50000
|
||||
% dt = dt / 2;
|
||||
% else
|
||||
end
|
||||
|
||||
if i == Nmax
|
||||
repi = repi + 1;
|
||||
if repi == 5
|
||||
error('too many iter')
|
||||
end
|
||||
if repi == 1
|
||||
dt = dt / 2;
|
||||
elseif repi == 2
|
||||
dt = dt / 3;
|
||||
else
|
||||
dt = dt / 10;
|
||||
end
|
||||
% dt = max(dt, w.dtmin);
|
||||
state = state0;
|
||||
else
|
||||
repi = 0;
|
||||
t = t + dt;
|
||||
count = count + 1;
|
||||
Times(count) = t;
|
||||
OutputRs{count} = state;
|
||||
Newtons_vs_time = [Newtons_vs_time; t, Newton_step];
|
||||
% qwell=qwell/dtc;%转换为单位时间的流量
|
||||
[Wellpara_t, WelChg, Weladd] = calcWellequation_oil_water_flow(Weladd, Wellc, WelChg, well_schedules{k,1}, r.nc, qwell, state);
|
||||
Wellpara{count} = Wellpara_t;
|
||||
state0 = state;
|
||||
tm = ADtimestep(yitap, yitas, omega, dp, dsw);
|
||||
% tm=1;
|
||||
dt = dt * tm;
|
||||
if t + dt > tend
|
||||
dt = tend - t;
|
||||
end
|
||||
if dt >= dtmax(k)
|
||||
dt = dtmax(k);
|
||||
end
|
||||
if i ~= Nmax
|
||||
% waitbar(t / tend);
|
||||
% disp(t);
|
||||
fprintf('正在计算:%.4f天/共%.4f天\n', t, sum(time));
|
||||
|
||||
end
|
||||
if t>300
|
||||
flag = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
trun.cons_Jacob=cons_Jacob;
|
||||
trun.leqs_solve_time=leqs_solve_time;
|
||||
trun.total_simulation_time = etime(clock,t_start);
|
||||
trun.Newton_step=Newton_step;
|
||||
trun.Newtons_vs_time=Newtons_vs_time;
|
||||
fprintf('计算完成');
|
||||
% close(h0);
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
function h = muo_ow(p, MUO, Ppr)
|
||||
h = interptable(Ppr, MUO, p);
|
||||
end
|
||||
@@ -0,0 +1,2 @@
|
||||
function h = muw_ow(p, vwi, prw, cvw)
|
||||
h = vwi + cvw * (p - prw);
|
||||
@@ -0,0 +1,16 @@
|
||||
function h = pcow(sw, SW, PCOW, varargin)
|
||||
n = numel(varargin);
|
||||
if PCOW == 0
|
||||
h = 0;
|
||||
else
|
||||
if n == 0
|
||||
h = interptable(SW, PCOW, sw);
|
||||
else
|
||||
SWF = varargin{1};
|
||||
PCOWF = varargin{2};
|
||||
rpt = varargin{3};
|
||||
hm = interptable(SW, PCOW, sw);
|
||||
hf = interptable(SWF, PCOWF, sw);
|
||||
h = rpt .* hm + ~rpt .* hf;
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
function h = por(p, prpor, pori, cpor, varargin)
|
||||
n = numel(varargin);
|
||||
if n == 0
|
||||
h = pori .* (1 + cpor .* (p - prpor));
|
||||
else
|
||||
prporf = varargin{1};
|
||||
cporf = varargin{2};
|
||||
rpt = varargin{3};
|
||||
hm = pori .* (1 + cpor .* (p - prpor));
|
||||
hf = pori .* (1 + cporf .* (p - prporf));
|
||||
h = rpt .* hm + ~rpt .* hf;
|
||||
end
|
||||
Reference in New Issue
Block a user