rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
fv_frechet_operators_diff_implicit_gradient3.m
Go to the documentation of this file.
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'.
7 %
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
10 % step
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.
14 %
15 % \note The *_implicit functions perform a 'dt' increase in 'model' \em before
16 % evaluating the data functions.
17 %
18 % Return values:
19 % spm : a struct containing all arguments for the creation of a sparse matrix
20 % with the 'sparse' command.
21 %
22 
23 % determine affine_decomposition_mode as integer
24 
25 grid = [];
26 if ~isempty(model_data)
27  grid = model_data.grid;
28 end
29 
30 meanptr = model.mean_ptr;
31 
32 meanx = model.mean_deriv1_ptr;
33 meany = model.mean_deriv2_ptr;
34 
35 n = grid.nelements;
36 
37 spm.sn = n;
38 spm.sm = n;
39 if nargin < 4 || isempty(NU_ind)
40  NU_ind = (1:n);
41 end
42 if size(NU_ind,2)==1
43  NU_ind = NU_ind';
44 end
45 
46 NBI = grid.NBI;
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(:)];
56 
57 if model.verbose >= 29
58  disp(['found ',num2str(length(real_NB_ind)),' non-boundary edges.'])
59  disp(['found ',num2str(length(dir_NB_ind)),' dirichlet-boundary edges.'])
60 end
61 
62 tmpU = repmat(U, 1, grid.nneigh);
63 neiU = tmpU;
64 real_nb_ind = NBI > 0;
65 neiU(real_nb_ind) = U(NBI(real_nb_ind));
66 
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);
76 
77 meanarg = [difftmp.K, diffnei.K];
78 KK = meanptr(meanarg);
79 
80 nulls = sum(abs(meanarg),2)==0;
81 d_KK = meanx(meanarg).*deri_difftmp.K;
82 d_KK(nulls) = 0;
83 d_KL = meany(meanarg).*deri_diffnei.K;
84 d_KL(nulls) = 0;
85 
86 diff.epsilon = meanptr([difftmp.epsilon, diffnei.epsilon]);
87 
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(:);
97  d_KK(dir_NB_ind) = 0;
98 end
99 
100 
101 if (length(KK) == 1)
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;
105 else
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));
109 end
110 
111 Ulaplace = model.laplacian_ptr([grid.CX(:),...
112  grid.CY(:)],...
113  U, model);
114 DUlaplace = model.laplacian_derivative_ptr([grid.CX(:),...
115  grid.CY(:)],...
116  U, model);
117 if length(DUlaplace) == 1
118  DUlaplace = ones(size(grid.CX)) * DUlaplace;
119 end
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));
124 
125 if ~isempty(dir_NB_ind)
126  Ulaplace_NB(dir_NB_ind) = model.laplacian_ptr([Xdir,Ydir],...
127  Udir, model);
128  DUlaplace_NB(dir_NB_ind) = model.laplacian_derivative_ptr([Xdir,Ydir],...
129  Udir, model);
130 end
131 
132 % compute products
133 valdiag = zeros(size(grid.ESX));
134 
135 [i,dummy] = ind2sub(size(NBI),real_or_dir_NB_ind);
136 i = i';
137 
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) ...
144  );
145 
146 valdiag = sum(valdiag, 2);
147 
148 valneigh = ...
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) ...
154  );
155 
156 % Ti_inv = repmat(grid.Ainv(:),1,grid.nneigh);
157 % val = val .* Ti_inv;
158 
159 % diagonal values:
160 %L_I_diag = sparse(1:n,1:n, sum(val,2));
161 % off-diagonal values:
162 
163 spm.si = [NU_ind, i];
164 spm.sj = [NU_ind, NBI(real_or_dir_NB_ind)'];
165 spm.svals = [valdiag(NU_ind)', valneigh'];
166 
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
171 
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)) ...
176  .* Kdir .*Udir;
177 % bdir_I_diff = - grid.Ainv(:).* sum(val2,2);
178  bdir_I_diff = - sum(val2,2);
179 else
180  bdir_I_diff = zeros(grid.nelements,1);
181 end
182 
function r = verbose(level, message, messageId)
This function displays messages depending on a message-id and/or a level. Aditionally you can set/res...
Definition: verbose.m:17
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...