2 model, model_data, U, NU_ind)
4 % model, model_data, U)
5 % computes a jacobian of implicit non-linear diffusion contributions to time
6 % evolution matrices at a point
'U'.
8 %
function computing the jacobian in
'U' of the implicit diffusion contribution
9 % of `L_I` and `b_I` to the time evolution matrices
for a finite volume time
11 % `L_I U^{k+1} = L_E U^k + b_E + b_I`.
12 % With the help of the returned Jacobian
'L_I_diff_jac' the Frechet derivative
13 % `DL_I ({U})` is approximated.
15 % \note The *_implicit functions perform a
'dt' increase in
'model' \em before
16 % evaluating the data functions.
19 % spm : a
struct containing all arguments
for the creation of a sparse matrix
20 % with the
'sparse' command.
23 % determine affine_decomposition_mode as integer
26 if ~isempty(model_data)
27 grid = model_data.grid;
30 meanptr = model.mean_ptr;
32 meanx = model.mean_deriv1_ptr;
33 meany = model.mean_deriv2_ptr;
39 if nargin < 4 || isempty(NU_ind)
47 NU_ind_inv = setdiff(1:n, NU_ind);
48 NBI(NU_ind_inv, :) = 0;
49 % determine index sets of boundary types
50 real_NB_ind = find(NBI>0);
51 %NBIind = grid.NBI(real_NB_ind);
52 %INBind = grid.INB(real_NB_ind);
53 % NB_real_NB_ind = sub2ind(size(grid.NBI),NBIind, INBind);
54 dir_NB_ind =find(NBI == -1);
55 real_or_dir_NB_ind = [real_NB_ind(:); dir_NB_ind(:)];
58 disp(['found ',num2str(length(real_NB_ind)),' non-boundary edges.'])
59 disp(['found ',num2str(length(dir_NB_ind)),' dirichlet-boundary edges.'])
62 tmpU = repmat(U, 1, grid.nneigh);
64 real_nb_ind = NBI > 0;
65 neiU(real_nb_ind) = U(NBI(real_nb_ind));
67 %edgeU = 0.5 * (tmpU + neiU);
68 %edgeU = sqrt(tmpU.*neiU);
69 %edgeU = min(tmpU,neiU);
70 %edgeU = 2*(1./tmpU + 1./neiU).^(-1);
71 %diff = model.diffusivity_ptr([grid.ESX(:), grid.ESY(:)],edgeU(:), model);
72 difftmp = model.diffusivity_ptr([grid.ESX(:),grid.ESY(:)],tmpU(:),model);
73 deri_difftmp = model.diffusivity_derivative_ptr([grid.ESX(:),grid.ESY(:)],tmpU(:),model);
74 diffnei = model.diffusivity_ptr([grid.ESX(:),grid.ESY(:)],neiU(:),model);
75 deri_diffnei = model.diffusivity_derivative_ptr([grid.ESX(:),grid.ESY(:)],neiU(:),model);
77 meanarg = [difftmp.K, diffnei.K];
78 KK = meanptr(meanarg);
80 nulls = sum(abs(meanarg),2)==0;
81 d_KK = meanx(meanarg).*deri_difftmp.K;
83 d_KL = meany(meanarg).*deri_diffnei.K;
86 diff.epsilon = meanptr([difftmp.epsilon, diffnei.epsilon]);
88 % exact diffusivity on dirichlet edges
89 if (~isempty(dir_NB_ind))
90 Xdir = grid.ECX(dir_NB_ind);
91 Ydir = grid.ECY(dir_NB_ind);
92 Udir = model.dirichlet_values_ptr([Xdir(:),Ydir(:)],model);
93 Kdir = model.diffusivity_ptr([Xdir(:),Ydir(:)],Udir,model);
94 K_deriv_dir = model.diffusivity_derivative_ptr([Xdir(:),Ydir(:)],Udir,model);
95 KK(dir_NB_ind) = Kdir.K(:);
96 d_KL(dir_NB_ind) = K_deriv_dir.K(:);
102 KK = ones(size(grid.ESX))*KK;
103 d_KK = ones(size(grid.ESX))*d_KK;
104 d_KL = ones(size(grid.ESX))*d_KL;
106 KK = reshape(KK,size(grid.ESX));
107 d_KK = reshape(d_KK,size(grid.ESX));
108 d_KL = reshape(d_KL,size(grid.ESX));
111 Ulaplace = model.laplacian_ptr([grid.CX(:),...
114 DUlaplace = model.laplacian_derivative_ptr([grid.CX(:),...
117 if length(DUlaplace) == 1
118 DUlaplace = ones(size(grid.CX)) * DUlaplace;
120 Ulaplace_NB = zeros(size(grid.ESX));
121 Ulaplace_NB(real_NB_ind) = Ulaplace(NBI(real_NB_ind));
122 DUlaplace_NB = zeros(size(grid.ESX));
123 DUlaplace_NB(real_NB_ind) = DUlaplace(NBI(real_NB_ind));
125 if ~isempty(dir_NB_ind)
126 Ulaplace_NB(dir_NB_ind) = model.laplacian_ptr([Xdir,Ydir],...
128 DUlaplace_NB(dir_NB_ind) = model.laplacian_derivative_ptr([Xdir,Ydir],...
133 valdiag = zeros(size(grid.ESX));
135 [i,dummy] = ind2sub(size(NBI),real_or_dir_NB_ind);
138 valdiag(real_or_dir_NB_ind) = ...
139 grid.EL(real_or_dir_NB_ind).* ...
140 grid.DS(real_or_dir_NB_ind).^(-1).* ...
141 ( d_KK(real_or_dir_NB_ind).* ...
142 (Ulaplace(i) - Ulaplace_NB(real_or_dir_NB_ind)) ...
143 + KK(real_or_dir_NB_ind).* DUlaplace(i) ...
146 valdiag = sum(valdiag, 2);
149 grid.EL(real_or_dir_NB_ind).* ...
150 grid.DS(real_or_dir_NB_ind).^(-1).* ...
151 ( d_KL(real_or_dir_NB_ind).* ...
152 (Ulaplace(i) - Ulaplace_NB(real_or_dir_NB_ind)) ...
153 - KK(real_or_dir_NB_ind).* DUlaplace_NB(real_or_dir_NB_ind) ...
156 % Ti_inv = repmat(grid.Ainv(:),1,grid.nneigh);
157 % val = val .* Ti_inv;
160 %L_I_diag = sparse(1:n,1:n, sum(val,2));
161 % off-diagonal values:
163 spm.si = [NU_ind, i];
164 spm.sj = [NU_ind, NBI(real_or_dir_NB_ind)'];
165 spm.svals = [valdiag(NU_ind)', valneigh'];
167 if ~isempty(dir_NB_ind)
168 error('Dirichlet values not yet supported');
169 % evaluate dirichlet values at edge midpoints at t+dt
170 % Xdir, Ydir, Udir, K(dir_NB_ind) already computed above
172 Kdir = K(dir_NB_ind); % diffusivity already computed above
173 val2 = zeros(size(grid.ESX));
174 val2(dir_NB_ind)= - grid.EL(dir_NB_ind).*...
175 Udirlaplace.*((1.0*grid.DS(dir_NB_ind)).^(-1)) ...
177 % bdir_I_diff = - grid.Ainv(:).* sum(val2,2);
178 bdir_I_diff = - sum(val2,2);
180 bdir_I_diff = zeros(grid.nelements,1);
function r = verbose(level, message, messageId)
This function displays messages depending on a message-id and/or a level. Aditionally you can set/res...
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...