rbmatlab 0.10.01
|
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