rbmatlab 0.10.01
grid/@cubegrid/refine.m
00001 function ngrid = refine(grid, lids)
00002 %function ngrid = refine(grid, lids)
00003 % refinement routine for cubegrid.
00004 %
00005 % Refinement rule is a simple division into `2^dim` smaller cubes After
00006 % refinement, a condensation of the vertex list is performed by
00007 % remove_duplicate_vetrices(), i.e. duplicate vertices generated during
00008 % refinement are removed.
00009 %
00010 % Parameters:
00011 % lids: List of leaf-element ids of the to-be-refined codim '0' entities.  Only
00012 %       leaf-elements can reasonably be refined, so do not pass global elements
00013 %       here, as internally a translation into global element ids is performed.
00014 %
00015 % Return values:
00016 %  ngrid: the refined grid
00017   
00018 % Bernard Haasdonk 1.3.2007  
00019   
00020 %  Make sure, that only leaf-elements are refined
00021   
00022   %  m = min(grid.isleaf(ids));
00023   %  if (m==0)
00024   %    error('Refinement of non-leaf entity is requested!');
00025   %  end;
00026     
00027   dim = grid.dimension;
00028   
00029   % get global ids
00030   gids = lid2gid(grid,lids);
00031 
00032   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00033   % set up refinement rule for elements:
00034   % for each dimension, a weight matrix is set up, which is later
00035   % multiplied to vertex coordinates
00036   % 1D: 3 child points:     ref_weights = [1.0,    0.5,   0.0 ; ... 
00037   %                                        0.0,    0.5    1.0];
00038   %     2 new elements:     ref_indices = [1, 2;     
00039   %                                        2, 3];
00040   % 2D  9 child points :    ref_weights = 
00041   %         [1.0,    0.5   0.0     0.5  0.25 0.5  0.0   0.0  0.0; ... 
00042   %          0.0,    0.5   1..0    0.0  0.25 0.5  0.0   0.0  0.0; ...
00043   %          0.0,    0.0,  0.0     0.5  0.25 0.5  1.0   0.5  0.0; ...
00044   %          0.0,    0.0,  0.0     0.0  0.25 0.5  0.0   0.5  1.0]
00045   %     4 new elements (doppelt so viele wie bei 1D weniger) 
00046   %              ref_indices = [1 2 4 5 ; ...
00047   %                             2 3 5 6 ; ...
00048   %                             4 5 7 8 ; ...
00049   %                             5 6 8 9 ];
00050 
00051   % Rekursiver Aufbau der weights:   
00052   % OD: ref_weights[0] = [1.0]
00053   % 1D: ref_weights[1] = [ref_weights[0] ,   0.5*rw[0] ;    0.0...
00054   %                              0.0         0.5*rw[0] ,   rw[0] ]
00055   % analog weiter :-)
00056   
00057   rw = ones(1,1);
00058   for i=1:dim;
00059     rw = [rw,                0.5*rw,  zeros(size(rw)); ...
00060           zeros(size(rw)),   0.5*rw,       rw        ];
00061   end;
00062   ref_weights = rw;
00063   
00064   % rekursiver Aufbau der indizes:
00065   %     shift = 3^(dim-1)
00066   % ri = [ ri, ri+ shift ; ...
00067   %        ri+shift, ri + 2*shift]; 
00068   %
00069   ri = ones(1,1);
00070   for i = 1:dim;
00071     shift = 3^(i-1);
00072     ri = [ri, ri + shift; ...
00073           ri+shift, ri+2*shift];
00074   end;
00075   ref_indices = ri;
00076   
00077   % generate new points after refinement:  
00078   % all 3^dim points in all to-be-refined elements
00079   
00080   new_vertex = zeros(0,dim);
00081   % generate new elements after refinement
00082   new_vertexindex = zeros(0,2^dim);
00083   new_level = [];
00084   new_firstchild = [];
00085   gids_firstchild = grid.nelements(1)+2^dim*(0:length(gids)-1)+1;
00086   
00087   for i = gids';
00088     co = grid.vertex(grid.vertexindex(i,:),:); % glob vertex coords as rows
00089     vid_offset = size(new_vertex,1) + size(grid.vertex,1);
00090     new_vertex = [new_vertex; ref_weights' * co]; 
00091     new_firstchild = [new_firstchild; zeros(2^dim,1)];
00092     new_vertexindex = [new_vertexindex; ref_indices + vid_offset];    
00093     new_level = [new_level; ones(2^dim,1)*grid.level(i)+ 1];
00094   end;
00095   
00096   % now consistent list is obtained, but vertices might be duplicated.
00097   grid.vertex = [grid.vertex; new_vertex];
00098   grid.vertexindex = [grid.vertexindex; new_vertexindex];
00099   grid.firstchild = [grid.firstchild; new_firstchild];
00100   grid.firstchild(gids) = gids_firstchild;
00101   grid.nelements = size(grid.vertexindex,1);
00102   grid.nvertices = size(grid.vertex,1); 
00103   grid.level = [grid.level(:); new_level];
00104   grid.isleaf = [grid.isleaf(:); ones(length(new_level),1)];
00105   % set refined elements to non-leaf
00106   grid.isleaf(gids) = 0; 
00107   
00108   % increase ref-counter 
00109   grid.refine_steps = grid.refine_steps + 1; 
00110   
00111   grid.creation_step = [grid.creation_step(:); ...
00112                     grid.refine_steps*ones(length(new_level),1)];
00113     
00114   ngrid = remove_duplicate_vertices(grid,1e-20);  
00115 %  ngrid = grid;
00116 
00117   if ~check_consistency(ngrid)
00118     disp('problem in duplicate elimination, keeping duplicate vertices!')
00119     ngrid = grid;
00120   end;
00121 
00122 end
00123 
All Classes Namespaces Files Functions Variables