6 ret_vars = {
'saturation'};
7 arg_vars = {
'saturation',
'velocity'};
8 arg_vars_short = {
'S',
'U'};
12 function [INC, INCoff, J] = apply(
this, model, model_data, sim_data, NU_ind)
13 %
function INC = apply(
this, model, model_data, sim_data, NU_ind)
15 grid = model_data.grid;
20 if nargin <= 4 || isempty(NU_ind)
21 NU_ind = (1:length(S));
24 if ~isfield(sim_data, 'm')
25 sim_data.m = length(S) + length(U);
28 model.diffusivity_ptr = @(glob, U, model) model.two_phase.phi(glob, U, model);
29 model.diffusivity_derivative_ptr = @(glob, U, model) model.two_phase.phi_derivative(glob, U, model);
30 model.laplacian_ptr = @(glob, U, descr) U;
31 model.laplacian_derivative_ptr = @(glob, U, descr) ones(length(U),1);
35 num_conv_flux_s = fv_num_conv_flux_waterflow_upwind(model, model_data, S, U);
37 % homogeneous neumann boundaries...
38 num_conv_flux_s.G(isnan(num_conv_flux_s.G)) = 0;
42 [maxval, maxi] = max(S);
44 % disp(['maximum value: ', num2str(maxval), ' maximum cell index: ', num2str(maxi)]);
45 diff_max = num_diff_flux_s.G(maxi, :);
47 disp('all values need to be positive:')
48 disp(num2str(num_diff_flux_s.G(maxi, :)));
51 % ELmax = grid.EL(maxi, :);
52 Umax = U(model_data.gEI(maxi,:))'.*(grid.NX(maxi,:) + grid.NY(maxi,:));
53 conv_max = num_conv_flux_s.G(maxi, :);
54 Uconv_neg = zeros(size(num_conv_flux_s.G(maxi,:)));
55 Uconv_pos = zeros(size(num_conv_flux_s.G(maxi,:)));
56 Uconv_neg(Umax < 0) = conv_max(Umax < 0);
57 fUk = model.two_phase.waterflow([], S(maxi), model);
58 Uconv_pos(Umax < 0) = - Umax(Umax < 0) .* fUk;
59 if any(Uconv_pos + Uconv_neg < 0)
60 disp('all values need to be positive:')
61 disp(num2str(Uconv_pos + Uconv_neg));
64 cmax = model.two_phase.injection_concentration(model);
65 source_contri = (fUk - cmax) * S_upper(maxi);
67 dodisp = source_contri < 0;
70 dodisp = source_contri > 0;
74 disp(['source contribution should be ', negpos, ': ', num2str(source_contri)]);
78 %sink_contri_196 = (S(196) - model.two_phase.waterflow([], S(196), model)) * S_lower(196);
79 % disp(['sink at entity 196 = ', num2str(sink_contri_196)]);
82 if sum(Uconv_pos + Uconv_neg) + source_contri ~= sum(conv_max) - cmax * S_upper(maxi)
83 % disp('convective flux differs!');
87 % disp(['f(S_k) = ', num2str(fUk), ' c = ', num2str(cmax)]);
90 INC = grid.Ainv(NU_ind, :) .* ...
91 ( sum(num_diff_flux_s.G(NU_ind,:), 2) ...
92 + sum(num_conv_flux_s.G(NU_ind,:), 2) ...
93 - model.two_phase.injection_concentration(model) .* model_data.opdata.S_upper ...
94 + S(NU_ind) .* model_data.opdata.S_lower );
104 UN_ind = zeros(length(S),1);
105 UN_ind(NU_ind) = 1:length(NU_ind);
106 if ~isfield(sim_data, 'Uoff')
107 sim_data.Uoff = length(S);
111 sp11 = grid.Ainv(1).*sparse(UN_ind(s_diff_s.si), s_diff_s.sj, s_diff_s.svals, n, m);
112 sp121 = sparse(UN_ind(s_conv_s_u.si), s_conv_s_u.sj, s_conv_s_u.svals, n, m);
113 sp122 = sparse(UN_ind(s_conv_s_u.ui), s_conv_s_u.uj+sim_data.Uoff, s_conv_s_u.uvals, n, m);
114 sp12 = grid.Ainv(1).*(sp121+sp122);
116 sli = intersect(find(model_data.opdata.S_lower), NU_ind);
117 sp13 = sparse(UN_ind(sli), sli, model_data.opdata.S_lower(sli) .* grid.Ainv(sli), n, m);
119 J = sp11 + sp12 + sp13;
124 function ret_size = ret_size(this, model_data, NU_ind)
125 if nargin == 2 || isempty(NU_ind)
126 ret_size = model_data.grid.nelements;
128 ret_size = length(NU_ind);
132 function arg_size = arg_size(this, model_data)
133 arg_size = 2 * model_data.grid.nelements;
136 function ipm = inner_product_matrix(this, model_data)
140 function [nmd, eind, eind_local] = compute_TM_global(this, model_data, TM)
142 grid = model_data.grid;
143 glob2loc = zeros(max(TM),1);
144 glob2loc(eind) = 1:length(eind);
145 eind_local = glob2loc(TM);
148 nmd.grid_local_ext = gridpart(grid,eind);
150 gle = nmd.grid_local_ext;
151 mask = zeros(size(gle.NBI));
152 mask(eind_local, :) = 1;
153 [elnb_i, elnb_j] = find(gle.NBI(eind_local, :) > 0);
154 elnb = sub2ind(size(mask), eind_local(elnb_i), elnb_j);
155 mask(sub2ind(size(mask), gle.NBI(elnb), gle.INB(elnb))) = 1;
156 gle.NBI(~mask) = -10;
158 % eind_local_inv = setdiff(1:nmd.grid_local_ext.nelements, eind_local);
159 % [tmp_i, tmp_j] = find(nmd.grid_local_ext.NBI(eind_local_inv, :) < 0);
160 % nmd.grid_local_ext.NBI(sub2ind(size(nmd.grid_local_ext.NBI), eind_local_inv(tmp_i), tmp_j')) = -10;
162 [nmd.gEI, nmd.gn_inner_edges, nmd.gn_boundary_edges] ...
164 nmd.gn_edges = nmd.gn_inner_edges + nmd.gn_boundary_edges;
166 error('unsupported grid');
169 nmd.TM_global_args{1} = eind;
170 vel_global = zeros(1, model_data.gn_edges);
171 vel_global(model_data.gEI(TM, :)) = 1;
172 nmd.TM_global_args{2} = find(vel_global);
175 function opdata = fill_opdata(
this, rmodel, detailed_data)
176 if isa(rmodel.M, '
DataTree.IdMapNode')
177 MM = get_by_description(rmodel.M, 'L_saturation');
181 opdata.S_lower = detailed_data.model_data.opdata.S_lower(detailed_data.TM(1:MM));
182 opdata.S_upper = detailed_data.model_data.opdata.S_upper(detailed_data.TM(1:MM));
185 function opdata = copy_extract_opdata(this, opdata_copy, rmodel, Mid)
186 MM = get_by_description(rmodel.M, Mid);
187 opdata.S_lower = opdata_copy.S_lower(1:MM);
188 opdata.S_upper = opdata_copy.S_upper(1:MM);
Interface for a localized operator that fulfills the so-called -independent DOF dependence.
function [ gEI , in_edges , b_edges , i_ints_bigger , b_ints ] = compute_edge_indices(gridbase grid)
edge index matrix. This matrix maps each edge specified by the tuple (element_id, local_edge_id) to a...
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...
A triangular conforming grid in two dimensions.
A cartesian rectangular grid in two dimensions with axis parallel elements.
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...
a one dimensional grid implementation