rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
cut_alu3d_hexa.m
1 function Mcut = cut_alu3d_hexa(M,pmin,pmax,bndval)
2 %function Mcut = cut_alu3d_hexa(M,pmin,pmax,bndval)
3 %
4 % function cutting out a "cube" out of given ALU3D grid.
5 % 1. in a first loop, all elements are identified, the cog of which
6 % lies strictly within the specified cube, these are marked for
7 % deletion
8 % 2. the boundary segments of to be deleted elements are marked for deletion
9 % 3. in a second loop all surviving neighbours of deleted elements
10 % a new boundary face is marked for inclusion
11 % 4. the new element and face list is generated
12 % 5. all vertices are determined, which are not used
13 % in any element or face and marked for deletion
14 % 6. the new vertex, element and boundary list are condensed
15 
16 % Bernard Haasdonk 13.3.2006
17 
18 debug_ = 0;
19 
20 % 1. search all elements with cog inside cube for deletion
21 % compute cog of all elements
22 
23 disp('1. detect elements for deletion');
24 linvind = M.elements(:)+1;
25 X = sum(reshape(M.vertices(1,linvind),8,M.num_elements))/8;
26 Y = sum(reshape(M.vertices(2,linvind),8,M.num_elements))/8;
27 Z = sum(reshape(M.vertices(3,linvind),8,M.num_elements))/8;
28 cog = [X;Y;Z];
29 
30 % must be positive for points within the cube
31 pmindiff = min(cog-repmat(pmin(:),1,M.num_elements));
32 pmaxdiff = min(repmat(pmax(:),1,M.num_elements)-cog);
33 mindiff = min([pmindiff; pmaxdiff]);
34 el_to_be_del_flag = (mindiff>0);
35 el_to_be_del_ind = find(mindiff>0);
36 
37 if debug_
38  disp('halt after el_to_be_del detection')
39  keyboard;
40 end;
41 
42 % 2. mark boundary segments of to be deleted elements for deletion/
43 % generate new boundary
44 
45 % generate list of all faces of to be deleted elements
46 % in ALUgrid notation 6 faces of 8 vertices:
47 % modified indices
48 %1 2 3 4 5 6 7 8
49 % =>
50 % 1 4 8 5
51 % 2 6 7 3
52 % 1 5 6 2
53 % 4 3 7 8
54 % 1 2 3 4
55 % 6 5 8 7
56 
57 disp('2. make boundary list of to be deleted elements');
58 fv_el_ind = [ 1 4 8 5 ...
59  2 6 7 3 ...
60  1 5 6 2 ...
61  4 3 7 8 ...
62  1 2 3 4 ...
63  6 5 8 7];
64 
65 fv_ind = M.elements(fv_el_ind,el_to_be_del_ind)+1;
66 fv_ind = reshape(fv_ind,4,6*length(el_to_be_del_ind));
67 % fvind now is the list of columnwise indices of candidate boundary faces
68 
69 if debug_
70  disp('halt after setup of list of candidate boundary faces')
71  keyboard;
72 end;
73 
74 % generate description of all faces and process
75 % 1-neigh to be del => do nothing
76 % 2-neigh not to be del => insert new boundary
77 % 3-neigh is existing boundary => delete boundary from existing list
78 % 0-not qualified neighbour: should not happen
79 
80 % initially nothing is known about faces
81 fv_ind_descr = zeros(1,size(fv_ind,2));
82 % detection of case 1: double appearance of the face in the list:
83 %keyboard;
84 disp('2. a) search boundaries to elements which are also to be deleted');
85 for facenr = 1:length(fv_ind_descr)
86  if mod(facenr,100)==0
87  disp([num2str(facenr),'/',num2str(length(fv_ind_descr))]);
88  end;
89  % search for faces with at least one identical vertex nr
90  cand_flag1 = max(fv_ind==fv_ind(1,facenr));
91  cand_flag2 = max(fv_ind==fv_ind(2,facenr));
92  cand_flag3 = max(fv_ind==fv_ind(3,facenr));
93  cand_flag4 = max(fv_ind==fv_ind(4,facenr));
94  cand_flag = cand_flag1 | cand_flag2 | cand_flag3 | cand_flag4;
95  ind_cand = find(cand_flag==1);
96  matrix = fv_ind(:,ind_cand);
97  ind = face_in_matrix(fv_ind(:,facenr),matrix);
98  if (length(ind)>1) % at least once as identical
99  fv_ind_descr(facenr) = 1;
100  end;
101 end;
102 
103 if debug_
104  disp('halt after detection of case 1 of boundary faces')
105  keyboard;
106 end;
107 
108 % detection of case 2:
109 % generate element list of elements with any vertex appearing in
110 % tobedeleted elements.
111 disp('2. b) search boundaries to elements which are not be deleted');
112 
113 vind = zeros(size(M.elements));
114 el_to_be_del_vind = M.elements(:,el_to_be_del_ind)+1;
115 j=0;
116 for i = el_to_be_del_vind(:)'
117  j=j+1;
118  if mod(j,100)==0
119  disp([num2str(j),'/',num2str(length(el_to_be_del_vind))]);
120  end;
121  fi = find(M.elements == (i-1));
122  vind(fi) = 1;
123 end;
124 cand_el_flag = max(vind);
125 
126 % make sure, that all listed elements are surviving
127 cand_el_flag(el_to_be_del_ind) = 0;
128 cand_el_ind = find(cand_el_flag==1);
129 
130 if debug_
131  disp('halt after detection of surviving neighbour elements')
132  keyboard;
133 end;
134 
135 % generate all boundary faces of remaining elements
136 fv_boundary_ind = M.elements(fv_el_ind,cand_el_ind)+1;
137 fv_boundary_ind = reshape(fv_boundary_ind,4,6*length(cand_el_ind));
138 
139 % search all questionable faces in the generated list
140 face_to_be_insert_flag = zeros(1,size(fv_boundary_ind,2));
141 for facenr = 1:length(fv_ind_descr)
142  if mod(facenr,100)==0
143  disp([num2str(facenr),'/',num2str(length(fv_ind_descr))]);
144  end;
145  % search for faces with at least one identical vertex nr
146  cand_flag1 = max(fv_boundary_ind==fv_ind(1,facenr));
147  cand_flag2 = max(fv_boundary_ind==fv_ind(2,facenr));
148  cand_flag3 = max(fv_boundary_ind==fv_ind(3,facenr));
149  cand_flag4 = max(fv_boundary_ind==fv_ind(4,facenr));
150  cand_flag = cand_flag1 | cand_flag2 | cand_flag3 | cand_flag4;
151  ind_cand = find(cand_flag==1);
152  matrix = fv_boundary_ind(:,ind_cand);
153  ind = face_in_matrix(fv_ind(:,facenr),matrix);
154  if (length(ind)>0) %
155  fv_ind_descr(facenr) = 2;
156  end;
157  face_to_be_insert_flag(ind_cand(ind)) = 1;
158 end;
159 face_to_be_insert_ind = find(face_to_be_insert_flag==1);
160 
161 if debug_
162  disp('halt after detection of case 2 of boundary faces')
163  keyboard;
164 end;
165 
166 % detection of case 3:
167 disp('2. c) search boundaries to former domain boundary');
168 face_to_be_del_flag = zeros(1,size(M.faces,2));
169 for facenr = 1:length(fv_ind_descr)
170  if mod(facenr,100)==0
171  disp([num2str(facenr),'/',num2str(length(fv_ind_descr))]);
172  end;
173  % search for faces with at least one identical vertex nr
174  cand_flag1 = max(M.faces(3:6,:)== (fv_ind(1,facenr)-1));
175  cand_flag2 = max(M.faces(3:6,:)== (fv_ind(2,facenr)-1));
176  cand_flag3 = max(M.faces(3:6,:)== (fv_ind(3,facenr)-1));
177  cand_flag4 = max(M.faces(3:6,:)== (fv_ind(4,facenr)-1));
178  cand_flag = cand_flag1 | cand_flag2 | cand_flag3 | cand_flag4;
179  ind_cand = find(cand_flag==1);
180  matrix = M.faces(3:6,ind_cand)+1;
181  ind = face_in_matrix(fv_ind(:,facenr),matrix);
182  if (length(ind)>0) %
183  fv_ind_descr(facenr) = 3;
184  end;
185  face_to_be_del_flag(ind_cand(ind)) = 1;
186 end;
187 face_to_be_del_ind = find(face_to_be_del_flag==1);
188 
189 if debug_
190  disp('halt after detection of case 3 of boundary faces')
191  keyboard;
192 end;
193 
194 % make sure that no face is left out of assignment 1-3
195 if ~isempty(find(fv_ind_descr==0))
196  disp('not all questionable boundaries are qualified!');
197  keyboard;
198 end;
199 
200 disp('3. c) generate new element, faces and vertices');
201 % 4. generate new element and face list
202 % new elements:
203 Mcut.elements = M.elements(:,find(el_to_be_del_flag==0));
204 Mcut.num_elements = size(Mcut.elements,2);
205 % new faces:
206 facesnew = [bndval * ones(1,length(face_to_be_insert_ind)); ...
207  4 * ones(1,length(face_to_be_insert_ind)); ...
208  fv_boundary_ind(:,face_to_be_insert_ind)-1 ];
209 Mcut.faces = [M.faces(:,find(face_to_be_del_flag==0)), ...
210  facesnew];
211 Mcut.num_faces = size(Mcut.faces,2);
212 
213 if debug_
214  disp('halt after setup of non-condensed result')
215  keyboard;
216 end;
217 
218 % 5. all vertices are determined, which are to be reused
219 new2old_vflag = zeros(1,M.num_vertices);
220 new2old_vflag(Mcut.elements+1) = 1;
221 new2old_vflag(Mcut.faces(3:6,:)+1) = 1;
222 new2old_vind = find(new2old_vflag==1);
223 Mcut.num_vertices = length(new2old_vind);
224 old2new_vind = zeros(1,M.num_vertices);
225 for i=1:length(new2old_vind);
226  old2new_vind(new2old_vind(i)) = i;
227 end;
228 
229 % 6. the new vertex, element and boundary list are condensed
230 Mcut.vertices = M.vertices(:,new2old_vind);
231 Mcut.elements = reshape(old2new_vind(Mcut.elements(:)+1),...
232  8,Mcut.num_elements)-1;
233 Mcf = Mcut.faces(3:6,:);
234 Mcut.faces(3:6,:) = reshape(old2new_vind(Mcf(:)+1),4,Mcut.num_faces)-1;
235 
236 if debug_
237  disp('halt before finishing routine');
238  keyboard;
239 end;
240 
241 
242 % TO BE ADJUSTED TO NEW SYNTAX
243 %| \docupdate