init
This commit is contained in:
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
%}
|
||||
|
||||
|
||||
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
|
||||
|
||||
%--------------------------------------------------------------------------
|
||||
%--------------------------------------------------------------------------
|
||||
%--------------------------------------------------------------------------
|
||||
@@ -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));
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
function state = initialRS(P, Sw, Cs, Cb)
|
||||
state.p = P;
|
||||
state.sw = Sw;
|
||||
state.cs = Cs;
|
||||
state.cb = Cb;
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -0,0 +1,2 @@
|
||||
function h = interptable(X, Y, u)
|
||||
h = interp1(X, Y, u, 'linear', 'extrap');
|
||||
Reference in New Issue
Block a user