rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
fv_operators_diff_implicit_gradient_tensor.m
1 function [L_I_diff, bdir_I_diff] = fv_operators_diff_implicit_gradient_tensor(...
2  model,model_data,NU_ind)
3 %function [L_I_diff, bdir_I_diff] = ...
4 % fv_operators_diff_implicit_gradient_tensor(model,model_data[,NU_ind])
5 %
6 % function computing the implicit diffusion contribution to the time evolution
7 % matrices for a finite volume time step L_I * Unew = L_E * U + b
8 % this function is called by fv_operators_implicit_explicit.
9 %
10 % the *_implicit functions perform a dt increase in model
11 % themselves before evaluating data functions
12 %
13 % Result is a sparse matrix L_I_diff and an offset vector
14 % bdir_I_diff, the latter containing dirichlet value contributions
15 %
16 % as numerical flux simple gradient approximation is used
17 %
18 % Function supports affine decomposition, i.e. different operation modes
19 % guided by optional field decomp_mode in model. See also the
20 % contents.txt for general explanation
21 
22 % Bernard Haasdonk 13.7.2006
23 
24 % determine affine_decomposition_mode as integer
25 
26 decomp_mode = model.decomp_mode;
27 
28 
29 old_t = model.t;
30 model.t=model.t+model.dt;
31 
32 if decomp_mode == 2 % coefficients
33  % simply forward the diffusivity sigmas
34  L_I_diff = [];
35  bdir_I_diff = [];
36  for edge = 1:4
37  [tmpgrad,bdir] = gradient_approx_matrix(model, [], [], edge);
38  diff_k = model.diffusivity_ptr([], model);
39  L_I_temp = kron(tmpgrad, diff_k);
40  b_I_temp = kron(bdir, diff_k);
41  L_I_diff = [ L_I_diff, L_I_temp ];
42  bdir_I_diff = [ bdir_I_diff, b_I_temp ];
43  end
44 else
45  grid = [];
46  if ~isempty(model_data)
47  grid = model_data.grid;
48  end
49 
50  %nu_ind_set = false;
51 
52  if nargin < 3 || isempty(NU_ind)
53  NU_ind = 1:grid.nelements;
54 % else
55  %nu_ind_set = true;
56  end
57 
58  nu_ind_length = length(NU_ind);
59  n = grid.nelements;
60  % determine index sets of boundary types
61  real_NB_ind = find(grid.NBI>0);
62  % NBIind = grid.NBI(real_NB_ind);
63  % INBind = grid.INB(real_NB_ind);
64  % NB_real_NB_ind = sub2ind(size(grid.NBI),NBIind, INBind);
65  dir_NB_ind =find(grid.NBI == -1);
66  % real_or_dir_NB_ind = [real_NB_ind(:); dir_NB_ind(:)];
67 
68  if model.verbose >= 29
69  disp(['found ',num2str(length(real_NB_ind)),' non-boundary edges.'])
70  disp(['found ',num2str(length(dir_NB_ind)),' dirichlet-boundary edges.'])
71  end;
72 
73  if ~isequal(model.gridtype, 'rectgrid')
74  error(['gradient_tensor is not implemented for specified gridtype ', ...
75  model.gridtype]);
76  end
77 
78  U = [];
79 
80  if decomp_mode == 0 % complete mode
81  tmp_flux_mat = sparse(nu_ind_length, n);
82  bdir_I_diff = zeros(nu_ind_length, 1);
83  for edge = 1:4
84  [tmpgrad,bdir] = gradient_approx_matrix(model, model_data, NU_ind, edge);
85  diff_k = model.diffusivity_ptr([grid.ECX(NU_ind,edge),grid.ECY(NU_ind,edge)], [], model);
86  diff = ...
87  model.diffusivity_tensor_ptr([grid.ECX(NU_ind,edge), grid.ECY(NU_ind,edge)], ...
88  U, model, 3);
89 
90 % if nu_ind_set && model.debug
91 % disp(['any wrong: ', num2str(any(bdir2(reshape([2*NU_ind-1,2*NU_ind]',2*length(NU_ind),1))-bdir))]);
92 %
93 % if any(bdir2(reshape([2*NU_ind-1,2*NU_ind]',2*length(NU_ind),1))-bdir)
94 % [bdir, bdir2(reshape([2*NU_ind-1,2*NU_ind]',2*length(NU_ind),1))]
95 % keyboard;
96 % end
97 % end
98 
99  % this works only for scalar diffusivity -> use only first value of
100  % diffusivity vector (assumed to be homogeneous)
101  if model.debug
102  if any(repmat(diff_k.K(1),length(diff_k.K),1) ~= diff_k.K)
103  error(['Error: model.diffusivity_ptr does not return a homogeneous vector!\n',...
104  'This is invalid inside fv_operators_diff_implicit_gradient_tensor.']);
105  end
106  end
107  tmp1 = diff_k.K(1) * diff.K;
108 
109  helper = sparse([1:nu_ind_length,1:nu_ind_length], ...
110  [2*(1:nu_ind_length)-1, 2*(1:nu_ind_length)], ...
111  reshape( [grid.NX(NU_ind,edge), grid.NY(NU_ind,edge)], ...
112  1, 2*nu_ind_length ) );
113 
114  tmp2 = helper * tmp1;
115 
116  ELL = spdiags(grid.EL(NU_ind,edge).*grid.Ainv(NU_ind,1),0,nu_ind_length,nu_ind_length);
117  tmp_flux_mat = tmp_flux_mat + ELL * tmp2 * tmpgrad;
118  bdir_I_diff = bdir_I_diff - tmp2 * bdir .* grid.EL(NU_ind,edge).*grid.Ainv(NU_ind,1);
119  end
120  L_I_diff = - tmp_flux_mat;
121  elseif decomp_mode == 1 % (components mode)
122  L_I_diff = cell(0,1);
123  bdir_I_diff = cell(0,1);
124  for edge = 1:4
125  model.decomp_mode = 0;
126  diff = model.diffusivity_tensor_ptr([grid.ECX(NU_ind,edge), ...
127  grid.ECY(NU_ind,edge)],[],model, 3);
128 
129  model.decomp_mode = 1;
130  [tmpgrad,bdir] = gradient_approx_matrix(model, model_data, NU_ind, edge);
131  diff_k = model.diffusivity_ptr([grid.ECX(NU_ind,edge),grid.ECY(NU_ind,edge)], [], model);
132 
133  L_I_temp = cell(length(diff_k) * length(tmpgrad), 1);
134  b_I_temp = cell(length(diff_k) * length(bdir), 1);
135 
136  helper = sparse([1:nu_ind_length,1:nu_ind_length], ...
137  [2*(1:nu_ind_length)-1, 2*(1:nu_ind_length)], ...
138  reshape( [grid.NX(NU_ind,edge), grid.NY(NU_ind,edge)], ...
139  1, 2*nu_ind_length ) );
140 
141  for q=1:length(diff_k)
142  tmp1 = spdiags(repmat(diff_k{q}.K,2,1),0,size(diff.K,1),size(diff.K,2)) * diff.K;
143  tmp2 = helper * tmp1;
144  for r=1:length(tmpgrad)
145  % t = diag(grid.EL(:,edge)) * tmp2 * tmpgrad{r};
146  ELL = spdiags(grid.EL(NU_ind,edge).*grid.Ainv(NU_ind,1),0,nu_ind_length,nu_ind_length);
147  L_I_temp{ (q-1)*length(tmpgrad) + r } = ELL * tmp2 * tmpgrad{r};
148  end
149  for r=1:length(bdir)
150  b_I_temp{ (q-1)*length(bdir) + r } = tmp2 * bdir{r} .* grid.EL(NU_ind,edge).*grid.Ainv(NU_ind,1);
151  end
152  end
153  L_I_diff = [ L_I_diff; L_I_temp ];
154  bdir_I_diff = [ bdir_I_diff; b_I_temp ];
155  end
156  else
157  error(['decomp_mode number ', model.decomp_mode, ' is unknown.']);
158  end
159 
160 end
161 
162 model.t = old_t;
163 
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
A cartesian rectangular grid in two dimensions with axis parallel elements.
Definition: rectgrid.m:17