1 function [INC, J] = fv_two_phase_space(model, model_data, CU, NU_ind)
2 %
function INC = fv_two_phase_space(model, model_data, CU, NU_ind)
4 grid = model_data.grid;
6 if nargin <= 3 || isempty(NU_ind)
8 NU_ind{1} = (1:grid.nelements)
';
9 NU_ind{2} = (1:model_data.gn_edges)';
10 NU_ind{3} = (1:grid.nelements)
';
13 Slength = grid.nelements;
14 Ulength = model_data.gn_edges;
16 U = CU(Slength+1:Slength+Ulength);
17 P = CU(Slength+Ulength+1:end);
19 % model.diffusivity_ptr = @(glob, U, model) struct('K
', 1, 'epsilon
', 0);%model.two_phase.phi(glob, U, model);
20 % model.diffusivity_derivative_ptr = @(glob, U, model) struct('K
', 0, 'epsilon
', 0);%model.two_phase.phi_derivative(glob, U, model);
21 % model.laplacian_ptr = @(glob, U, model) -getfield(model.two_phase.Phi(glob, U, model), 'K
')';
22 % model.laplacian_derivative_ptr = @(glob, U, model) -getfield(model.two_phase.phi(glob, U, model),
'K');
24 model.diffusivity_ptr = @(glob, U, model) model.two_phase.phi(glob, U, model);
25 model.diffusivity_derivative_ptr = @(glob, U, model) model.two_phase.phi_derivative(glob, U, model);
26 model.laplacian_ptr = @(glob, U, descr) U;
27 model.laplacian_derivative_ptr = @(glob, U, descr) ones(length(U),1);
31 num_conv_flux_s = fv_num_conv_flux_waterflow_upwind(model, model_data, S, U, NU_ind{1}, NU_ind{2});
33 % homogeneous neumann boundaries...
34 num_conv_flux_s.G(isnan(num_conv_flux_s.G)) = 0;
38 tmppar.local_mass_matrix = @fv_local_mass_matrix_rect;
40 tmppar.evaluate_basis = @fv_evaluate_basis;
42 S_upper = grid.A(NU_ind{1}).*l2project(@(elemin, loc, grid) model.two_phase.upper_source(elemin, loc, grid), 2, model_data.grid, tmppar);
43 S_lower = grid.A(NU_ind{1}).*l2project(@(elemin, loc, grid) model.two_phase.lower_source(elemin, loc, grid), 2, model_data.grid, tmppar);
45 % S_lower = grid.A(NU_ind{1}) .* model.two_phase.lower_source([grid.CX(NU_ind{1}), grid.CY(NU_ind{1})], model);
47 INC = zeros(2*Slength+Ulength+1, 1);
50 [maxval, maxi] = max(S);
52 % disp([
'maximum value: ', num2str(maxval),
' maximum cell index: ', num2str(maxi)]);
53 diff_max = num_diff_flux_s.G(maxi, :);
55 disp(
'all values need to be positive:')
56 disp(num2str(num_diff_flux_s.G(maxi, :)));
59 % ELmax = grid.EL(maxi, :);
60 Umax = U(model_data.gEI(maxi,:))'.*(grid.NX(maxi,:) + grid.NY(maxi,:));
61 conv_max = num_conv_flux_s.G(maxi, :);
62 Uconv_neg = zeros(size(num_conv_flux_s.G(maxi,:)));
63 Uconv_pos = zeros(size(num_conv_flux_s.G(maxi,:)));
64 Uconv_neg(Umax < 0) = conv_max(Umax < 0);
65 fUk = model.two_phase.waterflow([], S(maxi), model);
66 Uconv_pos(Umax < 0) = - Umax(Umax < 0) .* fUk;
67 if any(Uconv_pos + Uconv_neg < 0)
68 disp('all values need to be positive:')
69 disp(num2str(Uconv_pos + Uconv_neg));
72 cmax = model.two_phase.injection_concentration(model);
73 source_contri = (fUk - cmax) * S_upper(maxi);
75 dodisp = source_contri < 0;
78 dodisp = source_contri > 0;
82 disp(['source contribution should be ', negpos, ': ', num2str(source_contri)]);
86 %sink_contri_196 = (S(196) - model.two_phase.waterflow([], S(196), model)) * S_lower(196);
87 % disp(['sink at entity 196 = ', num2str(sink_contri_196)]);
90 if sum(Uconv_pos + Uconv_neg) + source_contri ~= sum(conv_max) - cmax * S_upper(maxi)
91 % disp('convective flux differs!');
95 % disp(['f(S_k) = ', num2str(fUk), ' c = ', num2str(cmax)]);
97 INC(1:Slength) = grid.Ainv(NU_ind{1}, :) .* ...
98 ( sum(num_diff_flux_s.G(NU_ind{1},:), 2) ...
99 + sum(num_conv_flux_s.G(NU_ind{1},:), 2) ...
100 - model.two_phase.injection_concentration(model) .* S_upper ...
101 + S(NU_ind{1}) .* S_lower );
103 UKL = -num_diff_flux_u.G(NU_ind{2});
105 INC(Slength+1:Ulength+Slength) = UKL - U;
107 INC(Slength+Ulength+1:end-1) = sum(U(model_data.gEI).*(grid.NX+grid.NY), 2) ...
110 % INC(end) = sum(grid.A(NU_ind{3}, :) .* P);
122 n = 2*Slength+Ulength+1;
123 m = 2*Slength+Ulength;
125 sp11 = grid.Ainv(1).*sparse(s_diff_s.si, s_diff_s.sj, s_diff_s.svals, n, m);
126 sp121 = sparse(s_conv_s_u.si, s_conv_s_u.sj, s_conv_s_u.svals, n, m);
127 sp122 = sparse(s_conv_s_u.ui, s_conv_s_u.uj+Slength, s_conv_s_u.uvals, n, m);
128 sp12 = grid.Ainv(1).*(sp121+sp122);
131 sp13 = sparse(sli, sli, S_lower(sli) .* grid.Ainv(sli), n, m);
133 sp1 = sp11 + sp12 + sp13;
135 sp21 = sparse(u_diff_p_s.si+Slength, u_diff_p_s.sj, u_diff_p_s.svals, n, m);
136 sp22 = sparse(u_diff_p_s.pi+Slength, u_diff_p_s.pj+Slength+Ulength, u_diff_p_s.pvals, n, m);
139 sp3i = repmat(1:Slength, 1, 4)+Ulength+Slength;
140 sp3j = model_data.gEI(:)+Slength;
141 sp3vals = grid.NX+grid.NY;
142 sp3 = sparse(sp3i,sp3j,sp3vals, n, m);
144 % sp4 = sparse(2*Slength+Ulength+1*ones(1,Slength), Slength+Ulength+1:2*Slength+Ulength, grid.A(:), n, m);
145 sp4 = sparse(2*Slength+Ulength+1, Slength+Ulength+1, 1, n, m);
147 sp5 = sparse((1:Ulength)+Slength, (1:Ulength)+Slength, -1, n,m);
149 J = sp1 + sp2 + sp3 + sp4 + sp5;
function spm = fv_frechet_operators_diff_flux_pressure_gradient(model, model_data, P, S, NU_ind)
computes a jacobian of implicit non-linear convective contributions to time evolution matrices at a p...
function num_flux_mat = fv_num_diff_flux_gradient(model, model_data, U, NU_ind)
computes a numerical diffusive flux for a diffusion problem
function spm = fv_frechet_operators_conv_flux_waterflow_upwind(model, model_data, S, U, NU_ind)
computes a jacobian of implicit non-linear convective contributions to time evolution matrices at a p...
function spm = fv_frechet_operators_diff_implicit_gradient3(model, model_data, U, NU_ind)
computes a jacobian of implicit non-linear diffusion contributions to time evolution matrices at a po...
function res = cubequadrature(poldeg, func, varargin)
integration of function func over reference cube == unit cube. by Gaussian quadrature exactly integra...
function num_flux_mat = fv_num_diff_flux_pressure_gradient(model, model_data, P, S)
computes a numerical diffusive flux for a diffusion problem