1 function Mcut = cut_alu3d_hexa(M,pmin,pmax,bndval)
2 %
function Mcut = cut_alu3d_hexa(M,pmin,pmax,bndval)
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
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
16 % Bernard Haasdonk 13.3.2006
20 % 1. search all elements with cog inside cube
for deletion
21 % compute cog of all elements
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;
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);
38 disp(
'halt after el_to_be_del detection')
42 % 2. mark boundary segments of to be deleted elements for deletion/
43 % generate new boundary
45 % generate list of all faces of to be deleted elements
46 % in ALUgrid notation 6 faces of 8 vertices:
57 disp('2. make boundary list of to be deleted elements');
58 fv_el_ind = [ 1 4 8 5 ...
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
70 disp('halt after setup of list of candidate boundary faces')
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
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:
84 disp('2. a) search boundaries to elements which are also to be deleted');
85 for facenr = 1:length(fv_ind_descr)
87 disp([num2str(facenr),'/',num2str(length(fv_ind_descr))]);
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;
104 disp('halt after detection of case 1 of boundary faces')
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');
113 vind = zeros(size(M.elements));
114 el_to_be_del_vind = M.elements(:,el_to_be_del_ind)+1;
116 for i = el_to_be_del_vind(:)'
119 disp([num2str(j),'/',num2str(length(el_to_be_del_vind))]);
121 fi = find(M.elements == (i-1));
124 cand_el_flag = max(vind);
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);
131 disp('halt after detection of surviving neighbour elements')
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));
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))]);
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);
155 fv_ind_descr(facenr) = 2;
157 face_to_be_insert_flag(ind_cand(ind)) = 1;
159 face_to_be_insert_ind = find(face_to_be_insert_flag==1);
162 disp('halt after detection of case 2 of boundary faces')
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))]);
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);
183 fv_ind_descr(facenr) = 3;
185 face_to_be_del_flag(ind_cand(ind)) = 1;
187 face_to_be_del_ind = find(face_to_be_del_flag==1);
190 disp('halt after detection of case 3 of boundary faces')
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!');
200 disp('3. c) generate new element, faces and vertices');
201 % 4. generate new element and face list
203 Mcut.elements = M.elements(:,find(el_to_be_del_flag==0));
204 Mcut.num_elements = size(Mcut.elements,2);
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)), ...
211 Mcut.num_faces = size(Mcut.faces,2);
214 disp('halt after setup of non-condensed result')
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;
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;
237 disp('halt before finishing routine');
242 % TO BE ADJUSTED TO NEW SYNTAX