function meshdemo % Define a simple mesh on a square domain. p = [0,0; 1,0; 0,1; 1,1; 0.5,0.5]; t = [1,2,5; 2,4,5; 4,3,5; 3,1,5]; be = [1,2; 2,4; 4,3; 3,1]; % Draw this simple mesh. plotmesh(1,p,be,t,'Initial mesh'); % Refine the mesh twice and draw the new mesh. for i=1:2 [p,be,t] = refine(p,be,t); end plotmesh(2,p,be,t,'Final mesh'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Draw the mesh % Inputs: % n_fig -- id of drawing window % p,be,t -- mesh data % titletext -- title of this plot %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function plotmesh(n_fig, p,be,t,titletext) figure(n_fig); clf; hold on; % draw all edges in blue for i=1:size(t,1); plot(p(t(i,:),1),p(t(i,:),2),'b'); end % draw boundary edge in red for i = 1:size(be,1); ind = be(i,:); plot(p(ind,1),p(ind,2),'r'); end hold off,axis equal,axis off title(titletext); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Refine the mesh uniformly % Inputs: % p,be,t -- original mesh % Outputs: % P,BE,T -- refined mesh %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [P, BE, T] = refine(p,be,t) % number of points, triangles, boundary edges, and edges np = size(p,1); nt = size(t,1); nbe = size(be,1); ne = (3*nt + nbe)/2; % Since we only have information about boundary edges, % here we need to reconstruct edges (including internal ones). % Notice that edges can be understood as the adjacency relation % of vertices, we first build the vertex adjacency table. % Here we also use the concept of "half edge". % A "half edge" is an edge in a triangle associated with the % positive (counter-clockwise) direction in this triangle. % Each internal edge can be viewed as two "half edges" pointing at % opposite directions, from the two triangles sharing this edge. % Each boundary edge has only one "half edge". % % p2p_adjacency_table: % If the (i,j)th entry of this table is 1, % then there is a "half edge" from the ith to the jth vertices. % If both (i,j) and (j,i) are 1, then this is an internal edge. % Otherwise, it is a boundary edge. % % e2t_table: % When the (i,j)th entry of p2p_adjacency_table is 1, % the (i,j)th entry of e2t_table stores the index % of the triangle where this "half edge" is defined. % p2p_adjacency_table = sparse (np, np); e2t_table =sparse(np, np); for i = 1:nt for j = 1:3 row = t(i,j); col = t(i,mod(j,3)+1); p2p_adjacency_table (row, col) = 1; e2t_table (row, col) = i; end end % Once we have p2p_adjacency_table and e2t_table, % we can build the edge table e, which is a ne-by-5 matrix. % Each row corresponds to one edge (internal and boundary). % For internal edges, we need to combine the two "half edges" % into one edge. For each edge, we need to specify % its starting and ending vertices. This is done by simply % chosing the starting vertex to be the vertex with a % smaller index. Notice this may give a direction different from % direction specified in the matrix be (boundary edges). % % Each row of matrix e contains 5 elements % in the following order: % starting_vertex_index : always the smaller index % ending_vertex_index : always the larger index % is_boundary_edge : =1 if this edge is on boundary % left_triangle_index : index of the left triangle % right_triangle_index : index of the right triangle % % For boundary edges, either left_triangle_index or % right_triangle_index is 0. e = zeros(ne,5); edgeindex = 1; for i = 1:np for j=(i+1):np adjacency = p2p_adjacency_table (i,j) + p2p_adjacency_table (j,i); if ( adjacency ~= 0 ) e(edgeindex, 1:2) = [i,j]; % Mark boundary edges if ( adjacency == 1 ) e(edgeindex, 3) = 1; end e(edgeindex, 4) = e2t_table (i,j); e(edgeindex, 5) = e2t_table (j,i); edgeindex = edgeindex + 1; end end end % Generate triangle-to-edge table t2e_table. % Each row of this table stores the index of three edges % in a triangle. t2e_table = zeros(nt,3); for i=1:ne if (e(i,4)>0) t2e_table ( e(i,4), find(t(e(i,4),:)==e(i,1)) ) = i; end if (e(i,5)>0) t2e_table ( e(i,5), find(t(e(i,5),:)==e(i,2)) ) = i; end end % Now we are ready to build the refined mesh P,BE,T. nP = np + ne; nT = 4*nt; nBE = 2*nbe; P = zeros(nP,2); T = zeros(nT,3); BE = zeros(nBE,2); % Generate P % P contains all original points in p % and center points of each edge in e P(1:np,:) = p; for i=1:ne P(np+i,:) = sum (p(e(i,1:2),:))*0.5; end % Generate BE % BE inherits the orientation of be. for i=1:nbe j = 1; while max( e(j,1:3) ~= [min(be(i,:)), max(be(i,:)), 1] ) j = j+1; end BE([2*i-1, 2*i], :) = [be(i,1), np+j; np+j, be(i,2)]; end % Generate T % Each triangle in t is divided into 4 small triangles for i=1:nt temp = [t(i,:), np+t2e_table(i,:)]; T((4*i-3):(4*i), :) = [ temp(1), temp(4), temp(6); temp(2), temp(5), temp(4); temp(3), temp(6), temp(5); temp(4), temp(5), temp(6)]; end

