rbmatlab  1.13.10
 All Classes Namespaces Files Functions Variables Groups Pages
refine.m
1 function ngrid = refine(grid, lids)
2 %function ngrid = refine(grid, lids)
3 % refinement routine for cubegrid.
4 %
5 % Refinement rule is a simple division into `2^dim` smaller cubes After
6 % refinement, a condensation of the vertex list is performed by
7 % remove_duplicate_vetrices(), i.e. duplicate vertices generated during
8 % refinement are removed.
9 %
10 % Parameters:
11 % lids: List of leaf-element ids of the to-be-refined codim '0' entities. Only
12 % leaf-elements can reasonably be refined, so do not pass global elements
13 % here, as internally a translation into global element ids is performed.
14 %
15 % Return values:
16 % ngrid: the refined grid
17 
18 % Bernard Haasdonk 1.3.2007
19 
20 % Make sure, that only leaf-elements are refined
21 
22  % m = min(grid.isleaf(ids));
23  % if (m==0)
24  % error('Refinement of non-leaf entity is requested!');
25  % end;
26 
27  dim = grid.dimension;
28 
29  % get global ids
30  gids = lid2gid(grid,lids);
31 
32  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33  % set up refinement rule for elements:
34  % for each dimension, a weight matrix is set up, which is later
35  % multiplied to vertex coordinates
36  % 1D: 3 child points: ref_weights = [1.0, 0.5, 0.0 ; ...
37  % 0.0, 0.5 1.0];
38  % 2 new elements: ref_indices = [1, 2;
39  % 2, 3];
40  % 2D 9 child points : ref_weights =
41  % [1.0, 0.5 0.0 0.5 0.25 0.5 0.0 0.0 0.0; ...
42  % 0.0, 0.5 1..0 0.0 0.25 0.5 0.0 0.0 0.0; ...
43  % 0.0, 0.0, 0.0 0.5 0.25 0.5 1.0 0.5 0.0; ...
44  % 0.0, 0.0, 0.0 0.0 0.25 0.5 0.0 0.5 1.0]
45  % 4 new elements (doppelt so viele wie bei 1D weniger)
46  % ref_indices = [1 2 4 5 ; ...
47  % 2 3 5 6 ; ...
48  % 4 5 7 8 ; ...
49  % 5 6 8 9 ];
50 
51  % Rekursiver Aufbau der weights:
52  % OD: ref_weights[0] = [1.0]
53  % 1D: ref_weights[1] = [ref_weights[0] , 0.5*rw[0] ; 0.0...
54  % 0.0 0.5*rw[0] , rw[0] ]
55  % analog weiter :-)
56 
57  rw = ones(1,1);
58  for i=1:dim;
59  rw = [rw, 0.5*rw, zeros(size(rw)); ...
60  zeros(size(rw)), 0.5*rw, rw ];
61  end;
62  ref_weights = rw;
63 
64  % rekursiver Aufbau der indizes:
65  % shift = 3^(dim-1)
66  % ri = [ ri, ri+ shift ; ...
67  % ri+shift, ri + 2*shift];
68  %
69  ri = ones(1,1);
70  for i = 1:dim;
71  shift = 3^(i-1);
72  ri = [ri, ri + shift; ...
73  ri+shift, ri+2*shift];
74  end;
75  ref_indices = ri;
76 
77  % generate new points after refinement:
78  % all 3^dim points in all to-be-refined elements
79 
80  new_vertex = zeros(0,dim);
81  % generate new elements after refinement
82  new_vertexindex = zeros(0,2^dim);
83  new_level = [];
84  new_firstchild = [];
85  gids_firstchild = grid.nelements(1)+2^dim*(0:length(gids)-1)+1;
86 
87  for i = gids';
88  co = grid.vertex(grid.vertexindex(i,:),:); % glob vertex coords as rows
89  vid_offset = size(new_vertex,1) + size(grid.vertex,1);
90  new_vertex = [new_vertex; ref_weights' * co];
91  new_firstchild = [new_firstchild; zeros(2^dim,1)];
92  new_vertexindex = [new_vertexindex; ref_indices + vid_offset];
93  new_level = [new_level; ones(2^dim,1)*grid.level(i)+ 1];
94  end;
95 
96  % now consistent list is obtained, but vertices might be duplicated.
97  grid.vertex = [grid.vertex; new_vertex];
98  grid.vertexindex = [grid.vertexindex; new_vertexindex];
99  grid.firstchild = [grid.firstchild; new_firstchild];
100  grid.firstchild(gids) = gids_firstchild;
101  grid.nelements = size(grid.vertexindex,1);
102  grid.nvertices = size(grid.vertex,1);
103  grid.level = [grid.level(:); new_level];
104  grid.isleaf = [grid.isleaf(:); ones(length(new_level),1)];
105  % set refined elements to non-leaf
106  grid.isleaf(gids) = 0;
107 
108  % increase ref-counter
109  grid.refine_steps = grid.refine_steps + 1;
110 
111  grid.creation_step = [grid.creation_step(:); ...
112  grid.refine_steps*ones(length(new_level),1)];
113 
114  ngrid = remove_duplicate_vertices(grid,1e-20);
115 % ngrid = grid;
116 
117  if ~check_consistency(ngrid)
118  disp('problem in duplicate elimination, keeping duplicate vertices!')
119  ngrid = grid;
120  end;
121 
122 end
123