commit 04e2bb29c7684975ad0d1c1eef8f3690991e0eeb Author: xinxiao Date: Fri Mar 13 11:24:41 2026 +0800 init diff --git a/closeup.m b/closeup.m new file mode 100644 index 0000000..2dc10c7 --- /dev/null +++ b/closeup.m @@ -0,0 +1 @@ + rmpath(genpath(pwd)) \ No newline at end of file diff --git a/core functions/preprocess/EDFM_transFunction/Bpara.m b/core functions/preprocess/EDFM_transFunction/Bpara.m new file mode 100644 index 0000000..332dba3 --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/Bpara.m @@ -0,0 +1,17 @@ +function BF = Bpara(xb, yb) +n = length(xb); +BF = zeros(n, 7); +BF(:,3) = xb; +BF(:,4) = yb; +for i = 1 : n + if i == n + ip = 1; + else + ip = i + 1; + end + BF(i,1) = (xb(i) + xb(ip)) / 2; + BF(i,2) = (yb(i) + yb(ip)) / 2; + BF(i,5) = ((xb(i) - xb(ip))^2 + (yb(i) - yb(ip))^2)^0.5; + BF(i,6) = (yb(ip) - yb(i)) / BF(i,5); + BF(i,7) = (xb(i) - xb(ip)) / BF(i,5); +end \ No newline at end of file diff --git a/core functions/preprocess/EDFM_transFunction/Fpara.m b/core functions/preprocess/EDFM_transFunction/Fpara.m new file mode 100644 index 0000000..ed624c1 --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/Fpara.m @@ -0,0 +1,14 @@ +function FF = Fpara(xf, yf) +nf = length(xf)/2; +FF = zeros(nf, 7); +for i = 1 : nf + i1 = 2 * i - 1; + i2 = 2 * i; + FF(i,3) = xf(i1); + FF(i,4) = yf(i1); + FF(i,1) = (xf(i1) + xf(i2)) / 2; + FF(i,2) = (yf(i1) + yf(i2)) / 2; + FF(i,5) = ((xf(i1) - xf(i2))^2 + (yf(i1) - yf(i2))^2)^0.5; + FF(i,6) = (yf(i2) - yf(i1)) / FF(i,5); + FF(i,7) = (xf(i1) - xf(i2)) / FF(i,5); +end \ No newline at end of file diff --git a/core functions/preprocess/EDFM_transFunction/anios.m b/core functions/preprocess/EDFM_transFunction/anios.m new file mode 100644 index 0000000..a3f24aa --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/anios.m @@ -0,0 +1,4 @@ +function [x1, y1, ka] = anios(kx, ky, x, y) +ka = (kx*ky)^0.5; +x1 = x*(ka/kx)^0.5; +y1 = y*(ka/ky)^0.5; \ No newline at end of file diff --git a/core functions/preprocess/EDFM_transFunction/finddg.m b/core functions/preprocess/EDFM_transFunction/finddg.m new file mode 100644 index 0000000..89788d8 --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/finddg.m @@ -0,0 +1,8 @@ +function dG = finddg(xs, ys, xk, yk, nkx, nky, lk) +% Function aims to solve the boundary integrals +dG = (lk / (2 * pi)) * quadgk(@(t)intdg(xs, ys, xk, yk, nkx, nky, lk, t), 0, 1); + +% intg.m +function y = intdg(xs, ys, xk, yk, nkx, nky, lk, t) +y = (nkx*(xk - xs) + nky*(yk - ys))... + ./((xk - t*lk*nky - xs).^2 + (yk + t*lk*nkx - ys).^2); \ No newline at end of file diff --git a/core functions/preprocess/EDFM_transFunction/finddgAn.m b/core functions/preprocess/EDFM_transFunction/finddgAn.m new file mode 100644 index 0000000..e177111 --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/finddgAn.m @@ -0,0 +1,15 @@ +function dG = finddgAn(xs, ys, xk, yk, nkx, nky, lk) +% Function aims to solve the boundary integrals +A = lk^2; +B = (-nky * (xk - xs) + nkx * (yk - ys)) * (2 * lk); +E = (xk - xs)^2 + (yk - ys)^2; +eps = 1e-9; +De = 4 * A * E - B^2; +if De <= eps + dG = 0; +else + dG = lk/pi * (nkx*(xk - xs)+nky*(yk - ys))/De^0.5 * ... + (atan((2*A+B)/De^0.5) - atan(B/De^0.5)); +end + + diff --git a/core functions/preprocess/EDFM_transFunction/findg.m b/core functions/preprocess/EDFM_transFunction/findg.m new file mode 100644 index 0000000..1dbf909 --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/findg.m @@ -0,0 +1,7 @@ +function G = findg(xs, ys, xk, yk, nkx, nky, lk) +% Function aims to solve the boundary integrals +G = (1 / (4 * pi)) * quadgk(@(t)intg(xs, ys, xk, yk, nkx, nky, lk, t), 0, 1); + +% intg.m +function y = intg(xs, ys, xk, yk, nkx, nky, lk, t) +y = log((xk - t*lk*nky - xs).^2 + (yk + t*lk*nkx - ys).^2); \ No newline at end of file diff --git a/core functions/preprocess/EDFM_transFunction/findgAn.m b/core functions/preprocess/EDFM_transFunction/findgAn.m new file mode 100644 index 0000000..91aa0cd --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/findgAn.m @@ -0,0 +1,16 @@ +function G = findgAn(xs, ys, xk, yk, nkx, nky, lk) +% Function aims to solve the boundary integrals +A = lk^2; +B = (-nky * (xk - xs) + nkx * (yk - ys)) * (2 * lk); +E = (xk - xs)^2 + (yk - ys)^2; +eps = 1e-9; +De = 4 * A * E - B^2; +if De <= eps + G = lk/2/pi * (log(lk/2) - 1); +else + G = 1/4/pi * (2*(log(lk) - 1) - B/2/A*log(abs(E/A))... + + (1 + B/2/A)*log(abs(1 + B/A + E/A)) + De^0.5/A... + *(atan((2*A + B)/De^0.5) - atan(B/De^0.5))); +end + + diff --git a/core functions/preprocess/EDFM_transFunction/transFunc.m b/core functions/preprocess/EDFM_transFunction/transFunc.m new file mode 100644 index 0000000..5605d2b --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/transFunc.m @@ -0,0 +1,35 @@ +function [qomf, qofm, qwmf, qwfm] = transFunc(r, krO, krW, BO, muO, BW, muW, po, pw) +%po,pw均是定义的类数据 +Ka = r.Ka; +M = r.M; +F2M = r.F2M; +MF_coef = r.MF_coef; +nfc = r.nfc;%裂缝单元个数 +nc = r.nc; % 存在流体交换的数量 +C = sparse((1 : nfc)' * [1 1], M, ones(nfc, 1) * [-1 1], nfc, nc); +grad = @(x) C * x; +faceUpstr = @(flag, x) faceUpstrb(flag, x, M, [nfc, nc]); +dpO = grad(po); +upc = (double(dpO)<=0); +mobO = faceUpstr(upc, krO./(BO.*muO)); +% qomf = Ka .* r.h .* mobO .* (MF_coef * po);%矩阵的行数为裂缝单元的数量 +qomf = r.V(r.nmc+1:r.nc)./r.wf.*Ka' .* mobO .* (MF_coef * po);%需乘以裂缝面积,因为因为一开始得到的是窜流量面密度 +% qomf = r.V(r.nmc+1:r.nc).*Ka .* mobO .* (MF_coef * po); +% qomf = Ka .* mobO .* (MF_coef * po); +qofm = -F2M * qomf;%矩阵行数为基质网格数量,体现向量化编程 +dpW = grad(pw); +upc = (double(dpW)<=0); +mobW = faceUpstr(upc, krW./(BW.*muW)); +% qwmf = Ka .* r.h .* mobW .* (MF_coef * pw); +qwmf = r.V(r.nmc+1:r.nc)./r.wf.*Ka' .* mobW .* (MF_coef * pw); +% qwmf = r.V(r.nmc+1:r.nc).*Ka .* mobW .* (MF_coef * pw); +% qwmf = Ka .* mobW .* (MF_coef * pw); +qwfm = -F2M * qwmf; + + +function xu = faceUpstrb(flag, x, N, sz) +flag = logical(flag); +upcell = N(:, 2); +upcell(flag) = N(flag, 1); +xu = sparse((1 : sz(1))', upcell, 1, sz(1), sz(2)) * x; + diff --git a/core functions/preprocess/EDFM_transFunction/transFunc_aniso.m b/core functions/preprocess/EDFM_transFunction/transFunc_aniso.m new file mode 100644 index 0000000..08d2de1 --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/transFunc_aniso.m @@ -0,0 +1,115 @@ +function [Ka, M, F2M , MF_coef,MF_deltt] = transFunc_aniso(nc,coordinates, nodes, connectmf,Ap,Apf , matrixvsfra,N,T , kx, ky,kz) +%[Ka, M, F2M , MF_coef,MF_deltt] = transFunc_aniso(nc,coordinates, nodes, connectmf,Ap,Apf ,Apmt,Apft, matrixvsfra,N,T , kx, ky,kz) +Ncell = size(connectmf, 1);%包含裂缝单元的基质网格数 +nmc=size(matrixvsfra,1); +nfc=nc-nmc; +I = zeros(1, 1); +J = zeros(1, 1); +M = zeros(1, 2); +Ka = zeros(1, 1); +cou = 0; +for i = 1 : Ncell + ie = connectmf{i,1};%该基质网格的编号 +% indxf = ConnecS{i, 3};%该基质网格包含的裂缝单元/点 +% order = reshape(ConnecS{i,2}',[],1);%该基质网格中包含的裂缝点的编号列向量 +% xb = coordinates(nodes(ie,:),1);%该基质网格顶点的x坐标 +% yb = coordinates(nodes(ie,:),2);%该基质网格顶点的y坐标 +% xf = Linep(order,1);%裂缝点的x坐标 +% yf = Linep(order,2);%裂缝点的y坐标 +% 如果是各向异性,就进行自变量代换 +% 先编译各向同性的 +% [xb1, yb1, ka] = anios(kx(ie), ky(ie), xb, yb); +% [xf1, yf1, ~] = anios(kx(ie), ky(ie), xf, yf); +% BF = Bpara(xb1, yb1); +% FF = Fpara(xf1, yf1); +% [Ap, Apf] = transMF(BF, FF); + indxf=connectmf{i,2}; + Api=Ap{i,1}; Apfi=Apf{i,1}; + nlf = length(indxf);%该基质网格中包含的裂缝单元数 + ind = ie;%该基质网格的编号 + indf = indxf + nmc;%该基质网格所包含裂缝单元在nc中的序号 + m1 = repmat(ind, nlf, 1); + f1 = repmat(indf, nlf, 1); + Il = zeros(nlf, 1+nlf); + Jl = [m1 f1]; + Vl = [Api Apfi]; + for j = 1 : nlf + cou = cou + 1; + Il(j,:) = indxf(j); + I(cou) = ie; + J(cou) = indxf(j);%裂缝单元在nfc中的序号 + ka=(kx(ie)*ky(ie)*kz(ie))^(1/3); + Ka(cou) = ka; + M(cou, 1) = connectmf{i,1}; + M(cou, 2) = indf(j); + end + Il = reshape(Il, [], 1); + Jl = reshape(Jl, [], 1); + Vl = reshape(Vl, [], 1); + if i == 1 + I2 = Il; + J2 = Jl; + V2 = Vl; + else + I2 = [I2; Il]; + J2 = [J2; Jl]; + V2 = [V2; Vl]; + end +end +V = ones(cou, 1); +F2M = sparse(I, J, V, nmc, nfc); +MF_coef = sparse(I2, J2, V2, nfc, nc); +% for i = 1 : Ncell +% ie = connectmf{i,1};%该基质网格的编号 +% indxf = ConnecS{i, 3};%该基质网格包含的裂缝单元/点 +% order = reshape(ConnecS{i,2}',[],1);%该基质网格中包含的裂缝点的编号列向量 +% xb = coordinates(nodes(ie,:),1);%该基质网格顶点的x坐标 +% yb = coordinates(nodes(ie,:),2);%该基质网格顶点的y坐标 +% xf = Linep(order,1);%裂缝点的x坐标 +% yf = Linep(order,2);%裂缝点的y坐标 +% 如果是各向异性,就进行自变量代换 +% 先编译各向同性的 +% [xb1, yb1, ka] = anios(kx(ie), ky(ie), xb, yb); +% [xf1, yf1, ~] = anios(kx(ie), ky(ie), xf, yf); +% BF = Bpara(xb1, yb1); +% FF = Fpara(xf1, yf1); +% [Ap, Apf] = transMF(BF, FF); +% indxf=connectmf{i,2}; +% Apmti=Apmt{i,1}; Apfti=Apft{i,1}; +% nlf = length(indxf);%该基质网格中包含的裂缝单元数 +% ind = ie;%该基质网格的编号 +% indf = indxf + nmc;%该基质网格所包含裂缝单元在nc中的序号 +% m1 = repmat(ind, nlf, 1); +% f1 = repmat(indf, nlf, 1); +% Il = zeros(nlf, 1+nlf); +% Jl = [m1 f1]; +% Vl = [Apmti Apfti]; +% for j = 1 : nlf +% cou = cou + 1; +% Il(j,:) = indxf(j); +% % I(cou) = ie; +% % J(cou) = indxf(j);%裂缝单元在nfc中的序号 +% % ka=(kx(ie)*ky(ie)*kz(ie))^(1/3); +% % Ka(cou) = ka; +% % M(cou, 1) = connectmf{i,1}; +% % M(cou, 2) = indf(j); +% end +% Il = reshape(Il, [], 1); +% Jl = reshape(Jl, [], 1); +% Vl = reshape(Vl, [], 1); +% if i == 1 +% I2 = Il; +% J2 = Jl; +% V2 = Vl; +% else +% I2 = [I2; Il]; +% J2 = [J2; Jl]; +% V2 = [V2; Vl]; +% end +% end +% % V = ones(cou, 1); +% % F2M = sparse(I, J, V, nmc, nfc); +% MF_deltt = sparse(I2, J2, V2, nfc, nc); +% end + + diff --git a/core functions/preprocess/EDFM_transFunction/transFuncdeltt.m b/core functions/preprocess/EDFM_transFunction/transFuncdeltt.m new file mode 100644 index 0000000..cdfb140 --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/transFuncdeltt.m @@ -0,0 +1,29 @@ +function [qomf, qofm] = transFuncdeltt(r, BO, muO, po,dt,pi) +%po,pw均是定义的类数据 +Ka = r.Ka; +M = r.M; +F2M = r.F2M; +MF_coef = r.MF_coef; +nfc = r.nfc;%裂缝单元个数 +nc = r.nc; % 存在流体交换的数量 +C = sparse((1 : nfc)' * [1 1], M, ones(nfc, 1) * [-1 1], nfc, nc); +grad = @(x) C * x; +faceUpstr = @(flag, x) faceUpstrb(flag, x, M, [nfc, nc]); +dpO = grad(po); +upc = (double(dpO)<=0); +mobO = faceUpstr(upc, 1./(BO.*muO)); +% qomf = Ka .* r.h .* mobO .* (MF_coef * po);%矩阵的行数为裂缝单元的数量 +qomf = r.V(r.nmc+1:r.nc)./r.wf.*Ka' .* mobO .* (MF_coef * po)+1/dt*(r.cpor+0.1*r.co)*r.wf.*(r.MF_deltt*(po-pi));%需乘以裂缝面积,因为因为一开始得到的是窜流量面密度 +% qomf = r.V(r.nmc+1:r.nc)./r.wf.*(Ka' .* mobO .* (MF_coef * po)); +% qomf = r.V(r.nmc+1:r.nc).*Ka .* mobO .* (MF_coef * po); +% qomf = Ka' .* mobO .* (MF_coef * po); +qofm = -F2M * qomf;%矩阵行数为基质网格数量,体现向量化编程 + + + +function xu = faceUpstrb(flag, x, N, sz) +flag = logical(flag); +upcell = N(:, 2); +upcell(flag) = N(flag, 1); +xu = sparse((1 : sz(1))', upcell, 1, sz(1), sz(2)) * x; + diff --git a/core functions/preprocess/EDFM_transFunction/transMF.m b/core functions/preprocess/EDFM_transFunction/transMF.m new file mode 100644 index 0000000..59716eb --- /dev/null +++ b/core functions/preprocess/EDFM_transFunction/transMF.m @@ -0,0 +1,61 @@ +function [Ap, Apf] = transMF(BF, FF) +[nb,~] = size(BF); +[nf,~] = size(FF); +Gb = zeros(nb); +dGb = zeros(nb); +Gmf = zeros(nb, nf); +Gf = zeros(nf, nb); +dGf = zeros(nf, nb); +Gff = zeros(nf); +xb = BF(:,1); +yb = BF(:,2); +xmk = BF(:,3); +ymk = BF(:,4); +lmk = BF(:,5); +nxmk = BF(:,6); +nymk = BF(:,7); +xf = FF(:,1); +yf = FF(:,2); +xfk = FF(:,3); +yfk = FF(:,4); +lfk = FF(:,5); +nxfk = FF(:,6); +nyfk = FF(:,7); +% boundary equation +for i = 1 : nb + for j = 1 : nb + if j == i + dGb(i, j) = 0.0; + Gb(i, j) = 1/(2*pi) * (log(lmk(j)/2) - 1.0); + else + Gb(i, j) = findg(xb(i), yb(i), xmk(j), ymk(j), nxmk(j), nymk(j), lmk(j)); + dGb(i, j) = finddg(xb(i), yb(i), xmk(j), ymk(j), nxmk(j), nymk(j), lmk(j)); + end + end + for j = 1 : nf + Gmf(i, j) = findg(xb(i), yb(i), xfk(j), yfk(j), nxfk(j), nyfk(j), lfk(j)); + end +end +dGb = dGb - 0.5 * eye(nb); +% fracture equation +for i = 1 : nf + for j = 1 : nb + Gf(i, j) = findg(xf(i), yf(i), xmk(j), ymk(j), nxmk(j), nymk(j), lmk(j)); + dGf(i, j) = finddg(xf(i), yf(i), xmk(j), ymk(j), nxmk(j), nymk(j), lmk(j)); + end + for j = 1 : nf + if i == j + Gff(i, j) = 1/(2*pi) * (log(lfk(j)/2) - 1.0); + else + Gff(i, j) = findg(xf(i), yf(i), xfk(j), yfk(j), nxfk(j), nyfk(j), lfk(j)); + end + end +end +Gbv = Gb^(-1); +Ap0 = dGf - Gf * Gbv * dGb; +Apf0 = Gf * Gbv * Gmf - Gff; +Apfv = Apf0^(-1); +Ap = Apfv * Ap0; +Ap = Ap * ones(nb,1); +Apf = -Apfv; + diff --git a/core functions/preprocess/Ulit/ADI.m b/core functions/preprocess/Ulit/ADI.m new file mode 100644 index 0000000..f7c2b25 --- /dev/null +++ b/core functions/preprocess/Ulit/ADI.m @@ -0,0 +1,324 @@ +classdef ADI + % ADI class: simple implementation of automatic differentiation for easy construction of jacobian matrices. + % + % SYNOPSIS: + % x = ADI(value, jacobian) + % + % PARAMETERS: + % value - The numerical value of the object + % + % jacobian - The Jacobian of the object. + % + % RETURNS: + % ADI object. + % + % COMMENTS: + % This class is typically instansiated for a set of different variables + % using initVariablesADI. The file contains a worked example demonstrating + % the usage for several variables. + % + % SEE ALSO: + % initVariablesADI + + %{ +Copyright 2009-2014 SINTEF ICT, Applied Mathematics. + +This file is part of The MATLAB Reservoir Simulation Toolbox (MRST). + +MRST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +MRST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with MRST. If not, see . + %} + + + properties + val %function value + jac %list of sparse jacobian matrices + end + + methods + function obj = ADI(a,b) + %ADI class constructor + if nargin == 0 % empty constructor + obj.val = []; + obj.jac = {}; + elseif nargin == 1 % + if isa(a, 'ADI') + obj = a; + else + error('Contructor requires 2 inputs') + end + elseif nargin == 2 % values + jacobians + obj.val = a; % value + if ~iscell(b) + b = {b}; + end + obj.jac = b; % jacobian or list of jacobians + else + error('Input to constructor not valid') + end + end + + %-------------------------------------------------------------------- + function h = numval(u) + h = numel(u.val); + end + + %-------------------------------------------------------------------- + function h = double(u) + h = u.val; + end + + %-------------------------------------------------------------------- + + function h = ge(u, v) + h = ge(double(u), double(v)); + end + + %-------------------------------------------------------------------- + + function h = gt(u, v) + h = gt(double(u), double(v)); + end + + %-------------------------------------------------------------------- + + function h = le(u, v) + h = le(double(u), double(v)); + end + + %-------------------------------------------------------------------- + + function h = lt(u, v) + h = lt(double(u), double(v)); + end + %-------------------------------------------------------------------- + + function h = uplus(u) + h = u; + end + + %-------------------------------------------------------------------- + + function h = uminus(u) + h = ADI(-u.val, uminusJac(u.jac)); + end + + %-------------------------------------------------------------------- + + % function h = plus(u,v) + % if ~isa(u,'ADI') %u is a vector/scalar + % h = ADI(u+v.val, v.jac); + % elseif ~isa(v,'ADI') %v is a vector/scalar + % h = ADI(u.val + v, u.jac); + % else + % h = ADI(u.val+v.val, plusJac(u.jac, v.jac) ); + % end + % end + + function h = plus(u,v) + if ~isa(u,'ADI') %u is a vector/scalar + if numel(u) <= numel(v.val) + h = ADI(u+v.val, v.jac); + elseif numel(v.val) == 1 + h = plus(u, repmat(v,[numel(u), 1])); + else + error('Vectors have different lengths') + end + elseif ~isa(v,'ADI') %v is a vector/scalar + if numel(v) <= numel(u.val) + h = ADI(u.val + v, u.jac); + elseif numel(u.val) == 1 + h = plus(repmat(u,[numel(v), 1]), v); + else + error('Vectors have different lengths') + end + else + if numel(u.val) == numel(v.val) + h = ADI(u.val+v.val, plusJac(u.jac, v.jac) ); + elseif numel(u.val) == 1 + h = plus(repmat(u, [numel(v.val), 1]), v); + elseif numel(v.val) == 1 + h = plus(u, repmat(v, [numel(u.val), 1])); + else + error('Vectors have different lengths') + end + end + end + + + %-------------------------------------------------------------------- + + function h = minus(u,v) + h = plus(u, uminus(v)); + end + + %-------------------------------------------------------------------- + + function h = mtimes(u,v)% '*' + if ~isa(u,'ADI') %u is a scalar/matrix + h = ADI(u*v.val, mtimesJac(u, v.jac)); + elseif ~isa(v,'ADI') %v is a scalar + h = mtimes(v,u); + else % special case where either u or v has single value + if numel(u.val) == 1 + h = times(repmat(u, [numel(v.val), 1]), v); + elseif numel(v.val) == 1 + h = times(u, repmat(v, [numel(u.val), 1])); + else + error('Operation not supported'); + end + end + end + + %-------------------------------------------------------------------- + + function h = times(u,v)% '.*' + if ~isa(u,'ADI') %u is a scalar/vector + if numel(u)==numel(v.val) + h = ADI(u.*v.val, lMultDiag(u, v.jac)); + else + h = mtimes(u,v); + end + elseif ~isa(v,'ADI') %v is a scalar/vector + h = times(v,u); + else + if numel(u.val)==numel(v.val) + h = ADI(u.val.*v.val, timesJac(u.val, v.val, u.jac, v.jac)); + elseif numel(v.val)==1||numel(u.val)==1 + h = mtimes(u,v); + else + error('Operation not supported'); + end + end + end + + %-------------------------------------------------------------------- + + function h = mrdivide(u,v)% '/' + if ~isa(v,'ADI') %v is a scalar + h = mtimes(u, 1/v); + else + error('Operation not supported'); + end + end + + %-------------------------------------------------------------------- + + function h = subsref(u,s) + switch s(1).type + case '.' + h = builtin('subsref',u,s); + case '()' + assert(numel(s(1).subs) == 1, ... + 'Expected single index, got %d', numel(s(1).subs)) + subs = s(1).subs{1}; + if ischar(s) && strcmp(subs, ':'), + h = u; + else + if islogical(subs), subs = find(subs); end + h = ADI(u.val(subs), subsrefJac(u.jac, subs)); + end + if numel(s) > 1 + % Recursively handle next operation + h = subsref(h, s(2:end)); + end + case '{}' + error('Operation not supported'); + end + end + + %-------------------------------------------------------------------- + + function h = power(u,v)% '.^' + h = ADI(u.val.^v, lMultDiag(v.*u.val.^(v-1), u.jac)); + end + + %-------------------------------------------------------------------- + + function h = rdivide(u,v)% './' + h = times(u, power(v, -1)); + end + + %-------------------------------------------------------------------- + + function h = exp(u) + eu = exp(u.val); + h = ADI(eu, lMultDiag(eu, u.jac)); + end + + %-------------------------------------------------------------------- + + function h = log(u) + logu = log(u.val); + h = ADI(logu, lMultDiag(1./u.val, u.jac)); + end + + %-------------------------------------------------------------------- + + function h = interptable(X, Y, u) + y = interptable(X, Y, u.val); + dydx = dinterptable(X, Y, u.val); + h = ADI(y,lMultDiag(dydx, u.jac)); + end + + %-------------------------------------------------------------------- + end +end + +%************************************************************************** +%-------- Helper functions involving Jacobians --------------------------- +%************************************************************************** +function J = uminusJac(J1) +J = cellfun(@uminus, J1, 'UniformOutput', false); +end + +function J = plusJac(J1, J2) +J = cellfun(@plus, J1, J2, 'UniformOutput', false); +end + +function J = mtimesJac(M, J1) +J = cell(1, numel(J1)); +for k = 1:numel(J) + J{k} = M*J1{k}; +end +end + +function J = lMultDiag(d, J1) +n = numel(d); +D = sparse((1:n)', (1:n)', d, n, n); +J = cell(1, numel(J1)); +for k = 1:numel(J) + J{k} = D*J1{k}; +end +end + +function J = timesJac(v1, v2, J1, J2) +n = numel(v1); +D1 = sparse((1:n)', (1:n)', v1, n, n); +D2 = sparse((1:n)', (1:n)', v2, n, n); +J = cell(1, numel(J1)); +for k = 1:numel(J) + J{k} = D1*J2{k} + D2*J1{k}; +end +end + +function J = subsrefJac(J1, subs) +J = cell(1, numel(J1)); +for k = 1:numel(J) + J{k} = J1{k}(subs,:); +end +end + +%-------------------------------------------------------------------------- +%-------------------------------------------------------------------------- +%-------------------------------------------------------------------------- diff --git a/core functions/preprocess/Ulit/ADtimestep.m b/core functions/preprocess/Ulit/ADtimestep.m new file mode 100644 index 0000000..de5c501 --- /dev/null +++ b/core functions/preprocess/Ulit/ADtimestep.m @@ -0,0 +1,6 @@ +function tm = ADtimestep(yitap, yitas, omega, dp, ds) +dp = abs(dp); +ds = abs(ds); +tm1 = (1 + omega) * yitap ./ (dp + omega * yitap); +tm2 = (1 + omega) * yitas ./ (ds + omega * yitas); +tm = min(min(tm1),min(tm2)); \ No newline at end of file diff --git a/core functions/preprocess/Ulit/OperatorRS.m b/core functions/preprocess/Ulit/OperatorRS.m new file mode 100644 index 0000000..d969174 --- /dev/null +++ b/core functions/preprocess/Ulit/OperatorRS.m @@ -0,0 +1,24 @@ +function os = OperatorRS(N, nex, nc) +%向量化编程体现 +%nex是网格之间具有流体交换的总数 +%nc 是网格总数 +%N 矩阵每一行对应着有着流体交换的基质单元之间、裂缝单元之间 +% Avg of face property +M = sparse((1 : nex)' * [1 1], N, 0.5 * ones(nex, 2), nex, nc); +os.faceAvg = @(x) M * x; +% Harm of face property +M = sparse((1 : nex)' * [1 1], N, ones(nex, 2), nex, nc); +os.faceHarm = @(x) 1./ (M * (1 ./ x)); +% Div and grad +C = sparse((1 : nex)' * [1 1], N, ones(nex, 1) * [-1 1], nex, nc); +os.grad = @(x) C * x; +os.div = @(x) -C' * x; +% Upstream weighting +os.faceUpstr = @(flag, x) faceUpstr(flag, x, N, [nex, nc]); + +function xu = faceUpstr(flag, x, N, sz) +flag = logical(flag); +upcell = N(:, 2); +upcell(flag) = N(flag, 1); +xu = sparse((1 : sz(1))', upcell, 1, sz(1), sz(2)) * x; + diff --git a/core functions/preprocess/Ulit/dinterptable.m b/core functions/preprocess/Ulit/dinterptable.m new file mode 100644 index 0000000..9179021 --- /dev/null +++ b/core functions/preprocess/Ulit/dinterptable.m @@ -0,0 +1,13 @@ +function h = dinterptable(X, Y, u) +% n = length(X); +% DYDX = diff(Y) ./ diff(X); +% DYDX = DYDX([1, 1:end, end]); +% [~, b] = histc(u, [-inf;X;inf]); +% b = b - 1; +% b(b == 0) = 1; +% b(b == n) = n - 1; +% h = DYDX(b); +DYDX = diff(Y) ./ diff(X); +DYDX = DYDX([1, 1:end, end]); +[~, b] = histc(u, [-inf;X;inf]); +h = reshape(DYDX(b), [], 1); diff --git a/core functions/preprocess/Ulit/fluidPVT.m b/core functions/preprocess/Ulit/fluidPVT.m new file mode 100644 index 0000000..bb486da --- /dev/null +++ b/core functions/preprocess/Ulit/fluidPVT.m @@ -0,0 +1,17 @@ +function f = fluidPVT(Bopb, pb, co, Bwi, prw, cw, vwi, cvw, visopb, cvo, SW, KRO, KRW, PCOW, ifpcow, SWF, KROF, KRWF, PCOWF, rpt,Dosi, Dwsi, cs_data, csa_data, cb_data, cba_data) +f.Bw = @(p) Bw(p, Bwi, prw, cw); +f.Bo = @(p) Bo(p, Bopb, pb, co); +f.muw = @(p) muw(p, vwi, prw, cvw); +f.muo = @(p) muo(p, visopb, pb, cvo); +f.kro = @(sw) kro(sw, SW, KRO, SWF, KROF, rpt); +f.krw = @(sw) krw(sw, SW, KRW, SWF, KRWF, rpt); +f.pcow = @(sw) pcow(sw, SW, PCOW, SWF, PCOWF, rpt); +f.krow = @(sw) kro(sw, SWF, KROF); +f.krww = @(sw) krw(sw, SWF, KRWF); +f.pcoww = @(sw) pcow(sw, SWF, PCOWF); +f.cs_absorb = @(sw) cs_absorb_f(cs, cs_data, csa_data); +f.cb_absorb = @(sw) cb_absorb_f(cb, cb_data, cba_data); +f.ifpcow = ifpcow; +f.Dosi = Dosi; +f.Dwsi = Dwsi; + diff --git a/core functions/preprocess/Ulit/initialRS.m b/core functions/preprocess/Ulit/initialRS.m new file mode 100644 index 0000000..4a52916 --- /dev/null +++ b/core functions/preprocess/Ulit/initialRS.m @@ -0,0 +1,5 @@ +function state = initialRS(P, Sw, Cs, Cb) +state.p = P; +state.sw = Sw; +state.cs = Cs; +state.cb = Cb; diff --git a/core functions/preprocess/Ulit/intADI.m b/core functions/preprocess/Ulit/intADI.m new file mode 100644 index 0000000..1582d8f --- /dev/null +++ b/core functions/preprocess/Ulit/intADI.m @@ -0,0 +1,31 @@ +function [P, Sw, Cs, Cb] = intADI(p, sw, cs, cb) +n = length(p); +Jp = cell(1,4); +Jsw = cell(1,4); +Jcs = cell(1,4); +Jcb = cell(1,4); + +Jp{1} = sparse(1:n, 1:n, ones(n,1), n, n); +Jp{2} = sparse(n,n); +Jp{3} = sparse(n,n); +Jp{4} = sparse(n,n); + +Jsw{1} = sparse(n,n); +Jsw{2} = sparse(1:n, 1:n, ones(n,1), n, n); +Jsw{3} = sparse(n,n); +Jsw{4} = sparse(n,n); + +Jcs{1} = sparse(n,n); +Jcs{2} = sparse(n,n); +Jcs{3} = sparse(1:n, 1:n, ones(n,1), n, n); +Jcs{4} = sparse(n,n); + +Jcb{1} = sparse(n,n); +Jcb{2} = sparse(n,n); +Jcb{3} = sparse(n,n); +Jcb{4} = sparse(1:n, 1:n, ones(n,1), n, n); + +P = ADI(p, Jp); +Sw = ADI(sw, Jsw); +Cs = ADI(cs, Jcs); +Cb = ADI(cb, Jcb); \ No newline at end of file diff --git a/core functions/preprocess/Ulit/intADI2.m b/core functions/preprocess/Ulit/intADI2.m new file mode 100644 index 0000000..da11a07 --- /dev/null +++ b/core functions/preprocess/Ulit/intADI2.m @@ -0,0 +1,44 @@ +function [P, Sw, Cs, Cb, Pwf] = intADI2(p, sw, cs, cb, pwf) +n = length(p); +npwf = length(pwf); +Jp = cell(1,5); +Jsw = cell(1,5); +Jcs = cell(1,5); +Jcb = cell(1,5); +Jpwf = cell(1,5); + +Jp{1} = sparse(1:n, 1:n, ones(n,1), n, n); +Jp{2} = sparse(n,n); +Jp{3} = sparse(n,n); +Jp{4} = sparse(n,n); +Jp{5} = sparse(n,npwf); + +Jsw{1} = sparse(n,n); +Jsw{2} = sparse(1:n, 1:n, ones(n,1), n, n); +Jsw{3} = sparse(n,n); +Jsw{4} = sparse(n,n); +Jsw{5} = sparse(n,npwf); + +Jcs{1} = sparse(n,n); +Jcs{2} = sparse(n,n); +Jcs{3} = sparse(1:n, 1:n, ones(n,1), n, n); +Jcs{4} = sparse(n,n); +Jcs{5} = sparse(n,npwf); + +Jcb{1} = sparse(n,n); +Jcb{2} = sparse(n,n); +Jcb{3} = sparse(n,n); +Jcb{4} = sparse(1:n, 1:n, ones(n,1), n, n); +Jcb{5} = sparse(n,npwf); + +Jpwf{1} = sparse(npwf,n); +Jpwf{2} = sparse(npwf,n); +Jpwf{3} = sparse(npwf,n); +Jpwf{4} = sparse(npwf,n); +Jpwf{5} = sparse(1:npwf, 1:npwf, ones(npwf,1), npwf, npwf); + +P = ADI(p, Jp); +Sw = ADI(sw, Jsw); +Cs = ADI(cs, Jcs); +Cb = ADI(cb, Jcb); +Pwf = ADI(pwf, Jpwf); \ No newline at end of file diff --git a/core functions/preprocess/Ulit/intADIz.m b/core functions/preprocess/Ulit/intADIz.m new file mode 100644 index 0000000..cbbd1d9 --- /dev/null +++ b/core functions/preprocess/Ulit/intADIz.m @@ -0,0 +1,6 @@ +function [z] = intADIz(z) +n = length(z); +Jz = cell(1,2); +Jz{1} = sparse( n, n);%对压力 +Jz{2} = sparse(n,n);%对饱和度 +z = ADI(z, Jz); diff --git a/core functions/preprocess/Ulit/interptable.m b/core functions/preprocess/Ulit/interptable.m new file mode 100644 index 0000000..9b620f3 --- /dev/null +++ b/core functions/preprocess/Ulit/interptable.m @@ -0,0 +1,2 @@ +function h = interptable(X, Y, u) +h = interp1(X, Y, u, 'linear', 'extrap'); \ No newline at end of file diff --git a/core functions/preprocess/about_Well/WellEquation.m b/core functions/preprocess/about_Well/WellEquation.m new file mode 100644 index 0000000..26bbafd --- /dev/null +++ b/core functions/preprocess/about_Well/WellEquation.m @@ -0,0 +1,149 @@ +function [Awell, qwell] = WellEquation(r, f, p, sw, cs, cb, 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 = 4 * 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, cs, cb] = intADI(p, sw, cs, cb); +else + [p, sw, cs, cb, pwf] = intADI2(p, sw, cs, cb, pwf); +end +BW = f.Bw(p); +muW = f.muw(p); +Nc = f.Nc(cs); +krW = f.krw(sw, Nc); +BG = f.Bg(p); +muG = f.mug(p); +krG = f.krrg(sw, Nc); +Ygt = krG ./ (muG .* BG); +Ywt = krW ./ (muW .* BW); +Ygj = krG ./ muG; +Ywj = krW ./ muW; +pcOW = 0; +if f.ifpcgl%若为0,则毛管力为0 + pcOW = f.pcgl(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 = Ygt(jperf); + Yw = Ywt(jperf); + qo = -Tr(j) .* Yo .*(p(jperf) - pwf(ipwf)); + qw = -Tr(j) .* Yw .*(pw(jperf) - pwf(ipwf)); + qcs = -Tr(j) .* cs(jperf).*Yw .*(pw(jperf) - pwf(ipwf)); + qcb = -Tr(j) .* cb(jperf).*Yw .*(pw(jperf) - pwf(ipwf)); + %前nc行是水相方程 + Awell(jperf, :) = [qw.jac{1} qw.jac{2} qw.jac{3} qw.jac{4} qw.jac{5}]; + qwell(jperf) = qw.val; + %后nc行是水相方程 + Awell(r.nc + jperf, :) = [qo.jac{1} qo.jac{2} qo.jac{3} qo.jac{4} qo.jac{5}]; + qwell(r.nc + jperf) = qo.val; + % 表活剂 + Awell(2*r.nc + jperf, :) = [qcs.jac{1} qcs.jac{2} qcs.jac{3} qcs.jac{4} qcs.jac{5}]; + qwell(2*r.nc + jperf) = qcs.val; + % 盐 + Awell(3*r.nc + jperf, :) = [qcb.jac{1} qcb.jac{2} qcb.jac{3} qcb.jac{4} qcb.jac{5}]; + qwell(3*r.nc + jperf) = qcb.val; + %把该井所有射孔点的产油、产水累加起来 + % 在定流量情况下,为了使得能够适用于更一般情况,比如气井流量较大,导致该方程MR迭代收敛条件过高,因此需要无因次化 + Awell(4*r.nc + ipwf, :) = Awell(4*r.nc + ipwf, :) + ... + [qw.jac{1} qw.jac{2} qw.jac{3} qw.jac{4} qw.jac{5}] + [qo.jac{1} qo.jac{2} qo.jac{3} qo.jac{4} qo.jac{5}]; + qwell(4*r.nc + ipwf) = qwell(4*r.nc + ipwf) + qw.val + qo.val; + end + qwell(4*r.nc + ipwf) = (qwell(4*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 = Ygt(jperf); + Yw = Ywt(jperf); + qo = -Tr(j) .* Yo .*(p(jperf) - pwfc); + qw = -Tr(j) .* Yw .*(pw(jperf) - pwfc); + qcs = -Tr(j) .* cs(jperf).*Yw .*(pw(jperf) - pwfc); + qcb = -Tr(j) .* cb(jperf).*Yw .*(pw(jperf) - pwfc); + % 水 + Awell(jperf, 1 : 4 * r.nc) = [qw.jac{1} qw.jac{2} qw.jac{3} qw.jac{4}]; + qwell(jperf) = qw.val; + % 油 + Awell(r.nc + jperf, 1 : 4 * r.nc) = [qo.jac{1} qo.jac{2} qo.jac{3} qo.jac{4}]; + qwell(r.nc + jperf) = qo.val; + % 表活剂 + Awell(2*r.nc + jperf, 1 : 4 * r.nc) = [qcs.jac{1} qcs.jac{2} qcs.jac{3} qcs.jac{4}]; + qwell(2*r.nc + jperf) = qcs.val; + % 盐 + Awell(3*r.nc + jperf, 1 : 4 * r.nc) = [qcb.jac{1} qcb.jac{2} qcb.jac{3} qcb.jac{4}]; + qwell(3*r.nc + jperf) = qcb.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 = Ygj(jperf); + Yw = Ywj(jperf); + qw = -Tr(j) ./ BW(jperf) .* (Yo + Yw) .* (pw(jperf) - pwf(ipwf)); + qcs = qw*well_schedules_k{i,8}; + qcb = qw*well_schedules_k{i,10}; + % 水 + Awell(jperf, :) = [qw.jac{1} qw.jac{2} qw.jac{3} qw.jac{4} qw.jac{5}]; + qwell(jperf) = qw.val; + % 表活剂 + Awell(2*r.nc + jperf, :) = [qcs.jac{1} qcs.jac{2} qcs.jac{3} qcs.jac{4} qcs.jac{5}]; + qwell(2*r.nc + jperf) = qcs.val; + % 盐 + Awell(3*r.nc + jperf, :) = [qcb.jac{1} qcb.jac{2} qcb.jac{3} qcb.jac{4} qcb.jac{5}]; + qwell(3*r.nc + jperf) = qcb.val; + % + Awell(4*r.nc + ipwf, :) = Awell(4*r.nc + ipwf, :) + ... + [qw.jac{1} qw.jac{2} qw.jac{3} qw.jac{4} qw.jac{5}]; + qwell(4*r.nc + ipwf) = qwell(4*r.nc + ipwf) + qw.val; + end + qwell(4*r.nc + ipwf) = qwell(4*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 = Ygj(jperf); + Yw = Ywj(jperf); + qw =- Tr(j) ./ BW(jperf) .* (Yo + Yw) .* (pw(jperf) - pwfc); + qcs = qw*well_schedules_k{i,8}; + qcb = qw*well_schedules_k{i,10}; + Awell(jperf, 1 : 4*r.nc) = [qw.jac{1} qw.jac{2} qw.jac{3} qw.jac{4}]; + qwell(jperf) = qw.val; + % 表活剂 + Awell(2*r.nc + jperf, 1 : 4*r.nc) = [qcs.jac{1} qcs.jac{2} qcs.jac{3} qcs.jac{4}]; + qwell(2*r.nc + jperf) = qcs.val; + % 盐 + Awell(3*r.nc + jperf, 1 : 4*r.nc) = [qcb.jac{1} qcb.jac{2} qcb.jac{3} qcb.jac{4}]; + qwell(3*r.nc + jperf) = qcb.val; + end + end + end + end +end diff --git a/core functions/preprocess/about_Well/calcTrans.m b/core functions/preprocess/about_Well/calcTrans.m new file mode 100644 index 0000000..a2471fb --- /dev/null +++ b/core functions/preprocess/about_Well/calcTrans.m @@ -0,0 +1,58 @@ +function Wellc0 = calcTrans(r, Wellc0) +% Wellcpara: welltype(1) nperf(2) index(3) rw/WI(4) protype(5) value(6) +% constraints(7) skin(8) Wellc(nWel, 6) +% welltype = 1 prod, welltype = 2 inj water, welltype = 3 inj gas +% protype = 1 const flowrate, protype = 2 const pwf +% 此处编程假设射孔段是整个网格的尺寸 +nwel = size(Wellc0, 1);%井数 +for i = 1 : nwel + perf = Wellc0{i, 3};%射孔点 + rw = Wellc0{i, 4};%井半径 + skin = Wellc0{i, 5};%井表皮 + nperf = length(perf);%射孔点的数量 + WI = zeros(nperf,1);%每个射孔点对应的生产指数 + for j = 1 : nperf + ind = perf(j); + if ind <= r.nmc % 代表该射孔点在基质网格 + kmx = r.kx(ind); + kmy = r.ky(ind); + kmz = r.kz(ind); + dx = r.dxv(ind); + dy = r.dyv(ind); + dz = r.dzv(ind); + if Wellc0{i,6}==1%说明是直井 +% h = r.h; + ro = 0.28* (((kmy/kmx)^0.5*dx^2 + (kmx/kmy)^0.5*dy^2))^0.5... + / ((kmy/kmx)^0.25 + (kmx/kmy)^0.25);%直井peaceman公式中的等效供给半径 + ka = (kmx*kmy*kmz)^(1/3);%该基质网格等效渗透率 + %cf=1,疑似为射开储层厚度的比例 + WI(j) = r.cf * 2 * 3.1415 * ka * dz / (log(ro / rw) + skin);%生产指数 + elseif Wellc0{i,6}==2%说明是沿x方向的水平井 + ro = 0.28* (((kmz/kmy)^0.5*dy^2 + (kmy/kmz)^0.5*dz^2))^0.5... + / ((kmz/kmy)^0.25 + (kmy/kmz)^0.25);%直井peaceman公式中的等效供给半径 + ka = (kmx*kmy*kmz)^(1/3);%该基质网格等效渗透率 + %cf=1,疑似为射开储层厚度的比例 + WI(j) = r.cf * 2 * 3.1415 * ka * dx / (log(ro / rw) + skin);%生产指数 + elseif Wellc0{i,6}==3%说明是沿y方向的水平井 + ro = 0.28* (((kmz/kmx)^0.5*dx^2 + (kmx/kmz)^0.5*dz^2))^0.5... + / ((kmz/kmx)^0.25 + (kmx/kmz)^0.25); + ka = (kmx*kmy*kmz)^(1/3); + %cf=1,疑似为射开储层厚度的比例 + WI(j) = r.cf * 2 * 3.1415 * ka * dy / (log(ro / rw) + skin);%生产指数 + end + else % 说明是多段压裂水平井, 射孔点在裂缝单元 + I = ind - r.nmc;%该射孔段设置为裂缝单元,是多段压裂水平井 + kf = r.kf(I); + wf = r.wf(I); + area=r.fcff{1,8}(I); +% lf = r.lf(I); +% h = r.h; +% h=1;lf=2; + %此处修改为该裂缝单元的面积的两倍,开二次方,乘以0.14 + ro = 0.14 * (2*area)^0.5; +% ro = 0.14 * (10^2+10^2)^0.5; + WI(j) = r.cf * 2 * 3.1415 * kf * wf / (log(ro / rw) + skin); + end + end + Wellc0{i, 4} = WI;%将半径替换为生产指数向量 +end diff --git a/core functions/preprocess/about_Well/calcWellequation.m b/core functions/preprocess/about_Well/calcWellequation.m new file mode 100644 index 0000000..ca8c648 --- /dev/null +++ b/core functions/preprocess/about_Well/calcWellequation.m @@ -0,0 +1,100 @@ +function [Wellpara, WelChg, Weladd] = calcWellequation(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); + 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 + 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 + end + end +end diff --git a/core functions/preprocess/about_Well/findWelloc.m b/core functions/preprocess/about_Well/findWelloc.m new file mode 100644 index 0000000..bbaf7c8 --- /dev/null +++ b/core functions/preprocess/about_Well/findWelloc.m @@ -0,0 +1,32 @@ +function perfnum = findWelloc(r, welloc) +% Linep = r.Linep; +% Fracp = r.Fracp; +corevsfra=r.fcff{1,4};%裂缝单元中心坐标 +% corevsfra = r.cell_mid_coordinates; +nfc = size(corevsfra,1); +% x = zeros(nfc, 1); +% y = zeros(nfc, 1); +% z = zeros(nfc, 1); +% for i = 1 : nf +% x = Linep(Fracp(i,:), 1); +% y = Linep(Fracp(i,:), 2); +% %基于两翼等长的人工主裂缝 +% xp(i) = mean(x); +% yp(i) = mean(y); +% end + x = corevsfra(:, 1); + y = corevsfra(:, 2); + z = corevsfra(:, 3); + % z = 5; + +Nperf = size(welloc, 1); +perfnum = zeros(1, Nperf); +for i = 1 : Nperf + xw = welloc(i, 1); + yw = welloc(i, 2); + zw = welloc(i,3); + rp = (xw - x).^2 + (yw - y).^2+(zw-z).^2; + [~,I] = min(rp); + perfnum(i) = I + r.nmc; + % perfnum(i) = I; +end \ No newline at end of file diff --git a/core functions/preprocess/about_Well/initalSchedule.m b/core functions/preprocess/about_Well/initalSchedule.m new file mode 100644 index 0000000..2af2409 --- /dev/null +++ b/core functions/preprocess/about_Well/initalSchedule.m @@ -0,0 +1,51 @@ +function [Weladd, pwf] = initalSchedule(p, sw, Wellc, f) +nWel = size(Wellc, 1);%井数 +Weladd = 0; +pwf = zeros(1); +BW = f.Bw(p); +muW = f.muw(p); +krW = f.krw(sw); +BG = f.Bg(p); +muG = f.mug(p); +krG = f.krrg(sw); +Ygt = krG ./ (muG .* BG);%mu代表黏度 +Ygj = krG ./ muG; +Ywt = krW ./ (muW .* BW);%mu代表黏度 +Ywj = krW ./ muW; + +for i = 1 : nWel + if Wellc{i,1} == 1 && Wellc{i,5} == 1%该井是生产井并定产生产 + 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 * Ygt(jperf(j));%生产指数 + Tnp = Tnp + Trans(j)*p(jperf(j)); + Tn = Tn + Trans(j); + end + pwf(Weladd) = (Tnp - Wellc{i,6}/86.4) / Tn;%说明井筒无限导流,压力为一个值 + elseif Wellc{i,1} == 2 && Wellc{i,5} == 1%注入井,恒定注入量 + 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)) * (Ygj(jperf(j)) + Ywj(jperf(j)));%多相流注入方程 + Tnp = Tnp + Trans(j)*p(jperf(j)); + Tn = Tn + Trans(j); + end + pwf(Weladd) = (Tnp + Wellc{i,6}/86.4) / Tn;%与生产井正好反过来 + else + continue + end +end +pwf = pwf'; \ No newline at end of file diff --git a/core functions/preprocess/about_Well/wellperf.m b/core functions/preprocess/about_Well/wellperf.m new file mode 100644 index 0000000..f3ba1ab --- /dev/null +++ b/core functions/preprocess/about_Well/wellperf.m @@ -0,0 +1,8 @@ +function welloc = wellperf(well, fracp) +n = size(fracp,1)/2; +welloc = zeros(n, 2); +for i = 1 : n + [xi,yi] = polyxpoly([fracp(2*i-1,1) fracp(2*i,1)],[fracp(2*i-1,2) fracp(2*i,2)],[well(1,1) well(2,1)],[well(1,2) well(2,2)]); + welloc(i,1) = xi; + welloc(i,2) = yi; +end \ No newline at end of file diff --git a/core functions/preprocess/about_equation/eqsOW_MB.m b/core functions/preprocess/about_equation/eqsOW_MB.m new file mode 100644 index 0000000..dbbfd9e --- /dev/null +++ b/core functions/preprocess/about_equation/eqsOW_MB.m @@ -0,0 +1,96 @@ +function [eqs, qomf, qofm, qwmf, qwfm, Awell, qwell] = eqsOW_MB(state, state0, dt, r, f, os, Wellc, Weladd, pwf, WelChg) + +p = state.p; +sw = state.sw; +p0 = state0.p; +sw0 = state0.sw; +[p, sw] = intADI(p, sw); + +% z方向上的位势 +% 由于当深度发生变化时,流体的密度也会发生变化,因此不能简单得处理成折算压力的情况计算 +%对位势z进行处理 +z=r.z; +z = intADIz(z); +% Dosi是地面标况下测得的油相密度,Dwsi是地面标况下测得的水相密度 + +% 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); %水相位势梯度 +upc = (double(dpW+dzw)<=0); +mobW = os.faceUpstr(upc, krW) .* os.faceAvg(1./(BW.*muW)); +bWvW = -r.T .* mobW .* dpW; + +% Oil Props +BO = f.Bo(p); +muO = f.muo(p); +krO = f.kro(sw); +dpO = os.grad(p); +dzo=1e-6*9.8*f.Dosi*os.grad(z./BO); %油相位势梯度 +upc = (double(dpO+dzo)<=0); +mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO)); +bOvO = -r.T .* mobO .* dpO; + +% z方向上的位势 +% 由于当深度发生变化时,流体的密度也会发生变化,因此不能简单得处理成折算压力的情况计算 +%对位势z进行处理 +z=r.z; +z = intADIz(z); +% Dosi是地面标况下测得的油相密度,Dwsi是地面标况下测得的水相密度 +dzo=1e-6*9.8*f.Dosi*os.grad(z./BO); %油相位势梯度 +dzw=1e-6*9.8*f.Dwsi*os.grad(z./BW); %水相位势梯度 +% 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); +qomf=qomf*dt; +qofm=qofm*dt; +qwmf=qwmf*dt; +qwfm=qwfm*dt; +% well equation +[Awell, qwell] = WellEquation(r, f, p.val, sw.val, Wellc, Weladd, pwf, WelChg); +Awell=Awell*dt; +qwell=qwell*dt; +% 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)*dt; +% eqs{1} = -os.div(bWvW) - Ar_w; +% Oil Equation +eqs{2} = (-os.div(bOvO) - Ar_o)*dt; +% 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)); + + + + + + + + + + diff --git a/core functions/preprocess/about_equation/eqsOW_MB_2014.asv b/core functions/preprocess/about_equation/eqsOW_MB_2014.asv new file mode 100644 index 0000000..5c30f88 --- /dev/null +++ b/core functions/preprocess/about_equation/eqsOW_MB_2014.asv @@ -0,0 +1,189 @@ +function [eqs, Awell, qwell,PVv, Bga, Bwa] = eqsOW_MB_2014(state, state0, dt, r, f, os, Wellc, Weladd, pwf, WelChg, well_schedules_k) + +p = state.p; +sw = state.sw; +cs = state.cs; +cb = state.cb; +p0 = state0.p; +sw0 = state0.sw; +cs0 = state0.cs; +cb0 = state0.cb; +[p, sw, cs, cb] = intADI(p, sw, cs, cb); + +% 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)); +Nc0 = f.Nc(cs0); +Nc = f.Nc(cs); +% Water Props +BW = f.Bw(p); +muW = f.muw(p); +krW = f.krw(sw, Nc); +pcOW = 0; +if f.ifpcgl + pcOW = f.pcgl(sw); +end +pw = p - pcOW+f.chemistry_potential; +dpW = os.grad(pw); +% dzw=1e-6*9.8*f.Dwsi*os.grad(z./BW); %姘寸浉浣嶅娍姊害 +dzw=0; +dpW = dpW+dzw; +upc = (double(dpW)<=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+f.chemistry_potential; + dpW0 = os.grad(pw0); + dzw0=0; + dpW0 = dpW0+dzw0; + pW_grad = r.T.*dpW0./r.flowArea; + ratio = smooth_relu_stable(pW_grad, f.p_grad_threshold); +else + ratio = 1; +end +bWvW = -r.T .* mobW .* (dpW).*ratio; + + +% 瀛旈殭搴 +pore = r.por(p); +% 琛ㄦ椿鍓 +mobW_s = os.faceUpstr(upc, krW.*cs) .* os.faceAvg(1./(BW.*muW)); +bWvW_s = -r.T .* mobW_s .* dpW; +dcs = os.grad(cs); +upc_s = (double(dcs)<=0); +mobW_s_diff = os.faceUpstr(upc_s, pore.*sw) .* os.faceAvg(1./(BW)); +diff_s = -r.T_diff .*mobW_s_diff .* dcs; + +% 鐩 +mobW_b = os.faceUpstr(upc, krW.*cb) .* os.faceAvg(1./(BW.*muW)); +bWvW_b = -r.T .* mobW_b .* dpW; +dcb = os.grad(cb); +upc_b = (double(dcb)<=0); +mobW_b_diff = os.faceUpstr(upc_b, pore.*sw) .* os.faceAvg(1./(BW)); +diff_b = -r.T_diff.*mobW_b_diff.*dcb; + +% gas Props +BG = f.Bg(p); +muG = f.mug(p); +krG = f.krrg(sw, Nc); +dpG = os.grad(p); +% dzg=1e-6*9.8*f.Dgsi*os.grad(z./BG); %娌圭浉浣嶅娍姊害 +dzg=0; +dpG = dpG+dzg; +upc = (double(dpG)<=0);%涓瀹氳鏄姌绠楀帇鍔涳紝鍚﹀垯鍑洪敊锛 +mgbG = os.faceUpstr(upc, krG) .* os.faceAvg(1./(BG.*muG)); +% mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO)).* os.faceAvg(stress_factor); +% 閽堝鍚姩鍘嬪姏姊害鐨勫钩婊戝鐞 +if f.p_grad_threshold ~= 0 + dp0 = os.grad(p0); + dzg0=0; + dp0 = dp0+dzg0; + pG_grad = r.T.*dpG./r.flowArea; + pG_grad_new = smooth_relu_stable(pG_grad, f.p_grad_threshold); + bGvG = -r.matrixflag.*f.gas_prop.Kn_modified_factor.* mgbG.* pG_grad_new.*r.flowArea ... + -(1-r.matrixflag).* mgbG.* pG_grad_new.*r.flowArea; % Knudsen 鎵╂暎褰卞搷 +else + bGvG = -r.matrixflag.*f.gas_prop.Kn_modified_factor.*r.T .* mgbG .* dpG ... + -(1-r.matrixflag).*r.T .* mgbG .* dpG; % Knudsen 鎵╂暎褰卞搷 +end + +% 闈炶揪瑗挎祦鍙戠敓浠呭彂鐢熷湪瑁傜紳缃戞牸鍐 +% Forchheimer_factor = 1/(1+kf/mug*beta*density_g*v_gf) +BG0 = f.Bg(p0);muG0 = f.mug(p0);krG0 = f.krrg(sw0,Nc0);dpG0 = os.grad(p0); +dzg0=0; +upc0 = (double(dpG0+dzg0)<=0);%涓瀹氳鏄姌绠楀帇鍔涳紝鍚﹀垯鍑洪敊锛 +mgbG0 = os.faceUpstr(upc0, krG0) .* os.faceAvg(1./(BG0.*muG0)); +% mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO)).* os.faceAvg(stress_factor); +v_gf = -(1-r.matrixflag).*r.T .* mgbG0 .* dpG0./r.flowArea; +density_g = f.Dgsi./BG0; +Forchheimer_factor = 1./(1+(1-r.matrixflag).*r.perm./os.faceAvg(muG0).*f.gas_prop.beta_non_Darcy_flow.*os.faceAvg(density_g).*abs(v_gf)); + +% 鍒嗗埆鏈夊熀璐ㄧ郴缁熺殑搴斿姏鏁忔劅绯绘暟 鍜 瑁傜紳绯荤粺鐨勫簲鍔涙晱鎰熺郴鏁 +stress_factor = r.matrixflag.*exp(f.gas_prop.stress_factor_matrix*(os.faceAvg(p0)-f.gas_prop.stress_factor_ref_pressure))... + +(1-r.matrixflag).*exp(f.gas_prop.stress_factor_fracture*(os.faceAvg(p0)-f.gas_prop.stress_factor_ref_pressure)); + +% 閲囩敤绠鍗曠殑鍙犲姞澶勭悊 +bWvW = bWvW.*stress_factor.*Forchheimer_factor; +bGvG = bGvG.*stress_factor.*Forchheimer_factor; +% 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(r, f, p.val, sw.val, cs.val, cb.val, Wellc, Weladd, pwf, WelChg, well_schedules_k); +% Awell=dt*Awell; +% qwell=dt*qwell; + +% langmuir 绛夋俯鍚搁檮 +V_CH4=r.rpt.*r.V.*(1-r.por(p)).*r.rock_density.*f.gas_prop.VL.*p/f.gas_prop.PL./(1+p/f.gas_prop.PL); +V_CH4_0=r.rpt.*r.V.*(1-r.por(p)).*r.rock_density.*f.gas_prop.VL.*p0/f.gas_prop.PL./(1+p0/f.gas_prop.PL); + +% Accumulation term +PV = r.V .* r.por(p); +PV0 = r.V .* r.por(p0); +RV = r.V .* (1-r.por(p)); +RV0 = r.V .* (1-r.por(p0)); +Ar_w = 1/dt*(PV .* (sw ./ BW) - PV0 .* (sw0 ./ f.Bw(p0))); +Ar_g = 1/dt*(PV .* ((1 - sw) ./ BG) - PV0 .* ((1 - sw0) ./ f.Bg(p0)) + (V_CH4-V_CH4_0)); +Ar_w_s = 1/dt*(PV .* (sw.*cs./ BW) - PV0 .* (sw0.*cs./ f.Bw(p0))+... + r.rock_density*(RV.*f.cs_absorb(cs)-RV0.*f.cs_absorb(cs0))); +Ar_w_b = 1/dt*(PV .* (sw.*cb./ BW) - PV0 .* (sw0.*cb0./ f.Bw(p0))+... + r.rock_density*(RV.*f.cb_absorb(cb)-RV0.*f.cb_absorb(cb0))); +% 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(bGvG) - Ar_g); +% 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; +eqs{3} = (-os.div(bWvW_s+diff_s) - Ar_w_s); +eqs{4} = (-os.div(bWvW_b+diff_b) - Ar_w_b); +% +PVv = PV.val; +Bwa = BW.val; +Bga = BG.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)); + + + + + + + + + + diff --git a/core functions/preprocess/about_equation/eqsOW_MB_2014.m b/core functions/preprocess/about_equation/eqsOW_MB_2014.m new file mode 100644 index 0000000..0f16415 --- /dev/null +++ b/core functions/preprocess/about_equation/eqsOW_MB_2014.m @@ -0,0 +1,187 @@ +function [eqs, Awell, qwell,PVv, Bga, Bwa] = eqsOW_MB_2014(state, state0, dt, r, f, os, Wellc, Weladd, pwf, WelChg, well_schedules_k) + +p = state.p; +sw = state.sw; +cs = state.cs; +cb = state.cb; +p0 = state0.p; +sw0 = state0.sw; +cs0 = state0.cs; +cb0 = state0.cb; +[p, sw, cs, cb] = intADI(p, sw, cs, cb); + +% 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)); +Nc0 = f.Nc(cs0); +Nc = f.Nc(cs); +% Water Props +BW = f.Bw(p); +muW = f.muw(p); +krW = f.krw(sw, Nc); +pcOW = 0; +if f.ifpcgl + pcOW = f.pcgl(sw); +end +pw = p - pcOW +f.chemistry_cof*log(cb0); +dpW = os.grad(pw); +% dzw=1e-6*9.8*f.Dwsi*os.grad(z./BW); %水相位势梯度 +dzw=0; +dpW = dpW+dzw; +upc = (double(dpW)<=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+f.chemistry_cof*log(cb0); + 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; + +% 孔隙度 +pore = r.por(p); +% 表活剂 +mobW_s = os.faceUpstr(upc, krW.*cs) .* os.faceAvg(1./(BW.*muW)); +bWvW_s = -r.T .* mobW_s .* dpW; +dcs = os.grad(cs); +upc_s = (double(dcs)<=0); +mobW_s_diff = os.faceUpstr(upc_s, pore.*sw) .* os.faceAvg(1./(BW)); +diff_s = -r.T_diff .*mobW_s_diff .* dcs; + +% 盐 +mobW_b = os.faceUpstr(upc, krW.*cb) .* os.faceAvg(1./(BW.*muW)); +bWvW_b = -r.T .* mobW_b .* dpW; +dcb = os.grad(cb); +upc_b = (double(dcb)<=0); +mobW_b_diff = os.faceUpstr(upc_b, pore.*sw) .* os.faceAvg(1./(BW)); +diff_b = -r.T_diff.*mobW_b_diff.*dcb; + +% gas Props +BG = f.Bg(p); +muG = f.mug(p); +krG = f.krrg(sw, Nc); +dpG = os.grad(p); +% dzg=1e-6*9.8*f.Dgsi*os.grad(z./BG); %油相位势梯度 +dzg=0; +dpG = dpG+dzg; +upc = (double(dpG)<=0);%一定要是折算压力,否则出错! +mgbG = os.faceUpstr(upc, krG) .* os.faceAvg(1./(BG.*muG)); +% mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO)).* os.faceAvg(stress_factor); +% 针对启动压力梯度的平滑处理 +if f.p_grad_threshold ~= 0 + dpG0 = os.grad(p0); + dzg0=0; + dpG0 = dpG0+dzg0; + pG_grad0 = r.T_diff./r.flowArea.*dpG0; + ratioG = smooth_relu_stable(pG_grad0, f.p_grad_threshold); +else + ratioG = 1; +end +% Knudsen 扩散影响 +bGvG = -r.matrixflag.*f.gas_prop.Kn_modified_factor.*r.T .* mgbG .* dpG.*ratioG ... + -(1-r.matrixflag).*r.T .* mgbG .* dpG.*ratioG; +% 非达西流发生仅发生在裂缝网格内 +% Forchheimer_factor = 1/(1+kf/mug*beta*density_g*v_gf) +BG0 = f.Bg(p0);muG0 = f.mug(p0);krG0 = f.krrg(sw0,Nc0);dpG0 = os.grad(p0); +dzg0=0; +upc0 = (double(dpG0+dzg0)<=0);%一定要是折算压力,否则出错! +mgbG0 = os.faceUpstr(upc0, krG0) .* os.faceAvg(1./(BG0.*muG0)); +% mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO)).* os.faceAvg(stress_factor); +v_gf = -(1-r.matrixflag).*r.T .* mgbG0 .* dpG0./r.flowArea; +density_g = f.Dgsi./BG0; +Forchheimer_factor = 1./(1+(1-r.matrixflag).*r.perm./os.faceAvg(muG0).*f.gas_prop.beta_non_Darcy_flow.*os.faceAvg(density_g).*abs(v_gf)); + +% 分别有基质系统的应力敏感系数 和 裂缝系统的应力敏感系数 +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; +bGvG = bGvG.*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(r, f, p.val, sw.val, cs.val, cb.val, Wellc, Weladd, pwf, WelChg, well_schedules_k); +% Awell=dt*Awell; +% qwell=dt*qwell; + +% langmuir 等温吸附 +V_CH4=r.rpt.*r.V.*(1-r.por(p)).*r.rock_density.*f.gas_prop.VL.*p/f.gas_prop.PL./(1+p/f.gas_prop.PL); +V_CH4_0=r.rpt.*r.V.*(1-r.por(p)).*r.rock_density.*f.gas_prop.VL.*p0/f.gas_prop.PL./(1+p0/f.gas_prop.PL); + +% Accumulation term +PV = r.V .* r.por(p); +PV0 = r.V .* r.por(p0); +RV = r.V .* (1-r.por(p)); +RV0 = r.V .* (1-r.por(p0)); +Ar_w = 1/dt*(PV .* (sw ./ BW) - PV0 .* (sw0 ./ f.Bw(p0))); +Ar_g = 1/dt*(PV .* ((1 - sw) ./ BG) - PV0 .* ((1 - sw0) ./ f.Bg(p0)) + (V_CH4-V_CH4_0)); +Ar_w_s = 1/dt*(PV .* (sw.*cs./ BW) - PV0 .* (sw0.*cs./ f.Bw(p0))+... + r.rock_density*(RV.*f.cs_absorb(cs)-RV0.*f.cs_absorb(cs0))); +Ar_w_b = 1/dt*(PV .* (sw.*cb./ BW) - PV0 .* (sw0.*cb0./ f.Bw(p0))+... + r.rock_density*(RV.*f.cb_absorb(cb)-RV0.*f.cb_absorb(cb0))); +% 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(bGvG) - Ar_g); +% 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; +eqs{3} = (-os.div(bWvW_s+diff_s) - Ar_w_s); +eqs{4} = (-os.div(bWvW_b+diff_b) - Ar_w_b); +% +PVv = PV.val; +Bwa = BW.val; +Bga = BG.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)); + + + + + + + + + + diff --git a/core functions/preprocess/about_equation/equa_process.m b/core functions/preprocess/about_equation/equa_process.m new file mode 100644 index 0000000..68306d3 --- /dev/null +++ b/core functions/preprocess/about_equation/equa_process.m @@ -0,0 +1,56 @@ +function [eqs, qomf, qofm, qwmf, qwfm, Awell, qwell] = equa_process(state, state0, dt, r, f, os, Wellc, Weladd, pwf, WelChg) +p = state.p; +sw = state.sw; +p0 = state0.p; +sw0 = state0.sw; +[p, sw] = intADI(p, sw); + +% Water Props +BW = f.Bw(p);%地层水体积系数 +muW = f.muw(p);%地层水粘度 +krW = f.krw(sw);%地层水相对渗透率 +pcOW = 0;%默认ifpcow=0,即默认忽略毛管力 +if f.ifpcow + pcOW = f.pcow(sw); +end +pw = p - pcOW;%水相压力 +dpW = os.grad(pw);%水相压力梯度 +upc = (double(dpW)<=0);%作为迎风格式函数的flag +mobW = os.faceUpstr(upc, krW) .* os.faceAvg(1./(BW.*muW));%按照迎风格式计算流度 +bWvW = -r.T .* mobW .* dpW;%传导系数*流度*压差 + +% Oil Props +BO = f.Bo(p);%油组分体积系数 +muO = f.muo(p);%油相粘度 +krO = f.kro(sw);%油相相对渗透率 +dpO = os.grad(p);%油相压力梯度 +upc = (double(dpO)<=0);%迎风格式函数flag +mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO));%计算流度 +bOvO = -r.T .* mobO .* dpO; + +% z方向上的位势 +% 由于当深度发生变化时,流体的密度也会发生变化,因此不能简单得处理成折算压力的情况计算 +%对位势z进行处理 +z=r.z; +z = intADIz(z); +% Dosi是地面标况下测得的油相密度,Dwsi是地面标况下测得的水相密度 +dzo=f.Dosi*os.grad(z./BO); %油相位势梯度 +dzw=f.Dwsi*os.grad(z./BW); %水相位势梯度 + + +% transfer function (OW) +[qomf, qofm, qwmf, qwfm] = transFunc(r, krO, krW, BO, muO, BW, muW, p, pw); + +% well equation +[Awell, qwell] = WellEquation(r, f, p.val, sw.val, Wellc, Weladd, pwf, WelChg); + +% 因为z的取法,故方程中是压力梯度加上位势梯度 +% Water Equation +eqs{1} = -os.div(bWvW+dzo) - r.V/dt .* (r.por(p) .* (sw ./ BW) - r.por(p0) .* (sw0 ./ f.Bw(p0))); + +% Oil Equation +eqs{2} = -os.div(bOvO+dzw) - r.V/dt .* (r.por(p) .* ((1 - sw) ./ BO) - r.por(p0) .* ((1 - sw0) ./ f.Bo(p0))); + + +end + diff --git a/core functions/preprocess/about_grid/GenerateNode_final.m b/core functions/preprocess/about_grid/GenerateNode_final.m new file mode 100644 index 0000000..6f5a818 --- /dev/null +++ b/core functions/preprocess/about_grid/GenerateNode_final.m @@ -0,0 +1,96 @@ +function [coordinates, nodes, nP, nE, dxv, dyv,dzv,zm,vm,xrao,yrao,zrao,cell_mid_coordinates] = GenerateNode_final(dx, dy,dz ,nx,ny,nz,NTG) +% coordinates xy cordinate,即每个节点的x,y坐标 +% nodes connection,即每个子区域对应的八个节点数 +% nP numbers of point,即节点数量 +% nE numbers of element,即子区域数量 +nP = (nx + 1) * (ny + 1)*(nz+1);%计算节点数量 +nE = nx * ny*nz;%子区域数量计算 +% dx=dx*ones(nx,1);%此处是为了暂时妥协 +% dy=dy*ones(nx,1); +% dz=dz*ones(nx,1); +dxv = zeros(nE, 1);%每个子区域x方向上尺寸矩阵 +dyv = zeros(nE, 1);%每个子区域y方向上尺寸矩阵 +dzv = zeros(nE, 1); +zm=zeros(nE, 1);%基质网格计算深度(以下平面为基准计算得到的高度,值为正数) +xm=zeros(nE, 1); +ym=zeros(nE, 1); +%给每个子区域的x方向和y方向赋尺寸 +vm=zeros(nE, 1);%基质网格体积 +for k=1:nz + for i = 1 : nx + for j = 1 : ny + dxv(i+(j-1)*nx+nx*ny*(k-1)) = dx(i); + dyv(i+(j-1)*nx+nx*ny*(k-1)) = dy(j); + dzv(i+(j-1)*nx+nx*ny*(k-1))= dz(k); + vm(i+(j-1)*nx+nx*ny*(k-1))=dx(i)*dy(j)*dz(k)*NTG(i+(j-1)*nx+nx*ny*(k-1)); + + end + end +end +coordinates = zeros(nP, 3);%初始化每个节点的x,y坐标矩阵 +nodes = zeros(nE, 8);%初始化每个子区域对应的八个节点数的矩阵 +%计算每个节点的坐标 +x0 = zeros(nx+1,1); +y0 = zeros(ny+1,1); +z0=zeros(nz+1,1); +sumx = 0; +sumy = 0; +sumz=0; +for i = 1 : nx + sumx = sumx+dx(i); + x0(i+1) = sumx; +end +for i = 1 : ny + sumy = sumy+dy(i); + y0(i+1) = sumy; +end +for i = 1 : nz + sumz = sumz+dz(i); + z0(i+1) = sumz; +end +for k=1:nz+1 +for j = 1 : ny + 1 + for i = 1 : nx + 1 + coordinates(i + (j - 1) * (nx + 1)+(nx+1)*(ny+1)*(k-1), 1) = x0(i);%(i,j)节点的x坐标赋值 + coordinates(i + (j - 1) * (nx + 1)+(nx+1)*(ny+1)*(k-1), 2) = y0(j);%(i,j)节点的y坐标赋值 + coordinates(i + (j - 1) * (nx + 1)+(nx+1)*(ny+1)*(k-1), 3) = z0(k); + end +end +end +%计算每个子区域的八个顶点(节点)对应的节点编号 +for k=1:nz +for j = 1 : ny + for i = 1 : nx + nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) = i + (j - 1) * (nx + 1)+(k-1)*(nx+1)*(ny+1); + nodes(i + (j - 1) * nx+nx*ny*(k-1), 2) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 3) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) + nx + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 4) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) + nx + 2; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1)+(nx+1)*(ny+1); + nodes(i + (j - 1) * nx+nx*ny*(k-1), 6) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 7) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) + nx + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 8) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) + nx + 2; + zm(i+(j-1)*nx+nx*ny*(k-1))=sum(coordinates(nodes(i + (j - 1) * nx+nx*ny*(k-1), :),3))/8; + xm(i+(j-1)*nx+nx*ny*(k-1))=sum(coordinates(nodes(i + (j - 1) * nx+nx*ny*(k-1), :),1))/8; + ym(i+(j-1)*nx+nx*ny*(k-1))=sum(coordinates(nodes(i + (j - 1) * nx+nx*ny*(k-1), :),2))/8; + end +end +end + +cell_mid_coordinates = [xm,ym,zm]; + +xrao=[0]; +for i=1:nx + xxiang=sum(dx(1,1:i)); + xrao=[xrao xxiang]; +end +yrao=[0]; +for i=1:ny + yxiang=sum(dy(1,1:i)); + yrao=[yrao yxiang]; +end +zrao=[0]; +for i=1:nz + zxiang=sum(dz(1,1:i)); + zrao=[zrao zxiang]; +end +end \ No newline at end of file diff --git a/core functions/preprocess/about_grid/GridProplpr.m b/core functions/preprocess/about_grid/GridProplpr.m new file mode 100644 index 0000000..09cdaa0 --- /dev/null +++ b/core functions/preprocess/about_grid/GridProplpr.m @@ -0,0 +1,175 @@ +function r = GridProplpr(nx, ny, nz, dx, dy, dz , kx, ky, kz, nf,f, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca) +%% 基质网格参数及网格参数计算、存储 +r.nx = nx; +r.ny = ny; +r.nz = nz; +r.dx = dx; +r.dy = dy; +r.dz = dz; +r.kx = kx; +r.ky = ky; +r.kz = kz; +r.Kf = Kf;%裂缝面对应的渗透率,非裂缝单元 +r.Wf = Wf;%裂缝面对应的缝宽,非裂缝单元 +r.cf = cf; +r.ca = ca; +% r.h = h; +% [coordinates, nodes, ~, nmc, Dxv, Dyv] = GenerateNode_final(Dx, Dy, nx, ny); +[coordinates, nodes, nP, nE, dxv, dyv,dzv,zm,vm] = GenerateNode_final(dx, dy,dz ,nx,ny,nz); +r.coordinates = coordinates; +r.nodes = nodes; +nmc=nE; +r.nmc =nmc; +r.dxv = dxv; +r.dyv = dyv; +r.dzv = dyv; +r.vm=vm; + +%% 求解裂缝与基质网格连接情况 +%% 关键参数矩阵初始化 +m=size(f,1);nf=m/5;%裂缝条数 +r.nf=nf; +%d3intersection=-1000*ones(1000,3);%用-1000做标识 +raopoint=cell(m,2);%利用元胞数组存储每条裂缝与基质网格线的交点, +%第一列是三维坐标形式,即d3intersection +%第二列是裂缝面参数形式,即anothersection +pointvsregion=cell(m,3);%利用元胞数组存储interarea函数的结果numofmesh, numvspoint,numofregion +fracrossfra=cell(m,m-1);%判断裂缝之间两交点坐标 +fratmaxfra=zeros(m,m-1);%判断裂缝之间交线参数的最大值 +fratminfra=zeros(m,m-1);%判断裂缝之间交线参数的最小值 +fracturemesh=cell(nf,1);%每一行是一条裂缝面上的网格剖分情况 +% [Linep, ConnecS, Fracp, ~, FracConf2] = Edfm_preprocess_final(coordinates, nodes, Lines, NF); +% r.Linep = Linep; +% r.ConnecS = ConnecS; +% r.Fracp = Fracp; +% r.FracConf2 = FracConf2; +%% 计算裂缝与基质网格相交情况 +for i=1:nf + raopoint{i,1}= intersectionsolve(f((5*i-4):(5*i),:),dx,dy,dz,nx,ny,nz ); + raopoint{i,2}= anosection( f((5*i-4):(5*i),:),raopoint{i,1} ); + [ pointvsregion{i,1},pointvsregion{i,2} ,pointvsregion{i,3}] = interarea( raopoint{i,1},dx,dy,dz,nx,ny,nz ); +end +%% 计算裂缝之间相交线情况 +for i=1:nf + for j=1:nf + [ cross,tmax,tmin ]=frac_cross_frac( f((5*i-4):(5*i),:),f((5*j-4):(5*j),:) ); + fracrossfra{i,j}=cross;fratmaxfra(i,j)=tmax;fratminfra(i,j)=tmin; + end +end +%% 计算裂缝被基质网格、其它裂缝与之相交后的网格分布情况,绘制二维裂缝平面参数坐标系上的网格分布情况 +figure(1); +for i=1:nf + d3intersection=raopoint{i,1};anothersection=raopoint{i,2}; + [ mesh ] = frac_mat_mesh( d3intersection,anothersection,pointvsregion{i,2},pointvsregion{i,1} ); + for j=1:nf +[ mesh,d3intersection,anothersection ]= frac_frac_mesh(mesh,f(5*i-4,:),f(5*i-3,:),f(5*i-2,:),fracrossfra{i,j},fratmaxfra(i,j),fratminfra(i,j),d3intersection,anothersection,pointvsregion{i,2},pointvsregion{i,1} ); + end + raopoint{i,1}=d3intersection;raopoint{i,2}=anothersection;%由原来裂缝与网格的交点不断更新加入其它裂缝与该裂缝的交点 + fracturemesh{i,1}=mesh;subplot(nf,1,i);plotmesh2D(mesh,raopoint{i,2}); +end + +%% 绘制三维背景网格(基质网格)及裂缝网格分布 +%figure(2) +%network3D(dx,dy,dz,nx,ny,nz ); +%hold on; + figure(2); +for i=1:nf +plotmesh3D( fracturemesh{i,1},raopoint{i,1} );hold on; +end +hold off; +%% 确定裂缝编号及连接情况,计算传导系数 +[ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv ); +nfc=size(fracnumber,1); +nex=size(T,1); +r.nfc=nfc; +nc=nfc+nmc; +r.nc=nc;%基质网格和裂缝单元总数 +r.nex=nex;%具有流体交换的总数 +kf=Kf(fcinff); +wf=Wf(fcinff); +r.kf=kf;%裂缝单元对应的渗透率 +r.wf=wf;%裂缝单元对应的缝宽 +r.N=N; +r.T=T; +r.vf=vf; +r.V=[vm;vf]; +r.porf=porf; +r.fcff=fcff; +%% 计算传导系数 +% dxvector=ones(1,nx);dyvector=ones(1,ny);dzvector=ones(1,nz); +% [ transmatrix,transfracture ] = trans(dxvector,dyvector,dzvector ,nx,ny,nz,nf,fracnumber,lengthvsfra,disvsfra,fracstart,connect_infrac,corevsfra,matrixvsfra,raopoint,f ); +%% 计算基质与裂缝之间窜流的相关系数 +% [ channelfrac ] = cuanliu( matrixvsfra,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf );%Gf矩阵 +% [ G ] = cuanliumatrix(dx,dy,dz );%G矩阵 +[ G,Gfm,Gff,Gf,Ap,Apf ]=lpr(dx,dy,dz,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); +%% +[Ka, M, F2M , MF_coef] = transFunc_aniso(nc,coordinates, nodes, connectmf,Ap,Apf, matrixvsfra,N,T,kx, ky,kz); +r.Ka = Ka; +r.M = M; +r.F2M = F2M; +r.MF_coef = MF_coef; +%% 计算深度(以下平面为基准计算得到的高度,值为正数) +z=[zm;zf]; +r.z=z; + +% nfc = length(Fracp); +% r.nfc = nfc; +% [kf, wf, porf] = FracProp(Kf, Wf, Porf, ConnecS); +% r.kf = kf; +% r.wf = wf; +% [Nff, Vf, lf] = FracConnec(Linep, Fracp, FracConf2, kf, wf, h); +% r.lf = lf; +% [nff, ~] = size(Nff); +% nc = nmc + nfc; +% r.nc = nc; + rpt = [ones(nmc, 1); zeros(nfc, 1)]; + r.rpt = rpt; + r.Porf = Porf; + pori = [pori; porf]; +r.pori = pori; +r.por = @(p)por(p, prpor, pori, cpor, prporf, cporf, r.rpt); +% nmf = 2 * nx * ny - nx - ny; +% r.nf = nmf + nff; +% N = zeros(nmf, 2); +% T = zeros(nmf, 1); +% c = 0; +% for j = 1 : ny +% for i = 1 : nx - 1 +% c = c + 1; +% index = i + (j - 1) * nx; +% indexn = index + 1; +% N(c, :) = [index, index + 1;]; +% T(c) = 2 * Dyv(index)*h*Kx(index)*Kx(indexn)/(Kx(index)*Dxv(indexn) + Kx(indexn)*Dxv(index)); +% end +% end +% for i = 1 : nx +% for j = 1 : ny - 1 +% c = c + 1; +% index = i + (j - 1) * nx; +% indexn = index + nx; +% N(c, :) = [index, index + nx]; +% T(c) = 2 * Dxv(index)*h*Ky(index)*Ky(indexn)/(Ky(index)*Dyv(indexn) + Ky(indexn)*Dyv(index)); +% end +% end +% r.N = [N; Nff(:, 1:2)+nmc]; +% r.T = [T; Nff(:, 3)]; +% r.cf = cf; +% r.ca = ca; +% r.Kx = Kx; +% r.Ky = Ky; +% r.Kf = Kf; +% r.Wf = Wf; +% r.Porf = Porf; +% r.lf = lf; +% Vm = Dxv .* Dyv .* h; +% r.V = [Vm; Vf]; +% pori = [pori; porf]; +% r.pori = pori; +% rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +% r.por = @(p)por(p, prpor, pori, cpor, prporf, cporf, r.rpt); +% [Ka, M, F2M , MF_coef] = transFunc_aniso(coordinates, nodes, Linep, ConnecS, nmc, nfc, nc, Kx, Ky); +% r.Ka = Ka; +% r.M = M; +% r.F2M = F2M; +% r.MF_coef = MF_coef; diff --git a/core functions/preprocess/about_grid/LGR3D.m b/core functions/preprocess/about_grid/LGR3D.m new file mode 100644 index 0000000..05927ea --- /dev/null +++ b/core functions/preprocess/about_grid/LGR3D.m @@ -0,0 +1,7 @@ +function [ output_args ] = LGR3D( input_args ) +%LGR3D 此处显示有关此函数的摘要 +% 此处显示详细说明 + + +end + diff --git a/core functions/preprocess/about_grid/anosection.m b/core functions/preprocess/about_grid/anosection.m new file mode 100644 index 0000000..1b25df0 --- /dev/null +++ b/core functions/preprocess/about_grid/anosection.m @@ -0,0 +1,28 @@ +function [ anothersection ] = anosection( fracture,d3intersection ) +%为了适用于delaunay函数,求得裂缝平面网格的面积,并有效得给裂缝平面网格编号 +%将裂缝平面上点的三维欧氏空间左边转换为裂缝面上的参数坐标,可见在确定裂缝形状给出 +%的正交向量必须取幺正标架 +%示例:[ anothersection ] = anothersection([0.5,0,0],[1,1,0],[0,0,1],d3intersection ) +t0=fracture(1,:);t1=fracture(2,:);t2=fracture(3,:); +A=[t1(1),t2(1); + t1(2),t2(2); + t1(3),t2(3)]; +n=size(d3intersection,1); +b=[t0(1);t0(2);t0(3)]; +B=d3intersection'-repmat(b,1,n); +C=A\B; +m=size(C,2); +% for i=1:1:m +% if((C(1,i)>umax)||(C(1,i)vmax)||(C(2,i)2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + length=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + tran1=kf(i)*wf(i)*length/disk; + tran2=kf(i)*wf(i)*length/disj; +% hartran=length/(disk+disj);%取调和平均 + hartran=tran1*tran2/(tran1+tran2); + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 +% lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=j:n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +c = 0; +for k= 1 : nz +for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)/(Kx(index)*dxv(indexn) + Kx(indexn)*dxv(index)); + end +end +end + +for k= 1 : nz +for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + end +end +end + +for i = 1 : nx +for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + end +end +end +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Knnc=2*kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=areavsfra(matrixvsfra(i,j)); + fracore=corevsfra(matrixvsfra(i,j)); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)/2,dzv(i)/2)/(dxv(i)*dyv(i)*dzv(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)/2,dzv(i)/2)/(dxv(i)*dyv(i)*dzv(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)/2,dzv(i)/2)/(dxv(i)*dyv(i)*dzv(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*integral(dn,-dxv(i)/2,dxv(i)/2); + else if norvec(2)~=0 + + raoT=Knnc*Annc/Dn; + Tinterflow=[Tinterflow;raoT]; + end + end +end + +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc;Ninterflow]; +T = [T; Tmff; Tff;Tinterflow]; +nex=size(N,1); +end diff --git a/core functions/preprocess/about_grid/connections.m b/core functions/preprocess/about_grid/connections.m new file mode 100644 index 0000000..bdc3bb4 --- /dev/null +++ b/core functions/preprocess/about_grid/connections.m @@ -0,0 +1,247 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff] = connections( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,kf,wf,Porf,dxv,dyv,dzv ) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf +rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; +for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 +% m=floor((i+(2^nf)-1)/(2^nf)); +% indice=find(matrixvsfra(numofmesh(m),:)~=0); + indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(i),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end +end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 +% if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; +end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + length=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + tran1=kf(i)*wf(i)*length/disk; + tran2=kf(i)*wf(i)*length/disj; +% hartran=length/(disk+disj);%取调和平均 + hartran=tran1*tran2/(tran1+tran2); + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 +% lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=j:n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +c = 0; +for k= 1 : nz +for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)/(Kx(index)*dxv(indexn) + Kx(indexn)*dxv(index)); + end +end +end + +for k= 1 : nz +for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + end +end +end + +for i = 1 : nx +for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + end +end +end + +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc]; +T = [T; Tmff; Tff]; +nex=size(N,1); +end diff --git a/core functions/preprocess/about_grid/connections_2014.m b/core functions/preprocess/about_grid/connections_2014.m new file mode 100644 index 0000000..757da1e --- /dev/null +++ b/core functions/preprocess/about_grid/connections_2014.m @@ -0,0 +1,529 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,cell_divided_by_fracture_flag, flowArea, perm, matrixflag,T_diff] = connections_2014( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,pori,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag,invalid_grids ) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf + rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; + for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 + % m=floor((i+(2^nf)-1)/(2^nf)); + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); + % indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end + end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +mat_frac=[]; +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 + % if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + mat_frac=[mat_frac;i]; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; + end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +% Kffl=funtion_data.Kffl; +% Dffl=funtion_data.Dffl; +% kffl=zeros(q-1,1); +% dffl=zeros(q-1,1); +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,1);%裂缝网格渗透率 +Wf=zeros(q-1,1);%裂缝单元缝宽 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +tran_no_perm=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +ave_disvsfra=zeros(q-1,1); +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +avfracFaceArea = zeros(q-1,1); +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 + for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if kf(i)==0 + hartran=0;hartran_convection=0; + kij = 0; + else + tran1=kf(i)*wf(i)*lengthcat/disk; + tran2=kf(i)*wf(i)*lengthcat/disj; + % hartran=length/(disk+disj);%取调和平均 + hartran=tran1*tran2/(tran1+tran2); + tran1_diff=wf(i)*lengthcat/disk; + tran2_diff=wf(i)*lengthcat/disj; + % hartran=length/(disk+disj);%取调和平均 + hartran_diff=tran1_diff*tran2_diff/(tran1_diff+tran2_diff); + % k_harmony= kf(i); + hartran_convection=kf(i)/(disk+disj)^2; + kij = 2*(Kf(j)^(-1)+Kf(k)^(-1))^(-1); + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + Tff_diff=[Tff_diff;hartran_diff]; + Tff_convection=[Tff_convection;hartran_convection]; + perm_ff = [perm_ff; kij]; + flowArea_ff = [flowArea_ff; wf(i)*lengthcat]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +Tff_convection(1,:)=[]; +Tff_diff(1,:)=[]; +perm_ff(1,:)=[]; +flowArea_ff(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +Tmff_diff=zeros(1,1); +Tmff_convection=zeros(1,1); +perm_mff=zeros(1,1); +flowArea_mff=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 + % lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc));sumtran_no_perm=sum(fcff{1,9}(allfc)); + if sumtran==0 + Tmff=[Tmff; 0];Tmff_convection=[Tmff_convection;0]; + Tmff_diff=[Tmff_diff;0]; + perm_mff=[perm_mff;0];flowArea_mff=[flowArea_mff;(avfracFaceArea(fc1)+avfracFaceArea(fc2))/2]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + Tmff_diff=[Tmff_diff;fcff{1,9}(fc1)*fcff{1,9}(fc2)/sumtran_no_perm]; + perm_mff=[perm_mff;(Kf(fc1)^(-1)+Kf(fc2)^(-1))^(-1)]; + flowArea_mff=[flowArea_mff;(avfracFaceArea(fc1)+avfracFaceArea(fc2))/2]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +% Tmff =Tmff*0; +Tmff_convection(1,:)=[]; +Tmff_diff(1,:)=[]; +perm_mff(1,:)=[]; +flowArea_mff(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc= nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +T_convection = zeros(nmm, 1); +T_diff = zeros(nmm, 1); +perm = zeros(nmm, 1); +flowArea = zeros(nmm, 1); +c = 0; +for k= 1 : nz + for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + T_convection(c) = 2/(1/Kx(index)+1/Kx(indexn))/(dxv(indexn)+dxv(index)); + perm(c)=2*Kx(index)*Kx(indexn)/(Kx(index) + Kx(indexn)); + T_diff(c)=dzv(index)*dyv(index)/(2/(1/dxv(indexn)+1/dxv(index))); + flowArea(c)=dzv(index)*dyv(index); + end + end +end + +for k= 1 : nz + for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + T_convection(c) = 2/(1/Ky(index)+1/Ky(indexn))/(dyv(indexn)+dyv(index)); + perm(c)=2*Ky(index)*Ky(indexn)/(Ky(index) + Ky(indexn)); + T_diff(c)=dzv(index)*dxv(index)/(2/(1/dyv(indexn)+1/dyv(index))); + flowArea(c)=dzv(index)*dxv(index); + end + end +end + +for i = 1 : nx + for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + T_convection(c) = 2/(1/Kz(index)+1/Kz(indexn))/(dzv(indexn)+dzv(index)); + perm(c)=2*Kz(index)*Kz(indexn)/(Kz(index) + Kz(indexn)); + T_diff(c)=dxv(index)*dyv(index)/(2/(1/dzv(indexn)+1/dzv(index))); + flowArea(c)=dxv(index)*dyv(index); + end + end +end +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +Tinterflow_convection=[]; +Tinterflow_diff=[]; +cell_divided_by_fracture_flag = []; +perm_interflow=[]; +flowArea_interflow=[]; +for i=1:nx*ny*nz %基质网格编号 + flag = 0; + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + flag = flag + 1; + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + % kcell = sqrt(10*100)*1e-3; + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=areavsfra(matrixvsfra(i,j)); + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); + % dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + % raoT=Knnc*Annc/Dn; + % raoT_convection=2*Knnc/Dn^2; + % Tinterflow=[Tinterflow;raoT]; + % Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + raoT1 = 2*kcell*Annc/Dn; + raoT2 = Kf(matrixvsfra(i,j))*Annc/(Wf(matrixvsfra(i,j))/2); + raoT = (raoT1^-1+raoT2^-1)^-1; + Tinterflow=[Tinterflow;raoT]; + raoT1_conv = kcell/Dn^2; + raoT2_conv = Kf(matrixvsfra(i,j))/(Wf(matrixvsfra(i,j))/2)^2; + raoT_convection = (raoT1_conv^-1+raoT2_conv^-1)^-1; + Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + Tinterflow_diff=[Tinterflow_diff;((2*Annc/Dn)^-1+(Annc/(Wf(matrixvsfra(i,j))/2))^-1)^-1;]; + perm_mf_this = kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + perm_interflow = [perm_interflow; perm_mf_this]; + flowArea_interflow = [flowArea_interflow; Annc]; + end + end + if flag >0 + cell_divided_by_fracture_flag = [cell_divided_by_fracture_flag; i]; + end +end +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +% syms x y z; +% Ninterflow=[]; +% Tinterflow=[]; +% for i=1:nx*ny*nz %基质网格编号 +% for j=1:10 +% if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell +% Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3); +% K1=Kf(matrixvsfra(i,j));d1=Wf(matrixvsfra(i,j)); +% K2=kffl(matrixvsfra(i,j));d2=dffl(matrixvsfra(i,j)); +% Annc=2*areavsfra(matrixvsfra(i,j)); +% fracore=corevsfra(matrixvsfra(i,j),:); +% matnodes=nodes(i,:); +% verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); +% matcore=mean(verco);d0=matcore-fracore; +% dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% % dn=abs(dn);%影响数值积分效率 +% dn=sqrt(dn^2); +% dn=matlabFunction(dn); +% if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 +% Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(2)~=0 +% Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(3)~=0 +% Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 && norvec(3)~=0 +% Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 +% Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 +% Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(3)~=0 +% Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% end +% end +% end +% end +% end +% end +% end +% raoT=((Kcell*Annc/(Dn-d2))^(-1)+(K2*Annc/d2)^(-1)+(K1*Annc/d1)^(-1))^(-1); +% Tinterflow=[Tinterflow;raoT]; +% end +% end +% end + +%% 把上述三种情况的矩阵分别叠加起来 +matrixflag = [ones(size(T,1),1); zeros(size(Tmff,1),1); zeros(size(Tff,1),1); ones(size(Tinterflow,1),1);]; +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;]; +T = [T; Tmff; Tff;Tinterflow;]; +T_convection = [T_convection;Tmff_convection; Tff_convection;Tinterflow_convection;]; +T_diff = [T_diff;Tmff_diff; Tff_diff;Tinterflow_diff;]; +perm = [perm; perm_mff; perm_ff;perm_interflow; ]; +flowArea = [flowArea; flowArea_mff; flowArea_ff;flowArea_interflow;]; +% +% deleted_rows = []; +% for i = 1:size(N,1) +% if ismember(N(i,1),invalid_grids) || ismember(N(i,2),invalid_grids) +% deleted_rows = [deleted_rows; i]; +% end +% end +% N(deleted_rows,:) = []; +% T(deleted_rows,:) = 0; +% T_convection(deleted_rows,:) = 0; +% T_diff(deleted_rows,:) = 0; +% perm(deleted_rows,:) = 0; +% flowArea(deleted_rows,:) = 0; +% nex=size(N,1); +%% 转到CMG或者ECLIPSE进行计算 +% [ Data_for_ECLIPSE ] = pEDFM_to_CMG_horizontalFractureWell(dxv,dyv,dzv,kx,ky,kz,pori,Kf,Wf,vf,porf,N,T); +% [ Data_for_ECLIPSE ] = pEDFM_to_CMG_horizontalFractureWell_net_pay(dxv,dyv,dzv,kx,ky,kz,pori,Kf,Wf,vf,porf,N,T); +end diff --git a/core functions/preprocess/about_grid/connections_PEDFM.m b/core functions/preprocess/about_grid/connections_PEDFM.m new file mode 100644 index 0000000..dd6d2ad --- /dev/null +++ b/core functions/preprocess/about_grid/connections_PEDFM.m @@ -0,0 +1,701 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff] = connections_PEDFM( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag ) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf +rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; +for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); +% indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end +end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 +% if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; +end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,10);%裂缝网格渗透率 +Wf=zeros(q-1,10);%裂缝单元缝宽 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 +for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if Kf(j)==0 || Kf(k)==0 + hartran=0; + else + tran1=Kf(j)*wf(i)*lengthcat/disk; + tran2=Kf(k)*wf(i)*lengthcat/disj; +% hartran=length/(disk+disj);%取调和平均的一半 + hartran=tran1*tran2/(tran1+tran2); + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 +% lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 Tmff=[Tmff; 0]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +S_ex=zeros(nmm,1);% 流体交换面面积 + +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +c = 0; +for k= 1 : nz +for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); +% 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)/(Kx(index)*dxv(indexn) + Kx(indexn)*dxv(index)); + S_ex(c)=dzv(index)*dyv(index); + end +end +end + +for k= 1 : nz +for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + S_ex(c)=dzv(index)*dxv(index); + end +end +end + +for i = 1 : nx +for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + S_ex(c)=dxv(index)*dyv(index); + end +end +end + + + + +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=areavsfra(matrixvsfra(i,j));% 此处与原始嵌入式不一样,原始是两倍 + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + % 为论文做修改 +% Dn=0.9; +% Dn=2.5; + Dn=dxv(i)/2; + raoT=Knnc*Annc/Dn; + Tinterflow=[Tinterflow;raoT]; + end + end +end + +%% 投影嵌入式处理 +nmc = size(matrixvsfra,1); +%基质网格流体交换面上的裂缝单元投影面之和 +S_p=zeros(nmm,1); +% 因为投影处理新加的F-M connections +Nmf_projection=[]; +Tmf_projection=[]; +for i=1:nmc + matnodes=nodes(i,:); + dx_grid=dxv(i); + dy_grid=dyv(i); + dz_grid=dzv(i); + grid_core=mean(coord(matnodes,:));%该基质网格中心 + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>=1) %先仅考虑n=1时的情况 + selected_face=zeros(1,3); + the_frac_cells=matrixvsfra(i,indice);%该裂缝单元编号 + for haihaihai = 1:length(the_frac_cells) + the_frac_cell = the_frac_cells(haihaihai); + which_frac=fcff{1,2}(the_frac_cell,1);%该裂缝单元所在的裂缝面 + core_frac_cell=fcff{1,4}(the_frac_cell,1:3);%该裂缝单元的中心坐标 + area_frac_cell=fcff{1,8}(the_frac_cell,1);%该裂缝单元面积 + rao_struct=[i,the_frac_cell+nmc]; + pos_rao=find_row(rao_struct,Ninterflow); + D_value=core_frac_cell-grid_core;% 向量OF + vector_1=f(5*which_frac-3,:); + vector_2=f(5*which_frac-2,:); + n_vector_1=cross(vector_1,vector_2); + n_vector_2=-cross(vector_1,vector_2); + if (dot(n_vector_1,D_value))>=0 + n_vector=n_vector_1; + else + n_vector=n_vector_2; + end + %该裂缝面法向量 + % x方向投影面积 + area_frac_cell_x=abs(area_frac_cell*dot([1,0,0],n_vector)/norm(n_vector)); + area_frac_cell_y=abs(area_frac_cell*dot([0,1,0],n_vector)/norm(n_vector)); + area_frac_cell_z=abs(area_frac_cell*dot([0,0,1],n_vector)/norm(n_vector)); +% %% 为valid case修改 +% area_frac_cell_x=10*10; +% area_frac_cell_y=10*10; +% area_frac_cell_z=10*10; + %将裂缝中心沿法向量做微小平移,此时再按照距离最近原则判断,可以保证得到符合物理意义的情况 + new_core=core_frac_cell+1e-4*n_vector; + % 裂缝单元中心相对于基质网格中心的向矢 + %x direction + D_value_new=new_core-grid_core; + if D_value_new(1)<=0 + selected_face(1)=3;nei_grid_x=i-1; + else selected_face(1)=4; nei_grid_x=i+1; + end +%% ----------------------% 为了做测试实用型pEDFM,人为加处理-------------------------------------- + % 为了做测试实用型pEDFM,人为加处理 +% selected_face(1)=4; nei_grid_x=i+1; +%% ----------------------% 人为处理结束--------------------------------------------------------------- + struc_x=[i,nei_grid_x]; + pos=find_row(struc_x,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_x; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_x)*ky(nei_grid_x)*kz(nei_grid_x))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_x,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% dis_added=norm(nei_grid_core-core_frac_cell); +% T_added=Knnc*area_frac_cell_x/dis_added; + % 采用另一种方式计算几何因子 +% dis_added=norm(nei_grid_core-core_frac_cell); + dis_added=abs(sum((nei_grid_core-core_frac_cell).*[1,0,0],2)); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_x/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + T_added=1/(1/Geofnei+1/Geof); +% T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% T_added=1/(1/Geofcell+1/Geof); +% T_added=0;%特殊情况 +% T_added=0;%特殊情况 +% T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_x,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end + + %y direction + if D_value_new(2)<=0 + selected_face(2)=2;nei_grid_y=i-nx; + else selected_face(2)=5;nei_grid_y=i+nx; + end +%% ----------------------% 为了做测试实用型pEDFM,人为加处理-------------------------------------- + % 为了做测试实用型pEDFM,人为加处理 +% selected_face(2)=5; nei_grid_y=i+nx; +%% ----------------------% 人为处理结束--------------------------------------------------------------- + struc_y=[i,nei_grid_y]; + pos=find_row(struc_y,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_y; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_y)*ky(nei_grid_y)*kz(nei_grid_y))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_y,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% dis_added=norm(nei_grid_core-core_frac_cell); +% T_added=Knnc*area_frac_cell_y/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_y/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% T_added=0;%特殊情况 +% T_added=0.002;%特殊情况 +% T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_y,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end + + + % z direction + if D_value_new(3)<=0 + selected_face(3)=1;nei_grid_z=i-nx*ny; + else selected_face(3)=6;nei_grid_z=i+nx*ny; + end +%% ----------------------% 为了做测试实用型pEDFM,人为加处理-------------------------------------- + % 为了做测试实用型pEDFM,人为加处理 + selected_face(3)=6;nei_grid_z=i+nx*ny; +%% ----------------------% 人为处理结束--------------------------------------------------------------- +% nei_grid_z=i-nx*ny; + struc_z=[i,nei_grid_z]; + pos=find_row(struc_z,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_z; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_z)*ky(nei_grid_z)*kz(nei_grid_z))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_z,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% dis_added=norm(nei_grid_core-core_frac_cell); +% T_added=Knnc*area_frac_cell_z/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_z/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% T_added=0;%特殊情况 +% T_added=0.0;%特殊情况 +% T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_z,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end +% %% 例二添加的 +% if D_value_new(1)>0 +% selected_face(1)=3;nei_grid_x=i-1; +% else selected_face(1)=4; nei_grid_x=i+1; +% end +% struc_x=[i,nei_grid_x]; +% pos=find_row(struc_x,N); +% if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 +% S_p(pos)=S_p(pos)+area_frac_cell_x; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 +% knei=(kx(nei_grid_x)*ky(nei_grid_x)*kz(nei_grid_x))^(1/3);%相邻那个基质网格渗透率 +% added_matnodes=nodes(nei_grid_x,:); +% nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% % dis_added=norm(nei_grid_core-core_frac_cell); +% % T_added=Knnc*area_frac_cell_x/dis_added; +% % 采用另一种方式计算几何因子 +% dis_added=norm(nei_grid_core-core_frac_cell); +% if Kf(the_frac_cell)==0 +% T_added=0; +% else +% % 单独裂缝单元几何因子 +% Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); +% % 单独相邻基质网格向裂缝单元几何因子 +% Geofnei=knei*area_frac_cell_x/dis_added; +% % 单独该基质网格向裂缝单元几何因子 +% Geofcell=Tinterflow(pos_rao,1); +% +% T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% % T_added=0;%特殊情况 +% % T_added=0;%特殊情况 +% % T_added=0.0039604;%特殊情况 +% end +% Nmf_projection=[Nmf_projection;nei_grid_x,the_frac_cell+nmc]; +% Tmf_projection=[Tmf_projection;T_added]; +% end +% +% %y direction +% if D_value_new(2)>0 +% selected_face(1)=2;nei_grid_y=i-nx; +% else selected_face(1)=5;nei_grid_y=i+nx; +% end +% struc_y=[i,nei_grid_y]; +% pos=find_row(struc_y,N); +% if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 +% S_p(pos)=S_p(pos)+area_frac_cell_y; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 +% knei=(kx(nei_grid_y)*ky(nei_grid_y)*kz(nei_grid_y))^(1/3);%相邻那个基质网格渗透率 +% added_matnodes=nodes(nei_grid_y,:); +% nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% % dis_added=norm(nei_grid_core-core_frac_cell); +% % T_added=Knnc*area_frac_cell_y/dis_added; +% % 采用另一种方式计算几何因子 +% dis_added=norm(nei_grid_core-core_frac_cell); +% if Kf(the_frac_cell)==0 +% T_added=0; +% else +% % 单独裂缝单元几何因子 +% Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); +% % 单独相邻基质网格向裂缝单元几何因子 +% Geofnei=knei*area_frac_cell_y/dis_added; +% % 单独该基质网格向裂缝单元几何因子 +% Geofcell=Tinterflow(pos_rao,1); +% +% T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% % T_added=0;%特殊情况 +% % T_added=0.002;%特殊情况 +% % T_added=0.0039604;%特殊情况 +% end +% Nmf_projection=[Nmf_projection;nei_grid_y,the_frac_cell+nmc]; +% Tmf_projection=[Tmf_projection;T_added]; +% end +% +% +% % z direction +% if D_value_new(3)>0 +% selected_face(1)=1;nei_grid_z=i-nx*ny; +% else selected_face(1)=6;nei_grid_z=i+nx*ny; +% end +% % nei_grid_z=i-nx*ny; +% struc_z=[i,nei_grid_z]; +% pos=find_row(struc_z,N); +% if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 +% S_p(pos)=S_p(pos)+area_frac_cell_z; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 +% knei=(kx(nei_grid_z)*ky(nei_grid_z)*kz(nei_grid_z))^(1/3);%相邻那个基质网格渗透率 +% added_matnodes=nodes(nei_grid_z,:); +% nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% % dis_added=norm(nei_grid_core-core_frac_cell); +% % T_added=Knnc*area_frac_cell_z/dis_added; +% % 采用另一种方式计算几何因子 +% dis_added=norm(nei_grid_core-core_frac_cell); +% if Kf(the_frac_cell)==0 +% T_added=0; +% else +% % 单独裂缝单元几何因子 +% Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); +% % 单独相邻基质网格向裂缝单元几何因子 +% Geofnei=knei*area_frac_cell_z/dis_added; +% % 单独该基质网格向裂缝单元几何因子 +% Geofcell=Tinterflow(pos_rao,1); +% +% T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% % T_added=0;%特殊情况 +% % T_added=0.0;%特殊情况 +% % T_added=0.0039604;%特殊情况 +% end +% Nmf_projection=[Nmf_projection;nei_grid_z,the_frac_cell+nmc]; +% Tmf_projection=[Tmf_projection;T_added]; +% end + + + end + end + end +end +%% 额外添加的改进 +im_N=[]; +im_T=[]; +% q=length(Kf)+1; +% for i=1:(q-1)/2%q-1是裂缝单元数量 +% for j=(q-1)/2+1:(q-1) +% if abs(corevsfra(j,1)-corevsfra(i,1))<=1e-2 +% im_N=[im_N;i+nmc,j+nmc]; +% % im_T=[im_T;0]; +% im_T=[im_T;0.0039604]; +% % im_T=[im_T;(((Kf(i))^(-1)+(1e-3)^(-1)+(1e-3)^(-1)+(Kf(j))^(-1))/4)^(-1)*2*2/0.4]; +% % +% end +% end +% end +%% 用投影面积修正基质网格间传导 +for i=1:nmm + % 为避免数值误差,导致没有真正封堵住,故 + if (S_ex(i)-S_p(i))/S_ex(i)<=1e-2 + T(i)=0; + else + T(i)= T(i)*(S_ex(i)-S_p(i))/S_ex(i); + end +end +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;Nmf_projection;im_N]; +T = [T; Tmff; Tff;Tinterflow;Tmf_projection;im_T]; +% N = [N; Nmff+nmc; Nff+nmc;Ninterflow;Nmf_projection]; +% T = [T; Tmff; Tff;Tinterflow;Tmf_projection]; +nex=size(N,1); +end diff --git a/core functions/preprocess/about_grid/connections_unstructured_EDFM.m b/core functions/preprocess/about_grid/connections_unstructured_EDFM.m new file mode 100644 index 0000000..3b4cebb --- /dev/null +++ b/core functions/preprocess/about_grid/connections_unstructured_EDFM.m @@ -0,0 +1,495 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag] = connections_unstructured_EDFM( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag ) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf +rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; +for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 +% m=floor((i+(2^nf)-1)/(2^nf)); + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); +% indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end +end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +mat_frac=[]; +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 +% if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + mat_frac=[mat_frac;i]; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; +end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +% Kffl=funtion_data.Kffl; +% Dffl=funtion_data.Dffl; +% kffl=zeros(q-1,1); +% dffl=zeros(q-1,1); +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,10);%裂缝网格渗透率 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +ave_disvsfra=zeros(q-1,1); +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 +for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if kf(i)==0 hartran=0;hartran_convection=0; + else + tran1=kf(i)*wf(i)*lengthcat/disk; + tran2=kf(i)*wf(i)*lengthcat/disj; +% hartran=length/(disk+disj);%取调和平均 + hartran=tran1*tran2/(tran1+tran2); + k_harmony= kf(i); + hartran_convection=kf(i)/(disk+disj)^2; + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + Tff_convection=[Tff_convection;hartran_convection]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +Tff_convection(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +Tmff_convection=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 +% lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 Tmff=[Tmff; 0];Tmff_convection=[Tmff_convection;0]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +Tmff_convection(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +T_convection = zeros(nmm, 1); +c = 0; +for k= 1 : nz +for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + T_convection(c) = 2/(1/Kx(index)+1/Kx(indexn))/(dxv(indexn)+dxv(index)); + end +end +end + +for k= 1 : nz +for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + T_convection(c) = 2/(1/Ky(index)+1/Ky(indexn))/(dyv(indexn)+dyv(index)); + end +end +end + +for i = 1 : nx +for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + T_convection(c) = 2/(1/Kz(index)+1/Kz(indexn))/(dzv(indexn)+dzv(index)); + end +end +end +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +Tinterflow_convection=[]; +matrix_cells_containing_fracture_cells = []; +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + matrix_cells_containing_fracture_cells = [matrix_cells_containing_fracture_cells; i]; + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=2*areavsfra(matrixvsfra(i,j)); + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + raoT=Knnc*Annc/Dn; + raoT_convection=2*Knnc/Dn^2; + Tinterflow=[Tinterflow;raoT]; + Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + end + end +end +%% 额外处理,此处并未通用化,有待进一步开展 +nfc=size(fracnumber,1); +the_added_matrix_cells = []; +nmc=nx * ny*nz; +the_added_mf_connec = []; +the_added_mf_T = []; +number_of_adding = 0; +cell_divided_by_fracture_flag = matrix_cells_containing_fracture_cells; +for i = 1:size(matrix_cells_containing_fracture_cells,1) + the_matrix_cell = matrix_cells_containing_fracture_cells(i,1); + number_of_adding = number_of_adding+1; + the_new_cell = number_of_adding+nmc; + the_added_matrix_cells = [the_added_matrix_cells; the_new_cell]; + % m-m连接 + for j = 1:size(N,1) + if N(j,1) == the_matrix_cell + if N(j,2) == the_matrix_cell+1 + N(j,1) = the_new_cell; T(j) = ... + ((Kx(the_matrix_cell)*dzv(the_matrix_cell)*dyv(the_matrix_cell)/(dxv(the_matrix_cell)/3))^(-1)+(Kx(the_matrix_cell+1)*dzv(the_matrix_cell+1)*dyv(the_matrix_cell+1)/(dxv(the_matrix_cell+1)/2))^(-1))^(-1); + end + if N(j,2) == the_matrix_cell-nx + N(j,1) = the_new_cell; T(j) = ... + ((Ky(the_matrix_cell)*dzv(the_matrix_cell)*dxv(the_matrix_cell)/(dyv(the_matrix_cell)/3))^(-1)+(Ky(the_matrix_cell-n)*dzv(the_matrix_cell-n)*dxv(the_matrix_cell-n)/(dxv(the_matrix_cell-n)/2))^(-1))^(-1); + end + end + if N(j,2) == the_matrix_cell + if N(j,1) == the_matrix_cell+1 + N(j,2) = the_new_cell; T(j) = ... + ((Kx(the_matrix_cell)*dzv(the_matrix_cell)*dyv(the_matrix_cell)/(dxv(the_matrix_cell)/3))^(-1)+(Kx(the_matrix_cell+1)*dzv(the_matrix_cell+1)*dyv(the_matrix_cell+1)/(dxv(the_matrix_cell+1)/2))^(-1))^(-1); + end + if N(j,1) == the_matrix_cell-nx + N(j,2) = the_new_cell; T(j) = ... + ((Ky(the_matrix_cell)*dzv(the_matrix_cell)*dxv(the_matrix_cell)/(dyv(the_matrix_cell)/3))^(-1)+(Ky(the_matrix_cell-n)*dzv(the_matrix_cell-n)*dxv(the_matrix_cell-n)/(dxv(the_matrix_cell-n)/2))^(-1))^(-1); + end + end + end +end +Ninterflow(:,2) = Ninterflow(:,2)+ number_of_adding; +ori_nmc = nmc; +nmc = ori_nmc +number_of_adding; +% m-f连接 +number_of_adding = 0; +for i = 1:size(matrix_cells_containing_fracture_cells,1) + the_matrix_cell = matrix_cells_containing_fracture_cells(i,1); + number_of_adding = number_of_adding+1; + the_new_cell = number_of_adding+ori_nmc; +for j = 1:size(Ninterflow,1) + if Ninterflow(j,1) == the_matrix_cell + the_added_mf_connec = [the_added_mf_connec;the_new_cell,Ninterflow(j,2)]; + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2]; + Tinterflow(j) = Tinterflow(j)/2; + end +end +end +Ninterflow = [Ninterflow; the_added_mf_connec]; +Tinterflow = [Tinterflow; the_added_mf_T]; +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +% syms x y z; +% Ninterflow=[]; +% Tinterflow=[]; +% for i=1:nx*ny*nz %基质网格编号 +% for j=1:10 +% if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell +% Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3); +% K1=Kf(matrixvsfra(i,j));d1=Wf(matrixvsfra(i,j)); +% K2=kffl(matrixvsfra(i,j));d2=dffl(matrixvsfra(i,j)); +% Annc=2*areavsfra(matrixvsfra(i,j)); +% fracore=corevsfra(matrixvsfra(i,j),:); +% matnodes=nodes(i,:); +% verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); +% matcore=mean(verco);d0=matcore-fracore; +% dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% % dn=abs(dn);%影响数值积分效率 +% dn=sqrt(dn^2); +% dn=matlabFunction(dn); +% if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 +% Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(2)~=0 +% Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(3)~=0 +% Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 && norvec(3)~=0 +% Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 +% Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 +% Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(3)~=0 +% Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% end +% end +% end +% end +% end +% end +% end +% raoT=((Kcell*Annc/(Dn-d2))^(-1)+(K2*Annc/d2)^(-1)+(K1*Annc/d1)^(-1))^(-1); +% Tinterflow=[Tinterflow;raoT]; +% end +% end +% end + +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;]; +T = [T; Tmff; Tff;Tinterflow;]; +T_convection = [T_convection;Tmff_convection; Tff_convection;Tinterflow_convection;]; +nex=size(N,1); +end diff --git a/core functions/preprocess/about_grid/frac_cross_frac.m b/core functions/preprocess/about_grid/frac_cross_frac.m new file mode 100644 index 0000000..8d204eb --- /dev/null +++ b/core functions/preprocess/about_grid/frac_cross_frac.m @@ -0,0 +1,185 @@ +function [ crossp,tmax,tmin ] = frac_cross_frac( f1,f2 ) +%f1,f2代表两条裂缝,f表示5*3矩阵,前三行每一行表示一个向量,后两行分别是两个参数的范围 +%以矩形缝为例,每个裂缝输入的为一个数组,[a0;a1;a2;umin,umax,vmin,vmax],若是其它类型缝,则是利用元胞数组存储,其中包含MATLABfunction +%裂缝与裂缝相交于一条线段,如果只相交于一点,则视为两裂缝无传质 +%解析求解这条相交线段的方程不易,因为裂缝形状的多样,因此利用参数等间隔搜寻两个相交点(x1,y1,z1),(x2,y2,z2), +%则可以确定该线段所在直线的参数方程,r=(x1,y1,z1)+t*(x2-x1,y2-y1,z2-z1),只需确定t的范围 +%使t在较大范围内等间隔搜索求解该点分别对应的两个裂缝的参数取值,并判断是否在裂缝形状设置的参数范围内,如果不是,就确定了该相交线段的具体位置。 +%[ cross,tmax,tmin ] = frac_cross_frac( [0.5,0,0;1,1,0;0,0,1;0,6,0;0,7,0],[5,0,0;-1,1,0;0,0,1;0,6,0;0,5,0] ) +a0=f1(1,:);a1=f1(2,:);a2=f1(3,:); +u1min=f1(4,1);u1max=f1(4,2);v1min=f1(5,1);v1max=f1(5,2); +b0=f2(1,:);b1=f2(2,:);b2=f2(3,:); +u2min=f2(4,1);u2max=f2(4,2);v2min=f2(5,1);v2max=f2(5,2); +n=1; +crossp=[]; +tmax=0;tmin=0; +n1=cross(a1,a2);%第一个裂缝面法向量; +n2=cross(b1,b2);%第二个裂缝面法向量; +flag=0;% 等于0表示b1直线有交点,等于1则表示b1没有 +if (norm(f1-f2)~=0) && (norm(cross(n1,n2))~=0) %确保存在交点 +% 直接用b1,b2所在直线去求交点,用之前,先判断该直线所在向量是否会与裂缝面平行,即此时无交点 +%b1直线: r=u2*b1+b0; +%裂缝面: r=a0+u1*a1+v1*a2; i.e., a0+u1*a1+v1*a2=u2*b1+b0 u1*a1+v1*a2-u2*b1=b0-a0 obtain three +%closed linear equations +coe=[a1(1) a2(1) -b1(1); + a1(2) a2(2) -b1(2); + a1(3) a2(3) -b1(3);]; +bv=[b0(1)-a0(1);b0(2)-a0(2);b0(3)-a0(3);]; +if abs(det(coe))<=1e-8 %表明无交点 +else + solution1=coe\bv; + crossp=[crossp;a0+solution1(1)*a1+solution1(2)*a2;]; + n=n+1; +%b1直线往b2方向平移一点: r=u2*b1+b2+b0; +%裂缝面: r=a0+u1*a1+v1*a2; i.e., a0+u1*a1+v1*a2=u2*b1+b0 u1*a1+v1*a2-u2*b1=b0-a0 obtain three +%closed linear equations +bv=[b2(1)+b0(1)-a0(1);b2(2)+b0(2)-a0(2);b2(3)+b0(3)-a0(3);]; +solution2=coe\bv; +crossp=[crossp;a0+solution2(1)*a1+solution2(2)*a2;]; +n=n+1; +end +end + + +%b2直线: r=u2*b2+b0; +coe=[a1(1) a2(1) -b2(1); + a1(2) a2(2) -b2(2); + a1(3) a2(3) -b2(3);]; +bv=[b0(1)-a0(1);b0(2)-a0(2);b0(3)-a0(3);]; +if abs(det(coe))<=1e-8 %表明无交点 +else + flag=1; + solution1=coe\bv; + crossp=[crossp;a0+solution1(1)*a1+solution1(2)*a2;]; + n=n+1; + %b2直线往b1方向平移一点: r=u2*b2+b1+b0; + bv=[b1(1)+b0(1)-a0(1);b1(2)+b0(2)-a0(2);b1(3)+b0(3)-a0(3);]; + solution2=coe\bv; + crossp=[crossp;a0+solution2(1)*a1+solution2(2)*a2;]; + n=n+1; +end + +if (n<3) crossp=zeros(2,3);tmax=0;tmin=0; +else + crossp=crossp(1:2,:); +vertex_1=[a0+u1min*a1+v1min*a2; +a0+u1min*a1+v1max*a2; +a0+u1max*a1+v1max*a2; +a0+u1max*a1+v1min*a2; +a0+u1min*a1+v1min*a2;]; +vertex_2=[b0+u2min*b1+v2min*b2; +b0+u2min*b1+v2max*b2; +b0+u2max*b1+v2max*b2; +b0+u2max*b1+v2min*b2; +b0+u2min*b1+v2min*b2;]; + +% 计算该交线与矩形裂缝面的交点 +t1=[];%交线在裂缝面1上时t的取值 +t2=[];%交线在裂缝面2上时t的取值 +%% 裂缝面1上计算 +for i=1:4 + k1=vertex_1(i+1,:)-vertex_1(i,:);%凸多边形相邻两点线段斜率 + k2=crossp(2,:)-crossp(1,:); +% if (((dot(k1,k2)/ norm(k1) / norm(k2))==1)||((dot(k1,k2)/ norm(k1) / norm(k2))==-1))%表明这两条边肯定不会相邻 + if (abs(abs(dot(k1,k2)/ norm(k1) / norm(k2))-1)<=1e-3)%表明这两条边肯定不会 + continue; + else + A=[crossp(2,1)-crossp(1,1),vertex_1(i,1)-vertex_1(i+1,1); + crossp(2,2)-crossp(1,2),vertex_1(i,2)-vertex_1(i+1,2); + crossp(2,3)-crossp(1,3),vertex_1(i,3)-vertex_1(i+1,3);]; + b=[vertex_1(i,1)-crossp(1,1); + vertex_1(i,2)-crossp(1,2); + vertex_1(i,3)-crossp(1,3)]; + if abs(det(A'*A))<1e-8 + end + para=A\b; +% if((para(2)>=0.999)||(para(2)<0)||(para(1)>tmax)||(para(1)=0.999)||(para(2)<0) continue;%取半线段,包含左边端点,不包含右侧端点,以免造成错误 + % 表示交点确在裂缝面边界线上 + else + t1=[t1;para(1)]; + end + end +end + +%% 裂缝面2上的计算 +for i=1:4 + k1=vertex_2(i+1,:)-vertex_2(i,:);%凸多边形相邻两点线段斜率 + k2=crossp(2,:)-crossp(1,:); +% if (((dot(k1,k2)/ norm(k1) / norm(k2))==1)||((dot(k1,k2)/ norm(k1) / norm(k2))==-1))%表明这两条边肯定不会相邻 + if (abs(abs(dot(k1,k2)/ norm(k1) / norm(k2))-1)<=1e-3)%表明这两条边肯定不会 + continue; + else + A=[crossp(2,1)-crossp(1,1),vertex_2(i,1)-vertex_2(i+1,1); + crossp(2,2)-crossp(1,2),vertex_2(i,2)-vertex_2(i+1,2); + crossp(2,3)-crossp(1,3),vertex_2(i,3)-vertex_2(i+1,3);]; + b=[vertex_2(i,1)-crossp(1,1); + vertex_2(i,2)-crossp(1,2); + vertex_2(i,3)-crossp(1,3)]; + if abs(det(A'*A))<1e-8 + end + para=A\b; +% if((para(2)>=0.999)||(para(2)<0)||(para(1)>tmax)||(para(1)=0.999)||(para(2)<0) continue;%取半线段,包含左边端点,不包含右侧端点,以免造成错误 + % 表示交点确在裂缝面边界线上 + else + t2=[t2;para(1)]; + end + end +end + +if length(t1)>2 || length(t2)>2 + error('Dr Rao reminds you to check the existing error carefully'); +elseif length(t1)<2 || length(t2)<2 || max(t1)<=min(t2) || max(t2)<=min(t1) %无公共交线部分 + crossp=zeros(2,3);tmax=0;tmin=0; +else + kitty=[t1;t2]; + kitty=sort(kitty); + tmin=kitty(2);tmax=kitty(3); +end + + + + + +% if flag==0 %则用b1直线即可求出交线在裂缝面上的参数取值范围 +% A1=[a1(1),a2(1); +% a1(2),a2(2); +% a1(3),a2(3)]; +% A2=[b1(1),b2(1); +% b1(2),b2(2); +% b1(3),b2(3)]; +% B1=crossp(1,:)-a0; +% B2=crossp(1,:)-b0; +% s1=A1\B1'; +% s2=A2\B2'; +% if((s1(1)>u1max)||(s1(1)v1max)||(s1(2)u2max)||(s2(1)v2max)||(s2(2)u1max)||(s1(1)v1max)||(s1(2)u2max)||(s2(1)v2max)||(s2(2)u1max)||(s1(1)v1max)||(s1(2)u2max)||(s2(1)v2max)||(s2(2)=1)||(para(2)<0)||(para(1)>tmax)||(para(1)raodu) raovector2(q)=mod(raovector2(q),raodu); + end + end + rao2=[f+crossnum(2),k(i,raovector2),f+crossnum(1),f+crossnum(2)]; + if(norm(anothersection(f+crossnum(1),:)-anothersection(indice(1),:))==0&&norm(anothersection(f+crossnum(2),:)==anothersection(indice(2),:))==0) + rao1=[indice(1),k(i,(indice(1)+1):1:indice(2)),indice(1)]; + rao2=[indice(2),k(i,raovector2),indice(2)]; + end + if(norm(anothersection(f+crossnum(1),:)-anothersection(indice(1),:))==0&&norm(anothersection(f+crossnum(2),:)-anothersection(indice(2),:))~=0) + rao1=[indice(1),k(i,(indice(1)+1):1:indice(2)),f+crossnum(2),indice(1)]; + rao2=[f+crossnum(2),k(i,raovector2),f+crossnum(2)]; + end + if(norm(anothersection(f+crossnum(1),:)-anothersection(indice(1),:))~=0&&norm(anothersection(f+crossnum(2),:)-anothersection(indice(2),:))==0) + rao1=[f+crossnum(1),k(i,(indice(1)+1):1:indice(2)),f+crossnum(1)]; + rao2=[indice(2),k(i,raovector2),f+crossnum(1),indice(2)]; + end + p=size(rao1,2);q=size(rao2,2); + xink(2*i-1,1:p)=rao1; xink(2*i,1:q)=rao2; + %raoindice=find(k(i)~=0); +% raodu=size(raodice,2)-1; +% rao1=indice(1):1:indice(2);rao1=[rao1,indice(1)]; +% rao2=indice(2):1:(indice(1)+raodu);rao2=[rao2,indice(2)]; +% rao2=mod(rao2,raodu); +% p=size(rao1,2);q=size(rao2,2); +% xink(2*i-1,1:p)=k(i,rao1); xink(2*i,1:q)=k(i,rao2); + end + end +end +%新的裂缝面网格剖分情况xink矩阵形成,xink中元素既是d3intersection中的行数,即实际的点序号 +% for i=1:1:2*n +% indice=find(xink(i,:)); +% if(size(indice,2)==0) continue; +% else +% point=xink(i,indice)'; +% u=anothersection(point,1); +% v=anothersection(point,2); +% dt=DelaunayTri(u,v); +% %triplot(d,anothersection(1,:),anothersection(2,:)); +% k1 = convexHull(dt);%k1是列向量,且长度极可能与k矩阵列数不一致 +% plot(u,v, '.', 'markersize',10); hold on; +% plot(u,v, 'r'); +% end +% end +% hold off; +end +% meshrao=[]; +% n=size(xink,1); +% for i=1:n +% a=xink(i,:); +% if(norm(a)~=0) +% meshrao=[meshrao;a]; +% end +% end +% xink=meshrao; +% +%xink(i,1:7)=k(i,:); xink(i,10)=i; + + +end + + diff --git a/core functions/preprocess/about_grid/frac_frac_mesh_modified.m b/core functions/preprocess/about_grid/frac_frac_mesh_modified.m new file mode 100644 index 0000000..b69e51e --- /dev/null +++ b/core functions/preprocess/about_grid/frac_frac_mesh_modified.m @@ -0,0 +1,206 @@ +function [ xink,d3intersection,anothersection,add_flag ]= frac_frac_mesh_modified(xrao,yrao,zrao,k, t0,t1,t2,cross,tmax,tmin,d3intersection,anothersection,numvspoint,numofmesh ) +%FRA_FRA_MESH 此处显示有关此函数的摘要 +%计算裂缝相交线在其中一条裂缝面上造成的区域更新 +%d3intersection是裂缝面与网格线交点的x,y,z的值矩阵,行代表点的序号,列依次是x,y,z +%anothersection是裂缝面与网格线交点的该裂缝面参数u,v的值矩阵,行代表点的序号,第一列u,第二列v +%numvspoint是裂缝面与网格线交点与区域的矩阵,行表示包含交点的基质网格的顺序序号, +%列表示每个区域中包含的交点对应于上述两个矩阵中的序号 +%numofmesh是包含交点的基质网格的序号,是一个列向量 +%cross表示确定的另一裂缝面与该裂缝相交线段上的两个点,每一行代表一个点的三维坐标 +%tmax表示该相交线段上所取参数的最大值 +%tmin表示该相交线段上所取参数的最小值 + +%第一步,判断每个区域包含的交点构成的凸多边形的连接顺序 +%需要在裂缝平面上根据参数u,v的取值利用delaunaytri函数及convexhull函数得到, +%这是由于如果用三维坐标,由于这些点共面,delaunaytri函数无法处理 +%% 将其它裂缝与该裂缝交线添加到裂缝平面上剖分的网格情况 +%对于其它裂缝与该裂缝的相交线并没有完全穿透一个网格时,则处理为:该网格不被这条相交线剖分 +%设置一个矩阵存储被再次剖分的网格情况,列数为10 +%行数初始化为2*size(k,1),以使有足够空间 +n=size(k,1); +z=size(k,2); +% xink=zeros(2*n,z+2); +% xink=sparse(2*n,z+2); +add_flag=0; +if(norm(cross)==0) %为了便于前处理而调整的 +% for i=1:n +% xink(2*i-1,1:z)=k(i,:); +% end +xink=k; +else + add_flag=1; + xink=zeros(2*n,z+2); +% [WO,~]=find(cross(:,1)>max(xrao)); +% [dao,~]=find(cross(:,2)>max(yrao)); +% [di,~]=find(cross(:,3)>max(zrao)); +% [gai,~]=find(cross(:,1)=0.999)||(para(2)<0)||(para(1)>tmax)||(para(1)raodu) raovector2(q)=mod(raovector2(q),raodu); + end + end + rao2=[f+crossnum(2),k(i,raovector2),f+crossnum(1),f+crossnum(2)]; + if norm(anothersection(f+crossnum(1),:)-anothersection(k(i,(indice(1))),:))<=1e-5&&norm(anothersection(f+crossnum(2),:)-anothersection(k(i,(indice(2))),:))<=1e-5 + rao1=[k(i,indice(1)),k(i,(indice(1)+1):1:indice(2)),k(i,indice(1))]; + rao2=[k(i,indice(2)),k(i,raovector2),k(i,indice(2))]; + end + if norm(anothersection(f+crossnum(1),:)-anothersection(k(i,(indice(1))),:))<=1e-5 &&norm(anothersection(f+crossnum(2),:)-anothersection(k(i,(indice(2))),:))>=1e-5 + rao1=[k(i,indice(1)),k(i,(indice(1)+1):1:indice(2)),f+crossnum(2),k(i,indice(1))]; + rao2=[f+crossnum(2),k(i,raovector2),f+crossnum(2)]; + end + if(norm(anothersection(f+crossnum(1),:)-anothersection(k(i,(indice(1))),:))>=1e-5&&norm(anothersection(f+crossnum(2),:)-anothersection(k(i,(indice(2))),:))<=1e-5) + rao1=[f+crossnum(1),k(i,(indice(1)+1):1:indice(2)),f+crossnum(1)]; + rao2=[k(i,indice(2)),k(i,raovector2),f+crossnum(1),k(i,indice(2))]; + end + p=size(rao1,2);q=size(rao2,2); + xink(2*i-1,:)=zeros(1,z+2); + xink(2*i-1,1:p)=rao1; xink(2*i,1:q)=rao2; + %raoindice=find(k(i)~=0); +% raodu=size(raodice,2)-1; +% rao1=indice(1):1:indice(2);rao1=[rao1,indice(1)]; +% rao2=indice(2):1:(indice(1)+raodu);rao2=[rao2,indice(2)]; +% rao2=mod(rao2,raodu); +% p=size(rao1,2);q=size(rao2,2); +% xink(2*i-1,1:p)=k(i,rao1); xink(2*i,1:q)=k(i,rao2); + end + end +end + +%% 去掉重复的点 +% dai=size(xink,1); +% for i=1:dai +% hui=unique(xink(i,:)); +% xink(i,:)=zeros(1,z+2); +% if length(hui)>2 +% xink(i,1:length(hui))=hui;xink(i,1)=xink(i,length(hui)); +% end +% end + +%新的裂缝面网格剖分情况xink矩阵形成,xink中元素既是d3intersection中的行数,即实际的点序号 +% for i=1:1:2*n +% indice=find(xink(i,:)); +% if(size(indice,2)==0) continue; +% else +% point=xink(i,indice)'; +% u=anothersection(point,1); +% v=anothersection(point,2); +% dt=DelaunayTri(u,v); +% %triplot(d,anothersection(1,:),anothersection(2,:)); +% k1 = convexHull(dt);%k1是列向量,且长度极可能与k矩阵列数不一致 +% plot(u,v, '.', 'markersize',10); hold on; +% plot(u,v, 'r'); +% end +% end +% hold off; + +% end +% xink=unique(xink, 'rows', 'stable'); +% d3intersection=unique(d3intersection, 'rows', 'stable'); +% anothersection=unique(anothersection, 'rows', 'stable'); +%xink(i,1:7)=k(i,:); xink(i,10)=i; + + +end + + diff --git a/core functions/preprocess/about_grid/frac_mat_mesh.m b/core functions/preprocess/about_grid/frac_mat_mesh.m new file mode 100644 index 0000000..82f8b7f --- /dev/null +++ b/core functions/preprocess/about_grid/frac_mat_mesh.m @@ -0,0 +1,31 @@ +function [ mesh] = frac_mat_mesh( d3intersection,anothersection,numvspoint,numofmesh ) +% 此函数由fracvsfrac函数拆分而来, +% 是为了计算裂缝面与基质网格相交产生的基质网格 +%% 画出裂缝与网格线交点在裂缝面上剖分网格的情况 +n=size(numvspoint,1); +mesh=zeros(n,7);%存放每个区域凸多边形的连点顺序,因为要形成闭合回路,因此列数加1以确保适用 +for i=1:1:n +indice=find(numvspoint(i,:)~=0); +if(size(indice,2)<3) mesh(i,:)=[0,0,0,0,0,0,0]; continue; +end +point=numvspoint(i,indice)'; +u=anothersection(point,1); +v=anothersection(point,2); +dt=DelaunayTri(u,v); +%triplot(d,anothersection(1,:),anothersection(2,:)); +k1 = convexHull(dt);%k1是列向量,且长度极可能与k矩阵列数不一致 +% plot(u,v, '.', 'markersize',10); hold on; +% plot(u(k1),v(k1), 'r'); +m=size(k1,1); +for j=1:1:m + mesh(i,j)=point(k1(j)); +end +% k1=k1'; +% m=size(k1,2); +% k(i,1:m)=k1; +%hold off; +end +%hold off + +end + diff --git a/core functions/preprocess/about_grid/fun1.m b/core functions/preprocess/about_grid/fun1.m new file mode 100644 index 0000000..8a8b790 --- /dev/null +++ b/core functions/preprocess/about_grid/fun1.m @@ -0,0 +1,114 @@ +function [ cf ] = fun1( anothersection,fracnumber,p0,f ) +%fracturenumber是该裂缝网格包含的点编号,anothersection是该裂缝平面点的参数坐标矩阵 +% 将每个裂缝网格的最后一个点去掉,防止重复 +% f表示该裂缝网格所在裂缝面的信息 +% facemid矩阵表示基质网格各面的中点坐标 + indice=find(fracnumber~=0); + m=size(indice,2); + newsection=fracnumber(1,1:(m-1)); + u=anothersection(newsection',1); + v=anothersection(newsection',2); +% ucore=mean(u);%该裂缝单元中心对应的u,v值 +% vcore=mean(v); + dt=delaunayTriangulation(u,v); + n=size(dt,1); + cf=0; + for k=1:n + coordinate=anothersection(newsection(dt(k,:))',:);%dt(k,:)只是newsection中的序号,因此如左所示 + cf=triint( coordinate,f,p0 )+cf; + end + +end + + +function [ cf ] = triint( coordinate,f,p0 ) +%TRIINT 此处显示有关此函数的摘要,f表示所处裂缝面的参数5*3矩阵 +% 此处显示详细说明 +syms u v r s length m n; +t0=f(1,:); +t1=f(2,:); +t2=f(3,:); +x1=coordinate(1,1);y1=coordinate(1,2); +x2=coordinate(2,1);y2=coordinate(2,2); +x3=coordinate(3,1);y3=coordinate(3,2); +Jocbimatrix=[x1-x3,x2-x3; + y1-y3,y2-y3]; +J=abs(det(Jocbimatrix)); +if(J==0) cf=0; +else +A=[t1(1),t2(1); +t1(2),t2(2); +t1(3),t2(3)]; +p1=p0-t0; +p2=A\p1'; +% p2=(A'*p1')\(A'*A); +u0=p2(1);v0=p2(2); +tol=t1*u0+t2*v0+t0-p0; +if(norm(tol)==0)%说明该点在该平面上,是奇点 +% length=sqrt((u-u0)^2*norm(t1)^2+(v-v0)^2*norm(t2)^2); +% g=-1/4/pi/length; +% g=subs(g,[u,v],[(x1-x3)*r+(x2-x3)*s+x3,(y1-y3)*r+(y2-y3)*s+y3]); +% g1=matlabFunction(g); +% f2=@(r,s)(r+s<=1); +% f1=@(r,s)(g1(r,s).*f2(r,s)); +% cf=J*norm(t1)*norm(t2)*integral2(f1,0,1,0,1,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%上述方法无效,因此拟打算在积分时给length加上一个较小的正常数,使其为非奇点情况 +%该处理是合理的,因为裂缝本就具有一定厚度,并且该积分本身是可积的,这保证了这样处理的误差极小,暂定为加0.01。 +lx=u*t1(1)+v*t2(1)+t0(1)-p0(1); +ly=u*t1(2)+v*t2(2)+t0(2)-p0(2); +lz=u*t1(3)+v*t2(3)+t0(3)-p0(3); +length=sqrt(lx^2+ly^2+lz^2)+1e-6; +g=-1/(4*pi*length); +g=subs(g,[u,v],[(x1-x3)*r+(x2-x3)*s+x3,(y1-y3)*r+(y2-y3)*s+y3]); +g1=matlabFunction(g); +f=@(r,s)(g1(r,s)); +smax=@(r)1-r; +% % % f2=@(r,s)(r+s<=1); +% % % f=@(r,s)(g1(r,s).*f2(r,s)); +% length=sqrt(lx^2+ly^2+lz^2)+1e-6;%与奇点相比具有本质的差别,在原积分可积的情况下,误差极小! +% g=-1/(4*pi*length); +% g1=matlabFunction(g); +% f2=@(u,v)(u+v<=1); +% f1=@(u,v)(g1(u,v).*f2(u,v)); +cf=J*norm(cross(t1,t2))*integral2(f,0,1,0,smax,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +else%不存在奇点 +lx=u*t1(1)+v*t2(1)+t0(1)-p0(1); +ly=u*t1(2)+v*t2(2)+t0(2)-p0(2); +lz=u*t1(3)+v*t2(3)+t0(3)-p0(3); +length=sqrt(lx^2+ly^2+lz^2)+1e-6; +g=-1/(4*pi*length); +g=subs(g,[u,v],[(x1-x3)*r+(x2-x3)*s+x3,(y1-y3)*r+(y2-y3)*s+y3]); +g1=matlabFunction(g); +% % % f2=@(r,s)(r+s<=1); +% % % f=@(r,s)(g1(r,s).*f2(r,s)); +f=@(r,s)(g1(r,s)); +smax=@(r)1-r; +% length=sqrt(lx^2+ly^2+lz^2)+1e-6; +% g=-1/(4*pi*length); +% g=subs(g,[u,v],[(x1-x3)*r+(x2-x3)*s+x3,(y1-y3)*r+(y2-y3)*s+y3]); +% g1=matlabFunction(g); +% f2=@(r,s)(r+s<=1); +% f=@(r,s)(g1(r,s).*f2(r,s)); +% cf=J*norm(t1)*norm(t2)*integral2(f,0,1,0,1,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +% g1=matlabFunction(g); +% f2=@(u,v)(u+v<=1); +% f1=@(u,v)(g1(u,v).*f2(u,v)); +cf=J*norm(cross(t1,t2))*integral2(f,0,1,0,smax,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +% g=@(r,s)(-1./(4.*pi.*sqrt((((x1-x3).*r+(x2-x3).*s+x3).*t1(1)+((y1-y3).*r+(y2-y3).*s+y3).*t2(1)+t0(1)-p0(1)).^2+... +% (((x1-x3).*r+(x2-x3).*s+x3).*t1(2)+((y1-y3).*r+(y2-y3).*s+y3).*t2(2)+t0(2)-p0(2)).^2+... +% (((x1-x3).*r+(x2-x3).*s+x3).*t1(3)+((y1-y3).*r+(y2-y3).*s+y3).*t2(3)+t0(3)-p0(3)).^2))); +% lx=u*t1(1)+v*t2(1)+t0(1)-p0(1); +% ly=u*t1(2)+v*t2(2)+t0(2)-p0(2); +% lz=u*t1(3)+v*t2(3)+t0(3)-p0(3); +% length=sqrt(lx^2+ly^2+lz^2); +% g=-1/(4*pi*length); +%g=subs(g,[u,v],[(x1-x3).*r+(x2-x3).*s+x3,(y1-y3).*r+(y2-y3).*s+y3]); +% g1=matlabFunction(g); +% f2=@(r,s)(r+s<=1); +% f=@(r,s)(g(r,s).*f2(r,s)); +% cf=J*norm(t1)*norm(t2)*integral2(f,0,1,0,1,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%cf=J*norm(t1)*norm(t2)*integral2(g1,0,1,0,1,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +end +end +end + diff --git a/core functions/preprocess/about_grid/fun2.m b/core functions/preprocess/about_grid/fun2.m new file mode 100644 index 0000000..c0dbf08 --- /dev/null +++ b/core functions/preprocess/about_grid/fun2.m @@ -0,0 +1,84 @@ +function [ cf ] = fun2( anothersection,fracnumber,coreco,f ) +%fracturenumber是该裂缝网格包含的点编号,anothersection是该裂缝平面点的参数坐标矩阵 +% 将每个裂缝网格的最后一个点去掉,防止重复 +% f表示该裂缝网格所在裂缝面的信息 +% facemid矩阵表示基质网格各面的中点坐标 + indice=find(fracnumber~=0); + m=size(indice,2); + newsection=fracnumber(1,1:(m-1)); + u=anothersection(newsection',1); + v=anothersection(newsection',2); + dt=delaunayTriangulation(u,v); + n=size(dt,1); + cf=0; + for k=1:n + coordinate=anothersection(newsection(dt(k,:))',:);%dt(k,:)只是newsection中的序号,因此如左所示 + cf=triint1( coordinate,f,coreco )+cf; + end + +end + + +function [ cf ] = triint1( coordinate,f,coreco ) +%TRIINT 此处显示有关此函数的摘要,f表示所处裂缝面的参数5*3矩阵 +% 此处显示详细说明 +syms u v r s length; +t0=f(1,:); +t1=f(2,:); +t2=f(3,:); +x1=coordinate(1,1);y1=coordinate(1,2); +x2=coordinate(2,1);y2=coordinate(2,2); +x3=coordinate(3,1);y3=coordinate(3,2); +Jocbimatrix=[x1-x3,x2-x3; + y1-y3,y2-y3]; +J=abs(det(Jocbimatrix)); +if(J==0) cf=0; +else +A=[t1(1),t2(1); +t1(2),t2(2); +t1(3),t2(3)]; +p1=coreco-t0; +p2=A\p1'; +u0=p2(1);v0=p2(2); +tol=t1*u0+t2*v0+t0-coreco; +if(norm(tol)==0)%说明该点在该平面上,是奇点 +% length=sqrt((u-u0)^2*norm(t1)^2+(v-v0)^2*norm(t2)^2)+1e-8; +lx=u*t1(1)+v*t2(1)+t0(1)-coreco(1); +ly=u*t1(2)+v*t2(2)+t0(2)-coreco(2); +lz=u*t1(3)+v*t2(3)+t0(3)-coreco(3); +length=sqrt(lx^2+ly^2+lz^2)+1e-8; +g=-1/4/pi/length; +g=subs(g,[u,v],[(x1-x3)*r+(x2-x3)*s+x3,(y1-y3)*r+(y2-y3)*s+y3]); +g1=matlabFunction(g); +% % % f2=@(r,s)(r+s<=1); +% % % f=@(r,s)(g1(r,s).*f2(r,s)); +f=@(r,s)(g1(r,s)); +smax=@(r)1-r; +cf=J*norm(cross(t1,t2))*integral2(f,0,1,0,smax,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +% lx=u*t1(1)+v*t2(1)+t0(1)-p0(1); +% ly=u*t1(2)+v*t2(2)+t0(2)-p0(2); +% lz=u*t1(3)+v*t2(3)+t0(3)-p0(3); +% length=sqrt(lx^2+ly^2+lz^2)+0.01;%与奇点相比具有本质的差别,在原积分可积的情况下,误差极小! +% g=-1/(4*pi*length); +% g1=matlabFunction(g); +% f2=@(u,v)(u+v<=1); +% f1=@(u,v)(g1(u,v).*f2(u,v)); +% cf=J*norm(t1)*norm(t2)*integral2(f1,0,1,0,1,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +else%不存在奇点 +lx=u*t1(1)+v*t2(1)+t0(1)-coreco(1); +ly=u*t1(2)+v*t2(2)+t0(2)-coreco(2); +lz=u*t1(3)+v*t2(3)+t0(3)-coreco(3); +length=sqrt(lx^2+ly^2+lz^2)+1e-8; +g=-1/(4*pi*length); +g=subs(g,[u,v],[(x1-x3)*r+(x2-x3)*s+x3,(y1-y3)*r+(y2-y3)*s+y3]); +g1=matlabFunction(g); +% % % f2=@(r,s)(r+s<=1); +% % % f=@(r,s)(g1(r,s).*f2(r,s)); +f=@(r,s)(g1(r,s)); +smax=@(r)1-r; +cf=J*norm(cross(t1,t2))*integral2(f,0,1,0,smax,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%cf=J*norm(t1)*norm(t2)*integral2(g1,0,1,0,1,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +end +end +end + diff --git a/core functions/preprocess/about_grid/fun3.m b/core functions/preprocess/about_grid/fun3.m new file mode 100644 index 0000000..6bebfd9 --- /dev/null +++ b/core functions/preprocess/about_grid/fun3.m @@ -0,0 +1,67 @@ +function [ cf ] = fun3( anothersection,p0,fracnumber,coreco,f ) +%fracturenumber是该裂缝网格包含的点编号,anothersection是该裂缝平面点的参数坐标矩阵 +% 将每个裂缝网格的最后一个点去掉,防止重复 +% f表示该裂缝网格所在裂缝面的信息 +% facemid矩阵表示基质网格各面的中点坐标 +% indice=find(fracnumber~=0); +% m=size(indice,2); +% newsection=fracnumber(1,1:(m-1)); +% u=anothersection(newsection',1); +% v=anothersection(newsection',2); +% dt=delaunayTriangulation(u,v); +% n=size(dt,1); +% cf=0; +% for k=1:n +% coordinate=anothersection(newsection(dt(k,:))',:);%dt(k,:)只是newsection中的序号,因此如左所示 +% cf=triint1( coordinate,f,p0 )+cf; +% end + +%TRIINT 此处显示有关此函数的摘要,f表示所处裂缝面的参数5*3矩阵 +% 此处显示详细说明 +syms u v r s length; +t0=f(1,:); +t1=f(2,:); +t2=f(3,:); +x1=coordinate(1,1);y1=coordinate(1,2); +x2=coordinate(2,1);y2=coordinate(2,2); +x3=coordinate(3,1);y3=coordinate(3,2); +Jocbimatrix=[x1-x3,x2-x3; + y1-y3,y2-y3]; +J=abs(det(Jocbimatrix)); +if(J==0) cf=0; +else +A=[t1(1),t2(1); +t1(2),t2(2); +t1(3),t2(3)]; +p1=coreco-t0; +p2=p1'\A; +u0=p2(1);v0=p2(2); +tol=t1*u0+t2*v0+t0-p0; +if(norm(tol)==0)%说明该点在该平面上,是奇点 +% length=sqrt((u-u0)^2*norm(t1)^2+(v-v0)^2*norm(t2)^2); +lx=u*t1(1)+v*t2(1)+t0(1)-p0(1); +ly=u*t1(2)+v*t2(2)+t0(2)-p0(2); +lz=u*t1(3)+v*t2(3)+t0(3)-p0(3); +length=sqrt(lx^2+ly^2+lz^2); +g=-1/4/pi/length; +g=subs(g,[u,v],[(x1-x3)*r+(x2-x3)*s+x3,(y1-y3)*r+(y2-y3)*s+y3]); +g1=matlabFunction(g); +f=@(r,s)(g1(r,s)); +smax=@(r)1-r; +cf=J*norm(cross(t1,t2))*integral2(f,0,1,0,smax,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +else%不存在奇点 +lx=u*t1(1)+v*t2(1)+t0(1)-p0(1); +ly=u*t1(2)+v*t2(2)+t0(2)-p0(2); +lz=u*t1(3)+v*t2(3)+t0(3)-p0(3); +length=sqrt(lx^2+ly^2+lz^2); +g=-1/(4*pi*length); +g=subs(g,[u,v],[(x1-x3)*r+(x2-x3)*s+x3,(y1-y3)*r+(y2-y3)*s+y3]); +g1=matlabFunction(g); +f=@(r,s)(g1(r,s)); +smax=@(r)1-r; +cf=J*norm(cross(t1,t2))*integral2(f,0,1,0,smax,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%cf=J*norm(t1)*norm(t2)*integral2(g1,0,1,0,1,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +end +end +end + diff --git a/core functions/preprocess/about_grid/interarea.m b/core functions/preprocess/about_grid/interarea.m new file mode 100644 index 0000000..6b064d5 --- /dev/null +++ b/core functions/preprocess/about_grid/interarea.m @@ -0,0 +1,135 @@ +function [ numofmesh, numvspoint,numofregion] = interarea( d3intersection,dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ) +%判断交点所在的区域编号 +%numofregion矩阵,row denotes point,column denotes ,一个点最多属于8个区域,因此建m行8列矩阵 +%numvspoint矩阵,row denotes the number of matrix mesh,column denotes the point,相交最多六个点,因此矩阵列数是6,行数为牵涉到的基质网格数 +%[ numofmesh, numvspoint,numofregion] = interarea( d3intersection,1,1,1,10,10,10 ) +m=size(d3intersection,1); +numofregion=zeros(m,8);%判断这些交点属于哪个基质网格 +for i=1:m +% a1=floor(d3intersection(i,1)/dx); +% a2=mod(d3intersection(i,1),dx); +% b1=floor(d3intersection(i,2)/dy); +% b2=mod(d3intersection(i,2),dy); +% c1=floor(d3intersection(i,3)/dz); +% c2=mod(d3intersection(i,3),dz); + + +for zhang=1:nx+1 + if xrao(1,zhang)<=d3intersection(i,1) + a1=zhang-1; + a2=d3intersection(i,1)-xrao(1,zhang); + end +end +for zhang=1:ny+1 + if yrao(1,zhang)<=d3intersection(i,2) + b1=zhang-1; + b2=d3intersection(i,2)-yrao(1,zhang); + end +end +for zhang=1:nz+1 + if zrao(1,zhang)<=d3intersection(i,3) + c1=zhang-1; + c2=d3intersection(i,3)-zrao(1,zhang); + end +end + +numofregion(i,:)=[a1+b1*nx+c1*nx*ny,a1+1+b1*nx+c1*nx*ny,a1+(b1-1)*nx+c1*nx*ny,a1+1+(b1-1)*nx+c1*nx*ny,... + a1+(b1-1)*nx+(c1-1)*nx*ny,a1+1+(b1-1)*nx+(c1-1)*nx*ny,a1+b1*nx+(c1-1)*nx*ny,a1+1+b1*nx+(c1-1)*nx*ny]; +% 坐标取0边界处理 +if((a1==0)&&(a2==0)) + numofregion(i,1)=0;numofregion(i,3)=0;numofregion(i,5)=0;numofregion(i,7)=0; +end +if((b1==0)&&(b2==0)) + numofregion(i,3)=0;numofregion(i,4)=0;numofregion(i,5)=0;numofregion(i,6)=0; +end +if((c1==0)&&(c2==0)) + numofregion(i,5)=0;numofregion(i,6)=0;numofregion(i,7)=0;numofregion(i,8)=0; +end +% 坐标取最大边界处理 +if a1==nx + numofregion(i,2)=0;numofregion(i,4)=0;numofregion(i,6)=0;numofregion(i,8)=0; +end +if b1==ny + numofregion(i,1)=0;numofregion(i,2)=0;numofregion(i,7)=0;numofregion(i,8)=0; +end +% if c1==nz +% numofregion(i,1)=0;numofregion(i,2)=0;numofregion(i,3)=0;numofregion(i,4)=0; +% end +if(a2~=0) + numofregion(i,1)=0;numofregion(i,3)=0;numofregion(i,5)=0;numofregion(i,7)=0; +end +if(b2~=0) + numofregion(i,3)=0;numofregion(i,4)=0;numofregion(i,5)=0;numofregion(i,6)=0; +end +if(c2~=0) + numofregion(i,5)=0;numofregion(i,6)=0;numofregion(i,7)=0;numofregion(i,8)=0; +end +end +numofregion(numofregion>nx*ny*nz)=0;%把基质网格不包含的剔除,因为最上面一层没有 +numofmesh=unique(numofregion);%输出的是列向量,即包含交点的基质网格编号 + +%% 将只包含不多于两个交点的mesh去掉 +record=[]; +n=size(numofmesh,1); +if(numofmesh(1)==0) + record=[record;1]; + for i=2:1:n + [I,J]= find(numofregion==numofmesh(i));%返回的是列向量 + k=size(I,1); + if(k<=2) record=[record;i]; + end + end +else + for i=1:1:n + [I,J]= find(numofregion==numofmesh(i)); + k=size(I,1); + if(k<=2) record=[record;k]; + end + end +end +numofmesh(record,:)=[]; + +%% +n=size(numofmesh,1); +if(numofmesh(1)==0) + numvspoint=zeros(n-1,6);%计算相应基质网格包含的交点 + for i=2:1:n + [I,J]= find(numofregion==numofmesh(i));%返回的是列向量 + k=size(I,1); + numvspoint(i-1,1:k)=I'; + end + numofmesh=numofmesh(2:n,:);%把开头的0去掉 +else + numvspoint=zeros(n,6); + for i=1:1:n + [I,J]= find(numofregion==numofmesh(i)); + k=size(I,1); + numvspoint(i,1:k)=I'; + end +end +numvspoint=sort(numvspoint,2); + +numvspoint=unique(numvspoint,'rows','stable'); + + + + +% if(a2==0) +% if(b2==0) +% if(c2==0) +% numofregion(i,:)=[a1+b1*nx+c1*nx*ny,a1+1+b1*nx+c1*nx*ny,a1+(b1-1)*nx+c1*nx*ny,a1+1+(b1-1)*nx+c1*nx*ny,... +% a1+(b1-1)*nx+(c1-1)*nx*ny,a1+1+(b1-1)*nx+(c1-1)*nx*ny,a1+b1*nx+(c1-1)*nx*ny,a1+1+b1*nx+(c1-1)*nx*ny]; +% else +% numofregion(i,:)=[a1+b1*nx+c1*nx*ny,a1+1+b1*nx+c1*nx*ny,a1+(b1-1)*nx+c1*nx*ny,a1+1+(b1-1)*nx+c1*nx*ny,... +% 0,0,0,0]; +% end +% else +% numofregion(i,:)=[a1+b1*nx+c1*nx*ny,a1+1+b1*nx+c1*nx*ny,... +% 0,0,0,0,0,0]; +% end +% else +% numofregion(i,:)=[a1+1+b1*nx+c1*nx*ny,... +% 0,0,0,0,0,0,0]; +% end +end + diff --git a/core functions/preprocess/about_grid/interflowmf.asv b/core functions/preprocess/about_grid/interflowmf.asv new file mode 100644 index 0000000..c5318c4 --- /dev/null +++ b/core functions/preprocess/about_grid/interflowmf.asv @@ -0,0 +1,303 @@ +function [ G,Gfm,Gff,Gf,Ap,Apf ] = interflowmf(dx,dy,dz,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coord,nf,corevsfra ) +%此函数用于计算在边界元方法中将源点选在基质网格面中心时, +%与三相窜流有关的系数矩阵 +%G矩阵,偏G偏n矩阵,Gfm矩阵 +%dx,dy,dz分别是包含裂缝的该基质网格的尺寸 +%假设选取的点在某xy平面上,要计算的是相对的另一面上的G矩阵的cm +% G矩阵求解 +m=size(connectmf,1);%包含有裂缝单元的基质网格数 + +syms z y x; +%dx=1;dy=1;dz=1; +%r=sqrt((z-dz/2).^2+y.^2+(dx/2).^2); +%c11 +g=@(x,y)-1./((4.*pi).*sqrt(x.^2+y.^2)); +c11=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c12 +g=@(x,z)-1./((4.*pi).*sqrt(x.^2+(-dy/2).^2+(z+dz./2).^2)); +c12=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c13 +g=@(y,z)-1./((4.*pi).*sqrt(y.^2+(-dx/2).^2+(z+dz./2).^2)); +c13=integral2(g,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c16 +g=@(x,y)-1./((4.*pi).*sqrt(x.^2+y.^2+dz.^2)); +c16=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c21 +g=@(x,y)-1./((4.*pi).*sqrt(x.^2+(y+dy/2).^2+(-dz/2).^2)); +c21=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c22 +g=@(x,z)-1./((4.*pi).*sqrt(x.^2+z.^2)); +c22=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c23 +g=@(y,z)-1./((4.*pi).*sqrt((-dx/2).^2+(y+dy/2).^2+z.^2)); +c23=integral2(g,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c25 +g=@(x,z)-1./((4.*pi).*sqrt(x.^2+dy.^2+z.^2)); +c25=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c31 +g=@(x,y)-1./((4.*pi).*sqrt((x+dx/2).^2+y.^2+(-dz/2).^2)); +c31=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c32 +g=@(x,z)-1./((4.*pi).*sqrt((x+dx/2).^2+(-dy/2).^2+z.^2)); +c32=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c33 +g=@(y,z)-1./((4.*pi).*sqrt(y.^2+z.^2)); +c33=integral2(g,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c34 +g=@(y,z)-1./((4.*pi).*sqrt(dx^2+y.^2+z.^2)); +c34=integral2(g,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c41 +g=@(x,y)-1./((4.*pi).*sqrt((x-dx/2).^2+y.^2+(-dz/2).^2)); +c41=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c42 +g=@(x,z)-1./((4.*pi).*sqrt((x-dx/2).^2+(-dy/2).^2+z.^2)); +c42=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c51 +g=@(x,y)-1./((4.*pi).*sqrt(x.^2+(y-dy/2).^2+(-dz/2).^2)); +c51=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c53 +g=@(x,y)-1./((4.*pi).*sqrt(x.^2+(y-dy/2).^2+(-dz/2).^2)); +c53=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c62 +g=@(x,z)-1./((4.*pi).*sqrt(x.^2+(-dy/2).^2+(z-dz/2).^2)); +c62=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c63 +g=@(y,z)-1./((4.*pi).*sqrt((-dx/2).^2+y.^2+(z-dz/2).^2)); +c63=integral2(g,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%计算G矩阵 +G=[c11,c12,c13,c13,c12,c16; + c21,c22,c23,c23,c25,c21; + c31,c32,c33,c34,c32,c31; + c41,c42,c34,c33,c42,c41; + c51,c25,c53,c53,c22,c51; + c16,c62,c63,c63,c62,c11]; +%% dG矩阵的求解 +dG=zeros(6); +grad=cell{6,1}; +%到编号为1源点的r(0,0,-dz/2) +r1=@(x,y,z)-1./((4.*pi).*sqrt(x.^2+y.^2+(z+dz./2).^2)); +grad{1,1}=[diff(r1,x),diff(r1,y),diff(r1,z)]; +n1=[0,0,-1]; +%到编号为2源点的r(0,-dy/2,0) +r2=@(x,y,z)-1./((4.*pi).*sqrt(x.^2+(y+dy/2).^2+z.^2)); +grad{2,1}=[diff(r2,x),diff(r2,y),diff(r2,z)]; +n2=[0,-1,0]; +%到编号为3源点的r(-dx/2,0,0) +r3=@(x,y,z)-1./((4.*pi).*sqrt((x+dx/2).^2+y.^2+z.^2)); +grad{3,1}=[diff(r3,x),diff(r3,y),diff(r3,z)]; +n3=[-1,0,0]; +%到编号为4源点的r(dx/2,0,0) +r4=@(x,y,z)-1./((4.*pi).*sqrt((x-dx/2).^2+y.^2+z.^2)); +grad{4,1}=[diff(r4,x),diff(r4,y),diff(r4,z)]; +n4=[0,0,1]; +%到编号为5源点的r(0,dy/2,0) +r5=@(x,y,z)-1./((4.*pi).*sqrt(x.^2+(y-dy/2).^2+z.^2)); +grad{5,1}=[diff(r5,x),diff(r5,y),diff(r5,z)]; +n5=[0,1,0]; +%到编号为6源点的r(0,0,dz/2) +r6=@(x,y,z)-1./((4.*pi).*sqrt(x.^2+y.^2+(z-dz./2).^2)); +grad{6,1}=[diff(r6,x),diff(r6,y),diff(r6,z)]; +n6=[0,0,1]; +% +for i=1:6 + if j==1 + rao=grad{i,1}.*n1; + g=subs(rao,z,-dz/2); + if j~=i + g1=matlabFunction(g); + g2=@(x,y)g1(x,y); + dG(i,j)=integral2(g2,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==2 + rao=grad{i,1}.*n2; + g=subs(rao,y,-dy/2); + if j~=i + g1=matlabFunction(g); + g2=@(x,z)g1(x,z); + dG(i,j)=integral2(g2,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==3 + rao=grad{i,1}.*n3; + g=subs(rao,x,-dx/2); + if j~=i + g1=matlabFunction(g); + g2=@(y,z)g1(y,z); + dG(i,j)=integral2(g2,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==4 + rao=grad{i,1}.*n4; + g=subs(rao,x,dx/2); + if j~=i + g1=matlabFunction(g); + g2=@(y,z)g1(y,z); + dG(i,j)=integral2(g2,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==5 + rao=grad{i,1}.*n5; + g=subs(rao,y,dy/2); + if j~=i + g1=matlabFunction(g); + g2=@(x,z)g1(x,z); + dG(i,j)=integral2(g2,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==1 + rao=grad{i,1}.*n6; + g=subs(rao,z,dz/2); + if j~=i + g1=matlabFunction(g); + g2=@(x,y)g1(x,y); + dG(i,j)=integral2(g2,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + dG=dG-2*pi/(4*pi)*eye(6); +% for i=1:6 +% for j=1:6 +% dG(i,j)=fun3 +% dG(i,i)=-2*pi/(4*pi); +% end +%% Gfm矩阵求解 +% m=size(matrixvsfra,1); +% Gfm=cell(m,1); +Gfm=cell(m,1); +for i=1:m + indice=find(matrixvsfra(connectmf{i,1},:)~=0); + n=size(indice,2); + cf=zeros(6,n); +if(n>0)%表明改基质网格包含裂缝网格n=size(indice,2); + matnodes=nodes(connectmf{i,1},:); + matnodes=coord(matnodes,:); + p(1,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(3,:)+matnodes(4,:))/4; + p(2,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(5,:)+matnodes(6,:))/4; + p(3,:)=(matnodes(1,:)+matnodes(3,:)+matnodes(5,:)+matnodes(7,:))/4; + p(4,:)=(matnodes(2,:)+matnodes(4,:)+matnodes(6,:)+matnodes(8,:))/4; + p(5,:)=(matnodes(3,:)+matnodes(4,:)+matnodes(7,:)+matnodes(8,:))/4; + p(6,:)=(matnodes(5,:)+matnodes(6,:)+matnodes(7,:)+matnodes(8,:))/4; + for j=1:6 + for k=1:n + for r=2:(nf+1) + if(matrixvsfra(connectmf{i,1},k)0)%表明改基质网格包含裂缝网格n=size(indice,2); + for j=1:n + for k=1:n + for r=2:(nf+1) + if(matrixvsfra(connectmf{i,1},k)0)%表明改基质网格包含裂缝网格n=size(indice,2); + r=p(1,:)-corevsfra(matrixvsfra(connectmf{i,1},j),:); + end + dGf{i,1}=cf; +end +%% Gf矩阵的求解 +%corevsfra矩阵存放每个裂缝网格的重心坐标 +syms z y x; +m=size(matrixvsfra,1); +Gf=cell(m,1); +for i=1:m + indice=find(matrixvsfra(connectmf{i,1},:)~=0); + n=size(indice,2); + cf=zeros(n,6); +if(n>0)%表明改基质网格包含裂缝网格n=size(indice,2); + matnodes=nodes(connectmf{i,1},:); + matnodes=coord(matnodes,:); + p(1,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(3,:)+matnodes(4,:))/4;%z不变 + p(2,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(5,:)+matnodes(6,:))/4;%y不变 + p(3,:)=(matnodes(1,:)+matnodes(3,:)+matnodes(5,:)+matnodes(7,:))/4;%x不变 + p(4,:)=(matnodes(2,:)+matnodes(4,:)+matnodes(6,:)+matnodes(8,:))/4;%x不变 + p(5,:)=(matnodes(3,:)+matnodes(4,:)+matnodes(7,:)+matnodes(8,:))/4;%y不变 + p(6,:)=(matnodes(5,:)+matnodes(6,:)+matnodes(7,:)+matnodes(8,:))/4;%z不变 + for j=1:n + %for k=1:6%使立方体面循环 +% for r=2:(nf+1) +% if(matrixvsfra(i,j)0)%表明改基质网格包含裂缝网格n=size(indice,2); + matnodes=nodes(connectmf{i,1},:); + matnodes=coord(matnodes,:); + p(1,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(3,:)+matnodes(4,:))/4; + p(2,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(5,:)+matnodes(6,:))/4; + p(3,:)=(matnodes(1,:)+matnodes(3,:)+matnodes(5,:)+matnodes(7,:))/4; + p(4,:)=(matnodes(2,:)+matnodes(4,:)+matnodes(6,:)+matnodes(8,:))/4; + p(5,:)=(matnodes(3,:)+matnodes(4,:)+matnodes(7,:)+matnodes(8,:))/4; + p(6,:)=(matnodes(5,:)+matnodes(6,:)+matnodes(7,:)+matnodes(8,:))/4; + for j=1:6 + for k=1:n + for r=2:(nf+1) + if(matrixvsfra(connectmf{i,1},k)0)%表明改基质网格包含裂缝网格n=size(indice,2); + for j=1:n + for k=1:n + for r=2:(nf+1) + if(matrixvsfra(connectmf{i,1},k)0)%表明改基质网格包含裂缝网格n=size(indice,2); + matnodes=nodes(connectmf{i,1},:); + matnodes=coord(matnodes,:); + p(1,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(3,:)+matnodes(4,:))/4; + p(2,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(5,:)+matnodes(6,:))/4; + p(3,:)=(matnodes(1,:)+matnodes(3,:)+matnodes(5,:)+matnodes(7,:))/4; + p(4,:)=(matnodes(2,:)+matnodes(4,:)+matnodes(6,:)+matnodes(8,:))/4; + p(5,:)=(matnodes(3,:)+matnodes(4,:)+matnodes(7,:)+matnodes(8,:))/4; + p(6,:)=(matnodes(5,:)+matnodes(6,:)+matnodes(7,:)+matnodes(8,:))/4; + cf=zeros(n,6); + for k=1:n + core=corevsfra(matrixvsfra(connectmf{i,1},k),:); +% r=-1./((4.*pi).*sqrt(x-core(1)).^2+(y-core(2)).^2+(z-core(3)).^2); +% grad=[diff(r,x),diff(r,y),diff(r,z)]; + gradx=(x-core(1))./((4.*pi).*((x-core(1)).^2+(y-core(2)).^2+(z-core(3)).^2)^(3/2)); + grady=(y-core(2))./((4.*pi).*((x-core(1)).^2+(y-core(2)).^2+(z-core(3)).^2)^(3/2)); + gradz=(z-core(3))./((4.*pi).*((x-core(1)).^2+(y-core(2)).^2+(z-core(3)).^2)^(3/2)); + grad=[gradx,grady,gradz]; + for j=1:6 + if j==1 + rao=grad*n1'; + g=subs(rao,[x,y,z],[p(1,1)+x1,p(1,2)+y1,p(1,3)]); + if (isempty(symvar(g))) cf(k,j)=0; + else + g1=matlabFunction(g); + g2=@(x1,y1)g1(x1,y1); + cf(k,j)=integral2(g2,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==2 + rao=grad*n2'; +% g=subs(rao,y,); + g=subs(rao,[x,y,z],[p(2,1)+x1,p(2,2),p(2,3)+z1]); + + if (isempty(symvar(g))) cf(k,j)=0; + else + g1=matlabFunction(g); + g2=@(x1,z1)g1(x1,z1); + cf(k,j)=integral2(g2,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==3 + rao=grad*n3'; +% g=subs(rao,x,-dx/2); + g=subs(rao,[x,y,z],[p(3,1),p(3,2)+y1,p(3,3)+z1]); + + if (isempty(symvar(g))) + cf(k,j)=0; + else + g1=matlabFunction(g); + g2=@(y1,z1)g1(y1,z1); + cf(k,j)=integral2(g2,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==4 + rao=grad*n4'; +% g=subs(rao,x,dx/2); + g=subs(rao,[x,y,z],[p(4,1),p(4,2)+y1,p(4,3)+z1]); + + if (isempty(symvar(g))) + cf(k,j)=0; + else + g1=matlabFunction(g);g2=@(y1,z1)g1(y1,z1); + cf(k,j)=integral2(g2,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==5 + rao=grad*n5'; +% g=subs(rao,y,dy/2); + g=subs(rao,[x,y,z],[p(5,1)+x1,p(5,2),p(5,3)+z1]); + + if (isempty(symvar(g))) + cf(k,j)=0; + else + g1=matlabFunction(g); g2=@(x1,z1)g1(x1,z1); + cf(k,j)=integral2(g2,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==6 + rao=grad*n6'; +% g=subs(rao,z,dz/2); + g=subs(rao,[x,y,z],[p(6,1)+x1,p(6,2)+y1,p(6,3)]); + + if (isempty(symvar(g))) + cf(k,j)=0; + else + g1=matlabFunction(g); g2=@(x1,y1)g1(x1,y1); + cf(k,j)=integral2(g2,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + end + + end + dGf{i,1}=cf; + end + + a=1; +end +%% Gf矩阵的求解 +%corevsfra矩阵存放每个裂缝网格的重心坐标 +syms z y x; +% m=size(matrixvsfra,1); +Gf=cell(m,1); +for i=1:m + dx=dimen(i,1); dy=dimen(i,2); dz=dimen(i,3); + indice=find(matrixvsfra(connectmf{i,1},:)~=0); + n=size(indice,2); + cf=zeros(n,6); +if(n>0)%表明改基质网格包含裂缝网格n=size(indice,2); + matnodes=nodes(connectmf{i,1},:); + matnodes=coord(matnodes,:); + p(1,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(3,:)+matnodes(4,:))/4;%z不变 + p(2,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(5,:)+matnodes(6,:))/4;%y不变 + p(3,:)=(matnodes(1,:)+matnodes(3,:)+matnodes(5,:)+matnodes(7,:))/4;%x不变 + p(4,:)=(matnodes(2,:)+matnodes(4,:)+matnodes(6,:)+matnodes(8,:))/4;%x不变 + p(5,:)=(matnodes(3,:)+matnodes(4,:)+matnodes(7,:)+matnodes(8,:))/4;%y不变 + p(6,:)=(matnodes(5,:)+matnodes(6,:)+matnodes(7,:)+matnodes(8,:))/4;%z不变 + for j=1:n + %for k=1:6%使立方体面循环 +% for r=2:(nf+1) +% if(matrixvsfra(i,j)0)%表明改基质网格包含裂缝网格n=size(indice,2); +% % % for j=1:n +% % % matnodes=nodes(connectmf{i,1},:); +% % % matnodes=coord(matnodes,:); +% % % pm=mean(matnodes); +% % % core=corevsfra(matrixvsfra(connectmf{i,1},j),:); +% % % r=-1./((4.*pi).*sqrt((x+pm(1)-core(1)).^2+(y+pm(2)-core(2)).^2+(z+pm(3)-core(3)).^2)+1e-8); +% % % f=matlabFunction(r); +% % % cf(j,1)=integral3(f,-dx/2,dx/2,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +% % % end +% % % end +% % % Gfmt{i,1}=cf; +% % % end +% % % +% % % %% Gfft +% % % Gfft=Gff;%没乘以相应缝宽 +%% 系数矩阵计算 +% m=size(matrixvsfra,1); +% Ap=cell(m,1); +Ap=cell(m,1); +Apf=cell(m,1); +% Apmt=cell(m,1); +% Apft=cell(m,1); +for i=1:m +% if (isempty(Gfm{i,1})==0)%非空 +% 计算转换矩阵 +% grid_num=connectmf{i,1}; +% % 先只考虑上下左右,因为如果要加上上下,则需要预先在上下各垫一层,防止超出索引,这样会极大增加运算量 +% C=zeros(4,5); +% rel_grid=[grid_num-r.nx,grid_num-1,grid_num+1,grid_num+r.nx,grid_num]; +% % x 方向 +% C(1,1)=r.ky(grid_num-r.nx)/r.dyv(grid_num-r.nx)/(r.ky(grid_num)/r.dyv(grid_num)+r.ky(grid_num-r.nx)/r.dyv(grid_num-r.nx)); +% C(1,5)=r.ky(grid_num)/r.dyv(grid_num)/(r.ky(grid_num)/r.dyv(grid_num)+r.ky(grid_num-r.nx)/r.dyv(grid_num-r.nx)); +% C(4,4)=r.ky(grid_num+r.nx)/r.dyv(grid_num+r.nx)/(r.ky(grid_num)/r.dyv(grid_num)+r.ky(grid_num+r.nx)/r.dyv(grid_num+r.nx)); +% C(4,5)=r.ky(grid_num)/r.dyv(grid_num)/(r.ky(grid_num)/r.dyv(grid_num)+r.ky(grid_num+r.nx)/r.dyv(grid_num+r.nx)); +% % y 方向 +% C(2,2)=r.kx(grid_num-1)/r.dxv(grid_num-1)/(r.kx(grid_num)/r.dxv(grid_num)+r.kx(grid_num-1)/r.dxv(grid_num-1)); +% C(2,5)=r.kx(grid_num)/r.dxv(grid_num)/(r.kx(grid_num)/r.dxv(grid_num)+r.kx(grid_num-1)/r.dxv(grid_num-1)); +% C(3,3)=r.kx(grid_num+1)/r.dxv(grid_num+1)/(r.kx(grid_num)/r.dxv(grid_num)+r.kx(grid_num+1)/r.dxv(grid_num+1)); +% C(3,5)=r.kx(grid_num)/r.dxv(grid_num)/(r.kx(grid_num)/r.dxv(grid_num)+r.kx(grid_num+1)/r.dxv(grid_num+1)); +% C=[[0,0,0,0,1];C;[0,0,0,0,1]]; + +Gin = G{i,1}^(-1); +Ap0 = dGf{i,1} - Gf{i,1} * Gin * dG{i,1}; +Apf0 = Gf{i,1} * Gin * Gfm{i,1} - Gff{i,1}; +Apfv = Apf0^(-1); +Apt= Apfv * Ap0; +Ap{i,1} = Apt * ones(6,1); +% Ap{i,1} = Apt * C; +% Ap{i,2} = rel_grid; +Apf{i,1} = -Apfv; +wo=size(Apfv,1); +ni=size(Apfv,2); +% Apmt{i,1}=0; +% Apft{i,1}=zeros(wo,ni); +% % % Apmt{i,1}=Apfv*(Gfmt{i,1}-Gf{i,1}*Gin*Gmt{i,1}); +% % % Apft{i,1}=Apfv*(Gfft{i,1}-Gf{i,1}*Gin*Gmft{i,1}); +end +end +% Ap = Ap * ones(nb,1); +% Apf = -Apfv; + + + + + diff --git a/core functions/preprocess/about_grid/interflowmf_MODIFIED.m b/core functions/preprocess/about_grid/interflowmf_MODIFIED.m new file mode 100644 index 0000000..0e74960 --- /dev/null +++ b/core functions/preprocess/about_grid/interflowmf_MODIFIED.m @@ -0,0 +1,528 @@ +function [ G,Gfm,Gff,Gf,Ap,Apf ] = interflowmf_MODIFIED(rr,dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coord,nf,corevsfra ) +%此函数用于计算在边界元方法中将源点选在基质网格面中心时, +%与三相窜流有关的系数矩阵 +%G矩阵,偏G偏n矩阵,Gfm矩阵 +%dx,dy,dz分别是包含裂缝的该基质网格的尺寸 +%假设选取的点在某xy平面上,要计算的是相对的另一面上的G矩阵的cm +% G矩阵求解 +%[ G,Gfm,Gff,Gf,Ap,Apf,Apmt,Apft ] = interflowmf1(dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coord,nf,corevsfra ) +syms z y x x0 y0 z0 x1 y1 z1; +m=size(connectmf,1);%包含有裂缝单元的基质网格数 +dimen=zeros(m,3); +for hui=1:m +dimen(hui,:)=[dxv(connectmf{hui,1}) dyv(connectmf{hui,1}) dzv(connectmf{hui,1})]; +end +raowang=unique(dimen,'rows'); +xiang=size(raowang,1); +wang=cell(xiang,1); +for i=1:xiang +dx=raowang(i,1);dy=raowang(i,2);dz=raowang(i,3); +%dx=1;dy=1;dz=1; +%r=sqrt((z-dz/2).^2+y.^2+(dx/2).^2); +%c11 +g=@(x,y)-1./((4.*pi).*sqrt(x.^2+y.^2)); +c11=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c12 +g=@(x,z)-1./((4.*pi).*sqrt(x.^2+(-dy/2).^2+(z+dz./2).^2)); +c12=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c13 +g=@(y,z)-1./((4.*pi).*sqrt(y.^2+(-dx/2).^2+(z+dz./2).^2)); +c13=integral2(g,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c16 +g=@(x,y)-1./((4.*pi).*sqrt(x.^2+y.^2+dz.^2)); +c16=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c21 +g=@(x,y)-1./((4.*pi).*sqrt(x.^2+(y+dy/2).^2+(-dz/2).^2)); +c21=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c22 +g=@(x,z)-1./((4.*pi).*sqrt(x.^2+z.^2)); +c22=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c23 +g=@(y,z)-1./((4.*pi).*sqrt((-dx/2).^2+(y+dy/2).^2+z.^2)); +c23=integral2(g,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c25 +g=@(x,z)-1./((4.*pi).*sqrt(x.^2+dy.^2+z.^2)); +c25=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c31 +g=@(x,y)-1./((4.*pi).*sqrt((x+dx/2).^2+y.^2+(-dz/2).^2)); +c31=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c32 +g=@(x,z)-1./((4.*pi).*sqrt((x+dx/2).^2+(-dy/2).^2+z.^2)); +c32=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c33 +g=@(y,z)-1./((4.*pi).*sqrt(y.^2+z.^2)); +c33=integral2(g,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c34 +g=@(y,z)-1./((4.*pi).*sqrt(dx^2+y.^2+z.^2)); +c34=integral2(g,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c41 +g=@(x,y)-1./((4.*pi).*sqrt((x-dx/2).^2+y.^2+(-dz/2).^2)); +c41=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c42 +g=@(x,z)-1./((4.*pi).*sqrt((x-dx/2).^2+(-dy/2).^2+z.^2)); +c42=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c51 +g=@(x,y)-1./((4.*pi).*sqrt(x.^2+(y-dy/2).^2+(-dz/2).^2)); +c51=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c53 +g=@(x,y)-1./((4.*pi).*sqrt(x.^2+(y-dy/2).^2+(-dz/2).^2)); +c53=integral2(g,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c62 +g=@(x,z)-1./((4.*pi).*sqrt(x.^2+(-dy/2).^2+(z-dz/2).^2)); +c62=integral2(g,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%c63 +g=@(y,z)-1./((4.*pi).*sqrt((-dx/2).^2+y.^2+(z-dz/2).^2)); +c63=integral2(g,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +%计算G矩阵 +wang{i,1}=[c11,c12,c13,c13,c12,c16; + c21,c22,c23,c23,c25,c21; + c31,c32,c33,c34,c32,c31; + c41,c42,c34,c33,c42,c41; + c51,c25,c53,c53,c22,c51; + c16,c62,c63,c63,c62,c11]; +end +G=cell(m,1); +for i=1:m +% index=connectmf{i,1};%该基质网格编号 +for j=1:xiang + if norm(dimen(i,:)-raowang(j,:))==0 + G{i,1}=wang{j,1}; + end +end +end + +%% dG矩阵的求解 +dai=cell(xiang,1); +n1=[0,0,-1]; +n2=[0,-1,0]; +n3=[-1,0,0]; +n4=[1,0,0]; +n5=[0,1,0]; +n6=[0,0,1]; +r=-1./((4.*pi).*sqrt((x-x0).^2+(y-y0).^2+(z-z0).^2)); +for zhang=1:xiang +dx=raowang(zhang,1); +dy=raowang(zhang,2); +dz=raowang(zhang,3); +dG=zeros(6); +grad=cell(6,1); +gradx=(x-x0)./((4.*pi).*((x-x0).^2+(y-y0).^2+(z-z0).^2)^(3/2)); +grady=(y-y0)./((4.*pi).*((x-x0).^2+(y-y0).^2+(z-z0).^2)^(3/2)); +gradz=(z-z0)./((4.*pi).*((x-x0).^2+(y-y0).^2+(z-z0).^2)^(3/2)); +gradrao=[gradx,grady,gradz]; +grad{1,1}=subs(gradrao,[x0,y0,z0],[0,0,-dz/2]); +grad{2,1}=subs(gradrao,[x0,y0,z0],[0,-dy/2,0]); +grad{3,1}=subs(gradrao,[x0,y0,z0],[-dx/2,0,0]); +grad{4,1}=subs(gradrao,[x0,y0,z0],[dx/2,0,0]); +grad{5,1}=subs(gradrao,[x0,y0,z0],[0,dy/2,0]); +grad{6,1}=subs(gradrao,[x0,y0,z0],[0,0,dz/2]); +for i=1:6 + for j=1:6 + if j==1 + rao=grad{i,1}*n1'; + g=subs(rao,z,-dz/2); + if j~=i + g1=matlabFunction(g); + g2=@(x,y)g1(x,y); + dG(i,j)=integral2(g2,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==2 + rao=grad{i,1}*n2'; + g=subs(rao,y,-dy/2); + if j~=i + g1=matlabFunction(g); + g2=@(x,z)g1(x,z); + dG(i,j)=integral2(g2,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + + end + end + if j==3 + rao=grad{i,1}*n3'; + g=subs(rao,x,-dx/2); + if j~=i + g1=matlabFunction(g); + g2=@(y,z)g1(y,z); + dG(i,j)=integral2(g2,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==4 + rao=grad{i,1}*n4'; + g=subs(rao,x,dx/2); + if j~=i + g1=matlabFunction(g); + g2=@(y,z)g1(y,z); + dG(i,j)=integral2(g2,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==5 + rao=grad{i,1}*n5'; + g=subs(rao,y,dy/2); + if j~=i + g1=matlabFunction(g); + g2=@(x,z)g1(x,z); + dG(i,j)=integral2(g2,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==6 + rao=grad{i,1}*n6'; + g=subs(rao,z,dz/2); + if j~=i + g1=matlabFunction(g); + g2=@(x,y)g1(x,y); + dG(i,j)=integral2(g2,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + end +end + dG=dG-2*pi/(4*pi)*eye(6); + dai{zhang,1}=dG; +end + +dG=cell(m,1); +parfor i=1:m +% index=connectmf{i,1};%该基质网格编号 +for j=1:xiang + if norm(dimen(i,:)-raowang(j,:))==0 + dG{i,1}=dai{j,1}; + end +end +end +% for i=1:6 +% for j=1:6 +% dG(i,j)=fun3 +% dG(i,i)=-2*pi/(4*pi); +% end +%% Gfm矩阵求解 +% m=size(matrixvsfra,1); +% Gfm=cell(m,1); +Gfm=cell(m,1); +for i=1:m + indice=find(matrixvsfra(connectmf{i,1},:)~=0); + n=size(indice,2); + cf=zeros(6,n); +if(n>0)%表明改基质网格包含裂缝网格n=size(indice,2); + matnodes=nodes(connectmf{i,1},:); + matnodes=coord(matnodes,:); + p(1,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(3,:)+matnodes(4,:))/4; + p(2,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(5,:)+matnodes(6,:))/4; + p(3,:)=(matnodes(1,:)+matnodes(3,:)+matnodes(5,:)+matnodes(7,:))/4; + p(4,:)=(matnodes(2,:)+matnodes(4,:)+matnodes(6,:)+matnodes(8,:))/4; + p(5,:)=(matnodes(3,:)+matnodes(4,:)+matnodes(7,:)+matnodes(8,:))/4; + p(6,:)=(matnodes(5,:)+matnodes(6,:)+matnodes(7,:)+matnodes(8,:))/4; + for j=1:6 + for k=1:n + for xiao=2:(nf+1) + if(matrixvsfra(connectmf{i,1},k)0)%表明改基质网格包含裂缝网格n=size(indice,2); + for j=1:n + for k=1:n + for r=2:(nf+1) + if(matrixvsfra(connectmf{i,1},k)0)%表明改基质网格包含裂缝网格n=size(indice,2); + matnodes=nodes(connectmf{i,1},:); + matnodes=coord(matnodes,:); + p(1,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(3,:)+matnodes(4,:))/4; + p(2,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(5,:)+matnodes(6,:))/4; + p(3,:)=(matnodes(1,:)+matnodes(3,:)+matnodes(5,:)+matnodes(7,:))/4; + p(4,:)=(matnodes(2,:)+matnodes(4,:)+matnodes(6,:)+matnodes(8,:))/4; + p(5,:)=(matnodes(3,:)+matnodes(4,:)+matnodes(7,:)+matnodes(8,:))/4; + p(6,:)=(matnodes(5,:)+matnodes(6,:)+matnodes(7,:)+matnodes(8,:))/4; + cf=zeros(n,6); + for k=1:n + core=corevsfra(matrixvsfra(connectmf{i,1},k),:); +% r=-1./((4.*pi).*sqrt(x-core(1)).^2+(y-core(2)).^2+(z-core(3)).^2); +% grad=[diff(r,x),diff(r,y),diff(r,z)]; + gradx=(x-core(1))./((4.*pi).*((x-core(1)).^2+(y-core(2)).^2+(z-core(3)).^2)^(3/2)); + grady=(y-core(2))./((4.*pi).*((x-core(1)).^2+(y-core(2)).^2+(z-core(3)).^2)^(3/2)); + gradz=(z-core(3))./((4.*pi).*((x-core(1)).^2+(y-core(2)).^2+(z-core(3)).^2)^(3/2)); + grad=[gradx,grady,gradz]; + for j=1:6 + if j==1 + rao=grad*n1'; + g=subs(rao,[x,y,z],[p(1,1)+x1,p(1,2)+y1,p(1,3)]); + if (isempty(symvar(g))) cf(k,j)=0; + else + g1=matlabFunction(g); + g2=@(x1,y1)g1(x1,y1); + cf(k,j)=integral2(g2,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==2 + rao=grad*n2'; +% g=subs(rao,y,); + g=subs(rao,[x,y,z],[p(2,1)+x1,p(2,2),p(2,3)+z1]); + + if (isempty(symvar(g))) cf(k,j)=0; + else + g1=matlabFunction(g); + g2=@(x1,z1)g1(x1,z1); + cf(k,j)=integral2(g2,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==3 + rao=grad*n3'; +% g=subs(rao,x,-dx/2); + g=subs(rao,[x,y,z],[p(3,1),p(3,2)+y1,p(3,3)+z1]); + + if (isempty(symvar(g))) + cf(k,j)=0; + else + g1=matlabFunction(g); + g2=@(y1,z1)g1(y1,z1); + cf(k,j)=integral2(g2,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==4 + rao=grad*n4'; +% g=subs(rao,x,dx/2); + g=subs(rao,[x,y,z],[p(4,1),p(4,2)+y1,p(4,3)+z1]); + + if (isempty(symvar(g))) + cf(k,j)=0; + else + g1=matlabFunction(g);g2=@(y1,z1)g1(y1,z1); + cf(k,j)=integral2(g2,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==5 + rao=grad*n5'; +% g=subs(rao,y,dy/2); + g=subs(rao,[x,y,z],[p(5,1)+x1,p(5,2),p(5,3)+z1]); + + if (isempty(symvar(g))) + cf(k,j)=0; + else + g1=matlabFunction(g); g2=@(x1,z1)g1(x1,z1); + cf(k,j)=integral2(g2,-dx/2,dx/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + if j==6 + rao=grad*n6'; +% g=subs(rao,z,dz/2); + g=subs(rao,[x,y,z],[p(6,1)+x1,p(6,2)+y1,p(6,3)]); + + if (isempty(symvar(g))) + cf(k,j)=0; + else + g1=matlabFunction(g); g2=@(x1,y1)g1(x1,y1); + cf(k,j)=integral2(g2,-dx/2,dx/2,-dy/2,dy/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); + end + end + end + + end + dGf{i,1}=cf; + end + + a=1; +end +%% Gf矩阵的求解 +%corevsfra矩阵存放每个裂缝网格的重心坐标 +syms z y x; +% m=size(matrixvsfra,1); +Gf=cell(m,1); +for i=1:m + dx=dimen(i,1); dy=dimen(i,2); dz=dimen(i,3); + indice=find(matrixvsfra(connectmf{i,1},:)~=0); + n=size(indice,2); + cf=zeros(n,6); +if(n>0)%表明改基质网格包含裂缝网格n=size(indice,2); + matnodes=nodes(connectmf{i,1},:); + matnodes=coord(matnodes,:); + p(1,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(3,:)+matnodes(4,:))/4;%z不变 + p(2,:)=(matnodes(1,:)+matnodes(2,:)+matnodes(5,:)+matnodes(6,:))/4;%y不变 + p(3,:)=(matnodes(1,:)+matnodes(3,:)+matnodes(5,:)+matnodes(7,:))/4;%x不变 + p(4,:)=(matnodes(2,:)+matnodes(4,:)+matnodes(6,:)+matnodes(8,:))/4;%x不变 + p(5,:)=(matnodes(3,:)+matnodes(4,:)+matnodes(7,:)+matnodes(8,:))/4;%y不变 + p(6,:)=(matnodes(5,:)+matnodes(6,:)+matnodes(7,:)+matnodes(8,:))/4;%z不变 + for j=1:n + %for k=1:6%使立方体面循环 +% for r=2:(nf+1) +% if(matrixvsfra(i,j)0)%表明改基质网格包含裂缝网格n=size(indice,2); +% % % for j=1:n +% % % matnodes=nodes(connectmf{i,1},:); +% % % matnodes=coord(matnodes,:); +% % % pm=mean(matnodes); +% % % core=corevsfra(matrixvsfra(connectmf{i,1},j),:); +% % % r=-1./((4.*pi).*sqrt((x+pm(1)-core(1)).^2+(y+pm(2)-core(2)).^2+(z+pm(3)-core(3)).^2)+1e-8); +% % % f=matlabFunction(r); +% % % cf(j,1)=integral3(f,-dx/2,dx/2,-dy/2,dy/2,-dz/2,dz/2,'Method','iterated','AbsTol',1e-8,'RelTol',1e-5); +% % % end +% % % end +% % % Gfmt{i,1}=cf; +% % % end +% % % +% % % %% Gfft +% % % Gfft=Gff;%没乘以相应缝宽 +%% 系数矩阵计算 +% m=size(matrixvsfra,1); +% Ap=cell(m,1); +Ap=cell(m,2); +Apf=cell(m,1); +% Apmt=cell(m,1); +% Apft=cell(m,1); +for i=1:m +% if (isempty(Gfm{i,1})==0)%非空 +% 计算转换矩阵 +grid_num=connectmf{i,1}; +% 先只考虑上下左右,因为如果要加上上下,则需要预先在上下各垫一层,防止超出索引,这样会极大增加运算量 +C=zeros(4,5); +rel_grid=[grid_num-rr.nx,grid_num-1,grid_num+1,grid_num+rr.nx,grid_num]; +% x 方向 +C(1,1)=rr.ky(grid_num-rr.nx)/rr.dyv(grid_num-rr.nx)/(rr.ky(grid_num)/rr.dyv(grid_num)+rr.ky(grid_num-rr.nx)/rr.dyv(grid_num-rr.nx)); +C(1,5)=rr.ky(grid_num)/rr.dyv(grid_num)/(rr.ky(grid_num)/rr.dyv(grid_num)+rr.ky(grid_num-rr.nx)/rr.dyv(grid_num-rr.nx)); +C(4,4)=rr.ky(grid_num+rr.nx)/rr.dyv(grid_num+rr.nx)/(rr.ky(grid_num)/rr.dyv(grid_num)+rr.ky(grid_num+rr.nx)/rr.dyv(grid_num+rr.nx)); +C(4,5)=rr.ky(grid_num)/rr.dyv(grid_num)/(rr.ky(grid_num)/rr.dyv(grid_num)+rr.ky(grid_num+rr.nx)/rr.dyv(grid_num+rr.nx)); +% y 方向 +C(2,2)=rr.kx(grid_num-1)/rr.dxv(grid_num-1)/(rr.kx(grid_num)/rr.dxv(grid_num)+rr.kx(grid_num-1)/rr.dxv(grid_num-1)); +C(2,5)=rr.kx(grid_num)/rr.dxv(grid_num)/(rr.kx(grid_num)/rr.dxv(grid_num)+rr.kx(grid_num-1)/rr.dxv(grid_num-1)); +C(3,3)=rr.kx(grid_num+1)/rr.dxv(grid_num+1)/(rr.kx(grid_num)/rr.dxv(grid_num)+rr.kx(grid_num+1)/rr.dxv(grid_num+1)); +C(3,5)=rr.kx(grid_num)/rr.dxv(grid_num)/(rr.kx(grid_num)/rr.dxv(grid_num)+rr.kx(grid_num+1)/rr.dxv(grid_num+1)); +C=[[0,0,0,0,1];C;[0,0,0,0,1]]; + +Gin = G{i,1}^(-1); +Ap0 = dGf{i,1} - Gf{i,1} * Gin * dG{i,1}; +Apf0 = Gf{i,1} * Gin * Gfm{i,1} - Gff{i,1}; +Apfv = Apf0^(-1); +Apt= Apfv * Ap0; +% Ap{i,1} = Apt * ones(6,1); +Ap{i,1} = Apt * C; +Ap{i,2} = rel_grid; +Apf{i,1} = -Apfv; +wo=size(Apfv,1); +ni=size(Apfv,2); +% Apmt{i,1}=0; +% Apft{i,1}=zeros(wo,ni); +% % % Apmt{i,1}=Apfv*(Gfmt{i,1}-Gf{i,1}*Gin*Gmt{i,1}); +% % % Apft{i,1}=Apfv*(Gfft{i,1}-Gf{i,1}*Gin*Gmft{i,1}); +end +end +% Ap = Ap * ones(nb,1); +% Apf = -Apfv; + + + + + diff --git a/core functions/preprocess/about_grid/intersectionsolve.m b/core functions/preprocess/about_grid/intersectionsolve.m new file mode 100644 index 0000000..1e1b63d --- /dev/null +++ b/core functions/preprocess/about_grid/intersectionsolve.m @@ -0,0 +1,225 @@ +function [ d3intersection ] = intersectionsolve(fracture,dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ) +% 裂缝由两个相互正交向量,及两个参数的范围确定,面缝具有几何上的对称性 +% dx,dy,dz,lx,ly,lz是网格属性参数 +% t=t0+u*t1+v*t2;缝上参数为u,v点的向量 +%如果只是相交于一点,则只用每一行前三个是交点坐标,存在d3intersection中; +%如果相交于一条线段,存在d2intersection中则只用每一行前三个中两个是坐标线的两个坐标,另一个代表未知的坐标(用-1表示);第四、五个表示相交线段在坐标线上的另一坐标取值范围; +%对d2intersection中的每一条线段进行处理 +%示例:[ d3intersection ] = intersectionsolve([0.5,0,0],[1,1,0],[0,0,1],0,6,0,7,1,1,1,10,10,10) +t0=fracture(1,:);t1=fracture(2,:);t2=fracture(3,:); +umin=fracture(4,1);umax=fracture(4,2);vmin=fracture(5,1);vmax=fracture(5,2); +d3intersection=-1000*ones(1000,3);%用-1000做标识 +% [I,J]=find(d3intersection==-1000);%用-1000做标识 +% n=min(I); +d2intersection=zeros(50,5); +n=1; +i=1; +unknown=ones(2,1); +% 判断与x方向坐标线相交情况 +%由于网格间距很可能不相等,故进行处理 + + +for wang=1:ny+1 + y=yrao(1,wang); + for dai=1:nz+1 + z=zrao(1,dai); + A=[t1(2),t2(2); + t1(3),t2(3)]; + b=[y;z]-[t0(2);t0(3)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)>=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + x=[t1(1),t2(1)]*unknown+t0(1); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + else + if((t1(2)~=0)) + if(((t1(2)*z)==(t1(3)*y))&&(y/t1(2)>=umin)&&(y/t1(2)<=umax)) + intersecxmin=t1(1)*y/t1(2)+t2(1)*vmin; + intersecxmax=t1(1)*y/t1(2)+t2(1)*vmax; + d2intersection(i,:)=[-1,y,z,intersecxmin,intersecxmax]+[0,t0(2),t0(3),t0(1),t0(1)]; + i=i+1; + end + else if(t1(3)~=0) + if(((t1(2)*z)==(t1(3)*y))&&(z/t1(3)>=umin)&&(z/t1(3)<=umax)) + intersecxmin=t1(1)*z/t1(3)+t2(1)*vmin; + intersecxmax=t1(1)*z/t1(3)+t2(1)*vmax; + d2intersection(i,:)=[-1,y,z,intersecxmin,intersecxmax]+[0,t0(2),t0(3),t0(1),t0(1)]; + i=i+1; + end + else if(t2(2)~=0) + if(((t2(2)*z)==(t2(3)*y))&&(y/t2(2)>=vmin)&&(y/t2(2)<=vmax)) + intersecxmin=t1(1)*umin+t2(1)*y/t2(2); + intersecxmax=t1(1)*umax+t2(1)*y/t2(2); + d2intersection(i,:)=[-1,y,z,intersecxmin,intersecxmax]+[0,t0(2),t0(3),t0(1),t0(1)]; + i=i+1; + end + else + if(((t2(2)*z)==(t2(3)*y))&&(z/t2(3)>=vmin)&&(z/t2(3)<=vmax)) + intersecxmin=t1(1)*umin+t2(1)*z/t2(3); + intersecxmax=t1(1)*umax+t2(1)*z/t2(3); + d2intersection(i,:)=[-1,y,z,intersecxmin,intersecxmax]+[0,t0(2),t0(3),t0(1),t0(1)]; + i=i+1; + end + end + end + end + end + end +end + +% 判断与y方向坐标线相交情况 +for wang=1:nx+1 + x=xrao(1,wang); + for dai=1:nz+1 + z=zrao(1,dai); + A=[t1(1),t2(1); + t1(3),t2(3)]; + b=[x;z]-[t0(1);t0(3)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)>=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + y=[t1(2),t2(2)]*unknown+t0(2); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + else + if((t1(1)~=0)) + if(((t1(1)*z)==(t1(3)*x))&&(x/t1(1)>=umin)&&(x/t1(1)<=umax)) + intersecymin=t1(2)*x/t1(1)+t2(2)*vmin; + intersecymax=t1(2)*x/t1(1)+t2(2)*vmax; + d2intersection(i,:)=[x,-1,z,intersecymin,intersecymax]+[t0(1),0,t0(3),t0(2),t0(2)]; + i=i+1; + end + else if(t1(3)~=0) + if(((t1(1)*z)==(t1(3)*x))&&(z/t1(3)>=umin)&&(z/t1(3)<=umax)) + intersecymin=t1(2)*z/t1(3)+t2(2)*vmin; + intersecymax=t1(2)*z/t1(3)+t2(2)*vmax; + d2intersection(i,:)=[x,-1,z,intersecymin,intersecymax]+[t0(1),0,t0(3),t0(2),t0(2)]; + i=i+1; + end + else if(t2(1)~=0) + if(((t2(1)*z)==(t2(3)*x))&&(x/t2(1)>=vmin)&&(x/t2(1)<=vmax)) + intersecymin=t1(2)*umin+t2(2)*x/t2(1); + intersecymax=t1(2)*umax+t2(2)*x/t2(1); + d2intersection(i,:)=[x,-1,z,intersecymin,intersecymax]+[t0(1),0,t0(3),t0(2),t0(2)]; + i=i+1; + end + else + if(((t2(1)*z)==(t2(3)*x))&&(z/t2(3)>=vmin)&&(z/t2(3)<=vmax)) + intersecymin=t1(2)*umin+t2(2)*z/t2(3); + intersecymax=t1(2)*umax+t2(2)*z/t2(3); + d2intersection(i,:)=[x,-1,z,intersecymin,intersecymax]+[t0(1),0,t0(3),t0(2),t0(2)]; + i=i+1; + end + end + end + end + end + end +end + +%判断与z方向坐标线相交情况 +for wang=1:nx+1 + x=xrao(1,wang); + for dai=1:ny+1 + y=yrao(1,dai); + A=[t1(1),t2(1); + t1(2),t2(2)]; + b=[x;y]-[t0(1);t0(2)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)>=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + z=[t1(3),t2(3)]*unknown+t0(3); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + else + if((t1(1)~=0)) + if(((t1(1)*y)==(t1(2)*x))&&(x/t1(1)>=umin)&&(x/t1(1)<=umax)) + interseczmin=t1(3)*x/t1(1)+t2(3)*vmin; + interseczmax=t1(3)*x/t1(1)+t2(3)*vmax; + d2intersection(i,:)=[x,y,-1,interseczmin,interseczmax]+[t0(1),t0(2),0,t0(3),t0(3)]; + i=i+1; + end + else if(t1(2)~=0) + if(((t1(1)*y)==(t1(2)*x))&&(y/t1(2)>=umin)&&(y/t1(2)<=umax)) + interseczmin=t1(3)*y/t1(2)+t2(3)*vmin; + interseczmax=t1(3)*y/t1(2)+t2(3)*vmax; + d2intersection(i,:)=[x,y,-1,interseczmin,interseczmax]+[t0(1),t0(2),0,t0(3),t0(3)]; + i=i+1; + end + else if(t2(1)~=0) + if(((t2(1)*y)==(t2(2)*x))&&(x/t2(1)>=vmin)&&(x/t2(1)<=vmax)) + interseczmin=t1(3)*umin+t2(3)*x/t2(1); + interseczmax=t1(3)*umax+t2(3)*x/t2(1); + d2intersection(i,:)=[x,y,-1,interseczmin,interseczmax]+[t0(1),t0(2),0,t0(3),t0(3)]; + i=i+1; + end + else + if(((t2(1)*y)==(t2(2)*x))&&(y/t2(2)>=vmin)&&(y/t2(2)<=vmax)) + interseczmin=t1(3)*umin+t2(3)*y/t2(2); + interseczmax=t1(3)*umax+t2(3)*y/t2(2); + d2intersection(i,:)=[x,y,-1,interseczmin,interseczmax]+[t0(1),t0(2),0,t0(3),t0(3)]; + i=i+1; + end + end + end + end + end + end +end +% 删去相同的线段 +d2intersection=unique(d2intersection, 'rows', 'stable'); +m=size(d2intersection,1); +for i=1:m + + if(d2intersection(i,1)==-1) +d3intersection(n,:)=[d2intersection(i,4),d2intersection(i,2),d2intersection(i,3)];n=n+1; +d3intersection(n,:)=[d2intersection(i,5),d2intersection(i,2),d2intersection(i,3)];n=n+1; + for wang=1:nx+1 + j=xrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) + d3intersection(n,:)=[j,d2intersection(i,2),d2intersection(i,3)];n=n+1; + end + end + end + + if(d2intersection(i,2)==-1) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,4),d2intersection(i,3)];n=n+1; +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,5),d2intersection(i,3)];n=n+1; + for wang=1:ny+1 + j=yrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) + d3intersection(n,:)=[d2intersection(i,1),j,d2intersection(i,3)];n=n+1; + end + end + end + + if(d2intersection(i,3)==-1) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),d2intersection(i,4)];n=n+1; +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),d2intersection(i,5)];n=n+1; + for wang=1:nz+1 + j=zrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),j];n=n+1; + end + end + end +end +d3intersection=unique(d3intersection, 'rows', 'stable'); +[I,J]=find(d3intersection==-1000); +d3intersection(I,:)=[]; + + +% A=[t1(1),t2(1); +% t1(2),t2(2); +% t1(3),t2(3)]; +% b=[0;0;0]; +% x=A\b; +% if((x(1)>umax)||(x(1)vmax)||(x(2)=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + x=[t1(1),t2(1)]*unknown+t0(1); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + %当A奇异时,当有无穷多组解时,可以知道 + %该坐标线所在的方向向量包含在该裂缝平面内,故该条坐标线上的所有点的矢径减去改裂缝面的t0向量后,必能表示成t1和t2的线性组合 + %因此,可以立刻求出该点对应的u,v值,然后加以判断是否符合u,v的范围, + %当无解时,用上述方法亦可判断出。 + else + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([0,y,z]-t0)'; + tests=A\test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:nx+1 + xtest=xrao(1,huihui); + vectest=[xtest,y,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + intersecxmin=xtest;flag=flag+1; break; + end + end + for huihui=nx+1:-1:1 + xtest=xrao(1,huihui); + vectest=[xtest,y,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + intersecxmax=xtest; flag=flag+1; break; + end + end + if flag==2 + d2intersection(i,:)=[-1,y,z,intersecxmin,intersecxmax];i=i+1; + end + end + end + end +end + + + + + + +% 判断与y方向坐标线相交情况 +for wang=1:nx+1 + x=xrao(1,wang); + for dai=1:nz+1 + z=zrao(1,dai); + A=[t1(1),t2(1); + t1(3),t2(3)]; + b=[x;z]-[t0(1);t0(3)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)>=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + y=[t1(2),t2(2)]*unknown+t0(2); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + else + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([x,0,z]-t0)'; + tests=A\test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:ny+1 + ytest=yrao(1,huihui); + vectest=[x,ytest,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + intersecymin=ytest; flag=flag+1; break; + end + end + for huihui=ny+1:-1:1 + ytest=yrao(1,huihui); + vectest=[x,ytest,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + intersecymax=ytest;flag=flag+1; break; + end + end + if flag==2 + d2intersection(i,:)=[x,-1,z,intersecymin,intersecymax];i=i+1; + end + + + end + end + end +end + + +%判断与z方向坐标线相交情况 +for wang=1:nx+1 + x=xrao(1,wang); + for dai=1:ny+1 + y=yrao(1,dai); + A=[t1(1),t2(1); + t1(2),t2(2)]; + b=[x;y]-[t0(1);t0(2)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)>=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + z=[t1(3),t2(3)]*unknown+t0(3); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + else + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([x,y,0]-t0)'; + tests=A\test; + hen=A*tests-test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:nz+1 + + ztest=zrao(1,huihui); + vectest=[x,y,ztest]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + interseczmin=ztest;flag=flag+1; break; + end + end + for huihui=nz+1:-1:1 + ztest=zrao(1,huihui); + vectest=[x,y,ztest]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + interseczmax=ztest;flag=flag+1; break; + end + end + if flag==2 + d2intersection(i,:)=[x,y,-1,interseczmin,interseczmax];i=i+1; + end + + + end + end + end +end + + +% 删去相同的线段及零线段 +d2intersection=unique(d2intersection, 'rows', 'stable'); +m=size(d2intersection,1); +for i=1:m + + if(d2intersection(i,1)==-1) +d3intersection(n,:)=[d2intersection(i,4),d2intersection(i,2),d2intersection(i,3)];n=n+1; +d3intersection(n,:)=[d2intersection(i,5),d2intersection(i,2),d2intersection(i,3)];n=n+1; + for wang=1:nx+1 + j=xrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) + d3intersection(n,:)=[j,d2intersection(i,2),d2intersection(i,3)];n=n+1; + end + end + end + + if(d2intersection(i,2)==-1) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,4),d2intersection(i,3)];n=n+1; +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,5),d2intersection(i,3)];n=n+1; + for wang=1:ny+1 + j=yrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) + d3intersection(n,:)=[d2intersection(i,1),j,d2intersection(i,3)];n=n+1; + end + end + end + + if(d2intersection(i,3)==-1) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),d2intersection(i,4)];n=n+1; +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),d2intersection(i,5)];n=n+1; + for wang=1:nz+1 + j=zrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),j];n=n+1; + end + end + end +end +d3intersection=unique(d3intersection, 'rows', 'stable'); +[I,J]=find(d3intersection==-1000); +d3intersection(I,:)=[]; + + +% A=[t1(1),t2(1); +% t1(2),t2(2); +% t1(3),t2(3)]; +% b=[0;0;0]; +% x=A\b; +% if((x(1)>umax)||(x(1)vmax)||(x(2)=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + x=[t1(1),t2(1)]*unknown+t0(1); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + %当A奇异时,当有无穷多组解时,可以知道 + %该坐标线所在的方向向量包含在该裂缝平面内,故该条坐标线上的所有点的矢径减去改裂缝面的t0向量后,必能表示成t1和t2的线性组合 + %因此,可以立刻求出该点对应的u,v值,然后加以判断是否符合u,v的范围, + %当无解时,用上述方法亦可判断出。 + else + + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([0,y,z]-t0)'; + tests=A\test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:nx+1 + xtest=xrao(1,huihui); + vectest=[xtest,y,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + + xxtest=xtest-0.01;vvectest=[xxtest,y,z];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==1 + intersecxmin=xtest;flag=flag+1; break; + else xlow=xrao(1,huihui-1); xhigh=xtest; + + end + while (xhigh-xlow>=tolerance) + xxtest=1/2*(xlow+xhigh); + vvectest=[xxtest,y,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + xhigh=xxtest; xlow=xlow; + else xlow=xxtest; xhigh=xhigh; + end + end + intersecxmin=xhigh;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecxmin=xtest;flag=flag+1; break; + end + end + end + + for huihui=nx+1:-1:1 + xtest=xrao(1,huihui); + vectest=[xtest,y,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + xxtest=xtest+0.01;vvectest=[xxtest,y,z];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==(nx+1) + intersecxmax=xtest;flag=flag+1; break; + else xlow=xtest; xhigh=xrao(1,huihui+1); + + end + while (xhigh-xlow>=tolerance) + xxtest=1/2*(xlow+xhigh); + vvectest=[xxtest,y,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + xhigh=xhigh; xlow=xxtest; + else xlow=xlow; xhigh=xxtest; + end + end + intersecxmax=xlow;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecxmax=xtest;flag=flag+1; break; + end + end + end + + if flag==2 + d2intersection(i,:)=[-1,y,z,intersecxmin,intersecxmax];i=i+1; + end + end + end + end +end + + + + + + +% 判断与y方向坐标线相交情况 +for wang=1:nx+1 + x=xrao(1,wang); + for dai=1:nz+1 + z=zrao(1,dai); + A=[t1(1),t2(1); + t1(3),t2(3)]; + b=[x;z]-[t0(1);t0(3)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)>=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + y=[t1(2),t2(2)]*unknown+t0(2); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + else + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([x,0,z]-t0)'; + tests=A\test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:ny+1 + ytest=yrao(1,huihui); + vectest=[x,ytest,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + yytest=ytest-0.01;vvectest=[x,yytest,z];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==1 + intersecymin=ytest;flag=flag+1; break; + else ylow=yrao(1,huihui-1); yhigh=ytest; + + end + while (yhigh-ylow>=tolerance) + yytest=1/2*(ylow+yhigh); + vvectest=[x,yytest,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + yhigh=yytest; ylow=ylow; + else ylow=yytest; yhigh=yhigh; + end + end + intersecymin=yhigh;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecymin=ytest;flag=flag+1; break; + end + end + end + + for huihui=ny+1:-1:1 + ytest=yrao(1,huihui); + vectest=[x,ytest,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + yytest=ytest+0.01;vvectest=[x,yytest,z];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==(ny+1) + intersecymax=ytest;flag=flag+1; break; + else ylow=ytest; yhigh=yrao(1,huihui+1); + + end + while (yhigh-ylow>=tolerance) + yytest=1/2*(ylow+yhigh); + vvectest=[x,yytest,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + yhigh=yhigh; ylow=yytest; + else ylow=ylow; yhigh=yytest; + end + end + intersecymax=ylow;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecymax=ytest;flag=flag+1; break; + end + end + end + + if flag==2 + d2intersection(i,:)=[x,-1,z,intersecymin,intersecymax];i=i+1; + end + + + end + end + end +end + + +%判断与z方向坐标线相交情况 +for wang=1:nx+1 + x=xrao(1,wang); + for dai=1:ny+1 + y=yrao(1,dai); + A=[t1(1),t2(1); + t1(2),t2(2)]; + b=[x;y]-[t0(1);t0(2)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)>=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + z=[t1(3),t2(3)]*unknown+t0(3); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + else + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([x,y,0]-t0)'; + tests=A\test; + hen=A*tests-test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:nz+1 + + ztest=zrao(1,huihui); + vectest=[x,y,ztest]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + zztest=ztest-0.01;vvectest=[x,y,zztest];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==1 + interseczmin=ztest;flag=flag+1; break; + else zlow=zrao(1,huihui-1); zhigh=ztest; + + end + while (zhigh-zlow>=tolerance) + zztest=1/2*(zlow+zhigh); + vvectest=[x,y,zztest]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + zhigh=zztest; zlow=zlow; + else zlow=zztest; zhigh=zhigh; + end + end + interseczmin=zhigh;flag=flag+1; break; + else %表明这个节点就是要找的点 + interseczmin=ztest;flag=flag+1; break; + end + end + end + + for huihui=nz+1:-1:1 + ztest=zrao(1,huihui); + vectest=[x,y,ztest]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + zztest=ztest+0.01;vvectest=[x,y,zztest];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==(nz+1) + interseczmax=ztest;flag=flag+1; break; + else zlow=ztest; zhigh=zrao(1,huihui+1); + + end + while (zhigh-zlow>=tolerance) + zztest=1/2*(zlow+zhigh); + vvectest=[x,y,zztest]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + zhigh=zhigh; zlow=zztest; + else zlow=zlow; zhigh=zztest; + end + end + interseczmax=zlow;flag=flag+1; break; + else %表明这个节点就是要找的点 + interseczmax=ztest;flag=flag+1; break; + end + end + end + + if flag==2 + d2intersection(i,:)=[x,y,-1,interseczmin,interseczmax];i=i+1; + end + + + end + end + end +end + +%% 求解裂缝面边界与基质网格面的交点 +% 当u=umin时 +%point=t0+umin*t1+v*t2; +%与y-z面的交点 +boundary=[umin,umax,vmin,vmax]; +for xiang=1:4 + +if xiang<=2 %说明定u的取值 +for hui=1:nx+1 + if t2(1)==0 break; + else + x=xrao(1,hui); + v=(x-t1(1)*boundary(xiang)-t0(1))/t2(1); + if (v>=vmin)&&(v<=vmax) + point=t0+boundary(xiang)*t1+v*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +else %定v的取值 +for hui=1:nx+1 + if t1(1)==0 break; + else + x=xrao(1,hui); + u=(x-t2(1)*boundary(xiang)-t0(1))/t1(1); + if (u>=umin)&&(u<=umax) + point=t0+u*t1+boundary(xiang)*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +end +end + +%与x-z面的交点 +boundary=[umin,umax,vmin,vmax]; +for xiang=1:4 + +if xiang<=2 %说明定u的取值 +for hui=1:ny+1 + if t2(2)==0 break; + else + y=yrao(1,hui); + v=(y-t1(2)*boundary(xiang)-t0(2))/t2(2); + if (v>=vmin)&&(v<=vmax) + point=t0+boundary(xiang)*t1+v*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +else %定v的取值 +for hui=1:ny+1 + if t1(2)==0 break; + else + y=yrao(1,hui); + u=(y-t2(2)*boundary(xiang)-t0(2))/t1(2); + if (u>=umin)&&(u<=umax) + point=t0+u*t1+boundary(xiang)*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +end +end + +%与x-y面的交点 +boundary=[umin,umax,vmin,vmax]; +for xiang=1:4 + +if xiang<=2 %说明定u的取值 +for hui=1:nz+1 + if t2(3)==0 break; + else + z=zrao(1,hui); + v=(z-t1(3)*boundary(xiang)-t0(3))/t2(3); + if (v>=vmin)&&(v<=vmax) + point=t0+boundary(xiang)*t1+v*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +else %定v的取值 +for hui=1:nz+1 + if t1(3)==0 break; + else + z=zrao(1,hui); + u=(z-t2(3)*boundary(xiang)-t0(3))/t1(3); + if (u>=umin)&&(u<=umax) + point=t0+u*t1+boundary(xiang)*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +end +end + + + + + + + +% 删去相同的线段及零线段 +d2intersection=unique(d2intersection, 'rows', 'stable'); +m=size(d2intersection,1); +for i=1:m + + if(d2intersection(i,1)==-1) +d3intersection(n,:)=[d2intersection(i,4),d2intersection(i,2),d2intersection(i,3)];n=n+1; +d3intersection(n,:)=[d2intersection(i,5),d2intersection(i,2),d2intersection(i,3)];n=n+1; + for wang=1:nx+1 + j=xrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) + d3intersection(n,:)=[j,d2intersection(i,2),d2intersection(i,3)];n=n+1; + end + end + end + + if(d2intersection(i,2)==-1) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,4),d2intersection(i,3)];n=n+1; +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,5),d2intersection(i,3)];n=n+1; + for wang=1:ny+1 + j=yrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) + d3intersection(n,:)=[d2intersection(i,1),j,d2intersection(i,3)];n=n+1; + end + end + end + + if(d2intersection(i,3)==-1) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),d2intersection(i,4)];n=n+1; +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),d2intersection(i,5)];n=n+1; + for wang=1:nz+1 + j=zrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),j];n=n+1; + end + end + end +end +d3intersection=unique(d3intersection, 'rows', 'stable'); +[I,J]=find(d3intersection==-1000); +d3intersection(I,:)=[]; + +record=[]; +kitty=size(d3intersection,1); +for i=1:kitty-1 + for j=i+1:kitty + if (norm(d3intersection(i,:)-d3intersection(j,:))<=1e-1)%该数值与网格属性有关 + record=[record;j]; + end + end +end +record=unique(record, 'rows', 'stable'); +d3intersection(record,:)=[]; + + + +% A=[t1(1),t2(1); +% t1(2),t2(2); +% t1(3),t2(3)]; +% b=[0;0;0]; +% x=A\b; +% if((x(1)>umax)||(x(1)vmax)||(x(2)=tolerance) + xxtest=1/2*(xlow+xhigh); + vvectest=[xxtest,y,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2)<=1) + xhigh=xxtest; xlow=xlow; + else xlow=xxtest; xhigh=xhigh; + end + end + intersecxmin=xhigh;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecxmin=xtest;flag=flag+1; break; + end + end + end + + for huihui=nx+1:-1:1 + xtest=xrao(1,huihui); + vectest=[xtest,y,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1,1)^2/urao^2+unknown(2,1)^2/vdai^2)<=1) + xxtest=xtest+0.01;vvectest=[xxtest,y,z];uunknown=A\(vvectest-t0)'; + if (uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2<=1)%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==(nx+1) + intersecxmax=xtest;flag=flag+1; break; + else xlow=xtest; xhigh=xrao(1,huihui+1); + + end + while (xhigh-xlow>=tolerance) + xxtest=1/2*(xlow+xhigh); + vvectest=[xxtest,y,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2)<=1) + xhigh=xhigh; xlow=xxtest; + else xlow=xlow; xhigh=xxtest; + end + end + intersecxmax=xlow;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecxmax=xtest;flag=flag+1; break; + end + end + end + + if flag==2 + d2intersection(i,:)=[-1,y,z,intersecxmin,intersecxmax];i=i+1; + end + end + end + end +end + + + + + + +% 判断与y方向坐标线相交情况 +for wang=1:nx+1 + x=xrao(1,wang); + for dai=1:nz+1 + z=zrao(1,dai); + A=[t1(1),t2(1); + t1(3),t2(3)]; + b=[x;z]-[t0(1);t0(3)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)^2/urao^2+unknown(2,1)^2/vdai^2)<=1) + y=[t1(2),t2(2)]*unknown+t0(2); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + else + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([x,0,z]-t0)'; + tests=A\test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:ny+1 + ytest=yrao(1,huihui); + vectest=[x,ytest,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1,1)^2/urao^2+unknown(2,1)^2/vdai^2)<=1) + yytest=ytest-0.01;vvectest=[x,yytest,z];uunknown=A\(vvectest-t0)'; + if ((uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2)<=1)%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==1 + intersecymin=ytest;flag=flag+1; break; + else ylow=yrao(1,huihui-1); yhigh=ytest; + + end + while (yhigh-ylow>=tolerance) + yytest=1/2*(ylow+yhigh); + vvectest=[x,yytest,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2)<=1) + yhigh=yytest; ylow=ylow; + else ylow=yytest; yhigh=yhigh; + end + end + intersecymin=yhigh;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecymin=ytest;flag=flag+1; break; + end + end + end + + for huihui=ny+1:-1:1 + ytest=yrao(1,huihui); + vectest=[x,ytest,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1,1)^2/urao^2+unknown(2,1)^2/vdai^2)<=1) + yytest=ytest+0.01;vvectest=[x,yytest,z];uunknown=A\(vvectest-t0)'; + if ((uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2)<=1)%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==(ny+1) + intersecymax=ytest;flag=flag+1; break; + else ylow=ytest; yhigh=yrao(1,huihui+1); + + end + while (yhigh-ylow>=tolerance) + yytest=1/2*(ylow+yhigh); + vvectest=[x,yytest,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2)<=1) + yhigh=yhigh; ylow=yytest; + else ylow=ylow; yhigh=yytest; + end + end + intersecymax=ylow;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecymax=ytest;flag=flag+1; break; + end + end + end + + if flag==2 + d2intersection(i,:)=[x,-1,z,intersecymin,intersecymax];i=i+1; + end + + + end + end + end +end + + +%判断与z方向坐标线相交情况 +for wang=1:nx+1 + x=xrao(1,wang); + for dai=1:ny+1 + y=yrao(1,dai); + A=[t1(1),t2(1); + t1(2),t2(2)]; + b=[x;y]-[t0(1);t0(2)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)^2/urao^2+unknown(2,1)^2/vdai^2)<=1) + z=[t1(3),t2(3)]*unknown+t0(3); + d3intersection(n,:)=[x,y,z]; + n=n+1; + end + else + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([x,y,0]-t0)'; + tests=A\test; + hen=A*tests-test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:nz+1 + + ztest=zrao(1,huihui); + vectest=[x,y,ztest]; + unknown=A\(vectest-t0)'; + if ((unknown(1,1)^2/urao^2+unknown(2,1)^2/vdai^2)<=1) + zztest=ztest-0.01;vvectest=[x,y,zztest];uunknown=A\(vvectest-t0)'; + if ((uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2)<=1)%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==1 + interseczmin=ztest;flag=flag+1; break; + else zlow=zrao(1,huihui-1); zhigh=ztest; + + end + while (zhigh-zlow>=tolerance) + zztest=1/2*(zlow+zhigh); + vvectest=[x,y,zztest]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2)<=1) + zhigh=zztest; zlow=zlow; + else zlow=zztest; zhigh=zhigh; + end + end + interseczmin=zhigh;flag=flag+1; break; + else %表明这个节点就是要找的点 + interseczmin=ztest;flag=flag+1; break; + end + end + end + + for huihui=nz+1:-1:1 + ztest=zrao(1,huihui); + vectest=[x,y,ztest]; + unknown=A\(vectest-t0)'; + if ((unknown(1,1)^2/urao^2+unknown(2,1)^2/vdai^2)<=1) + zztest=ztest+0.01;vvectest=[x,y,zztest];uunknown=A\(vvectest-t0)'; + if ((uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2)<=1)%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==(nz+1) + interseczmax=ztest;flag=flag+1; break; + else zlow=ztest; zhigh=zrao(1,huihui+1); + + end + while (zhigh-zlow>=tolerance) + zztest=1/2*(zlow+zhigh); + vvectest=[x,y,zztest]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1,1)^2/urao^2+uunknown(2,1)^2/vdai^2)<=1) + zhigh=zhigh; zlow=zztest; + else zlow=zlow; zhigh=zztest; + end + end + interseczmax=zlow;flag=flag+1; break; + else %表明这个节点就是要找的点 + interseczmax=ztest;flag=flag+1; break; + end + end + end + + if flag==2 + d2intersection(i,:)=[x,y,-1,interseczmin,interseczmax];i=i+1; + end + + + end + end + end +end + +%% 求解裂缝面边界与基质网格面的交点 +% 当u=umin时 +%point=t0+umin*t1+v*t2; +%与y-z面的交点 + +% 目前仅限于alfa2 向量只有z方向分量时 +%alfa1 向量没有z方向分量 + +%对于yz网格面 + +for hui=1:nx+1 + x=xrao(1,hui); + if t1(1)==0 break; %因为一般不将裂缝面设置得与坐标面重合 + else + u=(x-t0(1))/t1(1); + if (u<=urao) &&(u>=-urao) + v1=sqrt((1-u^2/urao^2)*vdai^2); + d3intersection(n,:)=t0+u*t1+v1*t2;n=n+1; + v2=-sqrt((1-u^2/urao^2)*vdai^2); + d3intersection(n,:)=t0+u*t1+v2*t2;n=n+1; + end + end +end + +% 对于xz网格面 + +for hui=1:ny+1 + y=yrao(1,hui); + if t1(2)==0 break; %因为一般不将裂缝面设置得与坐标面重合 + else + u=(y-t0(2))/t1(2); + if (u<=urao) && (u>=-urao) + v1=sqrt((1-u^2/urao^2)*vdai^2); + d3intersection(n,:)=t0+u*t1+v1*t2;n=n+1; + v2=-sqrt((1-u^2/urao^2)*vdai^2); + d3intersection(n,:)=t0+u*t1+v2*t2;n=n+1; + end + end +end + +% 对于xy网格面 +% 按照前述假设,t2向量才有z方向的分量 +for hui=1:nz+1 + z=zrao(1,hui); + if t2(3)==0 break; %因为一般不将裂缝面设置得与坐标面重合 + else + v=(z-t0(3))/t1(3); + if (v<=vdai) && (v>=-vdai) + u1=sqrt((1-v^2/vdai^2)*urao^2); + d3intersection(n,:)=t0+u1*t1+v*t2;n=n+1; + u2=-sqrt((1-v^2/vdai^2)*urao^2); + d3intersection(n,:)=t0+u2*t1+v*t2;n=n+1; + end + end +end + + + + +% 删去相同的线段及零线段 +d2intersection=unique(d2intersection, 'rows', 'stable'); +m=size(d2intersection,1); +for i=1:m + + if(d2intersection(i,1)==-1) +d3intersection(n,:)=[d2intersection(i,4),d2intersection(i,2),d2intersection(i,3)];n=n+1; +d3intersection(n,:)=[d2intersection(i,5),d2intersection(i,2),d2intersection(i,3)];n=n+1; + for wang=1:nx+1 + j=xrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) + d3intersection(n,:)=[j,d2intersection(i,2),d2intersection(i,3)];n=n+1; + end + end + end + + if(d2intersection(i,2)==-1) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,4),d2intersection(i,3)];n=n+1; +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,5),d2intersection(i,3)];n=n+1; + for wang=1:ny+1 + j=yrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) + d3intersection(n,:)=[d2intersection(i,1),j,d2intersection(i,3)];n=n+1; + end + end + end + + if(d2intersection(i,3)==-1) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),d2intersection(i,4)];n=n+1; +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),d2intersection(i,5)];n=n+1; + for wang=1:nz+1 + j=zrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),j];n=n+1; + end + end + end +end +d3intersection=unique(d3intersection, 'rows', 'stable'); +[I,J]=find(d3intersection==-1000); +d3intersection(I,:)=[]; + +record=[]; +kitty=size(d3intersection,1); +for i=1:kitty-1 + for j=i+1:kitty + if (norm(d3intersection(i,:)-d3intersection(j,:))<=1e-1)%该数值与网格属性有关 + record=[record;j]; + end + end +end +record=unique(record, 'rows', 'stable'); +d3intersection(record,:)=[]; + + + +% A=[t1(1),t2(1); +% t1(2),t2(2); +% t1(3),t2(3)]; +% b=[0;0;0]; +% x=A\b; +% if((x(1)>umax)||(x(1)vmax)||(x(2)=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + x=[t1(1),t2(1)]*unknown+t0(1); +% if x<=max(xrao) && x>=min(xrao) + d3intersection(n,:)=[x,y,z]; + n=n+1; +% end + end + %当A奇异时,当有无穷多组解时,可以知道 + %该坐标线所在的方向向量包含在该裂缝平面内,故该条坐标线上的所有点的矢径减去改裂缝面的t0向量后,必能表示成t1和t2的线性组合 + %因此,可以立刻求出该点对应的u,v值,然后加以判断是否符合u,v的范围, + %当无解时,用上述方法亦可判断出。 + else + + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([0,y,z]-t0)'; + tests=A\test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:nx+1 + xtest=xrao(1,huihui); + vectest=[xtest,y,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + + xxtest=xtest-0.01;vvectest=[xxtest,y,z];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==1 + intersecxmin=xtest;flag=flag+1; break; + else xlow=xrao(1,huihui-1); xhigh=xtest; + + end + while (xhigh-xlow>=tolerance) + xxtest=1/2*(xlow+xhigh); + vvectest=[xxtest,y,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + xhigh=xxtest; xlow=xlow; + else xlow=xxtest; xhigh=xhigh; + end + end + intersecxmin=xhigh;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecxmin=xtest;flag=flag+1; break; + end + end + end + + for huihui=nx+1:-1:1 + xtest=xrao(1,huihui); + vectest=[xtest,y,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + xxtest=xtest+0.01;vvectest=[xxtest,y,z];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==(nx+1) + intersecxmax=xtest;flag=flag+1; break; + else xlow=xtest; xhigh=xrao(1,huihui+1); + + end + while (xhigh-xlow>=tolerance) + xxtest=1/2*(xlow+xhigh); + vvectest=[xxtest,y,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + xhigh=xhigh; xlow=xxtest; + else xlow=xlow; xhigh=xxtest; + end + end + intersecxmax=xlow;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecxmax=xtest;flag=flag+1; break; + end + end + end + + if flag==2 + d2intersection(i,:)=[-1,y,z,intersecxmin,intersecxmax];i=i+1; + end + end + end + end +end + + + + + + +% 判断与y方向坐标线相交情况 +for wang=1:nx+1 + x=xrao(1,wang); + for dai=1:nz+1 + z=zrao(1,dai); + A=[t1(1),t2(1); + t1(3),t2(3)]; + b=[x;z]-[t0(1);t0(3)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)>=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + y=[t1(2),t2(2)]*unknown+t0(2); +% if y<=max(yrao) && y>=min(yrao) + d3intersection(n,:)=[x,y,z]; + n=n+1; +% end + end + else + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([x,0,z]-t0)'; + tests=A\test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:ny+1 + ytest=yrao(1,huihui); + vectest=[x,ytest,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + yytest=ytest-0.01;vvectest=[x,yytest,z];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==1 + intersecymin=ytest;flag=flag+1; break; + else ylow=yrao(1,huihui-1); yhigh=ytest; + + end + while (yhigh-ylow>=tolerance) + yytest=1/2*(ylow+yhigh); + vvectest=[x,yytest,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + yhigh=yytest; ylow=ylow; + else ylow=yytest; yhigh=yhigh; + end + end + intersecymin=yhigh;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecymin=ytest;flag=flag+1; break; + end + end + end + + for huihui=ny+1:-1:1 + ytest=yrao(1,huihui); + vectest=[x,ytest,z]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + yytest=ytest+0.01;vvectest=[x,yytest,z];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==(ny+1) + intersecymax=ytest;flag=flag+1; break; + else ylow=ytest; yhigh=yrao(1,huihui+1); + + end + while (yhigh-ylow>=tolerance) + yytest=1/2*(ylow+yhigh); + vvectest=[x,yytest,z]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + yhigh=yhigh; ylow=yytest; + else ylow=ylow; yhigh=yytest; + end + end + intersecymax=ylow;flag=flag+1; break; + else %表明这个节点就是要找的点 + intersecymax=ytest;flag=flag+1; break; + end + end + end + + if flag==2 + d2intersection(i,:)=[x,-1,z,intersecymin,intersecymax];i=i+1; + end + + + end + end + end +end + + +%判断与z方向坐标线相交情况 +for wang=1:nx+1 + x=xrao(1,wang); + for dai=1:ny+1 + y=yrao(1,dai); + A=[t1(1),t2(1); + t1(2),t2(2)]; + b=[x;y]-[t0(1);t0(2)]; + if(det(A)~=0) + unknown=A\b; + if ((unknown(1,1)>=umin)&&(unknown(1,1)<=umax)&&(unknown(2,1)>=vmin)&&(unknown(2,1)<=vmax)) + z=[t1(3),t2(3)]*unknown+t0(3); +% if z<=max(zrao) && z>=min(zrao) + d3intersection(n,:)=[x,y,z]; + n=n+1; +% end + end + else + A=[t1(1),t2(1), + t1(2),t2(2); + t1(3),t2(3)]; + test=([x,y,0]-t0)'; + tests=A\test; + hen=A*tests-test; + if norm(A*tests-test)<=1e-6 %说明这条坐标线在该裂缝面上 + flag=0; + for huihui=1:nz+1 + + ztest=zrao(1,huihui); + vectest=[x,y,ztest]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + zztest=ztest-0.01;vvectest=[x,y,zztest];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==1 + interseczmin=ztest;flag=flag+1; break; + else zlow=zrao(1,huihui-1); zhigh=ztest; + + end + while (zhigh-zlow>=tolerance) + zztest=1/2*(zlow+zhigh); + vvectest=[x,y,zztest]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + zhigh=zztest; zlow=zlow; + else zlow=zztest; zhigh=zhigh; + end + end + interseczmin=zhigh;flag=flag+1; break; + else %表明这个节点就是要找的点 + interseczmin=ztest;flag=flag+1; break; + end + end + end + + for huihui=nz+1:-1:1 + ztest=zrao(1,huihui); + vectest=[x,y,ztest]; + unknown=A\(vectest-t0)'; + if ((unknown(1)>=umin)&&(unknown(1)<=umax)&&(unknown(2)>=vmin)&&(unknown(2)<=vmax)) + zztest=ztest+0.01;vvectest=[x,y,zztest];uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax))%表明并不是正好是这个x,需要在区间内搜寻准确点 + + if huihui==(nz+1) + interseczmax=ztest;flag=flag+1; break; + else zlow=ztest; zhigh=zrao(1,huihui+1); + + end + while (zhigh-zlow>=tolerance) + zztest=1/2*(zlow+zhigh); + vvectest=[x,y,zztest]; + uunknown=A\(vvectest-t0)'; + if ((uunknown(1)>=umin)&&(uunknown(1)<=umax)&&(uunknown(2)>=vmin)&&(uunknown(2)<=vmax)) + zhigh=zhigh; zlow=zztest; + else zlow=zlow; zhigh=zztest; + end + end + interseczmax=zlow;flag=flag+1; break; + else %表明这个节点就是要找的点 + interseczmax=ztest;flag=flag+1; break; + end + end + end + + if flag==2 + d2intersection(i,:)=[x,y,-1,interseczmin,interseczmax];i=i+1; + end + + + end + end + end +end + +%% 求解裂缝面边界与基质网格面的交点 +% 当u=umin时 +%point=t0+umin*t1+v*t2; +%与y-z面的交点 +boundary=[umin,umax,vmin,vmax]; +for xiang=1:4 + +if xiang<=2 %说明定u的取值 +for hui=1:nx+1 + if t2(1)==0 break; + else + x=xrao(1,hui); + v=(x-t1(1)*boundary(xiang)-t0(1))/t2(1); + if (v>=vmin)&&(v<=vmax) + point=t0+boundary(xiang)*t1+v*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +else %定v的取值 +for hui=1:nx+1 + if t1(1)==0 break; + else + x=xrao(1,hui); + u=(x-t2(1)*boundary(xiang)-t0(1))/t1(1); + if (u>=umin)&&(u<=umax) + point=t0+u*t1+boundary(xiang)*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +end +end + +%与x-z面的交点 +boundary=[umin,umax,vmin,vmax]; +for xiang=1:4 + +if xiang<=2 %说明定u的取值 +for hui=1:ny+1 + if t2(2)==0 break; + else + y=yrao(1,hui); + v=(y-t1(2)*boundary(xiang)-t0(2))/t2(2); + if (v>=vmin)&&(v<=vmax) + point=t0+boundary(xiang)*t1+v*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +else %定v的取值 +for hui=1:ny+1 + if t1(2)==0 break; + else + y=yrao(1,hui); + u=(y-t2(2)*boundary(xiang)-t0(2))/t1(2); + if (u>=umin)&&(u<=umax) + point=t0+u*t1+boundary(xiang)*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +end +end + +%与x-y面的交点 +boundary=[umin,umax,vmin,vmax]; +for xiang=1:4 + +if xiang<=2 %说明定u的取值 +for hui=1:nz+1 + if t2(3)==0 break; + else + z=zrao(1,hui); + v=(z-t1(3)*boundary(xiang)-t0(3))/t2(3); + if (v>=vmin)&&(v<=vmax) + point=t0+boundary(xiang)*t1+v*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +else %定v的取值 +for hui=1:nz+1 + if t1(3)==0 break; + else + z=zrao(1,hui); + u=(z-t2(3)*boundary(xiang)-t0(3))/t1(3); + if (u>=umin)&&(u<=umax) + point=t0+u*t1+boundary(xiang)*t2; + d3intersection(n,:)=point;n=n+1; + end + end +end +end +end + +%% 删去相同的线段及零线段 +d2intersection=unique(d2intersection, 'rows', 'stable'); +m=size(d2intersection,1); +for i=1:m + + if(d2intersection(i,1)==-1) +d3intersection(n,:)=[d2intersection(i,4),d2intersection(i,2),d2intersection(i,3)];n=n+1; +d3intersection(n,:)=[d2intersection(i,5),d2intersection(i,2),d2intersection(i,3)];n=n+1; + for wang=1:nx+1 + j=xrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) + d3intersection(n,:)=[j,d2intersection(i,2),d2intersection(i,3)];n=n+1; + end + end + end + + if(d2intersection(i,2)==-1) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,4),d2intersection(i,3)];n=n+1; +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,5),d2intersection(i,3)];n=n+1; + for wang=1:ny+1 + j=yrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) + d3intersection(n,:)=[d2intersection(i,1),j,d2intersection(i,3)];n=n+1; + end + end + end + + if(d2intersection(i,3)==-1) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),d2intersection(i,4)];n=n+1; +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),d2intersection(i,5)];n=n+1; + for wang=1:nz+1 + j=zrao(1,wang); + if (((j>=d2intersection(i,4))&&(j<=d2intersection(i,5)))||((j>=d2intersection(i,5))&&(j<=d2intersection(i,4)))) +d3intersection(n,:)=[d2intersection(i,1),d2intersection(i,2),j];n=n+1; + end + end + end +end + +%% 添加矩形缝的四个顶点坐标 +vertex1=t0+umin*t1+vmin*t2; +vertex2=t0+umin*t1+vmax*t2; +vertex3=t0+umax*t1+vmin*t2; +vertex4=t0+umax*t1+vmax*t2; +d3intersection=[d3intersection;vertex1;vertex2;vertex3;vertex4]; +%% 后续处理 +d3intersection=unique(d3intersection, 'rows', 'stable'); +[I,J]=find(d3intersection==-1000); +d3intersection(I,:)=[]; + +record=[]; +kitty=size(d3intersection,1); +for i=1:kitty-1 + for j=i+1:kitty + if (norm(d3intersection(i,:)-d3intersection(j,:))<=1e-4)%该数值与网格属性有关 + record=[record;j]; + end + end +end +record=unique(record, 'rows', 'stable'); +d3intersection(record,:)=[]; + +record1=[]; +myhui=size(d3intersection,1); +for i=1:myhui + huix=d3intersection(i,1); + huiy=d3intersection(i,2); + huiz=d3intersection(i,3); + if huix>max(xrao) || huixmax(yrao) || huiymax(zrao) || huizumax)||(x(1)vmax)||(x(2)0)%此处判断已无必要,表明改基质网格包含裂缝网格n=size(indice,2); + %该函数的坐标基点是正六面体的左下角点,即编号为1的点 + matnodes=nodes(connectmf{i,1},1); + origin=coord(matnodes,:); + p=repmat(origin,np,1)+cor;%accor是该基质网格面上所有点的实际坐标 + + gfmc=[]; + for mei=1:np + + gfmr=[]; + for k=1:n + for r=2:(nf+1) + if(matrixvsfra(connectmf{i,1},k)0)%此处判断已无必要,表明改基质网格包含裂缝网格n=size(indice,2); + %该函数的坐标基点是正六面体的左下角点,即编号为1的点 + matnodes=nodes(connectmf{i,1},1); + origin=coord(matnodes,:); + p=repmat(origin,np,1)+cor;%accor是该基质网格面上所有点的实际坐标 + for j=1:np + for k=1:n + for r=2:(nf+1) + if(matrixvsfra(connectmf{i,1},k)0)%表明改基质网格包含裂缝网格n=size(indice,2); + gfmc=[]; + gfmr=[]; + %for j=1:n %裂缝单元源点选取 + fracp=cell(1,3); + cc=0; + conv=[]; + for k=1:n %裂缝单元面积积分区域选取 + for r=2:(nf+1) + if(matrixvsfra(connectmf{i,1},k)0)%表明改基质网格包含裂缝网格n=size(indice,2); +% for j=1:n +% for k=1:n +% for r=2:(nf+1) +% if(matrixvsfra(connectmf{i,1},k)0)%表明改基质网格包含裂缝网格n=size(indice,2); + for j=1:n + for k=1:n + for r=2:(nf+1) + if(matrixvsfra(connectmf{i,1},k)0)%表明改基质网格包含裂缝网格n=size(indice,2); + matnodes=nodes(connectmf{i,1},1); + origin=coord(matnodes,:); + p=repmat(origin,np,1)+cor;%accor是该基质网格面上所有点的实际坐标 + for j=1:n + for k=1:np + %for k=1:6%使立方体面循环 +% for r=2:(nf+1) +% if(matrixvsfra(i,j)=1&&i-1<=nx) + raomatrix(i + (j - 1) * nx+nx*ny*(k-1), i-1+ (j - 1) * nx+nx*ny*(k-1))=dy(j)*dz(k)/(dx(i)/2); + end + if(i+1>=1&&i+1<=nx) + raomatrix(i + (j - 1) * nx+nx*ny*(k-1), i+1+ (j - 1) * nx+nx*ny*(k-1))=dy(j)*dz(k)/(dx(i)/2); + end + if(j-2>=0&&j-2<=ny-1) + raomatrix(i + (j - 1) * nx+nx*ny*(k-1), i + (j - 2) * nx+nx*ny*(k-1))=dx(i)*dz(k)/(dy(j)/2); + end + if(j>=0&&j<=ny-1) + raomatrix(i + (j-1 ) * nx+nx*ny*(k-1), i + (j ) * nx+nx*ny*(k-1))=dx(i)*dz(k)/(dy(j)/2); + end + if(k-2>=0&&k-2<=nz-1) + raomatrix(i + (j - 1) * nx+nx*ny*(k-1), i + (j - 1) * nx+nx*ny*(k-2))=dx(i)*dy(j)/(dz(k)/2); + end + if(k>=0&&k-2<=nz-1) + raomatrix(i + (j - 1) * nx+nx*ny*(k-1), i + (j - 1) * nx+nx*ny*(k))=dx(i)*dy(j)/(dz(k)/2); + end + end + end +end +%利用tansmatrix矩阵的对称性减少循环运算,提高效率 +for i=1:np + for j=1:np + if(raomatrix(i,j)~=0) + transmatrix(i,j)=(raomatrix(i,j)*raomatrix(j,i))/(raomatrix(i,j)+raomatrix(j,i)); + end + end +end + +%% 计算裂缝网格之间的传导系数,先不管不同裂缝面相交时的传导系数情况 +%先将不同裂缝面的连接情况合在一起 +% raodu=zeros(m); +% p=1; +% for i=1:nf +% raonumber=size(connect_infrac{i,1},1); +% raodu(p:raonumber,p:p+raonumber-1)=connect_infrac{i,1}; +% p=p+raonumber; +% end +%计算裂缝网格之间的传导系数,没有乘以缝宽和渗透率 + +% for i=1:m +% for j=1:m +% if(raodu(i,j)~=0) +% A=fracnumber(j,:); +% B=fracnumber(k,:); +% A(A==0)=[]; +% B(B==0)=[]; +% raoflag=intersect(A,B); +% length=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:)); +% rao1=corevsfra(i,:)-d3intersection(raoflag(1),:); +% rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); +% disvsfra=norm(cross(rao1',rao2'))/norm(rao2);%计算出裂缝网格重心到公共边的距离 +% raofracture(i,j)=length/disvsfra;%没有乘以渗透率和缝宽 +% end +% end +% end +p=0; +for raox=1:nf + raonumber=size(connect_infrac{raox,1},1);% raox条裂缝面上的裂缝单元数 + d3intersection=raopoint{raox,1}; + for i=1:raonumber %p:(p+raonumber-1) + for j=1:10 + if(connect_infrac{raox,1}(i,j)~=0) + A=fracnumber(i+p,:); + B=fracnumber(connect_infrac{raox,1}(i,j),:); + A(A==0)=[]; + B(B==0)=[]; + raoflag=intersect(A,B); + length=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:)); + rao1=corevsfra(i+p,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + newdisvsfra=norm(cross(rao1',rao2'))/norm(rao2);%计算出裂缝网格重心到公共边的距离 + raofracture(i,connect_infrac{raox,1}(i,j))=length/newdisvsfra;%没有乘以渗透率和缝宽 + end + end + end + p=p+raonumber; +end + +for i=1:m + for j=1:m + if(raofracture(i,j)~=0) + transfracture(i,j)=(raofracture(i,j)*raofracture(j,i))/(raofracture(i,j)+raofracture(j,i)); + end + end +end +%% 考虑基质网格内裂缝相交时,裂缝网格之间的传导系数 +%首先将该基质网格中包含的裂缝网格按照裂缝面的不同分组存放,判断同一裂缝面上裂缝网格的交线, +%并计算相应裂缝网格重心到交线的距离,并将此作为该裂缝网格的传导系数,如果某裂缝网格与同一裂缝面上多个裂缝网格都有相交 +%则该裂缝网格的传导是所有传导系数的算数平均(因为不是在一条流线上) +%由于连接关系复杂,故简化为所有网格的传导系数,按照星型变换的规则,确定该基质网格中某裂缝网格到另一裂缝网格的传导系数 +% n=size(matrixvsfra,1); +% indice=zeros(nf,10); +% for i=1:n +% raoindice=find(matrixvsfra(i,:)~=0); +% if(size(raoindice,2)>1) +% for k=1:nf +% indice(k,:)=find((matrixvsfra(i,:)=fracstart(k))); +% end +% for k=1:nf +% if(size(indice(k,:),2)>1)%若等于0,则该裂缝面没有网格在其中,若等于1,说明该裂缝网格没有与其它裂缝面相交,故不予考虑去改变 +% rao=zero(size(indice(k,:),2)); +% for j=1:size(indice(k,:),2)%在同一裂缝面内查看这些同裂缝面裂缝网格的相交情况 +% for z=1:size(indice(k,:),2) +% A=fracnumber(matrixvsfra(i,indice(k,j)),:); +% B=fracnumber(matrixvsfra(i,indice(k,z)),:); +% raoindi=intersect(A,B); +% if(size(raoindi,2)==2) +% length=norm(d3intersection(raoindi(1),:)-d3intersection(raoindi(2),:)); +% rao1=corevsfra(matrixvsfra(i,indice(k,j)),:)-d3intersection(raoindi(1),:); +% rao2=d3intersection(raoindi(1),:)-d3intersection(raoindi(2),:); +% disvsfra=norm(cross(rao1',rao2'))/norm(rao2);%计算出裂缝网格重心到公共边的距离 +% rao(j,z)=length/disvsfra;%没有乘以渗透率和缝宽 +% +% +% +% +% +% end +% end + +% 首先将该基质网格中包含的裂缝网格按照裂缝面的不同分组存放,某一裂缝网格的传导系数等于朝向各边的传导系数的算术平均(连接情况复杂,此为简化处理) +% 按照星型变换的规则,确定该基质网格中某裂缝网格到另一裂缝网格的传导系数 +n=size(matrixvsfra,1); +indice=zeros(nf,10); +for i=1:n + raoindice=find(matrixvsfra(i,:)~=0); + if(size(raoindice,2)>1) + extratrans=zeros(1,size(raoindice,2)); + for j=1:size(raoindice,2) +% for k=2:(nf+1) +% if(matrixvsfra(i,raoindice(j)) 0 %瀛樺湪瀹氭祦閲忎簳 + pwf = state.pwf; +end +ipwf = 0; +for i = 1 : nWel + if strcmp(well_schedules_k{i,2},'open') + qgt = 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); + qgt = qgt + 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}.qg = abs(qgt)*86.4; + Wellpara{1,i}.pwf = pwf(ipwf); + else + Wellpara{1,i}.wellname = Wellc{i,1}; + Wellpara{1,i}.qw = 0; + Wellpara{1,i}.qg = 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); + qgt = qgt + qwell(nc + jperf); + end + Wellpara{1,i}.wellname = Wellc{i,1}; + Wellpara{1,i}.qw = abs(qwt)*86.4; + Wellpara{1,i}.qg = abs(qgt)*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}.qg = 0; + else + Wellpara{1,i}.wellname = Wellc{i,1}; + Wellpara{1,i}.qw = 0; + Wellpara{1,i}.pwf = pwf(ipwf); + Wellpara{1,i}.qg = 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}.qg = 0; + end + end + end +end \ No newline at end of file diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/eqsOW_MB_gas_water_flow.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/eqsOW_MB_gas_water_flow.m new file mode 100644 index 0000000..67074a9 --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/eqsOW_MB_gas_water_flow.m @@ -0,0 +1,159 @@ +function [eqs, Awell, qwell,PVv, Bga, Bwa] = eqsOW_MB_gas_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_gas_water_flow(p, sw); + +% 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.ifpcgl + pcOW = f.pcgl(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 +BG = f.Bg(p); +muG = f.mug(p); +krG = f.krrg(sw); +dpG = os.grad(p); +% dzg=1e-6*9.8*f.Dgsi*os.grad(z./BG); %娌圭浉浣嶅娍姊害 +dzg=0; +upc = (double(dpG+dzg)<=0);%涓瀹氳鏄姌绠楀帇鍔涳紝鍚﹀垯鍑洪敊锛 +mgbG = os.faceUpstr(upc, krG) .* os.faceAvg(1./(BG.*muG)); +% mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO)).* os.faceAvg(stress_factor); +% 閽堝鍚姩鍘嬪姏姊害鐨勫钩婊戝鐞 +if f.p_grad_threshold ~= 0 + dpG0 = os.grad(p0); + dzg0=0; + dpG0 = dpG0+dzg0; + pG_grad0 = r.T_diff./r.flowArea.*dpG0; + ratioG = smooth_relu_stable(pG_grad0, f.p_grad_threshold); +else + ratioG = 1; +end +% Knudsen 鎵╂暎褰卞搷 +bGvG = -r.matrixflag.*f.gas_prop.Kn_modified_factor.*r.T .* mgbG .* dpG.*ratioG ... + -(1-r.matrixflag).*r.T .* mgbG .* dpG.*ratioG; +% 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) +BG0 = f.Bg(p0);muG0 = f.mug(p0);krG0 = f.krrg(sw0);dpG0 = os.grad(p0); +dzg0=0; +upc0 = (double(dpG0+dzg0)<=0);%涓瀹氳鏄姌绠楀帇鍔涳紝鍚﹀垯鍑洪敊锛 +mgbG0 = os.faceUpstr(upc0, krG0) .* os.faceAvg(1./(BG0.*muG0)); +% mobO = os.faceUpstr(upc, krO) .* os.faceAvg(1./(BO.*muO)).* os.faceAvg(stress_factor); +v_gf = -(1-r.matrixflag).*r.T .* mgbG0 .* dpG0./r.flowArea; +density_g = f.density_g_sc./BG0; +Forchheimer_factor = 1./(1+(1-r.matrixflag).*r.perm./os.faceAvg(muG0).*f.gas_prop.beta_non_Darcy_flow.*os.faceAvg(density_g).*abs(v_gf)); + +% 鍒嗗埆鏈夊熀璐ㄧ郴缁熺殑搴斿姏鏁忔劅绯绘暟 鍜 瑁傜紳绯荤粺鐨勫簲鍔涙晱鎰熺郴鏁 +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; +bGvG = bGvG.*stress_factor.*Forchheimer_factor; +% 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_gas_water_flow(r, f, p.val, sw.val, Wellc, Weladd, pwf, WelChg, well_schedules_k); +% Awell=dt*Awell; +% qwell=dt*qwell; + +% langmuir 绛夋俯鍚搁檮 +V_CH4=r.rpt.*r.V.*(1-r.por(p)).*r.density_rock.*f.gas_prop.VL.*p/f.gas_prop.PL./(1+p/f.gas_prop.PL); +V_CH4_0=r.rpt.*r.V.*(1-r.por(p)).*r.density_rock.*f.gas_prop.VL.*p0/f.gas_prop.PL./(1+p0/f.gas_prop.PL); + +% 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_g = 1/dt*(PV .* ((1 - sw) ./ BG) - PV0 .* ((1 - sw0) ./ f.Bg(p0)) + (V_CH4-V_CH4_0)); + +% 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(bGvG) - Ar_g); +% 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 = BG.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)); + + + + + + + + + + diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/fluidPVT_gas_water_flow.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/fluidPVT_gas_water_flow.m new file mode 100644 index 0000000..ac9931c --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/fluidPVT_gas_water_flow.m @@ -0,0 +1,16 @@ +function f = fluidPVT_gas_water_flow(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, SW, KRG, KRW, PCGL, SWF, KRGF, KRWF, PCGLF, density_g_sc, ifpcgl, 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_gw(p, Bwi, prw, cw); +f.Bg = @(p) Bg_gw(p, BG, Ppr); +f.muw = @(p) muw_gw(p, vwi, prw, cvw); +f.mug = @(p) mug_gw(p, MUG, Ppr); +f.krrg = @(sw) krrg_gw(sw, SW, KRG, SWF, KRGF, rpt); +f.krw = @(sw) krw_gw(sw, SW, KRW, SWF, KRWF, rpt); +f.pcgl = @(sw) pc_gw(sw, SW, PCGL, SWF, PCGLF, rpt); +f.density_g_sc = density_g_sc; +f.ifpcgl = ifpcgl; +% f.Dosi=Dosi; +% f.Dwsi=Dwsi; + + + diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/initalSchedule_gas_water_flow.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/initalSchedule_gas_water_flow.m new file mode 100644 index 0000000..1d6c3f0 --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/initalSchedule_gas_water_flow.m @@ -0,0 +1,53 @@ +function [Weladd, pwf] = initalSchedule_gas_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); +BG = f.Bg(p); +muG = f.mug(p); +krG = f.krrg(sw); +Ygt = krG ./ (muG .* BG);%mu浠h〃榛忓害 +Ygj = krG ./ muG; +Ywt = krW ./ (muW .* BW);%mu浠h〃榛忓害 +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 * (Ygt(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)) * (Ygj(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;%涓庣敓浜т簳姝eソ鍙嶈繃鏉 + else + continue + end + end +end + pwf = pwf'; \ No newline at end of file diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/initialRS_gas_water_flow.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/initialRS_gas_water_flow.m new file mode 100644 index 0000000..d14ec7f --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/initialRS_gas_water_flow.m @@ -0,0 +1,3 @@ +function state = initialRS_gas_water_flow(P, Sw) +state.p = P; +state.sw = Sw; diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/intADI2_gas_water_flow.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/intADI2_gas_water_flow.m new file mode 100644 index 0000000..b9c6276 --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/intADI2_gas_water_flow.m @@ -0,0 +1,18 @@ +function [P, Sw, Pwf] = intADI2_gas_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); \ No newline at end of file diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/intADI_gas_water_flow.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/intADI_gas_water_flow.m new file mode 100644 index 0000000..04ef74b --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/intADI_gas_water_flow.m @@ -0,0 +1,10 @@ +function [P, Sw] = intADI_gas_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); \ No newline at end of file diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/krrg_gw.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/krrg_gw.m new file mode 100644 index 0000000..f071a27 --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/krrg_gw.m @@ -0,0 +1,14 @@ +function h = krrg_gw(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 \ No newline at end of file diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/krw_gw.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/krw_gw.m new file mode 100644 index 0000000..4f0532e --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/krw_gw.m @@ -0,0 +1,15 @@ +function h = krw_gw(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 + diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/mainRS_MB_gas_water_flow.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/mainRS_MB_gas_water_flow.m new file mode 100644 index 0000000..76dceab --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/mainRS_MB_gas_water_flow.m @@ -0,0 +1,153 @@ +function [Times, OutputRs, Wellpara, trun] = mainRS_MB_gas_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_gas_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_gas_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_gas_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('姝e湪璁$畻锛%.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); + + diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/mug_gw.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/mug_gw.m new file mode 100644 index 0000000..f9bf958 --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/mug_gw.m @@ -0,0 +1,3 @@ +function h = mug_gw(p, MUG, Ppr) +h = interptable(Ppr, MUG, p); +end \ No newline at end of file diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/muw_gw.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/muw_gw.m new file mode 100644 index 0000000..ca3fdc2 --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/muw_gw.m @@ -0,0 +1,2 @@ +function h = muw_gw(p, vwi, prw, cvw) +h = vwi + cvw * (p - prw); diff --git a/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/pc_gw.m b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/pc_gw.m new file mode 100644 index 0000000..49e36cc --- /dev/null +++ b/core functions/姘旀按涓ょ浉娴侀儴鍒嗕唬鐮/pc_gw.m @@ -0,0 +1,16 @@ +function h = pc_gw(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 diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/Bo_ow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/Bo_ow.m new file mode 100644 index 0000000..cae53b0 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/Bo_ow.m @@ -0,0 +1,3 @@ +function h = Bo_ow(p, BO, Ppr) +h = interptable(Ppr, BO, p); +end \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/Bw_ow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/Bw_ow.m new file mode 100644 index 0000000..f4ec6ea --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/Bw_ow.m @@ -0,0 +1,2 @@ +function h = Bw_ow(p, Bwi, prw, cw) +h = Bwi * (1 - cw * (p - prw)); \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/WellEquation_oil_water_flow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/WellEquation_oil_water_flow.m new file mode 100644 index 0000000..13d7eaa --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/WellEquation_oil_water_flow.m @@ -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)); + %鍓峮c琛屾槸姘寸浉鏂圭▼ + Awell(jperf, :) = [qw.jac{1} qw.jac{2} qw.jac{3}]; + qwell(jperf) = qw.val; + %鍚巒c琛屾槸姘寸浉鏂圭▼ + 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 \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/cal_oil_prop.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/cal_oil_prop.m new file mode 100644 index 0000000..89c7eed --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/cal_oil_prop.m @@ -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 \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/calcWellequation_oil_water_flow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/calcWellequation_oil_water_flow.m new file mode 100644 index 0000000..abf635d --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/calcWellequation_oil_water_flow.m @@ -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 \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/eqsOW_MB_oil_water_flow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/eqsOW_MB_oil_water_flow.m new file mode 100644 index 0000000..39b9a9f --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/eqsOW_MB_oil_water_flow.m @@ -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=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=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)); + + + + + + + + + + diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/fluidPVT_oil_water_flow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/fluidPVT_oil_water_flow.m new file mode 100644 index 0000000..8ca806d --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/fluidPVT_oil_water_flow.m @@ -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; + + + diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/initalSchedule_oil_water_flow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/initalSchedule_oil_water_flow.m new file mode 100644 index 0000000..0b320a8 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/initalSchedule_oil_water_flow.m @@ -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浠h〃榛忓害 +Yoj = krO ./ muO; +Ywt = krW ./ (muW .* BW);%mu浠h〃榛忓害 +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;%涓庣敓浜т簳姝eソ鍙嶈繃鏉 + else + continue + end + end +end + pwf = pwf'; \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/initialRS_oil_water_flow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/initialRS_oil_water_flow.m new file mode 100644 index 0000000..62c7606 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/initialRS_oil_water_flow.m @@ -0,0 +1,3 @@ +function state = initialRS_oil_water_flow(P, Sw) +state.p = P; +state.sw = Sw; \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/intADI2_oil_water_flow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/intADI2_oil_water_flow.m new file mode 100644 index 0000000..45ae1f5 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/intADI2_oil_water_flow.m @@ -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); \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/intADI_oil_water_flow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/intADI_oil_water_flow.m new file mode 100644 index 0000000..3463511 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/intADI_oil_water_flow.m @@ -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); \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/kro_ow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/kro_ow.m new file mode 100644 index 0000000..f18add0 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/kro_ow.m @@ -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 \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/krw_ow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/krw_ow.m new file mode 100644 index 0000000..a4b03f3 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/krw_ow.m @@ -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 + diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/mainRS_MB_oil_water_flow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/mainRS_MB_oil_water_flow.m new file mode 100644 index 0000000..5ee8e8d --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/mainRS_MB_oil_water_flow.m @@ -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('姝e湪璁$畻锛%.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); + + diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/muo_ow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/muo_ow.m new file mode 100644 index 0000000..4bc5fa3 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/muo_ow.m @@ -0,0 +1,3 @@ +function h = muo_ow(p, MUO, Ppr) +h = interptable(Ppr, MUO, p); +end \ No newline at end of file diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/muw_ow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/muw_ow.m new file mode 100644 index 0000000..538f194 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/muw_ow.m @@ -0,0 +1,2 @@ +function h = muw_ow(p, vwi, prw, cvw) +h = vwi + cvw * (p - prw); diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/pcow.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/pcow.m new file mode 100644 index 0000000..b3f4913 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/pcow.m @@ -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 diff --git a/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/por.m b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/por.m new file mode 100644 index 0000000..5561327 --- /dev/null +++ b/core functions/娌规按涓ょ浉娴侀儴鍒嗕唬鐮/por.m @@ -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 diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/GridProp_DP.asv b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/GridProp_DP.asv new file mode 100644 index 0000000..ad44248 --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/GridProp_DP.asv @@ -0,0 +1,523 @@ +function r = GridProp_DP(modelflag,nx, ny, nz, dx, dy, dz, kx, ky, kz, kx_matrixLayer, ky_matrixLayer, kz_matrixLayer, f, frac_information, fellip, Kf, Wf, pori, pori_matrixLayer, prpor, cpor, Porf, prporf, cporf, cf, ca,NTG) +tic; +%% 鍩鸿川缃戞牸鍙傛暟鍙婄綉鏍煎弬鏁拌绠椼佸瓨鍌 +r.modelflag=modelflag; +r.nx = nx; +r.ny = ny; +r.nz = nz; +r.dx = dx; +r.dy = dy; +r.dz = dz; +r.kx = kx; +r.ky = ky; +r.kz = kz; +r.kx_matrixLayer = kx_matrixLayer; +r.ky = ky; +r.kz = kz; +r.Kf = Kf;%瑁傜紳闈㈠搴旂殑娓楅忕巼锛岄潪瑁傜紳鍗曞厓 +r.Wf = Wf;%瑁傜紳闈㈠搴旂殑缂濆锛岄潪瑁傜紳鍗曞厓 +r.cf = cf; +r.ca = ca; +% r.co=co; +r.cpor=cpor; +r.cporf=cporf; +r.NTG=NTG; +r.frac_information = frac_information; + +[coordinates, nodes, nP, nE, dxv, dyv,dzv,zm,vm,xrao,yrao,zrao,cell_mid_coordinates] = GenerateNode_final(dx, dy,dz ,nx,ny,nz,NTG); +r.coordinates = coordinates; +r.nodes = nodes; +nmc=nE; +r.nmc =nmc; +r.dxv = dxv; +r.dyv = dyv; +r.dzv = dzv; +r.vm=vm; +r.cell_mid_coordinates=cell_mid_coordinates; +%% 姹傝В瑁傜紳涓庡熀璐ㄧ綉鏍艰繛鎺ユ儏鍐 +%% 鍏抽敭鍙傛暟鐭╅樀鍒濆鍖 +m=size(f,1); +n=size(fellip,1); +nfr=m/5;%鐭╁舰瑙勫垯瑁傜紳鏉℃暟 +nfir=n/5;%涓嶈鍒欒缂濇潯鏁帮紙褰撶劧鍖呭惈妞渾锛 +r.nfr=nfr; r.nfir=nfir; +nf=nfr+nfir; +r.nf=nf; +if (nfir~=0) && (nfr~=0) + f=[f;fellip]; +else if nfr~=0 + f=f; +else if nfir~=0 + f=fellip; +else error('Dr Rao reminds you that there is no information about fractures'); +end +end +end + +%d3intersection=-1000*ones(1000,3);%鐢-1000鍋氭爣璇 +raopoint=cell(nfr+nfir,2);%鍒╃敤鍏冭優鏁扮粍瀛樺偍姣忔潯瑁傜紳涓庡熀璐ㄧ綉鏍肩嚎鐨勪氦鐐癸紝 +%绗竴鍒楁槸涓夌淮鍧愭爣褰㈠紡锛屽嵆d3intersection +%绗簩鍒楁槸瑁傜紳闈㈠弬鏁板舰寮忥紝鍗砤nothersection +pointvsregion=cell(nfr+nfir,3);%鍒╃敤鍏冭優鏁扮粍瀛樺偍interarea鍑芥暟鐨勭粨鏋渘umofmesh, numvspoint,numofregion +fracrossfra=cell(nfr+nfir,nfr+nfir-1);%鍒ゆ柇瑁傜紳涔嬮棿涓や氦鐐瑰潗鏍 +fratmaxfra=zeros(nfr+nfir,nfr+nfir-1);%鍒ゆ柇瑁傜紳涔嬮棿浜ょ嚎鍙傛暟鐨勬渶澶у +fratminfra=zeros(nfr+nfir,nfr+nfir-1);%鍒ゆ柇瑁傜紳涔嬮棿浜ょ嚎鍙傛暟鐨勬渶灏忓 +fracturemesh=cell(nf,1);%姣忎竴琛屾槸涓鏉¤缂濋潰涓婄殑缃戞牸鍓栧垎鎯呭喌 + +%% 璁$畻瑁傜紳涓庡熀璐ㄧ綉鏍肩浉浜ゆ儏鍐 +for i=1:nfr + raopoint{i,1}= intersectionsolve_new_modified_r(f((5*i-4):(5*i),:),dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + raopoint{i,2}= anosection( f((5*i-4):(5*i),:),raopoint{i,1} ); + [ pointvsregion{i,1},pointvsregion{i,2} ,pointvsregion{i,3}] = interarea( raopoint{i,1},dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); +end +% 涓嶈鍒欑紳璁$畻 +if nfir>0 + for i=1:nfir + raopoint{nfr+i,1}= intersectionsolve_new_modified_irr(fellip((5*i-4):(5*i),:),dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + raopoint{nfr+i,2}= anosection( f((5*(nfr+i)-4):(5*(nfr+i)),:),raopoint{nfr+i,1} ); + [ pointvsregion{nfr+i,1},pointvsregion{nfr+i,2} ,pointvsregion{nfr+i,3}] = interarea( raopoint{nfr+i,1},dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + end +end + +%% 璁$畻瑁傜紳涔嬮棿鐩镐氦绾挎儏鍐 +for i=1:nf + for j=1:nf + if i>nfr || j>nfr cross=zeros(2,3);tmax=0;tmin=0; + else + % [ cross,tmax,tmin ]=frac_cross_frac( f((5*i-4):(5*i),:),f((5*j-4):(5*j),:) ); + cross=zeros(2,3);tmax=0;tmin=0; + end + fracrossfra{i,j}=cross;fratmaxfra(i,j)=tmax;fratminfra(i,j)=tmin; + end +end +%% 璁$畻瑁傜紳琚熀璐ㄧ綉鏍笺佸叾瀹冭缂濅笌涔嬬浉浜ゅ悗鐨勭綉鏍煎垎甯冩儏鍐,缁樺埗浜岀淮瑁傜紳骞抽潰鍙傛暟鍧愭爣绯讳笂鐨勭綉鏍煎垎甯冩儏鍐 +% figure('color','w'); +addflag=zeros(nf,1);%涔2鐨勫箓娆★紝闃叉鍥犱负瑁傜紳鏉℃暟杈冨锛岄犳垚鐭╅樀澶ぇ +for i=1:nf + d3intersection=raopoint{i,1};anothersection=raopoint{i,2}; + [ mesh ] = frac_mat_mesh( d3intersection,anothersection,pointvsregion{i,2},pointvsregion{i,1} ); + % for j=1:nf + % [ mesh,d3intersection,anothersection,add_flag ]= frac_frac_mesh_modified(xrao,yrao,zrao,mesh,f(5*i-4,:),f(5*i-3,:),f(5*i-2,:),fracrossfra{i,j},fratmaxfra(i,j),fratminfra(i,j),d3intersection,anothersection,pointvsregion{i,2},pointvsregion{i,1} ); + % addflag(j,1)=addflag(j,1)+add_flag; + % end + raopoint{i,1} = d3intersection; raopoint{i,2} = anothersection;%鐢卞師鏉ヨ缂濅笌缃戞牸鐨勪氦鐐逛笉鏂洿鏂板姞鍏ュ叾瀹冭缂濅笌璇ヨ缂濈殑浜ょ偣 + fracturemesh{i,1}=mesh; + % subplot(nf,1,i);color_fill={'y','r','b','g'}; + % plotmesh2D(mesh,raopoint{i,2},color_fill{1,mod(i,4)+1}); +end + +%% 缁樺埗涓夌淮鑳屾櫙缃戞牸锛堝熀璐ㄧ綉鏍硷級鍙婅缂濈綉鏍煎垎甯 +%figure(2) +%network3D(dx,dy,dz,nx,ny,nz ); +%hold on; +figure('color','w'); +% plot_reservoir_3D(max(xrao),max(yrao),dz(1),1,1,nz); +% plot_reservoir_3D(dx(1),dy(1),dz(1),nx,ny,nz); +network3D(dx(1),dy(1),dz(1),nx,ny,nz); +% network3D(1000,700,10,1,1,1); +% network3D(800,300,10,1,1,1); +hold on; + +% network3D_arbitrary(dx,dy,dz,nx,ny,nz); +% refine; +% hold on; +for i=1:nf + % color_fill={'y','r','b','g','c','m'}; + % color_fill={'y','r','b','g'}; + % plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill{1,mod(i,4)+1});hold on; + if i <= 100 + color_fill='b'; %娴佸姩灞忛殰 + % elseif i <=19 + % color_fill='b'; %鍘嬭缂 +% if i == 2 || i == 9 +% color_fill='r'; +% end + else + color_fill='k'; %澶╃劧瑁傜紳 + end + % plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill{1,mod(i,4)+1});hold on; + plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill);hold on; +end +% % % basic_node_coord = [0,0,0]; +% % % x_length = 700; +% % % y_length = 800; +% % % z_length = 10; +% % % nodes_domain = [basic_node_coord;] +% % % fill3(x,y,z,'w'); +% refine1; +% refine_chengjiepaper; +% refine; +% plot_reservoir_3D(max(xrao),max(yrao),dz(1),1,1,nz); +% plot_reservoir_3D(dx(1),dy(1),dz(1),nx,ny,nz); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +zlabel('z, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +% +% zticks([0, 5]); +% yticks(-1:0.5:1); +% 璁剧疆x杞村拰y杞寸殑鍒诲害鏍囩 +% zticklabels({'-2005', '-2000'}); +% yticklabels({'-1', '-0.5', '0', '0.5', '1'}); +% 鍏抽棴鍒诲害鏍囩鐨勬棆杞 +% xticklabels('Rotation', 0); +% yticklabels('Rotation', 0); +% axis equal; +% refine; +% hold on +% network3D(dx(1),dy(1),dz(1),nx,ny,nz); +% network3D(max(xrao),max(yrao),max(zrao),1,1,1 ); +% network3D(10,10,10,2,1,1 ); +% network3D(10,10,10,6,1,2 ); +alpha(1) +view(3) +% axis([min(xrao),max(xrao),min(yrao),max(yrao),min(zrao),max(zrao)]); +% axis equal +% % hold off; +%% 纭畾瑁傜紳缂栧彿鍙婅繛鎺ユ儏鍐碉紝璁$畻浼犲绯绘暟 +if modelflag==1 %琛ㄧず鐢2014, Monifar + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,cell_divided_by_fracture_flag, flowArea, perm, matrixflag ] = connections_2014( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,pori,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.flowArea=flowArea; + r.perm=perm; + r.matrixflag=matrixflag; +elseif modelflag==4 %琛ㄧず鐢 PEDFM + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_new( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==5 % 琛ㄧず瀹炵敤鍨婸EDFM + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff, flowArea, perm, matrixflag ] = connections_PEDFM_new_new( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,pori,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; + r.flowArea=flowArea; + r.perm=perm; + r.matrixflag=matrixflag; +elseif modelflag==6 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨剉alidation model + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag] = connections_unstructured_EDFM( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag)*1/2; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag)*1/2; + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==7 + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_EX1_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==8 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨剉alidation model + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX1_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==9 % EX2 涓嶅悓鎯呭喌涓 pEDFM 瑙 + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_EX2_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==10 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to3_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==11 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to2_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==12 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to4_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==13 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_TPFA_MFD( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,perm,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==14 %琛ㄧず鐢 PEDFM + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_new_twofractures( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +else + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,NTG ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; + %% 璁$畻浼犲绯绘暟 + % dxvector=ones(1,nx);dyvector=ones(1,ny);dzvector=ones(1,nz); + % [ transmatrix,transfracture ] = trans(dxvector,dyvector,dzvector ,nx,ny,nz,nf,fracnumber,lengthvsfra,disvsfra,fracstart,connect_infrac,corevsfra,matrixvsfra,raopoint,f ); + %% 璁$畻鍩鸿川涓庤缂濅箣闂寸獪娴佺殑鐩稿叧绯绘暟 + if modelflag==2 %琛ㄧず鐢2018, Rao + [ G,Gfm,Gff,Gf,Ap,Apf ]=interflowmf1(r,dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + [Ka, M, F2M , MF_coef] = transFunc_aniso(nc,coordinates, nodes, connectmf,Ap,Apf, matrixvsfra,N,T,kx, ky,kz); + r.Ka = Ka; + r.M = M; + r.F2M = F2M; + r.MF_coef = MF_coef; + elseif modelflag==5 %琛ㄧず鐢 Modified Rao, steady, 2018 + [ G,Gfm,Gff,Gf,Ap,Apf ] = interflowmf_MODIFIED(r,dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + [Ka, M, F2M , MF_coef] = transFunc_aniso_MODIFIED(nc,coordinates, nodes, connectmf,Ap,Apf, matrixvsfra,N,T,kx, ky,kz); + r.Ka = Ka; + r.M = M; + r.F2M = F2M; + r.MF_coef = MF_coef; + % [ G,Gfm,Gff,Gf,Ap,Apf,Apmt,Apft ]=interflowmf1_transient(dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + end + % [ G,Gfm,Gff,Gf,Ap,Apf ]=interflowmf1(dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + %% + + % r.MF_deltt=MF_deltt; +end +%% 璁$畻娣卞害锛堜互涓嬪钩闈负鍩哄噯璁$畻寰楀埌鐨勯珮搴︼紝鍊间负姝f暟锛 +z=[zm;zf]; +r.z=z; + + +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +r.rpt = rpt; +r.Porf = Porf; +pori = [pori; porf]; +r.pori = pori; +r.por = @(p)por(p, prpor, pori, cpor, prporf, cporf, r.rpt); +tpre=toc; +r.tpre=tpre; +end \ No newline at end of file diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/GridProp_DP.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/GridProp_DP.m new file mode 100644 index 0000000..858f589 --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/GridProp_DP.m @@ -0,0 +1,534 @@ +function r = GridProp_DP(modelflag, r, kx, ky, kz, kx_matrixLayer, ky_matrixLayer, kz_matrixLayer, f, frac_information, fellip, Kf, Wf, pori, pori_matrixLayer, prpor, cpor, Porf, prporf, cporf, cf, ca,NTG,sigma,valid_grids) +tic; +%% 鍩鸿川缃戞牸鍙傛暟鍙婄綉鏍煎弬鏁拌绠椼佸瓨鍌 +nx = r.nx; +ny = r.ny; +nz = r.nz; +dx = r.dx; +dy = r.dy; +dz = r.dz; +coordinates = r.coordinates; +nodes = r.nodes; +nP = r.nP; +nmc = r.nmc; +dxv = r.dxv; +dyv = r.dyv; +dzv = r.dzv; +zm = r.zm; +vm = r.vm; +xrao = r.xrao; +yrao = r.yrao; +zrao = r.zrao; +cell_mid_coords = r.cell_mid_coords; +% +r.modelflag=modelflag; +r.kx_matrixLayer = kx_matrixLayer; +r.ky_matrixLayer = ky_matrixLayer; +r.kz_matrixLayer = kz_matrixLayer; +r.Kf = Kf;%瑁傜紳闈㈠搴旂殑娓楅忕巼锛岄潪瑁傜紳鍗曞厓 +r.Wf = Wf;%瑁傜紳闈㈠搴旂殑缂濆锛岄潪瑁傜紳鍗曞厓 +r.cf = cf; +r.ca = ca; +% r.co=co; +r.cpor=cpor; +r.cporf=cporf; +r.NTG=NTG; +r.frac_information = frac_information; + +% [coordinates, nodes, nP, nE, dxv, dyv,dzv,zm,vm,xrao,yrao,zrao,cell_mid_coordinates] = GenerateNode_final(dx, dy,dz ,nx,ny,nz,NTG); +% r.coordinates = coordinates; +% r.nodes = nodes; +% nmc=nE; +% r.nmc =nmc; +% r.dxv = dxv; +% r.dyv = dyv; +% r.dzv = dzv; +% r.vm=vm; +% r.cell_mid_coordinates=cell_mid_coordinates; +%% 姹傝В瑁傜紳涓庡熀璐ㄧ綉鏍艰繛鎺ユ儏鍐 +%% 鍏抽敭鍙傛暟鐭╅樀鍒濆鍖 +m=size(f,1); +n=size(fellip,1); +nfr=m/5;%鐭╁舰瑙勫垯瑁傜紳鏉℃暟 +nfir=n/5;%涓嶈鍒欒缂濇潯鏁帮紙褰撶劧鍖呭惈妞渾锛 +r.nfr=nfr; r.nfir=nfir; +nf=nfr+nfir; +r.nf=nf; +if (nfir~=0) && (nfr~=0) + f=[f;fellip]; +else if nfr~=0 + f=f; +else if nfir~=0 + f=fellip; +else error('Dr Rao reminds you that there is no information about fractures'); +end +end +end + +%d3intersection=-1000*ones(1000,3);%鐢-1000鍋氭爣璇 +raopoint=cell(nfr+nfir,2);%鍒╃敤鍏冭優鏁扮粍瀛樺偍姣忔潯瑁傜紳涓庡熀璐ㄧ綉鏍肩嚎鐨勪氦鐐癸紝 +%绗竴鍒楁槸涓夌淮鍧愭爣褰㈠紡锛屽嵆d3intersection +%绗簩鍒楁槸瑁傜紳闈㈠弬鏁板舰寮忥紝鍗砤nothersection +pointvsregion=cell(nfr+nfir,3);%鍒╃敤鍏冭優鏁扮粍瀛樺偍interarea鍑芥暟鐨勭粨鏋渘umofmesh, numvspoint,numofregion +fracrossfra=cell(nfr+nfir,nfr+nfir-1);%鍒ゆ柇瑁傜紳涔嬮棿涓や氦鐐瑰潗鏍 +fratmaxfra=zeros(nfr+nfir,nfr+nfir-1);%鍒ゆ柇瑁傜紳涔嬮棿浜ょ嚎鍙傛暟鐨勬渶澶у +fratminfra=zeros(nfr+nfir,nfr+nfir-1);%鍒ゆ柇瑁傜紳涔嬮棿浜ょ嚎鍙傛暟鐨勬渶灏忓 +fracturemesh=cell(nf,1);%姣忎竴琛屾槸涓鏉¤缂濋潰涓婄殑缃戞牸鍓栧垎鎯呭喌 + +%% 璁$畻瑁傜紳涓庡熀璐ㄧ綉鏍肩浉浜ゆ儏鍐 +for i=1:nfr + raopoint{i,1}= intersectionsolve_new_modified_r(f((5*i-4):(5*i),:),dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + raopoint{i,2}= anosection( f((5*i-4):(5*i),:),raopoint{i,1} ); + [ pointvsregion{i,1},pointvsregion{i,2} ,pointvsregion{i,3}] = interarea( raopoint{i,1},dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); +end +% 涓嶈鍒欑紳璁$畻 +if nfir>0 + for i=1:nfir + raopoint{nfr+i,1}= intersectionsolve_new_modified_irr(fellip((5*i-4):(5*i),:),dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + raopoint{nfr+i,2}= anosection( f((5*(nfr+i)-4):(5*(nfr+i)),:),raopoint{nfr+i,1} ); + [ pointvsregion{nfr+i,1},pointvsregion{nfr+i,2} ,pointvsregion{nfr+i,3}] = interarea( raopoint{nfr+i,1},dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + end +end + +%% 璁$畻瑁傜紳涔嬮棿鐩镐氦绾挎儏鍐 +for i=1:nf + for j=1:nf + if i>nfr || j>nfr cross=zeros(2,3);tmax=0;tmin=0; + else + % [ cross,tmax,tmin ]=frac_cross_frac( f((5*i-4):(5*i),:),f((5*j-4):(5*j),:) ); + cross=zeros(2,3);tmax=0;tmin=0; + end + fracrossfra{i,j}=cross;fratmaxfra(i,j)=tmax;fratminfra(i,j)=tmin; + end +end +%% 璁$畻瑁傜紳琚熀璐ㄧ綉鏍笺佸叾瀹冭缂濅笌涔嬬浉浜ゅ悗鐨勭綉鏍煎垎甯冩儏鍐,缁樺埗浜岀淮瑁傜紳骞抽潰鍙傛暟鍧愭爣绯讳笂鐨勭綉鏍煎垎甯冩儏鍐 +% figure('color','w'); +addflag=zeros(nf,1);%涔2鐨勫箓娆★紝闃叉鍥犱负瑁傜紳鏉℃暟杈冨锛岄犳垚鐭╅樀澶ぇ +for i=1:nf + d3intersection=raopoint{i,1};anothersection=raopoint{i,2}; + [ mesh ] = frac_mat_mesh( d3intersection,anothersection,pointvsregion{i,2},pointvsregion{i,1} ); + % for j=1:nf + % [ mesh,d3intersection,anothersection,add_flag ]= frac_frac_mesh_modified(xrao,yrao,zrao,mesh,f(5*i-4,:),f(5*i-3,:),f(5*i-2,:),fracrossfra{i,j},fratmaxfra(i,j),fratminfra(i,j),d3intersection,anothersection,pointvsregion{i,2},pointvsregion{i,1} ); + % addflag(j,1)=addflag(j,1)+add_flag; + % end + raopoint{i,1} = d3intersection; raopoint{i,2} = anothersection;%鐢卞師鏉ヨ缂濅笌缃戞牸鐨勪氦鐐逛笉鏂洿鏂板姞鍏ュ叾瀹冭缂濅笌璇ヨ缂濈殑浜ょ偣 + fracturemesh{i,1}=mesh; + % subplot(nf,1,i);color_fill={'y','r','b','g'}; + % plotmesh2D(mesh,raopoint{i,2},color_fill{1,mod(i,4)+1}); +end + +%% 缁樺埗涓夌淮鑳屾櫙缃戞牸锛堝熀璐ㄧ綉鏍硷級鍙婅缂濈綉鏍煎垎甯 +%figure(2) +%network3D(dx,dy,dz,nx,ny,nz ); +%hold on; +figure('color','w'); +% plot_reservoir_3D(max(xrao),max(yrao),dz(1),1,1,nz); +% plot_reservoir_3D(dx(1),dy(1),dz(1),nx,ny,nz); +network3D(dx(1),dy(1),dz(1),nx,ny,nz); +% network3D(1000,700,10,1,1,1); +% network3D(800,300,10,1,1,1); +hold on; + +% network3D_arbitrary(dx,dy,dz,nx,ny,nz); +% refine; +% hold on; +for i=1:nf + % color_fill={'y','r','b','g','c','m'}; + % color_fill={'y','r','b','g'}; + % plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill{1,mod(i,4)+1});hold on; + if i <= 100 + color_fill='b'; %娴佸姩灞忛殰 + % elseif i <=19 + % color_fill='b'; %鍘嬭缂 +% if i == 2 || i == 9 +% color_fill='r'; +% end + else + color_fill='k'; %澶╃劧瑁傜紳 + end + % plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill{1,mod(i,4)+1});hold on; + plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill);hold on; +end +% % % basic_node_coord = [0,0,0]; +% % % x_length = 700; +% % % y_length = 800; +% % % z_length = 10; +% % % nodes_domain = [basic_node_coord;] +% % % fill3(x,y,z,'w'); +% refine1; +% refine_chengjiepaper; +% refine; +% plot_reservoir_3D(max(xrao),max(yrao),dz(1),1,1,nz); +% plot_reservoir_3D(dx(1),dy(1),dz(1),nx,ny,nz); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +zlabel('z, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +% +% zticks([0, 5]); +% yticks(-1:0.5:1); +% 璁剧疆x杞村拰y杞寸殑鍒诲害鏍囩 +% zticklabels({'-2005', '-2000'}); +% yticklabels({'-1', '-0.5', '0', '0.5', '1'}); +% 鍏抽棴鍒诲害鏍囩鐨勬棆杞 +% xticklabels('Rotation', 0); +% yticklabels('Rotation', 0); +% axis equal; +% refine; +% hold on +% network3D(dx(1),dy(1),dz(1),nx,ny,nz); +% network3D(max(xrao),max(yrao),max(zrao),1,1,1 ); +% network3D(10,10,10,2,1,1 ); +% network3D(10,10,10,6,1,2 ); +alpha(1) +view(3) +% axis([min(xrao),max(xrao),min(yrao),max(yrao),min(zrao),max(zrao)]); +% axis equal +% % hold off; +%% 纭畾瑁傜紳缂栧彿鍙婅繛鎺ユ儏鍐碉紝璁$畻浼犲绯绘暟 +if modelflag==1 %琛ㄧず鐢2014, Monifar + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,cell_divided_by_fracture_flag, flowArea, perm, matrixflag, T_diff ] = connections_2014_DP( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz, kx_matrixLayer, ky_matrixLayer, kz_matrixLayer, pori, pori_matrixLayer, Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,sigma,addflag,valid_grids ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.nmc = 2*nmc; + nc=nfc+r.nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.T_diff = T_diff; + r.vf=vf; + r.V=[vm;vm;vf]; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.flowArea=flowArea; + r.perm=perm; + r.matrixflag=matrixflag; +elseif modelflag==4 %琛ㄧず鐢 PEDFM + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_new( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==5 % 琛ㄧず瀹炵敤鍨婸EDFM + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff, flowArea, perm, matrixflag ] = connections_PEDFM_new_new( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,pori,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; + r.flowArea=flowArea; + r.perm=perm; + r.matrixflag=matrixflag; +elseif modelflag==6 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨剉alidation model + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag] = connections_unstructured_EDFM( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag)*1/2; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag)*1/2; + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==7 + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_EX1_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==8 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨剉alidation model + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX1_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==9 % EX2 涓嶅悓鎯呭喌涓 pEDFM 瑙 + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_EX2_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==10 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to3_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==11 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to2_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==12 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to4_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==13 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_TPFA_MFD( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,perm,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==14 %琛ㄧず鐢 PEDFM + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_new_twofractures( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +else + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,NTG ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; + %% 璁$畻浼犲绯绘暟 + % dxvector=ones(1,nx);dyvector=ones(1,ny);dzvector=ones(1,nz); + % [ transmatrix,transfracture ] = trans(dxvector,dyvector,dzvector ,nx,ny,nz,nf,fracnumber,lengthvsfra,disvsfra,fracstart,connect_infrac,corevsfra,matrixvsfra,raopoint,f ); + %% 璁$畻鍩鸿川涓庤缂濅箣闂寸獪娴佺殑鐩稿叧绯绘暟 + if modelflag==2 %琛ㄧず鐢2018, Rao + [ G,Gfm,Gff,Gf,Ap,Apf ]=interflowmf1(r,dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + [Ka, M, F2M , MF_coef] = transFunc_aniso(nc,coordinates, nodes, connectmf,Ap,Apf, matrixvsfra,N,T,kx, ky,kz); + r.Ka = Ka; + r.M = M; + r.F2M = F2M; + r.MF_coef = MF_coef; + elseif modelflag==5 %琛ㄧず鐢 Modified Rao, steady, 2018 + [ G,Gfm,Gff,Gf,Ap,Apf ] = interflowmf_MODIFIED(r,dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + [Ka, M, F2M , MF_coef] = transFunc_aniso_MODIFIED(nc,coordinates, nodes, connectmf,Ap,Apf, matrixvsfra,N,T,kx, ky,kz); + r.Ka = Ka; + r.M = M; + r.F2M = F2M; + r.MF_coef = MF_coef; + % [ G,Gfm,Gff,Gf,Ap,Apf,Apmt,Apft ]=interflowmf1_transient(dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + end + % [ G,Gfm,Gff,Gf,Ap,Apf ]=interflowmf1(dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + %% + + % r.MF_deltt=MF_deltt; +end +%% 璁$畻娣卞害锛堜互涓嬪钩闈负鍩哄噯璁$畻寰楀埌鐨勯珮搴︼紝鍊间负姝f暟锛 +z=[zm;zm;zf]; +r.z=z; +rpt = [ones(r.nmc, 1); zeros(nfc, 1)]; +r.rpt = rpt; +r.Porf = Porf; +pori = [pori; pori_matrixLayer; porf]; +r.pori = pori; +r.por = @(p)por(p, prpor, pori, cpor, prporf, cporf, r.rpt); +tpre=toc; +r.tpre=tpre; +end \ No newline at end of file diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/cal_gas_prop.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/cal_gas_prop.m new file mode 100644 index 0000000..7a482bb --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/cal_gas_prop.m @@ -0,0 +1,5 @@ +function [Ppr,BG,MUG] = cal_gas_prop(prg,Bgi,cg,vgi,cvg) +Ppr = (0.1:0.1:100)'; +BG = Bgi * (1 - cg * (Ppr - prg)); +MUG = vgi + cvg * (Ppr - prg); +end \ No newline at end of file diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/connections_2014_DP.asv b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/connections_2014_DP.asv new file mode 100644 index 0000000..98424b1 --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/connections_2014_DP.asv @@ -0,0 +1,579 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,cell_divided_by_fracture_flag, flowArea, perm, matrixflag] = connections_2014( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz, kx_matrixLayer, ky_matrixLayer, kz_matrixLayer, pori, pori_matrixLayer,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,sigma,addflag ) +% 璇ュ嚱鏁扮敤浠ョ粰瑁傜紳闈㈢綉鏍肩紪鍙凤紝骞跺瓨鍌ㄧ綉鏍奸棿鐨勮繛鎺ュ叧绯诲強浼犲鐜囷紝鏄墠澶勭悊鐨勫叧閿楠 +% 涓嶅悓浜庝簩缁村祵鍏ュ紡绂绘暎瑁傜紳妯″瀷锛屼笁缁存ā鍨嬩腑锛岃缂濇槸浜岀淮骞抽潰锛岀綉鏍间箣闂磋繛鎺ュ叧绯诲鏉傦紝 +%涓嶈兘绠鍗曞緱浠庡熀璐ㄧ綉鏍兼潵鍒ゅ畾锛岃嫢鎵澶勫熀璐ㄧ綉鏍间笉鐩搁偦锛屽垯瑁傜紳缃戞牸蹇呬笉鐩搁偦锛岃嫢鎵澶勫熀璐ㄧ綉鏍肩浉閭伙紝瑁傜紳缃戞牸鍗翠笉涓瀹氱浉閭 +%涓婅堪鍘熷垯鏃犲姪浜庢垜浠幓纭畾connections锛屾晠鎷熼噰鍙栦互涓嬫柟妗堬細 +%绗竴姝:鎸夌収xink鐭╅樀鍘绘帀闆惰鍚庯紝鎸夌収琛屾暟渚濇缁欐煇瑁傜紳闈㈢綉鏍肩紪鍙凤紝鍚屾椂瀛樺偍瑁傜紳缃戞牸鎵鍦ㄧ殑鍩鸿川缃戞牸搴忓彿 +%绗簩姝:瀛樺偍姣忎釜瑁傜紳缃戞牸鐨勯潰绉紝杈圭晫锛岃竟鐣岄暱搴︼紝涓績鐐瑰潗鏍囷紝涓績鐐瑰埌鍚勮竟鐣岀殑璺濈锛屼负鍚庣画鎿嶄綔鍋氬噯澶 +%绗笁姝:鎸夌収瑁傜紳缃戞牸搴忓彿椤哄簭锛屾寜鐓ц竟鐣岃繘琛屾悳绱紝濡傛灉鏈夌浉鍚岀殑杈圭晫锛屽垯涓や釜瑁傜紳缃戞牸鏄浉閭荤殑 +%matrixvsfra鐭╅樀浠h〃鍩鸿川缃戞牸涓寘鍚缂濈綉鏍肩紪鍙风殑鎯呭喌 +%fracnumber鐭╅樀锛岃搴忓彿琛ㄧず璇ヨ缂濈綉鏍肩紪鍙凤紝琛屽唴瀹硅〃绀鸿缃戞牸鍖呭惈鐨勭偣搴忓彿 +%areavsfra鐭╅樀锛岃搴忓彿琛ㄧず璇ヨ缂濈綉鏍肩紪鍙凤紝琛屽唴瀹硅〃绀鸿瑁傜紳缃戞牸鐨勯潰绉 +%姣忕浉閭讳袱鍒楁槸涓鏉¤竟锛岀劧鍚庡皢椤哄簭鍙嶈繃鏉ワ紝鍙堟槸涓ゅ垪涓鏉¤竟 +%lengthvsfra鐭╅樀锛岃搴忓彿琛ㄧず璇ヨ缂濈綉鏍肩紪鍙凤紝琛屽唴瀹硅〃绀鸿瑁傜紳缃戞牸鐨勫悇杈归暱搴 +%corevsfra鐭╅樀锛岃搴忓彿琛ㄧず璇ヨ缂濈綉鏍肩紪鍙凤紝琛屽唴瀹硅〃绀鸿瑁傜紳缃戞牸鐨勯噸蹇冨潗鏍 +%disvsfra鐭╅樀锛岃搴忓彿琛ㄧず璇ヨ缂濈綉鏍肩紪鍙凤紝琛屽唴瀹硅〃绀鸿瑁傜紳缃戞牸鐨勯噸蹇冨埌鍚勮竟鐨勮窛绂 +matrixvsfra=zeros(nx*ny*nz,10);%涓轰簡鍑忓皯璇ョ煩闃电殑澶у皬锛岃冭檻瀹為檯鎯呭喌锛屼竴涓熀璐ㄧ綉鏍间腑锛屼竴鑸笉浼氭湁瓒呰繃10涓缂濈綉鏍 +fracnumber=zeros(1000,20);%鏍规嵁瀹為檯鎯呭喌锛岃缂濈綉鏍间竴鑸笉浼氳秴杩1000涓紝涔熷彲鏍规嵁瀹為檯鎯呭喌鏀瑰彉 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf + rownum(i)=size(fracturemesh{i,1},1); +end +%% 灏嗘墍鏈夎缂濋潰缃戞牸杩炶捣鏉ヤ竴璧风紪鍙凤紝骞跺皢缂栧彿鎵旂粰鐩稿簲鐨勫熀璐ㄧ綉鏍 +q=1; +fracstart=zeros(nf+1,1);%杩欎釜琛ㄧず鍦ㄦ荤紪鍙蜂腑锛屾瘡鏉¤缂濊捣濮嬬殑鍙风爜 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; + for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q鍗虫槸璇ヨ缂濈紪鍙 + % m=floor((i+(2^nf)-1)/(2^nf)); + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); + % indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%灏嗚缂濈紪鍙烽檮缁欑浉搴旂殑鍩鸿川缃戞牸 + q=q+1; + end + end +end +fracstart(nf+1)=q;%瑁傜紳缃戞牸鎬绘暟閲+1 +fracnumber(q:1000,:)=[]; + + +%% 灏嗗寘鍚湁瑁傜紳鍗曞厓鐨勫熀璐ㄧ綉鏍肩瓫閫夊嚭鏉,骞惰繘琛屽鐞 +m=size(matrixvsfra,1); +mat_frac=[]; +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %绛涢夊嚭鍖呭惈瑁傜紳鐨勫熀璐ㄧ綉鏍 + % if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %瀛樺偍璇ュ熀璐ㄧ綉鏍肩紪鍙 + connectmf{cc,1} = i; + mat_frac=[mat_frac;i]; + %缁欒繖浜涜缂濈偣/瑁傜紳鍗曞厓鎸夐『搴忕紪鍙 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; + end +end + +%% 涓鏉℃潯瑁傜紳璁$畻瑁傜紳缃戞牸闈㈢Н銆佽竟鐣岀瓑绛 +% edgevsfra=cell(nf,1); +% Kffl=funtion_data.Kffl; +% Dffl=funtion_data.Dffl; +% kffl=zeros(q-1,1); +% dffl=zeros(q-1,1); +normalvec=zeros(q-1,3);%unit 娉曞悜閲 +areavsfra=zeros(q-1,1);%q-1鍗宠缂濈綉鏍兼绘暟 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,1);%瑁傜紳缃戞牸娓楅忕巼 +Wf=zeros(q-1,1);%瑁傜紳鍗曞厓缂濆 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%瑁傜紳缃戞牸骞冲潎浼犲锛岀敤浜庡悗缁殑绠鍖栬绠 +ave_disvsfra=zeros(q-1,1); +fcinff=zeros(q-1,1);%琛ㄧず瑁傜紳鍗曞厓鎵鍦ㄧ殑瑁傜紳闈㈠簭鍙 +zf=zeros(q-1,1);%瑁傜紳鍗曞厓楂樺害锛堜互涓嬭〃闈负鍩哄噯锛 +vf=zeros(q-1,1);%瑁傜紳鍗曞厓鐨勪綋绉 +porf=zeros(q-1,1);%瑁傜紳鍗曞厓鐨勫瓟闅欏害 +avfracFaceArea = zeros(q-1,1); +for i=1:1:q-1 %瀵硅缂濈綉鏍艰繘琛屾搷浣 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 + for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%鍥犱负鏄嚫澶氳竟褰紝鍥犳鍙浠h〃瑁傜紳缃戞牸鐨勮鍚戦噺鐨勫叡鏈夊厓绱犳湁2涓紝鍗虫湁鍏叡杈癸紱 + %濡傛灉澶氫簬2涓紝鍒欐槸鐩稿悓鐨勮缂濈綉鏍硷紝鍥犱负濡傛灉涓嶆槸锛屽垯蹇呮湁涓涓槸鍑瑰杈瑰舰锛岀煕鐩撅紝璇佹瘯锛涘鏋滃皬浜庝袱涓紝鍒欐病鏈夊叡鏈夌殑杈圭嚎 + else if (a==b) continue; %璇存槑杩欎袱涓缂濆崟鍏冨湪鍚屼竴涓熀璐ㄧ綉鏍间腑锛屽洜姝や笉搴旇绠楀湪姝ょ被涓 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%璁$畻瑁傜紳鍗曞厓鍏叡杈归暱搴 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %鍒嗗埆璁$畻涓よ缂濆崟鍏冧腑蹇冨埌鍏叡杈圭殑璺濈 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if kf(i)==0 + hartran=0;hartran_convection=0; + kij = 0; + else + tran1=kf(i)*wf(i)*lengthcat/disk; + tran2=kf(i)*wf(i)*lengthcat/disj; + % hartran=length/(disk+disj);%鍙栬皟鍜屽钩鍧 + hartran=tran1*tran2/(tran1+tran2); + k_harmony= kf(i); + hartran_convection=kf(i)/(disk+disj)^2; + kij = 2*(Kf(j)^(-1)+Kf(k)^(-1))^(-1); + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + Tff_convection=[Tff_convection;hartran_convection]; + perm_ff = [perm_ff; kij]; + flowArea_ff = [flowArea_ff; wf(i)*lengthcat]; + %璁$畻鍑烘瘡涓缂濈綉鏍奸噸蹇冨埌姣忔潯杈圭殑璺濈 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %鍘婚櫎绗竴琛岀殑闆惰 +Tff(1,:)=[]; +Tff_convection(1,:)=[]; +perm_ff(1,:)=[]; +flowArea_ff(1,:)=[]; +%% 鍦ㄥ悓涓鍩鸿川缃戞牸涓殑瑁傜紳鍗曞厓杩炴帴鎯呭喌鍙婁紶瀵肩巼璁$畻 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +Tmff_convection=zeros(1,1); +perm_mff=zeros(1,1); +flowArea_mff=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %姝ゆ椂琛ㄦ槑瑕侀噰鍙栦笅杩扮殑绠鍖栫畻娉 + % lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 姝ゆ椂鐨勮绠楁柟寮忔槸鍏堟眰姣忎釜瑁傜紳缃戞牸鐨勭畻鏈钩鍧囷紝鍐嶇畻鍖呭惈鍦ㄨ鍩鸿川缃戞牸涓殑鎵鏈夎缂濆崟鍏冪殑绠楁湳骞冲潎 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 + Tmff=[Tmff; 0];Tmff_convection=[Tmff_convection;0]; + perm_mff=[perm_mff;0];flowArea_mff=[flowArea_mff;(avfracFaceArea(fc1)+avfracFaceArea(fc2))/2]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + perm_mff=[perm_mff;(Kf(fc1)^(-1)+Kf(fc2)^(-1))^(-1)]; + flowArea_mff=[flowArea_mff;(avfracFaceArea(fc1)+avfracFaceArea(fc2))/2]; + end + end + end + end + end +end +Nmff(1,:)=[]; %鍘绘帀寮澶寸殑闆惰 +Tmff(1,:)=[]; +% Tmff =Tmff*0; +Tmff_convection(1,:)=[]; +perm_mff(1,:)=[]; +flowArea_mff(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 鍩鸿川缃戞牸鐨勮繛鎺ユ儏鍐靛強浼犲绯绘暟璁$畻 +nmc= nx * ny*nz;%鍩鸿川缃戞牸鏁扮洰 +nfc=size(fracnumber,1);%瑁傜紳鍗曞厓鏁扮洰 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm鏄熀璐ㄧ綉鏍间箣闂村瓨鍦ㄦ祦浣撲氦鎹㈢殑鎬绘暟 +% r.nf = nmm + nff;%nff鏄缂濆崟鍏冧箣闂村瓨鍦ㄦ祦浣撲氦鎹㈢殑鎬绘暟 +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%瀛樺偍鍩鸿川缃戞牸涔嬮棿瀛樺湪娴佷綋浜ゆ崲鐨勭綉鏍肩紪鍙 +T = zeros(nmm, 1);%瀛樺偍瀵瑰簲涓嶯鐭╅樀鐨勪紶瀵肩郴鏁 +T_convection = zeros(nmm, 1); +perm = zeros(nmm, 1); +flowArea = zeros(nmm, 1); +c = 0; +for k= 1 : nz + for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + T_convection(c) = 2/(1/Kx(index)+1/Kx(indexn))/(dxv(indexn)+dxv(index)); + perm(c)=2*Kx(index)*Kx(indexn)/(Kx(index) + Kx(indexn)); + flowArea(c)=dzv(index)*dyv(index); + end + end +end + +for k= 1 : nz + for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + T_convection(c) = 2/(1/Ky(index)+1/Ky(indexn))/(dyv(indexn)+dyv(index)); + perm(c)=2*Ky(index)*Ky(indexn)/(Ky(index) + Ky(indexn)); + flowArea(c)=dzv(index)*dxv(index); + end + end +end + +for i = 1 : nx + for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + T_convection(c) = 2/(1/Kz(index)+1/Kz(indexn))/(dzv(indexn)+dzv(index)); + perm(c)=2*Kz(index)*Kz(indexn)/(Kz(index) + Kz(indexn)); + flowArea(c)=dxv(index)*dyv(index); + end + end +end +%% 鍙岄噸浠嬭川澶勭悊 +%% 鍩鸿川缃戞牸鐨勮繛鎺ユ儏鍐靛強浼犲绯绘暟璁$畻 +nmc= nx * ny*nz;%鍩鸿川缃戞牸鏁扮洰 +nfc=size(fracnumber,1);%瑁傜紳鍗曞厓鏁扮洰 +rpt = [ones(nmc, 1); ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm鏄熀璐ㄧ綉鏍间箣闂村瓨鍦ㄦ祦浣撲氦鎹㈢殑鎬绘暟 +% r.nf = nmm + nff;%nff鏄缂濆崟鍏冧箣闂村瓨鍦ㄦ祦浣撲氦鎹㈢殑鎬绘暟 +Kx_matrixLayer=kx_matrixLayer.*ones(nmc,1); +Ky_matrixLayer=ky_matrixLayer.*ones(nmc,1); +Kz_matrixLayer=kz_matrixLayer.*ones(nmc,1); +N_matrixLayer = zeros(nmm, 2);% +T_matrixLayer = zeros(nmm, 1);% +T_convection_matrixLayer = zeros(nmm, 1); +perm_matrixLayer = zeros(nmm, 1); +flowArea_matrixLayer = zeros(nmm, 1); +c = 0; +for k= 1 : nz + for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N_matrixLayer(c, :) = [index, indexn]; + T_matrixLayer(c) = 2 * dzv(index)*dyv(index)*Kx_matrixLayer(index)*Kx_matrixLayer(indexn)*NTG(index)*NTG(indexn)/(Kx_matrixLayer(index)*dxv(indexn)*NTG(index) + Kx_matrixLayer(indexn)*dxv(index)*NTG(indexn)); + T_convection_matrixLayer(c) = 2/(1/Kx_matrixLayer(index)+1/Kx_matrixLayer(indexn))/(dxv(indexn)+dxv(index)); + perm_matrixLayer(c)=2*Kx_matrixLayer(index)*Kx_matrixLayer(indexn)/(Kx_matrixLayer(index) + Kx_matrixLayer(indexn)); + flowArea_matrixLayer(c)=dzv(index)*dyv(index); + end + end +end + +for k= 1 : nz + for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N_matrixLayer(c, :) = [index, indexn]; + T_matrixLayer(c) = 2 * dzv(index)*dxv(index)*Ky_matrixLayer(index)*Ky_matrixLayer(indexn)/(Ky_matrixLayer(index)*dyv(indexn) + Ky_matrixLayer(indexn)*dyv(index)); + T_convection_matrixLayer(c) = 2/(1/Ky_matrixLayer(index)+1/Ky_matrixLayer(indexn))/(dyv(indexn)+dyv(index)); + perm_matrixLayer(c)=2*Ky_matrixLayer(index)*Ky_matrixLayer(indexn)/(Ky_matrixLayer(index) + Ky_matrixLayer(indexn)); + flowArea_matrixLayer(c)=dzv(index)*dxv(index); + end + end +end + +for i = 1 : nx + for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N_matrixLayer(c, :) = [index, index + nx*ny]; + T_matrixLayer(c) = 2 * dxv(index)*dyv(index)*Kz_matrixLayer(index)*Kz_matrixLayer(indexn)/(Kz_matrixLayer(index)*dzv(indexn) + Kz_matrixLayer(indexn)*dzv(index)); + T_convection_matrixLayer(c) = 2/(1/Kz_matrixLayer(index)+1/Kz_matrixLayer(indexn))/(dzv(indexn)+dzv(index)); + perm_matrixLayer(c)=2*Kz_matrixLayer(index)*Kz_matrixLayer(indexn)/(Kz_matrixLayer(index) + Kz_matrixLayer(indexn)); + flowArea_matrixLayer(c)=dxv(index)*dyv(index); + end + end +end +%% 鏋勫缓鍩鸿川灞傜綉鏍间笌瑁傜紳灞傜綉鏍奸棿鐨勮繛鎺 +N_fractureMatrixLayer = zeros(nmc, 2);% +T_fractureMatrixLayer = zeros(nmc, 1);% +T_convection_fractureMatrixLayer = zeros(nmc, 1); +perm_fractureMatrixLayer = zeros(nmc, 1); +flowArea_fractureMatrixLayer = zeros(nmc, 1); +for k= 1 : nz + for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nmc; + N_fractureMatrixLayer(c, :) = [index, indexn]; + T_fractureMatrixLayer(c) = dzv(index)*dyv(index)*dxv(index)*Kx(index)*sigma(c); + T_convection_fractureMatrixLayer(c) = 2/(1/Kx_matrixLayer(index)+1/Kx_matrixLayer(indexn)); + perm_fractureMatrixLayer(c)=2*Kx_matrixLayer(index)*Kx_matrixLayer(indexn)/(Kx_matrixLayer(index) + Kx_matrixLayer(indexn)); + flowArea_fractureMatrixLayer(c)=dzv(index)*dyv(index); + end + end +end +%% 鎸夌収2014骞寸殑鏂规硶锛屽皢绐滄祦澶勭悊涓轰笌涓婅堪鐩镐技鐨勫舰寮 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +Tinterflow_convection=[]; +cell_divided_by_fracture_flag = []; +perm_interflow=[]; +flowArea_interflow=[]; +for i=1:nx*ny*nz %鍩鸿川缃戞牸缂栧彿 + flag = 0; + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + flag = flag + 1; + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + % kcell = sqrt(10*100)*1e-3; + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=areavsfra(matrixvsfra(i,j)); + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); + % dn=abs(dn);%褰卞搷鏁板肩Н鍒嗘晥鐜 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + % raoT=Knnc*Annc/Dn; + % raoT_convection=2*Knnc/Dn^2; + % Tinterflow=[Tinterflow;raoT]; + % Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + raoT1 = 2*kcell*Annc/Dn; + raoT2 = Kf(matrixvsfra(i,j))*Annc/(Wf(matrixvsfra(i,j))/2); + raoT = (raoT1^-1+raoT2^-1)^-1; + Tinterflow=[Tinterflow;raoT]; + raoT1_conv = kcell/Dn^2; + raoT2_conv = Kf(matrixvsfra(i,j))/(Wf(matrixvsfra(i,j))/2)^2; + raoT_convection = (raoT1_conv^-1+raoT2_conv^-1)^-1; + Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + perm_mf_this = kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + perm_interflow = [perm_interflow; perm_mf_this]; + flowArea_interflow = [flowArea_interflow; Annc]; + end + end + if flag >0 + cell_divided_by_fracture_flag = [cell_divided_by_fracture_flag; i]; + end +end +%% 鎸夌収2014骞寸殑鏂规硶锛屽皢绐滄祦澶勭悊涓轰笌涓婅堪鐩镐技鐨勫舰寮 +% syms x y z; +% Ninterflow=[]; +% Tinterflow=[]; +% for i=1:nx*ny*nz %鍩鸿川缃戞牸缂栧彿 +% for j=1:10 +% if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell +% Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3); +% K1=Kf(matrixvsfra(i,j));d1=Wf(matrixvsfra(i,j)); +% K2=kffl(matrixvsfra(i,j));d2=dffl(matrixvsfra(i,j)); +% Annc=2*areavsfra(matrixvsfra(i,j)); +% fracore=corevsfra(matrixvsfra(i,j),:); +% matnodes=nodes(i,:); +% verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); +% matcore=mean(verco);d0=matcore-fracore; +% dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% % dn=abs(dn);%褰卞搷鏁板肩Н鍒嗘晥鐜 +% dn=sqrt(dn^2); +% dn=matlabFunction(dn); +% if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 +% Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(2)~=0 +% Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(3)~=0 +% Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 && norvec(3)~=0 +% Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 +% Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 +% Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(3)~=0 +% Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% end +% end +% end +% end +% end +% end +% end +% raoT=((Kcell*Annc/(Dn-d2))^(-1)+(K2*Annc/d2)^(-1)+(K1*Annc/d1)^(-1))^(-1); +% Tinterflow=[Tinterflow;raoT]; +% end +% end +% end +%% 鍙岄噸浠嬭川澶勭悊 + +%% 鎶婁笂杩颁笁绉嶆儏鍐电殑鐭╅樀鍒嗗埆鍙犲姞璧锋潵 +matrixflag = [ones(size(T,1),1); zeros(size(Tmff,1),1); zeros(size(Tff,1),1); ones(size(Tinterflow,1),1);]; +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;]; +T = [T; Tmff; Tff;Tinterflow;]; +T_convection = [T_convection;Tmff_convection; Tff_convection;Tinterflow_convection;]; +perm = [perm; perm_mff; perm_ff;perm_interflow; ]; +flowArea = [flowArea; flowArea_mff; flowArea_ff;flowArea_interflow;]; +nex=size(N,1); +%% 杞埌CMG鎴栬匛CLIPSE杩涜璁$畻 +% [ Data_for_ECLIPSE ] = pEDFM_to_CMG_horizontalFractureWell(dxv,dyv,dzv,kx,ky,kz,pori,Kf,Wf,vf,porf,N,T); +% [ Data_for_ECLIPSE ] = pEDFM_to_CMG_horizontalFractureWell_net_pay(dxv,dyv,dzv,kx,ky,kz,pori,Kf,Wf,vf,porf,N,T); +end + diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/connections_2014_DP.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/connections_2014_DP.m new file mode 100644 index 0000000..c92c824 --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/connections_2014_DP.m @@ -0,0 +1,625 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,cell_divided_by_fracture_flag, flowArea, perm, matrixflag, T_diff] = connections_2014( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz, kx_matrixLayer, ky_matrixLayer, kz_matrixLayer, pori, pori_matrixLayer,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,sigma,addflag,invalid_grids ) +% 璇ュ嚱鏁扮敤浠ョ粰瑁傜紳闈㈢綉鏍肩紪鍙凤紝骞跺瓨鍌ㄧ綉鏍奸棿鐨勮繛鎺ュ叧绯诲強浼犲鐜囷紝鏄墠澶勭悊鐨勫叧閿楠 +% 涓嶅悓浜庝簩缁村祵鍏ュ紡绂绘暎瑁傜紳妯″瀷锛屼笁缁存ā鍨嬩腑锛岃缂濇槸浜岀淮骞抽潰锛岀綉鏍间箣闂磋繛鎺ュ叧绯诲鏉傦紝 +%涓嶈兘绠鍗曞緱浠庡熀璐ㄧ綉鏍兼潵鍒ゅ畾锛岃嫢鎵澶勫熀璐ㄧ綉鏍间笉鐩搁偦锛屽垯瑁傜紳缃戞牸蹇呬笉鐩搁偦锛岃嫢鎵澶勫熀璐ㄧ綉鏍肩浉閭伙紝瑁傜紳缃戞牸鍗翠笉涓瀹氱浉閭 +%涓婅堪鍘熷垯鏃犲姪浜庢垜浠幓纭畾connections锛屾晠鎷熼噰鍙栦互涓嬫柟妗堬細 +%绗竴姝:鎸夌収xink鐭╅樀鍘绘帀闆惰鍚庯紝鎸夌収琛屾暟渚濇缁欐煇瑁傜紳闈㈢綉鏍肩紪鍙凤紝鍚屾椂瀛樺偍瑁傜紳缃戞牸鎵鍦ㄧ殑鍩鸿川缃戞牸搴忓彿 +%绗簩姝:瀛樺偍姣忎釜瑁傜紳缃戞牸鐨勯潰绉紝杈圭晫锛岃竟鐣岄暱搴︼紝涓績鐐瑰潗鏍囷紝涓績鐐瑰埌鍚勮竟鐣岀殑璺濈锛屼负鍚庣画鎿嶄綔鍋氬噯澶 +%绗笁姝:鎸夌収瑁傜紳缃戞牸搴忓彿椤哄簭锛屾寜鐓ц竟鐣岃繘琛屾悳绱紝濡傛灉鏈夌浉鍚岀殑杈圭晫锛屽垯涓や釜瑁傜紳缃戞牸鏄浉閭荤殑 +%matrixvsfra鐭╅樀浠h〃鍩鸿川缃戞牸涓寘鍚缂濈綉鏍肩紪鍙风殑鎯呭喌 +%fracnumber鐭╅樀锛岃搴忓彿琛ㄧず璇ヨ缂濈綉鏍肩紪鍙凤紝琛屽唴瀹硅〃绀鸿缃戞牸鍖呭惈鐨勭偣搴忓彿 +%areavsfra鐭╅樀锛岃搴忓彿琛ㄧず璇ヨ缂濈綉鏍肩紪鍙凤紝琛屽唴瀹硅〃绀鸿瑁傜紳缃戞牸鐨勯潰绉 +%姣忕浉閭讳袱鍒楁槸涓鏉¤竟锛岀劧鍚庡皢椤哄簭鍙嶈繃鏉ワ紝鍙堟槸涓ゅ垪涓鏉¤竟 +%lengthvsfra鐭╅樀锛岃搴忓彿琛ㄧず璇ヨ缂濈綉鏍肩紪鍙凤紝琛屽唴瀹硅〃绀鸿瑁傜紳缃戞牸鐨勫悇杈归暱搴 +%corevsfra鐭╅樀锛岃搴忓彿琛ㄧず璇ヨ缂濈綉鏍肩紪鍙凤紝琛屽唴瀹硅〃绀鸿瑁傜紳缃戞牸鐨勯噸蹇冨潗鏍 +%disvsfra鐭╅樀锛岃搴忓彿琛ㄧず璇ヨ缂濈綉鏍肩紪鍙凤紝琛屽唴瀹硅〃绀鸿瑁傜紳缃戞牸鐨勯噸蹇冨埌鍚勮竟鐨勮窛绂 +matrixvsfra=zeros(nx*ny*nz,10);%涓轰簡鍑忓皯璇ョ煩闃电殑澶у皬锛岃冭檻瀹為檯鎯呭喌锛屼竴涓熀璐ㄧ綉鏍间腑锛屼竴鑸笉浼氭湁瓒呰繃10涓缂濈綉鏍 +fracnumber=zeros(1000,20);%鏍规嵁瀹為檯鎯呭喌锛岃缂濈綉鏍间竴鑸笉浼氳秴杩1000涓紝涔熷彲鏍规嵁瀹為檯鎯呭喌鏀瑰彉 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf + rownum(i)=size(fracturemesh{i,1},1); +end +%% 灏嗘墍鏈夎缂濋潰缃戞牸杩炶捣鏉ヤ竴璧风紪鍙凤紝骞跺皢缂栧彿鎵旂粰鐩稿簲鐨勫熀璐ㄧ綉鏍 +q=1; +fracstart=zeros(nf+1,1);%杩欎釜琛ㄧず鍦ㄦ荤紪鍙蜂腑锛屾瘡鏉¤缂濊捣濮嬬殑鍙风爜 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; + for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q鍗虫槸璇ヨ缂濈紪鍙 + % m=floor((i+(2^nf)-1)/(2^nf)); + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); + % indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%灏嗚缂濈紪鍙烽檮缁欑浉搴旂殑鍩鸿川缃戞牸 + q=q+1; + end + end +end +fracstart(nf+1)=q;%瑁傜紳缃戞牸鎬绘暟閲+1 +fracnumber(q:1000,:)=[]; + + +%% 灏嗗寘鍚湁瑁傜紳鍗曞厓鐨勫熀璐ㄧ綉鏍肩瓫閫夊嚭鏉,骞惰繘琛屽鐞 +m=size(matrixvsfra,1); +mat_frac=[]; +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %绛涢夊嚭鍖呭惈瑁傜紳鐨勫熀璐ㄧ綉鏍 + % if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %瀛樺偍璇ュ熀璐ㄧ綉鏍肩紪鍙 + connectmf{cc,1} = i; + mat_frac=[mat_frac;i]; + %缁欒繖浜涜缂濈偣/瑁傜紳鍗曞厓鎸夐『搴忕紪鍙 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; + end +end + +%% 涓鏉℃潯瑁傜紳璁$畻瑁傜紳缃戞牸闈㈢Н銆佽竟鐣岀瓑绛 +% edgevsfra=cell(nf,1); +% Kffl=funtion_data.Kffl; +% Dffl=funtion_data.Dffl; +% kffl=zeros(q-1,1); +% dffl=zeros(q-1,1); +normalvec=zeros(q-1,3);%unit 娉曞悜閲 +areavsfra=zeros(q-1,1);%q-1鍗宠缂濈綉鏍兼绘暟 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,1);%瑁傜紳缃戞牸娓楅忕巼 +Wf=zeros(q-1,1);%瑁傜紳鍗曞厓缂濆 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +tran_no_perm=zeros(q-1,10); +avtran=zeros(q-1,1);%瑁傜紳缃戞牸骞冲潎浼犲锛岀敤浜庡悗缁殑绠鍖栬绠 +ave_disvsfra=zeros(q-1,1); +fcinff=zeros(q-1,1);%琛ㄧず瑁傜紳鍗曞厓鎵鍦ㄧ殑瑁傜紳闈㈠簭鍙 +zf=zeros(q-1,1);%瑁傜紳鍗曞厓楂樺害锛堜互涓嬭〃闈负鍩哄噯锛 +vf=zeros(q-1,1);%瑁傜紳鍗曞厓鐨勪綋绉 +porf=zeros(q-1,1);%瑁傜紳鍗曞厓鐨勫瓟闅欏害 +avfracFaceArea = zeros(q-1,1); +for i=1:1:q-1 %瀵硅缂濈綉鏍艰繘琛屾搷浣 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 + for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%鍥犱负鏄嚫澶氳竟褰紝鍥犳鍙浠h〃瑁傜紳缃戞牸鐨勮鍚戦噺鐨勫叡鏈夊厓绱犳湁2涓紝鍗虫湁鍏叡杈癸紱 + %濡傛灉澶氫簬2涓紝鍒欐槸鐩稿悓鐨勮缂濈綉鏍硷紝鍥犱负濡傛灉涓嶆槸锛屽垯蹇呮湁涓涓槸鍑瑰杈瑰舰锛岀煕鐩撅紝璇佹瘯锛涘鏋滃皬浜庝袱涓紝鍒欐病鏈夊叡鏈夌殑杈圭嚎 + else if (a==b) continue; %璇存槑杩欎袱涓缂濆崟鍏冨湪鍚屼竴涓熀璐ㄧ綉鏍间腑锛屽洜姝や笉搴旇绠楀湪姝ょ被涓 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%璁$畻瑁傜紳鍗曞厓鍏叡杈归暱搴 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %鍒嗗埆璁$畻涓よ缂濆崟鍏冧腑蹇冨埌鍏叡杈圭殑璺濈 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if kf(i)==0 + hartran=0;hartran_convection=0; + kij = 0; + else + tran1=kf(i)*wf(i)*lengthcat/disk; + tran2=kf(i)*wf(i)*lengthcat/disj; + % hartran=length/(disk+disj);%鍙栬皟鍜屽钩鍧 + hartran=tran1*tran2/(tran1+tran2); + tran1_diff=wf(i)*lengthcat/disk; + tran2_diff=wf(i)*lengthcat/disj; + % hartran=length/(disk+disj);%鍙栬皟鍜屽钩鍧 + hartran_diff=tran1_diff*tran2_diff/(tran1_diff+tran2_diff); + k_harmony= kf(i); + hartran_convection=kf(i)/(disk+disj)^2; + kij = 2*(Kf(j)^(-1)+Kf(k)^(-1))^(-1); + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + Tff_diff=[Tff_diff;hartran_diff]; + Tff_convection=[Tff_convection;hartran_convection]; + perm_ff = [perm_ff; kij]; + flowArea_ff = [flowArea_ff; wf(i)*lengthcat]; + %璁$畻鍑烘瘡涓缂濈綉鏍奸噸蹇冨埌姣忔潯杈圭殑璺濈 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %鍘婚櫎绗竴琛岀殑闆惰 +Tff(1,:)=[]; +Tff_convection(1,:)=[]; +Tff_diff(1,:)=[]; +perm_ff(1,:)=[]; +flowArea_ff(1,:)=[]; +%% 鍦ㄥ悓涓鍩鸿川缃戞牸涓殑瑁傜紳鍗曞厓杩炴帴鎯呭喌鍙婁紶瀵肩巼璁$畻 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +Tmff_diff=zeros(1,1); +Tmff_convection=zeros(1,1); +perm_mff=zeros(1,1); +flowArea_mff=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %姝ゆ椂琛ㄦ槑瑕侀噰鍙栦笅杩扮殑绠鍖栫畻娉 + % lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 姝ゆ椂鐨勮绠楁柟寮忔槸鍏堟眰姣忎釜瑁傜紳缃戞牸鐨勭畻鏈钩鍧囷紝鍐嶇畻鍖呭惈鍦ㄨ鍩鸿川缃戞牸涓殑鎵鏈夎缂濆崟鍏冪殑绠楁湳骞冲潎 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc));sumtran_no_perm=sum(fcff{1,9}(allfc)); + if sumtran==0 + Tmff=[Tmff; 0];Tmff_convection=[Tmff_convection;0]; + Tmff_diff=[Tmff_diff;0]; + perm_mff=[perm_mff;0];flowArea_mff=[flowArea_mff;(avfracFaceArea(fc1)+avfracFaceArea(fc2))/2]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + Tmff_diff=[Tmff_diff;fcff{1,9}(fc1)*fcff{1,9}(fc2)/sumtran_no_perm]; + perm_mff=[perm_mff;(Kf(fc1)^(-1)+Kf(fc2)^(-1))^(-1)]; + flowArea_mff=[flowArea_mff;(avfracFaceArea(fc1)+avfracFaceArea(fc2))/2]; + end + end + end + end + end +end +Nmff(1,:)=[]; %鍘绘帀寮澶寸殑闆惰 +Tmff(1,:)=[]; +% Tmff =Tmff*0; +Tmff_convection(1,:)=[]; +Tmff_diff(1,:)=[]; +perm_mff(1,:)=[]; +flowArea_mff(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 鍩鸿川缃戞牸鐨勮繛鎺ユ儏鍐靛強浼犲绯绘暟璁$畻 +nmc= nx * ny*nz;%鍩鸿川缃戞牸鏁扮洰 +nfc=size(fracnumber,1);%瑁傜紳鍗曞厓鏁扮洰 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm鏄熀璐ㄧ綉鏍间箣闂村瓨鍦ㄦ祦浣撲氦鎹㈢殑鎬绘暟 +% r.nf = nmm + nff;%nff鏄缂濆崟鍏冧箣闂村瓨鍦ㄦ祦浣撲氦鎹㈢殑鎬绘暟 +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%瀛樺偍鍩鸿川缃戞牸涔嬮棿瀛樺湪娴佷綋浜ゆ崲鐨勭綉鏍肩紪鍙 +T = zeros(nmm, 1);%瀛樺偍瀵瑰簲涓嶯鐭╅樀鐨勪紶瀵肩郴鏁 +T_convection = zeros(nmm, 1); +T_diff = zeros(nmm, 1); +perm = zeros(nmm, 1); +flowArea = zeros(nmm, 1); +c = 0; +for k= 1 : nz + for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + T_convection(c) = 2/(1/Kx(index)+1/Kx(indexn))/(dxv(indexn)+dxv(index)); + perm(c)=2*Kx(index)*Kx(indexn)/(Kx(index) + Kx(indexn)); + T_diff(c)=dzv(index)*dyv(index)/(2/(1/dxv(indexn)+1/dxv(index))); + flowArea(c)=dzv(index)*dyv(index); + end + end +end + +for k= 1 : nz + for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + T_convection(c) = 2/(1/Ky(index)+1/Ky(indexn))/(dyv(indexn)+dyv(index)); + perm(c)=2*Ky(index)*Ky(indexn)/(Ky(index) + Ky(indexn)); + T_diff(c)=dzv(index)*dxv(index)/(2/(1/dyv(indexn)+1/dyv(index))); + flowArea(c)=dzv(index)*dxv(index); + end + end +end + +for i = 1 : nx + for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + T_convection(c) = 2/(1/Kz(index)+1/Kz(indexn))/(dzv(indexn)+dzv(index)); + perm(c)=2*Kz(index)*Kz(indexn)/(Kz(index) + Kz(indexn)); + T_diff(c)=dxv(index)*dyv(index)/(2/(1/dzv(indexn)+1/dzv(index))); + flowArea(c)=dxv(index)*dyv(index); + end + end +end +%% 鍙岄噸浠嬭川澶勭悊 +%% 鍩鸿川缃戞牸鐨勮繛鎺ユ儏鍐靛強浼犲绯绘暟璁$畻 +N_matrixLayer = [];% +T_matrixLayer = [];% +T_convection_matrixLayer = []; +T_diff_matrixLayer = []; +perm_matrixLayer = []; +flowArea_matrixLayer = []; +% % % nmc= nx * ny*nz;%鍩鸿川缃戞牸鏁扮洰 +% % % nfc=size(fracnumber,1);%瑁傜紳鍗曞厓鏁扮洰 +% % % rpt = [ones(nmc, 1); ones(nmc, 1); zeros(nfc, 1)]; +% % % % r.rpt = rpt; +% % % nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm鏄熀璐ㄧ綉鏍间箣闂村瓨鍦ㄦ祦浣撲氦鎹㈢殑鎬绘暟 +% % % % r.nf = nmm + nff;%nff鏄缂濆崟鍏冧箣闂村瓨鍦ㄦ祦浣撲氦鎹㈢殑鎬绘暟 +% % % Kx_matrixLayer=kx_matrixLayer.*ones(nmc,1); +% % % Ky_matrixLayer=ky_matrixLayer.*ones(nmc,1); +% % % Kz_matrixLayer=kz_matrixLayer.*ones(nmc,1); +% % % N_matrixLayer = zeros(nmm, 2);% +% % % T_matrixLayer = zeros(nmm, 1);% +% % % T_convection_matrixLayer = zeros(nmm, 1); +% % % T_diff_matrixLayer = zeros(nmm, 1); +% % % perm_matrixLayer = zeros(nmm, 1); +% % % flowArea_matrixLayer = zeros(nmm, 1); +% % % c = 0; +% % % for k= 1 : nz +% % % for j = 1 : ny +% % % for i = 1 : nx - 1 +% % % c = c + 1; +% % % index = i + (j - 1) * nx + (k - 1) * nx * ny; +% % % indexn = index + 1; +% % % N_matrixLayer(c, :) = [index+nmc, indexn+nmc]; +% % % T_matrixLayer(c) = 2 * dzv(index)*dyv(index)*Kx_matrixLayer(index)*Kx_matrixLayer(indexn)*NTG(index)*NTG(indexn)/(Kx_matrixLayer(index)*dxv(indexn)*NTG(index) + Kx_matrixLayer(indexn)*dxv(index)*NTG(indexn)); +% % % T_convection_matrixLayer(c) = 2/(1/Kx_matrixLayer(index)+1/Kx_matrixLayer(indexn))/(dxv(indexn)+dxv(index)); +% % % perm_matrixLayer(c)=2*Kx_matrixLayer(index)*Kx_matrixLayer(indexn)/(Kx_matrixLayer(index) + Kx_matrixLayer(indexn)); +% % % T_diff_matrixLayer(c)=dzv(index)*dyv(index)/(2/(1/dxv(indexn)+1/dxv(index))); +% % % flowArea_matrixLayer(c)=dzv(index)*dyv(index); +% % % end +% % % end +% % % end +% % % +% % % for k= 1 : nz +% % % for i = 1 : nx +% % % for j = 1 : ny - 1 +% % % c = c + 1; +% % % index = i + (j - 1) * nx + (k - 1) * nx * ny; +% % % indexn = index + nx; +% % % N_matrixLayer(c, :) = [index+nmc, indexn+nmc]; +% % % T_matrixLayer(c) = 2 * dzv(index)*dxv(index)*Ky_matrixLayer(index)*Ky_matrixLayer(indexn)/(Ky_matrixLayer(index)*dyv(indexn) + Ky_matrixLayer(indexn)*dyv(index)); +% % % T_convection_matrixLayer(c) = 2/(1/Ky_matrixLayer(index)+1/Ky_matrixLayer(indexn))/(dyv(indexn)+dyv(index)); +% % % perm_matrixLayer(c)=2*Ky_matrixLayer(index)*Ky_matrixLayer(indexn)/(Ky_matrixLayer(index) + Ky_matrixLayer(indexn)); +% % % T_diff_matrixLayer(c)=dzv(index)*dxv(index)/(2/(1/dyv(indexn)+1/dyv(index))); +% % % flowArea_matrixLayer(c)=dzv(index)*dxv(index); +% % % end +% % % end +% % % end +% % % +% % % for i = 1 : nx +% % % for j = 1 : ny +% % % for k= 1: nz-1 +% % % c = c + 1; +% % % index = i + (j - 1) * nx + (k - 1) * nx * ny; +% % % indexn = index + nx * ny; +% % % N_matrixLayer(c, :) = [index+nmc, index + nx*ny+nmc]; +% % % T_matrixLayer(c) = 2 * dxv(index)*dyv(index)*Kz_matrixLayer(index)*Kz_matrixLayer(indexn)/(Kz_matrixLayer(index)*dzv(indexn) + Kz_matrixLayer(indexn)*dzv(index)); +% % % T_convection_matrixLayer(c) = 2/(1/Kz_matrixLayer(index)+1/Kz_matrixLayer(indexn))/(dzv(indexn)+dzv(index)); +% % % perm_matrixLayer(c)=2*Kz_matrixLayer(index)*Kz_matrixLayer(indexn)/(Kz_matrixLayer(index) + Kz_matrixLayer(indexn)); +% % % T_diff_matrixLayer(c)=dxv(index)*dyv(index)/(2/(1/dzv(indexn)+1/dzv(index))); +% % % flowArea_matrixLayer(c)=dxv(index)*dyv(index); +% % % end +% % % end +% % % end +%% 鏋勫缓鍩鸿川灞傜綉鏍间笌瑁傜紳灞傜綉鏍奸棿鐨勮繛鎺 +N_fractureMatrixLayer = zeros(nmc, 2);% +T_fractureMatrixLayer = zeros(nmc, 1);% +T_convection_fractureMatrixLayer = zeros(nmc, 1); +T_diff_fractureMatrixLayer = zeros(nmc, 1); +perm_fractureMatrixLayer = zeros(nmc, 1); +flowArea_fractureMatrixLayer = zeros(nmc, 1); +c = 0; +for k= 1 : nz + for j = 1 : ny + for i = 1 : nx + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nmc; + N_fractureMatrixLayer(c, :) = [index, indexn]; + perm_fractureMatrixLayer(c)=(Kx(index)*Ky(index)*Kz(index))^(1/3); + T_fractureMatrixLayer(c) = dzv(index)*dyv(index)*dxv(index)*(Kx(index)*Ky(index)*Kz(index))^(1/3)*sigma(c); + T_convection_fractureMatrixLayer(c) = dzv(index)*dyv(index)*dxv(index)*Kx(index)*sigma(c)*dzv(index); + T_diff_fractureMatrixLayer(c) = dzv(index)*dyv(index)*dxv(index)*sigma(c); + flowArea_fractureMatrixLayer(c)=dxv(index)*dyv(index); + end + end +end +%% 鎸夌収2014骞寸殑鏂规硶锛屽皢绐滄祦澶勭悊涓轰笌涓婅堪鐩镐技鐨勫舰寮 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +Tinterflow_convection=[]; +Tinterflow_diff=[]; +cell_divided_by_fracture_flag = []; +perm_interflow=[]; +flowArea_interflow=[]; +for i=1:nx*ny*nz %鍩鸿川缃戞牸缂栧彿 + flag = 0; + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + flag = flag + 1; + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+2*nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + % kcell = sqrt(10*100)*1e-3; + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=areavsfra(matrixvsfra(i,j)); + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); + % dn=abs(dn);%褰卞搷鏁板肩Н鍒嗘晥鐜 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + % raoT=Knnc*Annc/Dn; + % raoT_convection=2*Knnc/Dn^2; + % Tinterflow=[Tinterflow;raoT]; + % Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + raoT1 = 2*kcell*Annc/Dn; + raoT2 = Kf(matrixvsfra(i,j))*Annc/(Wf(matrixvsfra(i,j))/2); + raoT = (raoT1^-1+raoT2^-1)^-1; + Tinterflow=[Tinterflow;raoT]; + raoT1_conv = kcell/Dn^2; + raoT2_conv = Kf(matrixvsfra(i,j))/(Wf(matrixvsfra(i,j))/2)^2; + raoT_convection = (raoT1_conv^-1+raoT2_conv^-1)^-1; + Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + Tinterflow_diff=[Tinterflow_diff;((2*Annc/Dn)^-1+(Annc/(Wf(matrixvsfra(i,j))/2))^-1)^-1;]; + perm_mf_this = kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + perm_interflow = [perm_interflow; perm_mf_this]; + flowArea_interflow = [flowArea_interflow; Annc]; + end + end + if flag >0 + cell_divided_by_fracture_flag = [cell_divided_by_fracture_flag; i]; + end +end +%% 鎸夌収2014骞寸殑鏂规硶锛屽皢绐滄祦澶勭悊涓轰笌涓婅堪鐩镐技鐨勫舰寮 +% syms x y z; +% Ninterflow=[]; +% Tinterflow=[]; +% for i=1:nx*ny*nz %鍩鸿川缃戞牸缂栧彿 +% for j=1:10 +% if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell +% Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3); +% K1=Kf(matrixvsfra(i,j));d1=Wf(matrixvsfra(i,j)); +% K2=kffl(matrixvsfra(i,j));d2=dffl(matrixvsfra(i,j)); +% Annc=2*areavsfra(matrixvsfra(i,j)); +% fracore=corevsfra(matrixvsfra(i,j),:); +% matnodes=nodes(i,:); +% verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); +% matcore=mean(verco);d0=matcore-fracore; +% dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% % dn=abs(dn);%褰卞搷鏁板肩Н鍒嗘晥鐜 +% dn=sqrt(dn^2); +% dn=matlabFunction(dn); +% if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 +% Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(2)~=0 +% Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(3)~=0 +% Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 && norvec(3)~=0 +% Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 +% Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 +% Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(3)~=0 +% Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% end +% end +% end +% end +% end +% end +% end +% raoT=((Kcell*Annc/(Dn-d2))^(-1)+(K2*Annc/d2)^(-1)+(K1*Annc/d1)^(-1))^(-1); +% Tinterflow=[Tinterflow;raoT]; +% end +% end +% end +%% 鍙岄噸浠嬭川澶勭悊 + +%% 鎶婁笂杩颁笁绉嶆儏鍐电殑鐭╅樀鍒嗗埆鍙犲姞璧锋潵 +matrixflag = [ones(size(T,1),1); ones(size(T_matrixLayer,1),1); ones(size(T_fractureMatrixLayer,1),1); zeros(size(Tmff,1),1); zeros(size(Tff,1),1); ones(size(Tinterflow,1),1);]; +N = [N; N_matrixLayer; N_fractureMatrixLayer; Nmff+2*nmc; Nff+2*nmc;Ninterflow;]; +T = [T; T_matrixLayer; T_fractureMatrixLayer; Tmff; Tff;Tinterflow;]; +T_convection = [T_convection;T_convection_matrixLayer; T_convection_fractureMatrixLayer; Tmff_convection; Tff_convection;Tinterflow_convection;]; +T_diff = [T_diff;T_diff_matrixLayer;T_diff_fractureMatrixLayer;Tmff_diff; Tff_diff;Tinterflow_diff;]; +perm = [perm; perm_matrixLayer; perm_fractureMatrixLayer; perm_mff; perm_ff;perm_interflow; ]; +flowArea = [flowArea; flowArea_matrixLayer; flowArea_fractureMatrixLayer; flowArea_mff; flowArea_ff;flowArea_interflow;]; +% +% deleted_rows = []; +% for i = 1:size(N,1) +% if ismember(N(i,1),invalid_grids) || ismember(N(i,2),invalid_grids) +% deleted_rows = [deleted_rows; i]; +% end +% end +% N(deleted_rows,:) = []; +% T(deleted_rows,:) = 0; +% T_convection(deleted_rows,:) = 0; +% T_diff(deleted_rows,:) = 0; +% perm(deleted_rows,:) = 0; +% flowArea(deleted_rows,:) = 0; +nex=size(N,1); +%% 杞埌CMG鎴栬匛CLIPSE杩涜璁$畻 +% [ Data_for_ECLIPSE ] = pEDFM_to_CMG_horizontalFractureWell(dxv,dyv,dzv,kx,ky,kz,pori,Kf,Wf,vf,porf,N,T); +% [ Data_for_ECLIPSE ] = pEDFM_to_CMG_horizontalFractureWell_net_pay(dxv,dyv,dzv,kx,ky,kz,pori,Kf,Wf,vf,porf,N,T); +end + diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/fluidPVT.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/fluidPVT.m new file mode 100644 index 0000000..917e510 --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/fluidPVT.m @@ -0,0 +1,18 @@ +function f = fluidPVT(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, SW, KRG, KRW, PCGL, SWF, KRGF, KRWF, PCGLF, density_g_sc, ifpcgl, rpt, cs_data, csa_data, cb_data, cba_data) +% 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(p, Bwi, prw, cw); +f.Bg = @(p) Bg(p, BG, Ppr); +f.muw = @(p) muw(p, vwi, prw, cvw); +f.mug = @(p) mug(p, MUG, Ppr); +f.krrg = @(sw) krrg(sw, SW, KRG, SWF, KRGF, rpt); +f.krw = @(sw) krw(sw, SW, KRW, SWF, KRWF, rpt); +f.pcgl = @(sw) pcgl(sw, SW, PCGL, SWF, PCGLF, rpt); +f.cs_absorb = @(cs) cs_absorb_f(cs, cs_data, csa_data); +f.cb_absorb = @(cb) cb_absorb_f(cb, cb_data, cba_data); +f.density_g_sc = density_g_sc; +f.ifpcgl = ifpcgl; +% f.Dosi=Dosi; +% f.Dwsi=Dwsi; + + + diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/fluidPVT_new.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/fluidPVT_new.m new file mode 100644 index 0000000..b9324bf --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/fluidPVT_new.m @@ -0,0 +1,22 @@ +function f = fluidPVT_new(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, ifpc, rpt, cs_data, csa_data, cb_data, cba_data, cs_Nc, Nc_nosurf, Nc_surf, kr_nosurf, kr_surf, PC, cs_Nc_fracture, kr_nosurf_fracture, kr_surf_fracture, PC_fracture) +% Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, ifpcgl, r.rpt, cs_data, csa_data, cb_data, cba_data, cs_Nc, Nc_nosurf, Nc_surf, kr_nosurf, kr_surf, cs_Nc_fracture, kr_nosurf_fracture, kr_surf_fracture, PC_fracture +% 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(p, Bwi, prw, cw); +f.Bg = @(p) Bg(p, BG, Ppr); +f.muw = @(p) muw(p, vwi, prw, cvw); +f.mug = @(p) mug(p, MUG, Ppr); +% f.krrg = @(sw) krrg(sw, SW, KRG, SWF, KRGF, rpt); +% f.krw = @(sw) krw(sw, SW, KRW, SWF, KRWF, rpt); +% f.pcgl = @(sw) pcgl(sw, SW, PCGL, SWF, PCGLF, rpt); +f.cs_absorb = @(cs) cs_absorb_f(cs, cs_data, csa_data); +f.cb_absorb = @(cb) cb_absorb_f(cb, cb_data, cba_data); +f.Nc = @(cs) cs_to_Nc(cs, cs_Nc, cs_Nc_fracture, rpt); +f.krrg = @(sw, Nc) krg(sw, Nc, Nc_nosurf, Nc_surf, kr_nosurf, kr_surf, kr_nosurf_fracture, kr_surf_fracture, rpt); +f.krw = @(sw, Nc) krw(sw, Nc, Nc_nosurf, Nc_surf, kr_nosurf, kr_surf, kr_nosurf_fracture, kr_surf_fracture, rpt); +f.pcgl = @(sw) pc(sw, PC, PC_fracture, rpt); +f.ifpcgl = ifpc; +% f.Dosi=Dosi; +% f.Dwsi=Dwsi; +end + + diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/fractureInformation_input_engineering_vector.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/fractureInformation_input_engineering_vector.m new file mode 100644 index 0000000..5c1a40a --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/fractureInformation_input_engineering_vector.m @@ -0,0 +1,15 @@ +function frac_information = fractureInformation_input_engineering_vector(f,fellip,flowBarrierFlags) +ff = [f;fellip]; +nf = size(ff,1)/5; +frac_information = zeros(3*nf,2); +for i = 1:size(ff,1)/5 + startPoint = ff(5*i-4,1:2)+ff(5*i-3,1:2)*ff(5*i-1,1); + endPoint = ff(5*i-4,1:2)+ff(5*i-3,1:2)*ff(5*i-1,2); + frac_information(3*i-2,:) = startPoint; + frac_information(3*i-1,:) = endPoint; + if ismember(i,flowBarrierFlags) + frac_information(3*i-0,:) = [0*1e-3,1e-2]; + else + frac_information(3*i-0,:) = [10000*1e-3,1e-2]; + end +end \ No newline at end of file diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/grid_discretization_DP_model.asv b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/grid_discretization_DP_model.asv new file mode 100644 index 0000000..c68d5b4 --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/grid_discretization_DP_model.asv @@ -0,0 +1,49 @@ +function r = grid_discretization_DP_model(modelflag, nx, ny, nz, dx, dy, dz, f, frac_information, fellip, nf) +% 瑁傜紳灞傜綉鏍兼笚娓楅忕巼 +kx = 50*1e-3 * ones(nx*ny*nz, 1); % 杈捐タ锛孌 +ky = 50*1e-3 * ones(nx*ny*nz, 1);% +kz = 50*1e-3 * ones(nx*ny*nz, 1);% +pori = 0.001 * ones(nx*ny*nz, 1);% +prpor = 20; % 鍙傝冨帇鍔涳紝MPa +cpor = 1.0e-5;% 鍩鸿川鍘嬬缉绯绘暟锛孧Pa +NTG= 1 * ones(nx*ny*nz, 1); +% 鍩鸿川灞傜綉鏍兼笚閫忕巼 +kx = 0.001*1e-3 * ones(nx*ny*nz, 1); % 杈捐タ锛孌 +ky = 0.001*1e-3 * ones(nx*ny*nz, 1);% +kz = 0.001*1e-3 * ones(nx*ny*nz, 1);% +pori = 1 * ones(nx*ny*nz, 1);% +prpor = 20; % 鍙傝冨帇鍔涳紝MPa +cpor = 1.0e-5;% 鍩鸿川鍘嬬缉绯绘暟锛孧Pa +% 褰㈢姸鍥犲瓙 +sigma = + +% SRV鍖哄煙瀹氫箟 +% % % base_x=23:78; nx_SRV=length(base_x); +% % % base_y=15:36; ny_SRV=length(base_y); +% % % base_z=1:1;nz_SRV=length(base_z); +% % % SRV=[]; +% % % for k=1:nz_SRV +% % % for j=1:ny_SRV +% % % for i=1:nx_SRV +% % % SRV=[SRV;(base_z(k)-1)*nx*ny+(base_y(j)-1)*nx+base_x(i)]; +% % % end +% % % end +% % % end +% % % % SRV娓楅忕巼璧嬪 +% % % kx(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % ky(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % kz(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% 瑁傜紳瀛旀笚 +Kf = 50000*1e-3*ones(1,nf);% 瑁傜紳娓楅忕巼 +Wf =1e-2*ones(1,nf);% 瑁傜紳寮搴 +Porf = 0.30*ones(1,nf);% 瑁傜紳瀛旈殭搴 +prporf = 20;% 瑁傜紳绯荤粺鍙傝冨帇鍔 +cporf = 1.0e-5;% 瑁傜紳绯荤粺鍘嬬缉绯绘暟 +% +Rpt = 2;cf = 1;ca = 1; +%% 缁撳悎鍩鸿川銆佽缂濈殑鍑犱綍鍙婄墿鎬т俊鎭紑灞曞墠澶勭悊 +% r = GridProp_new(modelflag, nx, ny, nz, dx, dy, dz, kx, ky, kz, f, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,co, NTG); +r = GridProp_DP(modelflag, nx, ny, nz, dx, dy, dz, kx, ky, kz, f, frac_information, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,NTG); +density_rock = 2700; % 宀╃煶瀵嗗害锛宬g/m^3 +r.density_rock = density_rock; +end \ No newline at end of file diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/handle_well1.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/handle_well1.m new file mode 100644 index 0000000..c857537 --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/handle_well1.m @@ -0,0 +1,13 @@ +function well1 = handle_well1(well1,r) +% 闇瑕佹壘鍒板皠瀛旀鍏蜂綋鎵鍦ㄧ殑鍩鸿川缃戞牸缂栧彿 +n1=size(well1,1); +for i=1:n1 + perf=well1{i,3}; + nperf=well1{i,2}; + perf(:,3)=(r.nz+1)*ones(nperf,1)-perf(:,3); + A=repmat([0 1 1],nperf,1); + B=(perf-A)*[1;r.nx;r.nx*r.ny]; + B=B'; %杞崲涓鸿鍚戦噺 + well1{i,3}=B; +end +end \ No newline at end of file diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/handle_well1_well2.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/handle_well1_well2.m new file mode 100644 index 0000000..e2fd8ca --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/handle_well1_well2.m @@ -0,0 +1,36 @@ +function Wellc = handle_well1_well2(well1,well2,welloc,r) +%-----------------鎶婁袱绫讳簳鏁村悎鍒颁竴璧------------------- +nwell1=size(well1,1); +nwell2=size(well2,1); +nwell=nwell1+nwell2; +Wellc0=cell(nwell,9); +% if nwell1==0 +% Wellc0=well2; +% elseif nwell2==0 +% Wellc0=well1; +% else +if nwell1~=0 + for i=1:nwell1 + for j=1:6 + Wellc0{i,j}=well1{i,j}; + end + plot3([r.cell_mid_coords(well1{i,3}(1),1);r.cell_mid_coords(well1{i,3}(1),1)],... + [r.cell_mid_coords(well1{i,3}(1),2);r.cell_mid_coords(well1{i,3}(1),2)],... + [r.cell_mid_coords(well1{i,3}(1),3);max(r.cell_mid_coords(:,3))+20],'color','k','LineWidth',2.5); + hold on; + end +end +if nwell2~=0 + for i=1:nwell2 + for j=1:6 + Wellc0{i+nwell1,j}=well2{i,j}; + end + plot3(welloc{i,1}(:,1),welloc{i,1}(:,2),welloc{i,1}(:,3),'color','k','LineWidth',2.5); + hold on; + end +end +% end +hold off; +% 璁$畻浜曟寚鏁 +Wellc = calcTrans(r, Wellc0); +end \ No newline at end of file diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/initalSchedule_2026.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/initalSchedule_2026.m new file mode 100644 index 0000000..521b82a --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/initalSchedule_2026.m @@ -0,0 +1,54 @@ +function [Weladd, pwf] = initalSchedule_2026(p, sw, cs, Wellc, f, well_schedules_k) +nWel = size(Wellc, 1);%浜曟暟 +Weladd = 0; +pwf = zeros(1); +BW = f.Bw(p); +muW = f.muw(p); +Nc = f.Nc(cs); +krW = f.krw(sw,Nc); +BG = f.Bg(p); +muG = f.mug(p); +krG = f.krrg(sw,Nc); +Ygt = krG ./ (muG .* BG);%mu浠h〃榛忓害 +Ygj = krG ./ muG; +Ywt = krW ./ (muW .* BW);%mu浠h〃榛忓害 +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 * (Ygt(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)) * (Ygj(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;%涓庣敓浜т簳姝eソ鍙嶈繃鏉 + else + continue + end + end +end + pwf = pwf'; \ No newline at end of file diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/input_fracture_2D.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/input_fracture_2D.m new file mode 100644 index 0000000..d60344f --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/input_fracture_2D.m @@ -0,0 +1,26 @@ +function [f,frac_information] = input_fracture_2D(fractureLines,fractureHeights,flowBarrierFlags) +f = zeros((size(fractureLines,1)/2-length(flowBarrierFlags))*5,3); +numberHighFracture = 0; +for i = 1:size(fractureLines,1)/2 + if ~ismember(i,flowBarrierFlags) + numberHighFracture = numberHighFracture +1; + f(5*numberHighFracture-4,:) = [fractureLines(2*i-1,:),0]; + f(5*numberHighFracture-3,:) = [fractureLines(2*i,:)-fractureLines(2*i-1,:),0]; + f(5*numberHighFracture-2,:) = [0,0,fractureHeights(i)]; + f(5*numberHighFracture-1,:) = [0,1,0]; + f(5*numberHighFracture-0,:) = [0,1,0]; + end +end +frac_information = zeros(size(fractureLines,1)*3,2); +for i = 1:size(fractureLines,1)/2 + frac_information(3*i-2,:) = [fractureLines(2*i-1,:)]; + frac_information(3*i-1,:) = [fractureLines(2*i,:)]; + if ismember(i,flowBarrierFlags) + frac_information(3*i-2,:) = frac_information(3*i-2,:); + frac_information(3*i-1,:) = frac_information(3*i-1,:); + frac_information(3*i-0,:) = [0*1e-3,1e-2]; + else + frac_information(3*i-0,:) = [10000*1e-3,1e-2]; + end +end +end diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/mainRS_MB_2026.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/mainRS_MB_2026.m new file mode 100644 index 0000000..f75540f --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/mainRS_MB_2026.m @@ -0,0 +1,165 @@ +function [Times, OutputRs, Wellpara, trun] = mainRS_MB_2026(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; +number_state_variables = f.number_state_variables; +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_2026(state0.p, state0.sw, state0.cs, 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_2014(state, state0, dtc, r, f, os, Wellc, Weladd, pwf, WelChg, well_schedules{k,1}); + Jacob = Awell; + Ris = qwell; + for iii = 1:number_state_variables + for jjj = 1:number_state_variables + Jacob((iii-1)*r.nc+1 : iii*r.nc,(jjj-1)*r.nc+1 : jjj*r.nc) = Jacob((iii-1)*r.nc+1 : iii*r.nc,(jjj-1)*r.nc+1 : jjj*r.nc) + eqs{iii}.jac{jjj} ; + end + Ris((iii-1)*r.nc+1 : iii*r.nc,1) = Ris((iii-1)*r.nc+1 : iii*r.nc,1) +eqs{iii}.val; + end + % % % 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: 4 * r.nc)./ [Pvv;Pvv;Pvv;Pvv] .* [Bwa;Boa;Bwa;Bwa] .* dtc; + % Dimensionless_Ris = Ris(1: 4 * r.nc); + 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; + dp = X(1 : r.nc); + dsw = X(r.nc + 1 : 2*r.nc); + dcs = X(2*r.nc + 1 : 3*r.nc); + dcb = X(3*r.nc + 1 : 4*r.nc); + state.p = state.p + dp; + state.sw = state.sw + dsw; + state.cs = state.cs + dcs; + state.cb = state.cb + dcb; + % deltp=state.p-state0.p; + % deltsw=state.sw-state0.sw; + if Weladd > 0 + dpwf = X(4 * 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(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('姝e湪璁$畻锛%.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); + + diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/multi_component_flow.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/multi_component_flow.m new file mode 100644 index 0000000..2e62237 --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/multi_component_flow.m @@ -0,0 +1,242 @@ +function [f,state0] = multi_component_flow(r) +%% 娴佷綋鎬ц川鍙傛暟 +%% 姘寸浉涓殑琛ㄦ椿鍓傘佺洂鐨勬墿鏁g郴鏁 +Ds = 0.76*1e-9; % m2/s +Db = 2.2*1e-9; % m2/s +%% 琛ㄦ椿鍓傘佺洂鍦ㄥ博鐭宠〃闈㈢殑鍚搁檮娴撳害涓庢按鐩告祿搴︾殑鍏崇郴琛紝绗竴鍒楀崟浣嶆槸kg/m3, 绗簩鍒楀拰绗笁鍒楀崟浣嶆槸g/kg +c_ca_table = [ +0 0 0 +0.05 1 0.075 +0.1 1.75 0.125 +0.2 3 0.2 +0.5 4.35 0.325 +1 4.55 0.365 +]; +cs_data = c_ca_table(:,1); +cb_data = c_ca_table(:,1); +csa_data = c_ca_table(:,2)*1e-3; % 杞崲涓 kg/kg +cba_data = c_ca_table(:,3)*1e-3; % 杞崲涓 kg/kg +%% 鍖栧鍔匡紙鍘嬭娑蹭笌鍦板眰姘寸殑鐩愬害宸紓缁欐按鐩稿甫鏉ョ殑棰濆鍘嬪樊锛 +R = 0.008314; % kJ/(mol*K) +Vm = 18.02*1e-6; % 姘寸殑鍋忔懇灏斾綋绉紝m^3/mol +Temperature = 293.15; % 娓╁害锛孠 +% salinity_fracturing_fluid = 0.1/100; +% salinity_reservoir_water = 28/100; +xf = 1; +xm = 0.9; +chemistry_cof = R*Temperature/Vm*1e-3/10; +x_total = [xm*ones(r.nmc,1); xf*ones(r.nfc,1)]; +chemistry_potential = chemistry_cof*log(x_total); +%% 鍔ㄦ佺浉娓楋紙鍑告樉鍑鸿〃娲诲墏瀵圭浉娓楃殑褰卞搷锛 +% 鍘熸湰搴斿厛寰楀埌琛ㄦ椿鍓傛祿搴︿笌琛ㄩ潰寮犲姏鐨勫叧绯伙紝鍐嶇粨鍚堟笚娴侀熷害璁$畻鍑轰釜琛ㄩ潰寮犲姏瀵瑰簲鐨勬瘺绠℃暟锛 +% 涓轰簡绠渚夸唬鐮佺紪鍐欙紝姝ゅ蹇界暐娓楁祦閫熷害鐨勫奖鍝嶏紝 +% 骞跺寮轰唬鐮侀氱敤鎬э紝姝ゅ鏀逛负杈撳叆琛ㄦ椿鍓傛祿搴︿笌姣涚鏁扮殑瀵瑰簲琛ㄦ牸锛 +% 绗竴鍒椾负琛ㄦ椿鍓傛祿搴︼紝绗簩鍒椾负鐩稿簲鐨勬瘺绠℃暟,锛岀涓夊垪鏄浉搴旂殑琛ㄩ潰寮犲姏 +% dynamic_kr = 1; +cs_Nc = [ +0 1.6*1e-6 30 +0.1 9.5*1e-6 10 +0.2 2.5*1e-5 4 +0.5 5.8*1e-5 1.4 +1 8.2*1e-5 1 +2 8.8*1e-5 0.75 +]; +Nc_nosurf = min(cs_Nc(:,2)); +Nc_surf = max(cs_Nc(:,2)); + +kr_nosurf = [ +0 0 0.64 +0.25 0 0.64 +0.30 0.072 0.6 +0.40 0.14 0.56 +0.50 0.26 0.48 +0.60 0.4 0.38 +0.70 0.56 0.26 +0.85 0.88 0 +1 0.88 0 + ]; + +kr_surf = [ +0 0 0.6 +0.18 0 0.6 +0.25 0.056 0.56 +0.30 0.1 0.52 +0.40 0.19 0.42 +0.50 0.29 0.3 +0.60 0.37 0.19 +0.75 0.46 0 +1 0.46 0 + ]; + +PC = [ +0 3.8916 +0.2 3.8916 +0.316 0.5796 +0.435 0.3724 +0.562 0.2425 +0.614 0.0608 +0.702 0.0372 +0.812 0.0137 +0.875 0.0104 +0.906 0.009 +0.937 0.0075 +0.969 0.0059 +1 0 +]; +cs_Nc_fracture = cs_Nc; +kr_nosurf_fracture = kr_nosurf; +kr_surf_fracture = kr_surf; +PC_fracture = PC; +ifpcgl = 0; % 鏄惁鑰冭檻姣涚鍔 +%% 鍚姩鍘嬪姏姊害 +p_grad_threshold = 0.01; % MPa/m +%% ================姘旂浉Langmuir绛夋俯鍚搁檮妯″瀷锛屽綋 VL=0锛屼害鍙敤浜庢补鐩=============== +% VE = VL*P/(PL+P) +gas_prop.VL = 0.0; % Langmuir volume, m^3/kg +gas_prop.PL = 3.5; % Langmuir pressure, MPa +% Psc = 1; +% Zsc = 1; +% density_rock = 2000; % +% ===================== Knudsen 鎵╂暎绯绘暟锛屽綋 Kn=0锛屼害鍙敤浜庢补鐩 ==================== +gas_prop.Kn = 0; % Knudsen鏁 +c1 =1; c2 =8/9; +gas_prop.Kn_modified_factor = 1+8*c1*gas_prop.Kn+16*c2*gas_prop.Kn^2; +% ===================== 搴斿姏鏁忔劅绯绘暟 ==================== +gas_prop.stress_factor_fracture = 0.000; % 1/MPa 0.001 +gas_prop.stress_factor_matrix = 0.000; % 1/MPa +gas_prop.stress_factor_ref_pressure = 20; % 涓鑸彇涓哄師濮嬪湴灞傚帇鍔 +% ===================== 楂橀熼潪杈捐タ娴 Forchheimer 鏂圭▼ ==================== +gas_prop.beta_non_Darcy_flow = 0; % 1e-8 +% =======================姘旂浉浣撶Н绯绘暟銆佺矘搴=============================== +density_g_sc = 800; +% 绗竴绉嶆ā寮忥紝鐩存帴杈撳叆鍙傝冨帇鍔涖佷綋绉郴鏁般佸帇缂╃郴鏁般佺矘搴 +gas_model =1; +if gas_model == 1 +prg = 20; % reference pressure, MPa +Bgi = 1; % gas phase volume factor +cg = 5e-4 ;% gas phase compressibility, 1/MPa +vgi = 6; % gas viscosity, cp +cvg = 0; +[Ppr,BG,MUG] = cal_gas_prop(prg,Bgi,cg,vgi,cvg); +end +if gas_model == 2 +Ppr = [ 0.1013 + 2.0946 + 4.0878 + 6.0811 + 8.0743 + 10.0676 + 12.0608 + 14.0540 + 16.0473 + 18.0405 + 20.0338 + 22.0270 + 24.0203 + 26.0135 + 28.0068 + 30.0000 + ]; +% BG = 0.01*ones(size(Ppr,1),1); +BG = [ 1.18297 + 0.0557041 + 0.0278168 + 0.0182594 + 0.0134665 + 0.0106154 + 0.00874829 + 0.00744907 + 0.00650639 + 0.0058006 + 0.0052587 + 0.0048336 + 0.00449378 + 0.00421751 + 0.0039895 + 0.00379871 + ]; +% MUG = 0.01*ones(size(Ppr,1),1); +MUG = [0.0127683 + 0.0130191 + 0.0133973 + 0.013872 + 0.014437 + 0.015088 + 0.0158182 + 0.0166173 + 0.0174719 + 0.0183671 + 0.0192882 + 0.0202219 + 0.0211575 + 0.0220865 + 0.0230024 + 0.0239008 + ]; +end +% ========================姘寸浉浣撶Н绯绘暟銆佺矘搴=============================== +density_w_sc = 1000; +prw = 20; % reference pressure +Bwi = 1.000; % water phase volume factor +cw = 4.0e-4 ;% water phase compressibility +vwi = 1; % viscosity +cvw = 0; +% =============================鍩鸿川鐩告笚=============================== +% ifpcgl = 0; % 鏄惁鑰冭檻姣涚鍔 +% RPGW=[ +% 0.0000 0.0000 1.0000 3.8916 +% 0.2000 0.0000 1.0000 3.8916 +% 0.3160 0.0002 0.6784 0.5796 +% 0.4350 0.0004 0.6215 0.3724 +% 0.5620 0.0010 0.5456 0.2425 +% 0.6140 0.0020 0.3939 0.0608 +% 0.7020 0.0280 0.1399 0.0372 +% 0.8120 0.1721 0.0515 0.0137 +% 0.8750 0.3395 0.0297 0.0104 +% 0.9060 0.4395 0.0226 0.0090 +% 0.9370 0.5500 0.0173 0.0075 +% 0.9690 0.6702 0.0131 0.0059 +% 1.0 1.0000 0.0000 0.0000 +% ]; +% SW=RPGW(:,1);KRW=RPGW(:,2);KRG=RPGW(:,3);PCGL=RPGW(:,4); +% +% % =============================瑁傜紳鐩告笚=============================== +% PRF=[ +% 0.0000 0.0000 1.0000 3.8916 +% 0.2000 0.0000 1.0000 3.8916 +% 0.3160 0.0002 0.6784 0.5796 +% 0.4350 0.0004 0.6215 0.3724 +% 0.5620 0.0010 0.5456 0.2425 +% 0.6140 0.0020 0.3939 0.0608 +% 0.7020 0.0280 0.1399 0.0372 +% 0.8120 0.1721 0.0515 0.0137 +% 0.8750 0.3395 0.0297 0.0104 +% 0.9060 0.4395 0.0226 0.0090 +% 0.9370 0.5500 0.0173 0.0075 +% 1.0 1.0000 0.0000 0.0000 +% ]; +% SWF = PRF(:,1);KRWF = PRF(:,2);KRGF = PRF(:,3);PCGLF=PRF(:,4); + +%% 缁撳悎娴佷綋鎬ц川鍙傛暟鐢熸垚鐩稿簲鐨勬暟鎹綋 +% f = fluidPVT(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, SW, KRG, KRW, PCGL, SWF, KRGF, KRWF, PCGLF, density_g_sc, ifpcgl, r.rpt, cs_data, csa_data, cb_data, cba_data, cs_Nc, kr_nosurf, kr_surf); +f = fluidPVT_new(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, ifpcgl, r.rpt, cs_data, csa_data, cb_data, cba_data, cs_Nc, Nc_nosurf, Nc_surf, kr_nosurf, kr_surf, PC, cs_Nc_fracture, kr_nosurf_fracture, kr_surf_fracture, PC_fracture); +f.Dwsi = density_w_sc; +f.Dgsi = density_g_sc; +f.gas_prop = gas_prop; +f.Ds = Ds; +f.Db = Db; +f.x_total = x_total; +f.chemistry_potential = chemistry_potential; +f.p_grad_threshold = p_grad_threshold; +%% 鍒濆兼潯浠 Initial Condition Section +% =================鍘嬪姏銆侀ケ鍜屽害鍒濆======================================= % +%鍘嬪姏鍒濆艰鑰冭檻閲嶅姏锛岀粰鍑烘补钘忎笅琛ㄩ潰鍘嬪姏鍊 +P = [20 * ones(r.nmc, 1); 20 * ones(r.nfc, 1)]; +% plow=25; % P =plow-1e-6*800*9.8*r.z; +Sw = [0.2 * ones(r.nmc, 1); 0.2 * ones(r.nfc, 1)]; +Cs = [0.0 * ones(r.nmc, 1); 0.0 * ones(r.nfc, 1)]; +Cb = [0.0 * ones(r.nmc, 1); 0.0 * ones(r.nfc, 1)]; +number_state_variables = 4; +f.number_state_variables = number_state_variables; +state0 = initialRS(P, Sw, Cs, Cb); +end \ No newline at end of file diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/smooth_relu_stable.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/smooth_relu_stable.m new file mode 100644 index 0000000..0e7bc4b --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/smooth_relu_stable.m @@ -0,0 +1,18 @@ +function ratio = smooth_relu_stable(dp,p_grad_threshold) + % 瀹夊叏骞虫粦ReLU锛屾案涓嶆孩鍑猴紝100%鍏煎鑷姩寰垎 + eps = 1e-8; + s = 200; + dP_abs = (dp.^2 + eps).^(1/2); + x = dP_abs - p_grad_threshold; + y = zeros(length(x),1); + idx1 = x <= 0; + y(idx1) = 0; + % y(idx1) = log(1 + exp(s * x(idx1))) / s; + + idx2 = x > 0; + y(idx2) = x(idx2); + % y(idx2) = x(idx2) + log(1 + exp(-s * x(idx2))) / s; + + activate = y; + ratio = activate ./ (dP_abs); +end \ No newline at end of file diff --git a/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/solver_NR.m b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/solver_NR.m new file mode 100644 index 0000000..d06438b --- /dev/null +++ b/core functions/绋嬪簭鏁村悎鍙婄粍鍒嗘祦閮ㄥ垎浠g爜/solver_NR.m @@ -0,0 +1,28 @@ +function [Times, OutputRs, Wellpara, trun] = solver_NR(r, flow_model, f, os, state0, yitap,yitas,omega,Nmax,epsave,epsmax,dtmin,dtmax,Wellc,time,well_schedules) +w.yitap = yitap; +w.yitas = yitas; +w.omega = omega; +w.Nmax = Nmax; +w.epsave = epsave; +w.epsmax = epsmax; +w.dtmin = dtmin; +w.dtmax = dtmax; +% w.tend = tend; +% w.WelChg = WelChg; +w.Wellc = Wellc; +w.time = time; +w.well_schedules = well_schedules; +%% 璁$畻 +if r.modelflag==1 || r.modelflag==4 || r.modelflag==5 + if flow_model == 1 + [Times, OutputRs, Wellpara, trun] = mainRS_MB_gas_water_flow(r, f, os, w, state0); + end + if flow_model == 2 + [Times, OutputRs, Wellpara, trun] = mainRS_MB_oil_water_flow(r, f, os, w, state0); + end + if flow_model == 3 + [Times, OutputRs, Wellpara, trun] = mainRS_MB_2026(r, f, os, w, state0); + end + % [Times, OutputRs, Wellpara, trun] = mainRS_MB_2014(r, f, os, w, state0); +end +end \ No newline at end of file diff --git a/generic extended/GenerateNode_final_new.m b/generic extended/GenerateNode_final_new.m new file mode 100644 index 0000000..1b4d881 --- /dev/null +++ b/generic extended/GenerateNode_final_new.m @@ -0,0 +1,90 @@ +function [coordinates, nodes, nP, nE, dxv, dyv,dzv,zm,vm,xrao,yrao,zrao] = GenerateNode_final_new(dx, dy,dz ,nx,ny,nz,NTG) +% coordinates xy cordinate,即每个节点的x,y坐标 +% nodes connection,即每个子区域对应的八个节点数 +% nP numbers of point,即节点数量 +% nE numbers of element,即子区域数量 +nP = (nx + 1) * (ny + 1)*(nz+1);%计算节点数量 +nE = nx * ny*nz;%子区域数量计算 +% dx=dx*ones(nx,1);%此处是为了暂时妥协 +% dy=dy*ones(nx,1); +% dz=dz*ones(nx,1); +dxv = zeros(nE, 1);%每个子区域x方向上尺寸矩阵 +dyv = zeros(nE, 1);%每个子区域y方向上尺寸矩阵 +dzv = zeros(nE, 1); +zm=zeros(nE, 1);%基质网格计算深度(以下平面为基准计算得到的高度,值为正数) +%给每个子区域的x方向和y方向赋尺寸 +vm=zeros(nE, 1);%基质网格体积 +for k=1:nz + for i = 1 : nx + for j = 1 : ny + dxv(i+(j-1)*nx+nx*ny*(k-1)) = dx(i); + dyv(i+(j-1)*nx+nx*ny*(k-1)) = dy(j); + dzv(i+(j-1)*nx+nx*ny*(k-1))=dz(k); + vm(i+(j-1)*nx+nx*ny*(k-1))=dx(i)*dy(j)*dz(k)*NTG(i+(j-1)*nx+nx*ny*(k-1)); + + end + end +end +coordinates = zeros(nP, 3);%初始化每个节点的x,y坐标矩阵 +nodes = zeros(nE, 8);%初始化每个子区域对应的八个节点数的矩阵 +%计算每个节点的坐标 +x0 = zeros(nx+1,1); +y0 = zeros(ny+1,1); +z0=zeros(nz+1,1); +sumx = 0; +sumy = 0; +sumz=0; +for i = 1 : nx + sumx = sumx+dx(i); + x0(i+1) = sumx; +end +for i = 1 : ny + sumy = sumy+dy(i); + y0(i+1) = sumy; +end +for i = 1 : nz + sumz = sumz+dz(i); + z0(i+1) = sumz; +end +for k=1:nz+1 +for j = 1 : ny + 1 + for i = 1 : nx + 1 + coordinates(i + (j - 1) * (nx + 1)+(nx+1)*(ny+1)*(k-1), 1) = x0(i);%(i,j)节点的x坐标赋值 + coordinates(i + (j - 1) * (nx + 1)+(nx+1)*(ny+1)*(k-1), 2) = y0(j);%(i,j)节点的y坐标赋值 + coordinates(i + (j - 1) * (nx + 1)+(nx+1)*(ny+1)*(k-1), 3) = z0(k); + end +end +end +%计算每个子区域的八个顶点(节点)对应的节点编号 +for k=1:nz +for j = 1 : ny + for i = 1 : nx + nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) = i + (j - 1) * (nx + 1)+(k-1)*(nx+1)*(ny+1); + nodes(i + (j - 1) * nx+nx*ny*(k-1), 2) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 3) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) + nx + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 4) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) + nx + 2; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1)+(nx+1)*(ny+1); + nodes(i + (j - 1) * nx+nx*ny*(k-1), 6) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 7) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) + nx + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 8) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) + nx + 2; + zm(i+(j-1)*nx+nx*ny*(k-1))=sum(coordinates(nodes(i + (j - 1) * nx+nx*ny*(k-1), :),3))/8; + end +end +end + +xrao=[0]; +for i=1:nx + xxiang=sum(dx(1,1:i)); + xrao=[xrao xxiang]; +end +yrao=[0]; +for i=1:ny + yxiang=sum(dy(1,1:i)); + yrao=[yrao yxiang]; +end +zrao=[0]; +for i=1:nz + zxiang=sum(dz(1,1:i)); + zrao=[zrao zxiang]; +end +end \ No newline at end of file diff --git a/generic extended/GridProp_new.asv b/generic extended/GridProp_new.asv new file mode 100644 index 0000000..c781341 --- /dev/null +++ b/generic extended/GridProp_new.asv @@ -0,0 +1,510 @@ +function r = GridProp_new(modelflag,nx, ny, nz, dx, dy, dz, kx, ky, kz, f, frac_information, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,co,NTG) +tic; +%% 鍩鸿川缃戞牸鍙傛暟鍙婄綉鏍煎弬鏁拌绠椼佸瓨鍌 +r.modelflag=modelflag; +r.nx = nx; +r.ny = ny; +r.nz = nz; +r.dx = dx; +r.dy = dy; +r.dz = dz; +r.kx = kx; +r.ky = ky; +r.kz = kz; +r.Kf = Kf;%瑁傜紳闈㈠搴旂殑娓楅忕巼锛岄潪瑁傜紳鍗曞厓 +r.Wf = Wf;%瑁傜紳闈㈠搴旂殑缂濆锛岄潪瑁傜紳鍗曞厓 +r.cf = cf; +r.ca = ca; +r.co=co; +r.cpor=cpor; +r.cporf=cporf; +r.NTG=NTG; +r.frac_information = frac_information; + +[coordinates, nodes, nP, nE, dxv, dyv,dzv,zm,vm,xrao,yrao,zrao,cell_mid_xy_coordinates] = GenerateNode_final(dx, dy,dz ,nx,ny,nz,NTG); +r.coordinates = coordinates; +r.nodes = nodes; +nmc=nE; +r.nmc =nmc; +r.dxv = dxv; +r.dyv = dyv; +r.dzv = dzv; +r.vm=vm; +r.cell_mid_coordinates=cell_mid_xy_coordinates; +%% 姹傝В瑁傜紳涓庡熀璐ㄧ綉鏍艰繛鎺ユ儏鍐 +%% 鍏抽敭鍙傛暟鐭╅樀鍒濆鍖 +m=size(f,1); +n=size(fellip,1); +nfr=m/5;%鐭╁舰瑙勫垯瑁傜紳鏉℃暟 +nfir=n/5;%涓嶈鍒欒缂濇潯鏁帮紙褰撶劧鍖呭惈妞渾锛 +r.nfr=nfr; r.nfir=nfir; +nf=nfr+nfir; +r.nf=nf; +if (nfir~=0) && (nfr~=0) + f=[f;fellip]; +else if nfr~=0 + f=f; + else if nfir~=0 + f=fellip; + else error('Dr Rao reminds you that there is no information about fractures'); + end + end +end + +%d3intersection=-1000*ones(1000,3);%鐢-1000鍋氭爣璇 +raopoint=cell(nfr+nfir,2);%鍒╃敤鍏冭優鏁扮粍瀛樺偍姣忔潯瑁傜紳涓庡熀璐ㄧ綉鏍肩嚎鐨勪氦鐐癸紝 +%绗竴鍒楁槸涓夌淮鍧愭爣褰㈠紡锛屽嵆d3intersection +%绗簩鍒楁槸瑁傜紳闈㈠弬鏁板舰寮忥紝鍗砤nothersection +pointvsregion=cell(nfr+nfir,3);%鍒╃敤鍏冭優鏁扮粍瀛樺偍interarea鍑芥暟鐨勭粨鏋渘umofmesh, numvspoint,numofregion +fracrossfra=cell(nfr+nfir,nfr+nfir-1);%鍒ゆ柇瑁傜紳涔嬮棿涓や氦鐐瑰潗鏍 +fratmaxfra=zeros(nfr+nfir,nfr+nfir-1);%鍒ゆ柇瑁傜紳涔嬮棿浜ょ嚎鍙傛暟鐨勬渶澶у +fratminfra=zeros(nfr+nfir,nfr+nfir-1);%鍒ゆ柇瑁傜紳涔嬮棿浜ょ嚎鍙傛暟鐨勬渶灏忓 +fracturemesh=cell(nf,1);%姣忎竴琛屾槸涓鏉¤缂濋潰涓婄殑缃戞牸鍓栧垎鎯呭喌 + +%% 璁$畻瑁傜紳涓庡熀璐ㄧ綉鏍肩浉浜ゆ儏鍐 +for i=1:nfr + raopoint{i,1}= intersectionsolve_new_modified_r(f((5*i-4):(5*i),:),dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + raopoint{i,2}= anosection( f((5*i-4):(5*i),:),raopoint{i,1} ); + [ pointvsregion{i,1},pointvsregion{i,2} ,pointvsregion{i,3}] = interarea( raopoint{i,1},dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); +end +% 涓嶈鍒欑紳璁$畻 +if nfir>0 + for i=1:nfir + raopoint{nfr+i,1}= intersectionsolve_new_modified_irr(fellip((5*i-4):(5*i),:),dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + raopoint{nfr+i,2}= anosection( f((5*(nfr+i)-4):(5*(nfr+i)),:),raopoint{nfr+i,1} ); + [ pointvsregion{nfr+i,1},pointvsregion{nfr+i,2} ,pointvsregion{nfr+i,3}] = interarea( raopoint{nfr+i,1},dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + end +end + +%% 璁$畻瑁傜紳涔嬮棿鐩镐氦绾挎儏鍐 +for i=1:nf + for j=1:nf + if i>nfr || j>nfr cross=zeros(2,3);tmax=0;tmin=0; + else +% [ cross,tmax,tmin ]=frac_cross_frac( f((5*i-4):(5*i),:),f((5*j-4):(5*j),:) ); + cross=zeros(2,3);tmax=0;tmin=0; + end + fracrossfra{i,j}=cross;fratmaxfra(i,j)=tmax;fratminfra(i,j)=tmin; + end +end +%% 璁$畻瑁傜紳琚熀璐ㄧ綉鏍笺佸叾瀹冭缂濅笌涔嬬浉浜ゅ悗鐨勭綉鏍煎垎甯冩儏鍐,缁樺埗浜岀淮瑁傜紳骞抽潰鍙傛暟鍧愭爣绯讳笂鐨勭綉鏍煎垎甯冩儏鍐 +% figure('color','w'); +addflag=zeros(nf,1);%涔2鐨勫箓娆★紝闃叉鍥犱负瑁傜紳鏉℃暟杈冨锛岄犳垚鐭╅樀澶ぇ +for i=1:nf + d3intersection=raopoint{i,1};anothersection=raopoint{i,2}; + [ mesh ] = frac_mat_mesh( d3intersection,anothersection,pointvsregion{i,2},pointvsregion{i,1} ); +% for j=1:nf +% [ mesh,d3intersection,anothersection,add_flag ]= frac_frac_mesh_modified(xrao,yrao,zrao,mesh,f(5*i-4,:),f(5*i-3,:),f(5*i-2,:),fracrossfra{i,j},fratmaxfra(i,j),fratminfra(i,j),d3intersection,anothersection,pointvsregion{i,2},pointvsregion{i,1} ); +% addflag(j,1)=addflag(j,1)+add_flag; +% end + raopoint{i,1} = d3intersection; raopoint{i,2} = anothersection;%鐢卞師鏉ヨ缂濅笌缃戞牸鐨勪氦鐐逛笉鏂洿鏂板姞鍏ュ叾瀹冭缂濅笌璇ヨ缂濈殑浜ょ偣 + fracturemesh{i,1}=mesh;subplot(nf,1,i);color_fill={'y','r','b','g'}; + plotmesh2D(mesh,raopoint{i,2},color_fill{1,mod(i,4)+1}); +end + +%% 缁樺埗涓夌淮鑳屾櫙缃戞牸锛堝熀璐ㄧ綉鏍硷級鍙婅缂濈綉鏍煎垎甯 +%figure(2) +%network3D(dx,dy,dz,nx,ny,nz ); +%hold on; +figure('color','w'); +% plot_reservoir_3D(max(xrao),max(yrao),dz(1),1,1,nz); +% plot_reservoir_3D(dx(1),dy(1),dz(1),nx,ny,nz); +network3D(dx(1),dy(1),dz(1),nx,ny,nz); +hold on; + +% network3D_arbitrary(dx,dy,dz,nx,ny,nz); +hold on; +% refine; +% hold on; +for i=1:nf + % color_fill={'y','r','b','g','c','m'}; + % color_fill={'y','r','b','g'}; + % plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill{1,mod(i,4)+1});hold on; + if i <= 30 + color_fill='b'; %娴佸姩灞忛殰 +% elseif i <=19 +% color_fill='b'; %鍘嬭缂 +if i == 2 || i == 9 + + rnf +elseif + color_fill='r'; %澶╃劧瑁傜紳 + end +% plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill{1,mod(i,4)+1});hold on; + plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill);hold on; +end +% % % basic_node_coord = [0,0,0]; +% % % x_length = 700; +% % % y_length = 800; +% % % z_length = 10; +% % % nodes_domain = [basic_node_coord;] +% % % fill3(x,y,z,'w'); +refine1; +% refine_chengjiepaper; +% refine; +% plot_reservoir_3D(max(xrao),max(yrao),dz(1),1,1,nz); +% plot_reservoir_3D(dx(1),dy(1),dz(1),nx,ny,nz); +xlabel('x, m','FontSize',12); +ylabel('y, m','FontSize',12); +zlabel('z, m','FontSize',12); +% +zticks([0, 5]); +% yticks(-1:0.5:1); +% 璁剧疆x杞村拰y杞寸殑鍒诲害鏍囩 +zticklabels({'-2005', '-2000'}); +% yticklabels({'-1', '-0.5', '0', '0.5', '1'}); +% 鍏抽棴鍒诲害鏍囩鐨勬棆杞 +% xticklabels('Rotation', 0); +% yticklabels('Rotation', 0); + +axis equal; +% refine; +% hold on +% network3D(dx(1),dy(1),dz(1),nx,ny,nz); +% network3D(max(xrao),max(yrao),max(zrao),1,1,1 ); +% network3D(10,10,10,2,1,1 ); +% network3D(10,10,10,6,1,2 ); +alpha(1) +view(2) +% axis([min(xrao),max(xrao),min(yrao),max(yrao),min(zrao),max(zrao)]); +% axis equal +% % hold off; +%% 纭畾瑁傜紳缂栧彿鍙婅繛鎺ユ儏鍐碉紝璁$畻浼犲绯绘暟 +if modelflag==1 %琛ㄧず鐢2014, Monifar + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,cell_divided_by_fracture_flag ] = connections_2014( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,pori,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; +elseif modelflag==4 %琛ㄧず鐢 PEDFM + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_new( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==5 % 琛ㄧず瀹炵敤鍨婸EDFM + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_new_new( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,pori,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==6 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨剉alidation model + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag] = connections_unstructured_EDFM( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag)*1/2; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag)*1/2; + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==7 + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_EX1_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==8 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨剉alidation model + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX1_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==9 % EX2 涓嶅悓鎯呭喌涓 pEDFM 瑙 + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_EX2_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==10 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to3_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==11 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to2_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==12 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio,fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to4_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + r.number_of_adding=number_of_adding; + nmc = nmc+number_of_adding; + r.nmc = nmc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.vf=vf; + r.fractureCell_matrixCell_addedMatrixCell = fractureCell_matrixCell_addedMatrixCell; + r.volume_ratio=volume_ratio; + % 鍔堝垎鎴栧鍔 + vm_the_added_cell = vm(cell_divided_by_fracture_flag).*volume_ratio; + vm(cell_divided_by_fracture_flag) = vm(cell_divided_by_fracture_flag).*(1-volume_ratio); + vm = [vm; vm_the_added_cell]; + r.V=[vm;vf]; + pori = [pori; pori(cell_divided_by_fracture_flag)]; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; +elseif modelflag==13 % 琛ㄧず鍩轰簬闈炵粨鏋勭綉鏍紁EDFM鐨 EX2 鍙傝冭В + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_TPFA_MFD( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,perm,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +elseif modelflag==14 %琛ㄧず鐢 PEDFM + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections_PEDFM_new_twofractures( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,frac_information, coordinates); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; +else + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff ] = connections( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,Kf,Wf,Porf,dxv,dyv,dzv,NTG ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%鍩鸿川缃戞牸鍜岃缂濆崟鍏冩绘暟 + r.nex=nex;%鍏锋湁娴佷綋浜ゆ崲鐨勬绘暟 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%瑁傜紳鍗曞厓瀵瑰簲鐨勬笚閫忕巼 + r.wf=wf;%瑁傜紳鍗曞厓瀵瑰簲鐨勭紳瀹 + r.N=N; + r.T=T; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; + %% 璁$畻浼犲绯绘暟 + % dxvector=ones(1,nx);dyvector=ones(1,ny);dzvector=ones(1,nz); + % [ transmatrix,transfracture ] = trans(dxvector,dyvector,dzvector ,nx,ny,nz,nf,fracnumber,lengthvsfra,disvsfra,fracstart,connect_infrac,corevsfra,matrixvsfra,raopoint,f ); + %% 璁$畻鍩鸿川涓庤缂濅箣闂寸獪娴佺殑鐩稿叧绯绘暟 + if modelflag==2 %琛ㄧず鐢2018, Rao + [ G,Gfm,Gff,Gf,Ap,Apf ]=interflowmf1(r,dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + [Ka, M, F2M , MF_coef] = transFunc_aniso(nc,coordinates, nodes, connectmf,Ap,Apf, matrixvsfra,N,T,kx, ky,kz); + r.Ka = Ka; + r.M = M; + r.F2M = F2M; + r.MF_coef = MF_coef; + elseif modelflag==5 %琛ㄧず鐢 Modified Rao, steady, 2018 + [ G,Gfm,Gff,Gf,Ap,Apf ] = interflowmf_MODIFIED(r,dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + [Ka, M, F2M , MF_coef] = transFunc_aniso_MODIFIED(nc,coordinates, nodes, connectmf,Ap,Apf, matrixvsfra,N,T,kx, ky,kz); + r.Ka = Ka; + r.M = M; + r.F2M = F2M; + r.MF_coef = MF_coef; + % [ G,Gfm,Gff,Gf,Ap,Apf,Apmt,Apft ]=interflowmf1_transient(dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + end + % [ G,Gfm,Gff,Gf,Ap,Apf ]=interflowmf1(dxv,dyv,dzv,matrixvsfra,connectmf,fracstart,fracnumber,raopoint,f,nodes,coordinates,nf,corevsfra ); + %% + + % r.MF_deltt=MF_deltt; +end +%% 璁$畻娣卞害锛堜互涓嬪钩闈负鍩哄噯璁$畻寰楀埌鐨勯珮搴︼紝鍊间负姝f暟锛 +z=[zm;zf]; +r.z=z; + + +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +r.rpt = rpt; +r.Porf = Porf; +pori = [pori; porf]; +r.pori = pori; +r.por = @(p)por(p, prpor, pori, cpor, prporf, cporf, r.rpt); +tpre=toc; +r.tpre=tpre; diff --git a/generic extended/GridProp_new.m b/generic extended/GridProp_new.m new file mode 100644 index 0000000..b196bc2 --- /dev/null +++ b/generic extended/GridProp_new.m @@ -0,0 +1,230 @@ +function r = GridProp_new(modelflag, r, kx, ky, kz, f, frac_information, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca, valid_grids) +tic; +%% 基质网格参数及网格参数读取 +nx = r.nx; +ny = r.ny; +nz = r.nz; +dx = r.dx; +dy = r.dy; +dz = r.dz; +NTG = r.NTG; +coordinates = r.coordinates; +nodes = r.nodes; +nP = r.nP; +nmc = r.nmc; +dxv = r.dxv; +dyv = r.dyv; +dzv = r.dzv; +zm = r.zm; +vm = r.vm; +xrao = r.xrao; +yrao = r.yrao; +zrao = r.zrao; +cell_mid_coords = r.cell_mid_coords; +% +kx(valid_grids==0)=1e-12; +ky(valid_grids==0)=1e-12; +kz(valid_grids==0)=1e-12; +% +r.modelflag=modelflag; +r.kx = kx; +r.ky = ky; +r.kz = kz; +r.Kf = Kf;%裂缝面对应的渗透率,非裂缝单元 +r.Wf = Wf;%裂缝面对应的缝宽,非裂缝单元 +r.cf = cf; +r.ca = ca; +% r.co=co; +r.cpor=cpor; +r.cporf=cporf; +r.frac_information = frac_information; + +% % % [coordinates, nodes, nP, nE, dxv, dyv,dzv,zm,vm,xrao,yrao,zrao,cell_mid_coordinates] = GenerateNode_final(dx, dy,dz ,nx,ny,nz,NTG); +% % % r.coordinates = coordinates; +% % % r.nodes = nodes; +% % % nmc=nE; +% % % r.nmc =nmc; +% % % r.dxv = dxv; +% % % r.dyv = dyv; +% % % r.dzv = dzv; +% % % r.vm=vm; +% % % r.cell_mid_coordinates=cell_mid_coordinates; +%% 求解裂缝与基质网格连接情况 +%% 关键参数矩阵初始化 +m=size(f,1); +n=size(fellip,1); +nfr=m/5;%矩形规则裂缝条数 +nfir=n/5;%不规则裂缝条数(当然包含椭圆) +r.nfr=nfr; r.nfir=nfir; +nf=nfr+nfir; +r.nf=nf; +if (nfir~=0) && (nfr~=0) + f=[f;fellip]; +else if nfr~=0 + f=f; +else if nfir~=0 + f=fellip; +else error('Dr Rao reminds you that there is no information about fractures'); +end +end +end + +%d3intersection=-1000*ones(1000,3);%用-1000做标识 +raopoint=cell(nfr+nfir,2);%利用元胞数组存储每条裂缝与基质网格线的交点, +%第一列是三维坐标形式,即d3intersection +%第二列是裂缝面参数形式,即anothersection +pointvsregion=cell(nfr+nfir,3);%利用元胞数组存储interarea函数的结果numofmesh, numvspoint,numofregion +fracrossfra=cell(nfr+nfir,nfr+nfir-1);%判断裂缝之间两交点坐标 +fratmaxfra=zeros(nfr+nfir,nfr+nfir-1);%判断裂缝之间交线参数的最大值 +fratminfra=zeros(nfr+nfir,nfr+nfir-1);%判断裂缝之间交线参数的最小值 +fracturemesh=cell(nf,1);%每一行是一条裂缝面上的网格剖分情况 + +%% 计算裂缝与基质网格相交情况 +for i=1:nfr + raopoint{i,1}= intersectionsolve_new_modified_r(f((5*i-4):(5*i),:),dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + raopoint{i,2}= anosection( f((5*i-4):(5*i),:),raopoint{i,1} ); + [ pointvsregion{i,1},pointvsregion{i,2} ,pointvsregion{i,3}] = interarea( raopoint{i,1},dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); +end +% 不规则缝计算 +if nfir>0 + for i=1:nfir + raopoint{nfr+i,1}= intersectionsolve_new_modified_irr(fellip((5*i-4):(5*i),:),dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + raopoint{nfr+i,2}= anosection( f((5*(nfr+i)-4):(5*(nfr+i)),:),raopoint{nfr+i,1} ); + [ pointvsregion{nfr+i,1},pointvsregion{nfr+i,2} ,pointvsregion{nfr+i,3}] = interarea( raopoint{nfr+i,1},dx,dy,dz,nx,ny,nz,xrao,yrao,zrao ); + end +end + +%% 计算裂缝之间相交线情况 +for i=1:nf + for j=1:nf + if i>nfr || j>nfr cross=zeros(2,3);tmax=0;tmin=0; + else + % [ cross,tmax,tmin ]=frac_cross_frac( f((5*i-4):(5*i),:),f((5*j-4):(5*j),:) ); + cross=zeros(2,3);tmax=0;tmin=0; + end + fracrossfra{i,j}=cross;fratmaxfra(i,j)=tmax;fratminfra(i,j)=tmin; + end +end +%% 计算裂缝被基质网格、其它裂缝与之相交后的网格分布情况,绘制二维裂缝平面参数坐标系上的网格分布情况 +% figure('color','w'); +addflag=zeros(nf,1);%乘2的幂次,防止因为裂缝条数较多,造成矩阵太大 +for i=1:nf + d3intersection=raopoint{i,1};anothersection=raopoint{i,2}; + [ mesh ] = frac_mat_mesh( d3intersection,anothersection,pointvsregion{i,2},pointvsregion{i,1} ); + % for j=1:nf + % [ mesh,d3intersection,anothersection,add_flag ]= frac_frac_mesh_modified(xrao,yrao,zrao,mesh,f(5*i-4,:),f(5*i-3,:),f(5*i-2,:),fracrossfra{i,j},fratmaxfra(i,j),fratminfra(i,j),d3intersection,anothersection,pointvsregion{i,2},pointvsregion{i,1} ); + % addflag(j,1)=addflag(j,1)+add_flag; + % end + raopoint{i,1} = d3intersection; raopoint{i,2} = anothersection;%由原来裂缝与网格的交点不断更新加入其它裂缝与该裂缝的交点 + fracturemesh{i,1}=mesh; + % subplot(nf,1,i);color_fill={'y','r','b','g'}; + % plotmesh2D(mesh,raopoint{i,2},color_fill{1,mod(i,4)+1}); +end + +%% 绘制三维背景网格(基质网格)及裂缝网格分布 +%figure(2) +%network3D(dx,dy,dz,nx,ny,nz ); +%hold on; +figure('color','w'); +% plot_reservoir_3D(max(xrao),max(yrao),dz(1),1,1,nz); +% plot_reservoir_3D(dx(1),dy(1),dz(1),nx,ny,nz); +network3D(dx(1),dy(1),dz(1),nx,ny,nz); +% network3D(1000,700,10,1,1,1); +% network3D(800,300,10,1,1,1); +hold on; + +% network3D_arbitrary(dx,dy,dz,nx,ny,nz); +% refine; +% hold on; +for i=1:nf + % color_fill={'y','r','b','g','c','m'}; + % color_fill={'y','r','b','g'}; + % plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill{1,mod(i,4)+1});hold on; + if i <= 100 + color_fill='b'; %流动屏障 + % elseif i <=19 + % color_fill='b'; %压裂缝 +% if i == 2 || i == 9 +% color_fill='r'; +% end + else + color_fill='k'; %天然裂缝 + end + % plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill{1,mod(i,4)+1});hold on; + plotmesh3D( fracturemesh{i,1},raopoint{i,1},color_fill);hold on; +end +% % % basic_node_coord = [0,0,0]; +% % % x_length = 700; +% % % y_length = 800; +% % % z_length = 10; +% % % nodes_domain = [basic_node_coord;] +% % % fill3(x,y,z,'w'); +% refine1; +% refine_chengjiepaper; +% refine; +% plot_reservoir_3D(max(xrao),max(yrao),dz(1),1,1,nz); +% plot_reservoir_3D(dx(1),dy(1),dz(1),nx,ny,nz); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +zlabel('z, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +% +% zticks([0, 5]); +% yticks(-1:0.5:1); +% 设置x轴和y轴的刻度标签 +% zticklabels({'-2005', '-2000'}); +% yticklabels({'-1', '-0.5', '0', '0.5', '1'}); +% 关闭刻度标签的旋转 +% xticklabels('Rotation', 0); +% yticklabels('Rotation', 0); +% axis equal; +% refine; +% hold on +% network3D(dx(1),dy(1),dz(1),nx,ny,nz); +% network3D(max(xrao),max(yrao),max(zrao),1,1,1 ); +% network3D(10,10,10,2,1,1 ); +% network3D(10,10,10,6,1,2 ); +alpha(1) +view(3) +% axis([min(xrao),max(xrao),min(yrao),max(yrao),min(zrao),max(zrao)]); +% axis equal +% % hold off; +%% 确定裂缝编号及连接情况,计算传导系数 +if modelflag==1 %表示用2014, Monifar + [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac, N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,cell_divided_by_fracture_flag, flowArea, perm, matrixflag, T_diff ] = connections_2014( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,pori,Kf,Wf,Porf,dxv,dyv,dzv,coordinates,nodes,NTG,addflag,valid_grids ); + nfc=size(fracnumber,1); + nex=size(T,1); + r.nfc=nfc; + nc=nfc+nmc; + r.nc=nc;%基质网格和裂缝单元总数 + r.nex=nex;%具有流体交换的总数 + kf=Kf(fcinff); + wf=Wf(fcinff); + r.kf=kf;%裂缝单元对应的渗透率 + r.wf=wf;%裂缝单元对应的缝宽 + r.N=N; + r.T=T; + r.T_convection=T_convection; + r.T_diff = T_diff; + r.vf=vf; + r.V=[vm;vf]; + r.porf=porf; + r.fcff=fcff; + r.mat_frac=mat_frac; + r.cell_divided_by_fracture_flag = cell_divided_by_fracture_flag; + r.flowArea=flowArea; + r.perm=perm; + r.matrixflag=matrixflag; +end +%% 计算深度(以下平面为基准计算得到的高度,值为正数) +z=[zm;zf]; +r.z=z; +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +r.rpt = rpt; +r.Porf = Porf; +pori = [pori; porf]; +r.pori = pori; +r.por = @(p)por(p, prpor, pori, cpor, prporf, cporf, r.rpt); +tpre=toc; +r.tpre=tpre; diff --git a/generic extended/calculate_relative_errors.m b/generic extended/calculate_relative_errors.m new file mode 100644 index 0000000..4726f83 --- /dev/null +++ b/generic extended/calculate_relative_errors.m @@ -0,0 +1,35 @@ +function [ relative_errors ] = calculate_relative_errors( results_EDFM_matrix, results_pEDFM_case1, results_pEDFM_case2, r_EDFMs) +%CALCULATE_RELATIVE_ERRORS 此处显示有关此函数的摘要 +% 此处显示详细说明 +% % % EDFM_result = results_EDFM_matrix(:,1); +% % % pEDFM_result_case1 = results_pEDFM_case1(:,2); +% % % modified_EDFM_result = results_pEDFM_case2(:,3); +% % % new_EDFM_result = results_EDFMs_matrix(:,4); +% % % LGR_result = results_LGR(:,1); + +EDFMs_cell_mid_point_coordinates = r_EDFMs.cell_mid_coordinates; +% LGR_cell_mid_point_coordinates = r_LGR.cell_mid_coordinates; + +num_of_cells = size(EDFMs_cell_mid_point_coordinates,1); +% the_reference_solution_for_comparison = zeros(num_of_cells,1); + +% % % for i = 1:num_of_cells +% % % [a,b]=min((LGR_cell_mid_point_coordinates(:,1)- EDFMs_cell_mid_point_coordinates(i,1)).^2+(LGR_cell_mid_point_coordinates(:,2)- EDFMs_cell_mid_point_coordinates(i,2)).^2); +% % % the_reference_solution_for_comparison(i,1) = LGR_result(b(1),1); +% % % end +% 相对误差计算 +fracture_perm = [ 100, 700, 4000, 20000, 100000]; +relative_errors = zeros(2,5); +for j = 1:5 +relative_errors(1,j) = norm(results_EDFM_matrix(1:num_of_cells,j)-results_pEDFM_case2(1:num_of_cells,j))/norm(results_pEDFM_case2(1:num_of_cells,j)); +relative_errors(2,j) = norm(results_pEDFM_case1(1:num_of_cells,j)-results_pEDFM_case2(1:num_of_cells,j))/norm(results_pEDFM_case2(1:num_of_cells,j)); + +% relative_errors(1,2) = norm(pEDFM_result(1:num_of_cells,1)-the_reference_solution_for_comparison(:,1))/norm(the_reference_solution_for_comparison(:,1)); +% relative_errors(1,3) = norm(modified_EDFM_result(1:num_of_cells,1)-the_reference_solution_for_comparison(:,1))/norm(the_reference_solution_for_comparison(:,1)); +% relative_errors(1,4) = norm(new_EDFM_result(1:num_of_cells,1)-the_reference_solution_for_comparison(:,1))/norm(the_reference_solution_for_comparison(:,1)); +end +% relative_errors(1,5) = norm(LGR_result(:,1)-the_reference_solution_for_comparison(:,1))/norm(the_reference_solution_for_comparison(:,1)); + + +end + diff --git a/generic extended/calculate_relative_errors_vs_cellsize.m b/generic extended/calculate_relative_errors_vs_cellsize.m new file mode 100644 index 0000000..7c2b4b8 --- /dev/null +++ b/generic extended/calculate_relative_errors_vs_cellsize.m @@ -0,0 +1,72 @@ +function [ relative_errors ] = calculate_relative_errors_vs_cellsize( results_EDFM_matrix, results_pEDFM_case1, results_pEDFM_case2, results_reference, r_0_5m, r_1m, r_2m, r_4m) +% r_EDFMs_0_25, r_EDFMs_0_5, r_EDFMs_1, r_EDFMs_2, r_EDFMs_4 +%CALCULATE_RELATIVE_ERRORS 此处显示有关此函数的摘要 +% 此处显示详细说明 +% % % EDFM_result = results_EDFM_matrix(:,1); +% % % pEDFM_result_case1 = results_pEDFM_case1(:,2); +% % % modified_EDFM_result = results_pEDFM_case2(:,3); +% % % new_EDFM_result = results_EDFMs_matrix(:,4); +% % % LGR_result = results_LGR(:,1); + +% EDFMs_cell_mid_point_coordinates = r_EDFMs.cell_mid_coordinates; +% % LGR_cell_mid_point_coordinates = r_LGR.cell_mid_coordinates; +% +% num_of_cells = size(EDFMs_cell_mid_point_coordinates,1); +% the_reference_solution_for_comparison = zeros(num_of_cells,1); + +% % % for i = 1:num_of_cells +% % % [a,b]=min((LGR_cell_mid_point_coordinates(:,1)- EDFMs_cell_mid_point_coordinates(i,1)).^2+(LGR_cell_mid_point_coordinates(:,2)- EDFMs_cell_mid_point_coordinates(i,2)).^2); +% % % the_reference_solution_for_comparison(i,1) = LGR_result(b(1),1); +% % % end +% 相对误差计算 +x_data = [0.5, 1, 2, 5]; +relative_errors = zeros(2,4); +for j = 1:4 +% if j == 1 r_EDFMs = r_EDFMs_0_25; end; +% if j == 2 r_EDFMs = r_EDFMs_0_5; end; +% if j == 3 r_EDFMs = r_EDFMs_1; end; +% if j == 4 r_EDFMs = r_EDFMs_2; end; +% if j == 5 r_EDFMs = r_EDFMs_4; end; + if j == 1 r_EDFMs = r_0_5m; end; + if j == 2 r_EDFMs = r_1m; end; + if j == 3 r_EDFMs = r_2m; end; + if j == 4 r_EDFMs = r_4m; end; +% if j == 5 r_EDFMs = r_EDFMs_4; end; + +EDFMs_cell_mid_point_coordinates = r_EDFMs.cell_mid_coordinates; +% LGR_cell_mid_point_coordinates = r_LGR.cell_mid_coordinates; +num_of_cells = size(EDFMs_cell_mid_point_coordinates,1); +the_numnering = (1:(r_EDFMs.nx*r_EDFMs.ny*r_EDFMs.nz))'; +the_numnering(r_EDFMs.cell_divided_by_fracture_flag)=[]; +% relative_errors(1,j) = norm(results_EDFM_matrix(1:num_of_cells,j)-results_pEDFM_case2(1:num_of_cells,j))/norm(results_pEDFM_case2(1:num_of_cells,j)); +% relative_errors(2,j) = norm(results_pEDFM_case1(1:num_of_cells,j)-results_pEDFM_case2(1:num_of_cells,j))/norm(results_pEDFM_case2(1:num_of_cells,j)); + +% relative_errors(1,j) = sqrt(sum((results_EDFM_matrix(the_numnering,j)-results_reference(the_numnering,j)).^2)/size(the_numnering,1)); +% relative_errors(2,j) = sqrt(sum((results_pEDFM_case1(the_numnering,j)-results_reference(the_numnering,j)).^2)/size(the_numnering,1)); +% relative_errors(3,j) = sqrt(sum((results_pEDFM_case2(the_numnering,j)-results_reference(the_numnering,j)).^2)/size(the_numnering,1)); +% +relative_errors(1,j) = norm(results_EDFM_matrix(the_numnering,j)-results_reference(the_numnering,j))/norm(1-results_reference(the_numnering,j)); +relative_errors(2,j) = norm(results_pEDFM_case1(the_numnering,j)-results_reference(the_numnering,j))/norm(1-results_reference(the_numnering,j)); +relative_errors(3,j) = norm(results_pEDFM_case2(the_numnering,j)-results_reference(the_numnering,j))/norm(1-results_reference(the_numnering,j)); + +% relative_errors(1,2) = norm(pEDFM_result(1:num_of_cells,1)-the_reference_solution_for_comparison(:,1))/norm(the_reference_solution_for_comparison(:,1)); +% relative_errors(1,3) = norm(modified_EDFM_result(1:num_of_cells,1)-the_reference_solution_for_comparison(:,1))/norm(the_reference_solution_for_comparison(:,1)); +% relative_errors(1,4) = norm(new_EDFM_result(1:num_of_cells,1)-the_reference_solution_for_comparison(:,1))/norm(the_reference_solution_for_comparison(:,1)); +end +% relative_errors(1,5) = norm(LGR_result(:,1)-the_reference_solution_for_comparison(:,1))/norm(the_reference_solution_for_comparison(:,1)); +figure('color','w'); +plot(x_data,relative_errors(1,:),'k^-'); +hold on; +plot(x_data,relative_errors(2,:),'rs-'); +hold on; +plot(x_data,relative_errors(3,:),'bo-'); +hold on; +plot(x_data,relative_errors(3,:),'gv-'); +hold off; +xlabel('grid size, m'); +ylabel('L_2 relative error, dimensionless'); +legend('EDFM', 'pEDFM-SDP', 'pEDFM-MTM', 'pEDFM-continuous'); + + +end + diff --git a/generic extended/connections_PEDFM_EX1_solutions.m b/generic extended/connections_PEDFM_EX1_solutions.m new file mode 100644 index 0000000..3b360a7 --- /dev/null +++ b/generic extended/connections_PEDFM_EX1_solutions.m @@ -0,0 +1,642 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff] = connections_PEDFM_EX1_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag,frac_information,coordinates) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf + rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; + for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); + % indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end + end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 + % if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; + end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +% +fractureCellType = zeros(q-1,1); +theNumber = 3; +fractureCellType = repmat((1:theNumber)',(q-1)/theNumber,1); +% +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,1);%裂缝网格渗透率 +Wf=zeros(q-1,1);%裂缝单元缝宽 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 + for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if Kf(j)==0 || Kf(k)==0 + hartran=0; + else + tran1=Kf(j)*wf(i)*lengthcat/disk; + tran2=Kf(k)*wf(i)*lengthcat/disj; + % hartran=length/(disk+disj);%取调和平均的一半 + hartran=tran1*tran2/(tran1+tran2); + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 + % lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 Tmff=[Tmff; 0]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +S_ex=zeros(nmm,1);% 流体交换面面积 + +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +c = 0; +for k= 1 : nz + for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + % 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)/(Kx(index)*dxv(indexn) + Kx(indexn)*dxv(index)); + S_ex(c)=dzv(index)*dyv(index); + end + end +end + +for k= 1 : nz + for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + S_ex(c)=dzv(index)*dxv(index); + end + end +end + +for i = 1 : nx + for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + S_ex(c)=dxv(index)*dyv(index); + end + end +end + + + + +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=areavsfra(matrixvsfra(i,j));% 此处与原始嵌入式不一样,原始是两倍 + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); + % dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + % 为论文做修改 + % Dn=0.9; + % Dn=2.5; + raoT=Knnc*Annc/Dn; + Tinterflow=[Tinterflow;raoT]; + end + end +end + +%% 投影嵌入式处理 +nmc=size(matrixvsfra,1); +%基质网格流体交换面上的裂缝单元投影面之和 +S_p=zeros(nmm,1); +% 因为投影处理新加的F-M connections +Nmf_projection=[]; +Tmf_projection=[]; +for i=1:nmc + matnodes=nodes(i,:); + dx_grid=dxv(i); + dy_grid=dyv(i); + dz_grid=dzv(i); + grid_core=mean(coord(matnodes,:));%该基质网格中心 + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>=1) %先仅考虑n=1时的情况 + selected_face=zeros(1,3); + the_frac_cell=matrixvsfra(i,indice);%该裂缝单元编号 + % if Kf(the_frac_cell) <= (kx(i)*ky(i)*kz(i))^(1/3);% + % else + which_frac=fcff{1,2}(the_frac_cell,1);%该裂缝单元所在的裂缝面 + core_frac_cell=fcff{1,4}(the_frac_cell,1:3);%该裂缝单元的中心坐标 + area_frac_cell=fcff{1,8}(the_frac_cell,1);%该裂缝单元面积 + rao_struct=[i,the_frac_cell+nmc]; + pos_rao=find_row(rao_struct,Ninterflow); + %该裂缝面法向量 + D_value=core_frac_cell-grid_core;% 向量OF + vector_1=f(5*which_frac-3,:); + vector_2=f(5*which_frac-2,:); + n_vector_1=cross(vector_1,vector_2); + n_vector_2=-cross(vector_1,vector_2); + if (dot(n_vector_1,D_value))>=0 + n_vector=n_vector_1; + else + n_vector=n_vector_2; + end + % 方向投影面积 + area_frac_cell_x=abs(area_frac_cell*dot([1,0,0],n_vector)/norm(n_vector)); + area_frac_cell_y=abs(area_frac_cell*dot([0,1,0],n_vector)/norm(n_vector)); + area_frac_cell_z=abs(area_frac_cell*dot([0,0,1],n_vector)/norm(n_vector)); + %% ----------------------% 根据fractureCellType选取投影面-------------------------------------- + % selected_face(1)=4; nei_grid_x=i+1; + % selected_face(2)=5; nei_grid_y=i+nx; + % selected_face(3)=6;nei_grid_z=i+nx*ny; + %% 选择哪种方法 + selectedMethod = 1; + %% method 1 + if selectedMethod == 1 + if fractureCellType(the_frac_cell) == 1 + nei_grid_x=i-1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 2 + nei_grid_x=i-1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 3 + nei_grid_x=i+1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + end + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y]; + struc_z=[i,nei_grid_z]; + end + %% method 2 + if selectedMethod == 2 + if fractureCellType(the_frac_cell) == 1 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 2 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 3 + nei_grid_x=i+1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + end + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y]; + struc_z=[i,nei_grid_z]; + end + %% method 3 + if selectedMethod == 3 + if fractureCellType(the_frac_cell) == 1 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + struc_x=[i,nei_grid_x]; + struc_y=[i,i];% 相当于没有 + struc_z=[i,nei_grid_z]; + end + if fractureCellType(the_frac_cell) == 2 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y];area_frac_cell_y = area_frac_cell_y*2;% 加上了fractureCellType(the_frac_cell) == 1时的area_frac_cell_y + struc_z=[i,nei_grid_z]; + end + if fractureCellType(the_frac_cell) == 3 + nei_grid_x=i+1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y]; + struc_z=[i,nei_grid_z]; + end + end + %% ----------------------% 各方向投影面积叠加及传导率计算--------------------------------------------------------------- + %% x direction +% struc_x=[i,nei_grid_x]; + pos=find_row(struc_x,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_x; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_x)*ky(nei_grid_x)*kz(nei_grid_x))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_x,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 + % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 + % dis_added=norm(nei_grid_core-core_frac_cell); + % T_added=Knnc*area_frac_cell_x/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_x/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); + % T_added=0;%特殊情况 + % T_added=0;%特殊情况 + % T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_x,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end + %% y direction +% struc_y=[i,nei_grid_y]; + pos=find_row(struc_y,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_y; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_y)*ky(nei_grid_y)*kz(nei_grid_y))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_y,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 + % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 + % dis_added=norm(nei_grid_core-core_frac_cell); + % T_added=Knnc*area_frac_cell_y/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_y/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); + % T_added=0;%特殊情况 + % T_added=0.002;%特殊情况 + % T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_y,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end + + %% z direction +% struc_z=[i,nei_grid_z]; + pos=find_row(struc_z,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_z; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_z)*ky(nei_grid_z)*kz(nei_grid_z))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_z,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 + % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 + % dis_added=norm(nei_grid_core-core_frac_cell); + % T_added=Knnc*area_frac_cell_z/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_z/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); + % T_added=0;%特殊情况 + % T_added=0.0;%特殊情况 + % T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_z,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end + + end + end +end +%% 额外添加的改进 +im_N=[]; +im_T=[]; +% % % q=length(Kf)+1; +% % % for i=1:(q-1)/2%q-1是裂缝单元数量 +% % % for j=(q-1)/2+1:(q-1) +% % % if abs(corevsfra(j,2)-corevsfra(i,2))<=1e-2 +% % % im_N=[im_N;i+nmc,j+nmc]; +% % % % im_T=[im_T;0]; +% % % % im_T=[im_T;0.0039604]; +% % % % im_T=[im_T;(((Kf(i))^(-1)+(1e-3)^(-1)+(1e-3)^(-1)+(Kf(j))^(-1))/4)^(-1)*2*2/0.4]; +% % % im_T=[im_T;(((Kf(i))^(-1)+(1e-3)^(-1)+(1e-3)^(-1)+(Kf(j))^(-1))/4)^(-1)*0.5*2/0.4]; +% % % % +% % % end +% % % end +% % % end +%% 用投影面积修正基质网格间传导 +for i=1:nmm + % 为避免数值误差,导致没有真正封堵住,故 + if (S_ex(i)-S_p(i))/S_ex(i)<=1e-2 + T(i)=0; + else + T(i)= T(i)*(S_ex(i)-S_p(i))/S_ex(i); + end +end +%% 实用型pEDFM额外处理 +% % % num_frac = size(frac_information,1)/3; +% % % for i = 1:num_frac +% % % if frac_information(3*i,1) <= (kx(1)*ky(1)*kz(1))^(1/3) +% % % % 裂缝的两端点 +% % % one_end = frac_information(3*i-2,:); +% % % the_other_end = frac_information(3*i-1,:); +% % % % 两网格之间的连接 +% % % for j = 1:size(N,1) +% % % added_matnodes_1=nodes(N(j,1),:); +% % % one_node_connect=mean(coord(added_matnodes_1,:));%该基质网格中心 +% % % added_matnodes_2=nodes(N(j,2),:); +% % % the_other_node_connect=mean(coord(added_matnodes_2,:)); +% % % coef_matrix = [ +% % % the_other_end(1)-one_end(1),-(the_other_node_connect(1)-one_node_connect(1)); +% % % the_other_end(2)-one_end(2),-(the_other_node_connect(2)-one_node_connect(2));]; +% % % coef_vector = [one_node_connect(1)-one_end(1);one_node_connect(2)-one_end(2);]; +% % % if abs(det(coef_matrix))<=1e-12 +% % % else +% % % parameters = coef_matrix\coef_vector; +% % % if parameters(1)>=0 && parameters(1)<=1 && parameters(2)>=0 && parameters(2)<=1 +% % % T(j) = (T(j)^-1 + frac_information(3*i,1)^-1)^-1; +% % % end +% % % end +% % % end +% % % end +% % % end +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;Nmf_projection;im_N]; +T = [T; Tmff; Tff;Tinterflow;Tmf_projection;im_T]; +% N = [N; Nmff+nmc; Nff+nmc;Ninterflow;Nmf_projection]; +% T = [T; Tmff; Tff;Tinterflow;Tmf_projection]; +nex=size(N,1); +end + + diff --git a/generic extended/connections_PEDFM_EX2_solutions.m b/generic extended/connections_PEDFM_EX2_solutions.m new file mode 100644 index 0000000..bd9ffb3 --- /dev/null +++ b/generic extended/connections_PEDFM_EX2_solutions.m @@ -0,0 +1,707 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff] = connections_PEDFM_EX2_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag,frac_information,coordinates) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf + rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; + for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); + % indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end + end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 + % if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; + end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +% +numberFractureCells = q-1; +% +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,1);%裂缝网格渗透率 +Wf=zeros(q-1,1);%裂缝单元缝宽 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 + for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if Kf(j)==0 || Kf(k)==0 + hartran=0; + else + tran1=Kf(j)*wf(i)*lengthcat/disk; + tran2=Kf(k)*wf(i)*lengthcat/disj; + % hartran=length/(disk+disj);%取调和平均的一半 + hartran=tran1*tran2/(tran1+tran2); + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 + % lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 Tmff=[Tmff; 0]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +S_ex=zeros(nmm,1);% 流体交换面面积 + +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +c = 0; +for k= 1 : nz + for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + % 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)/(Kx(index)*dxv(indexn) + Kx(indexn)*dxv(index)); + S_ex(c)=dzv(index)*dyv(index); + end + end +end + +for k= 1 : nz + for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + S_ex(c)=dzv(index)*dxv(index); + end + end +end + +for i = 1 : nx + for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + S_ex(c)=dxv(index)*dyv(index); + end + end +end + + + + +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=areavsfra(matrixvsfra(i,j));% 此处与原始嵌入式不一样,原始是两倍 + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); + % dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + % 为论文做修改 + % Dn=0.9; + % Dn=2.5; + raoT=Knnc*Annc/Dn; + Tinterflow=[Tinterflow;raoT]; + end + end +end + +%% 投影嵌入式处理 +nmc=size(matrixvsfra,1); +%基质网格流体交换面上的裂缝单元投影面之和 +S_p=zeros(nmm,1); +% 因为投影处理新加的F-M connections +Nmf_projection=[]; +Tmf_projection=[]; +for i=1:nmc + matnodes=nodes(i,:); + dx_grid=dxv(i); + dy_grid=dyv(i); + dz_grid=dzv(i); + grid_core=mean(coord(matnodes,:));%该基质网格中心 + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>=1) %先仅考虑n=1时的情况 + selected_face=zeros(1,3); + the_frac_cell=matrixvsfra(i,indice);%该裂缝单元编号 + % if Kf(the_frac_cell) <= (kx(i)*ky(i)*kz(i))^(1/3);% + % else + which_frac=fcff{1,2}(the_frac_cell,1);%该裂缝单元所在的裂缝面 + core_frac_cell=fcff{1,4}(the_frac_cell,1:3);%该裂缝单元的中心坐标 + area_frac_cell=fcff{1,8}(the_frac_cell,1);%该裂缝单元面积 + rao_struct=[i,the_frac_cell+nmc]; + pos_rao=find_row(rao_struct,Ninterflow); + %该裂缝面法向量 + D_value=core_frac_cell-grid_core;% 向量OF + vector_1=f(5*which_frac-3,:); + vector_2=f(5*which_frac-2,:); + n_vector_1=cross(vector_1,vector_2); + n_vector_2=-cross(vector_1,vector_2); + if (dot(n_vector_1,D_value))>=0 + n_vector=n_vector_1; + else + n_vector=n_vector_2; + end + % 方向投影面积 + area_frac_cell_x=abs(area_frac_cell*dot([1,0,0],n_vector)/norm(n_vector)); + area_frac_cell_y=abs(area_frac_cell*dot([0,1,0],n_vector)/norm(n_vector)); + area_frac_cell_z=abs(area_frac_cell*dot([0,0,1],n_vector)/norm(n_vector)); + %% ----------------------% 根据fractureCellType选取投影面-------------------------------------- + % selected_face(1)=4; nei_grid_x=i+1; + % selected_face(2)=5; nei_grid_y=i+nx; + % selected_face(3)=6;nei_grid_z=i+nx*ny; + %% 哪种类型? 1:2 1:3 1:4 + fractureCellType = zeros(numberFractureCells,1); + theNumber = 2; + fractureCellType = repmat((1:theNumber)',numberFractureCells/theNumber,1); + %% 选择哪种方法 + selectedMethod = 2; + %% when number = 2 + if theNumber == 2 + % method 1 + if selectedMethod == 1 + if fractureCellType(the_frac_cell) == 1 + nei_grid_x=i-1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 2 + nei_grid_x=i+1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + end + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y]; + struc_z=[i,nei_grid_z]; + end + % method 2 + if selectedMethod == 2 + if fractureCellType(the_frac_cell) == 1 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 2 + nei_grid_x=i+1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + end + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y]; + struc_z=[i,nei_grid_z]; + end + end + %% when number = 3 + if theNumber == 3 + % method 1 + if selectedMethod == 1 + if fractureCellType(the_frac_cell) == 1 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 2 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 3 + nei_grid_x=i+1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + end + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y]; + struc_z=[i,nei_grid_z]; + end + % method 2 + if selectedMethod == 2 + if fractureCellType(the_frac_cell) == 1 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + struc_x=[i,nei_grid_x]; + struc_y=[i,i];% 相当于没有 + struc_z=[i,nei_grid_z]; + end + if fractureCellType(the_frac_cell) == 2 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y];area_frac_cell_y = area_frac_cell_y*2;% 加上了fractureCellType(the_frac_cell) == 1时的area_frac_cell_y + struc_z=[i,nei_grid_z]; + end + if fractureCellType(the_frac_cell) == 3 + nei_grid_x=i+1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y]; + struc_z=[i,nei_grid_z]; + end + end + end + %% when number = 4 + if theNumber == 4 + % method 1 + if selectedMethod == 1 + if fractureCellType(the_frac_cell) == 1 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 2 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 3 + nei_grid_x=i+1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + end + if fractureCellType(the_frac_cell) == 4 + nei_grid_x=i+1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + end + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y]; + struc_z=[i,nei_grid_z]; + end + % method 2 + if selectedMethod == 2 + if fractureCellType(the_frac_cell) == 1 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + struc_x=[i,nei_grid_x]; + struc_y=[i,i]; + struc_z=[i,nei_grid_z]; + end + if fractureCellType(the_frac_cell) == 2 + nei_grid_x=i-1;nei_grid_y=i+nx;nei_grid_z=i+nx*ny; + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y];area_frac_cell_y = area_frac_cell_y*2; + struc_z=[i,nei_grid_z]; + end + if fractureCellType(the_frac_cell) == 3 + nei_grid_x=i+1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + struc_x=[i,nei_grid_x]; + struc_y=[i,nei_grid_y];area_frac_cell_y = area_frac_cell_y*2; + struc_z=[i,nei_grid_z]; + end + if fractureCellType(the_frac_cell) == 4 + nei_grid_x=i+1;nei_grid_y=i-nx;nei_grid_z=i+nx*ny; + struc_x=[i,nei_grid_x]; + struc_y=[i,i]; + struc_z=[i,nei_grid_z]; + end + end + end + %% ----------------------% 各方向投影面积叠加及传导率计算--------------------------------------------------------------- + %% x direction +% struc_x=[i,nei_grid_x]; + pos=find_row(struc_x,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_x; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_x)*ky(nei_grid_x)*kz(nei_grid_x))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_x,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 + % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 + % dis_added=norm(nei_grid_core-core_frac_cell); + % T_added=Knnc*area_frac_cell_x/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_x/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); + % T_added=0;%特殊情况 + % T_added=0;%特殊情况 + % T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_x,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end + %% y direction +% struc_y=[i,nei_grid_y]; + pos=find_row(struc_y,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_y; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_y)*ky(nei_grid_y)*kz(nei_grid_y))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_y,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 + % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 + % dis_added=norm(nei_grid_core-core_frac_cell); + % T_added=Knnc*area_frac_cell_y/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_y/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); + % T_added=0;%特殊情况 + % T_added=0.002;%特殊情况 + % T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_y,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end + + %% z direction +% struc_z=[i,nei_grid_z]; + pos=find_row(struc_z,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_z; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_z)*ky(nei_grid_z)*kz(nei_grid_z))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_z,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 + % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 + % dis_added=norm(nei_grid_core-core_frac_cell); + % T_added=Knnc*area_frac_cell_z/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_z/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); + % T_added=0;%特殊情况 + % T_added=0.0;%特殊情况 + % T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_z,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end + + end + end +end +%% 额外添加的改进 +im_N=[]; +im_T=[]; +% % % q=length(Kf)+1; +% % % for i=1:(q-1)/2%q-1是裂缝单元数量 +% % % for j=(q-1)/2+1:(q-1) +% % % if abs(corevsfra(j,2)-corevsfra(i,2))<=1e-2 +% % % im_N=[im_N;i+nmc,j+nmc]; +% % % % im_T=[im_T;0]; +% % % % im_T=[im_T;0.0039604]; +% % % % im_T=[im_T;(((Kf(i))^(-1)+(1e-3)^(-1)+(1e-3)^(-1)+(Kf(j))^(-1))/4)^(-1)*2*2/0.4]; +% % % im_T=[im_T;(((Kf(i))^(-1)+(1e-3)^(-1)+(1e-3)^(-1)+(Kf(j))^(-1))/4)^(-1)*0.5*2/0.4]; +% % % % +% % % end +% % % end +% % % end +%% 用投影面积修正基质网格间传导 +for i=1:nmm + % 为避免数值误差,导致没有真正封堵住,故 + if (S_ex(i)-S_p(i))/S_ex(i)<=1e-2 + T(i)=0; + else + T(i)= T(i)*(S_ex(i)-S_p(i))/S_ex(i); + end +end +%% 实用型pEDFM额外处理 +% % % num_frac = size(frac_information,1)/3; +% % % for i = 1:num_frac +% % % if frac_information(3*i,1) <= (kx(1)*ky(1)*kz(1))^(1/3) +% % % % 裂缝的两端点 +% % % one_end = frac_information(3*i-2,:); +% % % the_other_end = frac_information(3*i-1,:); +% % % % 两网格之间的连接 +% % % for j = 1:size(N,1) +% % % added_matnodes_1=nodes(N(j,1),:); +% % % one_node_connect=mean(coord(added_matnodes_1,:));%该基质网格中心 +% % % added_matnodes_2=nodes(N(j,2),:); +% % % the_other_node_connect=mean(coord(added_matnodes_2,:)); +% % % coef_matrix = [ +% % % the_other_end(1)-one_end(1),-(the_other_node_connect(1)-one_node_connect(1)); +% % % the_other_end(2)-one_end(2),-(the_other_node_connect(2)-one_node_connect(2));]; +% % % coef_vector = [one_node_connect(1)-one_end(1);one_node_connect(2)-one_end(2);]; +% % % if abs(det(coef_matrix))<=1e-12 +% % % else +% % % parameters = coef_matrix\coef_vector; +% % % if parameters(1)>=0 && parameters(1)<=1 && parameters(2)>=0 && parameters(2)<=1 +% % % T(j) = (T(j)^-1 + frac_information(3*i,1)^-1)^-1; +% % % end +% % % end +% % % end +% % % end +% % % end +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;Nmf_projection;im_N]; +T = [T; Tmff; Tff;Tinterflow;Tmf_projection;im_T]; +% N = [N; Nmff+nmc; Nff+nmc;Ninterflow;Nmf_projection]; +% T = [T; Tmff; Tff;Tinterflow;Tmf_projection]; +nex=size(N,1); +end + + diff --git a/generic extended/connections_PEDFM_new.m b/generic extended/connections_PEDFM_new.m new file mode 100644 index 0000000..1e3bbab --- /dev/null +++ b/generic extended/connections_PEDFM_new.m @@ -0,0 +1,735 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff] = connections_PEDFM_new( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag,frac_information,coordinates) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf +rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; +for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); +% indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end +end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 +% if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; +end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,1);%裂缝网格渗透率 +Wf=zeros(q-1,1);%裂缝单元缝宽 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if i == 41 + flag = 1; + end + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 +for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if Kf(j)==0 || Kf(k)==0 + hartran=0; + else + tran1=Kf(j)*wf(i)*lengthcat/disk; + tran2=Kf(k)*wf(i)*lengthcat/disj; +% hartran=length/(disk+disj);%取调和平均的一半 + hartran=tran1*tran2/(tran1+tran2); + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 +% lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 Tmff=[Tmff; 0]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +S_ex=zeros(nmm,1);% 流体交换面面积 + +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +c = 0; +for k= 1 : nz +for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); +% 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)/(Kx(index)*dxv(indexn) + Kx(indexn)*dxv(index)); + S_ex(c)=dzv(index)*dyv(index); + end +end +end + +for k= 1 : nz +for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + S_ex(c)=dzv(index)*dxv(index); + end +end +end + +for i = 1 : nx +for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + S_ex(c)=dxv(index)*dyv(index); + end +end +end + + + + +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=areavsfra(matrixvsfra(i,j));% 此处与原始嵌入式不一样,原始是两倍 + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + % 为论文做修改 +% Dn=0.9; +% Dn=2.5; + % raoT=Knnc*Annc/Dn; + raoT1 = kcell*Annc/Dn; + raoT2 = Kf(matrixvsfra(i,j))*Annc/(Wf(matrixvsfra(i,j))/2); + raoT = (raoT1^-1+raoT2^-1)^-1; + Tinterflow=[Tinterflow;raoT]; + end + end +end + +%% 投影嵌入式处理 +nmc=size(matrixvsfra,1); +%基质网格流体交换面上的裂缝单元投影面之和 +S_p=zeros(nmm,1); +% 因为投影处理新加的F-M connections +Nmf_projection=[]; +Tmf_projection=[]; +for i=1:nmc + matnodes=nodes(i,:); + dx_grid=dxv(i); + dy_grid=dyv(i); + dz_grid=dzv(i); + grid_core=mean(coord(matnodes,:));%该基质网格中心 + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n==1) %先仅考虑n=1时的情况 + selected_face=zeros(1,3); + the_frac_cell=matrixvsfra(i,indice);%该裂缝单元编号 +% if Kf(the_frac_cell) <= (kx(i)*ky(i)*kz(i))^(1/3);% +% else + which_frac=fcff{1,2}(the_frac_cell,1);%该裂缝单元所在的裂缝面 + core_frac_cell=fcff{1,4}(the_frac_cell,1:3);%该裂缝单元的中心坐标 + area_frac_cell=fcff{1,8}(the_frac_cell,1);%该裂缝单元面积 + rao_struct=[i,the_frac_cell+nmc]; + pos_rao=find_row(rao_struct,Ninterflow); + D_value=core_frac_cell-grid_core;% 向量OF + vector_1=f(5*which_frac-3,:); + vector_2=f(5*which_frac-2,:); + n_vector_1=cross(vector_1,vector_2); + n_vector_2=-cross(vector_1,vector_2); + if (dot(n_vector_1,D_value))>=0 + n_vector=n_vector_1; + else + n_vector=n_vector_2; + end + %该裂缝面法向量 + % x方向投影面积 + area_frac_cell_x=abs(area_frac_cell*dot([1,0,0],n_vector)/norm(n_vector)); + area_frac_cell_y=abs(area_frac_cell*dot([0,1,0],n_vector)/norm(n_vector)); + area_frac_cell_z=abs(area_frac_cell*dot([0,0,1],n_vector)/norm(n_vector)); +% %% 为valid case修改 +% area_frac_cell_x=10*10; +% area_frac_cell_y=10*10; +% area_frac_cell_z=10*10; + %将裂缝中心沿法向量做微小平移,此时再按照距离最近原则判断,可以保证得到符合物理意义的情况 + new_core=core_frac_cell+1e-6*n_vector; + % 裂缝单元中心相对于基质网格中心的向矢 + %x direction + D_value_new=new_core-grid_core; + if D_value_new(1)<=0 + selected_face(1)=3;nei_grid_x=i-1; + else selected_face(1)=4; nei_grid_x=i+1; + end +%% ----------------------% 为了做测试实用型pEDFM,人为加处理-------------------------------------- + % 为了做测试实用型pEDFM,人为加处理 +% selected_face(1)=4; nei_grid_x=i+1; +%% ----------------------% 人为处理结束--------------------------------------------------------------- + struc_x=[i,nei_grid_x]; + pos=find_row(struc_x,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_x; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_x)*ky(nei_grid_x)*kz(nei_grid_x))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_x,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% dis_added=norm(nei_grid_core-core_frac_cell); +% T_added=Knnc*area_frac_cell_x/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_x/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); + % T_added=0;%特殊情况 +% T_added=0;%特殊情况 +% T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_x,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end + + %y direction + if D_value_new(2)<=0 + selected_face(2)=2;nei_grid_y=i-nx; + else selected_face(2)=5;nei_grid_y=i+nx; + end +%% ----------------------% 为了做测试实用型pEDFM,人为加处理-------------------------------------- + % 为了做测试实用型pEDFM,人为加处理 +% selected_face(2)=5; nei_grid_y=i+nx; +%% ----------------------% 人为处理结束--------------------------------------------------------------- + struc_y=[i,nei_grid_y]; + pos=find_row(struc_y,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_y; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_y)*ky(nei_grid_y)*kz(nei_grid_y))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_y,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% dis_added=norm(nei_grid_core-core_frac_cell); +% T_added=Knnc*area_frac_cell_y/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_y/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); + % T_added=0;%特殊情况 +% T_added=0.002;%特殊情况 +% T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_y,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end + + + % z direction + if D_value_new(3)<=0 + selected_face(3)=1;nei_grid_z=i-nx*ny; + else selected_face(3)=6;nei_grid_z=i+nx*ny; + end +%% ----------------------% 为了做测试实用型pEDFM,人为加处理-------------------------------------- + % 为了做测试实用型pEDFM,人为加处理 +% selected_face(3)=6;nei_grid_z=i+nx*ny; +%% ----------------------% 人为处理结束--------------------------------------------------------------- +% nei_grid_z=i-nx*ny; + struc_z=[i,nei_grid_z]; + pos=find_row(struc_z,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_z; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_z)*ky(nei_grid_z)*kz(nei_grid_z))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_z,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% dis_added=norm(nei_grid_core-core_frac_cell); +% T_added=Knnc*area_frac_cell_z/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_z/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% T_added=0;%特殊情况 +% T_added=0.0;%特殊情况 +% T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_z,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + end +% %% 例二添加的 +% if D_value_new(1)>0 +% selected_face(1)=3;nei_grid_x=i-1; +% else selected_face(1)=4; nei_grid_x=i+1; +% end +% struc_x=[i,nei_grid_x]; +% pos=find_row(struc_x,N); +% if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 +% S_p(pos)=S_p(pos)+area_frac_cell_x; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 +% knei=(kx(nei_grid_x)*ky(nei_grid_x)*kz(nei_grid_x))^(1/3);%相邻那个基质网格渗透率 +% added_matnodes=nodes(nei_grid_x,:); +% nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% % dis_added=norm(nei_grid_core-core_frac_cell); +% % T_added=Knnc*area_frac_cell_x/dis_added; +% % 采用另一种方式计算几何因子 +% dis_added=norm(nei_grid_core-core_frac_cell); +% if Kf(the_frac_cell)==0 +% T_added=0; +% else +% % 单独裂缝单元几何因子 +% Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); +% % 单独相邻基质网格向裂缝单元几何因子 +% Geofnei=knei*area_frac_cell_x/dis_added; +% % 单独该基质网格向裂缝单元几何因子 +% Geofcell=Tinterflow(pos_rao,1); +% +% T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% % T_added=0;%特殊情况 +% % T_added=0;%特殊情况 +% % T_added=0.0039604;%特殊情况 +% end +% Nmf_projection=[Nmf_projection;nei_grid_x,the_frac_cell+nmc]; +% Tmf_projection=[Tmf_projection;T_added]; +% end +% +% %y direction +% if D_value_new(2)>0 +% selected_face(1)=2;nei_grid_y=i-nx; +% else selected_face(1)=5;nei_grid_y=i+nx; +% end +% struc_y=[i,nei_grid_y]; +% pos=find_row(struc_y,N); +% if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 +% S_p(pos)=S_p(pos)+area_frac_cell_y; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 +% knei=(kx(nei_grid_y)*ky(nei_grid_y)*kz(nei_grid_y))^(1/3);%相邻那个基质网格渗透率 +% added_matnodes=nodes(nei_grid_y,:); +% nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% % dis_added=norm(nei_grid_core-core_frac_cell); +% % T_added=Knnc*area_frac_cell_y/dis_added; +% % 采用另一种方式计算几何因子 +% dis_added=norm(nei_grid_core-core_frac_cell); +% if Kf(the_frac_cell)==0 +% T_added=0; +% else +% % 单独裂缝单元几何因子 +% Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); +% % 单独相邻基质网格向裂缝单元几何因子 +% Geofnei=knei*area_frac_cell_y/dis_added; +% % 单独该基质网格向裂缝单元几何因子 +% Geofcell=Tinterflow(pos_rao,1); +% +% T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% % T_added=0;%特殊情况 +% % T_added=0.002;%特殊情况 +% % T_added=0.0039604;%特殊情况 +% end +% Nmf_projection=[Nmf_projection;nei_grid_y,the_frac_cell+nmc]; +% Tmf_projection=[Tmf_projection;T_added]; +% end +% +% +% % z direction +% if D_value_new(3)>0 +% selected_face(1)=1;nei_grid_z=i-nx*ny; +% else selected_face(1)=6;nei_grid_z=i+nx*ny; +% end +% % nei_grid_z=i-nx*ny; +% struc_z=[i,nei_grid_z]; +% pos=find_row(struc_z,N); +% if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 +% S_p(pos)=S_p(pos)+area_frac_cell_z; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 +% knei=(kx(nei_grid_z)*ky(nei_grid_z)*kz(nei_grid_z))^(1/3);%相邻那个基质网格渗透率 +% added_matnodes=nodes(nei_grid_z,:); +% nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 +% % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 +% % dis_added=norm(nei_grid_core-core_frac_cell); +% % T_added=Knnc*area_frac_cell_z/dis_added; +% % 采用另一种方式计算几何因子 +% dis_added=norm(nei_grid_core-core_frac_cell); +% if Kf(the_frac_cell)==0 +% T_added=0; +% else +% % 单独裂缝单元几何因子 +% Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); +% % 单独相邻基质网格向裂缝单元几何因子 +% Geofnei=knei*area_frac_cell_z/dis_added; +% % 单独该基质网格向裂缝单元几何因子 +% Geofcell=Tinterflow(pos_rao,1); +% +% T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% % T_added=0;%特殊情况 +% % T_added=0.0;%特殊情况 +% % T_added=0.0039604;%特殊情况 +% end +% Nmf_projection=[Nmf_projection;nei_grid_z,the_frac_cell+nmc]; +% Tmf_projection=[Tmf_projection;T_added]; +% end + +% end + end + end +end +%% 额外添加的改进 +im_N=[]; +im_T=[]; +% q=length(Kf)+1; +% for i=1:(q-1)/2%q-1是裂缝单元数量 +% for j=(q-1)/2+1:(q-1) +% if norm(corevsfra(j,:)-corevsfra(i,:))<=3*1e-1 +% im_N=[im_N;i+nmc,j+nmc]; +% % im_T=[im_T;0]; +% % im_T=[im_T;0.0039604]; +% % im_T=[im_T;(((Kf(i))^(-1)+(1e-3)^(-1)+(1e-3)^(-1)+(Kf(j))^(-1))/4)^(-1)*2*2/0.4]; +% % im_T=[im_T;(((Kf(i))^(-1)+(1e-3)^(-1)+(1e-3)^(-1)+(Kf(j))^(-1))/4)^(-1)*0.5*2/0.4]; +% im_T=[im_T;((Kf(i)*1*2/0.005)^-1+(Kf(j)*1*2/0.005)^-1+(5*1e-3*1*2/0.1)^-1+(5*1e-3*1*2/0.1)^-1)^-1]; +% % +% end +% end +% end +%% 用投影面积修正基质网格间传导 +for i=1:nmm + % 为避免数值误差,导致没有真正封堵住,故 + if (S_ex(i)-S_p(i))/S_ex(i)<=1e-2 + T(i)=0; + else + T(i)= T(i)*(S_ex(i)-S_p(i))/S_ex(i); + end +end +%% 实用型pEDFM额外处理 +% % % num_frac = size(frac_information,1)/3; +% % % for i = 1:num_frac +% % % if frac_information(3*i,1) <= (kx(1)*ky(1)*kz(1))^(1/3) +% % % % 裂缝的两端点 +% % % one_end = frac_information(3*i-2,:); +% % % the_other_end = frac_information(3*i-1,:); +% % % % 两网格之间的连接 +% % % for j = 1:size(N,1) +% % % added_matnodes_1=nodes(N(j,1),:); +% % % one_node_connect=mean(coord(added_matnodes_1,:));%该基质网格中心 +% % % added_matnodes_2=nodes(N(j,2),:); +% % % the_other_node_connect=mean(coord(added_matnodes_2,:)); +% % % coef_matrix = [ +% % % the_other_end(1)-one_end(1),-(the_other_node_connect(1)-one_node_connect(1)); +% % % the_other_end(2)-one_end(2),-(the_other_node_connect(2)-one_node_connect(2));]; +% % % coef_vector = [one_node_connect(1)-one_end(1);one_node_connect(2)-one_end(2);]; +% % % if abs(det(coef_matrix))<=1e-12 +% % % else +% % % parameters = coef_matrix\coef_vector; +% % % if parameters(1)>=0 && parameters(1)<=1 && parameters(2)>=0 && parameters(2)<=1 +% % % T(j) = (T(j)^-1 + frac_information(3*i,1)^-1)^-1; +% % % end +% % % end +% % % end +% % % end +% % % end +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;Nmf_projection;im_N]; +T = [T; Tmff; Tff;Tinterflow;Tmf_projection;im_T]; +% N = [N; Nmff+nmc; Nff+nmc;Ninterflow;Nmf_projection]; +% T = [T; Tmff; Tff;Tinterflow;Tmf_projection]; +nex=size(N,1); +end diff --git a/generic extended/connections_PEDFM_new_new.m b/generic extended/connections_PEDFM_new_new.m new file mode 100644 index 0000000..4540d17 --- /dev/null +++ b/generic extended/connections_PEDFM_new_new.m @@ -0,0 +1,714 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff, flowArea, perm, matrixflag] = connections_PEDFM_new_new( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,pori,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag,frac_information,coordinates) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +cell_center_coordinates = zeros(nx*ny*nz, 3); % 裂缝网格中心在该矩阵基础上添加 +for j = 1:nx*ny*nz + nodes_of_the_cell = nodes(j,:); + cell_center_coordinates(j,:) = mean(coord(nodes_of_the_cell,:));%该基质网格中心 +end +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf + rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; + for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); + % indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end + end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 + % if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; + end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +number_fracture_cells = q-1; +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,1);%裂缝网格渗透率 +Wf=zeros(q-1,1);%裂缝单元缝宽 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +fracFaceArea=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +avfracFaceArea=zeros(q-1,1); +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 + for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if Kf(j)==0 || Kf(k)==0 + hartran=0; + kij = 0; + else + tran1=Kf(j)*wf(i)*lengthcat/disk; + tran2=Kf(k)*wf(i)*lengthcat/disj; + % hartran=length/(disk+disj);%取调和平均的一半 + hartran=tran1*tran2/(tran1+tran2); + kij = 2*(Kf(j)^(-1)+Kf(k)^(-1))^(-1); + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + perm_ff = [perm_ff; kij]; + flowArea_ff = [flowArea_ff; wf(i)*lengthcat]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +perm_ff(1,:)=[]; +flowArea_ff(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +perm_mff=zeros(1,1); +flowArea_mff=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 + % lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 Tmff=[Tmff; 0]; perm_mff=[perm_mff;0];flowArea_mff=[flowArea_mff;(avfracFaceArea(fc1)+avfracFaceArea(fc2))/2]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + perm_mff=[perm_mff;(Kf(fc1)^(-1)+Kf(fc2)^(-1))^(-1)]; + flowArea_mff=[flowArea_mff;(avfracFaceArea(fc1)+avfracFaceArea(fc2))/2]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +perm_mff(1,:)=[]; +flowArea_mff(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +S_ex=zeros(nmm,1);% 流体交换面面积 + +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +perm = zeros(nmm, 1); +flowArea = zeros(nmm, 1); +c = 0; +for k= 1 : nz + for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + % 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)/(Kx(index)*dxv(indexn) + Kx(indexn)*dxv(index)); + S_ex(c)=dzv(index)*dyv(index); + perm(c)=2*Kx(index)*Kx(indexn)/(Kx(index) + Kx(indexn)); + flowArea(c)=dzv(index)*dyv(index); + end + end +end + +for k= 1 : nz + for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + S_ex(c)=dzv(index)*dxv(index); + perm(c)=2*Ky(index)*Ky(indexn)/(Ky(index) + Ky(indexn)); + flowArea(c)=dzv(index)*dxv(index); + end + end +end + +for i = 1 : nx + for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + S_ex(c)=dxv(index)*dyv(index); + perm(c)=2*Kz(index)*Kz(indexn)/(Kz(index) + Kz(indexn)); + flowArea(c)=dxv(index)*dyv(index); + end + end +end + +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +perm_interflow=[]; +flowArea_interflow=[]; +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 +% if matrixvsfra(i,j)~=0 + if matrixvsfra(i,j)~=0 && (matrixvsfra(i,j) <= number_fracture_cells) %this matrix cell contains a fracture cell + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Annc=areavsfra(matrixvsfra(i,j));% 此处与原始嵌入式不一样,原始是两倍 + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); + % dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + % Dn=0.9; + % Dn=0.15; + % Dn = (5-0.5)/2; + raoT1 = kcell*Annc/Dn; + raoT2 = Kf(matrixvsfra(i,j))*Annc/(Wf(matrixvsfra(i,j))/2); + raoT = (raoT1^-1+raoT2^-1)^-1; + % raoT=Knnc*Annc/Dn; + Tinterflow=[Tinterflow;raoT]; + perm_mf_this = kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + perm_interflow = [perm_interflow; perm_mf_this]; + flowArea_interflow = [flowArea_interflow; Annc]; + end + end +end + +%% 投影嵌入式处理 +nmc=size(matrixvsfra,1); +%基质网格流体交换面上的裂缝单元投影面之和 +S_p=zeros(nmm,1); +% 因为投影处理新加的F-M connections +Nmf_projection=[]; +Tmf_projection=[]; +perm_projection=[]; +flowArea_projection=[]; +for i=1:nmc + matnodes=nodes(i,:); + dx_grid=dxv(i); + dy_grid=dyv(i); + dz_grid=dzv(i); + grid_core=mean(coord(matnodes,:));%该基质网格中心 + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); +% if (n>=1) + the_frac_cells=matrixvsfra(i,indice);%该裂缝单元编号 + if (n>=1) %先仅考虑n=1时的情况 + selected_face=zeros(1,3); + if n>1 + flag =1; + end + for haihaihai = 1:length(the_frac_cells) + the_frac_cell = the_frac_cells(haihaihai); + if Kf(the_frac_cell) <= (kx(i)*ky(i)*kz(i))^(1/3) % + else + which_frac=fcff{1,2}(the_frac_cell,1);%该裂缝单元所在的裂缝面 + core_frac_cell=fcff{1,4}(the_frac_cell,1:3);%该裂缝单元的中心坐标 + area_frac_cell=fcff{1,8}(the_frac_cell,1);%该裂缝单元面积 + rao_struct=[i,the_frac_cell+nmc]; + pos_rao=find_row(rao_struct,Ninterflow); + D_value=core_frac_cell-grid_core;% 向量OF + vector_1=f(5*which_frac-3,:); + vector_2=f(5*which_frac-2,:); + n_vector_1=cross(vector_1,vector_2); + n_vector_2=-cross(vector_1,vector_2); + if (dot(n_vector_1,D_value))>=0 + n_vector=n_vector_1; + else + n_vector=n_vector_2; + end + %该裂缝面法向量 + % x方向投影面积 + area_frac_cell_x=abs(area_frac_cell*dot([1,0,0],n_vector)/norm(n_vector)); + area_frac_cell_y=abs(area_frac_cell*dot([0,1,0],n_vector)/norm(n_vector)); + area_frac_cell_z=abs(area_frac_cell*dot([0,0,1],n_vector)/norm(n_vector)); + % %% 为valid case修改 + % area_frac_cell_x=10*10; + % area_frac_cell_y=10*10; + % area_frac_cell_z=10*10; + %将裂缝中心沿法向量做微小平移,此时再按照距离最近原则判断,可以保证得到符合物理意义的情况 + new_core=core_frac_cell+1e-4*n_vector; + % 裂缝单元中心相对于基质网格中心的向矢 + %x direction + D_value_new=new_core-grid_core; + if D_value_new(1)<=0 + selected_face(1)=3;nei_grid_x=i-1; + else selected_face(1)=4; nei_grid_x=i+1; + end + %% ----------------------% 为了做测试实用型pEDFM,人为加处理-------------------------------------- + % 为了做测试实用型pEDFM,人为加处理 +% selected_face(1)=4; nei_grid_x=i+1; + %% ----------------------% 人为处理结束--------------------------------------------------------------- + struc_x=[i,nei_grid_x]; + pos=find_row(struc_x,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_x; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_x)*ky(nei_grid_x)*kz(nei_grid_x))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_x,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 + % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 + % dis_added=norm(nei_grid_core-core_frac_cell); + % T_added=Knnc*area_frac_cell_x/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + % dis_added = (5+0.5)/2; + Geofnei=knei*area_frac_cell_x/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); + T_added = 1/(1/Geofnei+1/Geof); +% T_added=0;%特殊情况 + % T_added=0;%特殊情况 + % T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_x,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + perm_projection =[perm_projection;knei]; + flowArea_projection = [flowArea_projection;area_frac_cell_x]; + end + + %y direction + if D_value_new(2)<=0 + selected_face(2)=2;nei_grid_y=i-nx; + else selected_face(2)=5;nei_grid_y=i+nx; + end + %% ----------------------% 为了做测试实用型pEDFM,人为加处理-------------------------------------- + % 为了做测试实用型pEDFM,人为加处理 +% selected_face(2)=5; nei_grid_y=i+nx; + %% ----------------------% 人为处理结束--------------------------------------------------------------- + struc_y=[i,nei_grid_y]; + pos=find_row(struc_y,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_y; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_y)*ky(nei_grid_y)*kz(nei_grid_y))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_y,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 + % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 + % dis_added=norm(nei_grid_core-core_frac_cell); + % T_added=Knnc*area_frac_cell_y/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_y/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); + T_added = 1/(1/Geofnei+1/Geof); +% T_added=0;%特殊情况 + % T_added=0.002;%特殊情况 + % T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_y,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + perm_projection =[perm_projection;knei]; + flowArea_projection = [flowArea_projection;area_frac_cell_y]; + end + + + % z direction + if D_value_new(3)<=0 + selected_face(3)=1;nei_grid_z=i-nx*ny; + else selected_face(3)=6;nei_grid_z=i+nx*ny; + end + %% ----------------------% 为了做测试实用型pEDFM,人为加处理-------------------------------------- + % 为了做测试实用型pEDFM,人为加处理 +% selected_face(3)=6;nei_grid_z=i+nx*ny; + %% ----------------------% 人为处理结束--------------------------------------------------------------- + % nei_grid_z=i-nx*ny; + struc_z=[i,nei_grid_z]; + pos=find_row(struc_z,N); + if size(pos,1)==1 %说明需要削减这两个基质网格间的传导系数 + S_p(pos)=S_p(pos)+area_frac_cell_z; + kcell=(kx(i)*ky(i)*kz(i))^(1/3);%基质网格渗透率 + knei=(kx(nei_grid_z)*ky(nei_grid_z)*kz(nei_grid_z))^(1/3);%相邻那个基质网格渗透率 + added_matnodes=nodes(nei_grid_z,:); + nei_grid_core=mean(coord(added_matnodes,:));%该基质网格中心 + % Knnc=2*kcell*Kf(the_frac_cell)/(kcell+Kf(the_frac_cell));%调和平均后 + % dis_added=norm(nei_grid_core-core_frac_cell); + % T_added=Knnc*area_frac_cell_z/dis_added; + % 采用另一种方式计算几何因子 + dis_added=norm(nei_grid_core-core_frac_cell); + if Kf(the_frac_cell)==0 + T_added=0; + else + % 单独裂缝单元几何因子 + Geof=Kf(the_frac_cell)*area_frac_cell/(Wf(the_frac_cell)/2); + % 单独相邻基质网格向裂缝单元几何因子 + Geofnei=knei*area_frac_cell_z/dis_added; + % 单独该基质网格向裂缝单元几何因子 + Geofcell=Tinterflow(pos_rao,1); + + T_added=1/(1/Geofnei+1/Geofcell+1/Geof); +% T_added=0;%特殊情况 + % T_added=0.0;%特殊情况 + % T_added=0.0039604;%特殊情况 + end + Nmf_projection=[Nmf_projection;nei_grid_z,the_frac_cell+nmc]; + Tmf_projection=[Tmf_projection;T_added]; + perm_projection =[perm_projection;knei]; + flowArea_projection = [flowArea_projection;area_frac_cell_z]; + end + end + end + end + end +end +%% 额外添加的改进 +im_N=[]; +im_T=[]; +% q=length(Kf)+1; +% for i=1:(q-1)/2%q-1是裂缝单元数量 +% for j=(q-1)/2+1:(q-1) +% if abs(corevsfra(j,1)-corevsfra(i,1))<=1e-2 +% im_N=[im_N;i+nmc,j+nmc]; +% % im_T=[im_T;0]; +% im_T=[im_T;0.0039604]; +% % im_T=[im_T;(((Kf(i))^(-1)+(1e-3)^(-1)+(1e-3)^(-1)+(Kf(j))^(-1))/4)^(-1)*2*2/0.4]; +% % +% end +% end +% end +%% 用投影面积修正基质网格间传导 +num_weaken = 0; +for i=1:nmm + % 为避免数值误差,导致没有真正封堵住,故 + if (S_ex(i)-S_p(i))/S_ex(i)<=1e-2 + T(i)=0; + num_weaken = num_weaken+1; + else + T(i)= T(i)*(S_ex(i)-S_p(i))/S_ex(i); + end +end +% % % %% 实用型pEDFM额外处理 +% % % num_frac = size(frac_information,1)/3; +% % % for i = 1:num_frac +% % % if frac_information(3*i,1) <= (kx(1)*ky(1)*kz(1))^(1/3) +% % % % 裂缝的两端点 +% % % one_end = frac_information(3*i-2,:); +% % % the_other_end = frac_information(3*i-1,:); +% % % % 两网格之间的连接 +% % % for j = 1:size(N,1) +% % % added_matnodes_1=nodes(N(j,1),:); +% % % one_node_connect=mean(coord(added_matnodes_1,:));%该基质网格中心 +% % % added_matnodes_2=nodes(N(j,2),:); +% % % the_other_node_connect=mean(coord(added_matnodes_2,:)); +% % % coef_matrix = [ +% % % the_other_end(1)-one_end(1),-(the_other_node_connect(1)-one_node_connect(1)); +% % % the_other_end(2)-one_end(2),-(the_other_node_connect(2)-one_node_connect(2));]; +% % % coef_vector = [one_node_connect(1)-one_end(1);one_node_connect(2)-one_end(2);]; +% % % if abs(det(coef_matrix))<=1e-12 +% % % else +% % % parameters = coef_matrix\coef_vector; +% % % if parameters(1)>=0 && parameters(1)<=1 && parameters(2)>=0 && parameters(2)<=1 +% % % T(j) = (T(j)^-1 + frac_information(3*i,1)^-1)^-1; +% % % end +% % % end +% % % end +% % % end +% % % end +%% 把上述三种情况的矩阵分别叠加起来 +matrixflag = [ones(size(T,1),1); zeros(size(Tmff,1),1); zeros(size(Tff,1),1); ones(size(Tinterflow,1),1); ones(size(Tmf_projection,1),1); ones(size(im_T,1),1)]; +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;Nmf_projection;im_N]; +% Tmff = Tmff*0; +T = [T; Tmff; Tff;Tinterflow;Tmf_projection;im_T]; +perm = [perm; perm_mff; perm_ff;perm_interflow; perm_projection]; +flowArea = [flowArea; flowArea_mff; flowArea_ff;flowArea_interflow; flowArea_projection+0.0001]; +% N = [N; Nmff+nmc; Nff+nmc;Ninterflow;Nmf_projection]; +% T = [T; Tmff; Tff;Tinterflow;Tmf_projection]; +nex=size(N,1); +%% 实用型pEDFM额外处理 +num_frac = size(frac_information,1)/3; +for i = 1:num_frac + if frac_information(3*i,1) <= (kx(1)*ky(1)*kz(1))^(1/3) % 此处为做算例简化编写代码的, || i == 2 + % 裂缝的两端点 + one_end = frac_information(3*i-2,:); + the_other_end = frac_information(3*i-1,:); + % 两网格之间的连接 + for j = 1:size(N,1) + % added_matnodes_1=nodes(N(j,1),:); + % one_node_connect=mean(coord(added_matnodes_1,:));%该基质网格中心 + % added_matnodes_2=nodes(N(j,2),:); + % the_other_node_connect=mean(coord(added_matnodes_2,:)); + one_node_connect = cell_center_coordinates(N(j,1),:); + the_other_node_connect = cell_center_coordinates(N(j,2),:); + coef_matrix = [ + the_other_end(1)-one_end(1),-(the_other_node_connect(1)-one_node_connect(1)); + the_other_end(2)-one_end(2),-(the_other_node_connect(2)-one_node_connect(2));]; + coef_vector = [one_node_connect(1)-one_end(1);one_node_connect(2)-one_end(2);]; + if abs(det(coef_matrix))<=1e-12 + else + parameters = coef_matrix\coef_vector; + if parameters(1)>=0 && parameters(1)<=1 && parameters(2)>=0 && parameters(2)<=1 + disp('a T modfification in the new pEDFM'); + disp(T(j)); + if T(j) > 0.006 + flag = 1; + end + T(j) = (T(j)^-1 + (frac_information(3*i,1)/(frac_information(3*i,2)/2))^-1)^-1; +% T(j) = 0.005; + disp(T(j)); + end + end + end + end +end +%% 转到CMG或者ECLIPSE进行计算 +% [ Data_for_ECLIPSE ] = pEDFM_to_CMG_horizontalFractureWell(dxv,dyv,dzv,kx,ky,kz,pori,Kf,Wf,vf,porf,N,T); +% [ Data_for_ECLIPSE ] = pEDFM_to_CMG_horizontalFractureWell_net_pay(dxv,dyv,dzv,kx,ky,kz,pori,Kf,Wf,vf,porf,N,T); +end diff --git a/generic extended/connections_unstructured_EDFM_EX1_solutions.m b/generic extended/connections_unstructured_EDFM_EX1_solutions.m new file mode 100644 index 0000000..b99c0e9 --- /dev/null +++ b/generic extended/connections_unstructured_EDFM_EX1_solutions.m @@ -0,0 +1,629 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio, fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX1_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag ) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf +rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; +for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 +% m=floor((i+(2^nf)-1)/(2^nf)); + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); +% indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end +end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +mat_frac=[]; +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 +% if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + mat_frac=[mat_frac;i]; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; +end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +% Kffl=funtion_data.Kffl; +% Dffl=funtion_data.Dffl; +% kffl=zeros(q-1,1); +% dffl=zeros(q-1,1); +fractureCellFlag = (1:q-1)'; +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,10);%裂缝网格渗透率 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +ave_disvsfra=zeros(q-1,1); +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 +for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if kf(i)==0 hartran=0;hartran_convection=0; + else + tran1=kf(i)*wf(i)*lengthcat/disk; + tran2=kf(i)*wf(i)*lengthcat/disj; +% hartran=length/(disk+disj);%取调和平均 + hartran=tran1*tran2/(tran1+tran2); + k_harmony= kf(i); + hartran_convection=kf(i)/(disk+disj)^2; + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + Tff_convection=[Tff_convection;hartran_convection]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +Tff_convection(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +Tmff_convection=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 +% lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 Tmff=[Tmff; 0];Tmff_convection=[Tmff_convection;0]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +Tmff_convection(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +T_convection = zeros(nmm, 1); +c = 0; +for k= 1 : nz +for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + T_convection(c) = 2/(1/Kx(index)+1/Kx(indexn))/(dxv(indexn)+dxv(index)); + end +end +end + +for k= 1 : nz +for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + T_convection(c) = 2/(1/Ky(index)+1/Ky(indexn))/(dyv(indexn)+dyv(index)); + end +end +end + +for i = 1 : nx +for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + T_convection(c) = 2/(1/Kz(index)+1/Kz(indexn))/(dzv(indexn)+dzv(index)); + end +end +end +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +Tinterflow_convection=[]; +matrix_cells_containing_fracture_cells = []; +volume_ratio = []; +fractureMatrixFlag = zeros(size(fractureCellFlag,1),2); +numberInGroup = 3; +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + fractureMatrixFlag(matrixvsfra(i,j),:) = [matrixvsfra(i,j),i]; + matrix_cells_containing_fracture_cells = [matrix_cells_containing_fracture_cells; i]; + if mod(matrixvsfra(i,j),numberInGroup) == 1 volume_ratio = [volume_ratio; 5/6];end + if mod(matrixvsfra(i,j),numberInGroup) == 2 volume_ratio = [volume_ratio; 1/2];end + if mod(matrixvsfra(i,j),numberInGroup) == 0 volume_ratio = [volume_ratio; 1/6];end + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=2*areavsfra(matrixvsfra(i,j)); + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + raoT=Knnc*Annc/Dn; + raoT_convection=2*Knnc/Dn^2; + Tinterflow=[Tinterflow;raoT]; + Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + end + end +end +%% 额外处理,此处并未通用化,有待进一步开展 +nfc=size(fracnumber,1); +the_added_matrix_cells = []; +nmc=nx * ny*nz; +the_added_mf_connec = []; +the_added_mf_T = []; +number_of_adding = 0; +cell_divided_by_fracture_flag = matrix_cells_containing_fracture_cells; +% 记录基质网格被分成了哪两个网格,并删除原有的与这些基质网格相关的连接 +matrixCellsDivided = zeros(size(matrix_cells_containing_fracture_cells,1),2); +deletedFlag = []; +for i = 1:size(matrix_cells_containing_fracture_cells,1) + the_matrix_cell = matrix_cells_containing_fracture_cells(i,1); + number_of_adding = number_of_adding+1; + the_new_cell = number_of_adding+nmc; + the_added_matrix_cells = [the_added_matrix_cells; the_new_cell]; + matrixCellsDivided(i,:) = [the_matrix_cell, the_new_cell]; + % m-m连接 + for j = 1:size(N,1) + if N(j,1) == the_matrix_cell || N(j,2) == the_matrix_cell + deletedFlag = [deletedFlag; j]; + end +% % % if N(j,2) == the_matrix_cell+1 +% % % N(j,1) = the_new_cell; T(j) = ... +% % % ((Kx(the_matrix_cell)*dzv(the_matrix_cell)*dyv(the_matrix_cell)/(dxv(the_matrix_cell)/3))^(-1)+(Kx(the_matrix_cell+1)*dzv(the_matrix_cell+1)*dyv(the_matrix_cell+1)/(dxv(the_matrix_cell+1)/2))^(-1))^(-1); +% % % end + +% % % if N(j,2) == the_matrix_cell-nx +% % % N(j,1) = the_new_cell; T(j) = ... +% % % ((Ky(the_matrix_cell)*dzv(the_matrix_cell)*dxv(the_matrix_cell)/(dyv(the_matrix_cell)/3))^(-1)+(Ky(the_matrix_cell-n)*dzv(the_matrix_cell-n)*dxv(the_matrix_cell-n)/(dxv(the_matrix_cell-n)/2))^(-1))^(-1); +% % % end + +% % % if N(j,1) == the_matrix_cell+1 +% % % N(j,2) = the_new_cell; T(j) = ... +% % % ((Kx(the_matrix_cell)*dzv(the_matrix_cell)*dyv(the_matrix_cell)/(dxv(the_matrix_cell)/3))^(-1)+(Kx(the_matrix_cell+1)*dzv(the_matrix_cell+1)*dyv(the_matrix_cell+1)/(dxv(the_matrix_cell+1)/2))^(-1))^(-1); +% % % end + +% % % if N(j,1) == the_matrix_cell-nx +% % % N(j,2) = the_new_cell; T(j) = ... +% % % ((Ky(the_matrix_cell)*dzv(the_matrix_cell)*dxv(the_matrix_cell)/(dyv(the_matrix_cell)/3))^(-1)+(Ky(the_matrix_cell-n)*dzv(the_matrix_cell-n)*dxv(the_matrix_cell-n)/(dxv(the_matrix_cell-n)/2))^(-1))^(-1); +% % % end + + end +end +deletedFlag = unique(deletedFlag); +N(deletedFlag,:) = []; +T(deletedFlag,:) = []; +% 构建裂缝网格-基质网格-添加基质网格的对应矩阵,按照裂缝网格顺序排列,方便后续处理 +fractureCell_matrixCell_addedMatrixCell = zeros(size(fractureCellFlag,1),3); +for xiang = 1:size(fractureCellFlag,1) + theFractureCell = fractureCellFlag(xiang,1); + aaa = find(fractureMatrixFlag(:,1) == theFractureCell); + theMatrixCell = fractureMatrixFlag(aaa,2); + bbb = find(matrixCellsDivided(:,1) == theMatrixCell); + theAddedMatrixCells = matrixCellsDivided(bbb,2); + fractureCell_matrixCell_addedMatrixCell(theFractureCell,:) = [theFractureCell, theMatrixCell, theAddedMatrixCells]; +end +% 添加这些基质网格的真实连接 +relatedN = []; +relatedT = []; +for xiang = 1:size(fractureCellFlag,1)/numberInGroup + addedNSs =[ + % 左侧原有基质网格 x方向上的连接 + fractureCell_matrixCell_addedMatrixCell(3*xiang-2,2)-1, fractureCell_matrixCell_addedMatrixCell(3*xiang-2,2); + fractureCell_matrixCell_addedMatrixCell(3*xiang-1,2)-1, fractureCell_matrixCell_addedMatrixCell(3*xiang-1,2); + fractureCell_matrixCell_addedMatrixCell(3*xiang-0,2)-1, fractureCell_matrixCell_addedMatrixCell(3*xiang-0,2); + % 右侧添加基质网格 x方向上的连接 + fractureCell_matrixCell_addedMatrixCell(3*xiang-2,3), fractureCell_matrixCell_addedMatrixCell(3*xiang-2,2)+1; + fractureCell_matrixCell_addedMatrixCell(3*xiang-1,3), fractureCell_matrixCell_addedMatrixCell(3*xiang-1,2)+1; + fractureCell_matrixCell_addedMatrixCell(3*xiang-0,3), fractureCell_matrixCell_addedMatrixCell(3*xiang-0,2)+1; + % 左侧原有基质网格 y方向上的连接 + fractureCell_matrixCell_addedMatrixCell(3*xiang-2,2), fractureCell_matrixCell_addedMatrixCell(3*xiang-1,2); + fractureCell_matrixCell_addedMatrixCell(3*xiang-1,2), fractureCell_matrixCell_addedMatrixCell(3*xiang-0,2); + fractureCell_matrixCell_addedMatrixCell(3*xiang-0,2), fractureCell_matrixCell_addedMatrixCell(3*xiang-0,2)+nx; + % 右侧添加基质网格 y方向上的连接 + fractureCell_matrixCell_addedMatrixCell(3*xiang-2,2)-nx, fractureCell_matrixCell_addedMatrixCell(3*xiang-2,3); + fractureCell_matrixCell_addedMatrixCell(3*xiang-2,3), fractureCell_matrixCell_addedMatrixCell(3*xiang-1,3); + fractureCell_matrixCell_addedMatrixCell(3*xiang-1,3), fractureCell_matrixCell_addedMatrixCell(3*xiang-0,3); + ]; + relatedN = [relatedN; + addedNSs + ]; + % 计算传导率 + addedTs = []; + for dai = 1:size(addedNSs,1) + the_matrix_cell1 = addedNSs(dai,1); the_matrix_cell2 = addedNSs(dai,2); + if the_matrix_cell1> nmc + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,3) == the_matrix_cell1); + the_matrix_cell1 = fractureCell_matrixCell_addedMatrixCell(aaa,2); + end + if the_matrix_cell2> nmc + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,3) == the_matrix_cell2); + the_matrix_cell2 = fractureCell_matrixCell_addedMatrixCell(aaa,2); + end + if dai == 1 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/6))^(-1))^(-1); + end + if dai == 2 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/4))^(-1))^(-1); + end + if dai == 3 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)*5/12))^(-1))^(-1); + end + if dai == 4 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*5/12))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 5 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/4))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 6 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/6))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 7 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 8 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 9 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 10 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 11 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 12 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*5/12))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/4))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/6))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + + addedTs = [addedTs; theT]; + end + relatedT = [relatedT;addedTs]; +end +N = [N; relatedN]; +T = [T; relatedT]; + +% +Ninterflow(:,2) = Ninterflow(:,2)+ number_of_adding; +ori_nmc = nmc; +nmc = ori_nmc +number_of_adding; +% m-f连接 +% number_of_adding = 0; +for i = 1:size(matrix_cells_containing_fracture_cells,1) + the_matrix_cell = matrix_cells_containing_fracture_cells(i,1); + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,2) == the_matrix_cell); + the_new_cell = fractureCell_matrixCell_addedMatrixCell(aaa,3); + the_fracture_cell_flag = fractureCell_matrixCell_addedMatrixCell(aaa,1); +% number_of_adding = number_of_adding+1; +% the_new_cell = number_of_adding+ori_nmc; +for j = 1:size(Ninterflow,1) + if Ninterflow(j,1) == the_matrix_cell + the_added_mf_connec = [the_added_mf_connec;the_new_cell,Ninterflow(j,2)]; + if mod(the_fracture_cell_flag, numberInGroup) == 1 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2*((1/4)/((1+2/3)/2))]; + Tinterflow(j) = Tinterflow(j)/2*((1/4)/((0+1/3)/2)); + end + if mod(the_fracture_cell_flag, numberInGroup) == 2 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2]; + Tinterflow(j) = Tinterflow(j)/2; + end + if mod(the_fracture_cell_flag, numberInGroup) == 0 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2*((1/4)/((0+1/3)/2))]; + Tinterflow(j) = Tinterflow(j)/2*((1/4)/((1+2/3)/2)); + end + end +end +end +Ninterflow = [Ninterflow; the_added_mf_connec]; +Tinterflow = [Tinterflow; the_added_mf_T]; +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +% syms x y z; +% Ninterflow=[]; +% Tinterflow=[]; +% for i=1:nx*ny*nz %基质网格编号 +% for j=1:10 +% if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell +% Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3); +% K1=Kf(matrixvsfra(i,j));d1=Wf(matrixvsfra(i,j)); +% K2=kffl(matrixvsfra(i,j));d2=dffl(matrixvsfra(i,j)); +% Annc=2*areavsfra(matrixvsfra(i,j)); +% fracore=corevsfra(matrixvsfra(i,j),:); +% matnodes=nodes(i,:); +% verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); +% matcore=mean(verco);d0=matcore-fracore; +% dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% % dn=abs(dn);%影响数值积分效率 +% dn=sqrt(dn^2); +% dn=matlabFunction(dn); +% if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 +% Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(2)~=0 +% Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(3)~=0 +% Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 && norvec(3)~=0 +% Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 +% Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 +% Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(3)~=0 +% Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% end +% end +% end +% end +% end +% end +% end +% raoT=((Kcell*Annc/(Dn-d2))^(-1)+(K2*Annc/d2)^(-1)+(K1*Annc/d1)^(-1))^(-1); +% Tinterflow=[Tinterflow;raoT]; +% end +% end +% end + +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;]; +T = [T; Tmff; Tff;Tinterflow;]; +T_convection = [T_convection;Tmff_convection; Tff_convection;Tinterflow_convection;]; +nex=size(N,1); +end diff --git a/generic extended/connections_unstructured_EDFM_EX2_1to2_solutions.m b/generic extended/connections_unstructured_EDFM_EX2_1to2_solutions.m new file mode 100644 index 0000000..ac698f7 --- /dev/null +++ b/generic extended/connections_unstructured_EDFM_EX2_1to2_solutions.m @@ -0,0 +1,638 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio, fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to2_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag ) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf +rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; +for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 +% m=floor((i+(2^nf)-1)/(2^nf)); + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); +% indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end +end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +mat_frac=[]; +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 +% if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + mat_frac=[mat_frac;i]; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; +end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +% Kffl=funtion_data.Kffl; +% Dffl=funtion_data.Dffl; +% kffl=zeros(q-1,1); +% dffl=zeros(q-1,1); +fractureCellFlag = (1:q-1)'; +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,10);%裂缝网格渗透率 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +ave_disvsfra=zeros(q-1,1); +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 +for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if kf(i)==0 hartran=0;hartran_convection=0; + else + tran1=kf(i)*wf(i)*lengthcat/disk; + tran2=kf(i)*wf(i)*lengthcat/disj; +% hartran=length/(disk+disj);%取调和平均 + hartran=tran1*tran2/(tran1+tran2); + k_harmony= kf(i); + hartran_convection=kf(i)/(disk+disj)^2; + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + Tff_convection=[Tff_convection;hartran_convection]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +Tff_convection(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +Tmff_convection=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 +% lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 Tmff=[Tmff; 0];Tmff_convection=[Tmff_convection;0]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +Tmff_convection(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +T_convection = zeros(nmm, 1); +c = 0; +for k= 1 : nz +for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + T_convection(c) = 2/(1/Kx(index)+1/Kx(indexn))/(dxv(indexn)+dxv(index)); + end +end +end + +for k= 1 : nz +for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + T_convection(c) = 2/(1/Ky(index)+1/Ky(indexn))/(dyv(indexn)+dyv(index)); + end +end +end + +for i = 1 : nx +for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + T_convection(c) = 2/(1/Kz(index)+1/Kz(indexn))/(dzv(indexn)+dzv(index)); + end +end +end +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +Tinterflow_convection=[]; +matrix_cells_containing_fracture_cells = []; +volume_ratio = []; +fractureMatrixFlag = zeros(size(fractureCellFlag,1),2); +%% -------------------------------------------------------------------------此处是修改之重--------------------------------------------------------------- +numberInGroup = 2; +%% -------------------------------------------------------------------------上方修改结束--------------------------------------------------------------- +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + fractureMatrixFlag(matrixvsfra(i,j),:) = [matrixvsfra(i,j),i]; + matrix_cells_containing_fracture_cells = [matrix_cells_containing_fracture_cells; i]; +%% -------------------------------------------------------------------------此处是修改之重--------------------------------------------------------------- + if mod(matrixvsfra(i,j),numberInGroup) == 1 volume_ratio = [volume_ratio; 3/4];end % 右侧重新编号网格所占体积比例 +% if mod(matrixvsfra(i,j),numberInGroup) == 2 volume_ratio = [volume_ratio; 1/2];end + if mod(matrixvsfra(i,j),numberInGroup) == 0 volume_ratio = [volume_ratio; 1/4];end +%% -------------------------------------------------------------------------上方修改结束--------------------------------------------------------------- + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=2*areavsfra(matrixvsfra(i,j)); + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + raoT=Knnc*Annc/Dn; + raoT_convection=2*Knnc/Dn^2; + Tinterflow=[Tinterflow;raoT]; + Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + end + end +end +%% 额外处理,此处并未通用化,有待进一步开展 +nfc=size(fracnumber,1); +the_added_matrix_cells = []; +nmc=nx * ny*nz; +the_added_mf_connec = []; +the_added_mf_T = []; +number_of_adding = 0; +cell_divided_by_fracture_flag = matrix_cells_containing_fracture_cells; +% 记录基质网格被分成了哪两个网格,并删除原有的与这些基质网格相关的连接 +matrixCellsDivided = zeros(size(matrix_cells_containing_fracture_cells,1),2); +deletedFlag = []; +for i = 1:size(matrix_cells_containing_fracture_cells,1) + the_matrix_cell = matrix_cells_containing_fracture_cells(i,1); + number_of_adding = number_of_adding+1; + the_new_cell = number_of_adding+nmc; + the_added_matrix_cells = [the_added_matrix_cells; the_new_cell]; + matrixCellsDivided(i,:) = [the_matrix_cell, the_new_cell]; + % m-m连接 + for j = 1:size(N,1) + if N(j,1) == the_matrix_cell || N(j,2) == the_matrix_cell + deletedFlag = [deletedFlag; j]; + end +% % % if N(j,2) == the_matrix_cell+1 +% % % N(j,1) = the_new_cell; T(j) = ... +% % % ((Kx(the_matrix_cell)*dzv(the_matrix_cell)*dyv(the_matrix_cell)/(dxv(the_matrix_cell)/3))^(-1)+(Kx(the_matrix_cell+1)*dzv(the_matrix_cell+1)*dyv(the_matrix_cell+1)/(dxv(the_matrix_cell+1)/2))^(-1))^(-1); +% % % end + +% % % if N(j,2) == the_matrix_cell-nx +% % % N(j,1) = the_new_cell; T(j) = ... +% % % ((Ky(the_matrix_cell)*dzv(the_matrix_cell)*dxv(the_matrix_cell)/(dyv(the_matrix_cell)/3))^(-1)+(Ky(the_matrix_cell-n)*dzv(the_matrix_cell-n)*dxv(the_matrix_cell-n)/(dxv(the_matrix_cell-n)/2))^(-1))^(-1); +% % % end + +% % % if N(j,1) == the_matrix_cell+1 +% % % N(j,2) = the_new_cell; T(j) = ... +% % % ((Kx(the_matrix_cell)*dzv(the_matrix_cell)*dyv(the_matrix_cell)/(dxv(the_matrix_cell)/3))^(-1)+(Kx(the_matrix_cell+1)*dzv(the_matrix_cell+1)*dyv(the_matrix_cell+1)/(dxv(the_matrix_cell+1)/2))^(-1))^(-1); +% % % end + +% % % if N(j,1) == the_matrix_cell-nx +% % % N(j,2) = the_new_cell; T(j) = ... +% % % ((Ky(the_matrix_cell)*dzv(the_matrix_cell)*dxv(the_matrix_cell)/(dyv(the_matrix_cell)/3))^(-1)+(Ky(the_matrix_cell-n)*dzv(the_matrix_cell-n)*dxv(the_matrix_cell-n)/(dxv(the_matrix_cell-n)/2))^(-1))^(-1); +% % % end + + end +end +deletedFlag = unique(deletedFlag); +N(deletedFlag,:) = []; +T(deletedFlag,:) = []; +% 构建裂缝网格-基质网格-添加基质网格的对应矩阵,按照裂缝网格顺序排列,方便后续处理 +fractureCell_matrixCell_addedMatrixCell = zeros(size(fractureCellFlag,1),3); +for xiang = 1:size(fractureCellFlag,1) + theFractureCell = fractureCellFlag(xiang,1); + aaa = find(fractureMatrixFlag(:,1) == theFractureCell); + theMatrixCell = fractureMatrixFlag(aaa,2); + bbb = find(matrixCellsDivided(:,1) == theMatrixCell); + theAddedMatrixCells = matrixCellsDivided(bbb,2); + fractureCell_matrixCell_addedMatrixCell(theFractureCell,:) = [theFractureCell, theMatrixCell, theAddedMatrixCells]; +end +% 添加这些基质网格的真实连接 +relatedN = []; +relatedT = []; +for xiang = 1:size(fractureCellFlag,1)/numberInGroup +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + addedNSs =[ + % 左侧原有基质网格 x方向上的连接 +% fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2)-1, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2)-1, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2)-1, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2); + % 右侧添加基质网格 x方向上的连接 +% fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2)+1; + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2)+1; + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2)+1; + % 左侧原有基质网格 y方向上的连接 +% fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2)+nx; + % 右侧添加基质网格 y方向上的连接 + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2)-nx, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,3); +% fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,3); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,3); + ]; +%% --------------------------------------------------------------此处修改结束----------------------------------------------------------------- + relatedN = [relatedN; + addedNSs + ]; + % 计算传导率 + addedTs = []; + for dai = 1:size(addedNSs,1) + the_matrix_cell1 = addedNSs(dai,1); the_matrix_cell2 = addedNSs(dai,2); + if the_matrix_cell1> nmc + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,3) == the_matrix_cell1); + the_matrix_cell1 = fractureCell_matrixCell_addedMatrixCell(aaa,2); + end + if the_matrix_cell2> nmc + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,3) == the_matrix_cell2); + the_matrix_cell2 = fractureCell_matrixCell_addedMatrixCell(aaa,2); + end +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- +% if dai == 1 +% theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/6))^(-1))^(-1); +% end + if dai == 1 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)*1/8))^(-1))^(-1); + end + if dai == 2 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)*3/8))^(-1))^(-1); + end +% if dai == 4 +% theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*5/12))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% end + if dai == 3 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*3/8))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 4 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/8))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end +% if dai == 7 +% theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% end + if dai == 5 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/2/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/2/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 6 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/2/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/2/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 7 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/2/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/2/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end +% if dai == 11 +% theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% end + if dai == 8 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/2/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/2/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end +%% -------------------------------------------------------------------------此处修改结束----------------------------------------------------------------------- +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*5/12))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/4))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/6))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + + addedTs = [addedTs; theT]; + end + relatedT = [relatedT;addedTs]; +end +N = [N; relatedN]; +T = [T; relatedT]; +% +Ninterflow(:,2) = Ninterflow(:,2)+ number_of_adding; +ori_nmc = nmc; +nmc = ori_nmc +number_of_adding; +% m-f连接 +% number_of_adding = 0; +for i = 1:size(matrix_cells_containing_fracture_cells,1) + the_matrix_cell = matrix_cells_containing_fracture_cells(i,1); + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,2) == the_matrix_cell); + the_new_cell = fractureCell_matrixCell_addedMatrixCell(aaa,3); + the_fracture_cell_flag = fractureCell_matrixCell_addedMatrixCell(aaa,1); +% number_of_adding = number_of_adding+1; +% the_new_cell = number_of_adding+ori_nmc; +for j = 1:size(Ninterflow,1) + if Ninterflow(j,1) == the_matrix_cell + the_added_mf_connec = [the_added_mf_connec;the_new_cell,Ninterflow(j,2)]; +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + if mod(the_fracture_cell_flag, numberInGroup) == 1 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2*((1/4)/((1+1/2)/4))]; + Tinterflow(j) = Tinterflow(j)/2*((1/4)/((2-1-1/2)/4)); + end +% % % if mod(the_fracture_cell_flag, numberInGroup) == 2 +% % % the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2]; +% % % Tinterflow(j) = Tinterflow(j)/2; +% % % end + if mod(the_fracture_cell_flag, numberInGroup) == 0 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2*((1/4)/((1/2+0)/4))]; + Tinterflow(j) = Tinterflow(j)/2*((1/4)/((1/2+0)/4)); + end +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + end +end +end +Ninterflow = [Ninterflow; the_added_mf_connec]; +Tinterflow = [Tinterflow; the_added_mf_T]; +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +% syms x y z; +% Ninterflow=[]; +% Tinterflow=[]; +% for i=1:nx*ny*nz %基质网格编号 +% for j=1:10 +% if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell +% Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3); +% K1=Kf(matrixvsfra(i,j));d1=Wf(matrixvsfra(i,j)); +% K2=kffl(matrixvsfra(i,j));d2=dffl(matrixvsfra(i,j)); +% Annc=2*areavsfra(matrixvsfra(i,j)); +% fracore=corevsfra(matrixvsfra(i,j),:); +% matnodes=nodes(i,:); +% verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); +% matcore=mean(verco);d0=matcore-fracore; +% dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% % dn=abs(dn);%影响数值积分效率 +% dn=sqrt(dn^2); +% dn=matlabFunction(dn); +% if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 +% Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(2)~=0 +% Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(3)~=0 +% Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 && norvec(3)~=0 +% Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 +% Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 +% Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(3)~=0 +% Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% end +% end +% end +% end +% end +% end +% end +% raoT=((Kcell*Annc/(Dn-d2))^(-1)+(K2*Annc/d2)^(-1)+(K1*Annc/d1)^(-1))^(-1); +% Tinterflow=[Tinterflow;raoT]; +% end +% end +% end + +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;]; +T = [T; Tmff; Tff;Tinterflow;]; +T_convection = [T_convection;Tmff_convection; Tff_convection;Tinterflow_convection;]; +nex=size(N,1); +end diff --git a/generic extended/connections_unstructured_EDFM_EX2_1to3_solutions.m b/generic extended/connections_unstructured_EDFM_EX2_1to3_solutions.m new file mode 100644 index 0000000..164d7b9 --- /dev/null +++ b/generic extended/connections_unstructured_EDFM_EX2_1to3_solutions.m @@ -0,0 +1,638 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio, fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to3_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag ) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf +rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; +for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 +% m=floor((i+(2^nf)-1)/(2^nf)); + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); +% indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end +end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +mat_frac=[]; +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 +% if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + mat_frac=[mat_frac;i]; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; +end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +% Kffl=funtion_data.Kffl; +% Dffl=funtion_data.Dffl; +% kffl=zeros(q-1,1); +% dffl=zeros(q-1,1); +fractureCellFlag = (1:q-1)'; +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,10);%裂缝网格渗透率 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +ave_disvsfra=zeros(q-1,1); +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 +for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if kf(i)==0 hartran=0;hartran_convection=0; + else + tran1=kf(i)*wf(i)*lengthcat/disk; + tran2=kf(i)*wf(i)*lengthcat/disj; +% hartran=length/(disk+disj);%取调和平均 + hartran=tran1*tran2/(tran1+tran2); + k_harmony= kf(i); + hartran_convection=kf(i)/(disk+disj)^2; + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + Tff_convection=[Tff_convection;hartran_convection]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +Tff_convection(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +Tmff_convection=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 +% lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 Tmff=[Tmff; 0];Tmff_convection=[Tmff_convection;0]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +Tmff_convection(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +T_convection = zeros(nmm, 1); +c = 0; +for k= 1 : nz +for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + T_convection(c) = 2/(1/Kx(index)+1/Kx(indexn))/(dxv(indexn)+dxv(index)); + end +end +end + +for k= 1 : nz +for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + T_convection(c) = 2/(1/Ky(index)+1/Ky(indexn))/(dyv(indexn)+dyv(index)); + end +end +end + +for i = 1 : nx +for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + T_convection(c) = 2/(1/Kz(index)+1/Kz(indexn))/(dzv(indexn)+dzv(index)); + end +end +end +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +Tinterflow_convection=[]; +matrix_cells_containing_fracture_cells = []; +volume_ratio = []; +fractureMatrixFlag = zeros(size(fractureCellFlag,1),2); +%% -------------------------------------------------------------------------此处是修改之重--------------------------------------------------------------- +numberInGroup = 3; +%% -------------------------------------------------------------------------上方修改结束--------------------------------------------------------------- +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + fractureMatrixFlag(matrixvsfra(i,j),:) = [matrixvsfra(i,j),i]; + matrix_cells_containing_fracture_cells = [matrix_cells_containing_fracture_cells; i]; +%% -------------------------------------------------------------------------此处是修改之重--------------------------------------------------------------- + if mod(matrixvsfra(i,j),numberInGroup) == 1 volume_ratio = [volume_ratio; 5/6];end % 右侧重新编号网格所占体积比例 + if mod(matrixvsfra(i,j),numberInGroup) == 2 volume_ratio = [volume_ratio; 1/2];end + if mod(matrixvsfra(i,j),numberInGroup) == 0 volume_ratio = [volume_ratio; 1/6];end +%% -------------------------------------------------------------------------上方修改结束--------------------------------------------------------------- + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=2*areavsfra(matrixvsfra(i,j)); + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + raoT=Knnc*Annc/Dn; + raoT_convection=2*Knnc/Dn^2; + Tinterflow=[Tinterflow;raoT]; + Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + end + end +end +%% 额外处理,此处并未通用化,有待进一步开展 +nfc=size(fracnumber,1); +the_added_matrix_cells = []; +nmc=nx * ny*nz; +the_added_mf_connec = []; +the_added_mf_T = []; +number_of_adding = 0; +cell_divided_by_fracture_flag = matrix_cells_containing_fracture_cells; +% 记录基质网格被分成了哪两个网格,并删除原有的与这些基质网格相关的连接 +matrixCellsDivided = zeros(size(matrix_cells_containing_fracture_cells,1),2); +deletedFlag = []; +for i = 1:size(matrix_cells_containing_fracture_cells,1) + the_matrix_cell = matrix_cells_containing_fracture_cells(i,1); + number_of_adding = number_of_adding+1; + the_new_cell = number_of_adding+nmc; + the_added_matrix_cells = [the_added_matrix_cells; the_new_cell]; + matrixCellsDivided(i,:) = [the_matrix_cell, the_new_cell]; + % m-m连接 + for j = 1:size(N,1) + if N(j,1) == the_matrix_cell || N(j,2) == the_matrix_cell + deletedFlag = [deletedFlag; j]; + end +% % % if N(j,2) == the_matrix_cell+1 +% % % N(j,1) = the_new_cell; T(j) = ... +% % % ((Kx(the_matrix_cell)*dzv(the_matrix_cell)*dyv(the_matrix_cell)/(dxv(the_matrix_cell)/3))^(-1)+(Kx(the_matrix_cell+1)*dzv(the_matrix_cell+1)*dyv(the_matrix_cell+1)/(dxv(the_matrix_cell+1)/2))^(-1))^(-1); +% % % end + +% % % if N(j,2) == the_matrix_cell-nx +% % % N(j,1) = the_new_cell; T(j) = ... +% % % ((Ky(the_matrix_cell)*dzv(the_matrix_cell)*dxv(the_matrix_cell)/(dyv(the_matrix_cell)/3))^(-1)+(Ky(the_matrix_cell-n)*dzv(the_matrix_cell-n)*dxv(the_matrix_cell-n)/(dxv(the_matrix_cell-n)/2))^(-1))^(-1); +% % % end + +% % % if N(j,1) == the_matrix_cell+1 +% % % N(j,2) = the_new_cell; T(j) = ... +% % % ((Kx(the_matrix_cell)*dzv(the_matrix_cell)*dyv(the_matrix_cell)/(dxv(the_matrix_cell)/3))^(-1)+(Kx(the_matrix_cell+1)*dzv(the_matrix_cell+1)*dyv(the_matrix_cell+1)/(dxv(the_matrix_cell+1)/2))^(-1))^(-1); +% % % end + +% % % if N(j,1) == the_matrix_cell-nx +% % % N(j,2) = the_new_cell; T(j) = ... +% % % ((Ky(the_matrix_cell)*dzv(the_matrix_cell)*dxv(the_matrix_cell)/(dyv(the_matrix_cell)/3))^(-1)+(Ky(the_matrix_cell-n)*dzv(the_matrix_cell-n)*dxv(the_matrix_cell-n)/(dxv(the_matrix_cell-n)/2))^(-1))^(-1); +% % % end + + end +end +deletedFlag = unique(deletedFlag); +N(deletedFlag,:) = []; +T(deletedFlag,:) = []; +% 构建裂缝网格-基质网格-添加基质网格的对应矩阵,按照裂缝网格顺序排列,方便后续处理 +fractureCell_matrixCell_addedMatrixCell = zeros(size(fractureCellFlag,1),3); +for xiang = 1:size(fractureCellFlag,1) + theFractureCell = fractureCellFlag(xiang,1); + aaa = find(fractureMatrixFlag(:,1) == theFractureCell); + theMatrixCell = fractureMatrixFlag(aaa,2); + bbb = find(matrixCellsDivided(:,1) == theMatrixCell); + theAddedMatrixCells = matrixCellsDivided(bbb,2); + fractureCell_matrixCell_addedMatrixCell(theFractureCell,:) = [theFractureCell, theMatrixCell, theAddedMatrixCells]; +end +% 添加这些基质网格的真实连接 +relatedN = []; +relatedT = []; +for xiang = 1:size(fractureCellFlag,1)/numberInGroup +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + addedNSs =[ + % 左侧原有基质网格 x方向上的连接 + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2)-1, fractureCell_matrixCell_addedMatrixCell(3*xiang-2,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2)-1, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2)-1, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2); + % 右侧添加基质网格 x方向上的连接 + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2)+1; + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2)+1; + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2)+1; + % 左侧原有基质网格 y方向上的连接 + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2)+nx; + % 右侧添加基质网格 y方向上的连接 + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2)-nx, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,3); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,3); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,3); + ]; +%% --------------------------------------------------------------此处修改结束----------------------------------------------------------------- + relatedN = [relatedN; + addedNSs + ]; + % 计算传导率 + addedTs = []; + for dai = 1:size(addedNSs,1) + the_matrix_cell1 = addedNSs(dai,1); the_matrix_cell2 = addedNSs(dai,2); + if the_matrix_cell1> nmc + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,3) == the_matrix_cell1); + the_matrix_cell1 = fractureCell_matrixCell_addedMatrixCell(aaa,2); + end + if the_matrix_cell2> nmc + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,3) == the_matrix_cell2); + the_matrix_cell2 = fractureCell_matrixCell_addedMatrixCell(aaa,2); + end +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + if dai == 1 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/12))^(-1))^(-1); + end + if dai == 2 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/4))^(-1))^(-1); + end + if dai == 3 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)*5/12))^(-1))^(-1); + end + if dai == 4 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*5/12))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 5 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/4))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 6 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/12))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 7 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 8 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 9 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 10 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 11 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 12 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end +%% -------------------------------------------------------------------------此处修改结束----------------------------------------------------------------------- +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*5/12))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/4))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/6))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + + addedTs = [addedTs; theT]; + end + relatedT = [relatedT;addedTs]; +end +N = [N; relatedN]; +T = [T; relatedT]; +% +Ninterflow(:,2) = Ninterflow(:,2)+ number_of_adding; +ori_nmc = nmc; +nmc = ori_nmc +number_of_adding; +% m-f连接 +% number_of_adding = 0; +for i = 1:size(matrix_cells_containing_fracture_cells,1) + the_matrix_cell = matrix_cells_containing_fracture_cells(i,1); + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,2) == the_matrix_cell); + the_new_cell = fractureCell_matrixCell_addedMatrixCell(aaa,3); + the_fracture_cell_flag = fractureCell_matrixCell_addedMatrixCell(aaa,1); +% number_of_adding = number_of_adding+1; +% the_new_cell = number_of_adding+ori_nmc; +for j = 1:size(Ninterflow,1) + if Ninterflow(j,1) == the_matrix_cell + the_added_mf_connec = [the_added_mf_connec;the_new_cell,Ninterflow(j,2)]; +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + if mod(the_fracture_cell_flag, numberInGroup) == 1 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2*((1/4)/((1+2/3)/2))]; + Tinterflow(j) = Tinterflow(j)/2*((1/4)/((0+1/3)/2)); + end + if mod(the_fracture_cell_flag, numberInGroup) == 2 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2]; + Tinterflow(j) = Tinterflow(j)/2; + end + if mod(the_fracture_cell_flag, numberInGroup) == 0 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2*((1/4)/((0+1/3)/2))]; + Tinterflow(j) = Tinterflow(j)/2*((1/4)/((1+2/3)/2)); + end +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + end +end +end +Ninterflow = [Ninterflow; the_added_mf_connec]; +Tinterflow = [Tinterflow; the_added_mf_T]; +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +% syms x y z; +% Ninterflow=[]; +% Tinterflow=[]; +% for i=1:nx*ny*nz %基质网格编号 +% for j=1:10 +% if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell +% Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3); +% K1=Kf(matrixvsfra(i,j));d1=Wf(matrixvsfra(i,j)); +% K2=kffl(matrixvsfra(i,j));d2=dffl(matrixvsfra(i,j)); +% Annc=2*areavsfra(matrixvsfra(i,j)); +% fracore=corevsfra(matrixvsfra(i,j),:); +% matnodes=nodes(i,:); +% verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); +% matcore=mean(verco);d0=matcore-fracore; +% dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% % dn=abs(dn);%影响数值积分效率 +% dn=sqrt(dn^2); +% dn=matlabFunction(dn); +% if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 +% Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(2)~=0 +% Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(3)~=0 +% Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 && norvec(3)~=0 +% Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 +% Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 +% Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(3)~=0 +% Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% end +% end +% end +% end +% end +% end +% end +% raoT=((Kcell*Annc/(Dn-d2))^(-1)+(K2*Annc/d2)^(-1)+(K1*Annc/d1)^(-1))^(-1); +% Tinterflow=[Tinterflow;raoT]; +% end +% end +% end + +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;]; +T = [T; Tmff; Tff;Tinterflow;]; +T_convection = [T_convection;Tmff_convection; Tff_convection;Tinterflow_convection;]; +nex=size(N,1); +end diff --git a/generic extended/connections_unstructured_EDFM_EX2_1to4_solutions.m b/generic extended/connections_unstructured_EDFM_EX2_1to4_solutions.m new file mode 100644 index 0000000..0c5beb4 --- /dev/null +++ b/generic extended/connections_unstructured_EDFM_EX2_1to4_solutions.m @@ -0,0 +1,663 @@ +function [ matrixvsfra,connectmf,fracnumber,fracstart,corevsfra,connect_infrac,N,T,zf,fcinff,vf,porf,fcff,T_convection,mat_frac,number_of_adding,cell_divided_by_fracture_flag,volume_ratio, fractureCell_matrixCell_addedMatrixCell] = connections_unstructured_EDFM_EX2_1to4_solutions( fracturemesh,pointvsregion,raopoint,f,nf,nx,ny,nz,kx,ky,kz,kf,wf,Porf,dxv,dyv,dzv,coord,nodes,NTG,addflag ) +% 该函数用以给裂缝面网格编号,并存储网格间的连接关系及传导率,是前处理的关键步骤 +% 不同于二维嵌入式离散裂缝模型,三维模型中,裂缝是二维平面,网格之间连接关系复杂, +%不能简单得从基质网格来判定,若所处基质网格不相邻,则裂缝网格必不相邻,若所处基质网格相邻,裂缝网格却不一定相邻 +%上述原则无助于我们去确定connections,故拟采取以下方案: +%第一步:按照xink矩阵去掉零行后,按照行数依次给某裂缝面网格编号,同时存储裂缝网格所在的基质网格序号 +%第二步:存储每个裂缝网格的面积,边界,边界长度,中心点坐标,中心点到各边界的距离,为后续操作做准备 +%第三步:按照裂缝网格序号顺序,按照边界进行搜索,如果有相同的边界,则两个裂缝网格是相邻的 +%matrixvsfra矩阵代表基质网格中包含裂缝网格编号的情况 +%fracnumber矩阵,行序号表示该裂缝网格编号,行内容表示该网格包含的点序号 +%areavsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的面积 +%每相邻两列是一条边,然后将顺序反过来,又是两列一条边 +%lengthvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的各边长度 +%corevsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心坐标 +%disvsfra矩阵,行序号表示该裂缝网格编号,行内容表示该裂缝网格的重心到各边的距离 +matrixvsfra=zeros(nx*ny*nz,10);%为了减少该矩阵的大小,考虑实际情况,一个基质网格中,一般不会有超过10个裂缝网格 +fracnumber=zeros(1000,20);%根据实际情况,裂缝网格一般不会超过1000个,也可根据实际情况改变 +%m=size(xink,1); +rownum=zeros(nf,1); +for i=1:nf +rownum(i)=size(fracturemesh{i,1},1); +end +%% 将所有裂缝面网格连起来一起编号,并将编号扔给相应的基质网格 +q=1; +fracstart=zeros(nf+1,1);%这个表示在总编号中,每条裂缝起始的号码 +for j=1:nf + fracstart(j)=q; + numofmesh=pointvsregion{j,1}; +for i=1:1:rownum(j) + if(norm(fracturemesh{j,1}(i,:))~=0) + raoindice=size(fracturemesh{j,1}(i,:),2); + fracnumber(q,1:raoindice)=fracturemesh{j,1}(i,:);%q即是该裂缝编号 +% m=floor((i+(2^nf)-1)/(2^nf)); + m=floor((i+(2^addflag(j)-1))/(2^addflag(j))); + indice=find(matrixvsfra(numofmesh(m),:)~=0); +% indice=find(matrixvsfra(numofmesh(i),:)~=0); + if (size(indice,2)==0) xiang=1; + else + rao=max(indice'); + xiang=rao(1)+1; + end + matrixvsfra(numofmesh(m),xiang)=q;%将裂缝编号附给相应的基质网格 + q=q+1; + end +end +end +fracstart(nf+1)=q;%裂缝网格总数量+1 +fracnumber(q:1000,:)=[]; + + +%% 将包含有裂缝单元的基质网格筛选出来,并进行处理 +m=size(matrixvsfra,1); +mat_frac=[]; +connectmf=cell(1,4); +% for i=1:m +% if (norm(matrixvsfra(i,:))~=0) +% ConnecS = cell(1,4); +cc = 0; +cl = 1; +for i = 1 : m + %筛选出包含裂缝的基质网格 +% if ~isempty(matrixvsfra(i,:)) + if (norm(matrixvsfra(i,:)))~=0 + cc = cc + 1; + %存储该基质网格编号 + connectmf{cc,1} = i; + mat_frac=[mat_frac;i]; + %给这些裂缝点/裂缝单元按顺序编号 + A=matrixvsfra(i,:); + A(A==0)=[]; + connectmf{cc,2} =A; +end +end + +%% 一条条裂缝计算裂缝网格面积、边界等等 +% edgevsfra=cell(nf,1); +% Kffl=funtion_data.Kffl; +% Dffl=funtion_data.Dffl; +% kffl=zeros(q-1,1); +% dffl=zeros(q-1,1); +fractureCellFlag = (1:q-1)'; +normalvec=zeros(q-1,3);%unit 法向量 +areavsfra=zeros(q-1,1);%q-1即裂缝网格总数 +lengthvsfra=zeros(q-1,10); +Kf=zeros(q-1,10);%裂缝网格渗透率 +corevsfra=zeros(q-1,3); +disvsfra=zeros(q-1,10); +tran=zeros(q-1,10); +avtran=zeros(q-1,1);%裂缝网格平均传导,用于后续的简化计算 +ave_disvsfra=zeros(q-1,1); +fcinff=zeros(q-1,1);%表示裂缝单元所在的裂缝面序号 +zf=zeros(q-1,1);%裂缝单元高度(以下表面为基准) +vf=zeros(q-1,1);%裂缝单元的体积 +porf=zeros(q-1,1);%裂缝单元的孔隙度 +for i=1:1:q-1 %对裂缝网格进行操作 + if(norm(fracnumber(i,:))==0) break; + else + for k=2:(nf+1) + if(i0 +for i=1:(q-1) + [dogindex,~]=find(deindex==i); + if length(dogindex)~=0 + newnum(i)=0; + else + [catindex,~]=find(deindex2)||((size(raoflag,2)<2))) continue;%因为是凸多边形,因此只要代表裂缝网格的行向量的共有元素有2个,即有公共边; + %如果多于2个,则是相同的裂缝网格,因为如果不是,则必有一个是凹多边形,矛盾,证毕;如果小于两个,则没有共有的边线 + else if (a==b) continue; %说明这两个裂缝单元在同一个基质网格中,因此不应该算在此类中 + else + raoconnect(p,q)=k;q=q+1; + lengthcat=norm(d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:));%计算裂缝单元公共边长度 + rao1k=corevsfra(k,:)-d3intersection(raoflag(1),:); + rao1j=corevsfra(j,:)-d3intersection(raoflag(1),:); + rao2=d3intersection(raoflag(1),:)-d3intersection(raoflag(2),:); + %分别计算两裂缝单元中心到公共边的距离 + disk=norm(cross(rao1k',rao2'))/norm(rao2); + disj=norm(cross(rao1j',rao2'))/norm(rao2); + if kf(i)==0 hartran=0;hartran_convection=0; + else + tran1=kf(i)*wf(i)*lengthcat/disk; + tran2=kf(i)*wf(i)*lengthcat/disj; +% hartran=length/(disk+disj);%取调和平均 + hartran=tran1*tran2/(tran1+tran2); + k_harmony= kf(i); + hartran_convection=kf(i)/(disk+disj)^2; + end + Nff=[Nff; j,k]; + Tff=[Tff;hartran]; + Tff_convection=[Tff_convection;hartran_convection]; + %计算出每个裂缝网格重心到每条边的距离 + end + end + p=p+1; + end + connect_infrac{i,1}=raoconnect; + end +end +Nff(1,:)=[]; %去除第一行的零行 +Tff(1,:)=[]; +Tff_convection(1,:)=[]; +%% 在同一基质网格中的裂缝单元连接情况及传导率计算 +nmc=size(matrixvsfra,1); +Nmff=zeros(1,2); +Tmff=zeros(1,1); +Tmff_convection=zeros(1,1); +for i=1:nmc + if(norm(matrixvsfra(i,:))~=0) + indice=find(matrixvsfra(i,:)~=0); + n=size(indice,2); + if (n>1) %此时表明要采取下述的简化算法 +% lengthvsfra(matrixvsfra(i,indice))./disvsfra(matrixvsfra(i,indice)) + for j=1:n-1 + for k=(j+1):n + Nmff=[Nmff;matrixvsfra(i,indice(j)), matrixvsfra(i,indice(k))]; + % 此时的计算方式是先求每个裂缝网格的算术平均,再算包含在该基质网格中的所有裂缝单元的算术平均 + fc1=matrixvsfra(i,indice(j)); fc2=matrixvsfra(i,indice(k)); + allfc=matrixvsfra(i,1:n); sumtran=sum(fcff{1,7}(allfc)); + if sumtran==0 Tmff=[Tmff; 0];Tmff_convection=[Tmff_convection;0]; + else + Tmff=[Tmff; fcff{1,7}(fc1)*fcff{1,7}(fc2)/sumtran]; + end + end + end + end + end +end +Nmff(1,:)=[]; %去掉开头的零行 +Tmff(1,:)=[]; +Tmff_convection(1,:)=[]; +% N = [N; Nmff+nmc]; +% T = [T; Tmff]; + +%% 基质网格的连接情况及传导系数计算 +nmc=nx * ny*nz;%基质网格数目 +nfc=size(fracnumber,1);%裂缝单元数目 +rpt = [ones(nmc, 1); zeros(nfc, 1)]; +% r.rpt = rpt; +nmm = (nx-1)*ny*nz+(ny-1)*nx*nz+(nz-1)*nx*ny;%nmm是基质网格之间存在流体交换的总数 +% r.nf = nmm + nff;%nff是裂缝单元之间存在流体交换的总数 +Kx=kx.*ones(nmc,1); +Ky=ky.*ones(nmc,1); +Kz=kz.*ones(nmc,1); +N = zeros(nmm, 2);%存储基质网格之间存在流体交换的网格编号 +T = zeros(nmm, 1);%存储对应与N矩阵的传导系数 +T_convection = zeros(nmm, 1); +c = 0; +for k= 1 : nz +for j = 1 : ny + for i = 1 : nx - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + 1; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dyv(index)*Kx(index)*Kx(indexn)*NTG(index)*NTG(indexn)/(Kx(index)*dxv(indexn)*NTG(index) + Kx(indexn)*dxv(index)*NTG(indexn)); + T_convection(c) = 2/(1/Kx(index)+1/Kx(indexn))/(dxv(indexn)+dxv(index)); + end +end +end + +for k= 1 : nz +for i = 1 : nx + for j = 1 : ny - 1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx; + N(c, :) = [index, indexn]; + T(c) = 2 * dzv(index)*dxv(index)*Ky(index)*Ky(indexn)/(Ky(index)*dyv(indexn) + Ky(indexn)*dyv(index)); + T_convection(c) = 2/(1/Ky(index)+1/Ky(indexn))/(dyv(indexn)+dyv(index)); + end +end +end + +for i = 1 : nx +for j = 1 : ny + for k= 1: nz-1 + c = c + 1; + index = i + (j - 1) * nx + (k - 1) * nx * ny; + indexn = index + nx * ny; + N(c, :) = [index, index + nx*ny]; + T(c) = 2 * dxv(index)*dyv(index)*Kz(index)*Kz(indexn)/(Kz(index)*dzv(indexn) + Kz(indexn)*dzv(index)); + T_convection(c) = 2/(1/Kz(index)+1/Kz(indexn))/(dzv(indexn)+dzv(index)); + end +end +end +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +syms x y z; +Ninterflow=[]; +Tinterflow=[]; +Tinterflow_convection=[]; +matrix_cells_containing_fracture_cells = []; +volume_ratio = []; +fractureMatrixFlag = zeros(size(fractureCellFlag,1),2); +%% -------------------------------------------------------------------------此处是修改之重--------------------------------------------------------------- +numberInGroup = 4; +%% -------------------------------------------------------------------------上方修改结束--------------------------------------------------------------- +for i=1:nx*ny*nz %基质网格编号 + for j=1:10 + if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell + fractureMatrixFlag(matrixvsfra(i,j),:) = [matrixvsfra(i,j),i]; + matrix_cells_containing_fracture_cells = [matrix_cells_containing_fracture_cells; i]; +%% -------------------------------------------------------------------------此处是修改之重--------------------------------------------------------------- + if mod(matrixvsfra(i,j),numberInGroup) == 1 volume_ratio = [volume_ratio; 7/8];end % 右侧重新编号网格所占体积比例 + if mod(matrixvsfra(i,j),numberInGroup) == 2 volume_ratio = [volume_ratio; 5/8];end + if mod(matrixvsfra(i,j),numberInGroup) == 3 volume_ratio = [volume_ratio; 3/8];end + if mod(matrixvsfra(i,j),numberInGroup) == 0 volume_ratio = [volume_ratio; 1/8];end +%% -------------------------------------------------------------------------上方修改结束--------------------------------------------------------------- + Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; + kcell=(kx(i)*ky(i)*kz(i))^(1/3); + Knnc=kcell*Kf(matrixvsfra(i,j))/(kcell+Kf(matrixvsfra(i,j))); + Annc=2*areavsfra(matrixvsfra(i,j)); + fracore=corevsfra(matrixvsfra(i,j),:); + matnodes=nodes(i,:); + verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); + matcore=mean(verco);d0=matcore-fracore; + dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% dn=abs(dn);%影响数值积分效率 + dn=sqrt(dn^2); + dn=matlabFunction(dn); + if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 + Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(2)~=0 + Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 && norvec(3)~=0 + Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 && norvec(3)~=0 + Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(1)~=0 + Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(2)~=0 + Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + else if norvec(3)~=0 + Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); + end + end + end + end + end + end + end + raoT=Knnc*Annc/Dn; + raoT_convection=2*Knnc/Dn^2; + Tinterflow=[Tinterflow;raoT]; + Tinterflow_convection=[Tinterflow_convection;raoT_convection]; + end + end +end +%% 额外处理,此处并未通用化,有待进一步开展 +nfc=size(fracnumber,1); +the_added_matrix_cells = []; +nmc=nx * ny*nz; +the_added_mf_connec = []; +the_added_mf_T = []; +number_of_adding = 0; +cell_divided_by_fracture_flag = matrix_cells_containing_fracture_cells; +% 记录基质网格被分成了哪两个网格,并删除原有的与这些基质网格相关的连接 +matrixCellsDivided = zeros(size(matrix_cells_containing_fracture_cells,1),2); +deletedFlag = []; +for i = 1:size(matrix_cells_containing_fracture_cells,1) + the_matrix_cell = matrix_cells_containing_fracture_cells(i,1); + number_of_adding = number_of_adding+1; + the_new_cell = number_of_adding+nmc; + the_added_matrix_cells = [the_added_matrix_cells; the_new_cell]; + matrixCellsDivided(i,:) = [the_matrix_cell, the_new_cell]; + % m-m连接 + for j = 1:size(N,1) + if N(j,1) == the_matrix_cell || N(j,2) == the_matrix_cell + deletedFlag = [deletedFlag; j]; + end +% % % if N(j,2) == the_matrix_cell+1 +% % % N(j,1) = the_new_cell; T(j) = ... +% % % ((Kx(the_matrix_cell)*dzv(the_matrix_cell)*dyv(the_matrix_cell)/(dxv(the_matrix_cell)/3))^(-1)+(Kx(the_matrix_cell+1)*dzv(the_matrix_cell+1)*dyv(the_matrix_cell+1)/(dxv(the_matrix_cell+1)/2))^(-1))^(-1); +% % % end + +% % % if N(j,2) == the_matrix_cell-nx +% % % N(j,1) = the_new_cell; T(j) = ... +% % % ((Ky(the_matrix_cell)*dzv(the_matrix_cell)*dxv(the_matrix_cell)/(dyv(the_matrix_cell)/3))^(-1)+(Ky(the_matrix_cell-n)*dzv(the_matrix_cell-n)*dxv(the_matrix_cell-n)/(dxv(the_matrix_cell-n)/2))^(-1))^(-1); +% % % end + +% % % if N(j,1) == the_matrix_cell+1 +% % % N(j,2) = the_new_cell; T(j) = ... +% % % ((Kx(the_matrix_cell)*dzv(the_matrix_cell)*dyv(the_matrix_cell)/(dxv(the_matrix_cell)/3))^(-1)+(Kx(the_matrix_cell+1)*dzv(the_matrix_cell+1)*dyv(the_matrix_cell+1)/(dxv(the_matrix_cell+1)/2))^(-1))^(-1); +% % % end + +% % % if N(j,1) == the_matrix_cell-nx +% % % N(j,2) = the_new_cell; T(j) = ... +% % % ((Ky(the_matrix_cell)*dzv(the_matrix_cell)*dxv(the_matrix_cell)/(dyv(the_matrix_cell)/3))^(-1)+(Ky(the_matrix_cell-n)*dzv(the_matrix_cell-n)*dxv(the_matrix_cell-n)/(dxv(the_matrix_cell-n)/2))^(-1))^(-1); +% % % end + + end +end +deletedFlag = unique(deletedFlag); +N(deletedFlag,:) = []; +T(deletedFlag,:) = []; +% 构建裂缝网格-基质网格-添加基质网格的对应矩阵,按照裂缝网格顺序排列,方便后续处理 +fractureCell_matrixCell_addedMatrixCell = zeros(size(fractureCellFlag,1),3); +for xiang = 1:size(fractureCellFlag,1) + theFractureCell = fractureCellFlag(xiang,1); + aaa = find(fractureMatrixFlag(:,1) == theFractureCell); + theMatrixCell = fractureMatrixFlag(aaa,2); + bbb = find(matrixCellsDivided(:,1) == theMatrixCell); + theAddedMatrixCells = matrixCellsDivided(bbb,2); + fractureCell_matrixCell_addedMatrixCell(theFractureCell,:) = [theFractureCell, theMatrixCell, theAddedMatrixCells]; +end +% 添加这些基质网格的真实连接 +relatedN = []; +relatedT = []; +for xiang = 1:size(fractureCellFlag,1)/numberInGroup +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + addedNSs =[ + % 左侧原有基质网格 x方向上的连接 + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-3,2)-1, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-3,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2)-1, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2)-1, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2)-1, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2); + % 右侧添加基质网格 x方向上的连接 + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-3,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-3,2)+1; + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2)+1; + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2)+1; + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2)+1; + % 左侧原有基质网格 y方向上的连接 + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-3,2), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,2), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,2), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,2)+nx; + % 右侧添加基质网格 y方向上的连接 + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-3,2)-nx, fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-3,3); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-3,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,3); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-2,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,3); + fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-1,3), fractureCell_matrixCell_addedMatrixCell(numberInGroup*xiang-0,3); + ]; +%% --------------------------------------------------------------此处修改结束----------------------------------------------------------------- + relatedN = [relatedN; + addedNSs + ]; + % 计算传导率 + addedTs = []; + for dai = 1:size(addedNSs,1) + the_matrix_cell1 = addedNSs(dai,1); the_matrix_cell2 = addedNSs(dai,2); + if the_matrix_cell1> nmc + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,3) == the_matrix_cell1); + the_matrix_cell1 = fractureCell_matrixCell_addedMatrixCell(aaa,2); + end + if the_matrix_cell2> nmc + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,3) == the_matrix_cell2); + the_matrix_cell2 = fractureCell_matrixCell_addedMatrixCell(aaa,2); + end +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + % + if dai == 1 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)*1/16))^(-1))^(-1); + end + if dai == 2 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)*3/16))^(-1))^(-1); + end + if dai == 3 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)*5/16))^(-1))^(-1); + end + if dai == 4 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)*7/16))^(-1))^(-1); + end + % + if dai == 5 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*7/16))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 6 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*5/16))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 7 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*3/16))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 8 + theT = ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/16))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); + end + % + if dai == 9 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/4/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/4/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 10 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/4/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/4/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 11 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/4/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/4/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 12 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*4/4/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*4/4/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + % + if dai == 13 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*4/4/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*4/4/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 14 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/4/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/4/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 15 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/4/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/4/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end + if dai == 16 + theT = ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/4/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/4/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + end +%% -------------------------------------------------------------------------此处修改结束----------------------------------------------------------------------- +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*5/12))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/4))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Kx(the_matrix_cell1)*dzv(the_matrix_cell1)*dyv(the_matrix_cell1)/(dxv(the_matrix_cell1)*1/6))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dyv(the_matrix_cell2)/(dxv(the_matrix_cell2)/2))^(-1))^(-1); +% % % +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*3/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*3/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*2/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*2/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); +% % % ((Ky(the_matrix_cell1)*dzv(the_matrix_cell1)*dxv(the_matrix_cell1)*1/3/(dyv(the_matrix_cell1)/2))^(-1)+(Kx(the_matrix_cell2)*dzv(the_matrix_cell2)*dxv(the_matrix_cell2)*1/3/(dyv(the_matrix_cell2)/2))^(-1))^(-1); + + addedTs = [addedTs; theT]; + end + relatedT = [relatedT;addedTs]; +end +N = [N; relatedN]; +T = [T; relatedT]; +% +Ninterflow(:,2) = Ninterflow(:,2)+ number_of_adding; +ori_nmc = nmc; +nmc = ori_nmc +number_of_adding; +% m-f连接 +% number_of_adding = 0; +for i = 1:size(matrix_cells_containing_fracture_cells,1) + the_matrix_cell = matrix_cells_containing_fracture_cells(i,1); + aaa = find(fractureCell_matrixCell_addedMatrixCell(:,2) == the_matrix_cell); + the_new_cell = fractureCell_matrixCell_addedMatrixCell(aaa,3); + the_fracture_cell_flag = fractureCell_matrixCell_addedMatrixCell(aaa,1); +% number_of_adding = number_of_adding+1; +% the_new_cell = number_of_adding+ori_nmc; +for j = 1:size(Ninterflow,1) + if Ninterflow(j,1) == the_matrix_cell + the_added_mf_connec = [the_added_mf_connec;the_new_cell,Ninterflow(j,2)]; +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + if mod(the_fracture_cell_flag, numberInGroup) == 1 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2*((1/4)/((1+3/4)/4))]; + Tinterflow(j) = Tinterflow(j)/2*((1/4)/((2-1-3/4)/4)); + end + if mod(the_fracture_cell_flag, numberInGroup) == 2 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2*((1/4)/((3/4+2/4)/4))]; + Tinterflow(j) = Tinterflow(j)/2*((1/4)/((2-3/4-2/4)/4)); + end + if mod(the_fracture_cell_flag, numberInGroup) == 3 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2*((1/4)/((2/4+1/4)/4))]; + Tinterflow(j) = Tinterflow(j)/2*((1/4)/((2-2/4-1/4)/4)); + end + if mod(the_fracture_cell_flag, numberInGroup) == 0 + the_added_mf_T = [the_added_mf_T; Tinterflow(j)/2*((1/4)/((0+1/4)/4))]; + Tinterflow(j) = Tinterflow(j)/2*((1/4)/((2-0-1/4)/4)); + end +%% -------------------------------------------------------------------------此处亦是修改之重----------------------------------------------------------------------- + end +end +end +Ninterflow = [Ninterflow; the_added_mf_connec]; +Tinterflow = [Tinterflow; the_added_mf_T]; +%% 按照2014年的方法,将窜流处理为与上述相似的形式 +% syms x y z; +% Ninterflow=[]; +% Tinterflow=[]; +% for i=1:nx*ny*nz %基质网格编号 +% for j=1:10 +% if matrixvsfra(i,j)~=0 %this matrix cell contains a fracture cell +% Ninterflow=[Ninterflow;i,matrixvsfra(i,j)+nmc]; +% kcell=(kx(i)*ky(i)*kz(i))^(1/3); +% K1=Kf(matrixvsfra(i,j));d1=Wf(matrixvsfra(i,j)); +% K2=kffl(matrixvsfra(i,j));d2=dffl(matrixvsfra(i,j)); +% Annc=2*areavsfra(matrixvsfra(i,j)); +% fracore=corevsfra(matrixvsfra(i,j),:); +% matnodes=nodes(i,:); +% verco=coord(matnodes,:);norvec=normalvec(matrixvsfra(i,j),:); +% matcore=mean(verco);d0=matcore-fracore; +% dn=(x+d0(1))*norvec(1)+(y+d0(2))*norvec(2)+(z+d0(3))*norvec(3); +% % dn=abs(dn);%影响数值积分效率 +% dn=sqrt(dn^2); +% dn=matlabFunction(dn); +% if norvec(1)~=0 && norvec(2)~=0 && norvec(3)~=0 +% Dn=integral3(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(2)~=0 +% Dn=dzv(i)*NTG(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 && norvec(3)~=0 +% Dn=dyv(i)*integral2(dn,-dxv(i)/2,dxv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 && norvec(3)~=0 +% Dn=dxv(i)*integral2(dn,-dyv(i)/2,dyv(i)/2,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(1)~=0 +% Dn=dyv(i)*dzv(i)*NTG(i)*integral(dn,-dxv(i)/2,dxv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(2)~=0 +% Dn=dxv(i)*dzv(i)*NTG(i)*integral(dn,-dyv(i)/2,dyv(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% else if norvec(3)~=0 +% Dn=dxv(i)*dyv(i)*integral(dn,-dzv(i)*NTG(i)/2,dzv(i)*NTG(i)/2)/(dxv(i)*dyv(i)*dzv(i)*NTG(i)); +% end +% end +% end +% end +% end +% end +% end +% raoT=((Kcell*Annc/(Dn-d2))^(-1)+(K2*Annc/d2)^(-1)+(K1*Annc/d1)^(-1))^(-1); +% Tinterflow=[Tinterflow;raoT]; +% end +% end +% end + +%% 把上述三种情况的矩阵分别叠加起来 +N = [N; Nmff+nmc; Nff+nmc;Ninterflow;]; +T = [T; Tmff; Tff;Tinterflow;]; +T_convection = [T_convection;Tmff_convection; Tff_convection;Tinterflow_convection;]; +nex=size(N,1); +end diff --git a/generic extended/plotDis_3D_to_2D_1to3.m b/generic extended/plotDis_3D_to_2D_1to3.m new file mode 100644 index 0000000..310a4ed --- /dev/null +++ b/generic extended/plotDis_3D_to_2D_1to3.m @@ -0,0 +1,241 @@ +function plotDis_3D_to_2D_1to3(i, r, OutputRs, type) +coordinate=r.coordinates; +nodes=r.nodes; +cell_divided_by_fracture_flag = r.cell_divided_by_fracture_flag; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +if type == 1 + v = OutputRs{i}.p; +else + v = 1-OutputRs{i}.sw;%含油饱和度 +end +number_divided_cells = size(cell_divided_by_fracture_flag,1); +dis = zeros(nel, nmc-number_divided_cells); +x = zeros(nel, nmc-number_divided_cells); +y = zeros(nel, nmc-number_divided_cells); +the_numbering = 0; +for i = 1 :nmc + if ~ismember(i,cell_divided_by_fracture_flag) + the_numbering = the_numbering +1; + for j = 1 :nel + x(j, the_numbering) = coordinate(nodes(i,j), 1); + y(j, the_numbering) = coordinate(nodes(i,j), 2); + if j == 3 + x(j, the_numbering) = coordinate(nodes(i,4), 1); + y(j, the_numbering) = coordinate(nodes(i,4), 2); + end + if j == 4 + x(j, the_numbering) = coordinate(nodes(i,3), 1); + y(j, the_numbering) = coordinate(nodes(i,3), 2); + end + dis(j, the_numbering) = v(i); + end + end +end +% 被裂缝剖分的网格绘图 +nel = 3; +% if type == 1 +% v = OutputRs{i}.p; +% else +% v = 1-OutputRs{i}.sw;%含油饱和度 +% end +fractureCell_matrixCell_addedMatrixCell = r.fractureCell_matrixCell_addedMatrixCell; +volume_ratio = r.volume_ratio; +number_divided_cells = size(cell_divided_by_fracture_flag,1); +% dis_division = zeros(nel, 2*number_divided_cells); +% x_division = zeros(nel, 2*number_divided_cells); +% y_division = zeros(nel, 2*number_divided_cells); +dis_division_type1 = []; +x_division_type1 = []; +y_division_type1 = []; +nel_type1 = 4; + +dis_division_type2 = []; +x_division_type2 = []; +y_division_type2 = []; +nel_type2 = 3; + +the_numbering_division = 0; +for i = 1:nmc + if ismember(i,cell_divided_by_fracture_flag) + aaa = find(cell_divided_by_fracture_flag==i); + theVolumeRatio = volume_ratio(aaa); + theMatrixCell = cell_divided_by_fracture_flag(aaa); + bbb = find(fractureCell_matrixCell_addedMatrixCell(:,2) == theMatrixCell); + theAddedMatrixCell = fractureCell_matrixCell_addedMatrixCell(bbb,3); + if theVolumeRatio == 5/6 +% % % % 右侧四边形, 添加的基质网格 +% % % the_x_division_type1 = [coordinate(nodes(i,1), 1);coordinate(nodes(i,2), 1);coordinate(nodes(i,4), 1);2/3*coordinate(nodes(i,3), 1)+1/3*coordinate(nodes(i,4), 1)]; +% % % x_division_type1 = [x_division_type1, the_x_division_type1]; +% % % +% % % the_y_division_type1 = [coordinate(nodes(i,1), 2);coordinate(nodes(i,2), 2);coordinate(nodes(i,4), 2);2/3*coordinate(nodes(i,3), 2)+1/3*coordinate(nodes(i,4), 2)]; +% % % y_division_type1 = [y_division_type1, the_y_division_type1]; +% % % +% % % the_dis_division_type1 = v(theAddedMatrixCell)*ones(4,1); +% % % dis_division_type1 = [dis_division_type1, the_dis_division_type1]; + + % 左侧三角形, 原始基质网格 + the_x_division_type2 = [2/3*coordinate(nodes(i,3), 1)+1/3*coordinate(nodes(i,4), 1);coordinate(nodes(i,1), 1);coordinate(nodes(i,3), 1);]; + x_division_type2 = [x_division_type2, the_x_division_type2]; + + the_y_division_type2 = [2/3*coordinate(nodes(i,3), 2)+1/3*coordinate(nodes(i,4), 2);coordinate(nodes(i,1), 2);coordinate(nodes(i,3), 2);]; + y_division_type2 = [y_division_type2, the_y_division_type2]; + + the_dis_division_type2 = v(theMatrixCell)*ones(3,1); + dis_division_type2 = [dis_division_type2, the_dis_division_type2]; + end + if theVolumeRatio == 1/2 +% % % % 右侧添加的四边形基质网格 +% % % the_x_division_type1 = [2/3*coordinate(nodes(i,1), 1)+1/3*coordinate(nodes(i,2), 1);coordinate(nodes(i,2), 1);coordinate(nodes(i,4), 1);1/3*coordinate(nodes(i,3), 1)+2/3*coordinate(nodes(i,4), 1)]; +% % % x_division_type1 = [x_division_type1, the_x_division_type1]; +% % % +% % % the_y_division_type1 = [2/3*coordinate(nodes(i,1), 2)+1/3*coordinate(nodes(i,2), 2);coordinate(nodes(i,2), 2);coordinate(nodes(i,4), 2);1/3*coordinate(nodes(i,3), 2)+2/3*coordinate(nodes(i,4), 2)]; +% % % y_division_type1 = [y_division_type1, the_y_division_type1]; +% % % +% % % the_dis_division_type1 = v(theAddedMatrixCell)*ones(4,1); +% % % dis_division_type1 = [dis_division_type1, the_dis_division_type1]; + % 左侧原始的四边形基质网格 + the_x_division_type1 = [2/3*coordinate(nodes(i,1), 1)+1/3*coordinate(nodes(i,2), 1);1/3*coordinate(nodes(i,3), 1)+2/3*coordinate(nodes(i,4), 1); coordinate(nodes(i,3), 1);coordinate(nodes(i,1), 1);]; + x_division_type1 = [x_division_type1, the_x_division_type1]; + + the_y_division_type1 = [2/3*coordinate(nodes(i,1), 2)+1/3*coordinate(nodes(i,2), 2);1/3*coordinate(nodes(i,3), 2)+2/3*coordinate(nodes(i,4), 2); coordinate(nodes(i,3), 2);coordinate(nodes(i,1), 2);]; + y_division_type1 = [y_division_type1, the_y_division_type1]; + + the_dis_division_type1 = v(theMatrixCell)*ones(4,1); + dis_division_type1 = [dis_division_type1, the_dis_division_type1]; + end + if theVolumeRatio == 1/6 + % 四边形, 左侧原始基质网格 + the_x_division_type1 = [coordinate(nodes(i,1), 1);1/3*coordinate(nodes(i,1), 1)+2/3*coordinate(nodes(i,2), 1);coordinate(nodes(i,4), 1);coordinate(nodes(i,3), 1);]; + x_division_type1 = [x_division_type1, the_x_division_type1]; + + the_y_division_type1 = [coordinate(nodes(i,1), 2);1/3*coordinate(nodes(i,1), 2)+2/3*coordinate(nodes(i,2), 2);coordinate(nodes(i,4), 2);coordinate(nodes(i,3), 2);]; + y_division_type1 = [y_division_type1, the_y_division_type1]; + + the_dis_division_type1 = v(theMatrixCell)*ones(4,1); + dis_division_type1 = [dis_division_type1, the_dis_division_type1]; + +% % % % 三角形, 右侧添加的基质网格 +% % % the_x_division_type2 = [1/3*coordinate(nodes(i,1), 1)+2/3*coordinate(nodes(i,2), 1); coordinate(nodes(i,2), 1);coordinate(nodes(i,4), 1);]; +% % % x_division_type2 = [x_division_type2, the_x_division_type2]; +% % % +% % % the_y_division_type2 = [1/3*coordinate(nodes(i,1), 2)+2/3*coordinate(nodes(i,2), 2); coordinate(nodes(i,2), 2);coordinate(nodes(i,4), 2);]; +% % % y_division_type2 = [y_division_type2, the_y_division_type2]; +% % % +% % % the_dis_division_type2 = v(theAddedMatrixCell)*ones(3,1); +% % % dis_division_type2 = [dis_division_type2, the_dis_division_type2]; + end + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +hold on; +fill(x_division_type2,y_division_type2,dis_division_type2,'EdgeColor','interp'); +hold on; +fill(x_division_type1,y_division_type1,dis_division_type1,'EdgeColor','interp'); + +% +dis_division_type1 = []; +x_division_type1 = []; +y_division_type1 = []; +nel_type1 = 4; + +dis_division_type2 = []; +x_division_type2 = []; +y_division_type2 = []; +nel_type2 = 3; + +for i = 1:nmc + if ismember(i,cell_divided_by_fracture_flag) + aaa = find(cell_divided_by_fracture_flag==i); + theVolumeRatio = volume_ratio(aaa); + theMatrixCell = cell_divided_by_fracture_flag(aaa); + bbb = find(fractureCell_matrixCell_addedMatrixCell(:,2) == theMatrixCell); + theAddedMatrixCell = fractureCell_matrixCell_addedMatrixCell(bbb,3); + if theVolumeRatio == 5/6 + % 右侧四边形, 添加的基质网格 + the_x_division_type1 = [coordinate(nodes(i,1), 1);coordinate(nodes(i,2), 1);coordinate(nodes(i,4), 1);2/3*coordinate(nodes(i,3), 1)+1/3*coordinate(nodes(i,4), 1)]; + x_division_type1 = [x_division_type1, the_x_division_type1]; + + the_y_division_type1 = [coordinate(nodes(i,1), 2);coordinate(nodes(i,2), 2);coordinate(nodes(i,4), 2);2/3*coordinate(nodes(i,3), 2)+1/3*coordinate(nodes(i,4), 2)]; + y_division_type1 = [y_division_type1, the_y_division_type1]; + + the_dis_division_type1 = v(theAddedMatrixCell)*ones(4,1); + dis_division_type1 = [dis_division_type1, the_dis_division_type1]; + +% % % % 左侧三角形, 原始基质网格 +% % % the_x_division_type2 = [2/3*coordinate(nodes(i,3), 1)+1/3*coordinate(nodes(i,4), 1);coordinate(nodes(i,1), 1);coordinate(nodes(i,3), 1);]; +% % % x_division_type2 = [x_division_type2, the_x_division_type2]; +% % % +% % % the_y_division_type2 = [2/3*coordinate(nodes(i,3), 2)+1/3*coordinate(nodes(i,4), 2);coordinate(nodes(i,1), 2);coordinate(nodes(i,3), 2);]; +% % % y_division_type2 = [y_division_type2, the_y_division_type2]; +% % % +% % % the_dis_division_type2 = v(theMatrixCell)*ones(3,1); +% % % dis_division_type2 = [dis_division_type2, the_dis_division_type2]; + end + if theVolumeRatio == 1/2 + % 右侧添加的四边形基质网格 + the_x_division_type1 = [2/3*coordinate(nodes(i,1), 1)+1/3*coordinate(nodes(i,2), 1);coordinate(nodes(i,2), 1);coordinate(nodes(i,4), 1);1/3*coordinate(nodes(i,3), 1)+2/3*coordinate(nodes(i,4), 1)]; + x_division_type1 = [x_division_type1, the_x_division_type1]; + + the_y_division_type1 = [2/3*coordinate(nodes(i,1), 2)+1/3*coordinate(nodes(i,2), 2);coordinate(nodes(i,2), 2);coordinate(nodes(i,4), 2);1/3*coordinate(nodes(i,3), 2)+2/3*coordinate(nodes(i,4), 2)]; + y_division_type1 = [y_division_type1, the_y_division_type1]; + + the_dis_division_type1 = v(theAddedMatrixCell)*ones(4,1); + dis_division_type1 = [dis_division_type1, the_dis_division_type1]; + % 左侧原始的四边形基质网格 +% % % the_x_division_type1 = [2/3*coordinate(nodes(i,1), 1)+1/3*coordinate(nodes(i,2), 1);1/3*coordinate(nodes(i,3), 1)+2/3*coordinate(nodes(i,4), 1); coordinate(nodes(i,3), 1);coordinate(nodes(i,1), 1);]; +% % % x_division_type1 = [x_division_type1, the_x_division_type1]; +% % % +% % % the_y_division_type1 = [2/3*coordinate(nodes(i,1), 2)+1/3*coordinate(nodes(i,2), 2);1/3*coordinate(nodes(i,3), 2)+2/3*coordinate(nodes(i,4), 2); coordinate(nodes(i,3), 2);coordinate(nodes(i,1), 2);]; +% % % y_division_type1 = [y_division_type1, the_y_division_type1]; +% % % +% % % the_dis_division_type1 = v(theMatrixCell)*ones(4,1); +% % % dis_division_type1 = [dis_division_type1, the_dis_division_type1]; + end + if theVolumeRatio == 1/6 +% % % % 四边形, 左侧原始基质网格 +% % % the_x_division_type1 = [coordinate(nodes(i,1), 1);1/3*coordinate(nodes(i,1), 1)+2/3*coordinate(nodes(i,2), 1);coordinate(nodes(i,4), 1);coordinate(nodes(i,3), 1);]; +% % % x_division_type1 = [x_division_type1, the_x_division_type1]; +% % % +% % % the_y_division_type1 = [coordinate(nodes(i,1), 2);1/3*coordinate(nodes(i,1), 2)+2/3*coordinate(nodes(i,2), 2);coordinate(nodes(i,4), 2);coordinate(nodes(i,3), 2);]; +% % % y_division_type1 = [y_division_type1, the_y_division_type1]; +% % % +% % % the_dis_division_type1 = v(theMatrixCell)*ones(4,1); +% % % dis_division_type1 = [dis_division_type1, the_dis_division_type1]; + + % 三角形, 右侧添加的基质网格 + the_x_division_type2 = [1/3*coordinate(nodes(i,1), 1)+2/3*coordinate(nodes(i,2), 1); coordinate(nodes(i,2), 1);coordinate(nodes(i,4), 1);]; + x_division_type2 = [x_division_type2, the_x_division_type2]; + + the_y_division_type2 = [1/3*coordinate(nodes(i,1), 2)+2/3*coordinate(nodes(i,2), 2); coordinate(nodes(i,2), 2);coordinate(nodes(i,4), 2);]; + y_division_type2 = [y_division_type2, the_y_division_type2]; + + the_dis_division_type2 = v(theAddedMatrixCell)*ones(3,1); + dis_division_type2 = [dis_division_type2, the_dis_division_type2]; + end + end +end + +hold on; +fill(x_division_type2,y_division_type2,dis_division_type2,'EdgeColor','interp'); +hold on; +fill(x_division_type1,y_division_type1,dis_division_type1,'EdgeColor','interp'); + + +% +xlabel( 'x, m' ); +ylabel( 'y, m' ); +axis equal; +axis tight +xlim([0,60]); +ylim([0,60]); +colorbar +colormap jet +if type == 1 +caxis([14,43]); +end +% fill(x,y,dis); +% axis off diff --git a/generic extended/plotDis_3D_to_2D_new.m b/generic extended/plotDis_3D_to_2D_new.m new file mode 100644 index 0000000..257c064 --- /dev/null +++ b/generic extended/plotDis_3D_to_2D_new.m @@ -0,0 +1,85 @@ +function plotDis_3D_to_2D_new(i, r, OutputRs, type) +coordinate=r.coordinates; +nodes=r.nodes; +cell_divided_by_fracture_flag = r.cell_divided_by_fracture_flag; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +if type == 1 + v = OutputRs{i}.p; +else + v = 1-OutputRs{i}.sw;%含油饱和度 +end +number_divided_cells = size(cell_divided_by_fracture_flag,1); +dis = zeros(nel, nmc-number_divided_cells); +x = zeros(nel, nmc-number_divided_cells); +y = zeros(nel, nmc-number_divided_cells); +the_numbering = 0; +for i = 1 :nmc + if ~ismember(i,cell_divided_by_fracture_flag) + the_numbering = the_numbering +1; + for j = 1 :nel + x(j, the_numbering) = coordinate(nodes(i,j), 1); + y(j, the_numbering) = coordinate(nodes(i,j), 2); + if j == 3 + x(j, the_numbering) = coordinate(nodes(i,4), 1); + y(j, the_numbering) = coordinate(nodes(i,4), 2); + end + if j == 4 + x(j, the_numbering) = coordinate(nodes(i,3), 1); + y(j, the_numbering) = coordinate(nodes(i,3), 2); + end + dis(j, the_numbering) = v(i); + end + end +end +% 被裂缝剖分的网格绘图 +nel = 3; +% if type == 1 +% v = OutputRs{i}.p; +% else +% v = 1-OutputRs{i}.sw;%含油饱和度 +% end +number_divided_cells = size(cell_divided_by_fracture_flag,1); +dis_division = zeros(nel, 2*number_divided_cells); +x_division = zeros(nel, 2*number_divided_cells); +y_division = zeros(nel, 2*number_divided_cells); +the_numbering_division = 0; +for i = 1 :nmc + if ismember(i,cell_divided_by_fracture_flag) + the_numbering_division = the_numbering_division +2; +% for j = 1 :nel + x_division(1, the_numbering_division-1) = coordinate(nodes(i,1), 1); + y_division(1, the_numbering_division-1) = coordinate(nodes(i,1), 2); + x_division(2, the_numbering_division-1) = coordinate(nodes(i,4), 1); + y_division(2, the_numbering_division-1) = coordinate(nodes(i,4), 2); + x_division(3, the_numbering_division-1) = coordinate(nodes(i,3), 1); + y_division(3, the_numbering_division-1) = coordinate(nodes(i,3), 2); + dis_division(1:3, the_numbering_division-1) = v(i)*ones(3,1); + + x_division(1, the_numbering_division) = coordinate(nodes(i,1), 1); + y_division(1, the_numbering_division) = coordinate(nodes(i,1), 2); + x_division(2, the_numbering_division) = coordinate(nodes(i,2), 1); + y_division(2, the_numbering_division) = coordinate(nodes(i,2), 2); + x_division(3, the_numbering_division) = coordinate(nodes(i,4), 1); + y_division(3, the_numbering_division) = coordinate(nodes(i,4), 2); + + dis_division(1:3, the_numbering_division) = v(nmc+the_numbering_division/2)*ones(3,1); +% end + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +hold on; +fill(x_division,y_division,dis_division,'EdgeColor','interp'); +xlabel( 'x, m' ); +ylabel( 'y, m' ); +axis equal; +axis tight +xlim([0,60]); +ylim([0,60]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/generic extended/plotDislayer.m b/generic extended/plotDislayer.m new file mode 100644 index 0000000..4d53d84 --- /dev/null +++ b/generic extended/plotDislayer.m @@ -0,0 +1,145 @@ +function plotDislayer(i, k ,r,OutputRs, type) +%i:时间点,k是从上至下数的层位,type: 1是压力场 +figure('color','w') +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dislayer( r,k ); +coordinate=r.coordinates; +nodes=r.nodes; +nx=r.nx; +ny=r.ny; +nz=r.nz; +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%用以fill函数作图 +% % nmc = size(nodes,1);%基质网格数量 +% nmc = nx*ny; +% % nel = size(nodes,2);%每个基质网格所包含的点数量 +% nel=size(order,2); +if type == 1 + v = OutputRs{i}.p; +% v = log(r.kx); +elseif type == 2 +% v = 1-OutputRs{i}.sw -OutputRs{i}.sg;%含油饱和度 + v = 1-OutputRs{i}.sw;%含油饱和度 +elseif type == 3 + v = OutputRs{i}.sg;%含油饱和度 +else + v = OutputRs{i}.sw;%含油饱和度 +end +% 底面 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3); + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%左面 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3); + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%右面 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3); + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%前面 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3); + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%后面 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3); + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%上面 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3); + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel('x, m'); +ylabel('y, m'); +zlabel('z, m'); +view(2); +% fill(x,y,dis); +axis equal +% axis off +axis tight +colormap jet +colorbar +% caxis([0.2,0.8]); diff --git a/generic extended/plotWellResponse.m b/generic extended/plotWellResponse.m new file mode 100644 index 0000000..b6509ec --- /dev/null +++ b/generic extended/plotWellResponse.m @@ -0,0 +1,15 @@ +figure('color','w'); +plot(wellResponseData(1:105,1),wellResponseData(1:105,2),'rs-','markersize',6); +hold on; +plot(wellResponseData(1:105,3),wellResponseData(1:105,4),'bo-','markersize',6); +hold on; +plot(wellResponseData(1:104,5),wellResponseData(1:104,6),'k^-','markersize',6); +hold on; +plot(wellResponseData(1:104,7),wellResponseData(1:104,8),'gv-','markersize',6); +hold on; +plot(wellResponseData(1:104,9),wellResponseData(1:104,10),'k-','markersize',6); +hold off; +xlabel('time, days'); +ylabel('water cut of the porduction well, fraction'); +ylabel('BHP of the injection well, MPa'); +legend('EDFM', 'pEDFM-discontinuous', 'pEDFM-continuous','proposed pEDFM workflow','reference solution');% ,'pEDFM, case 3' \ No newline at end of file diff --git a/generic extended/plot_Newtons.m b/generic extended/plot_Newtons.m new file mode 100644 index 0000000..1b940d9 --- /dev/null +++ b/generic extended/plot_Newtons.m @@ -0,0 +1,13 @@ +figure('color','w'); +plot(Newtons(1:120,1),Newtons(1:120,2),'k^-'); +hold on; +plot(Newtons(1:123,3),Newtons(1:123,4),'rs-'); +hold on; +plot(Newtons(1:121,5),Newtons(1:121,6),'bo-'); +hold on; +plot(Newtons(1:121,7),Newtons(1:121,8),'gv-'); +hold off; +xlabel('time, days'); +ylabel('cumulative Newton iteration steps'); +legend('EDFM', 'pEDFM, method 1', 'pEDFM, method 2','pEDFM, method 3');% ,'pEDFM, case 3' + diff --git a/generic extended/plot_continuous.m b/generic extended/plot_continuous.m new file mode 100644 index 0000000..eb775fc --- /dev/null +++ b/generic extended/plot_continuous.m @@ -0,0 +1,116 @@ +dx=[0.5*ones(1,120) ]; +dy=[0.5*ones(1,120) ]; +dz=[2*ones(1,1)]; +nx=size(dx,2); +ny=size(dy,2); +nz=size(dz,2); +x_size = 60; +y_size = 60; +coordinates_pre = zeros(nx*ny*nz,2); +select_t = 120; +for k = 1:nz + for j = 1:ny + for i = 1:nx + if i == 1 + coordinates_pre(i+(j-1)*nx+(k-1)*nx*ny,1) = sum(dx(1:1),2)/2; + else + coordinates_pre(i+(j-1)*nx+(k-1)*nx*ny,1) = (sum(dx(1:i-1),2)+sum(dx(1:i),2))/2; + end + if j == 1 + coordinates_pre(i+(j-1)*nx+(k-1)*nx*ny,2) = sum(dy(1:1),2)/2; + else + coordinates_pre(i+(j-1)*nx+(k-1)*nx*ny,2) = (sum(dy(1:j-1),2)+sum(dy(1:j),2))/2; + end + % if k == 1 + % coordinates_pre(i+(j-1)*nx+(k-1)*nx*ny,3) = sum(dz(1:1),2)/2; + % else + % coordinates_pre(i+(j-1)*nx+(k-1)*nx*ny,3) = (sum(dz(1:k-1),2)+sum(dz(1:k),2))/2; + % end + end + end +end +% select_t = 508; +zData = OutputRs{select_t, 1}.p(1:nx*ny*nz,1); +zData1 = 1-OutputRs{select_t, 1}.sw(1:nx*ny*nz,1); +xData = coordinates_pre(:,1); +yData = coordinates_pre(:,2); +% zData = DATA_plot(:,21); +% zData1 = DATA_plot(:,22); + +% minx = min(xData); +% maxx = max(xData); +% miny = min(yData); +% maxy = max(yData); +minx = 0; +maxx = x_size; +miny = 0; +maxy = y_size; + +tx = (minx:0.05:maxx)'; +ty = (miny:0.05:maxy)'; + +[XI,YI] = meshgrid(tx,ty); +% 非画图区域标记 +% 计算域多边形刻画 +% Comput_domain_x = [0 40 200 160 200 40 0]; +% Comput_domain_y = [40 80 80 40 0 0 40]; +Comput_domain_x = [0 x_size x_size 0 0]; +Comput_domain_y = [0 0 y_size y_size 0]; +% load('coordinates_boundary_node_order.mat'); +% coordinates_boundary_node_order(:,1) = coordinates_boundary_node_order(:,1) + 200; +% coordinates_boundary_node_order(:,2) = coordinates_boundary_node_order(:,2) + 130; +% Comput_domain_x = coordinates_boundary_node_order(:,1); +% Comput_domain_y = coordinates_boundary_node_order(:,2); +% +NX = size(XI,1); +NY = size(YI,1); +% for i = 1:NX +% for j = 1:NY +% in=inpolygon(XI,YI,Comput_domain_x,Comput_domain_x); +% end +% end +in=inpolygon(XI,YI,Comput_domain_x',Comput_domain_y'); +XI(~in) = nan; YI(~in) = nan; + +% for i = 1:NX +% for j = 1:NY +% in=inpolygon(XI(i,j),YI(i,j),Comput_domain_x',Comput_domain_y'); +% if ~in XI(i,j) = nan; YI(i,j) = nan; end +% end +% end +ZI = griddata(xData,yData,zData,XI,YI); +ZII = griddata(xData,yData,zData1,XI,YI); +figure('color','w');surf(XI,YI,ZI), hold +% plot3(xData,yData,zData,'o'), hold off +grid off +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel( 'x, m' ); +ylabel( 'y, m' ); +zlabel( 'z, m' ); +% grid on +view( 0, 90 ); +axis equal; +xlim([0,60]); +ylim([0,60]); +colorbar +colormap jet +% caxis([10,15]); +hold off +shading interp +% set('edgecolor','none') +figure('color','w');surf(XI,YI,ZII), hold +% plot3(xData,yData,zData1,'o'), hold off +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel( 'x, m' ); +ylabel( 'y, m' ); +zlabel( 'z, m' ); +view( 0, 90 ); +axis equal; +xlim([0,60]); +ylim([0,60]); +grid off +colorbar +colormap jet +caxis([0.2,0.8]); +hold off +shading interp diff --git a/generic extended/plotfigures.m b/generic extended/plotfigures.m new file mode 100644 index 0000000..e03cdd7 --- /dev/null +++ b/generic extended/plotfigures.m @@ -0,0 +1,42 @@ +numberMatrixCells = 120*120; +% % % resultsSaturation1to2 = zeros(numberMatrixCells,5); +% % % resultsPressure1to2 = zeros(numberMatrixCells,5); +% % % +% % % load('resultsEDFM.mat') +% % % theMaxNumber = size(OutputRs,1); +% % % plotDis_3D_to_2D(theMaxNumber, r, OutputRs, 2);saveas(gcf, 'EDFM_saturation.fig'); +% % % plotDis_3D_to_2D(theMaxNumber, r, OutputRs, 1);saveas(gcf, 'EDFM_pressure.fig'); +% % % resultsSaturation1to2(:,1) = OutputRs{theMaxNumber,1}.sw(1:numberMatrixCells,1); +% % % resultsPressure1to2(:,1) = OutputRs{theMaxNumber,1}.p(1:numberMatrixCells,1); +% % % +% % % load('resultsPEDFM_method1.mat') +% % % theMaxNumber = size(OutputRs,1); +% % % plotDis_3D_to_2D(theMaxNumber, r, OutputRs, 2);saveas(gcf, 'pEDFM_method1_saturation.fig'); +% % % plotDis_3D_to_2D(theMaxNumber, r, OutputRs, 1);saveas(gcf, 'pEDFM_method1_pressure.fig'); +% % % resultsSaturation1to2(:,2) = OutputRs{theMaxNumber,1}.sw(1:numberMatrixCells,1); +% % % resultsPressure1to2(:,2) = OutputRs{theMaxNumber,1}.p(1:numberMatrixCells,1); +% % % +% % % load('resultsPEDFM_method2.mat') +% % % theMaxNumber = size(OutputRs,1); +% % % plotDis_3D_to_2D(theMaxNumber, r, OutputRs, 2);saveas(gcf, 'pEDFM_method2_saturation.fig'); +% % % plotDis_3D_to_2D(theMaxNumber, r, OutputRs, 1);saveas(gcf, 'pEDFM_method2_pressure.fig'); +% % % resultsSaturation1to2(:,3) = OutputRs{theMaxNumber,1}.sw(1:numberMatrixCells,1); +% % % resultsPressure1to2(:,3) = OutputRs{theMaxNumber,1}.p(1:numberMatrixCells,1); +% % % +% % % load('resultsNewPEDFM.mat') +% % % theMaxNumber = size(OutputRs,1); +% % % plotDis_3D_to_2D(theMaxNumber, r, OutputRs, 2);saveas(gcf, 'NewPEDFM_saturation.fig'); +% % % plotDis_3D_to_2D(theMaxNumber, r, OutputRs, 1);saveas(gcf, 'NewPEDFM_pressure.fig'); +% % % resultsSaturation1to2(:,4) = OutputRs{theMaxNumber,1}.sw(1:numberMatrixCells,1); +% % % resultsPressure1to2(:,4) = OutputRs{theMaxNumber,1}.p(1:numberMatrixCells,1); + +load('resultsReference.mat') +theMaxNumber = size(OutputRs,1); +plotDis_3D_to_2D_1to2(theMaxNumber, r, OutputRs, 2);saveas(gcf, 'reference_saturation.fig'); +plotDis_3D_to_2D_1to2(theMaxNumber, r, OutputRs, 1);saveas(gcf, 'reference_pressure.fig'); +% % % resultsSaturation1to2(:,5) = OutputRs{theMaxNumber,1}.sw(1:numberMatrixCells,1); +% % % resultsPressure1to2(:,5) = OutputRs{theMaxNumber,1}.p(1:numberMatrixCells,1); + +% save resultsSaturation1to2 resultsSaturation1to2; +% save resultsPressure1to2 resultsPressure1to2 + diff --git a/generic extended/plotwell.m b/generic extended/plotwell.m new file mode 100644 index 0000000..3b0bcf9 --- /dev/null +++ b/generic extended/plotwell.m @@ -0,0 +1,14 @@ +t = Times; +n=size(Times,1); +% para = cell2mat(Wellpara); +nw=1;%选井号 +% n = length(para); +bhp = zeros(n,1); +for i = 1 : n +% bhp(i) = para(i).bhp(2); +% bhp(i) = Wellpara{i,1}{1,nw}.pwf; +bhp(i) = Wellpara{i}{1,nw}.qo; +% bhp(i) = Wellpara{i}{1,nw}.pwf; +end +plot(t,bhp,'b*-') +hold on \ No newline at end of file diff --git a/main.asv b/main.asv new file mode 100644 index 0000000..7594c47 --- /dev/null +++ b/main.asv @@ -0,0 +1,194 @@ +function [ r, Times, OutputRs, Wellpara, trun ] = main() +%% ==================================PART 1: 妯″瀷閫夊彇======================================== +% 1-- classical EDFM +modelflag = 1;% 姝ゅ鍥哄畾涓1鍗冲彲 +%% ==================================PART 2: 鍩鸿川缃戞牸瀹氫箟===================================== +dx=[10*ones(1,100) ];nx=size(dx,2); +dy=[10*ones(1,50) ];ny=size(dy,2); +dz=[10*ones(1,2)];nz=size(dz,2); + +%% ==================================PART 3: 瑁傜紳鍒嗗竷鏁版嵁杈撳叆===================================== +% 鍥涚杈撳叆鏂瑰紡: 1琛ㄧず宸ョ▼搴旂敤杈撳叆锛2琛ㄧず鍚戦噺杈撳叆锛3琛ㄧず宸ョ▼搴旂敤杈撳叆锛屽寘鎷熀鍑嗙偣銆佸捐銆佹柟浣嶈銆佹姮鍗囪锛4琛ㄧず浠.fab鏂囦欢璇诲彇 +input_style = 1; +%% 杈撳叆鏂瑰紡1锛氬伐绋嬪簲鐢ㄨ緭鍏 +%浠呰兘鍒荤敾鍏锋湁鍙屽绉版ц川鐨勭煩褰㈢紳鎴栨き鍦嗙紳 +% 鍩哄噯鐐瑰潗鏍囷紙1锛夛紝鏂逛綅瑙掞紙2锛夛紝鍊捐锛3锛夛紝鎶崌瑙掞紙4锛夛紝缂濋暱锛堟き鍦嗛暱杞撮暱锛夛紙5锛夛紝缂濋珮锛堟き鍦嗙煭杞撮暱锛夛紙6锛夛紝绫诲瀷1鏄煩褰㈢紳銆2鏄き鍦嗙紳锛7锛 +if input_style==1 +input_content={ + [255,255,5],90,90,0,200,10,1; + [305,255,5],90,90,0,200,10,1; + [355,255,5],90,90,0,200,10,1; + [405,255,5],90,90,0,200,10,1; + [455,255,10],90,90,0,200,20,1; + [505,255,10],90,90,0,200,20,1; + [555,255,15],90,90,0,200,10,1; + [605,255,15],90,90,0,200,10,1; + [655,255,15],90,90,0,200,10,1; + [705,255,15],90,90,0,200,10,1; + [755,255,15],90,90,0,200,10,1; + }; +[f,fellip] = sort_fracture(input_content); +frac_information = fractureInformation_input_engineering_vector(f,fellip); +end +%% 杈撳叆鏂瑰紡2锛氬悜閲忚緭鍏 +%棣栧厛瀵圭煩褰㈢紳杩涜鐮旂┒锛岃缂濆弬鏁板寘鎷笁涓悜閲忓拰涓や釜鍙傛暟鐨勫彇鍊艰寖鍥达紝濡傛灉鏄叾瀹冪被鍨嬬紳锛屽垯鏄袱涓弬鏁伴棿鐨勫嚱鏁板叧绯 +%鍥犳涓涓5琛屼笁鍒楃殑鐭╅樀鍙互纭畾涓鏉¤缂 +%鍚戦噺鍒嗛噺鍙负闈炴暣鏁帮紝浠ユ淇濊瘉鍙傛暟鑼冨洿鐨勫彇鍊间负鏁存暟鍗冲彲锛 +%鏁呭彲鍏堥殢鎰忕‘瀹氫负鏁存暟鐨勫弬鏁拌寖鍥达紝鍐嶆牴鎹紳闀跨紳楂樺幓纭畾鍚戦噺鍒嗛噺鐨勫彇鍊 +% 鐭╁舰缂 +if input_style==2 + f=[ + 0,1200,0;10,-20,0;0,0,10;0,60,0;0,3,0; + 0,1200,0;10,20,0;0,0,10;0,15,0;0,3,0; + 150,1500,0;20,-10,0;0,0,10;0,20,0;0,3,0; + 550,1300,0;10,10,0;0,0,10;0,10,0;0,3,0; + 650,1400,0;10,-20,0;0,0,10;0,55,0;0,3,0; + 605,705,0;10,0,0;0,0,10;-20,20,0;0,3,0; + ]; +% 妞渾缂 +% fellip=[320,210,10;10,2,0;0,0,2;0,0,8;0,0,5; +% 280,300,10;10,2,0;0,0,2;0,0,10;0,0,4;]; +% 300,205,10;10,0,0;0,0,2;0,0,10;0,0,5]; +fellip=[]; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +frac_information = fractureInformation_input_engineering_vector(f,fellip); +end +%% 杈撳叆鏂瑰紡3锛氫簩缁磋緭鍏 +% load('fractures_generated.mat'); +% fractureLines = fractures_generated; +fractureLines = [ + 105,150;105,350; + 205,150;205,350; + 305,150;305,350; + 405,150;405,350; + 505,150;505,350; + 605,150;605,350; + 705,150;705,350; + 805,150;805,350; + 905,150;905,350; + ]; +fellip=[]; % 妞渾缂 +fractureHeights = [ + 10;10;10;10;10;10;10;10;10]; +% 妞渾缂 +fellip=[]; +flowBarrierFlags = [];% flowBarrierFlags = [1;2;3;4]; +[f,frac_information] = input_fracture_2D(fractureLines,fractureHeights,flowBarrierFlags); +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +%% 杈撳叆鏂瑰紡4锛氫粠.fab鏂囦欢璇诲彇 +if input_style==4 + +end + +%% ==================================PART 4: 鍩鸿川缃戞牸鍙婅缂濈墿鎬у弬鏁拌緭鍏===================================== +% 1-- 鍗曢噸浠嬭川 +% 2-- 鍙岄噸浠嬭川锛堝弻瀛斿弻娓楋級 +grid_model = 1; +if grid_model == 1 +r = grid_discretization_SP_model(modelflag, nx, ny, nz, dx, dy, dz, f, frac_information, fellip, nf); +end +if grid_model == 2 +r = grid_discretization_DP_model(modelflag, nx, ny, nz, dx, dy, dz, f, frac_information, fellip, nf); +end +%% 鐢熸垚鍚戦噺鍖栧彉鎴愭墍闇瑕佺殑绠楀瓙 +os = OperatorRS(r.N, r.nex, r.nc); + +%% ==================================PART 5: 妯″瀷绫诲瀷閫夊彇鍙婂垵濮嬬姸鎬佽瀹========================================= +% 1-- 姘旀按涓ょ浉娴 +% 2-- 娌规按涓ょ浉娴 +flow_model = 2; +if flow_model == 1 +[f,state0] = gas_water_flow(r); +end +if flow_model == 2 +[f,state0] = oil_water_flow(r); +end + +%% ==================================PART 6: 浜曞埗搴chedule璁惧畾================================================ +%灏嗙洿浜曘佹按骞充簳涓庡娈靛帇瑁傛按骞充簳鍒嗗紑澶勭悊 +%% 鐩翠簳銆佸父瑙勬按骞充簳瀹氫箟 +% Wellcpara: wellname(1) nperf锛屽皠瀛旂偣鏁伴噺(2) index(3) rw(4) skin(5) welltype(6) +% welltype=1 鐩翠簳锛寃elltype=2 姘村钩浜曟部x鏂瑰悜锛寃elltype=3 姘村钩浜曟部y鏂瑰悜 welltype=4 澶氭鍘嬭姘村钩浜 +% 鐩翠簳銆佹按骞充簳锛岃绉嶄簳鍨嬬殑澶勭悊鏄皢灏勫瓟娈靛畨鎺掑湪鍩鸿川缃戞牸 +% 瀵逛簬鐩翠簳銆佹枩浜曘佹按骞充簳锛岄噰鍙栦笌eclipse涓鑷寸殑鏂瑰紡锛岀粰鍑哄叾鍦ㄥ熀璐ㄧ綉鏍间腑浣嶇疆 +% 姣忎釜灏勫瓟鐐圭敱涓媝x,py,pz纭畾锛屽垎鍒〃绀鸿灏勫瓟鐐瑰湪x鏂瑰悜锛寉鏂瑰悜鐨勭綉鏍肩紪鍙凤紝鍙婂眰鏁板嵆z鍙嶆柟鍚戜笂鐨勭綉鏍肩紪鍙凤紙鏈鍒濇槸浠ュ瀭鐩村悜涓婂缓绔嬬殑鍩鸿川缃戞牸锛 +well1={ + 'w1', 2, [20 10 1;20 10 2;], 0.178/2, 0, 1; + 'w2', 2, [80 10 1;80 10 2;], 0.178/2, 0, 1; + 'w3', 1, [20 40 1;], 0.178/2, 0, 1; + 'w4', 1, [80 40 1;], 0.178/2, 0, 1; +% 'w2', 3, [67 20 1;67 20 2;67 20 3], 0.178/2, 0, 1; + }; +well1 = handle_well1(well1,r); +%% 鍘嬭姘村钩浜曞畾涔 +% 澶氭鍘嬭姘村钩浜曪細灏勫瓟娈佃缃湪瑁傜紳鍗曞厓涓婏紝鍙互缁欏嚭璇ュ皠瀛旂偣鎵鍦ㄧ殑鍧愭爣锛岀劧鍚庡幓瀵绘壘璇ョ偣鎵鍦ㄧ殑瑁傜紳鍗曞厓缂栧彿 +num_fracture_wells = 1; +welloc = cell(num_fracture_wells,1); +perfnum = cell(num_fracture_wells,1); +welloc{1,1}=[ + 255,155,5; + 305,155,5; + 355,155,5; + 405,155,5; + 455,155,5; + 505,155,5; + 555,155,15; + 605,155,15; + 655,155,15; + 705,155,15; + 755,155,15; + ]; +for i = 1:num_fracture_wells +perfnum{i,1} = findWelloc(r, welloc{i,1});%鍦ㄧ敤浠ellc0涔嬩腑 +end +% perfnum2 = findWelloc(r, welloc2); +well2={ + 'w5', length(perfnum{1,1}), perfnum{1,1}, 0.178/2, 0,4; + }; +Wellc = handle_well1_well2(well1,well2,welloc,r); +%% 浜曞埗搴﹁缃紙寮鍏充簳銆佸畾鍘/瀹氫骇銆佷究浜庡悶鍚愮瓑锛 +number_phases = 1; +well_schedules = cell(number_phases,1); +time = zeros(number_phases,1); +% time = [100;30;200]; +% (1)well state: 'open'琛ㄧず璇ヤ簳鏄紑鐨勶紱'close'琛ㄦ槑璇ヤ簳涓鐩存槸鍏崇殑锛屽鏋滃彧鏄樁娈垫у叧浜曪紝灏辩敤'open'瀹氭祦閲0鐢熶骇 +% (2)well type: 'pro'琛ㄧず鏄敓浜т簳锛'inj'琛ㄧず鏄敞鍏ヤ簳; +% (3)protype锛'const_q'鏄畾娴侀噺锛'const_pwf'鍒欐槸瀹氬帇 +% (4)value锛氬畾鐨勬祦閲忓兼垨鑰呬簳搴曞帇鍔涘 +% (5)value锛氭浠g爜璇ュ间笌锛3锛夊肩浉鍚 +time(1) = 0.001; +well_schedules{1,1} = {'w1','open','inj','const_pwf',30,30; + 'w2','open','inj','const_pwf',30,30; + 'w3','open','inj','const_pwf',30,30; + 'w4','open','inj','const_pwf',30,30; + 'w5','open','pro','const_pwf',10,10;}; +% time(2) = 30; +% well_schedules{2,1} = {'w1','open','inj','const_pwf',30,30; +% 'w2','open','pro','const_q',0,0;}; +% time(3) = 200; +% well_schedules{3,1} = {'w1','open','inj','const_pwf',30,30; +% 'w2','open','pro','const_pwf',10,10;}; +% time(4) = 200; +% well_schedules{4,1} = {'w1','open','inj','const_pwf',30,30; +% 'w2','open','pro','const_pwf',10,10;}; +% time(5) = 200; +% well_schedules{5,1} = {'w1','open','inj','const_pwf',30,30; +% 'w2','open','pro','const_pwf',10,10;}; +% time(6) = 200; +% well_schedules{6,1} = {'w1','open','inj','const_pwf',30,30; +% 'w2','open','pro','const_pwf',10,10;}; + +%% ======================================PART 7: Solver璁剧疆=========================================== +yitap = 5; % 50-500psi +yitas = 0.04; % 0.05-0.5 +omega = 0.5; % 0-1 +Nmax = 50; +epsave = 1e-6; +epsmax = 1e-6; +dtmin = 0.000001; +dtmax = 0.0001; +%% ======================================PART 8: 姝e紡璁$畻=========================================== +[Times, OutputRs, Wellpara, trun] = solver_NR(r, f, os, state0, yitap,yitas,omega,Nmax,epsave,epsmax,dtmin,dtmax,Wellc,time,well_schedules); +run_time=toc; +trun.run_time=run_time; +end \ No newline at end of file diff --git a/plotWellResponse.asv b/plotWellResponse.asv new file mode 100644 index 0000000..b5a88f8 --- /dev/null +++ b/plotWellResponse.asv @@ -0,0 +1,55 @@ +function [] = plotWellResponse(Times,Wellpara) +% 杈撳叆 +wellNumber = 1; % 浜曞彿 +dataType = 'GPR'; % 绫诲瀷锛屼骇姘旈熷害 GPR锛屼骇姘旈熷害 OPR, 浜ф按閫熷害 WPR锛屼簳搴曟祦鍘 BHP锛屽帇鍔涘鏁 dPWF +% +t = Times; +n= size(Times,1); +% para = cell2mat(Wellpara); +nw = wellNumber;%閫変簳鍙 +% n = length(para); +data = zeros(n,1); +if strcmp(dataType, 'GPR') +for i = 1 : n +data(i) = Wellpara{i}{1,nw}.qg; +figureYlegend = 'Gas production rate, m^3/d'; +end +end +if strcmp(dataType, 'OPR') +for i = 1 : n +data(i) = Wellpara{i}{1,nw}.qo; +figureYlegend = 'Oil production rate, m^3/d'; +end +end +if strcmp(dataType, 'WPR') +for i = 1 : n +data(i) = Wellpara{i}{1,nw}.qw; +figureYlegend = 'Water production rate, m^3/d'; +end +end +if strcmp(dataType, 'BHP') +for i = 1 : n +data(i) = Wellpara{i}{1,nw}.pwf; +figureYlegend = 'BHP, MPa'; +end +end +if strcmp(dataType, 'dPWF') % dpwf/dlnt = t*dpwf/dt +for i = 1 : n + if i == 1 +data(i) = Wellpara{i}{1,nw}.pwf; + elseif i == n +data(i) = Wellpara{i}{1,nw}.pwf; + else +data(i) = Wellpara{i}{1,nw}.pwf; + end +figureYlegend = 'Pressure derivative, MPa'; +end +end + +plot(t,data,'k^-') +hold off +% ylim([0,200]); +xlabel('Time, day'); +% ylabel('water cut'); +ylabel('Gas production rate, m^3/d'); +end \ No newline at end of file diff --git a/post processor/plot functions/data_standard.m b/post processor/plot functions/data_standard.m new file mode 100644 index 0000000..b0e4f3c --- /dev/null +++ b/post processor/plot functions/data_standard.m @@ -0,0 +1,343 @@ +function [ r, Times, OutputRs, Wellpara, trun ] = data_standard( ) +tic; +%% 模型选取 +% 1--2014, Monifar 2--2018, steady, Rao 3--2018, transient, Rao +% 4-- PEDFM, Tene, Jiang, Younis +modelflag=1; +%前处理综合 +%% 基质网格参数输入并进行网格参数计算 +% dx=[10*ones(1,100) ];nx=size(dx,2); +% dy=[10*ones(1,50) ];ny=size(dy,2); +% dz=[10*ones(1,4)];nz=size(dz,2); +% dx=[10*ones(1,50) ];nx=size(dx,2); +% dy=[10*ones(1,30) ];ny=size(dy,2); +% dz=[10*ones(1,3)];nz=size(dz,2); +dx=[10*ones(1,100) ];nx=size(dx,2); +dy=[10*ones(1,50) ];ny=size(dy,2); +dz=[10*ones(1,1)];nz=size(dz,2); +%% 裂缝参数输入 +% 两种输入方式,1表示向量输入,2表示基准点、倾角、方位角、抬升角输入 +input_style=2; +if input_style==1 +% ==================向量输入====================================== % +%首先对矩形缝进行研究,裂缝参数包括三个向量和两个参数的取值范围,如果是其它类型缝,则是两个参数间的函数关系 +%因此一个5行三列的矩阵可以确定一条裂缝 +%向量分量可为非整数,以此保证参数范围的取值为整数即可, +%故可先随意确定为整数的参数范围,再根据缝长缝高去确定向量分量的取值 + f=[ + 0,1200,0;10,-20,0;0,0,10;0,60,0;0,3,0; + 0,1200,0;10,20,0;0,0,10;0,15,0;0,3,0; + 150,1500,0;20,-10,0;0,0,10;0,20,0;0,3,0; + 550,1300,0;10,10,0;0,0,10;0,10,0;0,3,0; + 650,1400,0;10,-20,0;0,0,10;0,55,0;0,3,0; + 605,705,0;10,0,0;0,0,10;-20,20,0;0,3,0; + +% 385,485,2;5,0,0;0,0,1;-6,12,0;0,24,0; +% 385,365,2;5,0,0;0,0,1;-12,20,0;0,24,0; +% 385,245,2;5,0,0;0,0,1;-10,20,0;0,24,0; +% 385,925,2;5,0,0;0,0,1;-9,18,0;0,20,0; +% 385,805,2;5,0,0;0,0,1;-8,14,0;0,20,0; +% 385,685,2;5,0,0;0,0,1;-12,20,0;0,24,0; +% 385,565,2;5,0,0;0,0,1;-10,20,0;0,22,0; +% 385,445,2;5,0,0;0,0,1;-6,12,0;0,24,0; +% 955,1305,5;5,0,0;0,0,1;-5,4,0;0,15,0; +% 955,1225,5;5,0,0;0,0,1;-7,5,0;0,15,0; +% 955,1145,5;5,0,0;0,0,1;-9,6,0;0,15,0; +% 955,1065,5;5,0,0;0,0,1;-7,6,0;0,15,0; +% 955,985,5;5,0,0;0,0,1;-6,4,0;0,15,0; +% 955,755,5;5,0,0;0,0,1;-5,4,0;0,15,0; +% 955,675,5;5,0,0;0,0,1;-8,6,0;0,15,0; +% 955,595,5;5,0,0;0,0,1;-8,6,0;0,15,0; +% 955,515,5;5,0,0;0,0,1;-10,7,0;0,15,0; +% 955,435,5;5,0,0;0,0,1;-7,6,0;0,15,0; +% 955,355,5;5,0,0;0,0,1;-9,6,0;0,15,0; +% 1635,1245,5;5,0,0;0,0,1;-10,2,0;0,20,0; +% 1635,1165,5;5,0,0;0,0,1;-16,3,0;0,20,0; +% 1635,1085,5;5,0,0;0,0,1;-15,3,0;0,20,0; +% 1635,1005,5;5,0,0;0,0,1;-12,2,0;0,20,0; +% 1635,925,5;5,0,0;0,0,1;-10,2,0;0,20,0; +% 1635,695,5;5,0,0;0,0,1;-10,2,0;0,20,0; +% 1635,615,5;5,0,0;0,0,1;-12,2,0;0,20,0; + ]; +% 椭圆缝 +% fellip=[320,210,10;10,2,0;0,0,2;0,0,8;0,0,5; +% 280,300,10;10,2,0;0,0,2;0,0,10;0,0,4;]; +% 300,205,10;10,0,0;0,0,2;0,0,10;0,0,5]; +fellip=[]; +else +% ==================工程应用输入====================================== % +%仅能刻画具有双对称性质的矩形缝或椭圆缝 +% 基准点坐标(1),方位角(2),倾角(3),抬升角(4),缝长(椭圆长轴长)(5),缝高(椭圆短轴长)(6),类型1是矩形缝、2是椭圆缝(7) + input_content={ + [255,255,5],90,90,0,200,10,1; + [305,255,5],90,90,0,200,10,1; + [355,255,5],90,90,0,200,10,1; + [405,255,5],90,90,0,200,10,1; + [455,255,5],90,90,0,200,10,1; + [505,255,5],90,90,0,200,10,1; + [555,255,5],90,90,0,200,10,1; + [605,255,5],90,90,0,200,10,1; + [655,255,5],90,90,0,200,10,1; + [705,255,5],90,90,0,200,10,1; + [755,255,5],90,90,0,200,10,1; + }; +[f,fellip]=sort_fracture(input_content); +end + +% ==================裂缝情况整理====================================== % +m=size(f,1); +n=size(fellip,1); +nf=(m+n)/5;%裂缝条数 +%% 渗流介质相关参数 +% =====================基质孔渗====================================== % +% kx = 0.1*1e-3 * ones(nx*ny*nz, 1);%生成基质网格绝对渗透率x方向矩阵 +% ky =0.1*1e-3 * ones(nx*ny*nz, 1);%y方向 +% kz = 0.1*1e-3 * ones(nx*ny*nz, 1);%y方向 +pori = 0.3 * ones(nx*ny*nz, 1);%生成基质网格孔隙度矩阵 +prpor = 16;%基质孔隙度基准压力 +cpor = 1.07e-4;%孔隙体积压缩系数 +NTG= 1 * ones(nx*ny*nz, 1); +% SRV区域定义 +base_x=23:78; nx_SRV=length(base_x); +base_y=15:36; ny_SRV=length(base_y); +base_z=1:1;nz_SRV=length(base_z); +SRV=[]; +for k=1:nz_SRV + for j=1:ny_SRV + for i=1:nx_SRV + SRV=[SRV;(base_z(k)-1)*nx*ny+(base_y(j)-1)*nx+base_x(i)]; + end + end +end +% 非SRV渗透率赋值 +kx = 0.1*1e-3 * ones(nx*ny*nz, 1);%生成基质网格绝对渗透率x方向矩阵 +ky =0.1*1e-3 * ones(nx*ny*nz, 1);%y方向 +kz = 0.1*1e-3 * ones(nx*ny*nz, 1);%y方向 +% SRV渗透率赋值 +kx(SRV)=2*1e-3 * ones(length(SRV), 1); +ky(SRV)=2*1e-3 * ones(length(SRV), 1); +kz(SRV)=2*1e-3 * ones(length(SRV), 1); +% load ('NTG.mat'); +% NTG=sort_input(NTG,nx,ny,nz); +% =====================裂缝孔渗====================================== % +Kf = 20000*1e-3*ones(1,nf);%裂缝渗透率 +% Kf = [0*1e-3*ones(1,5) 10000*1e-3*ones(1,1);];%裂缝渗透率 +Wf =1e-2*ones(1,nf);%裂缝宽度 +Porf = 0.30*ones(1,nf);%裂缝孔隙度 +prporf = 20;%裂缝孔隙度基准压力 +cporf = 1.07e-4;%裂缝孔隙体积压缩系数 + +Rpt = 2;%flag +cf = 1; +ca = 1; +% co = 3.02e-3; +%% 流体性质参数 +% =======================密度================================= % +Dosi=820; %Dosi是地面标况下测得的油相密度,单位是千克/每立方米 +Dwsi=1000; %Dwsi是地面标况下测得的水相密度 +% ====================体积系数及压缩系数================================= % +pb = 20.0;%泡点压力 +Bopb = 1.0;%泡点压力pb对应的原油体积系数 +co = 3.02e-3;%原油体积压缩系数 +prw = 20.0;%地层水体积系数基准压力 +Bwi = 1.00001;%原始地层水体积系数 +cw = 5e-4;%地层水体积压缩系数 +prg = 25.0;%地层水体积系数基准压力 +% =======================粘度================================= % +visopb = 2;%泡点压力pb对应的原有粘度 +cvo = 0;%原油粘度随压力变化的系数 +vwi =0.6;%原始地层水粘度 +cvw = 0;%地层水粘度随压力变化的系数 +% ==================相渗及毛管力曲线====================================== % +% ==================基质油水相渗====================================== % +RPOW=[ +0 0 0.8 0 +0.15 0 0.8 0 +0.45 0.04 0.4 0 +0.5212 0.08 0.227 0 +0.5425 0.103 0.184 0 +0.5638 0.125 0.156 0 +0.5851 0.145 0.125 0 +0.6064 0.174 0.094 0 +0.6276 0.207 0.063 0 +0.6489 0.247 0.046 0 +0.6701 0.292 0.031 0 +0.6914 0.335 0.021 0 +0.7127 0.378 0.011 0 +0.76 0.475 0.005 0 +0.85 0.552 0 0 +1 0.552 0 0 +]; +SW=RPOW(:,1);KRW=RPOW(:,2);KRO=RPOW(:,3);PCOW=RPOW(:,4); +% ==================裂缝油水相渗====================================== % +% 在裂缝中,性质就是简单得两点线性插值 +if Rpt ~= 1%表示该网格是裂缝网格 +PRF=[ +0 0 0.8 0 +0.15 0 0.8 0 +0.85 0.6 0 0 +1 0.6 0 0 +]; +SWF = PRF(:,1);KRWF = PRF(:,2);KROF = PRF(:,3);PCOWF=PRF(:,4); +end +% ==================毛管力情况====================================== % +ifpcow = 0;%此处为控制是否忽略油水相间毛管力,0代表忽略,非0代表考虑 +%% 结合网格和流动介质参数进行前处理 +r = GridProp(modelflag, nx, ny, nz, dx, dy, dz, kx, ky, kz, f, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,co, NTG); +%% 生成向量化变成所需要的算子 +os = OperatorRS(r.N, r.nex, r.nc); +%% 结合流体性质参数进行处理 +f = fluidPVT(Bopb, pb, co, Bwi, prw, cw, vwi, cvw, visopb, cvo, SW, KRO, KRW, PCOW, ifpcow, SWF, KROF, KRWF, PCOWF, r.rpt,Dosi,Dwsi); +%% 初值条件 Initial Condition Section +% =================压力、饱和度初值======================================= % +%压力初值要考虑重力,给出油藏下表面压力值 +P = [20 * ones(r.nmc, 1); 20 * ones(r.nfc, 1)]; +% plow=25; % P =plow-1e-6*800*9.8*r.z; +Sw = [0.15 * ones(r.nmc, 1); 0.15 * ones(r.nfc, 1)]; +state0 = initialRS(P, Sw); +%% schedule +% 井参数输入 +% Wellcpara: welltype(1) nperf(2) index(3) rw(4) protype(5) value(6) +% constraints(7) skin(8) welltype2(9) +% welltype = 1 prod, welltype = 2 inj +% protype = 1 const flowrate, protype = 2 const pwf +% welltype2=1 直井, welltype2=2 水平井沿x方向,welltype2=3 水平井沿y方向 welltype2=4 多段压裂水平井 +%将直井、水平井与多段压裂水平井分开处理 +%直井、水平井,该种井型的处理是将射孔段安排在基质网格 +%由于是三维的储层,具体基质网格不好直接给出,对于直井、斜井、水平井,采取与eclipse一致的方式,给出其在基质网格中位置 +%每个射孔点由下px,py,pz确定,分别表示该射孔点在x方向,y方向的网格编号,及层数即z反方向上的网格编号(最初是以垂直向上建立的基质网格) +well1={ +% 2, 3, [10 20 1;10 20 2;10 20 3], 0.178/2, 2, 35 , 35, 0, 1; +% 2, 3, [67 20 1;67 20 2;67 20 3], 0.178/2, 2, 35 , 35, 0, 1; +% 2, 3, [130 20 1;130 20 2;130 20 3], 0.178/2, 2, 35 , 35, 0, 1; +% 2, 3, [196 20 1;196 20 2;196 20 3], 0.178/2, 2, 35 , 35, 0, 1; +% 2, 3, [10 148 1;10 148 2;10 148 3], 0.178/2, 2, 35 , 35, 0, 1; +% 2, 3, [67 148 1;67 148 2;67 148 3], 0.178/2, 2, 35 , 35, 0, 1; +% 2, 3, [130 148 1;130 148 2;130 148 3], 0.178/2, 2, 35 , 35, 0, 1; +% 2, 3, [196 148 1;196 148 2;196 148 3], 0.178/2, 2, 35 , 35, 0, 1; + }; +%需要找到射孔段具体所在的基质网格编号 +n1=size(well1,1); +for i=1:n1 + perf=well1{i,3}; + nperf=well1{i,2}; + perf(:,3)=(r.nz+1)*ones(nperf,1)-perf(:,3); + A=repmat([0 1 1],nperf,1); + B=(perf-A)*[1;r.nx;r.nx*r.ny]; + B=B'; %转换为行向量 + well1{i,3}=B; +end +% %多段压裂水平井的处理,射孔段设置在裂缝单元上,可以给出该射孔点所在的坐标,然后去寻找该点所在的裂缝单元编号 +welloc1=[ + [255,255,5]; + [305,255,5]; + [355,255,5]; + [405,255,5]; + [455,255,5]; + [505,255,5]; + [555,255,5]; + [605,255,5]; + [655,255,5]; + [705,255,5]; + [755,255,5]; +% [205,255,15]; +% [405,255,21]; +% [605,255,21]; +% [805,255,31]; +% 385,805,15; +% 385,685,15; +% 385,565,15; +% 385,445,15; + ]; +% welloc2=[955,1305,15; +% 955,1225,15; +% 955,1145,15; +% 955,1065,15; +% 955,985,15; +% 955,755,15; +% 955,675,15; +% 955,595,15; +% 955,515,15; +% 955,435,15; +% 955,355,15;]; +% welloc3=[1635,1245,15; +% 1635,1165,15; +% 1635,1085,15; +% 1635,1005,15; +% 1635,925,15; +% 1635,695,15; +% 1635,615,15; +% ]; +perfnum1 = findWelloc(r, welloc1);%在用以Wellc0之中 +% perfnum2 = findWelloc(r, welloc2); +% perfnum3 = findWelloc(r, welloc3); +well2={ + 1, length(perfnum1), perfnum1, 0.178/2, 2,10, 10, 0,4; +% 1, length(perfnum2), perfnum2, 0.178/2, 2,8, 8, 0,4; +% 1, length(perfnum3), perfnum3, 0.178/2, 2,8, 8, 0,4; + }; +% well2={}; +% well2={1, length(perfnum), perfnum, 0.1, 2,10, 10, 0,4; +% }; +% 2, 1, [ 5030 ], 0.3/0.318, 1,0.05, 30, 0,4 +%把两类井整合到一起 +nwell1=size(well1,1); +nwell2=size(well2,1); +nwell=nwell1+nwell2; +Wellc0=cell(nwell,9); +if nwell1==0 + Wellc0=well2; +elseif nwell2==0 + Wellc0=well1; +else +for i=1:nwell1 + for j=1:9 + Wellc0{i,j}=well1{i,j}; + end +end +for i=1:nwell2 + for j=1:9 + Wellc0{i+nwell1,j}=well2{i,j}; + end +end +end + +yitap = 5; % 50-500psi +yitas = 0.04; % 0.05-0.5 +omega = 0.5; % 0-1 +Nmax = 50; +epsave = 1e-6; +epsmax = 1e-6; +dtmin = 0.001; +dtmax =20; +tend = 500; +nwel = size(Wellc0, 1); +WelChg = zeros(nwel, 1);%这表示都开井 +Wellc = calcTrans(r, Wellc0); +w.yitap = yitap; +w.yitas = yitas; +w.omega = omega; +w.Nmax = Nmax; +w.epsave = epsave; +w.epsmax = epsmax; +w.epsave = epsave; +w.epsmax = epsmax; +w.dtmin = dtmin; +w.dtmax = dtmax; +w.tend = tend; +w.WelChg = WelChg; +w.Wellc = Wellc; + +%% 计算 +if modelflag==1 || modelflag==4 + [Times, OutputRs, Wellpara, trun] = mainRS_MB_2014(r, f, os, w, state0); +else +[Times, OutputRs, Wellpara, trun] = mainRS_MB_modified(r, f, os, w, state0); +end +% [Times, OutputRs, Wellpara, trun] = mainRS_MB_modified(r, f, os, w, state0); +run_time=toc; +trun.run_time=run_time; + end + + + diff --git a/post processor/plot functions/plotDis.m b/post processor/plot functions/plotDis.m new file mode 100644 index 0000000..c492aea --- /dev/null +++ b/post processor/plot functions/plotDis.m @@ -0,0 +1,144 @@ +function plotDis(i, r,OutputRs, type) +%为便于作图进行前处理 +figure('color','w') +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dis( r ); +coordinate=r.coordinates; +nodes=r.nodes; +% nmc = size(nodes,1);%基质网格数量 +% % nel = size(nodes,2);%每个基质网格所包含的点数量 +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%用以fill函数作图 +% nel=size(order,2); +if type == 1 + v = OutputRs{i}.p; +elseif type == 2 + v = 1-OutputRs{i}.sw;%含油饱和度 +elseif type == 3 + v = OutputRs{i}.sg;%含油饱和度 +else + v = OutputRs{i}.sw;%含油饱和度 +end +% 底面 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%左面 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%右面 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%前面 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%后面 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%上面 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel('x, m'); +ylabel('y, m'); +zlabel('z, m'); +view(3); +% 绘制油藏框架 +% plotframe( r ); +alpha(1) +% caxis([0.2,0.8]); +caxis([10,13]); +% caxis([12,22]); +colormap jet +colorbar +% zlim([-2020,-2000]); +% axis equal +axis tight + diff --git a/post processor/plot functions/plotDis_3D_to_2D.m b/post processor/plot functions/plotDis_3D_to_2D.m new file mode 100644 index 0000000..79331a4 --- /dev/null +++ b/post processor/plot functions/plotDis_3D_to_2D.m @@ -0,0 +1,46 @@ +function plotDis_3D_to_2D(i, r, OutputRs, type) +coordinate=r.coordinates; +nodes=r.nodes; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +if type == 1 +% v = r.kx; + v = OutputRs{i}.p; +else + v = 1-OutputRs{i}.sw;%含气饱和度 +end +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +for i = 1 :nmc + for j = 1 :nel + x(j, i) = coordinate(nodes(i,j), 1); + y(j, i) = coordinate(nodes(i,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(i,4), 1); + y(j, i) = coordinate(nodes(i,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(i,3), 1); + y(j, i) = coordinate(nodes(i,3), 2); + end + dis(j, i) = v(i); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +% clim([10,15]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/post processor/plot functions/plotDis_ECLIPSE.m b/post processor/plot functions/plotDis_ECLIPSE.m new file mode 100644 index 0000000..8e6d7a5 --- /dev/null +++ b/post processor/plot functions/plotDis_ECLIPSE.m @@ -0,0 +1,129 @@ +function plotDis_ECLIPSE( r,ECLIPSE_data) +%为便于作图进行前处理 +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dis( r ); + +coordinate=r.coordinates; +nodes=r.nodes; +% nmc = size(nodes,1);%基质网格数量 +% % nel = size(nodes,2);%每个基质网格所包含的点数量 +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%用以fill函数作图 +% nel=size(order,2); + v =reshape( ECLIPSE_data',[],1);%含油饱和度 + +% 底面 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3); + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%左面 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3); + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%右面 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3); + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%前面 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3); + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%后面 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3); + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%上面 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3); + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +% 绘制油藏框架 +% plotframe( r ); + + + +% axis equal +axis tight + diff --git a/post processor/plot functions/plotDislayer.asv b/post processor/plot functions/plotDislayer.asv new file mode 100644 index 0000000..ae3bc32 --- /dev/null +++ b/post processor/plot functions/plotDislayer.asv @@ -0,0 +1,147 @@ +function plotDislayer(i, k ,r,OutputRs, type) +%i:鏃堕棿鐐癸紝k鏄粠涓婅嚦涓嬫暟鐨勫眰浣嶏紝type: 1鏄帇鍔涘満 +figure('color','w') +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dislayer( r,k ); +coordinate=r.coordinates; +nodes=r.nodes; +nx=r.nx; +ny=r.ny; +nz=r.nz; +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%鐢ㄤ互fill鍑芥暟浣滃浘 +% % nmc = size(nodes,1);%鍩鸿川缃戞牸鏁伴噺 +% nmc = nx*ny; +% % nel = size(nodes,2);%姣忎釜鍩鸿川缃戞牸鎵鍖呭惈鐨勭偣鏁伴噺 +% nel=size(order,2); +if type == 1 + v = OutputRs{i}.p; +% v = log(r.kx); +elseif type == 2 +% v = 1-OutputRs{i}.sw -OutputRs{i}.sg;%鍚补楗卞拰搴 + v = 1-OutputRs{i}.sw;%鍚补楗卞拰搴 +elseif type == 3 + v = OutputRs{i}.sg;%鍚补楗卞拰搴 +else + v = OutputRs{i}.sw;%鍚补楗卞拰搴 +end +% 搴曢潰 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3); + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%宸﹂潰 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3); + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%鍙抽潰 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3); + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%鍓嶉潰 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3); + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%鍚庨潰 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3); + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%涓婇潰 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3); + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel('x, m'); +ylabel('y, m'); +zlabel('z, m'); +view(2); +% fill(x,y,dis); +axis equal +% axis off +axis tight +colormap jet +% caxis([12,22]); +colorbar +caxis([0.2,0.8]); + diff --git a/post processor/plot functions/plotDislayer.m b/post processor/plot functions/plotDislayer.m new file mode 100644 index 0000000..f5d736c --- /dev/null +++ b/post processor/plot functions/plotDislayer.m @@ -0,0 +1,153 @@ +function plotDislayer(i, k ,r,OutputRs, type) +%i:时间点,k是从上至下数的层位,type: 1是压力场 +figure('color','w') +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dislayer( r,k ); +coordinate=r.coordinates; +nodes=r.nodes; +nx=r.nx; +ny=r.ny; +nz=r.nz; +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%用以fill函数作图 +% % nmc = size(nodes,1);%基质网格数量 +% nmc = nx*ny; +% % nel = size(nodes,2);%每个基质网格所包含的点数量 +% nel=size(order,2); +if type == 1 + v = OutputRs{i}.p; +% v = log(r.kx); +elseif type == 2 +% v = 1-OutputRs{i}.sw -OutputRs{i}.sg;%含油饱和度 + v = 1-OutputRs{i}.sw;%含油饱和度 +elseif type == 3 + v = OutputRs{i}.sg;%含油饱和度 +else + v = OutputRs{i}.sw;%含油饱和度 +end +% 底面 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3); + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%左面 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3); + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%右面 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3); + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%前面 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3); + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%后面 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3); + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%上面 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3); + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel('x, m'); +ylabel('y, m'); +zlabel('z, m'); +view(2); +% fill(x,y,dis); +axis equal +% axis off +axis tight +colormap jet +if type ==1 + caxis([5,22]); +else + caxis([0.2,0.8]); +end +% caxis([12,22]); +% caxis([10,13]); +colorbar +% caxis([0.2,0.8]); + diff --git a/post processor/plot functions/plotDislayer_ECLIPSE.m b/post processor/plot functions/plotDislayer_ECLIPSE.m new file mode 100644 index 0000000..076c15d --- /dev/null +++ b/post processor/plot functions/plotDislayer_ECLIPSE.m @@ -0,0 +1,131 @@ +function plotDislayer_ECLIPSE( k ,r,ECLIPSE_data) +%i:时间点,k是从上至下数的层位,type: 1是压力场 +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dislayer( r,k ); +coordinate=r.coordinates; +nodes=r.nodes; +nx=r.nx; +ny=r.ny; +nz=r.nz; +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%用以fill函数作图 +% % nmc = size(nodes,1);%基质网格数量 +% nmc = nx*ny; +% % nel = size(nodes,2);%每个基质网格所包含的点数量 +% nel=size(order,2); +v =reshape( ECLIPSE_data',[],1);%含油饱和度 +% 底面 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3); + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%左面 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3); + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%右面 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3); + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%前面 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3); + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%后面 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3); + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%上面 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3); + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel('X, m'); +ylabel('Y, m'); +zlabel('Z, m'); +view(2); +% fill(x,y,dis); +axis equal +% axis off +axis tight diff --git a/post processor/plot functions/plot_layer.asv b/post processor/plot functions/plot_layer.asv new file mode 100644 index 0000000..33bf8c4 --- /dev/null +++ b/post processor/plot functions/plot_layer.asv @@ -0,0 +1,48 @@ +function plot_layer(i, k, r, OutputRs, type) +coordinate=r.coordinates; +nodes=r.nodes; +nz=r.nz; +nx=r.nx +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +if type == 1 +% v = r.kx; + v = OutputRs{i}.p; +else + v = 1-OutputRs{i}.sw;%鍚皵楗卞拰搴 +end +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +for i = 1 :nmc + for j = 1 :nel + x(j, i) = coordinate(nodes(i,j), 1); + y(j, i) = coordinate(nodes(i,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(i,4), 1); + y(j, i) = coordinate(nodes(i,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(i,3), 1); + y(j, i) = coordinate(nodes(i,3), 2); + end + dis(j, i) = v(i); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +% clim([10,15]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/post processor/plot functions/plot_layer.m b/post processor/plot functions/plot_layer.m new file mode 100644 index 0000000..f91a485 --- /dev/null +++ b/post processor/plot functions/plot_layer.m @@ -0,0 +1,49 @@ +function plot_layer(i, k, r, OutputRs, type) +coordinate=r.coordinates; +nodes=r.nodes; +nz=r.nz; +nx=r.nx; +ny=r.ny; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +if type == 1 +% v = r.kx; + v = OutputRs{i}.p; +else + v = 1-OutputRs{i}.sw;%含气饱和度 +end +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +for i = 1 :nmc + for j = 1 :nel + x(j, i) = coordinate(nodes(i,j), 1); + y(j, i) = coordinate(nodes(i,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(i,4), 1); + y(j, i) = coordinate(nodes(i,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(i,3), 1); + y(j, i) = coordinate(nodes(i,3), 2); + end + dis(j, i) = v(i+(nz-k)*nx*ny); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +% clim([10,15]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/post processor/plot functions/plot_reservoir_3D.m b/post processor/plot functions/plot_reservoir_3D.m new file mode 100644 index 0000000..840fc76 --- /dev/null +++ b/post processor/plot functions/plot_reservoir_3D.m @@ -0,0 +1,44 @@ +function [ ] = plot_reservoir_3D(dx,dy,dz,nx,ny,nz ) +%UNTITLED 此处显示有关此函数的摘要 +% 此处显示详细说明 +%figure +% 绘制x-y平面 +for i=1:(nz+1) +% if i ==nz+1 +face=[0,0,(i-1)*dz;nx*dx,0,(i-1)*dz;nx*dx,ny*dy,(i-1)*dz;0,ny*dy,(i-1)*dz]; +% fill3(face(:,1),face(:,2),face(:,3),[0.5,0.5,0.5]); +fill3(face(:,1),face(:,2),face(:,3),'w'); +% end + +hold on +end +% [0.5,0.5,0.5] + +% 绘制x-z平面 +for i=1:(ny+1) +% if i == 1 +face=[0,(i-1)*dy,0;nx*dx,(i-1)*dy,0;nx*dx,(i-1)*dy,nz*dz;0,(i-1)*dy,nz*dz]; +% fill3(face(:,1),face(:,2),face(:,3),[0.5,0.5,0.5]); +fill3(face(:,1),face(:,2),face(:,3),'w'); +% end +hold on +end + +% 绘制y-z平面 +for i=1:(nx+1) +% if i == 1 +face=[(i-1)*dx,0,0;(i-1)*dx,ny*dy,0;(i-1)*dx,ny*dy,nz*dz;(i-1)*dx,0,nz*dz;]; +% fill3(face(:,1),face(:,2),face(:,3),[0.5,0.5,0.5]); +fill3(face(:,1),face(:,2),face(:,3),'w'); +% end +hold on +end + +xlabel('x,m'); +ylabel('y,m'); +zlabel('z,m'); +alpha(1); +hold on; +view(3) +end + diff --git a/post processor/plot functions/plotcp.m b/post processor/plot functions/plotcp.m new file mode 100644 index 0000000..aefe722 --- /dev/null +++ b/post processor/plot functions/plotcp.m @@ -0,0 +1,37 @@ +function [ ] = plotcp( Times,Times2,Wellpara,Wellpara2 ) +%PLOTCP 此处显示有关此函数的摘要 +% 此处显示详细说明 +t = Times; +n=size(Times,1); +% para = cell2mat(Wellpara); +nw=1;%选井号 +% n = length(para); +bhp = zeros(n,1); +for i = 1 : n +% bhp(i) = para(i).bhp(2); +bhp(i) = Wellpara{i}{1,nw}.qo; +% bhp(i) = Wellpara{i}{1,nw}.qw; +% bhp(i) = Wellpara{i}{1,nw}.pwf; +end +plot(t,bhp,'r*-'); + +hold on +t = Times2; +n=size(Times2,1); +% para = cell2mat(Wellpara); +nw=1;%选井号 +% n = length(para); +bhp = zeros(n,1); +for i = 1 : n +% bhp(i) = para(i).bhp(2); +% bhp(i) = Wellpara2{i}{1,nw}.qo; +bhp(i) = Wellpara2(i); +% bhp(i) = Wellpara{i}{1,nw}.qw; +% bhp(i) = Wellpara{i}{1,nw}.pwf; +end +plot(t,bhp,'bo-'); + +hold off + +end + diff --git a/post processor/plot functions/plotframe.m b/post processor/plot functions/plotframe.m new file mode 100644 index 0000000..8981a2a --- /dev/null +++ b/post processor/plot functions/plotframe.m @@ -0,0 +1,37 @@ +function [ ] = plotframe( r ) +%PLOTFRAME 此处显示有关此函数的摘要 +% 此处显示详细说明 +xe=1000;ye=500;ze=10; +network3D(xe,ye,ze,1,1,1 ); +% f1=[335,445,0; +% 335,445,10; +% 335,555,10; +% 335,555,0; +% 335,455,0;]; +% plot3(f1(:,1),f1(:,2),f1(:,3)); +% +% f2=[445,445,0; +% 445,445,10; +% 445,555,10; +% 445,555,0 +% 445,445,0;]; +% plot3(f2(:,1),f2(:,2),f2(:,3)); +% +% f3=[555,445,0; +% 555,445,10; +% 555,550,10; +% 555,550,0 +% 555,445,0;]; +% plot3(f3(:,1),f3(:,2),f3(:,3)); +% +% f4=[665,445,0; +% 665,445,10; +% 665,555,10; +% 665,555,0 +% 665,445,0;]; +% plot3(f4(:,1),f4(:,2),f4(:,3)); + +% hold off + +end + diff --git a/post processor/plot functions/plotgraph.m b/post processor/plot functions/plotgraph.m new file mode 100644 index 0000000..0b6e506 --- /dev/null +++ b/post processor/plot functions/plotgraph.m @@ -0,0 +1,63 @@ + +%PLOTGRAPH 此处显示有关此函数的摘要 +% 此处显示详细说明 +% set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +subplot(1,2,1) +plotDislayer_new(15, 1 ,r,OutputRs, 1); +% caxis([10,30]); +title('Layer 1 in the 50th day','FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); + +axis equal +axis tight +% set(gca,'ztick',[0 30]) +% set(gca,'zticklabel',{'0' '30'}) +% xlabel('Layer 1 in the 50th day'); +% subplot(2,2,2) +% plotDislayer_new(15, 2 ,r,OutputRs, 1); +% caxis([10,20]); +% title('Layer 2 in the 50th day','FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +% set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +% axis equal +% axis tight +% set(gca,'ztick',[0 30]) +% set(gca,'zticklabel',{'0' '30'}) +% xlabel('Layer 2 in the 50th day'); +% subplot(2,2,3) +% plotDislayer_new(15, 3 ,r,OutputRs, 1); +% caxis([10,20]); +% title('Layer 3 in the 50th day','FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +% set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +% axis equal +% axis tight +% set(gca,'ztick',[0 30]) +% set(gca,'zticklabel',{'0' '30'}) +% xlabel('Layer 3 in the 50th day'); +subplot(1,2,2) +plotDis_new(15 ,r,OutputRs, 1); +% caxis([10,30]); +% xlabel('3D reservoir in the 50th day'); +title('3D reservoir in the 50th day','FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +axis equal +axis tight +% set(gca,'ztick',[0 30]) +% set(gca,'zticklabel',{'0' '30'}) +% colorbar('SouthOutside'); +colorbar('position',[0.93 0.3 0.03 0.4]); +% subplot(1,2,1) +% plotDislayer_new(9, 1 ,r,OutputRs, 1); +% subplot(1,2,2) +% plotDislayer_new(9, 2 ,r,OutputRs, 1); +% subplot(2,4,5) +% plotDislayer_new(31, 1 ,r,OutputRs, 1); +% subplot(2,4,6) +% plotDislayer_new(31, 2 ,r,OutputRs, 1); +% subplot(2,4,7) +% plotDislayer_new(31, 3 ,r,OutputRs, 1); +% subplot(2,4,8) +% plotDis_new(31 ,r,OutputRs, 1); + + + + diff --git a/post processor/plot functions/plotwell.m b/post processor/plot functions/plotwell.m new file mode 100644 index 0000000..f87460a --- /dev/null +++ b/post processor/plot functions/plotwell.m @@ -0,0 +1,19 @@ +t = Times; +n=size(Times,1); +% para = cell2mat(Wellpara); +nw= 1;%选井号 +% n = length(para); +bhp = zeros(n,1); +for i = 1 : n +% bhp(i) = para(i).bhp(2); +% bhp(i) = Wellpara{i}{1,nw}.pwf; +bhp(i) = Wellpara{i}{1,nw}.qo; +% bhp(i) = Wellpara{i}{1,nw}.pwf; +% bhp(i) = Wellpara{i}{1,nw}.qw/(Wellpara{i}{1,nw}.qw+Wellpara{i}{1,nw}.qo); +end +plot(t,bhp,'b^-') +hold off +% ylim([0,200]); +xlabel('time, day'); +% ylabel('water cut'); +ylabel('oil production rate, m^3/d'); \ No newline at end of file diff --git a/post processor/plot functions/plotwell_set.m b/post processor/plot functions/plotwell_set.m new file mode 100644 index 0000000..1c01228 --- /dev/null +++ b/post processor/plot functions/plotwell_set.m @@ -0,0 +1,130 @@ + +n=size(Times,1); +t = Times; +% para = cell2mat(Wellpara); +total_oil=sum(r.V.*r.pori)*0.85/1.056; +total_water=sum(r.V.*r.pori)*0.15/1.056; + +nw=1;%选井号 +% n = length(para); +Qo = zeros(n,1); +Qw = zeros(n,1); +% Qg = zeros(n,1); +water_content = zeros(n,1); +Pwf = zeros(n,1); +accumu_quan_oil = 0; +% 累计采出量 +accumu_oil = zeros(n,1); +% 采出程度 +proportion_oil = zeros(n,1); +% 平均地层压力 +average_pressure = zeros(n,1); + +for i = 1 : n +Qo(i) = Wellpara{i}{1,nw}.qo; +Qw(i) = Wellpara{i}{1,nw}.qw; +water_content(i) = Qw(i)/(Qo(i)+Qw(i)); +Pwf(i) = Wellpara{i}{1,nw}.pwf; +if i==1 + one_time_oil=Times(i)*Qo(i); + one_time_water=Times(i)*Qw(i); + accumu_oil(i)=one_time_oil; + accumu_water(i)=one_time_water; + else + one_time_oil=(Times(i)-Times(i-1))*Qo(i); + accumu_oil(i)=accumu_oil(i-1)+one_time_oil; + one_time_water=(Times(i)-Times(i-1))*Qw(i); + accumu_water(i)=accumu_water(i-1)+one_time_water; +end +proportion_oil(i)=accumu_oil(i)/total_oil; +proportion_water(i)=accumu_water(i)/total_water; +average_pressure(i)=mean(OutputRs{i,1}.p(1:r.nmc)); +end +%% 绘制前处理 +t=t/1; +%% 绘制日产油量和累积产油量 +% color('w'); +figure('color','w') +% figure(1) +[AX,H1,H2]=plotyy(t,Qo,t,accumu_oil); +% [AX,H1,H2] = plotyy(24,0,0,0,'plot'); +set(AX(1),'XColor','k','YColor','b'); +set(AX(2),'XColor','k','YColor','r'); +set(get(AX(1),'Ylabel'),'String','日产油量/m^3') +set(get(AX(2),'Ylabel'),'String','累积产油量/m^3') +set(H1,'LineStyle','-'); +set(H1,'Marker','o');set(H1,'MarkerSize',4); +set(H1,'color','b'); +set(H2,'LineStyle','-'); +set(H2,'Marker','^');set(H2,'MarkerSize',4); +set(H2,'color','r'); +legend([H1,H2],{'日产油量';'累积产油量'},'Location','Best'); +set(AX(1),'ylim',[0 500]) +% set(AX(2),'ylim',[0 600]) +% set(AX(1),'ytick',50:50:250) +% set(AX(2),'ytick',0:100:600) +% set(AX,'xlim',[0 30]) +% set(AX,'xtick',0:5:30) +% grid on +xlabel('生产时间/年') +% title('日产油量和累积产油量'); +%% 绘制日产水量和累积产水量 +% color('w'); +figure('color','w') +% figure(1) +[AX,H1,H2]=plotyy(t,Qw,t,accumu_water); +% [AX,H1,H2] = plotyy(24,0,0,0,'plot'); +set(AX(1),'XColor','k','YColor','b'); +set(AX(2),'XColor','k','YColor','r'); +set(get(AX(1),'Ylabel'),'String','日产水量/m^3') +set(get(AX(2),'Ylabel'),'String','累积产水量/m^3') +set(H1,'LineStyle','-'); +set(H1,'Marker','o');set(H1,'MarkerSize',4); +set(H1,'color','b'); +set(H2,'LineStyle','-'); +set(H2,'Marker','^');set(H2,'MarkerSize',4); +set(H2,'color','r'); +legend([H1,H2],{'日产水量';'累积产水量'},'Location','Best'); +% set(AX(1),'ylim',[50 250]) +% set(AX(2),'ylim',[0 600]) +% set(AX(1),'ytick',50:50:250) +% set(AX(2),'ytick',0:100:600) +% set(AX,'xlim',[0 30]) +% set(AX,'xtick',0:5:30) +% grid on +xlabel('生产时间/年') +% title('日产水量和累积产水量'); +%% 绘制平均地层压力和采出程度 +% color('w'); +figure('color','w') +% figure(1) +[AX,H1,H2]=plotyy(t,average_pressure,t,proportion_oil*100); +% [AX,H1,H2] = plotyy(24,0,0,0,'plot'); +set(AX(1),'XColor','k','YColor','b'); +set(AX(2),'XColor','k','YColor','r'); +set(get(AX(1),'Ylabel'),'String','平均地层压力/MPa') +set(get(AX(2),'Ylabel'),'String','采出程度/%') +set(H1,'LineStyle','-'); +set(H1,'Marker','o');set(H1,'MarkerSize',4); +set(H1,'color','b'); +set(H2,'LineStyle','-'); +set(H2,'Marker','^');set(H2,'MarkerSize',4); +set(H2,'color','r'); +legend([H1,H2],{'平均地层压力';'采出程度'},'Location','Best'); +% set(AX(1),'ylim',[50 250]) +% set(AX(2),'ylim',[0 600]) +% set(AX(1),'ytick',50:50:250) +% set(AX(2),'ytick',0:100:600) +% set(AX,'xlim',[0 30]) +% set(AX,'xtick',0:5:30) +% grid on +xlabel('生产时间/天') +% title('日产油量和累积产油量'); +%% 绘制含水率 +figure('color','w') +plot(t,water_content); +set(get(gca,'Xlabel'),'String','生产时间/天') +xlabel('生产时间/天') +ylabel('含水率') +% hold on +% plot(ECLIPSE(:,1),ECLIPSE(:,2),'B'); \ No newline at end of file diff --git a/post processor/plot functions/refine.m b/post processor/plot functions/refine.m new file mode 100644 index 0000000..b6db513 --- /dev/null +++ b/post processor/plot functions/refine.m @@ -0,0 +1,64 @@ +% network3D(2060,1580,10,1,1,3 ); +%REFINE 此处显示有关此函数的摘要 +% 此处显示详细说明 +% % % well=cell(4,1); +% % % load('perforation1.mat');welloc1 = [perforation1, 7.5*ones(size(perforation1,1),1)]; +% % % load('perforation2.mat');welloc2 = [perforation2, 7.5*ones(size(perforation2,1),1)]; +% % % load('perforation3.mat');welloc3 = [perforation3, 7.5*ones(size(perforation3,1),1)]; +% % % load('perforation4.mat');welloc4 = [perforation4, 7.5*ones(size(perforation4,1),1)]; +% % % well{1,1} = welloc1; +% % % well{2,1} = welloc2; +% % % well{3,1} = welloc3; +% % % well{4,1} = welloc4; +% % % +% % % for i=1:4 +% % % line(well{i,1}(:,1)',well{i,1}(:,2)',well{i,1}(:,3)','color','k','LineWidth',2); +% % % hold on +% % % end + +% load('injectionWellsCoord.mat') +% injectionWellsCoord = [45,45; +% 655,45; +% 45,625; +% 655,625;]; +% for i=1:size(injectionWellsCoord,1) +% line(injectionWellsCoord(i,1)*ones(2,1),injectionWellsCoord(i,2)*ones(2,1),[0;20],'color','k','LineWidth',2); +% hold on +% text(injectionWellsCoord(i,1),injectionWellsCoord(i,2),20,'注水井','FontSize',12,'FontWeight','bold'); +% hold on +% end + +% wellbore +% wellbore = [250+100,100+100,46; +% 550+100,100+1700,46]; +% % wellbore = [50,352,10; +% % 950,352,10;]; +% plot3(wellbore(:,1),wellbore(:,2),wellbore(:,3),'color','k','LineWidth',2.5); + +% wellbore = [450,520,10; +% 450,1420,10;]; +% % wellbore = [50,352,10; +% % 950,352,10;]; +% plot3(wellbore(:,1),wellbore(:,2),wellbore(:,3),'color','k','LineWidth',2.5); +hold on +% wellbore = [1175,370,10; +% 1175,1170,10;]; +% % wellbore = [50,352,10; +% % 950,352,10;]; +% plot3(wellbore(:,1),wellbore(:,2),wellbore(:,3),'color','k','LineWidth',2.5); +% text(wellbore(1,1),wellbore(1,2),10,'压裂水平井','FontSize',12,'FontWeight','bold'); +hold on +% hwell=cell(1,1); +% hwell{1,1}=[385,1300,15; +% 385,400,15;]; +% hwell{2,1}=[955,1330,15; +% 955,330,15;]; +% hwell{3,1}=[1635,1275,15; +% 1635,580,15;]; +% for i=1:3 +% line(hwell{i,1}(:,1)',hwell{i,1}(:,2)',hwell{i,1}(:,3)','color','k'); +% hold on +% end + + + diff --git a/post processor/plotWellResponse.m b/post processor/plotWellResponse.m new file mode 100644 index 0000000..b3bcc97 --- /dev/null +++ b/post processor/plotWellResponse.m @@ -0,0 +1,55 @@ +function [] = plotWellResponse(Times,Wellpara) +% 输入 +wellNumber = 1; % 井号 +dataType = 'dPWF'; % 类型,产气速度 GPR,产气速度 OPR, 产水速度 WPR,井底流压 BHP,压力导数 dPWF +% +t = Times; +n= size(Times,1); +% para = cell2mat(Wellpara); +nw = wellNumber;%选井号 +% n = length(para); +data = zeros(n,1); +if strcmp(dataType, 'GPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qg; + figureYlegend = 'Gas production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'OPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qo; + figureYlegend = 'Oil production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'WPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qw; + figureYlegend = 'Water production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'BHP') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.pwf; + figureYlegend = 'BHP, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'dPWF') % dpwf/dlnt = t*dpwf/dt + for i = 1 : n + if i == 1 + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i}{1,nw}.pwf)/(log(t(i+1))-log(t(i))); + elseif i == n + data(i) = (Wellpara{i}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i))-log(t(i-1))); + else + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i+1))-log(t(i-1))); + end + figureYlegend = 'Pressure derivative, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); + set(gca, 'XScale', 'log'); + set(gca, 'YScale', 'log'); +end +end \ No newline at end of file diff --git a/post processor/plot_2D_layer.m b/post processor/plot_2D_layer.m new file mode 100644 index 0000000..0d45394 --- /dev/null +++ b/post processor/plot_2D_layer.m @@ -0,0 +1,50 @@ +function plot_2D_layer(i, k, r, OutputRs, type) +coordinate=r.coordinates; +nodes=r.nodes; +nz=r.nz; +nx=r.nx; +ny=r.ny; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +if type == 1 +% v = r.kx; + v = OutputRs{i}.p; +else + v = 1-OutputRs{i}.sw;%含气饱和度 +end +dis = zeros(nel, nx*ny); +x = zeros(nel, nx*ny); +y = zeros(nel, nx*ny); +for i = 1 :nx*ny + for j = 1 :nel + grid_numbering = i+(nz-k)*nx*ny; + x(j, i) = coordinate(nodes(grid_numbering,j), 1); + y(j, i) = coordinate(nodes(grid_numbering,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(grid_numbering,4), 1); + y(j, i) = coordinate(nodes(grid_numbering,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(grid_numbering,3), 1); + y(j, i) = coordinate(nodes(grid_numbering,3), 2); + end + dis(j, i) = v(grid_numbering); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +% clim([10,15]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/post processor/plot_3D.m b/post processor/plot_3D.m new file mode 100644 index 0000000..05ac1b2 --- /dev/null +++ b/post processor/plot_3D.m @@ -0,0 +1,70 @@ +% 涓荤▼搴忕ず渚 +clear; clc; close all; + +% 璁剧疆缃戞牸鍙傛暟 +nx = 20; +ny = 15; +nz = 10; + +% 鐢熸垚闈炲潎鍖缃戞牸灏哄 +dx = linspace(0.5, 1.5, nx)'; % x鏂瑰悜缃戞牸灏哄浠0.5鍒1.5鍙樺寲 +dy = linspace(0.8, 1.2, ny)'; % y鏂瑰悜缃戞牸灏哄浠0.8鍒1.2鍙樺寲 +dz = ones(nz, 1) * 1.0; % z鏂瑰悜鍧囧寑缃戞牸 + +% 鐢熸垚绀轰緥鏁版嵁锛堜緥濡傦細涓夌淮楂樻柉鍒嗗竷锛 +x_center = sum(dx)/2; % 涓績浣嶇疆 +y_center = sum(dy)/2; +z_center = sum(dz)/2; + +% 璁$畻姣忎釜缃戞牸鐐圭殑鍧愭爣 +x_pos = zeros(nx, 1); +x_pos(1) = dx(1)/2; +for i = 2:nx + x_pos(i) = x_pos(i-1) + (dx(i-1) + dx(i))/2; +end + +y_pos = zeros(ny, 1); +y_pos(1) = dy(1)/2; +for i = 2:ny + y_pos(i) = y_pos(i-1) + (dy(i-1) + dy(i))/2; +end + +z_pos = zeros(nz, 1); +z_pos(1) = dz(1)/2; +for i = 2:nz + z_pos(i) = z_pos(i-1) + (dz(i-1) + dz(i))/2; +end + +% 鍒涘缓缃戞牸鍧愭爣 +[X, Y, Z] = ndgrid(x_pos, y_pos, z_pos); + +% 鐢熸垚绀轰緥鐗╃悊閲忔暟鎹紙涓夌淮楂樻柉鍒嗗竷锛 +sigma_x = max(x_pos)/3; +sigma_y = max(y_pos)/3; +sigma_z = max(z_pos)/3; +data = exp(-((X - x_center).^2/(2*sigma_x^2) + ... + (Y - y_center).^2/(2*sigma_y^2) + ... + (Z - z_center).^2/(2*sigma_z^2))); + +% 缁樺埗涓嶅悓绫诲瀷鐨勫浘 +% plot_3d_grid_data_slice(nx, ny, nz, dx, dy, dz, data); +% plot_3d_grid_data_scatter(nx, ny, nz, dx, dy, dz, data); +% plot_3d_grid_data_volume(nx, ny, nz, dx, dy, dz, data); +% 鏂规硶1锛氬熀鏈綋绱犲浘 +fprintf('缁樺埗鏂规硶1锛氬熀鏈綋绱犲浘...\n'); +plot_3d_grid_voxel_full(nx, ny, nz, dx, dy, dz, data); +title('鏂规硶1锛氬熀鏈綋绱犲浘 - 楂樻柉鍒嗗竷'); + +% 鏂规硶2锛氫紭鍖栫増鏈 +fprintf('缁樺埗鏂规硶2锛氫紭鍖栫増鏈...\n'); +plot_3d_grid_patch_optimized(nx, ny, nz, dx, dy, dz, data); +title('鏂规硶2锛氫紭鍖栫増鏈 - 鐞冨3鍒嗗竷'); + +% 鏂规硶3锛氫綋绱犲嚱鏁版硶 +fprintf('缁樺埗鏂规硶3锛氫綋绱犲嚱鏁版硶...\n'); +plot_3d_grid_voxel_function(nx, ny, nz, dx, dy, dz, data); +title('鏂规硶3锛氫綋绱犲嚱鏁版硶 - 娉㈢汗鍒嗗竷'); + +% 鏂规硶4锛氬崐閫忔槑鏁堟灉 +fprintf('缁樺埗鏂规硶4锛氬崐閫忔槑鏁堟灉...\n'); +plot_3d_grid_transparent(nx, ny, nz, dx, dy, dz, data); \ No newline at end of file diff --git a/post processor/plot_3D_dis.m b/post processor/plot_3D_dis.m new file mode 100644 index 0000000..6674f45 --- /dev/null +++ b/post processor/plot_3D_dis.m @@ -0,0 +1,144 @@ +function plot_3D_dis(i, r,OutputRs, type) +%为便于作图进行前处理 +figure('color','w') +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dis( r ); +coordinate=r.coordinates; +nodes=r.nodes; +% nmc = size(nodes,1);%基质网格数量 +% % nel = size(nodes,2);%每个基质网格所包含的点数量 +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%用以fill函数作图 +% nel=size(order,2); +if type == 1 + v = OutputRs{i}.p; +elseif type == 2 + v = 1-OutputRs{i}.sw;%含油饱和度 +elseif type == 3 + v = OutputRs{i}.sg;%含油饱和度 +else + v = OutputRs{i}.sw;%含油饱和度 +end +% 底面 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%左面 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%右面 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%前面 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%后面 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%上面 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel('x, m'); +ylabel('y, m'); +zlabel('z, m'); +view(3); +% 绘制油藏框架 +% plotframe( r ); +alpha(1) +% caxis([0.2,0.8]); +caxis([10,13]); +% caxis([12,22]); +colormap jet +colorbar +% zlim([-2020,-2000]); +% axis equal +axis tight + diff --git a/post processor/plot_3d_grid_data_scatter.m b/post processor/plot_3d_grid_data_scatter.m new file mode 100644 index 0000000..ba40397 --- /dev/null +++ b/post processor/plot_3d_grid_data_scatter.m @@ -0,0 +1,54 @@ +function plot_3d_grid_data_scatter(nx, ny, nz, dx, dy, dz, data) +% 缁樺埗涓夌淮缃戞牸鏁版嵁鐨勭偣浜戝浘 +% 杈撳叆鍙傛暟锛 +% nx, ny, nz - 鍚勬柟鍚戠殑缃戞牸鏁 +% dx, dy, dz - 鍚勬柟鍚戠殑缃戞牸灏哄鍚戦噺 +% data - 鐗╃悊閲忔暟鎹紝缁村害涓(nx, ny, nz) + +% 璁$畻姣忎釜缃戞牸鐐圭殑鍧愭爣浣嶇疆 +x = zeros(1, nx); +x(1) = dx(1)/2; +for i = 2:nx + x(i) = x(i-1) + (dx(i-1) + dx(i))/2; +end + +y = zeros(1, ny); +y(1) = dy(1)/2; +for i = 2:ny + y(i) = y(i-1) + (dy(i-1) + dy(i))/2; +end + +z = zeros(1, nz); +z(1) = dz(1)/2; +for i = 2:nz + z(i) = z(i-1) + (dz(i-1) + dz(i))/2; +end + +% 鍒涘缓鎵鏈夌綉鏍肩偣鐨勫潗鏍囩煩闃 +[X, Y, Z] = ndgrid(x, y, z); +% data宸茬粡鏄(nx, ny, nz)鏍煎紡锛屼笌ndgrid杈撳嚭鍖归厤 + +% 灏嗘暟鎹睍骞崇敤浜巗catter3 +X_flat = X(:); +Y_flat = Y(:); +Z_flat = Z(:); +data_flat = data(:); + +% 鍒涘缓鏂板浘褰 +figure('Position', [100, 100, 800, 600]); + +% 浣跨敤scatter3缁樺埗鐐逛簯鍥 +scatter3(X_flat, Y_flat, Z_flat, 20, data_flat, 'filled'); +colorbar; +colormap('jet'); +xlabel('X'); +ylabel('Y'); +zlabel('Z'); +title('涓夌淮缃戞牸鐗╃悊閲忓垎甯冿紙鐐逛簯鍥撅級'); +axis equal; +view(3); +grid on; + +% 娣诲姞閫忔槑搴﹁缃紙鍙夛紝鐢ㄤ簬鏄剧ず鍐呴儴鐐癸級 +alpha(0.8); +end \ No newline at end of file diff --git a/post processor/plot_3d_grid_data_slice.m b/post processor/plot_3d_grid_data_slice.m new file mode 100644 index 0000000..164b596 --- /dev/null +++ b/post processor/plot_3d_grid_data_slice.m @@ -0,0 +1,52 @@ +function plot_3d_grid_data_slice(nx, ny, nz, dx, dy, dz, data) +% 缁樺埗涓夌淮缃戞牸鏁版嵁鐨勫垏鐗囧浘 +% 杈撳叆鍙傛暟锛 +% nx, ny, nz - 鍚勬柟鍚戠殑缃戞牸鏁 +% dx, dy, dz - 鍚勬柟鍚戠殑缃戞牸灏哄鍚戦噺 +% data - 鐗╃悊閲忔暟鎹紝缁村害涓(nx, ny, nz) + +% 璁$畻姣忎釜缃戞牸鐐圭殑鍧愭爣浣嶇疆锛堝彇缃戞牸涓績鐐癸級 +x = zeros(1, nx); +x(1) = dx(1)/2; +for i = 2:nx + x(i) = x(i-1) + (dx(i-1) + dx(i))/2; +end + +y = zeros(1, ny); +y(1) = dy(1)/2; +for i = 2:ny + y(i) = y(i-1) + (dy(i-1) + dy(i))/2; +end + +z = zeros(1, nz); +z(1) = dz(1)/2; +for i = 2:nz + z(i) = z(i-1) + (dz(i-1) + dz(i))/2; +end + +% 鍒涘缓涓夌淮缃戞牸 +[X, Y, Z] = meshgrid(x, y, z); +% 娉ㄦ剰锛歮eshgrid鐢熸垚鐨勬暟缁勭淮搴﹂『搴忎负(ny, nx, nz) +% 濡傛灉data鏄(nx, ny, nz)锛岄渶瑕佽浆缃 +data_plot = permute(data, [2, 1, 3]); + +% 鍒涘缓鏂板浘褰 +figure('Position', [100, 100, 800, 600]); + +% 浣跨敤slice缁樺埗涓変釜姝d氦鍒囬潰 +xslice = [x(round(nx/4)), x(round(nx/2)), x(round(3*nx/4))]; +yslice = [y(round(ny/4)), y(round(ny/2)), y(round(3*ny/4))]; +zslice = [z(round(nz/4)), z(round(nz/2)), z(round(3*nz/4))]; + +slice(X, Y, Z, data_plot, xslice, yslice, zslice); +shading interp; +colorbar; +colormap('jet'); +xlabel('X'); +ylabel('Y'); +zlabel('Z'); +title('涓夌淮缃戞牸鐗╃悊閲忓垎甯冿紙鍒囩墖鍥撅級'); +axis equal; +view(3); +grid on; +end \ No newline at end of file diff --git a/post processor/plot_3d_grid_data_volume.m b/post processor/plot_3d_grid_data_volume.m new file mode 100644 index 0000000..14388a0 --- /dev/null +++ b/post processor/plot_3d_grid_data_volume.m @@ -0,0 +1,66 @@ +function plot_3d_grid_data_volume(nx, ny, nz, dx, dy, dz, data) +% 缁樺埗涓夌淮缃戞牸鏁版嵁鐨勪綋缁樺埗鍥 +% 杈撳叆鍙傛暟锛 +% nx, ny, nz - 鍚勬柟鍚戠殑缃戞牸鏁 +% dx, dy, dz - 鍚勬柟鍚戠殑缃戞牸灏哄鍚戦噺 +% data - 鐗╃悊閲忔暟鎹紝缁村害涓(nx, ny, nz) + +% 璁$畻姣忎釜缃戞牸鐐圭殑鍧愭爣浣嶇疆 +x = zeros(1, nx); +x(1) = dx(1)/2; +for i = 2:nx + x(i) = x(i-1) + (dx(i-1) + dx(i))/2; +end + +y = zeros(1, ny); +y(1) = dy(1)/2; +for i = 2:ny + y(i) = y(i-1) + (dy(i-1) + dy(i))/2; +end + +z = zeros(1, nz); +z(1) = dz(1)/2; +for i = 2:nz + z(i) = z(i-1) + (dz(i-1) + dz(i))/2; +end + +% 鍒涘缓涓夌淮缃戞牸 +[X, Y, Z] = meshgrid(x, y, z); +% 璋冩暣data缁村害 +data_plot = permute(data, [2, 1, 3]); + +% 鍒涘缓鏂板浘褰 +figure('Position', [100, 100, 900, 700]); + +% 鏂规硶1锛氫娇鐢╲ol3d v2锛堝鏋滃畨瑁呬簡File Exchange鐨剉ol3d宸ュ叿锛 +% 濡傛灉娌℃湁瀹夎锛屽彲浠ヤ娇鐢ㄤ互涓嬪熀鏈綋缁樺埗 + +% 鍒涘缓澶氫釜绛夊奸潰 +levels = linspace(min(data(:)), max(data(:)), 5); +for i = 2:length(levels)-1 + p = patch(isosurface(X, Y, Z, data_plot, levels(i))); + isonormals(X, Y, Z, data_plot, p); + set(p, 'FaceColor', 'interp', 'EdgeColor', 'none'); + + % 鏍规嵁鏁版嵁鍊艰缃鑹 + cdata = get(p, 'FaceVertexCData'); + set(p, 'FaceVertexCData', cdata); +end + +% 娣诲姞涓浜涘垏鐗囨潵鏄剧ず鍐呴儴缁撴瀯 +hold on; +h = slice(X, Y, Z, data_plot, x(round(nx/2)), y(round(ny/2)), z(round(nz/2))); +set(h, 'FaceAlpha', 0.6, 'EdgeColor', 'none'); + +colorbar; +colormap('jet'); +xlabel('X'); +ylabel('Y'); +zlabel('Z'); +title('涓夌淮缃戞牸鐗╃悊閲忓垎甯冿紙浣撶粯鍒讹級'); +axis equal; +view(3); +grid on; +camlight; +lighting gouraud; +end \ No newline at end of file diff --git a/post processor/plot_3d_grid_patch_optimized.m b/post processor/plot_3d_grid_patch_optimized.m new file mode 100644 index 0000000..eba5c39 --- /dev/null +++ b/post processor/plot_3d_grid_patch_optimized.m @@ -0,0 +1,128 @@ +function plot_3d_grid_patch_optimized(nx, ny, nz, dx, dy, dz, data) +% 浣跨敤patch涓娆℃х粯鍒舵墍鏈夌綉鏍硷紙浼樺寲鐗堟湰锛 +% 杈撳叆鍙傛暟锛 +% nx, ny, nz - 鍚勬柟鍚戠殑缃戞牸鏁 +% dx, dy, dz - 鍚勬柟鍚戠殑缃戞牸灏哄鍚戦噺 +% data - 鐗╃悊閲忔暟鎹紝缁村害涓(nx, ny, nz) + +% 璁$畻姣忎釜缃戞牸鐨勮竟鐣屽潗鏍 +x_edges = zeros(nx+1, 1); +x_edges(1) = 0; +for i = 1:nx + x_edges(i+1) = x_edges(i) + dx(i); +end + +y_edges = zeros(ny+1, 1); +y_edges(1) = 0; +for i = 1:ny + y_edges(i+1) = y_edges(i) + dy(i); +end + +z_edges = zeros(nz+1, 1); +z_edges(1) = 0; +for i = 1:nz + z_edges(i+1) = z_edges(i) + dz(i); +end + +% 鍒涘缓缃戞牸椤剁偣鍧愭爣 +[X_edges, Y_edges, Z_edges] = ndgrid(x_edges, y_edges, z_edges); + +% 閲嶆柊鎺掑垪椤剁偣 +vertices = [X_edges(:), Y_edges(:), Z_edges(:)]; + +% 鍒涘缓姣忎釜浣撶礌鐨8涓《鐐圭储寮 +n_cells = nx * ny * nz; +faces = zeros(n_cells * 6, 4); % 姣忎釜浣撶礌6涓潰锛屾瘡涓潰4涓《鐐 +face_colors = zeros(n_cells * 6, 1); + +% 椤剁偣缂栧彿鏂瑰紡锛氭寜鐓(i,j,k)椤哄簭 +% 姣忎釜浣撶礌鐨8涓《鐐圭储寮 +% v1: (i,j,k) +% v2: (i+1,j,k) +% v3: (i+1,j+1,k) +% v4: (i,j+1,k) +% v5: (i,j,k+1) +% v6: (i+1,j,k+1) +% v7: (i+1,j+1,k+1) +% v8: (i,j+1,k+1) + +face_idx = 1; +for i = 1:nx + for j = 1:ny + for k = 1:nz + % 璁$畻褰撳墠浣撶礌鐨8涓《鐐圭储寮 + idx = @(ii, jj, kk) (ii-1)*(ny+1)*(nz+1) + (jj-1)*(nz+1) + kk; + + v1 = idx(i, j, k); + v2 = idx(i+1, j, k); + v3 = idx(i+1, j+1, k); + v4 = idx(i, j+1, k); + v5 = idx(i, j, k+1); + v6 = idx(i+1, j, k+1); + v7 = idx(i+1, j+1, k+1); + v8 = idx(i, j+1, k+1); + + % 褰撳墠浣撶礌鐨勫 + cell_value = data(i, j, k); + + % 搴曢潰 (k灞) + faces(face_idx, :) = [v1, v2, v3, v4]; + face_colors(face_idx) = cell_value; + face_idx = face_idx + 1; + + % 椤堕潰 (k+1灞) + faces(face_idx, :) = [v5, v6, v7, v8]; + face_colors(face_idx) = cell_value; + face_idx = face_idx + 1; + + % 鍓嶉潰 (j灞) + faces(face_idx, :) = [v1, v2, v6, v5]; + face_colors(face_idx) = cell_value; + face_idx = face_idx + 1; + + % 鍚庨潰 (j+1灞) + faces(face_idx, :) = [v4, v3, v7, v8]; + face_colors(face_idx) = cell_value; + face_idx = face_idx + 1; + + % 宸﹂潰 (i灞) + faces(face_idx, :) = [v1, v4, v8, v5]; + face_colors(face_idx) = cell_value; + face_idx = face_idx + 1; + + % 鍙抽潰 (i+1灞) + faces(face_idx, :) = [v2, v3, v7, v6]; + face_colors(face_idx) = cell_value; + face_idx = face_idx + 1; + end + end +end + +% 鍒涘缓鍥惧舰 +figure('Position', [100, 100, 1000, 800]); + +% 缁樺埗鎵鏈夐潰 +patch('Vertices', vertices, 'Faces', faces, ... + 'FaceVertexCData', face_colors, ... + 'FaceColor', 'flat', ... + 'CDataMapping', 'scaled', ... + 'EdgeColor', 'none', ... + 'FaceAlpha', 0.9); + +% 璁剧疆灞炴 +colorbar; +colormap jet; +xlabel('X'); +ylabel('Y'); +zlabel('Z'); +title('涓夌淮绗涘崱灏旂綉鏍煎叏鍏呮弧鐗╃悊閲忓垎甯冿紙浼樺寲鐗堬級'); +axis equal; +view(3); +grid on; +box on; + +% 鍏夌収璁剧疆 +lighting gouraud; +light('Position', [1 1 1], 'Style', 'infinite'); +light('Position', [-1 -1 -1], 'Style', 'infinite'); +end \ No newline at end of file diff --git a/post processor/plot_3d_grid_transparent.m b/post processor/plot_3d_grid_transparent.m new file mode 100644 index 0000000..24256cb --- /dev/null +++ b/post processor/plot_3d_grid_transparent.m @@ -0,0 +1,105 @@ +function plot_3d_grid_transparent(nx, ny, nz, dx, dy, dz, data) +% 缁樺埗鍗婇忔槑鏁堟灉鐨勪笁缁寸綉鏍 +% 杈撳叆鍙傛暟锛 +% nx, ny, nz - 鍚勬柟鍚戠殑缃戞牸鏁 +% dx, dy, dz - 鍚勬柟鍚戠殑缃戞牸灏哄鍚戦噺 +% data - 鐗╃悊閲忔暟鎹紝缁村害涓(nx, ny, nz) + +% 璁$畻姣忎釜缃戞牸鐨勮竟鐣屽潗鏍 +x_edges = zeros(nx+1, 1); +x_edges(1) = 0; +for i = 1:nx + x_edges(i+1) = x_edges(i) + dx(i); +end + +y_edges = zeros(ny+1, 1); +y_edges(1) = 0; +for i = 1:ny + y_edges(i+1) = y_edges(i) + dy(i); +end + +z_edges = zeros(nz+1, 1); +z_edges(1) = 0; +for i = 1:nz + z_edges(i+1) = z_edges(i) + dz(i); +end + +% 鍒涘缓鍥惧舰 +figure('Position', [100, 100, 1000, 800]); +hold on; + +% 璁剧疆棰滆壊鏄犲皠 +colormap jet; +caxis([min(data(:)), max(data(:))]); + +% 鏍规嵁鐗╃悊閲忓艰缃忔槑搴 +% 鍊艰秺澶ц秺涓嶉忔槑锛屽艰秺灏忚秺閫忔槑 +data_min = min(data(:)); +data_max = max(data(:)); +data_range = data_max - data_min; + +for i = 1:nx + for j = 1:ny + for k = 1:nz + % 鑾峰彇褰撳墠浣撶礌鐨勮竟鐣 + x_min = x_edges(i); + x_max = x_edges(i+1); + y_min = y_edges(j); + y_max = y_edges(j+1); + z_min = z_edges(k); + z_max = z_edges(k+1); + + % 鑾峰彇褰撳墠浣撶礌鐨勭墿鐞嗛噺鍊 + value = data(i, j, k); + + % 鏍规嵁鍊艰缃忔槑搴︼紙鍊艰秺澶ц秺涓嶉忔槑锛 + % alpha_val = 0.3 + 0.6 * (value - data_min) / data_range; + alpha_val = 1; + + % 鍒涘缓浣撶礌鐨8涓《鐐 + vertices = [x_min, y_min, z_min; + x_max, y_min, z_min; + x_max, y_max, z_min; + x_min, y_max, z_min; + x_min, y_min, z_max; + x_max, y_min, z_max; + x_max, y_max, z_max; + x_min, y_max, z_max]; + + % 鍒涘缓6涓潰鐨勯《鐐圭储寮 + faces = [1 2 3 4; % 搴曢潰 + 5 6 7 8; % 椤堕潰 + 1 2 6 5; % 鍓嶉潰 + 2 3 7 6; % 鍙抽潰 + 3 4 8 7; % 鍚庨潰 + 4 1 5 8]; % 宸﹂潰 + + % 缁樺埗浣撶礌 + patch('Vertices', vertices, 'Faces', faces, ... + 'FaceColor', 'flat', ... + 'FaceVertexCData', value, ... + 'CDataMapping', 'scaled', ... + 'FaceAlpha', alpha_val, ... + 'EdgeColor', 'none'); + end + end +end + +% 璁剧疆鍥惧舰灞炴 +colorbar; +xlabel('X'); +ylabel('Y'); +zlabel('Z'); +title('涓夌淮绗涘崱灏旂綉鏍煎叏鍏呮弧鐗╃悊閲忓垎甯冿紙閫忔槑搴︿笌鏁板肩浉鍏筹級'); +axis equal; +view(3); +grid on; +box on; + +% 鍏夌収璁剧疆 +lighting gouraud; +light('Position', [1 1 1], 'Style', 'infinite'); +light('Position', [-1 -1 -1], 'Style', 'infinite'); + +hold off; +end \ No newline at end of file diff --git a/post processor/plot_3d_grid_voxel_full.m b/post processor/plot_3d_grid_voxel_full.m new file mode 100644 index 0000000..b85b56a --- /dev/null +++ b/post processor/plot_3d_grid_voxel_full.m @@ -0,0 +1,99 @@ +function plot_3d_grid_voxel_full(nx, ny, nz, dx, dy, dz, data) +% 缁樺埗涓夌淮绗涘崱灏旂綉鏍煎叏鍏呮弧鐨勪綋绱犲浘锛堟瘡涓綉鏍煎崟涓棰滆壊锛 +% 杈撳叆鍙傛暟锛 +% nx, ny, nz - 鍚勬柟鍚戠殑缃戞牸鏁 +% dx, dy, dz - 鍚勬柟鍚戠殑缃戞牸灏哄鍚戦噺 +% data - 鐗╃悊閲忔暟鎹紝缁村害涓(nx, ny, nz) + +% 璁$畻姣忎釜缃戞牸鐨勮竟鐣屽潗鏍 +x_edges = zeros(nx+1, 1); +x_edges(1) = 0; +for i = 1:nx + x_edges(i+1) = x_edges(i) + dx(i); +end + +y_edges = zeros(ny+1, 1); +y_edges(1) = 0; +for i = 1:ny + y_edges(i+1) = y_edges(i) + dy(i); +end + +z_edges = zeros(nz+1, 1); +z_edges(1) = 0; +for i = 1:nz + z_edges(i+1) = z_edges(i) + dz(i); +end + +% 鍒涘缓鍥惧舰绐楀彛 +figure('Position', [100, 100, 1000, 800]); +hold on; + +% 璁剧疆棰滆壊鏄犲皠 +colormap jet; +caxis([min(data(:)), max(data(:))]); + +% 缁樺埗姣忎釜浣撶礌 +alpha_value = 0.9; % 閫忔槑搴 + +for i = 1:nx + for j = 1:ny + for k = 1:nz + % 鑾峰彇褰撳墠浣撶礌鐨勮竟鐣 + x_min = x_edges(i); + x_max = x_edges(i+1); + y_min = y_edges(j); + y_max = y_edges(j+1); + z_min = z_edges(k); + z_max = z_edges(k+1); + + % 鑾峰彇褰撳墠浣撶礌鐨勭墿鐞嗛噺鍊 + value = data(i, j, k); + + % 鍒涘缓浣撶礌鐨8涓《鐐 + vertices = [x_min, y_min, z_min; + x_max, y_min, z_min; + x_max, y_max, z_min; + x_min, y_max, z_min; + x_min, y_min, z_max; + x_max, y_min, z_max; + x_max, y_max, z_max; + x_min, y_max, z_max]; + + % 鍒涘缓6涓潰鐨勯《鐐圭储寮 + faces = [1 2 3 4; % 搴曢潰 + 5 6 7 8; % 椤堕潰 + 1 2 6 5; % 鍓嶉潰 + 2 3 7 6; % 鍙抽潰 + 3 4 8 7; % 鍚庨潰 + 4 1 5 8]; % 宸﹂潰 + + % 鍏抽敭淇敼锛氫娇鐢 'flat' 纭繚姣忎釜闈㈠崟涓棰滆壊 + % 骞朵笖涓烘瘡涓潰鎸囧畾鐩稿悓鐨勯鑹插 + patch('Vertices', vertices, 'Faces', faces, ... + 'FaceColor', 'flat', ... % 'flat' 纭繚姣忎釜闈㈠崟涓棰滆壊 + 'FaceVertexCData', value * ones(size(faces, 1), 1), ... % 鎵鏈夐潰浣跨敤鐩稿悓棰滆壊鍊 + 'CDataMapping', 'scaled', ... + 'FaceAlpha', alpha_value, ... + 'EdgeColor', 'none'); + end + end +end + +% 璁剧疆鍥惧舰灞炴 +colorbar; +xlabel('X'); +ylabel('Y'); +zlabel('Z'); +title('涓夌淮绗涘崱灏旂綉鏍煎叏鍏呮弧鐗╃悊閲忓垎甯冿紙姣忎釜缃戞牸鍗曚竴棰滆壊锛'); +axis equal; +view(3); +grid on; +box on; + +% 璁剧疆鍏夌収 +lighting gouraud; +light('Position', [1 1 1], 'Style', 'infinite'); +light('Position', [-1 -1 -1], 'Style', 'infinite'); + +hold off; +end \ No newline at end of file diff --git a/post processor/plot_3d_grid_voxel_function.m b/post processor/plot_3d_grid_voxel_function.m new file mode 100644 index 0000000..3cbaac7 --- /dev/null +++ b/post processor/plot_3d_grid_voxel_function.m @@ -0,0 +1,105 @@ +function plot_3d_grid_voxel_function_fixed(nx, ny, nz, dx, dy, dz, data) +% 浣跨敤鑷畾涔塿oxel鍑芥暟缁樺埗涓夌淮缃戞牸锛堟瘡涓綉鏍煎崟涓棰滆壊锛 +% 杈撳叆鍙傛暟锛 +% nx, ny, nz - 鍚勬柟鍚戠殑缃戞牸鏁 +% dx, dy, dz - 鍚勬柟鍚戠殑缃戞牸灏哄鍚戦噺 +% data - 鐗╃悊閲忔暟鎹紝缁村害涓(nx, ny, nz) + +% 璁$畻姣忎釜缃戞牸鐨勪腑蹇冨潗鏍 +x_center = zeros(nx, 1); +x_center(1) = dx(1)/2; +for i = 2:nx + x_center(i) = x_center(i-1) + (dx(i-1) + dx(i))/2; +end + +y_center = zeros(ny, 1); +y_center(1) = dy(1)/2; +for i = 2:ny + y_center(i) = y_center(i-1) + (dy(i-1) + dy(i))/2; +end + +z_center = zeros(nz, 1); +z_center(1) = dz(1)/2; +for i = 2:nz + z_center(i) = z_center(i-1) + (dz(i-1) + dz(i))/2; +end + +% 鍒涘缓鍥惧舰 +figure('Position', [100, 100, 1000, 800]); +hold on; + +% 璁剧疆棰滆壊鏄犲皠 +colormap jet; +caxis([min(data(:)), max(data(:))]); + +% 缁樺埗姣忎釜浣撶礌 +alpha_val = 0.9; % 閫忔槑搴 + +for i = 1:nx + for j = 1:ny + for k = 1:nz + % 缁樺埗浣撶礌 - 浼犻掑綋鍓嶇綉鏍肩殑鍊 + voxel_fixed([x_center(i), y_center(j), z_center(k)], ... + [dx(i), dy(j), dz(k)], ... + data(i, j, k), alpha_val); + end + end +end + +% 璁剧疆鍥惧舰灞炴 +colorbar; +xlabel('X'); +ylabel('Y'); +zlabel('Z'); +title('涓夌淮绗涘崱灏旂綉鏍煎叏鍏呮弧鐗╃悊閲忓垎甯冿紙浣撶礌娉曪紝鍗曚竴棰滆壊锛'); +axis equal; +view(3); +grid on; +box on; + +% 鍏夌収璁剧疆 +lighting gouraud; +light('Position', [1 1 1], 'Style', 'infinite'); +light('Position', [-1 -1 -1], 'Style', 'infinite'); + +hold off; +end + +function voxel_fixed(center, size, value, alpha) +% 缁樺埗鍗曚釜浣撶礌鐨勮緟鍔╁嚱鏁帮紙姣忎釜闈娇鐢ㄧ浉鍚岄鑹诧級 +% center: [x, y, z] 涓績鍧愭爣 +% size: [dx, dy, dz] 灏哄 +% value: 鐗╃悊閲忓 +% alpha: 閫忔槑搴 + +% 璁$畻8涓《鐐 +x = center(1) + [-size(1)/2, size(1)/2]; +y = center(2) + [-size(2)/2, size(2)/2]; +z = center(3) + [-size(3)/2, size(3)/2]; + +% 鍒涘缓8涓《鐐 +vertices = [x(1), y(1), z(1); + x(2), y(1), z(1); + x(2), y(2), z(1); + x(1), y(2), z(1); + x(1), y(1), z(2); + x(2), y(1), z(2); + x(2), y(2), z(2); + x(1), y(2), z(2)]; + +% 6涓潰鐨勯《鐐圭储寮 +faces = [1 2 3 4; + 5 6 7 8; + 1 2 6 5; + 2 3 7 6; + 3 4 8 7; + 4 1 5 8]; + +% 鍏抽敭淇敼锛氫娇鐢 'flat' 骞剁‘淇濇墍鏈夐潰浣跨敤鐩稿悓鐨勯鑹插 +patch('Vertices', vertices, 'Faces', faces, ... + 'FaceColor', 'flat', ... % 'flat' 纭繚姣忎釜闈㈠崟涓棰滆壊 + 'FaceVertexCData', value * ones(size(faces, 1), 1), ... % 鎵鏈夐潰鐩稿悓棰滆壊 + 'CDataMapping', 'scaled', ... + 'FaceAlpha', alpha, ... + 'EdgeColor', 'none'); +end \ No newline at end of file diff --git a/post processor/plot_SP_DP.m b/post processor/plot_SP_DP.m new file mode 100644 index 0000000..7f63e8e --- /dev/null +++ b/post processor/plot_SP_DP.m @@ -0,0 +1,51 @@ +function plot_SP_DP(k, r) +coordinate=r.coordinates; +nodes=r.nodes; +nz=r.nz; +nx=r.nx; +ny=r.ny; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +v = r.sigma; +% if type == 1 +% % v = r.kx; +% v = OutputRs{i}.p; +% else +% v = 1-OutputRs{i}.sw;%含气饱和度 +% end +dis = zeros(nel, nx*ny); +x = zeros(nel, nx*ny); +y = zeros(nel, nx*ny); +for i = 1 :nx*ny + for j = 1 :nel + grid_numbering = i+(nz-k)*nx*ny; + x(j, i) = coordinate(nodes(grid_numbering,j), 1); + y(j, i) = coordinate(nodes(grid_numbering,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(grid_numbering,4), 1); + y(j, i) = coordinate(nodes(grid_numbering,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(grid_numbering,3), 1); + y(j, i) = coordinate(nodes(grid_numbering,3), 2); + end + dis(j, i) = v(grid_numbering); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +% clim([10,15]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/post processor/pre_plot/preplot_dis.m b/post processor/pre_plot/preplot_dis.m new file mode 100644 index 0000000..5609ee9 --- /dev/null +++ b/post processor/pre_plot/preplot_dis.m @@ -0,0 +1,40 @@ +function [ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dis( r ) +%PREPLOT 此处显示有关此函数的摘要 +% 此处显示详细说明 +nx=r.nx; +ny=r.ny; +nz=r.nz; +downgrid=[]; +frontgrid=[]; +leftgrid=[]; +rightgrid=[]; +backgrid=[]; +upgrid=[]; +for k=1:nz + for j=1:ny + for i=1:nx + rao=i+(j-1)*nx+(k-1)*nx*ny; + if k==1 + downgrid=[downgrid rao]; + end + if k==nz + upgrid=[upgrid rao]; + end + if i==1 + leftgrid=[leftgrid rao]; + end + if i==nx + rightgrid=[rightgrid rao]; + end + if j==1 + frontgrid=[frontgrid rao]; + end + if j==ny + backgrid=[backgrid rao]; + end + end + end +end + +end + diff --git a/post processor/pre_plot/preplot_dislayer.m b/post processor/pre_plot/preplot_dislayer.m new file mode 100644 index 0000000..a78a754 --- /dev/null +++ b/post processor/pre_plot/preplot_dislayer.m @@ -0,0 +1,41 @@ +function [ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dislayer( r,k ) +%PREPLOT 此处显示有关此函数的摘要 +% 此处显示详细说明 +% k表示从上面数的层数 +nx=r.nx; +ny=r.ny; +nz=r.nz; +downgrid=[]; +frontgrid=[]; +leftgrid=[]; +rightgrid=[]; +backgrid=[]; +upgrid=[]; +xiang=nz+1-k; + for j=1:ny + for i=1:nx + rao=i+(j-1)*nx+(xiang-1)*nx*ny; + + downgrid=[downgrid rao]; + + + upgrid=[upgrid rao]; + + if i==1 + leftgrid=[leftgrid rao]; + end + if i==nx + rightgrid=[rightgrid rao]; + end + if j==1 + frontgrid=[frontgrid rao]; + end + if j==ny + backgrid=[backgrid rao]; + end + end + end + + +end + diff --git a/post processor/pre_plot/sort_fracture.m b/post processor/pre_plot/sort_fracture.m new file mode 100644 index 0000000..cb8c49f --- /dev/null +++ b/post processor/pre_plot/sort_fracture.m @@ -0,0 +1,27 @@ +function [ f,fellip ] = sort_fracture( inputf ) +nf=size(inputf,1); +f=[];fellip=[]; +for i=1:nf + ft1=inputf{i,1}; + alpha=inputf{i,2}/180*pi;beta=inputf{i,3}/180*pi;gama=inputf{i,4}/180*pi;%角度转换为弧度制 + lf=inputf{i,5};hf=inputf{i,6}; + ft2=lf/2*[cos(alpha)*cos(gama)+sin(alpha)*cos(beta)*sin(gama),-cos(alpha)*cos(beta)*sin(gama)+sin(alpha)*cos(gama),... + sin(beta)*sin(gama)]; + ft3=hf/2*[sin(alpha)*cos(beta)*cos(gama)-cos(alpha)*sin(gama),-sin(alpha)*sin(gama)-cos(alpha)*cos(beta)*cos(gama),sin(beta)*cos(gama)]; + if inputf{i,7}==1 %矩形缝 + ft4=[-1,1,0];ft5=[-1,1,0]; + f=[f;ft1;ft2;ft3;ft4;ft5]; + f(abs(f)<=1e-4)=0; + else %椭圆缝 + ft4=[0,0,1];ft5=[0,0,1]; + fellip=[fellip;ft1;ft2;ft3;ft4;ft5]; + fellip(abs(fellip)<=1e-4)=0; + end +end + + +end + + + + diff --git a/post processor/pre_plot/sort_fracture_project.m b/post processor/pre_plot/sort_fracture_project.m new file mode 100644 index 0000000..ace60dc --- /dev/null +++ b/post processor/pre_plot/sort_fracture_project.m @@ -0,0 +1,29 @@ +function [ f,fellip ] = sort_fracture_project( inputf ) +nf=size(inputf{1,1},1); +f=[];fellip=[]; +for i=1:nf + ft1=inputf{1,1}(i,:); +% alpha=inputf{i,2}/180*pi;beta=inputf{i,3}/180*pi;gama=inputf{i,4}/180*pi;%角度转换为弧度制 +% lf=inputf{i,5};hf=inputf{i,6}; + alpha=90/180*pi;beta=90/180*pi;gama=0/180*pi;%角度转换为弧度制 + lf=200;hf=5; + ft2=lf/2*[cos(alpha)*cos(gama)+sin(alpha)*cos(beta)*sin(gama),-cos(alpha)*cos(beta)*sin(gama)+sin(alpha)*cos(gama),... + sin(beta)*sin(gama)]; + ft3=hf/2*[sin(alpha)*cos(beta)*cos(gama)-cos(alpha)*sin(gama),-sin(alpha)*sin(gama)-cos(alpha)*cos(beta)*cos(gama),sin(beta)*cos(gama)]; +% if inputf{i,7}==1 %矩形缝 + ft4=[-1,1,0];ft5=[-1,1,0]; + f=[f;ft1;ft2;ft3;ft4;ft5]; + f(abs(f)<=1e-4)=0; +% else %椭圆缝 +% ft4=[0,0,1];ft5=[0,0,1]; +% fellip=[fellip;ft1;ft2;ft3;ft4;ft5]; +% fellip(abs(fellip)<=1e-4)=0; +% end +end + + +end + + + + diff --git a/post processor/pre_plot/sort_input.m b/post processor/pre_plot/sort_input.m new file mode 100644 index 0000000..4441eb2 --- /dev/null +++ b/post processor/pre_plot/sort_input.m @@ -0,0 +1,22 @@ +function [ input_modi ] = sort_input( input,nx,ny,nz ) +input=reshape(input',[],1); +input(input==0)=0.0001; +% hei=length(input); +hei=nx*ny*nz; +input=input(1:hei,1); +input_modi=zeros(hei,1); +for i=1:hei + zz=floor((i-1)/(nx*ny)); + zzz=nz-zz; + yy=floor((i-zz*nx*ny-1)/nx); + yyy=ny-yy; +% yyy=yy+1; + xxx=mod(i-zz*nx*ny-1,nx); + if xxx==0 xxx=nx; + end + input_modi(xxx+(yyy-1)*nx+(zzz-1)*nx*ny,1)=input(i); +end + + + + diff --git a/post processor/untitled2.m b/post processor/untitled2.m new file mode 100644 index 0000000..aa3428e --- /dev/null +++ b/post processor/untitled2.m @@ -0,0 +1,11 @@ +% 鍔犺浇鐢熸垚鐨勬暟鎹 +load('test_data.mat'); + +% 浣跨敤楂樻柉鍒嗗竷鏁版嵁缁樺埗鍒囩墖鍥 +plot_3d_grid_data_slice(nx, ny, nz, dx, dy, dz, data1); + +% 浣跨敤鐞冨3鍒嗗竷鏁版嵁缁樺埗鐐逛簯鍥 +plot_3d_grid_data_scatter(nx, ny, nz, dx, dy, dz, data2); + +% 浣跨敤娉㈢汗鍒嗗竷鏁版嵁缁樺埗浣撶粯鍒跺浘 +plot_3d_grid_data_volume(nx, ny, nz, dx, dy, dz, data3); \ No newline at end of file diff --git a/startup.m b/startup.m new file mode 100644 index 0000000..b8702bb --- /dev/null +++ b/startup.m @@ -0,0 +1 @@ + addpath(genpath(pwd)) \ No newline at end of file diff --git a/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/GridProp_pre.m b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/GridProp_pre.m new file mode 100644 index 0000000..e7b75b1 --- /dev/null +++ b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/GridProp_pre.m @@ -0,0 +1,115 @@ +function [r] = GridProp_pre(dx, dy,dz,nx,ny,nz,NTG) +% coordinates xy cordinate锛屽嵆姣忎釜鑺傜偣鐨剎,y鍧愭爣 +% nodes connection锛屽嵆姣忎釜瀛愬尯鍩熷搴旂殑鍏釜鑺傜偣鏁 +% nP numbers of point锛屽嵆鑺傜偣鏁伴噺 +% nE numbers of element锛屽嵆瀛愬尯鍩熸暟閲 +nP = (nx + 1) * (ny + 1)*(nz+1);%璁$畻鑺傜偣鏁伴噺 +nE = nx * ny*nz;%瀛愬尯鍩熸暟閲忚绠 +% dx=dx*ones(nx,1);%姝ゅ鏄负浜嗘殏鏃跺Ε鍗 +% dy=dy*ones(nx,1); +% dz=dz*ones(nx,1); +dxv = zeros(nE, 1);%姣忎釜瀛愬尯鍩焫鏂瑰悜涓婂昂瀵哥煩闃 +dyv = zeros(nE, 1);%姣忎釜瀛愬尯鍩焬鏂瑰悜涓婂昂瀵哥煩闃 +dzv = zeros(nE, 1); +zm=zeros(nE, 1);%鍩鸿川缃戞牸璁$畻娣卞害锛堜互涓嬪钩闈负鍩哄噯璁$畻寰楀埌鐨勯珮搴︼紝鍊间负姝f暟锛 +xm=zeros(nE, 1); +ym=zeros(nE, 1); +%缁欐瘡涓瓙鍖哄煙鐨剎鏂瑰悜鍜寉鏂瑰悜璧嬪昂瀵 +vm=zeros(nE, 1);%鍩鸿川缃戞牸浣撶Н +for k=1:nz + for i = 1 : nx + for j = 1 : ny + dxv(i+(j-1)*nx+nx*ny*(k-1)) = dx(i); + dyv(i+(j-1)*nx+nx*ny*(k-1)) = dy(j); + dzv(i+(j-1)*nx+nx*ny*(k-1))= dz(k); + vm(i+(j-1)*nx+nx*ny*(k-1))=dx(i)*dy(j)*dz(k)*NTG(i+(j-1)*nx+nx*ny*(k-1)); + end + end +end +coordinates = zeros(nP, 3);%鍒濆鍖栨瘡涓妭鐐圭殑x,y鍧愭爣鐭╅樀 +nodes = zeros(nE, 8);%鍒濆鍖栨瘡涓瓙鍖哄煙瀵瑰簲鐨勫叓涓妭鐐规暟鐨勭煩闃 +%璁$畻姣忎釜鑺傜偣鐨勫潗鏍 +x0 = zeros(nx+1,1); +y0 = zeros(ny+1,1); +z0=zeros(nz+1,1); +sumx = 0; +sumy = 0; +sumz=0; +for i = 1 : nx + sumx = sumx+dx(i); + x0(i+1) = sumx; +end +for i = 1 : ny + sumy = sumy+dy(i); + y0(i+1) = sumy; +end +for i = 1 : nz + sumz = sumz+dz(i); + z0(i+1) = sumz; +end +for k=1:nz+1 +for j = 1 : ny + 1 + for i = 1 : nx + 1 + coordinates(i + (j - 1) * (nx + 1)+(nx+1)*(ny+1)*(k-1), 1) = x0(i);%(i,j锛夎妭鐐圭殑x鍧愭爣璧嬪 + coordinates(i + (j - 1) * (nx + 1)+(nx+1)*(ny+1)*(k-1), 2) = y0(j);%(i,j锛夎妭鐐圭殑y鍧愭爣璧嬪 + coordinates(i + (j - 1) * (nx + 1)+(nx+1)*(ny+1)*(k-1), 3) = z0(k); + end +end +end +%璁$畻姣忎釜瀛愬尯鍩熺殑鍏釜椤剁偣(鑺傜偣锛夊搴旂殑鑺傜偣缂栧彿 +for k=1:nz +for j = 1 : ny + for i = 1 : nx + nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) = i + (j - 1) * (nx + 1)+(k-1)*(nx+1)*(ny+1); + nodes(i + (j - 1) * nx+nx*ny*(k-1), 2) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 3) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) + nx + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 4) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1) + nx + 2; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 1)+(nx+1)*(ny+1); + nodes(i + (j - 1) * nx+nx*ny*(k-1), 6) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 7) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) + nx + 1; + nodes(i + (j - 1) * nx+nx*ny*(k-1), 8) = nodes(i + (j - 1) * nx+nx*ny*(k-1), 5) + nx + 2; + zm(i+(j-1)*nx+nx*ny*(k-1))=sum(coordinates(nodes(i + (j - 1) * nx+nx*ny*(k-1), :),3))/8; + xm(i+(j-1)*nx+nx*ny*(k-1))=sum(coordinates(nodes(i + (j - 1) * nx+nx*ny*(k-1), :),1))/8; + ym(i+(j-1)*nx+nx*ny*(k-1))=sum(coordinates(nodes(i + (j - 1) * nx+nx*ny*(k-1), :),2))/8; + end +end +end + +cell_mid_coordinates = [xm,ym,zm]; + +xrao=[0]; +for i=1:nx + xxiang=sum(dx(1,1:i)); + xrao=[xrao xxiang]; +end +yrao=[0]; +for i=1:ny + yxiang=sum(dy(1,1:i)); + yrao=[yrao yxiang]; +end +zrao=[0]; +for i=1:nz + zxiang=sum(dz(1,1:i)); + zrao=[zrao zxiang]; +end +r.dx = dx; +r.dy = dy; +r.dz = dz; +r.nx = nx; +r.ny = ny; +r.nz = nz; +r.coordinates = coordinates; +r.nodes = nodes; +r.nP = nP; +r.nmc = nE; +r.dxv = dxv; +r.dyv = dyv; +r.dzv = dzv; +r.zm = zm; +r.vm = vm; +r.xrao = xrao; +r.yrao = yrao; +r.zrao = zrao; +r.cell_mid_coords = cell_mid_coordinates; +r.NTG = NTG; +end \ No newline at end of file diff --git a/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/grid_discretization_SP_model.m b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/grid_discretization_SP_model.m new file mode 100644 index 0000000..5333e3e --- /dev/null +++ b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/grid_discretization_SP_model.m @@ -0,0 +1,70 @@ +function r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf) +% 鏁版嵁璇诲彇 +nx = r.nx; ny = r.ny; nz = r.nz; NTG = r.NTG; cell_mid_coords = r.cell_mid_coords; +% 涓嶈鍒欒竟鐣岃瀹 +boundary = [0,100; + 800,50; + 1000,150; + 1000,350; + 800,450; + 0,400; + 0,100]; +% 灏嗕笉鍦ㄨ竟鐣屽唴鐨勭綉鏍肩殑valid鍊艰祴涓0 +valid_grids = ones(nx*ny*nz); +in = inpolygon(cell_mid_coords(:,1),cell_mid_coords(:,2),boundary(:,1),boundary(:,2)); +valid_grids(~in) = 0; +invalid_layer = []; % +if ~isempty(invalid_layer) + for i = 1:length(invalid_layer) + grid_numbering_range = ((invalid_layer(i)-1)*nx*ny+1:invalid_layer(i)*nx*ny)'; + valid_grids(grid_numbering_range,1) = 0; + end +end +% 涓句緥锛岀粰鍑烘笚閫忕巼鍑芥暟褰㈠紡 k(x,y) = (x/500+y/250+1)*1e-3 D锛屾垨鑰呴氳繃宸茬煡鐐规彃鍊艰绠楃瓑锛岄兘琛 +kx = (cell_mid_coords(:,1)/500+cell_mid_coords(:,2)/250+1)*1e-3; +ky = kx; +kz = kx; +% 涓句緥锛岀粰鍑哄瓟闅欏害鍑芥暟褰㈠紡 phi(x,y) = (x/20000+y/10000+0.1)锛屾垨鑰呴氳繃宸茬煡鐐规彃鍊艰绠楃瓑锛岄兘琛 +pori = (cell_mid_coords(:,1)/20000+cell_mid_coords(:,2)/10000+0.1); +% +prpor = 20; % 鍙傝冨帇鍔涳紝MPa +cpor = 1.0e-5;% 鍩鸿川鍘嬬缉绯绘暟锛孧Pa +rock_density = 2700; % 宀╃煶瀵嗗害锛宬g/m^3 + +% SRV鍖哄煙瀹氫箟 +% % % base_x=23:78; nx_SRV=length(base_x); +% % % base_y=15:36; ny_SRV=length(base_y); +% % % base_z=1:1;nz_SRV=length(base_z); +% % % SRV=[]; +% % % for k=1:nz_SRV +% % % for j=1:ny_SRV +% % % for i=1:nx_SRV +% % % SRV=[SRV;(base_z(k)-1)*nx*ny+(base_y(j)-1)*nx+base_x(i)]; +% % % end +% % % end +% % % end +% % % % SRV娓楅忕巼璧嬪 +% % % kx(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % ky(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % kz(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% 瑁傜紳瀛旀笚 +Kf = 10000*1e-3*ones(1,nf);% 瑁傜紳娓楅忕巼 +Wf = 1e-2*ones(1,nf);% 瑁傜紳寮搴 +Porf = 0.30*ones(1,nf);% 瑁傜紳瀛旈殭搴 +prporf = 20;% 瑁傜紳绯荤粺鍙傝冨帇鍔 +cporf = 1.0e-5;% 瑁傜紳绯荤粺鍘嬬缉绯绘暟 +% 搴斿姏鏁忔劅绯绘暟 +stress_factor_fracture = 0.000; % 1/MPa 0.001 +stress_factor_matrix = 0.000; % 1/MPa +stress_factor_ref_pressure = 20; % 涓鑸彇涓哄師濮嬪湴灞傚帇鍔 +% +Rpt = 2;cf = 1;ca = 1; +%% 缁撳悎鍩鸿川銆佽缂濈殑鍑犱綍鍙婄墿鎬т俊鎭紑灞曞墠澶勭悊 +% r = GridProp(modelflag, nx, ny, nz, dx, dy, dz, kx, ky, kz, f, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,co, NTG); +r = GridProp_new(modelflag, r, kx, ky, kz, f, frac_information, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,valid_grids); +r.rock_density = rock_density; +r.valid_grids = valid_grids; +r.stress_factor_fracture = stress_factor_fracture; +r.stress_factor_matrix = stress_factor_matrix; +r.stress_factor_ref_pressure = stress_factor_ref_pressure; +end \ No newline at end of file diff --git a/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/main1.m b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/main1.m new file mode 100644 index 0000000..e6cd6e4 --- /dev/null +++ b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/main1.m @@ -0,0 +1,222 @@ +function [ r, Times, OutputRs, Wellpara, trun ] = main1() +%% ==================================PART 1: 妯″瀷閫夊彇======================================== +% 1-- classical EDFM +modelflag = 1;% 姝ゅ鍥哄畾涓1鍗冲彲 +%% ==================================PART 2: 鍩鸿川缃戞牸瀹氫箟===================================== +dx=[10*ones(1,100) ];nx=size(dx,2); +dy=[10*ones(1,50) ];ny=size(dy,2); +dz=[10*ones(1,1)];nz=size(dz,2); +NTG= 1*ones(nx*ny*nz,1); +r = GridProp_pre(dx, dy,dz,nx,ny,nz,NTG); +%% ==================================PART 3: 瑁傜紳鍒嗗竷鏁版嵁杈撳叆===================================== +% 鍥涚杈撳叆鏂瑰紡: 1琛ㄧず宸ョ▼搴旂敤杈撳叆锛2琛ㄧず鍚戦噺杈撳叆锛3琛ㄧず宸ョ▼搴旂敤杈撳叆锛屽寘鎷熀鍑嗙偣銆佸捐銆佹柟浣嶈銆佹姮鍗囪锛4琛ㄧず浠.fab鏂囦欢璇诲彇 +input_style = 1; +%% 杈撳叆鏂瑰紡1锛氬伐绋嬪簲鐢ㄨ緭鍏 +%浠呰兘鍒荤敾鍏锋湁鍙屽绉版ц川鐨勭煩褰㈢紳鎴栨き鍦嗙紳 +% 鍩哄噯鐐瑰潗鏍囷紙1锛夛紝鏂逛綅瑙掞紙2锛夛紝鍊捐锛3锛夛紝鎶崌瑙掞紙4锛夛紝缂濋暱锛堟き鍦嗛暱杞撮暱锛夛紙5锛夛紝缂濋珮锛堟き鍦嗙煭杞撮暱锛夛紙6锛夛紝绫诲瀷1鏄煩褰㈢紳銆2鏄き鍦嗙紳锛7锛 +if input_style==1 +input_content={ + [255,255,5],90,90,0,200,10,1; + [305,255,5],90,90,0,200,10,1; + [355,255,5],90,90,0,200,10,1; + [405,255,5],90,90,0,200,10,1; + [455,255,5],90,90,0,200,10,1; + [505,255,5],90,90,0,200,10,1; + [555,255,5],90,90,0,200,10,1; + [605,255,5],90,90,0,200,10,1; + [655,255,5],90,90,0,200,10,1; + [705,255,5],90,90,0,200,10,1; + [755,255,5],90,90,0,200,10,1; + }; +[f,fellip] = sort_fracture(input_content); +flowBarrierFlags = []; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5; +frac_information = fractureInformation_input_engineering_vector(f,fellip,flowBarrierFlags); +end +%% 杈撳叆鏂瑰紡2锛氬悜閲忚緭鍏 +%棣栧厛瀵圭煩褰㈢紳杩涜鐮旂┒锛岃缂濆弬鏁板寘鎷笁涓悜閲忓拰涓や釜鍙傛暟鐨勫彇鍊艰寖鍥达紝濡傛灉鏄叾瀹冪被鍨嬬紳锛屽垯鏄袱涓弬鏁伴棿鐨勫嚱鏁板叧绯 +%鍥犳涓涓5琛屼笁鍒楃殑鐭╅樀鍙互纭畾涓鏉¤缂 +%鍚戦噺鍒嗛噺鍙负闈炴暣鏁帮紝浠ユ淇濊瘉鍙傛暟鑼冨洿鐨勫彇鍊间负鏁存暟鍗冲彲锛 +%鏁呭彲鍏堥殢鎰忕‘瀹氫负鏁存暟鐨勫弬鏁拌寖鍥达紝鍐嶆牴鎹紳闀跨紳楂樺幓纭畾鍚戦噺鍒嗛噺鐨勫彇鍊 +% 鐭╁舰缂 +if input_style==2 + f=[ + 0,1200,0;10,-20,0;0,0,10;0,60,0;0,3,0; + 0,1200,0;10,20,0;0,0,10;0,15,0;0,3,0; + 150,1500,0;20,-10,0;0,0,10;0,20,0;0,3,0; + 550,1300,0;10,10,0;0,0,10;0,10,0;0,3,0; + 650,1400,0;10,-20,0;0,0,10;0,55,0;0,3,0; + 605,705,0;10,0,0;0,0,10;-20,20,0;0,3,0; + ]; +% 妞渾缂 +% fellip=[320,210,10;10,2,0;0,0,2;0,0,8;0,0,5; +% 280,300,10;10,2,0;0,0,2;0,0,10;0,0,4;]; +% 300,205,10;10,0,0;0,0,2;0,0,10;0,0,5]; +fellip=[]; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +frac_information = fractureInformation_input_engineering_vector(f,fellip); +end +%% 杈撳叆鏂瑰紡3锛氫簩缁磋緭鍏 +% load('fractures_generated.mat'); +% fractureLines = fractures_generated; +if input_style==3 +fractureLines = [ + 105,150;105,350; + 205,150;205,350; + 305,150;305,350; + 405,150;405,350; + 505,150;505,350; + 605,150;605,350; + 705,150;705,350; + 805,150;805,350; + 905,150;905,350; + ]; +fellip=[]; % 妞渾缂 +fractureHeights = [ + 10;10;10;10;10;10;10;10;10]; +% 妞渾缂 +fellip=[]; +flowBarrierFlags = [];% flowBarrierFlags = [1;2;3;4]; +[f,frac_information] = input_fracture_2D(fractureLines,fractureHeights,flowBarrierFlags); +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +end +%% 杈撳叆鏂瑰紡4锛氫粠.fab鏂囦欢璇诲彇 Frac_PT +if input_style==4 + +end + +%% ==================================PART 4: 鍩鸿川缃戞牸鍙婅缂濈墿鎬у弬鏁拌緭鍏===================================== +% 1-- 鍗曢噸浠嬭川 +% 2-- 鍙岄噸浠嬭川锛堝弻瀛斿弻娓楋級 +grid_model = 1; +if grid_model == 1 +r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf); +end +if grid_model == 2 +r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf); +end + +%% 鐢熸垚鍚戦噺鍖栧彉鎴愭墍闇瑕佺殑绠楀瓙 +os = OperatorRS(r.N, r.nex, r.nc); + +%% ==================================PART 5: 妯″瀷绫诲瀷閫夊彇鍙婂垵濮嬬姸鎬佽瀹========================================= +% 1-- 姘旀按涓ょ浉娴 +% 2-- 娌规按涓ょ浉娴 +flow_model = 3; +if flow_model == 1 +[f,state0] = gas_water_flow(r); +end +if flow_model == 2 +[f,state0] = oil_water_flow(r); +end +if flow_model == 3 +[f,state0] = multi_component_flow(r); +end + +%% ==================================PART 6: 浜曞埗搴chedule璁惧畾================================================ +%灏嗙洿浜曘佹按骞充簳涓庡娈靛帇瑁傛按骞充簳鍒嗗紑澶勭悊 +%% 鐩翠簳銆佸父瑙勬按骞充簳瀹氫箟 +% Wellcpara: wellname(1) nperf锛屽皠瀛旂偣鏁伴噺(2) index(3) rw(4) skin(5) welltype(6) +% welltype=1 鐩翠簳锛寃elltype=2 姘村钩浜曟部x鏂瑰悜锛寃elltype=3 姘村钩浜曟部y鏂瑰悜 welltype=4 澶氭鍘嬭姘村钩浜 +% 鐩翠簳銆佹按骞充簳锛岃绉嶄簳鍨嬬殑澶勭悊鏄皢灏勫瓟娈靛畨鎺掑湪鍩鸿川缃戞牸 +% 瀵逛簬鐩翠簳銆佹枩浜曘佹按骞充簳锛岄噰鍙栦笌eclipse涓鑷寸殑鏂瑰紡锛岀粰鍑哄叾鍦ㄥ熀璐ㄧ綉鏍间腑浣嶇疆 +% 姣忎釜灏勫瓟鐐圭敱涓媝x,py,pz纭畾锛屽垎鍒〃绀鸿灏勫瓟鐐瑰湪x鏂瑰悜锛寉鏂瑰悜鐨勭綉鏍肩紪鍙凤紝鍙婂眰鏁板嵆z鍙嶆柟鍚戜笂鐨勭綉鏍肩紪鍙凤紙鏈鍒濇槸浠ュ瀭鐩村悜涓婂缓绔嬬殑鍩鸿川缃戞牸锛 +well1={ + % 'w1', 2, [20 10 1;20 10 2;], 0.178/2, 0, 1; + % 'w2', 2, [80 10 1;80 10 2;], 0.178/2, 0, 1; + % 'w3', 1, [20 40 1;], 0.178/2, 0, 1; + % 'w4', 1, [80 40 1;], 0.178/2, 0, 1; +% 'w2', 3, [67 20 1;67 20 2;67 20 3], 0.178/2, 0, 1; + }; +well1 = handle_well1(well1,r); +%% 鍘嬭姘村钩浜曞畾涔 +% 澶氭鍘嬭姘村钩浜曪細灏勫瓟娈佃缃湪瑁傜紳鍗曞厓涓婏紝鍙互缁欏嚭璇ュ皠瀛旂偣鎵鍦ㄧ殑鍧愭爣锛岀劧鍚庡幓瀵绘壘璇ョ偣鎵鍦ㄧ殑瑁傜紳鍗曞厓缂栧彿 +num_fracture_wells = 1; +welloc = cell(num_fracture_wells,1); +perfnum = cell(num_fracture_wells,1); +welloc{1,1}=[ + 255,255,5; + 305,255,5; + 355,255,5; + 405,255,5; + 455,255,5; + 505,255,5; + 555,255,5; + 605,255,5; + 655,255,5; + 705,255,5; + 755,255,5; + ]; +for i = 1:num_fracture_wells +perfnum{i,1} = findWelloc(r, welloc{i,1});%鍦ㄧ敤浠ellc0涔嬩腑 +end +% perfnum2 = findWelloc(r, welloc2); +well2={ + 'w1', length(perfnum{1,1}), perfnum{1,1}, 0.178/2, 0,4; + }; +Wellc = handle_well1_well2(well1,well2,welloc,r); %鍔犱簳鍜屽皠瀛斾綅缃 +%% 浜曞埗搴﹁缃紙寮鍏充簳銆佸畾鍘/瀹氫骇銆佷究浜庡悶鍚愮瓑锛 +number_phases = 3; +well_schedules = cell(number_phases,1); +time = zeros(number_phases,1); +% 涓嶅悓鏂瑰紡瀵瑰簲鐨勬敹鏁涢毦搴︺侀渶瑕佷笉涓鏍凤紝闇鍒嗛樁娈佃皟鎺э紝 +% 渚嬪鍦ㄦ敞鍏ラ樁娈甸渶瑕佸皬涓浜涳紝濡傛灉闇瑕佸仛鏃╂湡璇曚簳锛宒tmax銆乨tmin閮介渶瑕佸皬涓浜 +dtmax = zeros(number_phases,1); +dtmin = zeros(number_phases,1); + +% (1)well state: 'open'琛ㄧず璇ヤ簳鏄紑鐨勶紱'close'琛ㄦ槑璇ヤ簳涓鐩存槸鍏崇殑锛屽鏋滃彧鏄樁娈垫у叧浜曪紝灏辩敤'open'瀹氭祦閲0鐢熶骇 +% (2)well type: 'pro'琛ㄧず鏄敓浜т簳锛'inj'琛ㄧず鏄敞鍏ヤ簳; +% (3)protype锛'const_q'鏄畾娴侀噺锛'const_pwf'鍒欐槸瀹氬帇 +% (4)value锛氬畾鐨勬祦閲忓兼垨鑰呬簳搴曞帇鍔涘 +% (5)value锛氭浠g爜璇ュ间笌锛3锛夊肩浉鍚 +% (8)value锛氭敞鍏ヨ〃娲诲墏鐨勬祿搴 kg/m3 +% (10)value锛氭敞鍏ユ按/鍘嬭娑茬殑鐩愭祿搴︼紙鐭垮寲搴︼級锛屼竴鑸槸 1kg/m3 +time(1) = 10; dtmax(1) = 0.1; dtmin(1) = 0.001; +well_schedules{1,1} = { + % 'w1','open','inj','const_pwf',30,30; + % 'w2','open','inj','const_pwf',30,30; + % 'w3','open','inj','const_pwf',30,30; + % 'w4','open','inj','const_pwf',30,30; + 'w1','open','inj','const_pwf',40,40,'Cs_inj',0.5,'Cb_inj',1}; +time(2) = 30; dtmax(2) = 0.5; dtmin(2) = 0.001; +well_schedules{2,1} = { + 'w1','open','pro','const_q',0,0; + % 'w1','open','pro','const_pwf',10,10; + % 'w2','open','pro','const_q',0,0; + }; +time(3) = 200; dtmax(3) = 0.5; dtmin(3) = 0.001; +well_schedules{3,1} = { + 'w1','open','pro','const_pwf',10,10; + % 'w2','open','pro','const_pwf',10,10; + }; +% time(1) = 200; +% well_schedules{1,1} = { +% 'w1','open','pro','const_pwf',10,10; +% % 'w2','open','pro','const_pwf',10,10; +% }; +% time(4) = 200; +% well_schedules{4,1} = {'w1','open','inj','const_pwf',30,30; +% 'w2','open','pro','const_pwf',10,10;}; +% time(5) = 200; +% well_schedules{5,1} = {'w1','open','inj','const_pwf',30,30; +% 'w2','open','pro','const_pwf',10,10;}; +% time(6) = 200; +% well_schedules{6,1} = {'w1','open','inj','const_pwf',30,30; +% 'w2','open','pro','const_pwf',10,10;}; + +%% ======================================PART 7: Solver璁剧疆=========================================== +yitap = 5; % 50-500psi +yitas = 0.04; % 0.05-0.5 +omega = 0.5; % 0-1 +Nmax = 50; +epsave = 1e-6; +epsmax = 1e-6; +% dtmin = 0.001; +% dtmax = 10; +% dtmin = 0.000001; +% dtmax = 0.0001; +%% ======================================PART 8: 姝e紡璁$畻=========================================== +[Times, OutputRs, Wellpara, trun] = solver_NR(r, flow_model, f, os, state0, yitap,yitas,omega,Nmax,epsave,epsmax,dtmin,dtmax,Wellc,time,well_schedules); +run_time=toc; +trun.run_time=run_time; +end \ No newline at end of file diff --git a/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/multi_component_flow.m b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/multi_component_flow.m new file mode 100644 index 0000000..94eb4b0 --- /dev/null +++ b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/multi_component_flow.m @@ -0,0 +1,232 @@ +function [f,state0] = multi_component_flow(r) +%% 娴佷綋鎬ц川鍙傛暟 +%% 姘寸浉涓殑琛ㄦ椿鍓傘佺洂鐨勬墿鏁g郴鏁 +Ds = 0.76*1e-9; % m2/s +Db = 2.2*1e-9; % m2/s +%% 琛ㄦ椿鍓傘佺洂鍦ㄥ博鐭宠〃闈㈢殑鍚搁檮娴撳害涓庢按鐩告祿搴︾殑鍏崇郴琛紝绗竴鍒楀崟浣嶆槸kg/m3, 绗簩鍒楀拰绗笁鍒楀崟浣嶆槸g/kg +c_ca_table = [ +0 0 0 +0.05 1 0.075 +0.1 1.75 0.125 +0.2 3 0.2 +0.5 4.35 0.325 +1 4.55 0.365 +]; +cs_data = c_ca_table(:,1); +cb_data = c_ca_table(:,1); +csa_data = c_ca_table(:,2)*1e-3; % 杞崲涓 kg/kg +cba_data = c_ca_table(:,3)*1e-3; % 杞崲涓 kg/kg +%% 鍖栧鍔匡紙鍘嬭娑蹭笌鍦板眰姘寸殑鐩愬害宸紓缁欐按鐩稿甫鏉ョ殑棰濆鍘嬪樊锛 +R = 0.008314; % kJ/(mol*K) +Vm = 18.02*1e-6; % 姘寸殑鍋忔懇灏斾綋绉紝m^3/mol +Temperature = 293.15; % 娓╁害锛孠 +chemistry_cof = R*Temperature/Vm*1e-3/10; +%% 鍔ㄦ佺浉娓楋紙鍑告樉鍑鸿〃娲诲墏瀵圭浉娓楃殑褰卞搷锛 +% 鍘熸湰搴斿厛寰楀埌琛ㄦ椿鍓傛祿搴︿笌琛ㄩ潰寮犲姏鐨勫叧绯伙紝鍐嶇粨鍚堟笚娴侀熷害璁$畻鍑轰釜琛ㄩ潰寮犲姏瀵瑰簲鐨勬瘺绠℃暟锛 +% 涓轰簡绠渚夸唬鐮佺紪鍐欙紝姝ゅ蹇界暐娓楁祦閫熷害鐨勫奖鍝嶏紝 +% 骞跺寮轰唬鐮侀氱敤鎬э紝姝ゅ鏀逛负杈撳叆琛ㄦ椿鍓傛祿搴︿笌姣涚鏁扮殑瀵瑰簲琛ㄦ牸锛 +% 绗竴鍒椾负琛ㄦ椿鍓傛祿搴︼紝绗簩鍒椾负鐩稿簲鐨勬瘺绠℃暟,锛岀涓夊垪鏄浉搴旂殑琛ㄩ潰寮犲姏 +% dynamic_kr = 1; +cs_Nc = [ +0 1.6*1e-6 30 +0.1 9.5*1e-6 10 +0.2 2.5*1e-5 4 +0.5 5.8*1e-5 1.4 +1 8.2*1e-5 1 +2 8.8*1e-5 0.75 +]; +Nc_nosurf = min(cs_Nc(:,2)); +Nc_surf = max(cs_Nc(:,2)); + +kr_nosurf = [ +0 0 0.64 +0.25 0 0.64 +0.30 0.072 0.6 +0.40 0.14 0.56 +0.50 0.26 0.48 +0.60 0.4 0.38 +0.70 0.56 0.26 +0.85 0.88 0 +1 0.88 0 + ]; + +kr_surf = [ +0 0 0.6 +0.18 0 0.6 +0.25 0.056 0.56 +0.30 0.1 0.52 +0.40 0.19 0.42 +0.50 0.29 0.3 +0.60 0.37 0.19 +0.75 0.46 0 +1 0.46 0 + ]; + +PC = [ +0 3.8916 +0.2 3.8916 +0.316 0.5796 +0.435 0.3724 +0.562 0.2425 +0.614 0.0608 +0.702 0.0372 +0.812 0.0137 +0.875 0.0104 +0.906 0.009 +0.937 0.0075 +0.969 0.0059 +1 0 +]; +cs_Nc_fracture = cs_Nc; +kr_nosurf_fracture = kr_nosurf; +kr_surf_fracture = kr_surf; +PC_fracture = PC; +ifpcgl = 0; % 鏄惁鑰冭檻姣涚鍔 +%% 鍚姩鍘嬪姏姊害 +p_grad_threshold = 0.00; % MPa/m +%% ================姘旂浉Langmuir绛夋俯鍚搁檮妯″瀷锛屽綋 VL=0锛屼害鍙敤浜庢补鐩=============== +% VE = VL*P/(PL+P) +gas_prop.VL = 0.0; % Langmuir volume, m^3/kg +gas_prop.PL = 3.5; % Langmuir pressure, MPa +% Psc = 1; +% Zsc = 1; +% density_rock = 2000; % +% ===================== Knudsen 鎵╂暎绯绘暟锛屽綋 Kn=0锛屼害鍙敤浜庢补鐩 ==================== +gas_prop.Kn = 0; % Knudsen鏁 +c1 =1; c2 =8/9; +gas_prop.Kn_modified_factor = 1+8*c1*gas_prop.Kn+16*c2*gas_prop.Kn^2; +% ===================== 楂橀熼潪杈捐タ娴 Forchheimer 鏂圭▼ ==================== +gas_prop.beta_non_Darcy_flow = 0; % 1e-8 +% =======================姘旂浉浣撶Н绯绘暟銆佺矘搴=============================== +density_g_sc = 800; +% 绗竴绉嶆ā寮忥紝鐩存帴杈撳叆鍙傝冨帇鍔涖佷綋绉郴鏁般佸帇缂╃郴鏁般佺矘搴 +gas_model =1; +if gas_model == 1 +prg = 20; % reference pressure, MPa +Bgi = 1; % gas phase volume factor +cg = 5e-4 ;% gas phase compressibility, 1/MPa +vgi = 6; % gas viscosity, cp +cvg = 0; +[Ppr,BG,MUG] = cal_gas_prop(prg,Bgi,cg,vgi,cvg); +end +if gas_model == 2 +Ppr = [ 0.1013 + 2.0946 + 4.0878 + 6.0811 + 8.0743 + 10.0676 + 12.0608 + 14.0540 + 16.0473 + 18.0405 + 20.0338 + 22.0270 + 24.0203 + 26.0135 + 28.0068 + 30.0000 + ]; +% BG = 0.01*ones(size(Ppr,1),1); +BG = [ 1.18297 + 0.0557041 + 0.0278168 + 0.0182594 + 0.0134665 + 0.0106154 + 0.00874829 + 0.00744907 + 0.00650639 + 0.0058006 + 0.0052587 + 0.0048336 + 0.00449378 + 0.00421751 + 0.0039895 + 0.00379871 + ]; +% MUG = 0.01*ones(size(Ppr,1),1); +MUG = [0.0127683 + 0.0130191 + 0.0133973 + 0.013872 + 0.014437 + 0.015088 + 0.0158182 + 0.0166173 + 0.0174719 + 0.0183671 + 0.0192882 + 0.0202219 + 0.0211575 + 0.0220865 + 0.0230024 + 0.0239008 + ]; +end +% ========================姘寸浉浣撶Н绯绘暟銆佺矘搴=============================== +density_w_sc = 1000; +prw = 20; % reference pressure +Bwi = 1.000; % water phase volume factor +cw = 4.0e-4 ;% water phase compressibility +vwi = 1; % viscosity +cvw = 0; +% =============================鍩鸿川鐩告笚=============================== +% ifpcgl = 0; % 鏄惁鑰冭檻姣涚鍔 +% RPGW=[ +% 0.0000 0.0000 1.0000 3.8916 +% 0.2000 0.0000 1.0000 3.8916 +% 0.3160 0.0002 0.6784 0.5796 +% 0.4350 0.0004 0.6215 0.3724 +% 0.5620 0.0010 0.5456 0.2425 +% 0.6140 0.0020 0.3939 0.0608 +% 0.7020 0.0280 0.1399 0.0372 +% 0.8120 0.1721 0.0515 0.0137 +% 0.8750 0.3395 0.0297 0.0104 +% 0.9060 0.4395 0.0226 0.0090 +% 0.9370 0.5500 0.0173 0.0075 +% 0.9690 0.6702 0.0131 0.0059 +% 1.0 1.0000 0.0000 0.0000 +% ]; +% SW=RPGW(:,1);KRW=RPGW(:,2);KRG=RPGW(:,3);PCGL=RPGW(:,4); +% +% % =============================瑁傜紳鐩告笚=============================== +% PRF=[ +% 0.0000 0.0000 1.0000 3.8916 +% 0.2000 0.0000 1.0000 3.8916 +% 0.3160 0.0002 0.6784 0.5796 +% 0.4350 0.0004 0.6215 0.3724 +% 0.5620 0.0010 0.5456 0.2425 +% 0.6140 0.0020 0.3939 0.0608 +% 0.7020 0.0280 0.1399 0.0372 +% 0.8120 0.1721 0.0515 0.0137 +% 0.8750 0.3395 0.0297 0.0104 +% 0.9060 0.4395 0.0226 0.0090 +% 0.9370 0.5500 0.0173 0.0075 +% 1.0 1.0000 0.0000 0.0000 +% ]; +% SWF = PRF(:,1);KRWF = PRF(:,2);KRGF = PRF(:,3);PCGLF=PRF(:,4); + +%% 缁撳悎娴佷綋鎬ц川鍙傛暟鐢熸垚鐩稿簲鐨勬暟鎹綋 +% f = fluidPVT(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, SW, KRG, KRW, PCGL, SWF, KRGF, KRWF, PCGLF, density_g_sc, ifpcgl, r.rpt, cs_data, csa_data, cb_data, cba_data, cs_Nc, kr_nosurf, kr_surf); +f = fluidPVT_new(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, ifpcgl, r.rpt, cs_data, csa_data, cb_data, cba_data, cs_Nc, Nc_nosurf, Nc_surf, kr_nosurf, kr_surf, PC, cs_Nc_fracture, kr_nosurf_fracture, kr_surf_fracture, PC_fracture); +f.Dwsi = density_w_sc; +f.Dgsi = density_g_sc; +f.gas_prop = gas_prop; +f.Ds = Ds; +f.Db = Db; +f.chemistry_cof = chemistry_cof; +f.p_grad_threshold = p_grad_threshold; +%% 鍒濆兼潯浠 Initial Condition Section +% =================鍘嬪姏銆侀ケ鍜屽害鍒濆======================================= % +%鍘嬪姏鍒濆艰鑰冭檻閲嶅姏锛岀粰鍑烘补钘忎笅琛ㄩ潰鍘嬪姏鍊 +P = [20 * ones(r.nmc, 1); 20 * ones(r.nfc, 1)]; +% plow=25; % P =plow-1e-6*800*9.8*r.z; +Sw = [0.2 * ones(r.nmc, 1); 0.2 * ones(r.nfc, 1)]; +Cs = [0.0 * ones(r.nmc, 1); 0.0 * ones(r.nfc, 1)];% kg/m3 +Cb = [50.0 * ones(r.nmc, 1); 50.0 * ones(r.nfc, 1)];% kg/m3 +% 娌硅棌鍦板眰姘寸熆鍖栧害涓鑸负 50 kg/m3锛屾敞鍏ユ按銆佸帇瑁傛恫鐨勭熆鍖栧害涓鑸负 1 kg/m3 +number_state_variables = 4; +f.number_state_variables = number_state_variables; +state0 = initialRS(P, Sw, Cs, Cb); +end \ No newline at end of file diff --git a/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/perm.fig b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/perm.fig new file mode 100644 index 0000000..d87421e Binary files /dev/null and b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/perm.fig differ diff --git a/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plotWellResponse.m b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plotWellResponse.m new file mode 100644 index 0000000..b3bcc97 --- /dev/null +++ b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plotWellResponse.m @@ -0,0 +1,55 @@ +function [] = plotWellResponse(Times,Wellpara) +% 输入 +wellNumber = 1; % 井号 +dataType = 'dPWF'; % 类型,产气速度 GPR,产气速度 OPR, 产水速度 WPR,井底流压 BHP,压力导数 dPWF +% +t = Times; +n= size(Times,1); +% para = cell2mat(Wellpara); +nw = wellNumber;%选井号 +% n = length(para); +data = zeros(n,1); +if strcmp(dataType, 'GPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qg; + figureYlegend = 'Gas production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'OPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qo; + figureYlegend = 'Oil production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'WPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qw; + figureYlegend = 'Water production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'BHP') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.pwf; + figureYlegend = 'BHP, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'dPWF') % dpwf/dlnt = t*dpwf/dt + for i = 1 : n + if i == 1 + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i}{1,nw}.pwf)/(log(t(i+1))-log(t(i))); + elseif i == n + data(i) = (Wellpara{i}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i))-log(t(i-1))); + else + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i+1))-log(t(i-1))); + end + figureYlegend = 'Pressure derivative, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); + set(gca, 'XScale', 'log'); + set(gca, 'YScale', 'log'); +end +end \ No newline at end of file diff --git a/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plot_2D_layer.m b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plot_2D_layer.m new file mode 100644 index 0000000..0d45394 --- /dev/null +++ b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plot_2D_layer.m @@ -0,0 +1,50 @@ +function plot_2D_layer(i, k, r, OutputRs, type) +coordinate=r.coordinates; +nodes=r.nodes; +nz=r.nz; +nx=r.nx; +ny=r.ny; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +if type == 1 +% v = r.kx; + v = OutputRs{i}.p; +else + v = 1-OutputRs{i}.sw;%含气饱和度 +end +dis = zeros(nel, nx*ny); +x = zeros(nel, nx*ny); +y = zeros(nel, nx*ny); +for i = 1 :nx*ny + for j = 1 :nel + grid_numbering = i+(nz-k)*nx*ny; + x(j, i) = coordinate(nodes(grid_numbering,j), 1); + y(j, i) = coordinate(nodes(grid_numbering,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(grid_numbering,4), 1); + y(j, i) = coordinate(nodes(grid_numbering,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(grid_numbering,3), 1); + y(j, i) = coordinate(nodes(grid_numbering,3), 2); + end + dis(j, i) = v(grid_numbering); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +% clim([10,15]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plot_3D_dis.m b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plot_3D_dis.m new file mode 100644 index 0000000..6674f45 --- /dev/null +++ b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plot_3D_dis.m @@ -0,0 +1,144 @@ +function plot_3D_dis(i, r,OutputRs, type) +%为便于作图进行前处理 +figure('color','w') +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dis( r ); +coordinate=r.coordinates; +nodes=r.nodes; +% nmc = size(nodes,1);%基质网格数量 +% % nel = size(nodes,2);%每个基质网格所包含的点数量 +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%用以fill函数作图 +% nel=size(order,2); +if type == 1 + v = OutputRs{i}.p; +elseif type == 2 + v = 1-OutputRs{i}.sw;%含油饱和度 +elseif type == 3 + v = OutputRs{i}.sg;%含油饱和度 +else + v = OutputRs{i}.sw;%含油饱和度 +end +% 底面 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%左面 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%右面 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%前面 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%后面 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%上面 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel('x, m'); +ylabel('y, m'); +zlabel('z, m'); +view(3); +% 绘制油藏框架 +% plotframe( r ); +alpha(1) +% caxis([0.2,0.8]); +caxis([10,13]); +% caxis([12,22]); +colormap jet +colorbar +% zlim([-2020,-2000]); +% axis equal +axis tight + diff --git a/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plot_perm.m b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plot_perm.m new file mode 100644 index 0000000..f730d14 --- /dev/null +++ b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/plot_perm.m @@ -0,0 +1,51 @@ +function plot_perm(k, r) +coordinate=r.coordinates; +nodes=r.nodes; +nz=r.nz; +nx=r.nx; +ny=r.ny; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +v = r.kx; +% if type == 1 +% % v = r.kx; +% v = OutputRs{i}.p; +% else +% v = 1-OutputRs{i}.sw;%含气饱和度 +% end +dis = zeros(nel, nx*ny); +x = zeros(nel, nx*ny); +y = zeros(nel, nx*ny); +for i = 1 :nx*ny + for j = 1 :nel + grid_numbering = i+(nz-k)*nx*ny; + x(j, i) = coordinate(nodes(grid_numbering,j), 1); + y(j, i) = coordinate(nodes(grid_numbering,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(grid_numbering,4), 1); + y(j, i) = coordinate(nodes(grid_numbering,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(grid_numbering,3), 1); + y(j, i) = coordinate(nodes(grid_numbering,3), 2); + end + dis(j, i) = v(grid_numbering); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +% clim([10,15]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/preprocess_heterogeneous.m b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/preprocess_heterogeneous.m new file mode 100644 index 0000000..01b6980 --- /dev/null +++ b/绠椾緥1-缁勫垎娴-涓嶈鍒欓潪鍧囪川璁$畻鍩/preprocess_heterogeneous.m @@ -0,0 +1,26 @@ +% 鏁版嵁璇诲彇 +nx = r.nx; +ny = r.ny; +nz = r.nz; +% dx = r.dx; +% dy = r.dy; +% dz = r.dz; +cell_mid_coords = r.cell_mid_coords; +% 涓嶈鍒欒竟鐣岃瀹 +boundary = [0,100; + 800,50; + 1000,150; + 1000,350; + 800,450; + 0,400; + 0,100]; +% 灏嗕笉鍦ㄨ竟鐣屽唴鐨勭綉鏍肩殑valid鍊艰祴涓0 +valid_in = ones(nx*ny*nz); +in = inpolygon(cell_mid_coords(:,1),cell_mid_coords(:,2),boundary(:,1),boundary(:,2)); +valid_in(~in) = 0; +% 涓句緥锛岀粰鍑烘笚閫忕巼鍑芥暟褰㈠紡 k(x,y) = (x/500+y/250+1)*1e-3 D锛屾垨鑰呴氳繃宸茬煡鐐规彃鍊艰绠楃瓑锛岄兘琛 +kx = (cell_mid_coords(:,1)/500+cell_mid_coords(:,2)/250+1)*1e-3; +ky = kx; +kz = kx; +% 涓句緥锛岀粰鍑哄瓟闅欏害鍑芥暟褰㈠紡 phi(x,y) = (x/20000+y/10000+0.1)锛屾垨鑰呴氳繃宸茬煡鐐规彃鍊艰绠楃瓑锛岄兘琛 +pori = (cell_mid_coords(:,1)/20000+cell_mid_coords(:,2)/10000+0.1); \ No newline at end of file diff --git a/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/grid_discretization_SP_model.m b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/grid_discretization_SP_model.m new file mode 100644 index 0000000..6141739 --- /dev/null +++ b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/grid_discretization_SP_model.m @@ -0,0 +1,55 @@ +function r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf) +% 鏁版嵁璇诲彇 +nx = r.nx; ny = r.ny; nz = r.nz; NTG = r.NTG; cell_mid_coords = r.cell_mid_coords; +% 鍩鸿川瀛旀笚 +rock_density = 2700; % 宀╃煶瀵嗗害锛宬g/m^3 +kx = 1*1e-3 * ones(nx*ny*nz, 1); % 杈捐タ锛孌 +ky = 1*1e-3 * ones(nx*ny*nz, 1);% +kz = 1*1e-3 * ones(nx*ny*nz, 1);% +pori = 0.08 * ones(nx*ny*nz, 1);% +prpor = 20; % 鍙傝冨帇鍔涳紝MPa +cpor = 1.0e-5;% 鍩鸿川鍘嬬缉绯绘暟锛,MPa +% 鏈夋晥缃戞牸 +valid_grids = ones(nx*ny*nz, 1); +invalid_layer = 2; % 灏嗙浜屽眰鏃犳晥缃戞牸 +for i = 1:length(invalid_layer) + grid_numbering_range = ((invalid_layer(i)-1)*nx*ny+1:invalid_layer(i)*nx*ny)'; + valid_grids(grid_numbering_range,1) = 0; +end +% SRV鍖哄煙瀹氫箟 +% % % base_x=23:78; nx_SRV=length(base_x); +% % % base_y=15:36; ny_SRV=length(base_y); +% % % base_z=1:1;nz_SRV=length(base_z); +% % % SRV=[]; +% % % for k=1:nz_SRV +% % % for j=1:ny_SRV +% % % for i=1:nx_SRV +% % % SRV=[SRV;(base_z(k)-1)*nx*ny+(base_y(j)-1)*nx+base_x(i)]; +% % % end +% % % end +% % % end +% % % % SRV娓楅忕巼璧嬪 +% % % kx(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % ky(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % kz(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% 瑁傜紳瀛旀笚 +Kf = 10000*1e-3*ones(1,nf);% 瑁傜紳娓楅忕巼 +Wf = 1e-2*ones(1,nf);% 瑁傜紳寮搴 +Porf = 0.30*ones(1,nf);% 瑁傜紳瀛旈殭搴 +prporf = 20;% 瑁傜紳绯荤粺鍙傝冨帇鍔 +cporf = 1.0e-5;% 瑁傜紳绯荤粺鍘嬬缉绯绘暟 +% 搴斿姏鏁忔劅绯绘暟 +stress_factor_fracture = 0.000; % 1/MPa 0.001 +stress_factor_matrix = 0.000; % 1/MPa +stress_factor_ref_pressure = 20; % 涓鑸彇涓哄師濮嬪湴灞傚帇鍔 +% +Rpt = 2;cf = 1;ca = 1; +%% 缁撳悎鍩鸿川銆佽缂濈殑鍑犱綍鍙婄墿鎬т俊鎭紑灞曞墠澶勭悊 +% r = GridProp(modelflag, nx, ny, nz, dx, dy, dz, kx, ky, kz, f, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,co, NTG); +r = GridProp_new(modelflag, r, kx, ky, kz, f, frac_information, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca, valid_grids); +r.rock_density = rock_density; +r.valid_grids = valid_grids; +r.stress_factor_fracture = stress_factor_fracture; +r.stress_factor_matrix = stress_factor_matrix; +r.stress_factor_ref_pressure = stress_factor_ref_pressure; +end \ No newline at end of file diff --git a/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/main1.m b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/main1.m new file mode 100644 index 0000000..1759026 --- /dev/null +++ b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/main1.m @@ -0,0 +1,205 @@ +function [ r, Times, OutputRs, Wellpara, trun ] = main1() +%% ==================================PART 1: 妯″瀷閫夊彇======================================== +% 1-- classical EDFM +modelflag = 1;% 姝ゅ鍥哄畾涓1鍗冲彲 +%% ==================================PART 2: 鍩鸿川缃戞牸瀹氫箟===================================== +dx=[10*ones(1,100) ];nx=size(dx,2); +dy=[10*ones(1,50) ];ny=size(dy,2); +dz=[10*ones(1,3)];nz=size(dz,2); +NTG= 1*ones(nx*ny*nz,1); +r = GridProp_pre(dx,dy,dz,nx,ny,nz,NTG); +%% ==================================PART 3: 瑁傜紳鍒嗗竷鏁版嵁杈撳叆===================================== +% 鍥涚杈撳叆鏂瑰紡: 1琛ㄧず宸ョ▼搴旂敤杈撳叆锛2琛ㄧず鍚戦噺杈撳叆锛3琛ㄧず宸ョ▼搴旂敤杈撳叆锛屽寘鎷熀鍑嗙偣銆佸捐銆佹柟浣嶈銆佹姮鍗囪锛4琛ㄧず浠.fab鏂囦欢璇诲彇 +input_style = 1; +%% 杈撳叆鏂瑰紡1锛氬伐绋嬪簲鐢ㄨ緭鍏 +%浠呰兘鍒荤敾鍏锋湁鍙屽绉版ц川鐨勭煩褰㈢紳鎴栨き鍦嗙紳 +% 鍩哄噯鐐瑰潗鏍囷紙1锛夛紝鏂逛綅瑙掞紙2锛夛紝鍊捐锛3锛夛紝鎶崌瑙掞紙4锛夛紝缂濋暱锛堟き鍦嗛暱杞撮暱锛夛紙5锛夛紝缂濋珮锛堟き鍦嗙煭杞撮暱锛夛紙6锛夛紝绫诲瀷1鏄煩褰㈢紳銆2鏄き鍦嗙紳锛7锛 +if input_style==1 +input_content={ + [255,255,5],90,90,0,200,10,1; + [305,255,5],90,90,0,200,10,1; + [355,255,5],90,90,0,200,10,1; + [405,255,5],90,90,0,200,10,1; + [455,255,5],90,90,0,200,10,1; + [505,255,5],90,90,0,200,10,1; + [555,255,25],90,90,0,200,10,1; + [605,255,25],90,90,0,200,10,1; + [655,255,25],90,90,0,200,10,1; + [705,255,25],90,90,0,200,10,1; + [755,255,25],90,90,0,200,10,1; + }; +[f,fellip] = sort_fracture(input_content); +flowBarrierFlags = []; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5; +frac_information = fractureInformation_input_engineering_vector(f,fellip,flowBarrierFlags); +end +%% 杈撳叆鏂瑰紡2锛氬悜閲忚緭鍏 +%棣栧厛瀵圭煩褰㈢紳杩涜鐮旂┒锛岃缂濆弬鏁板寘鎷笁涓悜閲忓拰涓や釜鍙傛暟鐨勫彇鍊艰寖鍥达紝濡傛灉鏄叾瀹冪被鍨嬬紳锛屽垯鏄袱涓弬鏁伴棿鐨勫嚱鏁板叧绯 +%鍥犳涓涓5琛屼笁鍒楃殑鐭╅樀鍙互纭畾涓鏉¤缂 +%鍚戦噺鍒嗛噺鍙负闈炴暣鏁帮紝浠ユ淇濊瘉鍙傛暟鑼冨洿鐨勫彇鍊间负鏁存暟鍗冲彲锛 +%鏁呭彲鍏堥殢鎰忕‘瀹氫负鏁存暟鐨勫弬鏁拌寖鍥达紝鍐嶆牴鎹紳闀跨紳楂樺幓纭畾鍚戦噺鍒嗛噺鐨勫彇鍊 +% 鐭╁舰缂 +if input_style==2 + f=[ + 0,1200,0;10,-20,0;0,0,10;0,60,0;0,3,0; + 0,1200,0;10,20,0;0,0,10;0,15,0;0,3,0; + 150,1500,0;20,-10,0;0,0,10;0,20,0;0,3,0; + 550,1300,0;10,10,0;0,0,10;0,10,0;0,3,0; + 650,1400,0;10,-20,0;0,0,10;0,55,0;0,3,0; + 605,705,0;10,0,0;0,0,10;-20,20,0;0,3,0; + ]; +% 妞渾缂 +% fellip=[320,210,10;10,2,0;0,0,2;0,0,8;0,0,5; +% 280,300,10;10,2,0;0,0,2;0,0,10;0,0,4;]; +% 300,205,10;10,0,0;0,0,2;0,0,10;0,0,5]; +fellip=[]; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +frac_information = fractureInformation_input_engineering_vector(f,fellip); +end +%% 杈撳叆鏂瑰紡3锛氫簩缁磋緭鍏 +% load('fractures_generated.mat'); +% fractureLines = fractures_generated; +if input_style==3 +fractureLines = [ + 105,150;105,350; + 205,150;205,350; + 305,150;305,350; + 405,150;405,350; + 505,150;505,350; + 605,150;605,350; + 705,150;705,350; + 805,150;805,350; + 905,150;905,350; + ]; +fellip=[]; % 妞渾缂 +fractureHeights = [ + 10;10;10;10;10;10;10;10;10]; +% 妞渾缂 +fellip=[]; +flowBarrierFlags = [];% flowBarrierFlags = [1;2;3;4]; +[f,frac_information] = input_fracture_2D(fractureLines,fractureHeights,flowBarrierFlags); +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +end +%% 杈撳叆鏂瑰紡4锛氫粠.fab鏂囦欢璇诲彇 Frac_PT +if input_style==4 + +end + +%% ==================================PART 4: 鍩鸿川缃戞牸鍙婅缂濈墿鎬у弬鏁拌緭鍏===================================== +% 1-- 鍗曢噸浠嬭川 +% 2-- 鍙岄噸浠嬭川锛堝弻瀛斿弻娓楋級 +grid_model = 1; +if grid_model == 1 +r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf); +end +if grid_model == 2 +r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf); +end + +%% 鐢熸垚鍚戦噺鍖栧彉鎴愭墍闇瑕佺殑绠楀瓙 +os = OperatorRS(r.N, r.nex, r.nc); + +%% ==================================PART 5: 妯″瀷绫诲瀷閫夊彇鍙婂垵濮嬬姸鎬佽瀹========================================= +% 1-- 姘旀按涓ょ浉娴 +% 2-- 娌规按涓ょ浉娴 +flow_model = 3; +if flow_model == 1 +[f,state0] = gas_water_flow(r); +end +if flow_model == 2 +[f,state0] = oil_water_flow(r); +end +if flow_model == 3 +[f,state0] = multi_component_flow(r); +end + +%% ==================================PART 6: 浜曞埗搴chedule璁惧畾================================================ +%灏嗙洿浜曘佹按骞充簳涓庡娈靛帇瑁傛按骞充簳鍒嗗紑澶勭悊 +%% 鐩翠簳銆佸父瑙勬按骞充簳瀹氫箟 +% Wellcpara: wellname(1) nperf锛屽皠瀛旂偣鏁伴噺(2) index(3) rw(4) skin(5) welltype(6) +% welltype=1 鐩翠簳锛寃elltype=2 姘村钩浜曟部x鏂瑰悜锛寃elltype=3 姘村钩浜曟部y鏂瑰悜 welltype=4 澶氭鍘嬭姘村钩浜 +% 鐩翠簳銆佹按骞充簳锛岃绉嶄簳鍨嬬殑澶勭悊鏄皢灏勫瓟娈靛畨鎺掑湪鍩鸿川缃戞牸 +% 瀵逛簬鐩翠簳銆佹枩浜曘佹按骞充簳锛岄噰鍙栦笌eclipse涓鑷寸殑鏂瑰紡锛岀粰鍑哄叾鍦ㄥ熀璐ㄧ綉鏍间腑浣嶇疆 +% 姣忎釜灏勫瓟鐐圭敱涓媝x,py,pz纭畾锛屽垎鍒〃绀鸿灏勫瓟鐐瑰湪x鏂瑰悜锛寉鏂瑰悜鐨勭綉鏍肩紪鍙凤紝鍙婂眰鏁板嵆z鍙嶆柟鍚戜笂鐨勭綉鏍肩紪鍙凤紙鏈鍒濇槸浠ュ瀭鐩村悜涓婂缓绔嬬殑鍩鸿川缃戞牸锛 +well1={ + % 'w1', 2, [20 10 1;20 10 2;], 0.178/2, 0, 1; + % 'w2', 2, [80 10 1;80 10 2;], 0.178/2, 0, 1; + % 'w3', 1, [20 40 1;], 0.178/2, 0, 1; + % 'w4', 1, [80 40 1;], 0.178/2, 0, 1; +% 'w2', 3, [67 20 1;67 20 2;67 20 3], 0.178/2, 0, 1; + }; +well1 = handle_well1(well1,r); +%% 鍘嬭姘村钩浜曞畾涔 +% 澶氭鍘嬭姘村钩浜曪細灏勫瓟娈佃缃湪瑁傜紳鍗曞厓涓婏紝鍙互缁欏嚭璇ュ皠瀛旂偣鎵鍦ㄧ殑鍧愭爣锛岀劧鍚庡幓瀵绘壘璇ョ偣鎵鍦ㄧ殑瑁傜紳鍗曞厓缂栧彿 +num_fracture_wells = 1; +welloc = cell(num_fracture_wells,1); +perfnum = cell(num_fracture_wells,1); +welloc{1,1}=[ + 255,255,5; + 305,255,5; + 355,255,5; + 405,255,5; + 455,255,5; + 505,255,5; + 555,255,25; + 605,255,25; + 655,255,25; + 705,255,25; + 755,255,25; + ]; +for i = 1:num_fracture_wells +perfnum{i,1} = findWelloc(r, welloc{i,1});%鍦ㄧ敤浠ellc0涔嬩腑 +end +% perfnum2 = findWelloc(r, welloc2); +well2={ + 'w1', length(perfnum{1,1}), perfnum{1,1}, 0.178/2, 0,4; + }; +Wellc = handle_well1_well2(well1,well2,welloc,r); %鍔犱簳鍜屽皠瀛斾綅缃 +%% 浜曞埗搴﹁缃紙寮鍏充簳銆佸畾鍘/瀹氫骇銆佷究浜庡悶鍚愮瓑锛 +number_phases = 3; +well_schedules = cell(number_phases,1); +time = zeros(number_phases,1); +% 涓嶅悓鏂瑰紡瀵瑰簲鐨勬敹鏁涢毦搴︺侀渶瑕佷笉涓鏍凤紝闇鍒嗛樁娈佃皟鎺э紝 +% 渚嬪鍦ㄦ敞鍏ラ樁娈甸渶瑕佸皬涓浜涳紝濡傛灉闇瑕佸仛鏃╂湡璇曚簳锛宒tmax銆乨tmin閮介渶瑕佸皬涓浜 +dtmax = zeros(number_phases,1); +dtmin = zeros(number_phases,1); + +% (1)well state: 'open'琛ㄧず璇ヤ簳鏄紑鐨勶紱'close'琛ㄦ槑璇ヤ簳涓鐩存槸鍏崇殑锛屽鏋滃彧鏄樁娈垫у叧浜曪紝灏辩敤'open'瀹氭祦閲0鐢熶骇 +% (2)well type: 'pro'琛ㄧず鏄敓浜т簳锛'inj'琛ㄧず鏄敞鍏ヤ簳; +% (3)protype锛'const_q'鏄畾娴侀噺锛'const_pwf'鍒欐槸瀹氬帇 +% (4)value锛氬畾鐨勬祦閲忓兼垨鑰呬簳搴曞帇鍔涘 +% (5)value锛氭浠g爜璇ュ间笌锛3锛夊肩浉鍚 +% (8)value锛氭敞鍏ヨ〃娲诲墏鐨勬祿搴 kg/m3 +% (10)value锛氭敞鍏ユ按/鍘嬭娑茬殑鐩愭祿搴︼紙鐭垮寲搴︼級锛屼竴鑸槸 1kg/m3 +time(1) = 10; dtmax(1) = 0.1; dtmin(1) = 0.001; +well_schedules{1,1} = { + % 'w1','open','inj','const_pwf',30,30; + % 'w2','open','inj','const_pwf',30,30; + % 'w3','open','inj','const_pwf',30,30; + % 'w4','open','inj','const_pwf',30,30; + 'w1','open','inj','const_pwf',40,40,'Cs_inj',0.5,'Cb_inj',1}; +time(2) = 30; dtmax(2) = 0.5; dtmin(2) = 0.001; +well_schedules{2,1} = { + 'w1','open','pro','const_q',0,0; + % 'w1','open','pro','const_pwf',10,10; + % 'w2','open','pro','const_q',0,0; + }; +time(3) = 200; dtmax(3) = 0.5; dtmin(3) = 0.001; +well_schedules{3,1} = { + 'w1','open','pro','const_pwf',10,10; + % 'w2','open','pro','const_pwf',10,10; + }; + +%% ======================================PART 7: Solver璁剧疆=========================================== +yitap = 5; % 50-500psi +yitas = 0.04; % 0.05-0.5 +omega = 0.5; % 0-1 +Nmax = 50; +epsave = 1e-6; +epsmax = 1e-6; + +%% ======================================PART 8: 姝e紡璁$畻=========================================== +[Times, OutputRs, Wellpara, trun] = solver_NR(r, flow_model, f, os, state0, yitap,yitas,omega,Nmax,epsave,epsmax,dtmin,dtmax,Wellc,time,well_schedules); +run_time=toc; +trun.run_time=run_time; +end \ No newline at end of file diff --git a/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/multi_component_flow.m b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/multi_component_flow.m new file mode 100644 index 0000000..94eb4b0 --- /dev/null +++ b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/multi_component_flow.m @@ -0,0 +1,232 @@ +function [f,state0] = multi_component_flow(r) +%% 娴佷綋鎬ц川鍙傛暟 +%% 姘寸浉涓殑琛ㄦ椿鍓傘佺洂鐨勬墿鏁g郴鏁 +Ds = 0.76*1e-9; % m2/s +Db = 2.2*1e-9; % m2/s +%% 琛ㄦ椿鍓傘佺洂鍦ㄥ博鐭宠〃闈㈢殑鍚搁檮娴撳害涓庢按鐩告祿搴︾殑鍏崇郴琛紝绗竴鍒楀崟浣嶆槸kg/m3, 绗簩鍒楀拰绗笁鍒楀崟浣嶆槸g/kg +c_ca_table = [ +0 0 0 +0.05 1 0.075 +0.1 1.75 0.125 +0.2 3 0.2 +0.5 4.35 0.325 +1 4.55 0.365 +]; +cs_data = c_ca_table(:,1); +cb_data = c_ca_table(:,1); +csa_data = c_ca_table(:,2)*1e-3; % 杞崲涓 kg/kg +cba_data = c_ca_table(:,3)*1e-3; % 杞崲涓 kg/kg +%% 鍖栧鍔匡紙鍘嬭娑蹭笌鍦板眰姘寸殑鐩愬害宸紓缁欐按鐩稿甫鏉ョ殑棰濆鍘嬪樊锛 +R = 0.008314; % kJ/(mol*K) +Vm = 18.02*1e-6; % 姘寸殑鍋忔懇灏斾綋绉紝m^3/mol +Temperature = 293.15; % 娓╁害锛孠 +chemistry_cof = R*Temperature/Vm*1e-3/10; +%% 鍔ㄦ佺浉娓楋紙鍑告樉鍑鸿〃娲诲墏瀵圭浉娓楃殑褰卞搷锛 +% 鍘熸湰搴斿厛寰楀埌琛ㄦ椿鍓傛祿搴︿笌琛ㄩ潰寮犲姏鐨勫叧绯伙紝鍐嶇粨鍚堟笚娴侀熷害璁$畻鍑轰釜琛ㄩ潰寮犲姏瀵瑰簲鐨勬瘺绠℃暟锛 +% 涓轰簡绠渚夸唬鐮佺紪鍐欙紝姝ゅ蹇界暐娓楁祦閫熷害鐨勫奖鍝嶏紝 +% 骞跺寮轰唬鐮侀氱敤鎬э紝姝ゅ鏀逛负杈撳叆琛ㄦ椿鍓傛祿搴︿笌姣涚鏁扮殑瀵瑰簲琛ㄦ牸锛 +% 绗竴鍒椾负琛ㄦ椿鍓傛祿搴︼紝绗簩鍒椾负鐩稿簲鐨勬瘺绠℃暟,锛岀涓夊垪鏄浉搴旂殑琛ㄩ潰寮犲姏 +% dynamic_kr = 1; +cs_Nc = [ +0 1.6*1e-6 30 +0.1 9.5*1e-6 10 +0.2 2.5*1e-5 4 +0.5 5.8*1e-5 1.4 +1 8.2*1e-5 1 +2 8.8*1e-5 0.75 +]; +Nc_nosurf = min(cs_Nc(:,2)); +Nc_surf = max(cs_Nc(:,2)); + +kr_nosurf = [ +0 0 0.64 +0.25 0 0.64 +0.30 0.072 0.6 +0.40 0.14 0.56 +0.50 0.26 0.48 +0.60 0.4 0.38 +0.70 0.56 0.26 +0.85 0.88 0 +1 0.88 0 + ]; + +kr_surf = [ +0 0 0.6 +0.18 0 0.6 +0.25 0.056 0.56 +0.30 0.1 0.52 +0.40 0.19 0.42 +0.50 0.29 0.3 +0.60 0.37 0.19 +0.75 0.46 0 +1 0.46 0 + ]; + +PC = [ +0 3.8916 +0.2 3.8916 +0.316 0.5796 +0.435 0.3724 +0.562 0.2425 +0.614 0.0608 +0.702 0.0372 +0.812 0.0137 +0.875 0.0104 +0.906 0.009 +0.937 0.0075 +0.969 0.0059 +1 0 +]; +cs_Nc_fracture = cs_Nc; +kr_nosurf_fracture = kr_nosurf; +kr_surf_fracture = kr_surf; +PC_fracture = PC; +ifpcgl = 0; % 鏄惁鑰冭檻姣涚鍔 +%% 鍚姩鍘嬪姏姊害 +p_grad_threshold = 0.00; % MPa/m +%% ================姘旂浉Langmuir绛夋俯鍚搁檮妯″瀷锛屽綋 VL=0锛屼害鍙敤浜庢补鐩=============== +% VE = VL*P/(PL+P) +gas_prop.VL = 0.0; % Langmuir volume, m^3/kg +gas_prop.PL = 3.5; % Langmuir pressure, MPa +% Psc = 1; +% Zsc = 1; +% density_rock = 2000; % +% ===================== Knudsen 鎵╂暎绯绘暟锛屽綋 Kn=0锛屼害鍙敤浜庢补鐩 ==================== +gas_prop.Kn = 0; % Knudsen鏁 +c1 =1; c2 =8/9; +gas_prop.Kn_modified_factor = 1+8*c1*gas_prop.Kn+16*c2*gas_prop.Kn^2; +% ===================== 楂橀熼潪杈捐タ娴 Forchheimer 鏂圭▼ ==================== +gas_prop.beta_non_Darcy_flow = 0; % 1e-8 +% =======================姘旂浉浣撶Н绯绘暟銆佺矘搴=============================== +density_g_sc = 800; +% 绗竴绉嶆ā寮忥紝鐩存帴杈撳叆鍙傝冨帇鍔涖佷綋绉郴鏁般佸帇缂╃郴鏁般佺矘搴 +gas_model =1; +if gas_model == 1 +prg = 20; % reference pressure, MPa +Bgi = 1; % gas phase volume factor +cg = 5e-4 ;% gas phase compressibility, 1/MPa +vgi = 6; % gas viscosity, cp +cvg = 0; +[Ppr,BG,MUG] = cal_gas_prop(prg,Bgi,cg,vgi,cvg); +end +if gas_model == 2 +Ppr = [ 0.1013 + 2.0946 + 4.0878 + 6.0811 + 8.0743 + 10.0676 + 12.0608 + 14.0540 + 16.0473 + 18.0405 + 20.0338 + 22.0270 + 24.0203 + 26.0135 + 28.0068 + 30.0000 + ]; +% BG = 0.01*ones(size(Ppr,1),1); +BG = [ 1.18297 + 0.0557041 + 0.0278168 + 0.0182594 + 0.0134665 + 0.0106154 + 0.00874829 + 0.00744907 + 0.00650639 + 0.0058006 + 0.0052587 + 0.0048336 + 0.00449378 + 0.00421751 + 0.0039895 + 0.00379871 + ]; +% MUG = 0.01*ones(size(Ppr,1),1); +MUG = [0.0127683 + 0.0130191 + 0.0133973 + 0.013872 + 0.014437 + 0.015088 + 0.0158182 + 0.0166173 + 0.0174719 + 0.0183671 + 0.0192882 + 0.0202219 + 0.0211575 + 0.0220865 + 0.0230024 + 0.0239008 + ]; +end +% ========================姘寸浉浣撶Н绯绘暟銆佺矘搴=============================== +density_w_sc = 1000; +prw = 20; % reference pressure +Bwi = 1.000; % water phase volume factor +cw = 4.0e-4 ;% water phase compressibility +vwi = 1; % viscosity +cvw = 0; +% =============================鍩鸿川鐩告笚=============================== +% ifpcgl = 0; % 鏄惁鑰冭檻姣涚鍔 +% RPGW=[ +% 0.0000 0.0000 1.0000 3.8916 +% 0.2000 0.0000 1.0000 3.8916 +% 0.3160 0.0002 0.6784 0.5796 +% 0.4350 0.0004 0.6215 0.3724 +% 0.5620 0.0010 0.5456 0.2425 +% 0.6140 0.0020 0.3939 0.0608 +% 0.7020 0.0280 0.1399 0.0372 +% 0.8120 0.1721 0.0515 0.0137 +% 0.8750 0.3395 0.0297 0.0104 +% 0.9060 0.4395 0.0226 0.0090 +% 0.9370 0.5500 0.0173 0.0075 +% 0.9690 0.6702 0.0131 0.0059 +% 1.0 1.0000 0.0000 0.0000 +% ]; +% SW=RPGW(:,1);KRW=RPGW(:,2);KRG=RPGW(:,3);PCGL=RPGW(:,4); +% +% % =============================瑁傜紳鐩告笚=============================== +% PRF=[ +% 0.0000 0.0000 1.0000 3.8916 +% 0.2000 0.0000 1.0000 3.8916 +% 0.3160 0.0002 0.6784 0.5796 +% 0.4350 0.0004 0.6215 0.3724 +% 0.5620 0.0010 0.5456 0.2425 +% 0.6140 0.0020 0.3939 0.0608 +% 0.7020 0.0280 0.1399 0.0372 +% 0.8120 0.1721 0.0515 0.0137 +% 0.8750 0.3395 0.0297 0.0104 +% 0.9060 0.4395 0.0226 0.0090 +% 0.9370 0.5500 0.0173 0.0075 +% 1.0 1.0000 0.0000 0.0000 +% ]; +% SWF = PRF(:,1);KRWF = PRF(:,2);KRGF = PRF(:,3);PCGLF=PRF(:,4); + +%% 缁撳悎娴佷綋鎬ц川鍙傛暟鐢熸垚鐩稿簲鐨勬暟鎹綋 +% f = fluidPVT(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, SW, KRG, KRW, PCGL, SWF, KRGF, KRWF, PCGLF, density_g_sc, ifpcgl, r.rpt, cs_data, csa_data, cb_data, cba_data, cs_Nc, kr_nosurf, kr_surf); +f = fluidPVT_new(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, ifpcgl, r.rpt, cs_data, csa_data, cb_data, cba_data, cs_Nc, Nc_nosurf, Nc_surf, kr_nosurf, kr_surf, PC, cs_Nc_fracture, kr_nosurf_fracture, kr_surf_fracture, PC_fracture); +f.Dwsi = density_w_sc; +f.Dgsi = density_g_sc; +f.gas_prop = gas_prop; +f.Ds = Ds; +f.Db = Db; +f.chemistry_cof = chemistry_cof; +f.p_grad_threshold = p_grad_threshold; +%% 鍒濆兼潯浠 Initial Condition Section +% =================鍘嬪姏銆侀ケ鍜屽害鍒濆======================================= % +%鍘嬪姏鍒濆艰鑰冭檻閲嶅姏锛岀粰鍑烘补钘忎笅琛ㄩ潰鍘嬪姏鍊 +P = [20 * ones(r.nmc, 1); 20 * ones(r.nfc, 1)]; +% plow=25; % P =plow-1e-6*800*9.8*r.z; +Sw = [0.2 * ones(r.nmc, 1); 0.2 * ones(r.nfc, 1)]; +Cs = [0.0 * ones(r.nmc, 1); 0.0 * ones(r.nfc, 1)];% kg/m3 +Cb = [50.0 * ones(r.nmc, 1); 50.0 * ones(r.nfc, 1)];% kg/m3 +% 娌硅棌鍦板眰姘寸熆鍖栧害涓鑸负 50 kg/m3锛屾敞鍏ユ按銆佸帇瑁傛恫鐨勭熆鍖栧害涓鑸负 1 kg/m3 +number_state_variables = 4; +f.number_state_variables = number_state_variables; +state0 = initialRS(P, Sw, Cs, Cb); +end \ No newline at end of file diff --git a/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/plotWellResponse.m b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/plotWellResponse.m new file mode 100644 index 0000000..b3bcc97 --- /dev/null +++ b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/plotWellResponse.m @@ -0,0 +1,55 @@ +function [] = plotWellResponse(Times,Wellpara) +% 输入 +wellNumber = 1; % 井号 +dataType = 'dPWF'; % 类型,产气速度 GPR,产气速度 OPR, 产水速度 WPR,井底流压 BHP,压力导数 dPWF +% +t = Times; +n= size(Times,1); +% para = cell2mat(Wellpara); +nw = wellNumber;%选井号 +% n = length(para); +data = zeros(n,1); +if strcmp(dataType, 'GPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qg; + figureYlegend = 'Gas production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'OPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qo; + figureYlegend = 'Oil production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'WPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qw; + figureYlegend = 'Water production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'BHP') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.pwf; + figureYlegend = 'BHP, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'dPWF') % dpwf/dlnt = t*dpwf/dt + for i = 1 : n + if i == 1 + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i}{1,nw}.pwf)/(log(t(i+1))-log(t(i))); + elseif i == n + data(i) = (Wellpara{i}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i))-log(t(i-1))); + else + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i+1))-log(t(i-1))); + end + figureYlegend = 'Pressure derivative, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); + set(gca, 'XScale', 'log'); + set(gca, 'YScale', 'log'); +end +end \ No newline at end of file diff --git a/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/plot_2D_layer.m b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/plot_2D_layer.m new file mode 100644 index 0000000..5eb8afc --- /dev/null +++ b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/plot_2D_layer.m @@ -0,0 +1,51 @@ +function plot_2D_layer(i, k, r, OutputRs, type) +coordinate=r.coordinates; +nodes=r.nodes; +nz=r.nz; +nx=r.nx; +ny=r.ny; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +if type == 1 +% v = r.kx; + v = OutputRs{i}.p; +else + v = 1-OutputRs{i}.sw;%含气饱和度 +end +dis = zeros(nel, nx*ny); +x = zeros(nel, nx*ny); +y = zeros(nel, nx*ny); +for i = 1 :nx*ny + for j = 1 :nel + grid_numbering = i+(nz-k)*nx*ny; + x(j, i) = coordinate(nodes(grid_numbering,j), 1); + y(j, i) = coordinate(nodes(grid_numbering,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(grid_numbering,4), 1); + y(j, i) = coordinate(nodes(grid_numbering,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(grid_numbering,3), 1); + y(j, i) = coordinate(nodes(grid_numbering,3), 2); + end + dis(j, i) = v(grid_numbering); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +clim([10,20]); +colorbar +colormap jet +saveas(gcf, sprintf('第%d层压力分布.fig', k)); +% fill(x,y,dis); +% axis off diff --git a/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/plot_3D_dis.m b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/plot_3D_dis.m new file mode 100644 index 0000000..6674f45 --- /dev/null +++ b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/plot_3D_dis.m @@ -0,0 +1,144 @@ +function plot_3D_dis(i, r,OutputRs, type) +%为便于作图进行前处理 +figure('color','w') +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dis( r ); +coordinate=r.coordinates; +nodes=r.nodes; +% nmc = size(nodes,1);%基质网格数量 +% % nel = size(nodes,2);%每个基质网格所包含的点数量 +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%用以fill函数作图 +% nel=size(order,2); +if type == 1 + v = OutputRs{i}.p; +elseif type == 2 + v = 1-OutputRs{i}.sw;%含油饱和度 +elseif type == 3 + v = OutputRs{i}.sg;%含油饱和度 +else + v = OutputRs{i}.sw;%含油饱和度 +end +% 底面 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%左面 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%右面 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%前面 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%后面 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%上面 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel('x, m'); +ylabel('y, m'); +zlabel('z, m'); +view(3); +% 绘制油藏框架 +% plotframe( r ); +alpha(1) +% caxis([0.2,0.8]); +caxis([10,13]); +% caxis([12,22]); +colormap jet +colorbar +% zlim([-2020,-2000]); +% axis equal +axis tight + diff --git a/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/绗1灞傚帇鍔涘垎甯.fig b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/绗1灞傚帇鍔涘垎甯.fig new file mode 100644 index 0000000..59e9d43 Binary files /dev/null and b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/绗1灞傚帇鍔涘垎甯.fig differ diff --git a/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/绗2灞傚帇鍔涘垎甯.fig b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/绗2灞傚帇鍔涘垎甯.fig new file mode 100644 index 0000000..395857b Binary files /dev/null and b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/绗2灞傚帇鍔涘垎甯.fig differ diff --git a/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/绗3灞傚帇鍔涘垎甯.fig b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/绗3灞傚帇鍔涘垎甯.fig new file mode 100644 index 0000000..a695ef4 Binary files /dev/null and b/绠椾緥2-缁勫垎娴-鏃犳晥缃戞牸/绗3灞傚帇鍔涘垎甯.fig differ diff --git a/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/grid_discretization_DP_model.m b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/grid_discretization_DP_model.m new file mode 100644 index 0000000..b5f4ae2 --- /dev/null +++ b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/grid_discretization_DP_model.m @@ -0,0 +1,70 @@ +function r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf) +% 鏁版嵁璇诲彇 +nx = r.nx; ny = r.ny; nz = r.nz; NTG = r.NTG; cell_mid_coords = r.cell_mid_coords; +% 瑁傜紳灞傜綉鏍兼笚娓楅忕巼 +kx = 5*1e-3 * ones(nx*ny*nz, 1); % 杈捐タ锛孌 +% load('kx.mat'); +ky = 5*1e-3 * ones(nx*ny*nz, 1);% +kz = 5*1e-3 * ones(nx*ny*nz, 1);% +pori = 0.01 * ones(nx*ny*nz, 1);% +prpor = 20; % 鍙傝冨帇鍔涳紝MPa +cpor = 1.0e-5;% 鍩鸿川鍘嬬缉绯绘暟锛孧Pa +NTG= 1 * ones(nx*ny*nz, 1); +% 鍩鸿川灞傜綉鏍兼笚閫忕巼 +kx_matrixLayer = 0.01*1e-3 * ones(nx*ny*nz, 1); % 杈捐タ锛孌 +ky_matrixLayer = 0.01*1e-3 * ones(nx*ny*nz, 1);% +kz_matrixLayer = 0.01*1e-3 * ones(nx*ny*nz, 1);% +pori_matrixLayer = 0.1 * ones(nx*ny*nz, 1);% +% prpor = 20; % 鍙傝冨帇鍔涳紝MPa +% cpor = 1.0e-5;% 鍩鸿川鍘嬬缉绯绘暟锛孧Pa +% 褰㈢姸鍥犲瓙 +sigma = 0.08*ones(nx*ny*nz, 1); +for k = 1:nz + for j= 1:ny + for i= 1:floor(nx/2) + grid_numbering = (k-1)*(nx*ny)+(j-1)*nx+i; + sigma(grid_numbering,1) = 0.08; + end + end +end +% 鏈夋晥缃戞牸 +valid_grids = ones(nx*ny*nz, 1); +% SRV鍖哄煙瀹氫箟 +% % % base_x=23:78; nx_SRV=length(base_x); +% % % base_y=15:36; ny_SRV=length(base_y); +% % % base_z=1:1;nz_SRV=length(base_z); +% % % SRV=[]; +% % % for k=1:nz_SRV +% % % for j=1:ny_SRV +% % % for i=1:nx_SRV +% % % SRV=[SRV;(base_z(k)-1)*nx*ny+(base_y(j)-1)*nx+base_x(i)]; +% % % end +% % % end +% % % end +% % % % SRV娓楅忕巼璧嬪 +% % % kx(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % ky(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % kz(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% 瑁傜紳瀛旀笚 +Kf = 10000*1e-3*ones(1,nf);% 瑁傜紳娓楅忕巼 +Wf =1e-2*ones(1,nf);% 瑁傜紳寮搴 +Porf = 0.30*ones(1,nf);% 瑁傜紳瀛旈殭搴 +prporf = 20;% 瑁傜紳绯荤粺鍙傝冨帇鍔 +cporf = 1.0e-5;% 瑁傜紳绯荤粺鍘嬬缉绯绘暟 +% 搴斿姏鏁忔劅绯绘暟 +stress_factor_fracture = 0.000; % 1/MPa 0.001 +stress_factor_matrix = 0.000; % 1/MPa +stress_factor_ref_pressure = 20; % 涓鑸彇涓哄師濮嬪湴灞傚帇鍔 +% +Rpt = 2;cf = 1;ca = 1; +%% 缁撳悎鍩鸿川銆佽缂濈殑鍑犱綍鍙婄墿鎬т俊鎭紑灞曞墠澶勭悊 +% r = GridProp_new(modelflag, nx, ny, nz, dx, dy, dz, kx, ky, kz, f, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,co, NTG); +r = GridProp_DP(modelflag, r, kx, ky, kz, kx_matrixLayer, ky_matrixLayer, kz_matrixLayer, f, frac_information, fellip, Kf, Wf, pori, pori_matrixLayer, prpor, cpor, Porf, prporf, cporf, cf, ca,NTG,sigma,valid_grids); +rock_density = 2700; % 宀╃煶瀵嗗害锛宬g/m^3 +r.sigma = sigma; +r.rock_density = rock_density; +r.valid_grids = valid_grids; +r.stress_factor_fracture = stress_factor_fracture; +r.stress_factor_matrix = stress_factor_matrix; +r.stress_factor_ref_pressure = stress_factor_ref_pressure; +end \ No newline at end of file diff --git a/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/main1.m b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/main1.m new file mode 100644 index 0000000..e6d8bc2 --- /dev/null +++ b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/main1.m @@ -0,0 +1,211 @@ +function [ r, Times, OutputRs, Wellpara, trun ] = main1() +%% ==================================PART 1: 妯″瀷閫夊彇======================================== +% 1-- classical EDFM +modelflag = 1;% 姝ゅ鍥哄畾涓1鍗冲彲 +%% ==================================PART 2: 鍩鸿川缃戞牸瀹氫箟===================================== +dx=[10*ones(1,100) ];nx=size(dx,2); +dy=[10*ones(1,50) ];ny=size(dy,2); +dz=[10*ones(1,1)];nz=size(dz,2); +NTG= 1*ones(nx*ny*nz,1); +r = GridProp_pre(dx,dy,dz,nx,ny,nz,NTG); +%% ==================================PART 3: 瑁傜紳鍒嗗竷鏁版嵁杈撳叆===================================== +% 鍥涚杈撳叆鏂瑰紡: 1琛ㄧず宸ョ▼搴旂敤杈撳叆锛2琛ㄧず鍚戦噺杈撳叆锛3琛ㄧず宸ョ▼搴旂敤杈撳叆锛屽寘鎷熀鍑嗙偣銆佸捐銆佹柟浣嶈銆佹姮鍗囪锛4琛ㄧず浠.fab鏂囦欢璇诲彇 +input_style = 1; +%% 杈撳叆鏂瑰紡1锛氬伐绋嬪簲鐢ㄨ緭鍏 +%浠呰兘鍒荤敾鍏锋湁鍙屽绉版ц川鐨勭煩褰㈢紳鎴栨き鍦嗙紳 +% 鍩哄噯鐐瑰潗鏍囷紙1锛夛紝鏂逛綅瑙掞紙2锛夛紝鍊捐锛3锛夛紝鎶崌瑙掞紙4锛夛紝缂濋暱锛堟き鍦嗛暱杞撮暱锛夛紙5锛夛紝缂濋珮锛堟き鍦嗙煭杞撮暱锛夛紙6锛夛紝绫诲瀷1鏄煩褰㈢紳銆2鏄き鍦嗙紳锛7锛 +if input_style==1 +input_content={ + [255,255,5],90,90,0,200,10,1; + [305,255,5],90,90,0,200,10,1; + [355,255,5],90,90,0,200,10,1; + [405,255,5],90,90,0,200,10,1; + [455,255,5],90,90,0,200,10,1; + [505,255,5],90,90,0,200,10,1; + [555,255,5],90,90,0,200,10,1; + [605,255,5],90,90,0,200,10,1; + [655,255,5],90,90,0,200,10,1; + [705,255,5],90,90,0,200,10,1; + [755,255,5],90,90,0,200,10,1; + }; +[f,fellip] = sort_fracture(input_content); +flowBarrierFlags = []; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5; +frac_information = fractureInformation_input_engineering_vector(f,fellip,flowBarrierFlags); +end +%% 杈撳叆鏂瑰紡2锛氬悜閲忚緭鍏 +%棣栧厛瀵圭煩褰㈢紳杩涜鐮旂┒锛岃缂濆弬鏁板寘鎷笁涓悜閲忓拰涓や釜鍙傛暟鐨勫彇鍊艰寖鍥达紝濡傛灉鏄叾瀹冪被鍨嬬紳锛屽垯鏄袱涓弬鏁伴棿鐨勫嚱鏁板叧绯 +%鍥犳涓涓5琛屼笁鍒楃殑鐭╅樀鍙互纭畾涓鏉¤缂 +%鍚戦噺鍒嗛噺鍙负闈炴暣鏁帮紝浠ユ淇濊瘉鍙傛暟鑼冨洿鐨勫彇鍊间负鏁存暟鍗冲彲锛 +%鏁呭彲鍏堥殢鎰忕‘瀹氫负鏁存暟鐨勫弬鏁拌寖鍥达紝鍐嶆牴鎹紳闀跨紳楂樺幓纭畾鍚戦噺鍒嗛噺鐨勫彇鍊 +% 鐭╁舰缂 +if input_style==2 + f=[ + 0,1200,0;10,-20,0;0,0,10;0,60,0;0,3,0; + 0,1200,0;10,20,0;0,0,10;0,15,0;0,3,0; + 150,1500,0;20,-10,0;0,0,10;0,20,0;0,3,0; + 550,1300,0;10,10,0;0,0,10;0,10,0;0,3,0; + 650,1400,0;10,-20,0;0,0,10;0,55,0;0,3,0; + 605,705,0;10,0,0;0,0,10;-20,20,0;0,3,0; + ]; +% 妞渾缂 +% fellip=[320,210,10;10,2,0;0,0,2;0,0,8;0,0,5; +% 280,300,10;10,2,0;0,0,2;0,0,10;0,0,4;]; +% 300,205,10;10,0,0;0,0,2;0,0,10;0,0,5]; +fellip=[]; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +frac_information = fractureInformation_input_engineering_vector(f,fellip); +end +%% 杈撳叆鏂瑰紡3锛氫簩缁磋緭鍏 +% load('fractures_generated.mat'); +% fractureLines = fractures_generated; +if input_style==3 +fractureLines = [ + 105,150;105,350; + 205,150;205,350; + 305,150;305,350; + 405,150;405,350; + 505,150;505,350; + 605,150;605,350; + 705,150;705,350; + 805,150;805,350; + 905,150;905,350; + ]; +fellip=[]; % 妞渾缂 +fractureHeights = [ + 10;10;10;10;10;10;10;10;10]; +% 妞渾缂 +fellip=[]; +flowBarrierFlags = [];% flowBarrierFlags = [1;2;3;4]; +[f,frac_information] = input_fracture_2D(fractureLines,fractureHeights,flowBarrierFlags); +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +end +%% 杈撳叆鏂瑰紡4锛氫粠.fab鏂囦欢璇诲彇 Frac_PT +if input_style==4 + +end + +%% ==================================PART 4: 鍩鸿川缃戞牸鍙婅缂濈墿鎬у弬鏁拌緭鍏===================================== +% 1-- 鍗曢噸浠嬭川 +% 2-- 鍙岄噸浠嬭川锛堝弻瀛斿弻娓楋級 +grid_model = 2; +if grid_model == 1 +r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf); +end +if grid_model == 2 +r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf); +end + +%% 鐢熸垚鍚戦噺鍖栧彉鎴愭墍闇瑕佺殑绠楀瓙 +os = OperatorRS(r.N, r.nex, r.nc); + +%% ==================================PART 5: 妯″瀷绫诲瀷閫夊彇鍙婂垵濮嬬姸鎬佽瀹========================================= +% 1-- 姘旀按涓ょ浉娴 +% 2-- 娌规按涓ょ浉娴 +flow_model = 3; +if flow_model == 1 +[f,state0] = gas_water_flow(r); +end +if flow_model == 2 +[f,state0] = oil_water_flow(r); +end +if flow_model == 3 +[f,state0] = multi_component_flow(r); +end + +%% ==================================PART 6: 浜曞埗搴chedule璁惧畾================================================ +%灏嗙洿浜曘佹按骞充簳涓庡娈靛帇瑁傛按骞充簳鍒嗗紑澶勭悊 +%% 鐩翠簳銆佸父瑙勬按骞充簳瀹氫箟 +% Wellcpara: wellname(1) nperf锛屽皠瀛旂偣鏁伴噺(2) index(3) rw(4) skin(5) welltype(6) +% welltype=1 鐩翠簳锛寃elltype=2 姘村钩浜曟部x鏂瑰悜锛寃elltype=3 姘村钩浜曟部y鏂瑰悜 welltype=4 澶氭鍘嬭姘村钩浜 +% 鐩翠簳銆佹按骞充簳锛岃绉嶄簳鍨嬬殑澶勭悊鏄皢灏勫瓟娈靛畨鎺掑湪鍩鸿川缃戞牸 +% 瀵逛簬鐩翠簳銆佹枩浜曘佹按骞充簳锛岄噰鍙栦笌eclipse涓鑷寸殑鏂瑰紡锛岀粰鍑哄叾鍦ㄥ熀璐ㄧ綉鏍间腑浣嶇疆 +% 姣忎釜灏勫瓟鐐圭敱涓媝x,py,pz纭畾锛屽垎鍒〃绀鸿灏勫瓟鐐瑰湪x鏂瑰悜锛寉鏂瑰悜鐨勭綉鏍肩紪鍙凤紝鍙婂眰鏁板嵆z鍙嶆柟鍚戜笂鐨勭綉鏍肩紪鍙凤紙鏈鍒濇槸浠ュ瀭鐩村悜涓婂缓绔嬬殑鍩鸿川缃戞牸锛 +well1={ + % 'w1', 2, [20 10 1;20 10 2;], 0.178/2, 0, 1; + % 'w2', 2, [80 10 1;80 10 2;], 0.178/2, 0, 1; + % 'w3', 1, [20 40 1;], 0.178/2, 0, 1; + % 'w4', 1, [80 40 1;], 0.178/2, 0, 1; +% 'w2', 3, [67 20 1;67 20 2;67 20 3], 0.178/2, 0, 1; + }; +well1 = handle_well1(well1,r); +%% 鍘嬭姘村钩浜曞畾涔 +% 澶氭鍘嬭姘村钩浜曪細灏勫瓟娈佃缃湪瑁傜紳鍗曞厓涓婏紝鍙互缁欏嚭璇ュ皠瀛旂偣鎵鍦ㄧ殑鍧愭爣锛岀劧鍚庡幓瀵绘壘璇ョ偣鎵鍦ㄧ殑瑁傜紳鍗曞厓缂栧彿 +num_fracture_wells = 1; +welloc = cell(num_fracture_wells,1); +perfnum = cell(num_fracture_wells,1); +welloc{1,1}=[ + 255,255,5; + 305,255,5; + 355,255,5; + 405,255,5; + 455,255,5; + 505,255,5; + 555,255,5; + 605,255,5; + 655,255,5; + 705,255,5; + 755,255,5; + ]; +for i = 1:num_fracture_wells +perfnum{i,1} = findWelloc(r, welloc{i,1});%鍦ㄧ敤浠ellc0涔嬩腑 +end +% perfnum2 = findWelloc(r, welloc2); +well2={ + 'w1', length(perfnum{1,1}), perfnum{1,1}, 0.178/2, 0,4; + }; +Wellc = handle_well1_well2(well1,well2,welloc,r); %鍔犱簳鍜屽皠瀛斾綅缃 +%% 浜曞埗搴﹁缃紙寮鍏充簳銆佸畾鍘/瀹氫骇銆佷究浜庡悶鍚愮瓑锛 +number_phases = 3; +well_schedules = cell(number_phases,1); +time = zeros(number_phases,1); +% 涓嶅悓鏂瑰紡瀵瑰簲鐨勬敹鏁涢毦搴︺侀渶瑕佷笉涓鏍凤紝闇鍒嗛樁娈佃皟鎺э紝 +% 渚嬪鍦ㄦ敞鍏ラ樁娈甸渶瑕佸皬涓浜涳紝濡傛灉闇瑕佸仛鏃╂湡璇曚簳锛宒tmax銆乨tmin閮介渶瑕佸皬涓浜 +dtmax = zeros(number_phases,1); +dtmin = zeros(number_phases,1); + +% (1)well state: 'open'琛ㄧず璇ヤ簳鏄紑鐨勶紱'close'琛ㄦ槑璇ヤ簳涓鐩存槸鍏崇殑锛屽鏋滃彧鏄樁娈垫у叧浜曪紝灏辩敤'open'瀹氭祦閲0鐢熶骇 +% (2)well type: 'pro'琛ㄧず鏄敓浜т簳锛'inj'琛ㄧず鏄敞鍏ヤ簳; +% (3)protype锛'const_q'鏄畾娴侀噺锛'const_pwf'鍒欐槸瀹氬帇 +% (4)value锛氬畾鐨勬祦閲忓兼垨鑰呬簳搴曞帇鍔涘 +% (5)value锛氭浠g爜璇ュ间笌锛3锛夊肩浉鍚 +% (8)value锛氭敞鍏ヨ〃娲诲墏鐨勬祿搴 kg/m3 +% (10)value锛氭敞鍏ユ按/鍘嬭娑茬殑鐩愭祿搴︼紙鐭垮寲搴︼級锛屼竴鑸槸 1kg/m3 +time(1) = 10; dtmax(1) = 0.1; dtmin(1) = 0.001; +well_schedules{1,1} = { + % 'w1','open','inj','const_pwf',30,30; + % 'w2','open','inj','const_pwf',30,30; + % 'w3','open','inj','const_pwf',30,30; + % 'w4','open','inj','const_pwf',30,30; + 'w1','open','inj','const_pwf',40,40,'Cs_inj',0.5,'Cb_inj',1}; +time(2) = 30; dtmax(2) = 0.5; dtmin(2) = 0.001; +well_schedules{2,1} = { + 'w1','open','pro','const_q',0,0; + % 'w1','open','pro','const_pwf',10,10; + % 'w2','open','pro','const_q',0,0; + }; +time(3) = 200; dtmax(3) = 5; dtmin(3) = 0.001; +well_schedules{3,1} = { + 'w1','open','pro','const_pwf',10,10; + % 'w2','open','pro','const_pwf',10,10; + }; + +% time(1) = 200; +% well_schedules{1,1} = { +% 'w1','open','pro','const_pwf',10,10; +% % 'w2','open','pro','const_pwf',10,10; +% }; + +%% ======================================PART 7: Solver璁剧疆=========================================== +yitap = 5; % 50-500psi +yitas = 0.04; % 0.05-0.5 +omega = 0.5; % 0-1 +Nmax = 50; +epsave = 1e-6; +epsmax = 1e-6; + +%% ======================================PART 8: 姝e紡璁$畻=========================================== +[Times, OutputRs, Wellpara, trun] = solver_NR(r, flow_model, f, os, state0, yitap,yitas,omega,Nmax,epsave,epsmax,dtmin,dtmax,Wellc,time,well_schedules); +run_time=toc; +trun.run_time=run_time; +end \ No newline at end of file diff --git a/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/multi_component_flow.m b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/multi_component_flow.m new file mode 100644 index 0000000..94eb4b0 --- /dev/null +++ b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/multi_component_flow.m @@ -0,0 +1,232 @@ +function [f,state0] = multi_component_flow(r) +%% 娴佷綋鎬ц川鍙傛暟 +%% 姘寸浉涓殑琛ㄦ椿鍓傘佺洂鐨勬墿鏁g郴鏁 +Ds = 0.76*1e-9; % m2/s +Db = 2.2*1e-9; % m2/s +%% 琛ㄦ椿鍓傘佺洂鍦ㄥ博鐭宠〃闈㈢殑鍚搁檮娴撳害涓庢按鐩告祿搴︾殑鍏崇郴琛紝绗竴鍒楀崟浣嶆槸kg/m3, 绗簩鍒楀拰绗笁鍒楀崟浣嶆槸g/kg +c_ca_table = [ +0 0 0 +0.05 1 0.075 +0.1 1.75 0.125 +0.2 3 0.2 +0.5 4.35 0.325 +1 4.55 0.365 +]; +cs_data = c_ca_table(:,1); +cb_data = c_ca_table(:,1); +csa_data = c_ca_table(:,2)*1e-3; % 杞崲涓 kg/kg +cba_data = c_ca_table(:,3)*1e-3; % 杞崲涓 kg/kg +%% 鍖栧鍔匡紙鍘嬭娑蹭笌鍦板眰姘寸殑鐩愬害宸紓缁欐按鐩稿甫鏉ョ殑棰濆鍘嬪樊锛 +R = 0.008314; % kJ/(mol*K) +Vm = 18.02*1e-6; % 姘寸殑鍋忔懇灏斾綋绉紝m^3/mol +Temperature = 293.15; % 娓╁害锛孠 +chemistry_cof = R*Temperature/Vm*1e-3/10; +%% 鍔ㄦ佺浉娓楋紙鍑告樉鍑鸿〃娲诲墏瀵圭浉娓楃殑褰卞搷锛 +% 鍘熸湰搴斿厛寰楀埌琛ㄦ椿鍓傛祿搴︿笌琛ㄩ潰寮犲姏鐨勫叧绯伙紝鍐嶇粨鍚堟笚娴侀熷害璁$畻鍑轰釜琛ㄩ潰寮犲姏瀵瑰簲鐨勬瘺绠℃暟锛 +% 涓轰簡绠渚夸唬鐮佺紪鍐欙紝姝ゅ蹇界暐娓楁祦閫熷害鐨勫奖鍝嶏紝 +% 骞跺寮轰唬鐮侀氱敤鎬э紝姝ゅ鏀逛负杈撳叆琛ㄦ椿鍓傛祿搴︿笌姣涚鏁扮殑瀵瑰簲琛ㄦ牸锛 +% 绗竴鍒椾负琛ㄦ椿鍓傛祿搴︼紝绗簩鍒椾负鐩稿簲鐨勬瘺绠℃暟,锛岀涓夊垪鏄浉搴旂殑琛ㄩ潰寮犲姏 +% dynamic_kr = 1; +cs_Nc = [ +0 1.6*1e-6 30 +0.1 9.5*1e-6 10 +0.2 2.5*1e-5 4 +0.5 5.8*1e-5 1.4 +1 8.2*1e-5 1 +2 8.8*1e-5 0.75 +]; +Nc_nosurf = min(cs_Nc(:,2)); +Nc_surf = max(cs_Nc(:,2)); + +kr_nosurf = [ +0 0 0.64 +0.25 0 0.64 +0.30 0.072 0.6 +0.40 0.14 0.56 +0.50 0.26 0.48 +0.60 0.4 0.38 +0.70 0.56 0.26 +0.85 0.88 0 +1 0.88 0 + ]; + +kr_surf = [ +0 0 0.6 +0.18 0 0.6 +0.25 0.056 0.56 +0.30 0.1 0.52 +0.40 0.19 0.42 +0.50 0.29 0.3 +0.60 0.37 0.19 +0.75 0.46 0 +1 0.46 0 + ]; + +PC = [ +0 3.8916 +0.2 3.8916 +0.316 0.5796 +0.435 0.3724 +0.562 0.2425 +0.614 0.0608 +0.702 0.0372 +0.812 0.0137 +0.875 0.0104 +0.906 0.009 +0.937 0.0075 +0.969 0.0059 +1 0 +]; +cs_Nc_fracture = cs_Nc; +kr_nosurf_fracture = kr_nosurf; +kr_surf_fracture = kr_surf; +PC_fracture = PC; +ifpcgl = 0; % 鏄惁鑰冭檻姣涚鍔 +%% 鍚姩鍘嬪姏姊害 +p_grad_threshold = 0.00; % MPa/m +%% ================姘旂浉Langmuir绛夋俯鍚搁檮妯″瀷锛屽綋 VL=0锛屼害鍙敤浜庢补鐩=============== +% VE = VL*P/(PL+P) +gas_prop.VL = 0.0; % Langmuir volume, m^3/kg +gas_prop.PL = 3.5; % Langmuir pressure, MPa +% Psc = 1; +% Zsc = 1; +% density_rock = 2000; % +% ===================== Knudsen 鎵╂暎绯绘暟锛屽綋 Kn=0锛屼害鍙敤浜庢补鐩 ==================== +gas_prop.Kn = 0; % Knudsen鏁 +c1 =1; c2 =8/9; +gas_prop.Kn_modified_factor = 1+8*c1*gas_prop.Kn+16*c2*gas_prop.Kn^2; +% ===================== 楂橀熼潪杈捐タ娴 Forchheimer 鏂圭▼ ==================== +gas_prop.beta_non_Darcy_flow = 0; % 1e-8 +% =======================姘旂浉浣撶Н绯绘暟銆佺矘搴=============================== +density_g_sc = 800; +% 绗竴绉嶆ā寮忥紝鐩存帴杈撳叆鍙傝冨帇鍔涖佷綋绉郴鏁般佸帇缂╃郴鏁般佺矘搴 +gas_model =1; +if gas_model == 1 +prg = 20; % reference pressure, MPa +Bgi = 1; % gas phase volume factor +cg = 5e-4 ;% gas phase compressibility, 1/MPa +vgi = 6; % gas viscosity, cp +cvg = 0; +[Ppr,BG,MUG] = cal_gas_prop(prg,Bgi,cg,vgi,cvg); +end +if gas_model == 2 +Ppr = [ 0.1013 + 2.0946 + 4.0878 + 6.0811 + 8.0743 + 10.0676 + 12.0608 + 14.0540 + 16.0473 + 18.0405 + 20.0338 + 22.0270 + 24.0203 + 26.0135 + 28.0068 + 30.0000 + ]; +% BG = 0.01*ones(size(Ppr,1),1); +BG = [ 1.18297 + 0.0557041 + 0.0278168 + 0.0182594 + 0.0134665 + 0.0106154 + 0.00874829 + 0.00744907 + 0.00650639 + 0.0058006 + 0.0052587 + 0.0048336 + 0.00449378 + 0.00421751 + 0.0039895 + 0.00379871 + ]; +% MUG = 0.01*ones(size(Ppr,1),1); +MUG = [0.0127683 + 0.0130191 + 0.0133973 + 0.013872 + 0.014437 + 0.015088 + 0.0158182 + 0.0166173 + 0.0174719 + 0.0183671 + 0.0192882 + 0.0202219 + 0.0211575 + 0.0220865 + 0.0230024 + 0.0239008 + ]; +end +% ========================姘寸浉浣撶Н绯绘暟銆佺矘搴=============================== +density_w_sc = 1000; +prw = 20; % reference pressure +Bwi = 1.000; % water phase volume factor +cw = 4.0e-4 ;% water phase compressibility +vwi = 1; % viscosity +cvw = 0; +% =============================鍩鸿川鐩告笚=============================== +% ifpcgl = 0; % 鏄惁鑰冭檻姣涚鍔 +% RPGW=[ +% 0.0000 0.0000 1.0000 3.8916 +% 0.2000 0.0000 1.0000 3.8916 +% 0.3160 0.0002 0.6784 0.5796 +% 0.4350 0.0004 0.6215 0.3724 +% 0.5620 0.0010 0.5456 0.2425 +% 0.6140 0.0020 0.3939 0.0608 +% 0.7020 0.0280 0.1399 0.0372 +% 0.8120 0.1721 0.0515 0.0137 +% 0.8750 0.3395 0.0297 0.0104 +% 0.9060 0.4395 0.0226 0.0090 +% 0.9370 0.5500 0.0173 0.0075 +% 0.9690 0.6702 0.0131 0.0059 +% 1.0 1.0000 0.0000 0.0000 +% ]; +% SW=RPGW(:,1);KRW=RPGW(:,2);KRG=RPGW(:,3);PCGL=RPGW(:,4); +% +% % =============================瑁傜紳鐩告笚=============================== +% PRF=[ +% 0.0000 0.0000 1.0000 3.8916 +% 0.2000 0.0000 1.0000 3.8916 +% 0.3160 0.0002 0.6784 0.5796 +% 0.4350 0.0004 0.6215 0.3724 +% 0.5620 0.0010 0.5456 0.2425 +% 0.6140 0.0020 0.3939 0.0608 +% 0.7020 0.0280 0.1399 0.0372 +% 0.8120 0.1721 0.0515 0.0137 +% 0.8750 0.3395 0.0297 0.0104 +% 0.9060 0.4395 0.0226 0.0090 +% 0.9370 0.5500 0.0173 0.0075 +% 1.0 1.0000 0.0000 0.0000 +% ]; +% SWF = PRF(:,1);KRWF = PRF(:,2);KRGF = PRF(:,3);PCGLF=PRF(:,4); + +%% 缁撳悎娴佷綋鎬ц川鍙傛暟鐢熸垚鐩稿簲鐨勬暟鎹綋 +% f = fluidPVT(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, SW, KRG, KRW, PCGL, SWF, KRGF, KRWF, PCGLF, density_g_sc, ifpcgl, r.rpt, cs_data, csa_data, cb_data, cba_data, cs_Nc, kr_nosurf, kr_surf); +f = fluidPVT_new(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, ifpcgl, r.rpt, cs_data, csa_data, cb_data, cba_data, cs_Nc, Nc_nosurf, Nc_surf, kr_nosurf, kr_surf, PC, cs_Nc_fracture, kr_nosurf_fracture, kr_surf_fracture, PC_fracture); +f.Dwsi = density_w_sc; +f.Dgsi = density_g_sc; +f.gas_prop = gas_prop; +f.Ds = Ds; +f.Db = Db; +f.chemistry_cof = chemistry_cof; +f.p_grad_threshold = p_grad_threshold; +%% 鍒濆兼潯浠 Initial Condition Section +% =================鍘嬪姏銆侀ケ鍜屽害鍒濆======================================= % +%鍘嬪姏鍒濆艰鑰冭檻閲嶅姏锛岀粰鍑烘补钘忎笅琛ㄩ潰鍘嬪姏鍊 +P = [20 * ones(r.nmc, 1); 20 * ones(r.nfc, 1)]; +% plow=25; % P =plow-1e-6*800*9.8*r.z; +Sw = [0.2 * ones(r.nmc, 1); 0.2 * ones(r.nfc, 1)]; +Cs = [0.0 * ones(r.nmc, 1); 0.0 * ones(r.nfc, 1)];% kg/m3 +Cb = [50.0 * ones(r.nmc, 1); 50.0 * ones(r.nfc, 1)];% kg/m3 +% 娌硅棌鍦板眰姘寸熆鍖栧害涓鑸负 50 kg/m3锛屾敞鍏ユ按銆佸帇瑁傛恫鐨勭熆鍖栧害涓鑸负 1 kg/m3 +number_state_variables = 4; +f.number_state_variables = number_state_variables; +state0 = initialRS(P, Sw, Cs, Cb); +end \ No newline at end of file diff --git a/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plotWellResponse.m b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plotWellResponse.m new file mode 100644 index 0000000..b3bcc97 --- /dev/null +++ b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plotWellResponse.m @@ -0,0 +1,55 @@ +function [] = plotWellResponse(Times,Wellpara) +% 输入 +wellNumber = 1; % 井号 +dataType = 'dPWF'; % 类型,产气速度 GPR,产气速度 OPR, 产水速度 WPR,井底流压 BHP,压力导数 dPWF +% +t = Times; +n= size(Times,1); +% para = cell2mat(Wellpara); +nw = wellNumber;%选井号 +% n = length(para); +data = zeros(n,1); +if strcmp(dataType, 'GPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qg; + figureYlegend = 'Gas production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'OPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qo; + figureYlegend = 'Oil production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'WPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qw; + figureYlegend = 'Water production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'BHP') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.pwf; + figureYlegend = 'BHP, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'dPWF') % dpwf/dlnt = t*dpwf/dt + for i = 1 : n + if i == 1 + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i}{1,nw}.pwf)/(log(t(i+1))-log(t(i))); + elseif i == n + data(i) = (Wellpara{i}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i))-log(t(i-1))); + else + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i+1))-log(t(i-1))); + end + figureYlegend = 'Pressure derivative, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); + set(gca, 'XScale', 'log'); + set(gca, 'YScale', 'log'); +end +end \ No newline at end of file diff --git a/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plot_2D_layer.m b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plot_2D_layer.m new file mode 100644 index 0000000..0d45394 --- /dev/null +++ b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plot_2D_layer.m @@ -0,0 +1,50 @@ +function plot_2D_layer(i, k, r, OutputRs, type) +coordinate=r.coordinates; +nodes=r.nodes; +nz=r.nz; +nx=r.nx; +ny=r.ny; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +if type == 1 +% v = r.kx; + v = OutputRs{i}.p; +else + v = 1-OutputRs{i}.sw;%含气饱和度 +end +dis = zeros(nel, nx*ny); +x = zeros(nel, nx*ny); +y = zeros(nel, nx*ny); +for i = 1 :nx*ny + for j = 1 :nel + grid_numbering = i+(nz-k)*nx*ny; + x(j, i) = coordinate(nodes(grid_numbering,j), 1); + y(j, i) = coordinate(nodes(grid_numbering,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(grid_numbering,4), 1); + y(j, i) = coordinate(nodes(grid_numbering,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(grid_numbering,3), 1); + y(j, i) = coordinate(nodes(grid_numbering,3), 2); + end + dis(j, i) = v(grid_numbering); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +% clim([10,15]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plot_3D_dis.m b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plot_3D_dis.m new file mode 100644 index 0000000..6674f45 --- /dev/null +++ b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plot_3D_dis.m @@ -0,0 +1,144 @@ +function plot_3D_dis(i, r,OutputRs, type) +%为便于作图进行前处理 +figure('color','w') +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dis( r ); +coordinate=r.coordinates; +nodes=r.nodes; +% nmc = size(nodes,1);%基质网格数量 +% % nel = size(nodes,2);%每个基质网格所包含的点数量 +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%用以fill函数作图 +% nel=size(order,2); +if type == 1 + v = OutputRs{i}.p; +elseif type == 2 + v = 1-OutputRs{i}.sw;%含油饱和度 +elseif type == 3 + v = OutputRs{i}.sg;%含油饱和度 +else + v = OutputRs{i}.sw;%含油饱和度 +end +% 底面 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%左面 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%右面 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%前面 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%后面 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%上面 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel('x, m'); +ylabel('y, m'); +zlabel('z, m'); +view(3); +% 绘制油藏框架 +% plotframe( r ); +alpha(1) +% caxis([0.2,0.8]); +caxis([10,13]); +% caxis([12,22]); +colormap jet +colorbar +% zlim([-2020,-2000]); +% axis equal +axis tight + diff --git a/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plot_SP_DP.m b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plot_SP_DP.m new file mode 100644 index 0000000..7f63e8e --- /dev/null +++ b/绠椾緥3-鍗曢噸鍙岄噸绂绘暎瑁傜紳娣峰悎妯″瀷/plot_SP_DP.m @@ -0,0 +1,51 @@ +function plot_SP_DP(k, r) +coordinate=r.coordinates; +nodes=r.nodes; +nz=r.nz; +nx=r.nx; +ny=r.ny; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +v = r.sigma; +% if type == 1 +% % v = r.kx; +% v = OutputRs{i}.p; +% else +% v = 1-OutputRs{i}.sw;%含气饱和度 +% end +dis = zeros(nel, nx*ny); +x = zeros(nel, nx*ny); +y = zeros(nel, nx*ny); +for i = 1 :nx*ny + for j = 1 :nel + grid_numbering = i+(nz-k)*nx*ny; + x(j, i) = coordinate(nodes(grid_numbering,j), 1); + y(j, i) = coordinate(nodes(grid_numbering,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(grid_numbering,4), 1); + y(j, i) = coordinate(nodes(grid_numbering,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(grid_numbering,3), 1); + y(j, i) = coordinate(nodes(grid_numbering,3), 2); + end + dis(j, i) = v(grid_numbering); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +% clim([10,15]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/gas_water_flow.m b/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/gas_water_flow.m new file mode 100644 index 0000000..063f4ac --- /dev/null +++ b/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/gas_water_flow.m @@ -0,0 +1,141 @@ +function [f,state0] = gas_water_flow(r) +%% 娴佷綋鎬ц川鍙傛暟 +% ===================== Langmuir绛夋俯鍚搁檮妯″瀷==================== +% VE = VL*P/(PL+P) +gas_prop.VL = 0.021; % Langmuir volume, m^3/kg +gas_prop.PL = 3.5; % Langmuir pressure, MPa +% Psc = 1; +% Zsc = 1; +% density_rock = 2000; % +% ===================== Knudsen 鎵╂暎绯绘暟 ==================== +gas_prop.Kn = 1; % Knudsen鏁 +c1 =1; c2 =8/9; +gas_prop.Kn_modified_factor = 1+8*c1*gas_prop.Kn+16*c2*gas_prop.Kn^2; +% ===================== 楂橀熼潪杈捐タ娴 Forchheimer 鏂圭▼ ==================== +gas_prop.beta_non_Darcy_flow = 0; % 1e-8 +% ===================== 鍚姩鍘嬪姏姊害 ==================== +p_grad_threshold = 0.00; % MPa/m +% =======================姘旂浉浣撶Н绯绘暟銆佺矘搴=============================== +density_g_sc = 0.716; +% 绗竴绉嶆ā寮忥紝鐩存帴杈撳叆鍙傝冨帇鍔涖佷綋绉郴鏁般佸帇缂╃郴鏁般佺矘搴 +gas_model =1; +if gas_model == 1 +prg = 30; % reference pressure, MPa +Bgi = 0.01; % gas phase volume factor +cg = 1e-2 ;% gas phase compressibility, 1/MPa +vgi = 0.01; % gas viscosity, cp +cvg = 0; +[Ppr,BG,MUG] = cal_gas_prop(prg,Bgi,cg,vgi,cvg); +end +if gas_model == 2 +Ppr = [ 0.1013 + 2.0946 + 4.0878 + 6.0811 + 8.0743 + 10.0676 + 12.0608 + 14.0540 + 16.0473 + 18.0405 + 20.0338 + 22.0270 + 24.0203 + 26.0135 + 28.0068 + 30.0000 + ]; +% BG = 0.01*ones(size(Ppr,1),1); +BG = [ 1.18297 + 0.0557041 + 0.0278168 + 0.0182594 + 0.0134665 + 0.0106154 + 0.00874829 + 0.00744907 + 0.00650639 + 0.0058006 + 0.0052587 + 0.0048336 + 0.00449378 + 0.00421751 + 0.0039895 + 0.00379871 + ]; +% MUG = 0.01*ones(size(Ppr,1),1); +MUG = [0.0127683 + 0.0130191 + 0.0133973 + 0.013872 + 0.014437 + 0.015088 + 0.0158182 + 0.0166173 + 0.0174719 + 0.0183671 + 0.0192882 + 0.0202219 + 0.0211575 + 0.0220865 + 0.0230024 + 0.0239008 + ]; +end +% ========================姘寸浉浣撶Н绯绘暟銆佺矘搴=============================== +density_w_sc = 1000; +prw = 30; % reference pressure +Bwi = 1.000; % water phase volume factor +cw = 4.0e-4 ;% water phase compressibility +vwi = 1; % viscosity +cvw = 0; +% =============================鍩鸿川鐩告笚=============================== +ifpcgl = 0; % 鏄惁鑰冭檻姣涚鍔 +RPGW=[ + 0.0000 0.0000 1.0000 3.8916 +0.2000 0.0000 1.0000 3.8916 +0.3160 0.0002 0.6784 0.5796 +0.4350 0.0004 0.6215 0.3724 +0.5620 0.0010 0.5456 0.2425 +0.6140 0.0020 0.3939 0.0608 +0.7020 0.0280 0.1399 0.0372 +0.8120 0.1721 0.0515 0.0137 +0.8750 0.3395 0.0297 0.0104 +0.9060 0.4395 0.0226 0.0090 +0.9370 0.5500 0.0173 0.0075 +0.9690 0.6702 0.0131 0.0059 +1.0 1.0000 0.0000 0.0000 +]; +SW=RPGW(:,1);KRW=RPGW(:,2);KRG=RPGW(:,3);PCGL=RPGW(:,4); + +% =============================瑁傜紳鐩告笚=============================== +PRF=[ +0.0000 0.0000 1.0000 3.8916 +0.2000 0.0000 1.0000 3.8916 +0.3160 0.0002 0.6784 0.5796 +0.4350 0.0004 0.6215 0.3724 +0.5620 0.0010 0.5456 0.2425 +0.6140 0.0020 0.3939 0.0608 +0.7020 0.0280 0.1399 0.0372 +0.8120 0.1721 0.0515 0.0137 +0.8750 0.3395 0.0297 0.0104 +0.9060 0.4395 0.0226 0.0090 +0.9370 0.5500 0.0173 0.0075 +1.0 1.0000 0.0000 0.0000 +]; +SWF = PRF(:,1);KRWF = PRF(:,2);KRGF = PRF(:,3);PCGLF=PRF(:,4); + +%% 缁撳悎娴佷綋鎬ц川鍙傛暟鐢熸垚鐩稿簲鐨勬暟鎹綋 +f = fluidPVT_gas_water_flow(Ppr, BG, MUG, Bwi, prw, cw, vwi, cvw, SW, KRG, KRW, PCGL, SWF, KRGF, KRWF, PCGLF, density_g_sc, ifpcgl, r.rpt); +f.Dwsi = density_w_sc; +f.Dgsi = density_g_sc; +f.gas_prop = gas_prop; +f.p_grad_threshold = p_grad_threshold; +%% 鍒濆兼潯浠 Initial Condition Section +% =================鍘嬪姏銆侀ケ鍜屽害鍒濆======================================= % +%鍘嬪姏鍒濆艰鑰冭檻閲嶅姏锛岀粰鍑烘补钘忎笅琛ㄩ潰鍘嬪姏鍊 +P = [20 * ones(r.nmc, 1); 20 * ones(r.nfc, 1)]; +% plow=25; % P =plow-1e-6*800*9.8*r.z; +Sw = [0.2 * ones(r.nmc, 1); 0.2 * ones(r.nfc, 1)]; +state0 = initialRS_gas_water_flow(P, Sw); +end \ No newline at end of file diff --git a/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/grid_discretization_SP_model.m b/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/grid_discretization_SP_model.m new file mode 100644 index 0000000..76c4f50 --- /dev/null +++ b/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/grid_discretization_SP_model.m @@ -0,0 +1,55 @@ +function r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf) +% 鏁版嵁璇诲彇 +nx = r.nx; ny = r.ny; nz = r.nz; NTG = r.NTG; cell_mid_coords = r.cell_mid_coords; +% 鍩鸿川瀛旀笚 +density_rock = 2700; % 宀╃煶瀵嗗害锛宬g/m^3 +kx = 1*1e-3 * ones(nx*ny*nz, 1); % 杈捐タ锛孌 +ky = 1*1e-3 * ones(nx*ny*nz, 1);% +kz = 1*1e-3 * ones(nx*ny*nz, 1);% +pori = 0.08 * ones(nx*ny*nz, 1);% +prpor = 20; % 鍙傝冨帇鍔涳紝MPa +cpor = 1.0e-5;% 鍩鸿川鍘嬬缉绯绘暟锛,MPa +% 鏈夋晥缃戞牸 +valid_grids = ones(nx*ny*nz, 1); +invalid_layer = []; % 灏嗙浜屽眰鏃犳晥缃戞牸 +for i = 1:length(invalid_layer) + grid_numbering_range = ((invalid_layer(i)-1)*nx*ny+1:invalid_layer(i)*nx*ny)'; + valid_grids(grid_numbering_range,1) = 0; +end +% SRV鍖哄煙瀹氫箟 +% % % base_x=23:78; nx_SRV=length(base_x); +% % % base_y=15:36; ny_SRV=length(base_y); +% % % base_z=1:1;nz_SRV=length(base_z); +% % % SRV=[]; +% % % for k=1:nz_SRV +% % % for j=1:ny_SRV +% % % for i=1:nx_SRV +% % % SRV=[SRV;(base_z(k)-1)*nx*ny+(base_y(j)-1)*nx+base_x(i)]; +% % % end +% % % end +% % % end +% % % % SRV娓楅忕巼璧嬪 +% % % kx(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % ky(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % kz(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% 瑁傜紳瀛旀笚 +Kf = 10000*1e-3*ones(1,nf);% 瑁傜紳娓楅忕巼 +Wf = 1e-2*ones(1,nf);% 瑁傜紳寮搴 +Porf = 0.30*ones(1,nf);% 瑁傜紳瀛旈殭搴 +prporf = 20;% 瑁傜紳绯荤粺鍙傝冨帇鍔 +cporf = 1.0e-5;% 瑁傜紳绯荤粺鍘嬬缉绯绘暟 +% 搴斿姏鏁忔劅绯绘暟 +stress_factor_fracture = 0.000; % 1/MPa 0.001 +stress_factor_matrix = 0.000; % 1/MPa +stress_factor_ref_pressure = 20; % 涓鑸彇涓哄師濮嬪湴灞傚帇鍔 +% +Rpt = 2;cf = 1;ca = 1; +%% 缁撳悎鍩鸿川銆佽缂濈殑鍑犱綍鍙婄墿鎬т俊鎭紑灞曞墠澶勭悊 +% r = GridProp(modelflag, nx, ny, nz, dx, dy, dz, kx, ky, kz, f, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,co, NTG); +r = GridProp_new(modelflag, r, kx, ky, kz, f, frac_information, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca, valid_grids); +r.density_rock = density_rock; +r.valid_grids = valid_grids; +r.stress_factor_fracture = stress_factor_fracture; +r.stress_factor_matrix = stress_factor_matrix; +r.stress_factor_ref_pressure = stress_factor_ref_pressure; +end \ No newline at end of file diff --git a/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/main1.asv b/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/main1.asv new file mode 100644 index 0000000..5b10be2 --- /dev/null +++ b/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/main1.asv @@ -0,0 +1,195 @@ +function [ r, Times, OutputRs, Wellpara, trun ] = main1() +%% ==================================PART 1: 妯″瀷閫夊彇======================================== +% 1-- classical EDFM +modelflag = 1;% 姝ゅ鍥哄畾涓1鍗冲彲 +%% ==================================PART 2: 鍩鸿川缃戞牸瀹氫箟===================================== +dx=[10*ones(1,100) ];nx=size(dx,2); +dy=[10*ones(1,50) ];ny=size(dy,2); +dz=[10*ones(1,1)];nz=size(dz,2); +NTG= 1*ones(nx*ny*nz,1); +r = GridProp_pre(dx, dy,dz,nx,ny,nz,NTG); +%% ==================================PART 3: 瑁傜紳鍒嗗竷鏁版嵁杈撳叆===================================== +% 鍥涚杈撳叆鏂瑰紡: 1琛ㄧず宸ョ▼搴旂敤杈撳叆锛2琛ㄧず鍚戦噺杈撳叆锛3琛ㄧず宸ョ▼搴旂敤杈撳叆锛屽寘鎷熀鍑嗙偣銆佸捐銆佹柟浣嶈銆佹姮鍗囪锛4琛ㄧず浠.fab鏂囦欢璇诲彇 +input_style = 1; +%% 杈撳叆鏂瑰紡1锛氬伐绋嬪簲鐢ㄨ緭鍏 +%浠呰兘鍒荤敾鍏锋湁鍙屽绉版ц川鐨勭煩褰㈢紳鎴栨き鍦嗙紳 +% 鍩哄噯鐐瑰潗鏍囷紙1锛夛紝鏂逛綅瑙掞紙2锛夛紝鍊捐锛3锛夛紝鎶崌瑙掞紙4锛夛紝缂濋暱锛堟き鍦嗛暱杞撮暱锛夛紙5锛夛紝缂濋珮锛堟き鍦嗙煭杞撮暱锛夛紙6锛夛紝绫诲瀷1鏄煩褰㈢紳銆2鏄き鍦嗙紳锛7锛 +if input_style==1 +input_content={ + [255,255,5],90,90,0,200,10,1; + [305,255,5],90,90,0,200,10,1; + [355,255,5],90,90,0,200,10,1; + [405,255,5],90,90,0,200,10,1; + [455,255,5],90,90,0,200,10,1; + [505,255,5],90,90,0,200,10,1; + [555,255,5],90,90,0,200,10,1; + [605,255,5],90,90,0,200,10,1; + [655,255,5],90,90,0,200,10,1; + [705,255,5],90,90,0,200,10,1; + [755,255,5],90,90,0,200,10,1; + }; +[f,fellip] = sort_fracture(input_content); +flowBarrierFlags = []; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5; +frac_information = fractureInformation_input_engineering_vector(f,fellip,flowBarrierFlags); +end +%% 杈撳叆鏂瑰紡2锛氬悜閲忚緭鍏 +%棣栧厛瀵圭煩褰㈢紳杩涜鐮旂┒锛岃缂濆弬鏁板寘鎷笁涓悜閲忓拰涓や釜鍙傛暟鐨勫彇鍊艰寖鍥达紝濡傛灉鏄叾瀹冪被鍨嬬紳锛屽垯鏄袱涓弬鏁伴棿鐨勫嚱鏁板叧绯 +%鍥犳涓涓5琛屼笁鍒楃殑鐭╅樀鍙互纭畾涓鏉¤缂 +%鍚戦噺鍒嗛噺鍙负闈炴暣鏁帮紝浠ユ淇濊瘉鍙傛暟鑼冨洿鐨勫彇鍊间负鏁存暟鍗冲彲锛 +%鏁呭彲鍏堥殢鎰忕‘瀹氫负鏁存暟鐨勫弬鏁拌寖鍥达紝鍐嶆牴鎹紳闀跨紳楂樺幓纭畾鍚戦噺鍒嗛噺鐨勫彇鍊 +% 鐭╁舰缂 +if input_style==2 + f=[ + 0,1200,0;10,-20,0;0,0,10;0,60,0;0,3,0; + 0,1200,0;10,20,0;0,0,10;0,15,0;0,3,0; + 150,1500,0;20,-10,0;0,0,10;0,20,0;0,3,0; + 550,1300,0;10,10,0;0,0,10;0,10,0;0,3,0; + 650,1400,0;10,-20,0;0,0,10;0,55,0;0,3,0; + 605,705,0;10,0,0;0,0,10;-20,20,0;0,3,0; + ]; +% 妞渾缂 +% fellip=[320,210,10;10,2,0;0,0,2;0,0,8;0,0,5; +% 280,300,10;10,2,0;0,0,2;0,0,10;0,0,4;]; +% 300,205,10;10,0,0;0,0,2;0,0,10;0,0,5]; +fellip=[]; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +frac_information = fractureInformation_input_engineering_vector(f,fellip); +end +%% 杈撳叆鏂瑰紡3锛氫簩缁磋緭鍏 +% load('fractures_generated.mat'); +% fractureLines = fractures_generated; +if input_style==3 +fractureLines = [ + 105,150;105,350; + 205,150;205,350; + 305,150;305,350; + 405,150;405,350; + 505,150;505,350; + 605,150;605,350; + 705,150;705,350; + 805,150;805,350; + 905,150;905,350; + ]; +fellip=[]; % 妞渾缂 +fractureHeights = [ + 10;10;10;10;10;10;10;10;10]; +% 妞渾缂 +fellip=[]; +flowBarrierFlags = [];% flowBarrierFlags = [1;2;3;4]; +[f,frac_information] = input_fracture_2D(fractureLines,fractureHeights,flowBarrierFlags); +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +end +%% 杈撳叆鏂瑰紡4锛氫粠.fab鏂囦欢璇诲彇 Frac_PT +if input_style==4 + +end + +%% ==================================PART 4: 鍩鸿川缃戞牸鍙婅缂濈墿鎬у弬鏁拌緭鍏===================================== +% 1-- 鍗曢噸浠嬭川 +% 2-- 鍙岄噸浠嬭川锛堝弻瀛斿弻娓楋級 +grid_model = 1; +if grid_model == 1 +r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf); +end +if grid_model == 2 +r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf); +end +%% 鐢熸垚鍚戦噺鍖栧彉鎴愭墍闇瑕佺殑绠楀瓙 +os = OperatorRS(r.N, r.nex, r.nc); + +%% ==================================PART 5: 妯″瀷绫诲瀷閫夊彇鍙婂垵濮嬬姸鎬佽瀹========================================= +% 1-- 姘旀按涓ょ浉娴 +% 2-- 娌规按涓ょ浉娴 +flow_model = 1; +if flow_model == 1 +[f,state0] = gas_water_flow(r); +end +if flow_model == 2 +[f,state0] = oil_water_flow(r); +end +if flow_model == 3 +[f,state0] = multi_component_flow(r); +end + +%% ==================================PART 6: 浜曞埗搴chedule璁惧畾================================================ +%灏嗙洿浜曘佹按骞充簳涓庡娈靛帇瑁傛按骞充簳鍒嗗紑澶勭悊 +%% 鐩翠簳銆佸父瑙勬按骞充簳瀹氫箟 +% Wellcpara: wellname(1) nperf锛屽皠瀛旂偣鏁伴噺(2) index(3) rw(4) skin(5) welltype(6) +% welltype=1 鐩翠簳锛寃elltype=2 姘村钩浜曟部x鏂瑰悜锛寃elltype=3 姘村钩浜曟部y鏂瑰悜 welltype=4 澶氭鍘嬭姘村钩浜 +% 鐩翠簳銆佹按骞充簳锛岃绉嶄簳鍨嬬殑澶勭悊鏄皢灏勫瓟娈靛畨鎺掑湪鍩鸿川缃戞牸 +% 瀵逛簬鐩翠簳銆佹枩浜曘佹按骞充簳锛岄噰鍙栦笌eclipse涓鑷寸殑鏂瑰紡锛岀粰鍑哄叾鍦ㄥ熀璐ㄧ綉鏍间腑浣嶇疆 +% 姣忎釜灏勫瓟鐐圭敱涓媝x,py,pz纭畾锛屽垎鍒〃绀鸿灏勫瓟鐐瑰湪x鏂瑰悜锛寉鏂瑰悜鐨勭綉鏍肩紪鍙凤紝鍙婂眰鏁板嵆z鍙嶆柟鍚戜笂鐨勭綉鏍肩紪鍙凤紙鏈鍒濇槸浠ュ瀭鐩村悜涓婂缓绔嬬殑鍩鸿川缃戞牸锛 +well1={ + % 'w1', 2, [20 10 1;20 10 2;], 0.178/2, 0, 1; + % 'w2', 2, [80 10 1;80 10 2;], 0.178/2, 0, 1; + % 'w3', 1, [20 40 1;], 0.178/2, 0, 1; + % 'w4', 1, [80 40 1;], 0.178/2, 0, 1; + }; +well1 = handle_well1(well1,r); +%% 鍘嬭姘村钩浜曞畾涔 +% 澶氭鍘嬭姘村钩浜曪細灏勫瓟娈佃缃湪瑁傜紳鍗曞厓涓婏紝鍙互缁欏嚭璇ュ皠瀛旂偣鎵鍦ㄧ殑鍧愭爣锛岀劧鍚庡幓瀵绘壘璇ョ偣鎵鍦ㄧ殑瑁傜紳鍗曞厓缂栧彿 +num_fracture_wells = 1; +welloc = cell(num_fracture_wells,1); +perfnum = cell(num_fracture_wells,1); +welloc{1,1}=[ + 255,255,5; + 305,255,5; + 355,255,5; + 405,255,5; + 455,255,5; + 505,255,5; + 555,255,5; + 605,255,5; + 655,255,5; + 705,255,5; + 755,255,5; + ]; +for i = 1:num_fracture_wells +perfnum{i,1} = findWelloc(r, welloc{i,1});%鍦ㄧ敤浠ellc0涔嬩腑 +end +% perfnum2 = findWelloc(r, welloc2); +well2={ + 'w1', length(perfnum{1,1}), perfnum{1,1}, 0.178/2, 0,4; + }; +Wellc = handle_well1_well2(well1,well2,welloc,r); %鍔犱簳鍜屽皠瀛斾綅缃 +%% 浜曞埗搴﹁缃紙寮鍏充簳銆佸畾鍘/瀹氫骇銆佷究浜庡悶鍚愮瓑锛 +number_phases = 1; +well_schedules = cell(number_phases,1); +time = zeros(number_phases,1); +% 涓嶅悓鏂瑰紡瀵瑰簲鐨勬敹鏁涢毦搴︺侀渶瑕佷笉涓鏍凤紝闇鍒嗛樁娈佃皟鎺э紝 +% 渚嬪鍦ㄦ敞鍏ラ樁娈甸渶瑕佸皬涓浜涳紝濡傛灉闇瑕佸仛鏃╂湡璇曚簳锛宒tmax銆乨tmin閮介渶瑕佸皬涓浜 +dtmax = zeros(number_phases,1); +dtmin = zeros(number_phases,1); + +% (1)well state: 'open'琛ㄧず璇ヤ簳鏄紑鐨勶紱'close'琛ㄦ槑璇ヤ簳涓鐩存槸鍏崇殑锛屽鏋滃彧鏄樁娈垫у叧浜曪紝灏辩敤'open'瀹氭祦閲0鐢熶骇 +% (2)well type: 'pro'琛ㄧず鏄敓浜т簳锛'inj'琛ㄧず鏄敞鍏ヤ簳; +% (3)protype锛'const_q'鏄畾娴侀噺锛'const_pwf'鍒欐槸瀹氬帇 +% (4)value锛氬畾鐨勬祦閲忓兼垨鑰呬簳搴曞帇鍔涘 +% (5)value锛氭浠g爜璇ュ间笌锛3锛夊肩浉鍚 +time(1) = 1e-3; dtmax(1) = 0.00002; dtmin(1) = 0.00001; +well_schedules{1,1} = { + 'w1','open','pro','const_q',10000,10000}; +time(2) = 99e-3; dtmax(2) = 0.0002; dtmin(2) = 0.0001; +well_schedules{1,1} = { + 'w1','open','pro','const_q',10000,10000}; +time(3) = 99e-3; dtmax(3) = 0.0002; dtmin(3) = 0.0001; +well_schedules{1,1} = { + 'w1','open','pro','const_q',10000,10000}; + +%% ======================================PART 7: Solver璁剧疆=========================================== +yitap = 5; % 50-500psi +yitas = 0.04; % 0.05-0.5 +omega = 0.5; % 0-1 +Nmax = 50; +epsave = 1e-6; +epsmax = 1e-6; +% dtmin = 0.001; +% dtmax = 10; +% dtmin = 0.000001; +% dtmax = 0.0001; +%% ======================================PART 8: 姝e紡璁$畻=========================================== +[Times, OutputRs, Wellpara, trun] = solver_NR(r, flow_model, f, os, state0, yitap,yitas,omega,Nmax,epsave,epsmax,dtmin,dtmax,Wellc,time,well_schedules); +run_time=toc; +trun.run_time=run_time; +end \ No newline at end of file diff --git a/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/main1.m b/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/main1.m new file mode 100644 index 0000000..ca69cef --- /dev/null +++ b/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/main1.m @@ -0,0 +1,200 @@ +function [ r, Times, OutputRs, Wellpara, trun ] = main1() +%% ==================================PART 1: 妯″瀷閫夊彇======================================== +% 1-- classical EDFM +modelflag = 1;% 姝ゅ鍥哄畾涓1鍗冲彲 +%% ==================================PART 2: 鍩鸿川缃戞牸瀹氫箟===================================== +dx=[10*ones(1,100) ];nx=size(dx,2); +dy=[10*ones(1,50) ];ny=size(dy,2); +dz=[10*ones(1,1)];nz=size(dz,2); +NTG= 1*ones(nx*ny*nz,1); +r = GridProp_pre(dx, dy,dz,nx,ny,nz,NTG); +%% ==================================PART 3: 瑁傜紳鍒嗗竷鏁版嵁杈撳叆===================================== +% 鍥涚杈撳叆鏂瑰紡: 1琛ㄧず宸ョ▼搴旂敤杈撳叆锛2琛ㄧず鍚戦噺杈撳叆锛3琛ㄧず宸ョ▼搴旂敤杈撳叆锛屽寘鎷熀鍑嗙偣銆佸捐銆佹柟浣嶈銆佹姮鍗囪锛4琛ㄧず浠.fab鏂囦欢璇诲彇 +input_style = 1; +%% 杈撳叆鏂瑰紡1锛氬伐绋嬪簲鐢ㄨ緭鍏 +%浠呰兘鍒荤敾鍏锋湁鍙屽绉版ц川鐨勭煩褰㈢紳鎴栨き鍦嗙紳 +% 鍩哄噯鐐瑰潗鏍囷紙1锛夛紝鏂逛綅瑙掞紙2锛夛紝鍊捐锛3锛夛紝鎶崌瑙掞紙4锛夛紝缂濋暱锛堟き鍦嗛暱杞撮暱锛夛紙5锛夛紝缂濋珮锛堟き鍦嗙煭杞撮暱锛夛紙6锛夛紝绫诲瀷1鏄煩褰㈢紳銆2鏄き鍦嗙紳锛7锛 +if input_style==1 +input_content={ + [255,255,5],90,90,0,200,10,1; + [305,255,5],90,90,0,200,10,1; + [355,255,5],90,90,0,200,10,1; + [405,255,5],90,90,0,200,10,1; + [455,255,5],90,90,0,200,10,1; + [505,255,5],90,90,0,200,10,1; + [555,255,5],90,90,0,200,10,1; + [605,255,5],90,90,0,200,10,1; + [655,255,5],90,90,0,200,10,1; + [705,255,5],90,90,0,200,10,1; + [755,255,5],90,90,0,200,10,1; + }; +[f,fellip] = sort_fracture(input_content); +flowBarrierFlags = []; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5; +frac_information = fractureInformation_input_engineering_vector(f,fellip,flowBarrierFlags); +end +%% 杈撳叆鏂瑰紡2锛氬悜閲忚緭鍏 +%棣栧厛瀵圭煩褰㈢紳杩涜鐮旂┒锛岃缂濆弬鏁板寘鎷笁涓悜閲忓拰涓や釜鍙傛暟鐨勫彇鍊艰寖鍥达紝濡傛灉鏄叾瀹冪被鍨嬬紳锛屽垯鏄袱涓弬鏁伴棿鐨勫嚱鏁板叧绯 +%鍥犳涓涓5琛屼笁鍒楃殑鐭╅樀鍙互纭畾涓鏉¤缂 +%鍚戦噺鍒嗛噺鍙负闈炴暣鏁帮紝浠ユ淇濊瘉鍙傛暟鑼冨洿鐨勫彇鍊间负鏁存暟鍗冲彲锛 +%鏁呭彲鍏堥殢鎰忕‘瀹氫负鏁存暟鐨勫弬鏁拌寖鍥达紝鍐嶆牴鎹紳闀跨紳楂樺幓纭畾鍚戦噺鍒嗛噺鐨勫彇鍊 +% 鐭╁舰缂 +if input_style==2 + f=[ + 0,1200,0;10,-20,0;0,0,10;0,60,0;0,3,0; + 0,1200,0;10,20,0;0,0,10;0,15,0;0,3,0; + 150,1500,0;20,-10,0;0,0,10;0,20,0;0,3,0; + 550,1300,0;10,10,0;0,0,10;0,10,0;0,3,0; + 650,1400,0;10,-20,0;0,0,10;0,55,0;0,3,0; + 605,705,0;10,0,0;0,0,10;-20,20,0;0,3,0; + ]; +% 妞渾缂 +% fellip=[320,210,10;10,2,0;0,0,2;0,0,8;0,0,5; +% 280,300,10;10,2,0;0,0,2;0,0,10;0,0,4;]; +% 300,205,10;10,0,0;0,0,2;0,0,10;0,0,5]; +fellip=[]; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +frac_information = fractureInformation_input_engineering_vector(f,fellip); +end +%% 杈撳叆鏂瑰紡3锛氫簩缁磋緭鍏 +% load('fractures_generated.mat'); +% fractureLines = fractures_generated; +if input_style==3 +fractureLines = [ + 105,150;105,350; + 205,150;205,350; + 305,150;305,350; + 405,150;405,350; + 505,150;505,350; + 605,150;605,350; + 705,150;705,350; + 805,150;805,350; + 905,150;905,350; + ]; +fellip=[]; % 妞渾缂 +fractureHeights = [ + 10;10;10;10;10;10;10;10;10]; +% 妞渾缂 +fellip=[]; +flowBarrierFlags = [];% flowBarrierFlags = [1;2;3;4]; +[f,frac_information] = input_fracture_2D(fractureLines,fractureHeights,flowBarrierFlags); +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +end +%% 杈撳叆鏂瑰紡4锛氫粠.fab鏂囦欢璇诲彇 Frac_PT +if input_style==4 + +end + +%% ==================================PART 4: 鍩鸿川缃戞牸鍙婅缂濈墿鎬у弬鏁拌緭鍏===================================== +% 1-- 鍗曢噸浠嬭川 +% 2-- 鍙岄噸浠嬭川锛堝弻瀛斿弻娓楋級 +grid_model = 1; +if grid_model == 1 +r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf); +end +if grid_model == 2 +r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf); +end +%% 鐢熸垚鍚戦噺鍖栧彉鎴愭墍闇瑕佺殑绠楀瓙 +os = OperatorRS(r.N, r.nex, r.nc); + +%% ==================================PART 5: 妯″瀷绫诲瀷閫夊彇鍙婂垵濮嬬姸鎬佽瀹========================================= +% 1-- 姘旀按涓ょ浉娴 +% 2-- 娌规按涓ょ浉娴 +flow_model = 1; +if flow_model == 1 +[f,state0] = gas_water_flow(r); +end +if flow_model == 2 +[f,state0] = oil_water_flow(r); +end +if flow_model == 3 +[f,state0] = multi_component_flow(r); +end + +%% ==================================PART 6: 浜曞埗搴chedule璁惧畾================================================ +%灏嗙洿浜曘佹按骞充簳涓庡娈靛帇瑁傛按骞充簳鍒嗗紑澶勭悊 +%% 鐩翠簳銆佸父瑙勬按骞充簳瀹氫箟 +% Wellcpara: wellname(1) nperf锛屽皠瀛旂偣鏁伴噺(2) index(3) rw(4) skin(5) welltype(6) +% welltype=1 鐩翠簳锛寃elltype=2 姘村钩浜曟部x鏂瑰悜锛寃elltype=3 姘村钩浜曟部y鏂瑰悜 welltype=4 澶氭鍘嬭姘村钩浜 +% 鐩翠簳銆佹按骞充簳锛岃绉嶄簳鍨嬬殑澶勭悊鏄皢灏勫瓟娈靛畨鎺掑湪鍩鸿川缃戞牸 +% 瀵逛簬鐩翠簳銆佹枩浜曘佹按骞充簳锛岄噰鍙栦笌eclipse涓鑷寸殑鏂瑰紡锛岀粰鍑哄叾鍦ㄥ熀璐ㄧ綉鏍间腑浣嶇疆 +% 姣忎釜灏勫瓟鐐圭敱涓媝x,py,pz纭畾锛屽垎鍒〃绀鸿灏勫瓟鐐瑰湪x鏂瑰悜锛寉鏂瑰悜鐨勭綉鏍肩紪鍙凤紝鍙婂眰鏁板嵆z鍙嶆柟鍚戜笂鐨勭綉鏍肩紪鍙凤紙鏈鍒濇槸浠ュ瀭鐩村悜涓婂缓绔嬬殑鍩鸿川缃戞牸锛 +well1={ + % 'w1', 2, [20 10 1;20 10 2;], 0.178/2, 0, 1; + % 'w2', 2, [80 10 1;80 10 2;], 0.178/2, 0, 1; + % 'w3', 1, [20 40 1;], 0.178/2, 0, 1; + % 'w4', 1, [80 40 1;], 0.178/2, 0, 1; + }; +well1 = handle_well1(well1,r); +%% 鍘嬭姘村钩浜曞畾涔 +% 澶氭鍘嬭姘村钩浜曪細灏勫瓟娈佃缃湪瑁傜紳鍗曞厓涓婏紝鍙互缁欏嚭璇ュ皠瀛旂偣鎵鍦ㄧ殑鍧愭爣锛岀劧鍚庡幓瀵绘壘璇ョ偣鎵鍦ㄧ殑瑁傜紳鍗曞厓缂栧彿 +num_fracture_wells = 1; +welloc = cell(num_fracture_wells,1); +perfnum = cell(num_fracture_wells,1); +welloc{1,1}=[ + 255,255,5; + 305,255,5; + 355,255,5; + 405,255,5; + 455,255,5; + 505,255,5; + 555,255,5; + 605,255,5; + 655,255,5; + 705,255,5; + 755,255,5; + ]; +for i = 1:num_fracture_wells +perfnum{i,1} = findWelloc(r, welloc{i,1});%鍦ㄧ敤浠ellc0涔嬩腑 +end +% perfnum2 = findWelloc(r, welloc2); +well2={ + 'w1', length(perfnum{1,1}), perfnum{1,1}, 0.178/2, 0,4; + }; +Wellc = handle_well1_well2(well1,well2,welloc,r); %鍔犱簳鍜屽皠瀛斾綅缃 +%% 浜曞埗搴﹁缃紙寮鍏充簳銆佸畾鍘/瀹氫骇銆佷究浜庡悶鍚愮瓑锛 +number_phases = 5; +well_schedules = cell(number_phases,1); +time = zeros(number_phases,1); +% 涓嶅悓鏂瑰紡瀵瑰簲鐨勬敹鏁涢毦搴︺侀渶瑕佷笉涓鏍凤紝闇鍒嗛樁娈佃皟鎺э紝 +% 渚嬪鍦ㄦ敞鍏ラ樁娈甸渶瑕佸皬涓浜涳紝濡傛灉闇瑕佸仛鏃╂湡璇曚簳锛宒tmax銆乨tmin閮介渶瑕佸皬涓浜 +dtmax = zeros(number_phases,1); +dtmin = zeros(number_phases,1); + +% (1)well state: 'open'琛ㄧず璇ヤ簳鏄紑鐨勶紱'close'琛ㄦ槑璇ヤ簳涓鐩存槸鍏崇殑锛屽鏋滃彧鏄樁娈垫у叧浜曪紝灏辩敤'open'瀹氭祦閲0鐢熶骇 +% (2)well type: 'pro'琛ㄧず鏄敓浜т簳锛'inj'琛ㄧず鏄敞鍏ヤ簳; +% (3)protype锛'const_q'鏄畾娴侀噺锛'const_pwf'鍒欐槸瀹氬帇 +% (4)value锛氬畾鐨勬祦閲忓兼垨鑰呬簳搴曞帇鍔涘 +% (5)value锛氭浠g爜璇ュ间笌锛3锛夊肩浉鍚 +time(1) = 1e-3; dtmax(1) = 0.00002; dtmin(1) = 0.00001; +well_schedules{1,1} = { + 'w1','open','pro','const_q',10000,10000}; +time(2) = 99e-3; dtmax(2) = 0.0002; dtmin(2) = 0.0001; +well_schedules{2,1} = { + 'w1','open','pro','const_q',10000,10000}; +time(3) = 0.9; dtmax(3) = 0.002; dtmin(3) = 0.001; +well_schedules{3,1} = { + 'w1','open','pro','const_q',10000,10000}; +time(4) = 100; dtmax(4) = 2; dtmin(4) = 0.01; +well_schedules{4,1} = { + 'w1','open','pro','const_q',10000,10000}; +time(5) = 900; dtmax(5) = 10; dtmin(5) = 0.01; +well_schedules{5,1} = { + 'w1','open','pro','const_q',10000,10000}; +%% ======================================PART 7: Solver璁剧疆=========================================== +yitap = 5; % 50-500psi +yitas = 0.04; % 0.05-0.5 +omega = 0.5; % 0-1 +Nmax = 50; +epsave = 1e-6; +epsmax = 1e-6; +% dtmin = 0.001; +% dtmax = 10; +% dtmin = 0.000001; +% dtmax = 0.0001; +%% ======================================PART 8: 姝e紡璁$畻=========================================== +[Times, OutputRs, Wellpara, trun] = solver_NR(r, flow_model, f, os, state0, yitap,yitas,omega,Nmax,epsave,epsmax,dtmin,dtmax,Wellc,time,well_schedules); +run_time=toc; +trun.run_time=run_time; +end \ No newline at end of file diff --git a/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/plotWellResponse.m b/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/plotWellResponse.m new file mode 100644 index 0000000..b3bcc97 --- /dev/null +++ b/绠椾緥4-姘旀按涓ょ浉娴-鍘嬪姏瀵兼暟鏇茬嚎/plotWellResponse.m @@ -0,0 +1,55 @@ +function [] = plotWellResponse(Times,Wellpara) +% 输入 +wellNumber = 1; % 井号 +dataType = 'dPWF'; % 类型,产气速度 GPR,产气速度 OPR, 产水速度 WPR,井底流压 BHP,压力导数 dPWF +% +t = Times; +n= size(Times,1); +% para = cell2mat(Wellpara); +nw = wellNumber;%选井号 +% n = length(para); +data = zeros(n,1); +if strcmp(dataType, 'GPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qg; + figureYlegend = 'Gas production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'OPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qo; + figureYlegend = 'Oil production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'WPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qw; + figureYlegend = 'Water production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'BHP') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.pwf; + figureYlegend = 'BHP, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'dPWF') % dpwf/dlnt = t*dpwf/dt + for i = 1 : n + if i == 1 + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i}{1,nw}.pwf)/(log(t(i+1))-log(t(i))); + elseif i == n + data(i) = (Wellpara{i}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i))-log(t(i-1))); + else + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i+1))-log(t(i-1))); + end + figureYlegend = 'Pressure derivative, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); + set(gca, 'XScale', 'log'); + set(gca, 'YScale', 'log'); +end +end \ No newline at end of file diff --git a/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/grid_discretization_SP_model.m b/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/grid_discretization_SP_model.m new file mode 100644 index 0000000..fe08427 --- /dev/null +++ b/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/grid_discretization_SP_model.m @@ -0,0 +1,55 @@ +function r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf) +% 鏁版嵁璇诲彇 +nx = r.nx; ny = r.ny; nz = r.nz; NTG = r.NTG; cell_mid_coords = r.cell_mid_coords; +% 鍩鸿川瀛旀笚 +rock_density = 2700; % 宀╃煶瀵嗗害锛宬g/m^3 +kx = 5*1e-3 * ones(nx*ny*nz, 1); % 杈捐タ锛孌 +ky = 5*1e-3 * ones(nx*ny*nz, 1);% +kz = 5*1e-3 * ones(nx*ny*nz, 1);% +pori = 0.01 * ones(nx*ny*nz, 1);% +prpor = 20; % 鍙傝冨帇鍔涳紝MPa +cpor = 1.0e-5;% 鍩鸿川鍘嬬缉绯绘暟锛,MPa +% 鏈夋晥缃戞牸 +valid_grids = ones(nx*ny*nz, 1); +invalid_layer = []; % 灏嗙浜屽眰鏃犳晥缃戞牸 +for i = 1:length(invalid_layer) + grid_numbering_range = ((invalid_layer(i)-1)*nx*ny+1:invalid_layer(i)*nx*ny)'; + valid_grids(grid_numbering_range,1) = 0; +end +% SRV鍖哄煙瀹氫箟 +% % % base_x=23:78; nx_SRV=length(base_x); +% % % base_y=15:36; ny_SRV=length(base_y); +% % % base_z=1:1;nz_SRV=length(base_z); +% % % SRV=[]; +% % % for k=1:nz_SRV +% % % for j=1:ny_SRV +% % % for i=1:nx_SRV +% % % SRV=[SRV;(base_z(k)-1)*nx*ny+(base_y(j)-1)*nx+base_x(i)]; +% % % end +% % % end +% % % end +% % % % SRV娓楅忕巼璧嬪 +% % % kx(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % ky(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % kz(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% 瑁傜紳瀛旀笚 +Kf = 10000*1e-3*ones(1,nf);% 瑁傜紳娓楅忕巼 +Wf = 1e-2*ones(1,nf);% 瑁傜紳寮搴 +Porf = 0.30*ones(1,nf);% 瑁傜紳瀛旈殭搴 +prporf = 20;% 瑁傜紳绯荤粺鍙傝冨帇鍔 +cporf = 1.0e-5;% 瑁傜紳绯荤粺鍘嬬缉绯绘暟 +% 搴斿姏鏁忔劅 +stress_factor_fracture = 0.000; % 1/MPa 0.001 +stress_factor_matrix = 0.000; % 1/MPa +stress_factor_ref_pressure = 20; % 涓鑸彇涓哄師濮嬪湴灞傚帇鍔汳Pa +% +Rpt = 2;cf = 1;ca = 1; +%% 缁撳悎鍩鸿川銆佽缂濈殑鍑犱綍鍙婄墿鎬т俊鎭紑灞曞墠澶勭悊 +% r = GridProp(modelflag, nx, ny, nz, dx, dy, dz, kx, ky, kz, f, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,co, NTG); +r = GridProp_new(modelflag, r, kx, ky, kz, f, frac_information, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca, valid_grids); +r.rock_density = rock_density; +r.valid_grids = valid_grids; +r.stress_factor_fracture = stress_factor_fracture; +r.stress_factor_matrix = stress_factor_matrix; +r.stress_factor_ref_pressure = stress_factor_ref_pressure; +end \ No newline at end of file diff --git a/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/main1.m b/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/main1.m new file mode 100644 index 0000000..472478f --- /dev/null +++ b/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/main1.m @@ -0,0 +1,200 @@ +function [ r, Times, OutputRs, Wellpara, trun ] = main1() +%% ==================================PART 1: 妯″瀷閫夊彇======================================== +% 1-- classical EDFM +modelflag = 1;% 姝ゅ鍥哄畾涓1鍗冲彲 +%% ==================================PART 2: 鍩鸿川缃戞牸瀹氫箟===================================== +dx=[10*ones(1,100) ];nx=size(dx,2); +dy=[10*ones(1,50) ];ny=size(dy,2); +dz=[10*ones(1,1)];nz=size(dz,2); +NTG= 1*ones(nx*ny*nz,1); +r = GridProp_pre(dx,dy,dz,nx,ny,nz,NTG); +%% ==================================PART 3: 瑁傜紳鍒嗗竷鏁版嵁杈撳叆===================================== +% 鍥涚杈撳叆鏂瑰紡: 1琛ㄧず宸ョ▼搴旂敤杈撳叆锛2琛ㄧず鍚戦噺杈撳叆锛3琛ㄧず宸ョ▼搴旂敤杈撳叆锛屽寘鎷熀鍑嗙偣銆佸捐銆佹柟浣嶈銆佹姮鍗囪锛4琛ㄧず浠.fab鏂囦欢璇诲彇 +input_style = 1; +%% 杈撳叆鏂瑰紡1锛氬伐绋嬪簲鐢ㄨ緭鍏 +%浠呰兘鍒荤敾鍏锋湁鍙屽绉版ц川鐨勭煩褰㈢紳鎴栨き鍦嗙紳 +% 鍩哄噯鐐瑰潗鏍囷紙1锛夛紝鏂逛綅瑙掞紙2锛夛紝鍊捐锛3锛夛紝鎶崌瑙掞紙4锛夛紝缂濋暱锛堟き鍦嗛暱杞撮暱锛夛紙5锛夛紝缂濋珮锛堟き鍦嗙煭杞撮暱锛夛紙6锛夛紝绫诲瀷1鏄煩褰㈢紳銆2鏄き鍦嗙紳锛7锛 +if input_style==1 +input_content={ + [255,255,5],90,90,0,200,10,1; + [305,255,5],90,90,0,200,10,1; + [355,255,5],90,90,0,200,10,1; + [405,255,5],90,90,0,200,10,1; + [455,255,5],90,90,0,200,10,1; + [505,255,5],90,90,0,200,10,1; + [555,255,5],90,90,0,200,10,1; + [605,255,5],90,90,0,200,10,1; + [655,255,5],90,90,0,200,10,1; + [705,255,5],90,90,0,200,10,1; + [755,255,5],90,90,0,200,10,1; + }; +[f,fellip] = sort_fracture(input_content); +flowBarrierFlags = []; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5; +frac_information = fractureInformation_input_engineering_vector(f,fellip,flowBarrierFlags); +end +%% 杈撳叆鏂瑰紡2锛氬悜閲忚緭鍏 +%棣栧厛瀵圭煩褰㈢紳杩涜鐮旂┒锛岃缂濆弬鏁板寘鎷笁涓悜閲忓拰涓や釜鍙傛暟鐨勫彇鍊艰寖鍥达紝濡傛灉鏄叾瀹冪被鍨嬬紳锛屽垯鏄袱涓弬鏁伴棿鐨勫嚱鏁板叧绯 +%鍥犳涓涓5琛屼笁鍒楃殑鐭╅樀鍙互纭畾涓鏉¤缂 +%鍚戦噺鍒嗛噺鍙负闈炴暣鏁帮紝浠ユ淇濊瘉鍙傛暟鑼冨洿鐨勫彇鍊间负鏁存暟鍗冲彲锛 +%鏁呭彲鍏堥殢鎰忕‘瀹氫负鏁存暟鐨勫弬鏁拌寖鍥达紝鍐嶆牴鎹紳闀跨紳楂樺幓纭畾鍚戦噺鍒嗛噺鐨勫彇鍊 +% 鐭╁舰缂 +if input_style==2 + f=[ + 0,1200,0;10,-20,0;0,0,10;0,60,0;0,3,0; + 0,1200,0;10,20,0;0,0,10;0,15,0;0,3,0; + 150,1500,0;20,-10,0;0,0,10;0,20,0;0,3,0; + 550,1300,0;10,10,0;0,0,10;0,10,0;0,3,0; + 650,1400,0;10,-20,0;0,0,10;0,55,0;0,3,0; + 605,705,0;10,0,0;0,0,10;-20,20,0;0,3,0; + ]; +% 妞渾缂 +% fellip=[320,210,10;10,2,0;0,0,2;0,0,8;0,0,5; +% 280,300,10;10,2,0;0,0,2;0,0,10;0,0,4;]; +% 300,205,10;10,0,0;0,0,2;0,0,10;0,0,5]; +fellip=[]; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +frac_information = fractureInformation_input_engineering_vector(f,fellip); +end +%% 杈撳叆鏂瑰紡3锛氫簩缁磋緭鍏 +% load('fractures_generated.mat'); +% fractureLines = fractures_generated; +if input_style==3 +fractureLines = [ + 105,150;105,350; + 205,150;205,350; + 305,150;305,350; + 405,150;405,350; + 505,150;505,350; + 605,150;605,350; + 705,150;705,350; + 805,150;805,350; + 905,150;905,350; + ]; +fellip=[]; % 妞渾缂 +fractureHeights = [ + 10;10;10;10;10;10;10;10;10]; +% 妞渾缂 +fellip=[]; +flowBarrierFlags = [];% flowBarrierFlags = [1;2;3;4]; +[f,frac_information] = input_fracture_2D(fractureLines,fractureHeights,flowBarrierFlags); +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +end +%% 杈撳叆鏂瑰紡4锛氫粠.fab鏂囦欢璇诲彇 Frac_PT +if input_style==4 + +end + +%% ==================================PART 4: 鍩鸿川缃戞牸鍙婅缂濈墿鎬у弬鏁拌緭鍏===================================== +% 1-- 鍗曢噸浠嬭川 +% 2-- 鍙岄噸浠嬭川锛堝弻瀛斿弻娓楋級 +grid_model = 1; +if grid_model == 1 +r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf); +end +if grid_model == 2 +r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf); +end + +%% 鐢熸垚鍚戦噺鍖栧彉鎴愭墍闇瑕佺殑绠楀瓙 +os = OperatorRS(r.N, r.nex, r.nc); + +%% ==================================PART 5: 妯″瀷绫诲瀷閫夊彇鍙婂垵濮嬬姸鎬佽瀹========================================= +% 1-- 姘旀按涓ょ浉娴 +% 2-- 娌规按涓ょ浉娴 +flow_model = 2; +if flow_model == 1 +[f,state0] = gas_water_flow(r); +end +if flow_model == 2 +[f,state0] = oil_water_flow(r); +end +if flow_model == 3 +[f,state0] = multi_component_flow(r); +end + +%% ==================================PART 6: 浜曞埗搴chedule璁惧畾================================================ +%灏嗙洿浜曘佹按骞充簳涓庡娈靛帇瑁傛按骞充簳鍒嗗紑澶勭悊 +%% 鐩翠簳銆佸父瑙勬按骞充簳瀹氫箟 +% Wellcpara: wellname(1) nperf锛屽皠瀛旂偣鏁伴噺(2) index(3) rw(4) skin(5) welltype(6) +% welltype=1 鐩翠簳锛寃elltype=2 姘村钩浜曟部x鏂瑰悜锛寃elltype=3 姘村钩浜曟部y鏂瑰悜 welltype=4 澶氭鍘嬭姘村钩浜 +% 鐩翠簳銆佹按骞充簳锛岃绉嶄簳鍨嬬殑澶勭悊鏄皢灏勫瓟娈靛畨鎺掑湪鍩鸿川缃戞牸 +% 瀵逛簬鐩翠簳銆佹枩浜曘佹按骞充簳锛岄噰鍙栦笌eclipse涓鑷寸殑鏂瑰紡锛岀粰鍑哄叾鍦ㄥ熀璐ㄧ綉鏍间腑浣嶇疆 +% 姣忎釜灏勫瓟鐐圭敱涓媝x,py,pz纭畾锛屽垎鍒〃绀鸿灏勫瓟鐐瑰湪x鏂瑰悜锛寉鏂瑰悜鐨勭綉鏍肩紪鍙凤紝鍙婂眰鏁板嵆z鍙嶆柟鍚戜笂鐨勭綉鏍肩紪鍙凤紙鏈鍒濇槸浠ュ瀭鐩村悜涓婂缓绔嬬殑鍩鸿川缃戞牸锛 +well1={ + % 'w1', 2, [20 10 1;20 10 2;], 0.178/2, 0, 1; + % 'w2', 2, [80 10 1;80 10 2;], 0.178/2, 0, 1; + % 'w3', 1, [20 40 1;], 0.178/2, 0, 1; + % 'w4', 1, [80 40 1;], 0.178/2, 0, 1; +% 'w2', 3, [67 20 1;67 20 2;67 20 3], 0.178/2, 0, 1; + }; +well1 = handle_well1(well1,r); +%% 鍘嬭姘村钩浜曞畾涔 +% 澶氭鍘嬭姘村钩浜曪細灏勫瓟娈佃缃湪瑁傜紳鍗曞厓涓婏紝鍙互缁欏嚭璇ュ皠瀛旂偣鎵鍦ㄧ殑鍧愭爣锛岀劧鍚庡幓瀵绘壘璇ョ偣鎵鍦ㄧ殑瑁傜紳鍗曞厓缂栧彿 +num_fracture_wells = 1; +welloc = cell(num_fracture_wells,1); +perfnum = cell(num_fracture_wells,1); +welloc{1,1}=[ + 255,255,5; + 305,255,5; + 355,255,5; + 405,255,5; + 455,255,5; + 505,255,5; + 555,255,5; + 605,255,5; + 655,255,5; + 705,255,5; + 755,255,5; + ]; +for i = 1:num_fracture_wells +perfnum{i,1} = findWelloc(r, welloc{i,1});%鍦ㄧ敤浠ellc0涔嬩腑 +end +% perfnum2 = findWelloc(r, welloc2); +well2={ + 'w1', length(perfnum{1,1}), perfnum{1,1}, 0.178/2, 0,4; + }; +Wellc = handle_well1_well2(well1,well2,welloc,r); %鍔犱簳鍜屽皠瀛斾綅缃 +%% 浜曞埗搴﹁缃紙寮鍏充簳銆佸畾鍘/瀹氫骇銆佷究浜庡悶鍚愮瓑锛 +number_phases = 3; +well_schedules = cell(number_phases,1); +time = zeros(number_phases,1); +% 涓嶅悓鏂瑰紡瀵瑰簲鐨勬敹鏁涢毦搴︺侀渶瑕佷笉涓鏍凤紝闇鍒嗛樁娈佃皟鎺э紝 +% 渚嬪鍦ㄦ敞鍏ラ樁娈甸渶瑕佸皬涓浜涳紝濡傛灉闇瑕佸仛鏃╂湡璇曚簳锛宒tmax銆乨tmin閮介渶瑕佸皬涓浜 +dtmax = zeros(number_phases,1); +dtmin = zeros(number_phases,1); + +% (1)well state: 'open'琛ㄧず璇ヤ簳鏄紑鐨勶紱'close'琛ㄦ槑璇ヤ簳涓鐩存槸鍏崇殑锛屽鏋滃彧鏄樁娈垫у叧浜曪紝灏辩敤'open'瀹氭祦閲0鐢熶骇 +% (2)well type: 'pro'琛ㄧず鏄敓浜т簳锛'inj'琛ㄧず鏄敞鍏ヤ簳; +% (3)protype锛'const_q'鏄畾娴侀噺锛'const_pwf'鍒欐槸瀹氬帇 +% (4)value锛氬畾鐨勬祦閲忓兼垨鑰呬簳搴曞帇鍔涘 +% (5)value锛氭浠g爜璇ュ间笌锛3锛夊肩浉鍚 +time(1) = 10; dtmax(1) = 0.5; dtmin(1) = 0.001; +well_schedules{1,1} = { + % 'w1','open','inj','const_pwf',30,30; + % 'w2','open','inj','const_pwf',30,30; + % 'w3','open','inj','const_pwf',30,30; + % 'w4','open','inj','const_pwf',30,30; + 'w1','open','inj','const_pwf',40,40}; +time(2) = 30; dtmax(2) = 1; dtmin(2) = 0.001; +well_schedules{2,1} = { + 'w1','open','pro','const_q',0,0; + }; +time(3) = 200; dtmax(3) = 5; dtmin(3) = 0.001; +well_schedules{3,1} = { + 'w1','open','pro','const_pwf',10,10; + % 'w2','open','pro','const_pwf',10,10; + }; + +%% ======================================PART 7: Solver璁剧疆=========================================== +yitap = 5; % 50-500psi +yitas = 0.04; % 0.05-0.5 +omega = 0.5; % 0-1 +Nmax = 50; +epsave = 1e-6; +epsmax = 1e-6; +%% ======================================PART 8: 姝e紡璁$畻=========================================== +[Times, OutputRs, Wellpara, trun] = solver_NR(r, flow_model, f, os, state0, yitap,yitas,omega,Nmax,epsave,epsmax,dtmin,dtmax,Wellc,time,well_schedules); +run_time=toc; +trun.run_time=run_time; +end \ No newline at end of file diff --git a/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/oil_water_flow.m b/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/oil_water_flow.m new file mode 100644 index 0000000..2b37ab7 --- /dev/null +++ b/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/oil_water_flow.m @@ -0,0 +1,126 @@ +function [f,state0] = oil_water_flow(r) +% =======================娌圭浉浣撶Н瀵嗗害銆佷綋绉郴鏁般佺矘搴︾瓑=============================== +density_o_sc = 800; % kg/m3 +% 绗竴绉嶆ā寮忥紝鐩存帴杈撳叆鍙傝冨帇鍔涖佷綋绉郴鏁般佸帇缂╃郴鏁般佺矘搴 +oil_model =1; +if oil_model == 1 +pro = 30; % reference pressure, MPa +Boi = 1.1; % gas phase volume factor +co = 1e-3 ;% gas phase compressibility, 1/MPa +voi = 10; % gas viscosity, cp +cvo = 0; % 姘旂浉绮樺害闅忓帇鍔涘彉鍖栫殑绾挎х郴鏁帮紝cp/MPa +[Ppr,BO,MUO] = cal_oil_prop(pro,Boi,co,voi,cvo); +end +if oil_model == 2 +Ppr = [ 0.1013 + 2.0946 + 4.0878 + 6.0811 + 8.0743 + 10.0676 + 12.0608 + 14.0540 + 16.0473 + 18.0405 + 20.0338 + 22.0270 + 24.0203 + 26.0135 + 28.0068 + 30.0000 + ]; +% BO = 0.01*ones(size(Ppr,1),1); +BO = [ 1.18297 + 0.0557041 + 0.0278168 + 0.0182594 + 0.0134665 + 0.0106154 + 0.00874829 + 0.00744907 + 0.00650639 + 0.0058006 + 0.0052587 + 0.0048336 + 0.00449378 + 0.00421751 + 0.0039895 + 0.00379871 + ]; +% MUG = 0.01*ones(size(Ppr,1),1); +MUO = [0.0127683 + 0.0130191 + 0.0133973 + 0.013872 + 0.014437 + 0.015088 + 0.0158182 + 0.0166173 + 0.0174719 + 0.0183671 + 0.0192882 + 0.0202219 + 0.0211575 + 0.0220865 + 0.0230024 + 0.0239008 + ]; +end +% ========================姘寸浉浣撶Н绯绘暟銆佺矘搴=============================== +density_w_sc = 1000; % kg/m3 +prw = 30; % reference pressure, MPa +Bwi = 1.000; % water phase volume factor, 鏃犲洜娆 +cw = 4.0e-4 ;% water phase compressibility, 1/MPa +vwi = 1; % water viscosity, cp +cvw = 0; % 姘寸浉绮樺害闅忓帇鍔涘彉鍖栫殑绾挎х郴鏁帮紝cp/MPa +% =============================鍩鸿川鐩告笚=============================== +ifpcow = 0; % 鏄惁鑰冭檻姣涚鍔 +PRM=[ + 0.0000 0.0000 1.0000 3.8916 +0.2000 0.0000 1.0000 3.8916 +0.3160 0.0002 0.6784 0.5796 +0.4350 0.0004 0.6215 0.3724 +0.5620 0.0010 0.5456 0.2425 +0.6140 0.0020 0.3939 0.0608 +0.7020 0.0280 0.1399 0.0372 +0.8120 0.1721 0.0515 0.0137 +0.8750 0.3395 0.0297 0.0104 +0.9060 0.4395 0.0 0.0090 +1.0 0.4395 0.0 0.0090 +]; +SW=PRM(:,1);KRW=PRM(:,2);KRO=PRM(:,3);PCOW=PRM(:,4); + +% =============================瑁傜紳鐩告笚=============================== +PRF=[ +0.0000 0.0000 1.0000 3.8916 +0.2000 0.0000 1.0000 3.8916 +0.3160 0.0002 0.6784 0.5796 +0.4350 0.0004 0.6215 0.3724 +0.5620 0.0010 0.5456 0.2425 +0.6140 0.0020 0.3939 0.0608 +0.7020 0.0280 0.1399 0.0372 +0.8120 0.1721 0.0515 0.0137 +0.8750 0.3395 0.0297 0.0104 +0.9060 0.4395 0.0 0.0090 +1.0 0.4395 0.0 0.0090 +]; +SWF = PRF(:,1);KRWF = PRF(:,2);KROF = PRF(:,3);PCOWF=PRF(:,4); +%% +% ===================== 楂橀熼潪杈捐タ娴 Forchheimer 鏂圭▼ ==================== +beta_non_Darcy_flow = 0; % 1e-8 +% ===================== 鍚姩鍘嬪姏姊害 ==================== +p_grad_threshold = 0.00; % MPa/m +%% 缁撳悎娴佷綋鎬ц川鍙傛暟鐢熸垚鐩稿簲鐨勬暟鎹綋 +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, r.rpt); +f.beta_non_Darcy_flow = beta_non_Darcy_flow; +f.Dwsi = density_w_sc; +f.Dosi = density_o_sc; +f.p_grad_threshold = p_grad_threshold; +%% 鍒濆兼潯浠 Initial Condition Section +% =================鍘嬪姏銆侀ケ鍜屽害鍒濆======================================= % +%鍘嬪姏鍒濆艰鑰冭檻閲嶅姏锛岀粰鍑烘补钘忎笅琛ㄩ潰鍘嬪姏鍊 +P = [20 * ones(r.nmc, 1); 20 * ones(r.nfc, 1)]; +% plow=25; % P =plow-1e-6*800*9.8*r.z; +Sw = [0.2 * ones(r.nmc, 1); 0.2 * ones(r.nfc, 1)]; +state0 = initialRS_oil_water_flow(P, Sw); +end \ No newline at end of file diff --git a/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/plotWellResponse.m b/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/plotWellResponse.m new file mode 100644 index 0000000..fcd76ee --- /dev/null +++ b/绠椾緥5-娌规按涓ょ浉娴-娉ㄧ剸閲/plotWellResponse.m @@ -0,0 +1,55 @@ +function [] = plotWellResponse(Times,Wellpara) +% 输入 +wellNumber = 1; % 井号 +dataType = 'OPR'; % 类型,产气速度 GPR,产气速度 OPR, 产水速度 WPR,井底流压 BHP,压力导数 dPWF +% +t = Times; +n= size(Times,1); +% para = cell2mat(Wellpara); +nw = wellNumber;%选井号 +% n = length(para); +data = zeros(n,1); +if strcmp(dataType, 'GPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qg; + figureYlegend = 'Gas production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'OPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qo; + figureYlegend = 'Oil production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'WPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qw; + figureYlegend = 'Water production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'BHP') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.pwf; + figureYlegend = 'BHP, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'dPWF') % dpwf/dlnt = t*dpwf/dt + for i = 1 : n + if i == 1 + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i}{1,nw}.pwf)/(log(t(i+1))-log(t(i))); + elseif i == n + data(i) = (Wellpara{i}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i))-log(t(i-1))); + else + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i+1))-log(t(i-1))); + end + figureYlegend = 'Pressure derivative, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); + set(gca, 'XScale', 'log'); + set(gca, 'YScale', 'log'); +end +end \ No newline at end of file diff --git a/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/grid_discretization_SP_model.m b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/grid_discretization_SP_model.m new file mode 100644 index 0000000..5469bbc --- /dev/null +++ b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/grid_discretization_SP_model.m @@ -0,0 +1,55 @@ +function r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf) +% 鏁版嵁璇诲彇 +nx = r.nx; ny = r.ny; nz = r.nz; NTG = r.NTG; cell_mid_coords = r.cell_mid_coords; +% 鍩鸿川瀛旀笚 +density_rock = 2700; % 宀╃煶瀵嗗害锛宬g/m^3 +kx = 1*1e-3 * ones(nx*ny*nz, 1); % 杈捐タ锛孌 +ky = 1*1e-3 * ones(nx*ny*nz, 1);% +kz = 1*1e-3 * ones(nx*ny*nz, 1);% +pori = 0.08 * ones(nx*ny*nz, 1);% +prpor = 20; % 鍙傝冨帇鍔涳紝MPa +cpor = 1.0e-5;% 鍩鸿川鍘嬬缉绯绘暟锛,MPa +% 鏈夋晥缃戞牸 +valid_grids = ones(nx*ny*nz, 1); +invalid_layer = []; % 灏嗙浜屽眰鏃犳晥缃戞牸 +for i = 1:length(invalid_layer) + grid_numbering_range = ((invalid_layer(i)-1)*nx*ny+1:invalid_layer(i)*nx*ny)'; + valid_grids(grid_numbering_range,1) = 0; +end +% SRV鍖哄煙瀹氫箟 +% % % base_x=23:78; nx_SRV=length(base_x); +% % % base_y=15:36; ny_SRV=length(base_y); +% % % base_z=1:1;nz_SRV=length(base_z); +% % % SRV=[]; +% % % for k=1:nz_SRV +% % % for j=1:ny_SRV +% % % for i=1:nx_SRV +% % % SRV=[SRV;(base_z(k)-1)*nx*ny+(base_y(j)-1)*nx+base_x(i)]; +% % % end +% % % end +% % % end +% % % % SRV娓楅忕巼璧嬪 +% % % kx(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % ky(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % kz(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% 瑁傜紳瀛旀笚 +Kf = 10000*1e-3*ones(1,nf);% 瑁傜紳娓楅忕巼 +Wf = 1e-2*ones(1,nf);% 瑁傜紳寮搴 +Porf = 0.30*ones(1,nf);% 瑁傜紳瀛旈殭搴 +prporf = 20;% 瑁傜紳绯荤粺鍙傝冨帇鍔 +cporf = 1.0e-5;% 瑁傜紳绯荤粺鍘嬬缉绯绘暟 +% 搴斿姏鏁忔劅 +stress_factor_fracture = 0.000; % 1/MPa 0.001 +stress_factor_matrix = 0.000; % 1/MPa +stress_factor_ref_pressure = 20; % 涓鑸彇涓哄師濮嬪湴灞傚帇鍔汳Pa +% +Rpt = 2;cf = 1;ca = 1; +%% 缁撳悎鍩鸿川銆佽缂濈殑鍑犱綍鍙婄墿鎬т俊鎭紑灞曞墠澶勭悊 +% r = GridProp(modelflag, nx, ny, nz, dx, dy, dz, kx, ky, kz, f, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,co, NTG); +r = GridProp_new(modelflag, r, kx, ky, kz, f, frac_information, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca, valid_grids); +r.density_rock = density_rock; +r.valid_grids = valid_grids; +r.stress_factor_fracture = stress_factor_fracture; +r.stress_factor_matrix = stress_factor_matrix; +r.stress_factor_ref_pressure = stress_factor_ref_pressure; +end \ No newline at end of file diff --git a/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/main1.m b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/main1.m new file mode 100644 index 0000000..99df1fa --- /dev/null +++ b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/main1.m @@ -0,0 +1,196 @@ +function [ r, Times, OutputRs, Wellpara, trun ] = main1() +%% ==================================PART 1: 妯″瀷閫夊彇======================================== +% 1-- classical EDFM +modelflag = 1;% 姝ゅ鍥哄畾涓1鍗冲彲 +%% ==================================PART 2: 鍩鸿川缃戞牸瀹氫箟===================================== +dx=[10*ones(1,100) ];nx=size(dx,2); +dy=[10*ones(1,50) ];ny=size(dy,2); +dz=[10*ones(1,2)];nz=size(dz,2); +NTG= 1*ones(nx*ny*nz,1); +r = GridProp_pre(dx, dy,dz,nx,ny,nz,NTG); +%% ==================================PART 3: 瑁傜紳鍒嗗竷鏁版嵁杈撳叆===================================== +% 鍥涚杈撳叆鏂瑰紡: 1琛ㄧず宸ョ▼搴旂敤杈撳叆锛2琛ㄧず鍚戦噺杈撳叆锛3琛ㄧず宸ョ▼搴旂敤杈撳叆锛屽寘鎷熀鍑嗙偣銆佸捐銆佹柟浣嶈銆佹姮鍗囪锛4琛ㄧず浠.fab鏂囦欢璇诲彇 +input_style = 1; +%% 杈撳叆鏂瑰紡1锛氬伐绋嬪簲鐢ㄨ緭鍏 +%浠呰兘鍒荤敾鍏锋湁鍙屽绉版ц川鐨勭煩褰㈢紳鎴栨き鍦嗙紳 +% 鍩哄噯鐐瑰潗鏍囷紙1锛夛紝鏂逛綅瑙掞紙2锛夛紝鍊捐锛3锛夛紝鎶崌瑙掞紙4锛夛紝缂濋暱锛堟き鍦嗛暱杞撮暱锛夛紙5锛夛紝缂濋珮锛堟き鍦嗙煭杞撮暱锛夛紙6锛夛紝绫诲瀷1鏄煩褰㈢紳銆2鏄き鍦嗙紳锛7锛 +if input_style==1 +input_content={ + [255,255,5],90,90,0,200,10,1; + [305,255,5],90,90,0,200,10,1; + [355,255,5],90,90,0,200,10,1; + [405,255,5],90,90,0,200,10,1; + [455,255,5],90,90,0,200,10,1; + [505,255,5],90,90,0,200,10,1; + [555,255,15],90,90,0,200,10,1; + [605,255,15],90,90,0,200,10,1; + [655,255,15],90,90,0,200,10,1; + [705,255,15],90,90,0,200,10,1; + [755,255,15],90,90,0,200,10,1; + }; +[f,fellip] = sort_fracture(input_content); +flowBarrierFlags = []; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5; +frac_information = fractureInformation_input_engineering_vector(f,fellip,flowBarrierFlags); +end +%% 杈撳叆鏂瑰紡2锛氬悜閲忚緭鍏 +%棣栧厛瀵圭煩褰㈢紳杩涜鐮旂┒锛岃缂濆弬鏁板寘鎷笁涓悜閲忓拰涓や釜鍙傛暟鐨勫彇鍊艰寖鍥达紝濡傛灉鏄叾瀹冪被鍨嬬紳锛屽垯鏄袱涓弬鏁伴棿鐨勫嚱鏁板叧绯 +%鍥犳涓涓5琛屼笁鍒楃殑鐭╅樀鍙互纭畾涓鏉¤缂 +%鍚戦噺鍒嗛噺鍙负闈炴暣鏁帮紝浠ユ淇濊瘉鍙傛暟鑼冨洿鐨勫彇鍊间负鏁存暟鍗冲彲锛 +%鏁呭彲鍏堥殢鎰忕‘瀹氫负鏁存暟鐨勫弬鏁拌寖鍥达紝鍐嶆牴鎹紳闀跨紳楂樺幓纭畾鍚戦噺鍒嗛噺鐨勫彇鍊 +% 鐭╁舰缂 +if input_style==2 + f=[ + 0,1200,0;10,-20,0;0,0,10;0,60,0;0,3,0; + 0,1200,0;10,20,0;0,0,10;0,15,0;0,3,0; + 150,1500,0;20,-10,0;0,0,10;0,20,0;0,3,0; + 550,1300,0;10,10,0;0,0,10;0,10,0;0,3,0; + 650,1400,0;10,-20,0;0,0,10;0,55,0;0,3,0; + 605,705,0;10,0,0;0,0,10;-20,20,0;0,3,0; + ]; +% 妞渾缂 +% fellip=[320,210,10;10,2,0;0,0,2;0,0,8;0,0,5; +% 280,300,10;10,2,0;0,0,2;0,0,10;0,0,4;]; +% 300,205,10;10,0,0;0,0,2;0,0,10;0,0,5]; +fellip=[]; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +frac_information = fractureInformation_input_engineering_vector(f,fellip); +end +%% 杈撳叆鏂瑰紡3锛氫簩缁磋緭鍏 +% load('fractures_generated.mat'); +% fractureLines = fractures_generated; +if input_style==3 +fractureLines = [ + 105,150;105,350; + 205,150;205,350; + 305,150;305,350; + 405,150;405,350; + 505,150;505,350; + 605,150;605,350; + 705,150;705,350; + 805,150;805,350; + 905,150;905,350; + ]; +fellip=[]; % 妞渾缂 +fractureHeights = [ + 10;10;10;10;10;10;10;10;10]; +% 妞渾缂 +fellip=[]; +flowBarrierFlags = [];% flowBarrierFlags = [1;2;3;4]; +[f,frac_information] = input_fracture_2D(fractureLines,fractureHeights,flowBarrierFlags); +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +end +%% 杈撳叆鏂瑰紡4锛氫粠.fab鏂囦欢璇诲彇 Frac_PT +if input_style==4 + +end + +%% ==================================PART 4: 鍩鸿川缃戞牸鍙婅缂濈墿鎬у弬鏁拌緭鍏===================================== +% 1-- 鍗曢噸浠嬭川 +% 2-- 鍙岄噸浠嬭川锛堝弻瀛斿弻娓楋級 +grid_model = 1; +if grid_model == 1 +r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf); +end +if grid_model == 2 +r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf); +end + +%% 鐢熸垚鍚戦噺鍖栧彉鎴愭墍闇瑕佺殑绠楀瓙 +os = OperatorRS(r.N, r.nex, r.nc); + +%% ==================================PART 5: 妯″瀷绫诲瀷閫夊彇鍙婂垵濮嬬姸鎬佽瀹========================================= +% 1-- 姘旀按涓ょ浉娴 +% 2-- 娌规按涓ょ浉娴 +flow_model = 2; +if flow_model == 1 +[f,state0] = gas_water_flow(r); +end +if flow_model == 2 +[f,state0] = oil_water_flow(r); +end +if flow_model == 3 +[f,state0] = multi_component_flow(r); +end + +%% ==================================PART 6: 浜曞埗搴chedule璁惧畾================================================ +%灏嗙洿浜曘佹按骞充簳涓庡娈靛帇瑁傛按骞充簳鍒嗗紑澶勭悊 +%% 鐩翠簳銆佸父瑙勬按骞充簳瀹氫箟 +% Wellcpara: wellname(1) nperf锛屽皠瀛旂偣鏁伴噺(2) index(3) rw(4) skin(5) welltype(6) +% welltype=1 鐩翠簳锛寃elltype=2 姘村钩浜曟部x鏂瑰悜锛寃elltype=3 姘村钩浜曟部y鏂瑰悜 welltype=4 澶氭鍘嬭姘村钩浜 +% 鐩翠簳銆佹按骞充簳锛岃绉嶄簳鍨嬬殑澶勭悊鏄皢灏勫瓟娈靛畨鎺掑湪鍩鸿川缃戞牸 +% 瀵逛簬鐩翠簳銆佹枩浜曘佹按骞充簳锛岄噰鍙栦笌eclipse涓鑷寸殑鏂瑰紡锛岀粰鍑哄叾鍦ㄥ熀璐ㄧ綉鏍间腑浣嶇疆 +% 姣忎釜灏勫瓟鐐圭敱涓媝x,py,pz纭畾锛屽垎鍒〃绀鸿灏勫瓟鐐瑰湪x鏂瑰悜锛寉鏂瑰悜鐨勭綉鏍肩紪鍙凤紝鍙婂眰鏁板嵆z鍙嶆柟鍚戜笂鐨勭綉鏍肩紪鍙凤紙鏈鍒濇槸浠ュ瀭鐩村悜涓婂缓绔嬬殑鍩鸿川缃戞牸锛 +well1={ + 'w1', 2, [20 10 1;20 10 2;], 0.178/2, 0, 1; + 'w2', 2, [80 10 1;80 10 2;], 0.178/2, 0, 1; + 'w3', 1, [20 40 1;], 0.178/2, 0, 1; + 'w4', 1, [80 40 1;], 0.178/2, 0, 1; + }; +well1 = handle_well1(well1,r); +%% 鍘嬭姘村钩浜曞畾涔 +% 澶氭鍘嬭姘村钩浜曪細灏勫瓟娈佃缃湪瑁傜紳鍗曞厓涓婏紝鍙互缁欏嚭璇ュ皠瀛旂偣鎵鍦ㄧ殑鍧愭爣锛岀劧鍚庡幓瀵绘壘璇ョ偣鎵鍦ㄧ殑瑁傜紳鍗曞厓缂栧彿 +num_fracture_wells = 1; +welloc = cell(num_fracture_wells,1); +perfnum = cell(num_fracture_wells,1); +welloc{1,1}=[ + 255,255,5; + 305,255,5; + 355,255,5; + 405,255,5; + 455,255,5; + 505,255,5; + 555,255,15; + 605,255,15; + 655,255,15; + 705,255,15; + 755,255,15; + ]; +for i = 1:num_fracture_wells +perfnum{i,1} = findWelloc(r, welloc{i,1});%鍦ㄧ敤浠ellc0涔嬩腑 +end +% perfnum2 = findWelloc(r, welloc2); +well2={ + 'w1', length(perfnum{1,1}), perfnum{1,1}, 0.178/2, 0,4; + }; +Wellc = handle_well1_well2(well1,well2,welloc,r); %鍔犱簳鍜屽皠瀛斾綅缃 +%% 浜曞埗搴﹁缃紙寮鍏充簳銆佸畾鍘/瀹氫骇銆佷究浜庡悶鍚愮瓑锛 +number_phases = 1; +well_schedules = cell(number_phases,1); +time = zeros(number_phases,1); +% 涓嶅悓鏂瑰紡瀵瑰簲鐨勬敹鏁涢毦搴︺侀渶瑕佷笉涓鏍凤紝闇鍒嗛樁娈佃皟鎺э紝 +% 渚嬪鍦ㄦ敞鍏ラ樁娈甸渶瑕佸皬涓浜涳紝濡傛灉闇瑕佸仛鏃╂湡璇曚簳锛宒tmax銆乨tmin閮介渶瑕佸皬涓浜 +dtmax = zeros(number_phases,1); +dtmin = zeros(number_phases,1); + +% (1)well state: 'open'琛ㄧず璇ヤ簳鏄紑鐨勶紱'close'琛ㄦ槑璇ヤ簳涓鐩存槸鍏崇殑锛屽鏋滃彧鏄樁娈垫у叧浜曪紝灏辩敤'open'瀹氭祦閲0鐢熶骇 +% (2)well type: 'pro'琛ㄧず鏄敓浜т簳锛'inj'琛ㄧず鏄敞鍏ヤ簳; +% (3)protype锛'const_q'鏄畾娴侀噺锛'const_pwf'鍒欐槸瀹氬帇 +% (4)value锛氬畾鐨勬祦閲忓兼垨鑰呬簳搴曞帇鍔涘 +% (5)value锛氭浠g爜璇ュ间笌锛3锛夊肩浉鍚 +time(1) = 200; dtmax(1) = 2; dtmin(1) = 0.001; +well_schedules{1,1} = { + 'w1','open','inj','const_pwf',35,35; + 'w2','open','inj','const_pwf',35,35; + 'w3','open','inj','const_pwf',35,35; + 'w4','open','inj','const_pwf',35,35; + 'w5','open','pro','const_pwf',10,10; + % 'w2','open','pro','const_pwf',10,10; + }; + +%% ======================================PART 7: Solver璁剧疆=========================================== +yitap = 5; % 50-500psi +yitas = 0.04; % 0.05-0.5 +omega = 0.5; % 0-1 +Nmax = 50; +epsave = 1e-6; +epsmax = 1e-6; +% dtmin = 0.001; +% dtmax = 10; +% dtmin = 0.000001; +% dtmax = 0.0001; +%% ======================================PART 8: 姝e紡璁$畻=========================================== +[Times, OutputRs, Wellpara, trun] = solver_NR(r, flow_model, f, os, state0, yitap,yitas,omega,Nmax,epsave,epsmax,dtmin,dtmax,Wellc,time,well_schedules); +run_time=toc; +trun.run_time=run_time; +end \ No newline at end of file diff --git a/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/oil_water_flow.m b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/oil_water_flow.m new file mode 100644 index 0000000..2b37ab7 --- /dev/null +++ b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/oil_water_flow.m @@ -0,0 +1,126 @@ +function [f,state0] = oil_water_flow(r) +% =======================娌圭浉浣撶Н瀵嗗害銆佷綋绉郴鏁般佺矘搴︾瓑=============================== +density_o_sc = 800; % kg/m3 +% 绗竴绉嶆ā寮忥紝鐩存帴杈撳叆鍙傝冨帇鍔涖佷綋绉郴鏁般佸帇缂╃郴鏁般佺矘搴 +oil_model =1; +if oil_model == 1 +pro = 30; % reference pressure, MPa +Boi = 1.1; % gas phase volume factor +co = 1e-3 ;% gas phase compressibility, 1/MPa +voi = 10; % gas viscosity, cp +cvo = 0; % 姘旂浉绮樺害闅忓帇鍔涘彉鍖栫殑绾挎х郴鏁帮紝cp/MPa +[Ppr,BO,MUO] = cal_oil_prop(pro,Boi,co,voi,cvo); +end +if oil_model == 2 +Ppr = [ 0.1013 + 2.0946 + 4.0878 + 6.0811 + 8.0743 + 10.0676 + 12.0608 + 14.0540 + 16.0473 + 18.0405 + 20.0338 + 22.0270 + 24.0203 + 26.0135 + 28.0068 + 30.0000 + ]; +% BO = 0.01*ones(size(Ppr,1),1); +BO = [ 1.18297 + 0.0557041 + 0.0278168 + 0.0182594 + 0.0134665 + 0.0106154 + 0.00874829 + 0.00744907 + 0.00650639 + 0.0058006 + 0.0052587 + 0.0048336 + 0.00449378 + 0.00421751 + 0.0039895 + 0.00379871 + ]; +% MUG = 0.01*ones(size(Ppr,1),1); +MUO = [0.0127683 + 0.0130191 + 0.0133973 + 0.013872 + 0.014437 + 0.015088 + 0.0158182 + 0.0166173 + 0.0174719 + 0.0183671 + 0.0192882 + 0.0202219 + 0.0211575 + 0.0220865 + 0.0230024 + 0.0239008 + ]; +end +% ========================姘寸浉浣撶Н绯绘暟銆佺矘搴=============================== +density_w_sc = 1000; % kg/m3 +prw = 30; % reference pressure, MPa +Bwi = 1.000; % water phase volume factor, 鏃犲洜娆 +cw = 4.0e-4 ;% water phase compressibility, 1/MPa +vwi = 1; % water viscosity, cp +cvw = 0; % 姘寸浉绮樺害闅忓帇鍔涘彉鍖栫殑绾挎х郴鏁帮紝cp/MPa +% =============================鍩鸿川鐩告笚=============================== +ifpcow = 0; % 鏄惁鑰冭檻姣涚鍔 +PRM=[ + 0.0000 0.0000 1.0000 3.8916 +0.2000 0.0000 1.0000 3.8916 +0.3160 0.0002 0.6784 0.5796 +0.4350 0.0004 0.6215 0.3724 +0.5620 0.0010 0.5456 0.2425 +0.6140 0.0020 0.3939 0.0608 +0.7020 0.0280 0.1399 0.0372 +0.8120 0.1721 0.0515 0.0137 +0.8750 0.3395 0.0297 0.0104 +0.9060 0.4395 0.0 0.0090 +1.0 0.4395 0.0 0.0090 +]; +SW=PRM(:,1);KRW=PRM(:,2);KRO=PRM(:,3);PCOW=PRM(:,4); + +% =============================瑁傜紳鐩告笚=============================== +PRF=[ +0.0000 0.0000 1.0000 3.8916 +0.2000 0.0000 1.0000 3.8916 +0.3160 0.0002 0.6784 0.5796 +0.4350 0.0004 0.6215 0.3724 +0.5620 0.0010 0.5456 0.2425 +0.6140 0.0020 0.3939 0.0608 +0.7020 0.0280 0.1399 0.0372 +0.8120 0.1721 0.0515 0.0137 +0.8750 0.3395 0.0297 0.0104 +0.9060 0.4395 0.0 0.0090 +1.0 0.4395 0.0 0.0090 +]; +SWF = PRF(:,1);KRWF = PRF(:,2);KROF = PRF(:,3);PCOWF=PRF(:,4); +%% +% ===================== 楂橀熼潪杈捐タ娴 Forchheimer 鏂圭▼ ==================== +beta_non_Darcy_flow = 0; % 1e-8 +% ===================== 鍚姩鍘嬪姏姊害 ==================== +p_grad_threshold = 0.00; % MPa/m +%% 缁撳悎娴佷綋鎬ц川鍙傛暟鐢熸垚鐩稿簲鐨勬暟鎹綋 +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, r.rpt); +f.beta_non_Darcy_flow = beta_non_Darcy_flow; +f.Dwsi = density_w_sc; +f.Dosi = density_o_sc; +f.p_grad_threshold = p_grad_threshold; +%% 鍒濆兼潯浠 Initial Condition Section +% =================鍘嬪姏銆侀ケ鍜屽害鍒濆======================================= % +%鍘嬪姏鍒濆艰鑰冭檻閲嶅姏锛岀粰鍑烘补钘忎笅琛ㄩ潰鍘嬪姏鍊 +P = [20 * ones(r.nmc, 1); 20 * ones(r.nfc, 1)]; +% plow=25; % P =plow-1e-6*800*9.8*r.z; +Sw = [0.2 * ones(r.nmc, 1); 0.2 * ones(r.nfc, 1)]; +state0 = initialRS_oil_water_flow(P, Sw); +end \ No newline at end of file diff --git a/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/plotWellResponse.m b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/plotWellResponse.m new file mode 100644 index 0000000..b3bcc97 --- /dev/null +++ b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/plotWellResponse.m @@ -0,0 +1,55 @@ +function [] = plotWellResponse(Times,Wellpara) +% 输入 +wellNumber = 1; % 井号 +dataType = 'dPWF'; % 类型,产气速度 GPR,产气速度 OPR, 产水速度 WPR,井底流压 BHP,压力导数 dPWF +% +t = Times; +n= size(Times,1); +% para = cell2mat(Wellpara); +nw = wellNumber;%选井号 +% n = length(para); +data = zeros(n,1); +if strcmp(dataType, 'GPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qg; + figureYlegend = 'Gas production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'OPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qo; + figureYlegend = 'Oil production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'WPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qw; + figureYlegend = 'Water production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'BHP') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.pwf; + figureYlegend = 'BHP, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'dPWF') % dpwf/dlnt = t*dpwf/dt + for i = 1 : n + if i == 1 + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i}{1,nw}.pwf)/(log(t(i+1))-log(t(i))); + elseif i == n + data(i) = (Wellpara{i}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i))-log(t(i-1))); + else + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i+1))-log(t(i-1))); + end + figureYlegend = 'Pressure derivative, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); + set(gca, 'XScale', 'log'); + set(gca, 'YScale', 'log'); +end +end \ No newline at end of file diff --git a/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/plot_2D_layer.m b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/plot_2D_layer.m new file mode 100644 index 0000000..0d45394 --- /dev/null +++ b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/plot_2D_layer.m @@ -0,0 +1,50 @@ +function plot_2D_layer(i, k, r, OutputRs, type) +coordinate=r.coordinates; +nodes=r.nodes; +nz=r.nz; +nx=r.nx; +ny=r.ny; +nmc = size(nodes,1); +% nel = size(nodes,2); +nel = 4; +if type == 1 +% v = r.kx; + v = OutputRs{i}.p; +else + v = 1-OutputRs{i}.sw;%含气饱和度 +end +dis = zeros(nel, nx*ny); +x = zeros(nel, nx*ny); +y = zeros(nel, nx*ny); +for i = 1 :nx*ny + for j = 1 :nel + grid_numbering = i+(nz-k)*nx*ny; + x(j, i) = coordinate(nodes(grid_numbering,j), 1); + y(j, i) = coordinate(nodes(grid_numbering,j), 2); + if j == 3 + x(j, i) = coordinate(nodes(grid_numbering,4), 1); + y(j, i) = coordinate(nodes(grid_numbering,4), 2); + end + if j == 4 + x(j, i) = coordinate(nodes(grid_numbering,3), 1); + y(j, i) = coordinate(nodes(grid_numbering,3), 2); + end + dis(j, i) = v(grid_numbering); + end +end +% fill(x,y,dis,'EdgeAlpha',1); +figure('color','w'); +fill(x,y,dis,'EdgeColor','interp'); +xlabel('x, m','FontSize',14); +ylabel('y, m','FontSize',14); +ax = gca; +ax.FontSize = 14; +axis equal; +axis tight +% xlim([0,60]); +% ylim([0,60]); +% clim([10,15]); +colorbar +colormap jet +% fill(x,y,dis); +% axis off diff --git a/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/plot_3D_dis.m b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/plot_3D_dis.m new file mode 100644 index 0000000..6674f45 --- /dev/null +++ b/绠椾緥6-娌规按涓ょ浉娴-鐩翠簳娉ㄥ帇瑁傛按骞充簳閲/plot_3D_dis.m @@ -0,0 +1,144 @@ +function plot_3D_dis(i, r,OutputRs, type) +%为便于作图进行前处理 +figure('color','w') +[ downgrid, frontgrid ,leftgrid, rightgrid, backgrid, upgrid ] = preplot_dis( r ); +coordinate=r.coordinates; +nodes=r.nodes; +% nmc = size(nodes,1);%基质网格数量 +% % nel = size(nodes,2);%每个基质网格所包含的点数量 +% order=[1,2,4,3,1,5,6,8,7,3,4,8,6,2,1];%用以fill函数作图 +% nel=size(order,2); +if type == 1 + v = OutputRs{i}.p; +elseif type == 2 + v = 1-OutputRs{i}.sw;%含油饱和度 +elseif type == 3 + v = OutputRs{i}.sg;%含油饱和度 +else + v = OutputRs{i}.sw;%含油饱和度 +end +% 底面 +order=[1,2,4,3,1]; +nel=size(order,2); +nmc=size(downgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(downgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(downgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(downgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(downgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +hold on + +%左面 +order=[1,5,7,3,1]; +nel=size(order,2); +nmc=size(leftgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(leftgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(leftgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(leftgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(leftgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%右面 +order=[2,4,8,6,2]; +nel=size(order,2); +nmc=size(rightgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(rightgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(rightgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(rightgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(rightgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%前面 +order=[1,2,6,5,1]; +nel=size(order,2); +nmc=size(frontgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(frontgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(frontgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(frontgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(frontgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%后面 +order=[3,4,8,7,3]; +nel=size(order,2); +nmc=size(backgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(backgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(backgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(backgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(backgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); + +%上面 +order=[5,6,8,7,5]; +nel=size(order,2); +nmc=size(upgrid,2); +dis = zeros(nel, nmc); +x = zeros(nel, nmc); +y = zeros(nel, nmc); +z = zeros(nel, nmc); +for i = 1 : nmc + for j = 1 : nel + x(j, i) = coordinate(nodes(upgrid(i),order(j)), 1); + y(j, i) = coordinate(nodes(upgrid(i),order(j)), 2); + z(j, i) = coordinate(nodes(upgrid(i),order(j)), 3)-max(coordinate(:,3))-2000; + dis(j, i) = v(upgrid(i)); + end +end +fill3(x,y,z,dis,'edgeColor','interp'); +set(gca,'FontName','Times New Roman','FontSize',10,'FontWeight','bold'); +xlabel('x, m'); +ylabel('y, m'); +zlabel('z, m'); +view(3); +% 绘制油藏框架 +% plotframe( r ); +alpha(1) +% caxis([0.2,0.8]); +caxis([10,13]); +% caxis([12,22]); +colormap jet +colorbar +% zlim([-2020,-2000]); +% axis equal +axis tight + diff --git a/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/grid_discretization_SP_model.m b/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/grid_discretization_SP_model.m new file mode 100644 index 0000000..fe08427 --- /dev/null +++ b/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/grid_discretization_SP_model.m @@ -0,0 +1,55 @@ +function r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf) +% 鏁版嵁璇诲彇 +nx = r.nx; ny = r.ny; nz = r.nz; NTG = r.NTG; cell_mid_coords = r.cell_mid_coords; +% 鍩鸿川瀛旀笚 +rock_density = 2700; % 宀╃煶瀵嗗害锛宬g/m^3 +kx = 5*1e-3 * ones(nx*ny*nz, 1); % 杈捐タ锛孌 +ky = 5*1e-3 * ones(nx*ny*nz, 1);% +kz = 5*1e-3 * ones(nx*ny*nz, 1);% +pori = 0.01 * ones(nx*ny*nz, 1);% +prpor = 20; % 鍙傝冨帇鍔涳紝MPa +cpor = 1.0e-5;% 鍩鸿川鍘嬬缉绯绘暟锛,MPa +% 鏈夋晥缃戞牸 +valid_grids = ones(nx*ny*nz, 1); +invalid_layer = []; % 灏嗙浜屽眰鏃犳晥缃戞牸 +for i = 1:length(invalid_layer) + grid_numbering_range = ((invalid_layer(i)-1)*nx*ny+1:invalid_layer(i)*nx*ny)'; + valid_grids(grid_numbering_range,1) = 0; +end +% SRV鍖哄煙瀹氫箟 +% % % base_x=23:78; nx_SRV=length(base_x); +% % % base_y=15:36; ny_SRV=length(base_y); +% % % base_z=1:1;nz_SRV=length(base_z); +% % % SRV=[]; +% % % for k=1:nz_SRV +% % % for j=1:ny_SRV +% % % for i=1:nx_SRV +% % % SRV=[SRV;(base_z(k)-1)*nx*ny+(base_y(j)-1)*nx+base_x(i)]; +% % % end +% % % end +% % % end +% % % % SRV娓楅忕巼璧嬪 +% % % kx(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % ky(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% % % kz(SRV)=0.001*1e-3 * ones(length(SRV), 1); +% 瑁傜紳瀛旀笚 +Kf = 10000*1e-3*ones(1,nf);% 瑁傜紳娓楅忕巼 +Wf = 1e-2*ones(1,nf);% 瑁傜紳寮搴 +Porf = 0.30*ones(1,nf);% 瑁傜紳瀛旈殭搴 +prporf = 20;% 瑁傜紳绯荤粺鍙傝冨帇鍔 +cporf = 1.0e-5;% 瑁傜紳绯荤粺鍘嬬缉绯绘暟 +% 搴斿姏鏁忔劅 +stress_factor_fracture = 0.000; % 1/MPa 0.001 +stress_factor_matrix = 0.000; % 1/MPa +stress_factor_ref_pressure = 20; % 涓鑸彇涓哄師濮嬪湴灞傚帇鍔汳Pa +% +Rpt = 2;cf = 1;ca = 1; +%% 缁撳悎鍩鸿川銆佽缂濈殑鍑犱綍鍙婄墿鎬т俊鎭紑灞曞墠澶勭悊 +% r = GridProp(modelflag, nx, ny, nz, dx, dy, dz, kx, ky, kz, f, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca,co, NTG); +r = GridProp_new(modelflag, r, kx, ky, kz, f, frac_information, fellip, Kf, Wf, pori, prpor, cpor, Porf, prporf, cporf, cf, ca, valid_grids); +r.rock_density = rock_density; +r.valid_grids = valid_grids; +r.stress_factor_fracture = stress_factor_fracture; +r.stress_factor_matrix = stress_factor_matrix; +r.stress_factor_ref_pressure = stress_factor_ref_pressure; +end \ No newline at end of file diff --git a/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/main1.m b/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/main1.m new file mode 100644 index 0000000..e13eafe --- /dev/null +++ b/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/main1.m @@ -0,0 +1,219 @@ +function [ r, Times, OutputRs, Wellpara, trun ] = main1() +%% ==================================PART 1: 妯″瀷閫夊彇======================================== +% 1-- classical EDFM +modelflag = 1;% 姝ゅ鍥哄畾涓1鍗冲彲 +%% ==================================PART 2: 鍩鸿川缃戞牸瀹氫箟===================================== +dx=[10*ones(1,100) ];nx=size(dx,2); +dy=[10*ones(1,50) ];ny=size(dy,2); +dz=[10*ones(1,1)];nz=size(dz,2); +NTG= 1*ones(nx*ny*nz,1); +r = GridProp_pre(dx,dy,dz,nx,ny,nz,NTG); +%% ==================================PART 3: 瑁傜紳鍒嗗竷鏁版嵁杈撳叆===================================== +% 鍥涚杈撳叆鏂瑰紡: 1琛ㄧず宸ョ▼搴旂敤杈撳叆锛2琛ㄧず鍚戦噺杈撳叆锛3琛ㄧず宸ョ▼搴旂敤杈撳叆锛屽寘鎷熀鍑嗙偣銆佸捐銆佹柟浣嶈銆佹姮鍗囪锛4琛ㄧず浠.fab鏂囦欢璇诲彇 +input_style = 1; +%% 杈撳叆鏂瑰紡1锛氬伐绋嬪簲鐢ㄨ緭鍏 +%浠呰兘鍒荤敾鍏锋湁鍙屽绉版ц川鐨勭煩褰㈢紳鎴栨き鍦嗙紳 +% 鍩哄噯鐐瑰潗鏍囷紙1锛夛紝鏂逛綅瑙掞紙2锛夛紝鍊捐锛3锛夛紝鎶崌瑙掞紙4锛夛紝缂濋暱锛堟き鍦嗛暱杞撮暱锛夛紙5锛夛紝缂濋珮锛堟き鍦嗙煭杞撮暱锛夛紙6锛夛紝绫诲瀷1鏄煩褰㈢紳銆2鏄き鍦嗙紳锛7锛 +if input_style==1 +input_content={ + [255,255,5],90,90,0,200,10,1; + [355,255,5],90,90,0,200,10,1; + [455,255,5],90,90,0,200,10,1; + [555,255,5],90,90,0,200,10,1; + [655,255,5],90,90,0,200,10,1; + [755,255,5],90,90,0,200,10,1; + }; +[f,fellip] = sort_fracture(input_content); +flowBarrierFlags = []; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5; +frac_information = fractureInformation_input_engineering_vector(f,fellip,flowBarrierFlags); +end +%% 杈撳叆鏂瑰紡2锛氬悜閲忚緭鍏 +%棣栧厛瀵圭煩褰㈢紳杩涜鐮旂┒锛岃缂濆弬鏁板寘鎷笁涓悜閲忓拰涓や釜鍙傛暟鐨勫彇鍊艰寖鍥达紝濡傛灉鏄叾瀹冪被鍨嬬紳锛屽垯鏄袱涓弬鏁伴棿鐨勫嚱鏁板叧绯 +%鍥犳涓涓5琛屼笁鍒楃殑鐭╅樀鍙互纭畾涓鏉¤缂 +%鍚戦噺鍒嗛噺鍙负闈炴暣鏁帮紝浠ユ淇濊瘉鍙傛暟鑼冨洿鐨勫彇鍊间负鏁存暟鍗冲彲锛 +%鏁呭彲鍏堥殢鎰忕‘瀹氫负鏁存暟鐨勫弬鏁拌寖鍥达紝鍐嶆牴鎹紳闀跨紳楂樺幓纭畾鍚戦噺鍒嗛噺鐨勫彇鍊 +% 鐭╁舰缂 +if input_style==2 + f=[ + 0,1200,0;10,-20,0;0,0,10;0,60,0;0,3,0; + 0,1200,0;10,20,0;0,0,10;0,15,0;0,3,0; + 150,1500,0;20,-10,0;0,0,10;0,20,0;0,3,0; + 550,1300,0;10,10,0;0,0,10;0,10,0;0,3,0; + 650,1400,0;10,-20,0;0,0,10;0,55,0;0,3,0; + 605,705,0;10,0,0;0,0,10;-20,20,0;0,3,0; + ]; +% 妞渾缂 +% fellip=[320,210,10;10,2,0;0,0,2;0,0,8;0,0,5; +% 280,300,10;10,2,0;0,0,2;0,0,10;0,0,4;]; +% 300,205,10;10,0,0;0,0,2;0,0,10;0,0,5]; +fellip=[]; +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +frac_information = fractureInformation_input_engineering_vector(f,fellip); +end +%% 杈撳叆鏂瑰紡3锛氫簩缁磋緭鍏 +% load('fractures_generated.mat'); +% fractureLines = fractures_generated; +if input_style==3 +fractureLines = [ + 105,150;105,350; + 205,150;205,350; + 305,150;305,350; + 405,150;405,350; + 505,150;505,350; + 605,150;605,350; + 705,150;705,350; + 805,150;805,350; + 905,150;905,350; + ]; +fellip=[]; % 妞渾缂 +fractureHeights = [ + 10;10;10;10;10;10;10;10;10]; +% 妞渾缂 +fellip=[]; +flowBarrierFlags = [];% flowBarrierFlags = [1;2;3;4]; +[f,frac_information] = input_fracture_2D(fractureLines,fractureHeights,flowBarrierFlags); +m=size(f,1);n=size(fellip,1);nf=(m+n)/5;%瑁傜紳鏉℃暟 +end +%% 杈撳叆鏂瑰紡4锛氫粠.fab鏂囦欢璇诲彇 Frac_PT +if input_style==4 + +end + +%% ==================================PART 4: 鍩鸿川缃戞牸鍙婅缂濈墿鎬у弬鏁拌緭鍏===================================== +% 1-- 鍗曢噸浠嬭川 +% 2-- 鍙岄噸浠嬭川锛堝弻瀛斿弻娓楋級 +grid_model = 1; +if grid_model == 1 +r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf); +end +if grid_model == 2 +r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf); +end + +%% 鐢熸垚鍚戦噺鍖栧彉鎴愭墍闇瑕佺殑绠楀瓙 +os = OperatorRS(r.N, r.nex, r.nc); + +%% ==================================PART 5: 妯″瀷绫诲瀷閫夊彇鍙婂垵濮嬬姸鎬佽瀹========================================= +% 1-- 姘旀按涓ょ浉娴 +% 2-- 娌规按涓ょ浉娴 +flow_model = 2; +if flow_model == 1 +[f,state0] = gas_water_flow(r); +end +if flow_model == 2 +[f,state0] = oil_water_flow(r); +end +if flow_model == 3 +[f,state0] = multi_component_flow(r); +end + +%% ==================================PART 6: 浜曞埗搴chedule璁惧畾================================================ +%灏嗙洿浜曘佹按骞充簳涓庡娈靛帇瑁傛按骞充簳鍒嗗紑澶勭悊 +%% 鐩翠簳銆佸父瑙勬按骞充簳瀹氫箟 +% Wellcpara: wellname(1) nperf锛屽皠瀛旂偣鏁伴噺(2) index(3) rw(4) skin(5) welltype(6) +% welltype=1 鐩翠簳锛寃elltype=2 姘村钩浜曟部x鏂瑰悜锛寃elltype=3 姘村钩浜曟部y鏂瑰悜 welltype=4 澶氭鍘嬭姘村钩浜 +% 鐩翠簳銆佹按骞充簳锛岃绉嶄簳鍨嬬殑澶勭悊鏄皢灏勫瓟娈靛畨鎺掑湪鍩鸿川缃戞牸 +% 瀵逛簬鐩翠簳銆佹枩浜曘佹按骞充簳锛岄噰鍙栦笌eclipse涓鑷寸殑鏂瑰紡锛岀粰鍑哄叾鍦ㄥ熀璐ㄧ綉鏍间腑浣嶇疆 +% 姣忎釜灏勫瓟鐐圭敱涓媝x,py,pz纭畾锛屽垎鍒〃绀鸿灏勫瓟鐐瑰湪x鏂瑰悜锛寉鏂瑰悜鐨勭綉鏍肩紪鍙凤紝鍙婂眰鏁板嵆z鍙嶆柟鍚戜笂鐨勭綉鏍肩紪鍙凤紙鏈鍒濇槸浠ュ瀭鐩村悜涓婂缓绔嬬殑鍩鸿川缃戞牸锛 +well1={ + % 'w1', 2, [20 10 1;20 10 2;], 0.178/2, 0, 1; + % 'w2', 2, [80 10 1;80 10 2;], 0.178/2, 0, 1; + % 'w3', 1, [20 40 1;], 0.178/2, 0, 1; + % 'w4', 1, [80 40 1;], 0.178/2, 0, 1; +% 'w2', 3, [67 20 1;67 20 2;67 20 3], 0.178/2, 0, 1; + }; +well1 = handle_well1(well1,r); +%% 鍘嬭姘村钩浜曞畾涔 +% 澶氭鍘嬭姘村钩浜曪細灏勫瓟娈佃缃湪瑁傜紳鍗曞厓涓婏紝鍙互缁欏嚭璇ュ皠瀛旂偣鎵鍦ㄧ殑鍧愭爣锛岀劧鍚庡幓瀵绘壘璇ョ偣鎵鍦ㄧ殑瑁傜紳鍗曞厓缂栧彿 +num_fracture_wells = 6; +welloc = cell(num_fracture_wells,1); +perfnum = cell(num_fracture_wells,1); +welloc{1,1}=[ + 255,255,5;]; +welloc{2,1}=[ + 355,255,5;]; +welloc{3,1}=[ + 455,255,5;]; +welloc{4,1}=[ + 555,255,5;]; +welloc{5,1}=[ + 655,255,5;]; +welloc{6,1}=[ + 755,255,5;]; +for i = 1:num_fracture_wells +perfnum{i,1} = findWelloc(r, welloc{i,1});%鍦ㄧ敤浠ellc0涔嬩腑 +end +% perfnum2 = findWelloc(r, welloc2); +well2={ + 'w1_f1', length(perfnum{1,1}), perfnum{1,1}, 0.178/2, 0,4; + 'w1_f2', length(perfnum{2,1}), perfnum{2,1}, 0.178/2, 0,4; + 'w1_f3', length(perfnum{3,1}), perfnum{3,1}, 0.178/2, 0,4; + 'w1_f4', length(perfnum{4,1}), perfnum{4,1}, 0.178/2, 0,4; + 'w1_f5', length(perfnum{5,1}), perfnum{5,1}, 0.178/2, 0,4; + 'w1_f6', length(perfnum{6,1}), perfnum{6,1}, 0.178/2, 0,4; + }; +Wellc = handle_well1_well2(well1,well2,welloc,r); %鍔犱簳鍜屽皠瀛斾綅缃 +%% 浜曞埗搴﹁缃紙寮鍏充簳銆佸畾鍘/瀹氫骇銆佷究浜庡悶鍚愮瓑锛 +number_phases = 4; +well_schedules = cell(number_phases,1); +time = zeros(number_phases,1); +% 涓嶅悓鏂瑰紡瀵瑰簲鐨勬敹鏁涢毦搴︺侀渶瑕佷笉涓鏍凤紝闇鍒嗛樁娈佃皟鎺э紝 +% 渚嬪鍦ㄦ敞鍏ラ樁娈甸渶瑕佸皬涓浜涳紝濡傛灉闇瑕佸仛鏃╂湡璇曚簳锛宒tmax銆乨tmin閮介渶瑕佸皬涓浜 +dtmax = zeros(number_phases,1); +dtmin = zeros(number_phases,1); + +% (1)well state: 'open'琛ㄧず璇ヤ簳鏄紑鐨勶紱'close'琛ㄦ槑璇ヤ簳涓鐩存槸鍏崇殑锛屽鏋滃彧鏄樁娈垫у叧浜曪紝灏辩敤'open'瀹氭祦閲0鐢熶骇 +% (2)well type: 'pro'琛ㄧず鏄敓浜т簳锛'inj'琛ㄧず鏄敞鍏ヤ簳; +% (3)protype锛'const_q'鏄畾娴侀噺锛'const_pwf'鍒欐槸瀹氬帇 +% (4)value锛氬畾鐨勬祦閲忓兼垨鑰呬簳搴曞帇鍔涘 +% (5)value锛氭浠g爜璇ュ间笌锛3锛夊肩浉鍚 +time(1) = 10; dtmax(1) = 0.5; dtmin(1) = 0.001; +well_schedules{1,1} = { + 'w1_f1','open','inj','const_pwf',40,40; + 'w1_f2','open','inj','const_pwf',40,40; + 'w1_f3','open','inj','const_pwf',40,40; + 'w1_f4','open','inj','const_pwf',40,40; + 'w1_f5','open','inj','const_pwf',40,40; + 'w1_f6','open','inj','const_pwf',40,40; + }; +time(2) = 10; dtmax(2) = 0.5; dtmin(2) = 0.001; +well_schedules{2,1} = { + 'w1_f1','open','pro','const_q',0,0; + 'w1_f2','open','inj','const_pwf',40,40; + 'w1_f3','open','pro','const_q',0,0; + 'w1_f4','open','inj','const_pwf',40,40; + 'w1_f5','open','pro','const_q',0,0; + 'w1_f6','open','inj','const_pwf',40,40; + }; +time(3) = 10; dtmax(3) = 0.5; dtmin(3) = 0.001; +well_schedules{3,1} = { + 'w1_f1','open','pro','const_pwf',10,10; + 'w1_f2','open','pro','const_q',0,0; + 'w1_f3','open','pro','const_pwf',10,10; + 'w1_f4','open','pro','const_q',0,0; + 'w1_f5','open','pro','const_pwf',10,10; + 'w1_f6','open','pro','const_q',0,0; + }; +time(4) = 200; dtmax(4) = 1; dtmin(4) = 0.001; +well_schedules{4,1} = { + 'w1_f1','open','pro','const_pwf',10,10; + 'w1_f2','open','pro','const_pwf',10,10; + 'w1_f3','open','pro','const_pwf',10,10; + 'w1_f4','open','pro','const_pwf',10,10; + 'w1_f5','open','pro','const_pwf',10,10; + 'w1_f6','open','pro','const_pwf',10,10; + }; + +%% ======================================PART 7: Solver璁剧疆=========================================== +yitap = 5; % 50-500psi +yitas = 0.04; % 0.05-0.5 +omega = 0.5; % 0-1 +Nmax = 50; +epsave = 1e-6; +epsmax = 1e-6; +%% ======================================PART 8: 姝e紡璁$畻=========================================== +[Times, OutputRs, Wellpara, trun] = solver_NR(r, flow_model, f, os, state0, yitap,yitas,omega,Nmax,epsave,epsmax,dtmin,dtmax,Wellc,time,well_schedules); +run_time=toc; +trun.run_time=run_time; +end \ No newline at end of file diff --git a/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/oil_water_flow.m b/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/oil_water_flow.m new file mode 100644 index 0000000..2b37ab7 --- /dev/null +++ b/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/oil_water_flow.m @@ -0,0 +1,126 @@ +function [f,state0] = oil_water_flow(r) +% =======================娌圭浉浣撶Н瀵嗗害銆佷綋绉郴鏁般佺矘搴︾瓑=============================== +density_o_sc = 800; % kg/m3 +% 绗竴绉嶆ā寮忥紝鐩存帴杈撳叆鍙傝冨帇鍔涖佷綋绉郴鏁般佸帇缂╃郴鏁般佺矘搴 +oil_model =1; +if oil_model == 1 +pro = 30; % reference pressure, MPa +Boi = 1.1; % gas phase volume factor +co = 1e-3 ;% gas phase compressibility, 1/MPa +voi = 10; % gas viscosity, cp +cvo = 0; % 姘旂浉绮樺害闅忓帇鍔涘彉鍖栫殑绾挎х郴鏁帮紝cp/MPa +[Ppr,BO,MUO] = cal_oil_prop(pro,Boi,co,voi,cvo); +end +if oil_model == 2 +Ppr = [ 0.1013 + 2.0946 + 4.0878 + 6.0811 + 8.0743 + 10.0676 + 12.0608 + 14.0540 + 16.0473 + 18.0405 + 20.0338 + 22.0270 + 24.0203 + 26.0135 + 28.0068 + 30.0000 + ]; +% BO = 0.01*ones(size(Ppr,1),1); +BO = [ 1.18297 + 0.0557041 + 0.0278168 + 0.0182594 + 0.0134665 + 0.0106154 + 0.00874829 + 0.00744907 + 0.00650639 + 0.0058006 + 0.0052587 + 0.0048336 + 0.00449378 + 0.00421751 + 0.0039895 + 0.00379871 + ]; +% MUG = 0.01*ones(size(Ppr,1),1); +MUO = [0.0127683 + 0.0130191 + 0.0133973 + 0.013872 + 0.014437 + 0.015088 + 0.0158182 + 0.0166173 + 0.0174719 + 0.0183671 + 0.0192882 + 0.0202219 + 0.0211575 + 0.0220865 + 0.0230024 + 0.0239008 + ]; +end +% ========================姘寸浉浣撶Н绯绘暟銆佺矘搴=============================== +density_w_sc = 1000; % kg/m3 +prw = 30; % reference pressure, MPa +Bwi = 1.000; % water phase volume factor, 鏃犲洜娆 +cw = 4.0e-4 ;% water phase compressibility, 1/MPa +vwi = 1; % water viscosity, cp +cvw = 0; % 姘寸浉绮樺害闅忓帇鍔涘彉鍖栫殑绾挎х郴鏁帮紝cp/MPa +% =============================鍩鸿川鐩告笚=============================== +ifpcow = 0; % 鏄惁鑰冭檻姣涚鍔 +PRM=[ + 0.0000 0.0000 1.0000 3.8916 +0.2000 0.0000 1.0000 3.8916 +0.3160 0.0002 0.6784 0.5796 +0.4350 0.0004 0.6215 0.3724 +0.5620 0.0010 0.5456 0.2425 +0.6140 0.0020 0.3939 0.0608 +0.7020 0.0280 0.1399 0.0372 +0.8120 0.1721 0.0515 0.0137 +0.8750 0.3395 0.0297 0.0104 +0.9060 0.4395 0.0 0.0090 +1.0 0.4395 0.0 0.0090 +]; +SW=PRM(:,1);KRW=PRM(:,2);KRO=PRM(:,3);PCOW=PRM(:,4); + +% =============================瑁傜紳鐩告笚=============================== +PRF=[ +0.0000 0.0000 1.0000 3.8916 +0.2000 0.0000 1.0000 3.8916 +0.3160 0.0002 0.6784 0.5796 +0.4350 0.0004 0.6215 0.3724 +0.5620 0.0010 0.5456 0.2425 +0.6140 0.0020 0.3939 0.0608 +0.7020 0.0280 0.1399 0.0372 +0.8120 0.1721 0.0515 0.0137 +0.8750 0.3395 0.0297 0.0104 +0.9060 0.4395 0.0 0.0090 +1.0 0.4395 0.0 0.0090 +]; +SWF = PRF(:,1);KRWF = PRF(:,2);KROF = PRF(:,3);PCOWF=PRF(:,4); +%% +% ===================== 楂橀熼潪杈捐タ娴 Forchheimer 鏂圭▼ ==================== +beta_non_Darcy_flow = 0; % 1e-8 +% ===================== 鍚姩鍘嬪姏姊害 ==================== +p_grad_threshold = 0.00; % MPa/m +%% 缁撳悎娴佷綋鎬ц川鍙傛暟鐢熸垚鐩稿簲鐨勬暟鎹綋 +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, r.rpt); +f.beta_non_Darcy_flow = beta_non_Darcy_flow; +f.Dwsi = density_w_sc; +f.Dosi = density_o_sc; +f.p_grad_threshold = p_grad_threshold; +%% 鍒濆兼潯浠 Initial Condition Section +% =================鍘嬪姏銆侀ケ鍜屽害鍒濆======================================= % +%鍘嬪姏鍒濆艰鑰冭檻閲嶅姏锛岀粰鍑烘补钘忎笅琛ㄩ潰鍘嬪姏鍊 +P = [20 * ones(r.nmc, 1); 20 * ones(r.nfc, 1)]; +% plow=25; % P =plow-1e-6*800*9.8*r.z; +Sw = [0.2 * ones(r.nmc, 1); 0.2 * ones(r.nfc, 1)]; +state0 = initialRS_oil_water_flow(P, Sw); +end \ No newline at end of file diff --git a/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/plotWellResponse.m b/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/plotWellResponse.m new file mode 100644 index 0000000..fcd76ee --- /dev/null +++ b/绠椾緥7-娌规按涓ょ浉娴-涓嶅悓瑁傜紳鍒跺害涓嶅悓/plotWellResponse.m @@ -0,0 +1,55 @@ +function [] = plotWellResponse(Times,Wellpara) +% 输入 +wellNumber = 1; % 井号 +dataType = 'OPR'; % 类型,产气速度 GPR,产气速度 OPR, 产水速度 WPR,井底流压 BHP,压力导数 dPWF +% +t = Times; +n= size(Times,1); +% para = cell2mat(Wellpara); +nw = wellNumber;%选井号 +% n = length(para); +data = zeros(n,1); +if strcmp(dataType, 'GPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qg; + figureYlegend = 'Gas production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'OPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qo; + figureYlegend = 'Oil production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'WPR') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.qw; + figureYlegend = 'Water production rate, m^3/d'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'BHP') + for i = 1 : n + data(i) = Wellpara{i}{1,nw}.pwf; + figureYlegend = 'BHP, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); +end +if strcmp(dataType, 'dPWF') % dpwf/dlnt = t*dpwf/dt + for i = 1 : n + if i == 1 + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i}{1,nw}.pwf)/(log(t(i+1))-log(t(i))); + elseif i == n + data(i) = (Wellpara{i}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i))-log(t(i-1))); + else + data(i) = (Wellpara{i+1}{1,nw}.pwf-Wellpara{i-1}{1,nw}.pwf)/(log(t(i+1))-log(t(i-1))); + end + figureYlegend = 'Pressure derivative, MPa'; + end + plot(t,data,'k^-');hold off; xlabel('Time, day');ylabel(figureYlegend); + set(gca, 'XScale', 'log'); + set(gca, 'YScale', 'log'); +end +end \ No newline at end of file