rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
fv_two_phase_space.m
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)
3 
4  grid = model_data.grid;
5 
6  if nargin <= 3 || isempty(NU_ind)
7  NU_ind = cell(1,3);
8  NU_ind{1} = (1:grid.nelements)';
9  NU_ind{2} = (1:model_data.gn_edges)';
10  NU_ind{3} = (1:grid.nelements)';
11  end
12 
13  Slength = grid.nelements;
14  Ulength = model_data.gn_edges;
15  S = CU(1:Slength);
16  U = CU(Slength+1:Slength+Ulength);
17  P = CU(Slength+Ulength+1:end);
18 
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');
23 
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);
28 
29  num_diff_flux_s = fv_num_diff_flux_gradient(model, model_data, S, NU_ind{1});
30 
31  num_conv_flux_s = fv_num_conv_flux_waterflow_upwind(model, model_data, S, U, NU_ind{1}, NU_ind{2});
32 
33  % homogeneous neumann boundaries...
34  num_conv_flux_s.G(isnan(num_conv_flux_s.G)) = 0;
35 
36  num_diff_flux_u = fv_num_diff_flux_pressure_gradient(model, model_data, P, S, NU_ind{3}, NU_ind{1});
37 
38  tmppar.local_mass_matrix = @fv_local_mass_matrix_rect;
39  tmppar.element_quadrature = @cubequadrature;
40  tmppar.evaluate_basis = @fv_evaluate_basis;
41  tmppar.pdeg = 0;
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);
44 
45 % S_lower = grid.A(NU_ind{1}) .* model.two_phase.lower_source([grid.CX(NU_ind{1}), grid.CY(NU_ind{1})], model);
46 
47  INC = zeros(2*Slength+Ulength+1, 1);
48 
49  % find maximum index:
50  [maxval, maxi] = max(S);
51 
52 % disp(['maximum value: ', num2str(maxval), ' maximum cell index: ', num2str(maxi)]);
53  diff_max = num_diff_flux_s.G(maxi, :);
54  if any(diff_max < 0);
55  disp('all values need to be positive:')
56  disp(num2str(num_diff_flux_s.G(maxi, :)));
57  keyboard;
58  end
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));
70  keyboard;
71  end
72  cmax = model.two_phase.injection_concentration(model);
73  source_contri = (fUk - cmax) * S_upper(maxi);
74  if fUk > cmax
75  dodisp = source_contri < 0;
76  negpos = 'positive';
77  else
78  dodisp = source_contri > 0;
79  negpos = 'negative';
80  end
81  if dodisp
82  disp(['source contribution should be ', negpos, ': ', num2str(source_contri)]);
83  keyboard;
84  end
85 
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)]);
88 
89 
90  if sum(Uconv_pos + Uconv_neg) + source_contri ~= sum(conv_max) - cmax * S_upper(maxi)
91 % disp('convective flux differs!');
92 % keyboard;
93  end
94 
95 % disp(['f(S_k) = ', num2str(fUk), ' c = ', num2str(cmax)]);
96 
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 );
102 
103  UKL = -num_diff_flux_u.G(NU_ind{2});
104 
105  INC(Slength+1:Ulength+Slength) = UKL - U;
106 
107  INC(Slength+Ulength+1:end-1) = sum(U(model_data.gEI).*(grid.NX+grid.NY), 2) ...
108  - S_upper + S_lower;
109 
110 % INC(end) = sum(grid.A(NU_ind{3}, :) .* P);
111 
112  INC(end) = P(1);
113 
114  if nargout > 1
115 
116  s_diff_s = fv_frechet_operators_diff_implicit_gradient3(model, model_data, S, NU_ind{1});
117  s_conv_s_u = fv_frechet_operators_conv_flux_waterflow_upwind(model, model_data, S, U, NU_ind{1}, NU_ind{2});
118 
119  u_diff_p_s = fv_frechet_operators_diff_flux_pressure_gradient(model, model_data, P, S, NU_ind{3}, NU_ind{1});
120 
121 
122  n = 2*Slength+Ulength+1;
123  m = 2*Slength+Ulength;
124 
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);
129 
130  sli = find(S_lower);
131  sp13 = sparse(sli, sli, S_lower(sli) .* grid.Ainv(sli), n, m);
132 
133  sp1 = sp11 + sp12 + sp13;
134  %sp1 = 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);
137  sp2 = -(sp21+sp22);
138 
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);
143 
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);
146 
147  sp5 = sparse((1:Ulength)+Slength, (1:Ulength)+Slength, -1, n,m);
148 
149  J = sp1 + sp2 + sp3 + sp4 + sp5;
150  J(isnan(J)) = 0;
151  end
152 
153 end
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