rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
gradient_approx_matrix.m
1 function [grad,bdir] = gradient_approx_matrix(model,model_data, NU_ind, edge)
2 %function grad = gradient_approx_matrix(model,model_data, [NU_ind], edge)
3 %
4 % function that returns a matrix with which an approximation of the gradient
5 % over the edge given by 'edge' can be computed.
6 %
7 % Martin Drohmann 13.05.2008
8 
9 decomp_mode = model.decomp_mode;
10 
11 if decomp_mode == 2
12  grad = 1;
13  bdir = model.dirichlet_values_ptr([],model);
14 else
15  grid = model_data.grid;
16  nels = grid.nelements;
17 
18  if(isempty(NU_ind))
19  NU_ind = 1:nels;
20  end
21  nu_ind_length = length(NU_ind);
22 
23 
24 
25  % get a 6-environment of each cell (see get_enbi for details)
26  ENBI = get_enbi(grid, edge, model.tstep);
27 
28  %%%% Handle dirichlet cells ("ghost" cells with index -1) %%%%
29  % if a cell adjacent to the current edge is a _dirichlet_ "ghost" cell,
30  % entries in the matrix UE have to be replaced by exact evaluations at
31  % the dirichlet boundary. The following cases have to be separated:
32  % case 1: one of the adjacent cells is a ghost
33  % => replace the cell's entry in UE with the dirichlet value at
34  % the edge's center
35  % case 2/3: one cell adjacent to the tip is a ghost
36  % => replace the tip's entry in UE with the dirichlet value at the
37  % edge's tip.
38 
39  % find the _row_ index (edge index) of the three cases
40  case1_dir_ind = find(ENBI(:,4) == -1);
41  case2_dir_ind = find(ENBI(:,5) == -1);
42  case3_dir_ind = find(ENBI(:,6) == -1);
43 
44  % the case23_mapper maps to the correct edge tip (correct column index)
45  % in UE.
46  if edge > 2
47  case23_mapper = [ mod(edge, 4) + 1, edge ];
48  else
49  case23_mapper = [ edge, mod(edge, 4) + 1 ];
50  end
51 
52  % update the 4-environment concerning dirichlet cells
53  if decomp_mode == 0
54  UE = zeros(nels, 3);
55  Xdir = grid.ESX(case1_dir_ind, edge);
56  Ydir = grid.ESY(case1_dir_ind, edge);
57  UE(case1_dir_ind, 1) = model.dirichlet_values_ptr([Xdir,Ydir],model);
58  Xdir = grid.X(grid.VI(case2_dir_ind, case23_mapper(1) ));
59  Ydir = grid.Y(grid.VI(case2_dir_ind, case23_mapper(1) ));
60  UE(case2_dir_ind, 2) = model.dirichlet_values_ptr([Xdir,Ydir],model);
61  Xdir = grid.X(grid.VI(case3_dir_ind, case23_mapper(2) ));
62  Ydir = grid.Y(grid.VI(case3_dir_ind, case23_mapper(2) ));
63  UE(case3_dir_ind, 3) = model.dirichlet_values_ptr([Xdir,Ydir],model);
64  else % decomp_mode == 1
65  Xdir = grid.ESX(case1_dir_ind, edge);
66  Ydir = grid.ESY(case1_dir_ind, edge);
67  tmp = model.dirichlet_values_ptr([Xdir,Ydir],model);
68  UE = cell(length(tmp), 3);
69  UE(:,1) = cellfun(@(X)(assemble_UE(X,nels,case1_dir_ind)), tmp, ...
70  'UniformOutput', false);
71  Xdir = grid.X(grid.VI(case2_dir_ind, case23_mapper(1) ));
72  Ydir = grid.Y(grid.VI(case2_dir_ind, case23_mapper(1) ));
73  tmp = model.dirichlet_values_ptr([Xdir,Ydir],model);
74  UE(:,2) = cellfun(@(X)(assemble_UE(X,nels,case2_dir_ind)), tmp, ...
75  'UniformOutput', false);
76  Xdir = grid.X(grid.VI(case3_dir_ind, case23_mapper(2) ));
77  Ydir = grid.Y(grid.VI(case3_dir_ind, case23_mapper(2) ));
78  tmp = model.dirichlet_values_ptr([Xdir,Ydir],model);
79  UE(:,3) = cellfun(@(X)(assemble_UE(X,nels,case3_dir_ind)), tmp, ...
80  'UniformOutput', false);
81  end
82 
83  % neuman boundaries!!! For all other ghost cells the entries of
84  % adjacent non-ghost cells are copied. Ghost cells in the corners of
85  % the rectgrid are assigned in the end by copying one of the already
86  % assigned adjacent ghost-cell. It is unspecified which ghost cell is
87  % used.
88  if(any(any(ENBI(NU_ind, :) == -10)))
89  disp('Attention in gradient_approx_matrix! This line should never be executed');
90  end
91  dir_bnd_ind1 = ENBI(NU_ind,4) == -1;
92  dir_bnd_ind2 = find(ENBI(NU_ind,[2,5]) == -1);
93  dir_bnd_ind3 = find(ENBI(NU_ind,[3,6]) == -1);
94  case2_dir_ind = find(ENBI(NU_ind,5) == -1);
95  case3_dir_ind = find(ENBI(NU_ind,6) == -1);
96  nb_ind = find(ENBI(:,2) <= 0);
97  ENBI(nb_ind, 2) = ENBI(nb_ind, 1);
98  nb_ind = find(ENBI(:,3) <= 0);
99  ENBI(nb_ind, 3) = ENBI(nb_ind, 1);
100  nb_ind = find(ENBI(:,4) <= 0);
101  ENBI(nb_ind, 4) = ENBI(nb_ind, 1);
102  nb_ind = find(ENBI(:,5) == -2);
103  ENBI(nb_ind, 5) = ENBI(nb_ind, 2);
104  nb_ind = find(ENBI(:,5) <= 0);
105  ENBI(nb_ind, 5) = ENBI(nb_ind, 4);
106  nb_ind = find(ENBI(:,6) == -2);
107  ENBI(nb_ind, 6) = ENBI(nb_ind, 3);
108  nb_ind = find(ENBI(:,6) <= 0);
109  ENBI(nb_ind, 6) = ENBI(nb_ind, 4);
110 
111  I = cell(2,1);
112  J = cell(2,1);
113  S = cell(2,1);
114 
115  I{1} = ones(nu_ind_length, 2);
116  J{1} = ones(nu_ind_length, 2);
117  S{1} = ones(nu_ind_length, 2);
118  I{2} = ones(nu_ind_length, 4);
119  J{2} = ones(nu_ind_length, 4);
120  S{2} = ones(nu_ind_length, 4);
121  I{3} = ones(length(case2_dir_ind), 2);
122  J{3} = ones(length(case2_dir_ind), 2);
123  S{3} = ones(length(case2_dir_ind), 2);
124  I{4} = ones(length(case3_dir_ind), 2);
125  J{4} = ones(length(case3_dir_ind), 2);
126  S{4} = ones(length(case3_dir_ind), 2);
127 
128  horiz_length = grid.EL(1,1);
129  vert_length = grid.EL(1,2);
130 
131  if edge == 1
132  s1factor = -1/horiz_length;
133  s2factor = -1/vert_length;
134  order_addend1 = -1;
135  order_addend2 = 0;
136  elseif edge == 2
137  s1factor = -1/vert_length;
138  s2factor = 1/horiz_length;
139  order_addend1 = 0;
140  order_addend2 = -1;
141  elseif edge == 3
142  s1factor = 1/horiz_length;
143  s2factor = -1/vert_length;
144  order_addend1 = -1;
145  order_addend2 = 0;
146  elseif edge == 4
147  s1factor = 1/vert_length;
148  s2factor = 1/horiz_length;
149  order_addend1 = 0;
150  order_addend2 = -1;
151  end
152 
153  I{1} = repmat(2*(1:nu_ind_length)+order_addend1,1,2);
154  J{1} = ENBI(NU_ind,[1,4]);
155 % J{1}(dir_bnd_ind1,2) = dir_bnd_ind1;
156  S{1} = s1factor * repmat([1,-1],nu_ind_length,1);
157  S{1}(dir_bnd_ind1,2) = 0;
158 
159 % S{1} = 1;
160  I{2} = repmat(2*(1:nu_ind_length)+order_addend2,1,4);
161  J{2} = ENBI(NU_ind,[2,5,3,6]);
162  [row_numbers1,dummy] = ind2sub([nu_ind_length,2],dir_bnd_ind2);
163  [row_numbers2,dummy] = ind2sub([nu_ind_length,2],dir_bnd_ind3);
164  S{2} = s2factor * repmat([1/4,1/4,-1/4,-1/4],nu_ind_length,1);
165  S{2}(row_numbers1,[1,2]) = 0;
166  S{2}(row_numbers2,[3,4]) = 0;
167 
168  I{3} = repmat(2*case2_dir_ind+order_addend2,1,2);
169  J{3} = ENBI(case2_dir_ind,[1,4]);
170  S{3} = s2factor * repmat([-1/4,-1/4],length(case2_dir_ind),1);
171 
172  I{4} = repmat(2*case3_dir_ind+order_addend2,1,2);
173  J{4} = ENBI(case3_dir_ind,[1,4]);
174  S{4} = s2factor * repmat([1/4,1/4],length(case3_dir_ind),1);
175 
176 
177  II = [ reshape(I{1},2*nu_ind_length,1); reshape(I{2},4*nu_ind_length,1); ...
178  reshape(I{3},2*length(case2_dir_ind),1); reshape(I{4},2*length(case3_dir_ind),1) ];
179  JJ = [ reshape(J{1},2*nu_ind_length,1); reshape(J{2},4*nu_ind_length,1); ...
180  reshape(J{3},2*length(case2_dir_ind),1); reshape(J{4},2*length(case3_dir_ind),1) ];
181  SS = [ reshape(S{1},2*nu_ind_length,1); reshape(S{2},4*nu_ind_length,1); ...
182  reshape(S{3},2*length(case2_dir_ind),1); reshape(S{4},2*length(case3_dir_ind),1) ];
183 
184  if decomp_mode == 0
185  if edge == 1
186  bdir = [UE(NU_ind,1)./horiz_length, (UE(NU_ind,3)-UE(NU_ind,2))./(vert_length)];
187  elseif edge == 2
188  bdir = [(UE(NU_ind,2)-UE(NU_ind,3))./(horiz_length), UE(NU_ind,1)./vert_length];
189  elseif edge == 3
190  bdir = [-UE(NU_ind,1)./horiz_length, (UE(NU_ind,3)-UE(NU_ind,2))./(vert_length)];
191  elseif edge == 4
192  bdir = [(UE(NU_ind,2)-UE(NU_ind,3))./(horiz_length), -UE(NU_ind,1)./vert_length];
193  end
194  bdir = reshape(bdir', 2*nu_ind_length,1);
195  grad = sparse(II,JJ,SS, 2*nu_ind_length,nels);
196  else %decomp_mode == 1
197  if edge == 1
198  tmp1 = cellfun(@(X)(X(NU_ind)./horiz_length), UE(:,1), ...
199  'UniformOutput', false);
200  tmp2 = cellfun(@(X,Y)( (X(NU_ind)-Y(NU_ind))./vert_length ), UE(:,3), UE(:,2), ...
201  'UniformOutput', false);
202  elseif edge == 2
203  tmp1 = cellfun(@(X,Y)( (X(NU_ind)-Y(NU_ind))./horiz_length ), UE(:,2), UE(:,3), ...
204  'UniformOutput', false);
205  tmp2 = cellfun(@(X)(X(NU_ind)./vert_length), UE(:,1), ...
206  'UniformOutput', false);
207  elseif edge == 3
208  tmp1 = cellfun(@(X)(-X(NU_ind)./horiz_length), UE(:,1), ...
209  'UniformOutput', false);
210  tmp2 = cellfun(@(X,Y)( (X(NU_ind)-Y(NU_ind))./vert_length ), UE(:,3), UE(:,2),...
211  'UniformOutput', false);
212  elseif edge == 4
213  tmp1 = cellfun(@(X,Y)( (X(NU_ind)-Y(NU_ind))./horiz_length ), UE(:,2), UE(:,3), ...
214  'UniformOutput', false);
215  tmp2 = cellfun(@(X)(-X(NU_ind)./vert_length), UE(:,1), ...
216  'UniformOutput', false);
217  end
218  bdir = cellfun(@(X,Y)([X,Y]), tmp1, tmp2, 'UniformOutput', false);
219  bdir = cellfun(@(X)(reshape(X', 2*nu_ind_length,1)), bdir, 'UniformOutput', false);
220  grad = {sparse(II,JJ,SS,2*nu_ind_length,nels)};
221  end
222 end
223 
224 end
225 
226 function [ret] = assemble_UE(X,nels,dir_ind)
227  ret = zeros(1,nels);
228  ret(dir_ind) = X;
229 end
230 
231 %| \docupdate
A cartesian rectangular grid in two dimensions with axis parallel elements.
Definition: rectgrid.m:17