2 model, model_data, S, U, NU_ind)
4 % model, model_data, S, U [,S_ind, U_ind])
5 % computes a jacobian of implicit non-linear convective contributions to time
6 % evolution matrices at a point
'(S,U)'.
14 if nargin < 5 || isempty(NU_ind)
17 if(size(NU_ind, 2) == 1)
21 if ~isfield(model, 'flux_quad_degree') || isempty(model.flux_quad_degree)
22 model.flux_quad_degree = 1;
26 if ~isempty(model_data)
27 grid = model_data.grid;
31 NU_ind_inv = setdiff(1:spm.sn, NU_ind);
32 NBI(NU_ind_inv, :) = 0;
36 dir_NB_ind = find(NBI == -1);
37 neu_NB_ind = (NBI == -2);
38 %real_dir_NB_ind = [find(grid.NBI > repmat((1:grid.nelements)',1,4)); find(grid.NBI < 0)];
39 NBIind = NBI(real_NB_ind);
40 INBind = INB(real_NB_ind);
41 NB_real_NB_ind = sub2ind(size(NBI),NBIind,INBind);
43 if ~isempty(dir_NB_ind)
44 error('Dirichlet boundaries not yet implemented');
49 jj = grid.NBI(real_NB_ind);
51 % Note: find(real_NB_ind) == sub2ind(size(grid.NBI),i,j));
55 spm.sj = [NU_ind, jj];
60 spm.uj = model_data.gEI(real_NB_ind);
62 Sn = repmat(S, 1, size(grid.ECX,2));
63 [elids, edgeids] = ind2sub(size(grid.VI),1:length(grid.VI(:)));
64 PP = edge_quad_points(grid,elids, edgeids, model.flux_quad_degree);
66 fs = model.two_phase.waterflow(PP,repmat(Sn(:), model.flux_quad_degree, 1)', model);
67 % matrix evaluating the flux by quadratures over all edges
68 FS = reshape(fs,size(grid.NBI));
69 FS_NB = nan * ones([grid.nelements,grid.nneigh]);
70 FS_NB(real_NB_ind) = FS(NB_real_NB_ind);
72 dfs = model.two_phase.waterflow_derivative(PP,repmat(Sn(:), model.flux_quad_degree, 1)', model);
73 % matrix evaluating the flux derivative by quadratures over all edges
74 DFS = reshape(dfs,size(grid.NBI));
75 DFS_NB = nan * ones([grid.nelements,grid.nneigh]);
76 DFS_NB(real_NB_ind) = DFS(NB_real_NB_ind);
78 UU = nan(size(model_data.gEI));
79 UU(model_data.gEI > 0) = U(model_data.gEI(model_data.gEI>0));
82 % evaluate flux matrix derivative (average over edges)
83 flux_derivative_mat.Vx = grid.NX .* UU;
84 flux_derivative_mat.Vy = grid.NY .* UU;
85 % produced fields: Vx, Vy
87 c_jl_u_deri = (flux_derivative_mat.Vx + flux_derivative_mat.Vy);
88 I_c_jl_u_deri_pos = c_jl_u_deri > 0;
89 I_c_jl_v_deri_neg = c_jl_u_deri <= 0;
90 G1 = zeros(size(grid.NBI)); % zero matrix
91 G1(I_c_jl_u_deri_pos) = ... %grid.EL(I_c_jl_u_deri_pos) .* ...
92 DFS(I_c_jl_u_deri_pos) .* ...
93 (flux_derivative_mat.Vx(I_c_jl_u_deri_pos) + flux_derivative_mat.Vy(I_c_jl_u_deri_pos));
97 G2 = zeros(size(grid.NBI)); % zero matrix
98 G2(I_c_jl_v_deri_neg) = ... % grid.EL(I_c_jl_v_deri_neg) .* ...
99 DFS_NB(I_c_jl_v_deri_neg) .* ...
100 (flux_derivative_mat.Vx(I_c_jl_v_deri_neg) + flux_derivative_mat.Vy(I_c_jl_v_deri_neg));
102 svals2 = G2(real_NB_ind);
104 spm.svals = [svals1(NU_ind)', svals2'];
106 G3 = zeros(size(grid.NBI)); % zero matrix
107 G3(I_c_jl_u_deri_pos) = FS(I_c_jl_u_deri_pos) .* (grid.NX(I_c_jl_u_deri_pos) + grid.NY(I_c_jl_u_deri_pos));
108 G3(I_c_jl_v_deri_neg) = FS_NB(I_c_jl_v_deri_neg) .* (grid.NX(I_c_jl_v_deri_neg) + grid.NY(I_c_jl_v_deri_neg));
112 spm.uvals = G3(real_NB_ind);
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...