2 % A hierarchical
cubegrid of arbitrary dimension
4 % This is an axis parallel hexaedral grid, with non-conform refinement
5 % structure. All vertices are explicitly generated and stored. Only practical
6 %
for low dimensions, i.e. 1 to 4 or perhaps 5.
10 dimension; % dimension of grid/number of coordinates per vertex
12 vertex; %
'vertex(i,j)' is the j-th coordinate of i-th vertex point
14 %
'vertexindex(id,j)' is the index of j-th vertex of element
'id'
17 level; %
'level(id)' equals refinement level of element
'id'
19 isleaf; %
'isleaf(id)' indicates, wether element
'id' is
leaf or not
21 firstchild; %
'firstchild(id)' indicates the lowest-index of a child element
23 % number of refinement-steps, that have been performed on the grid so far
26 %
'creation_step(id)' stores the refinement step number that has led to the
36 % constructor of a hierarchical
cubegrid
40 % -
'gid' denotes global element indices, i.e. also covering non-
leaf
42 % -
'lid' denotes indices
for leaf indices.
44 % Conversion can be performed by
'gids = lid2gid(grid,lid)'
45 % Conversion can be performed by
'lids = gid2lid(grid,gid)'
47 % The constructor has the following
50 % -
'cubegrid()' : construction of a
default cubegrid (2d unit square)
51 % -
'cubegrid(cgrid)' : copy-constructor
52 % -
'cubegrid(params)': generate
cubegrid with certain options. The
53 % argument
'params' requires the following fields:
54 % -#
'range' : cell array of intervals, where the array lengths
55 % determine the grid dimension
56 % -#
'numintervals': vector with number of intervals per dimension
58 % perhaps later: constructor by duneDGF-file?
60 % generated fields of grid:
61 % dimension : dimension of grid/number of coordinates per vertex
62 % nelements : number of overall elements (
leaf + nonleaf);
63 % nvertices : number of vertices;
64 % vertex :
'vertex(i,j) = 'j-th coordinate of
'i'-th vertex point
65 % vertexindex :
'vertexindex(id,j) = ' index of
'j'-th vertex of element
'id'
66 % level :
'level(id) = ' level, i.e. refinement steps of element
id
67 % isleaf :
'isleaf(id) = ' 0 or 1 whether element
id is
leaf or not
68 % refine_steps : number of refinement-steps, that have been performed
70 % creation_step :
'creation_step(id) ' stores the refinement step number
71 % that has led to the element
'id'.
73 % Bernard Haasdonk 1.3.2007
75 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76 %
default constructor: unit square
79 %range = {[0,1],[0,1]};
80 %numintervals = {1,1};
83 % list of vertex vectors: rowwise coordinates
84 % => vectex(i,j) : j-th coordinate of i-th vector
85 grid.vertex = [0 1 0 1; ...
87 % vertex-index vectors: i-th row contains indices of element i
88 % element_vertices(i,j): index of j-th vertex of element i
89 grid.vertexindex = [1 2 3 4];
91 grid.level = zeros(grid.nelements,1); % everything level 0 by default
92 grid.isleaf = ones(grid.nelements,1); % everything leaf by default
93 grid.creation_step = zeros(grid.nelements,1); % 0 by default
94 grid.refine_steps = 0; % initially set ref-counter to zero
96 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103 % construct from params
105 if isnumeric(varargin{1}) && size(varargin{1},1)==1
106 partition = varargin{1};
108 params.numintervals = length(partition)-1;
109 params.range = {partition([1,end])};
113 params = varargin{1};
115 grid.dimension = length(params.range);
117 dim = grid.dimension;
118 grid.nelements = prod(params.numintervals);
119 grid.nvertices = prod(params.numintervals+1);
124 ni = params.numintervals(i);
125 ra = params.range{i};
126 rangevec{i} = (0:ni) * (ra(2) - ra(1)) / ni + ra(1);
130 [vi{:}] = ndgrid(rangevec{:});
134 ve = zeros(grid.nvertices,0);
140 % generate element vertex index lists
141 % list for first element is clear, others obtained by shifting
144 % 2D: [0, 1, intervals(1)+1, intervals(1)+2]
145 % 3D: [ 2D, 2D + (intervals(1)+1)*(intervals(2)+1)],
146 % ... doubling plus npoints-product
148 ref_elem_indices = [0 1];
149 npoints = params.numintervals + 1;
151 ref_elem_indices = [ref_elem_indices, ...
152 ref_elem_indices + prod(npoints(1:(i-1)))];
155 % generate list of starting points
156 % volume of starting indices:
160 indexvec{i} = 0:(params.numintervals(i)-1);
164 [vi{:}] = ndgrid(indexvec{:});
168 % starting indices = 1+ vi{1} + npoints(1)*vi{2} + npoints(1)*npoints(2)*vi{3}
169 ve = ones(grid.nelements,1);
171 ve = ve + prod(npoints(1:(i-1))) * vi{i}(:);
174 % for each starting point: attach shifted array
175 grid.vertexindex = ...
176 repmat(ve,1,length(ref_elem_indices)) + ...
177 repmat(ref_elem_indices,length(ve),1);
178 grid.firstchild = zeros(grid.nelements,1);
180 grid.level = zeros(grid.nelements,1); % everything level 0 by default
181 grid.isleaf = ones(grid.nelements,1); % everything leaf by default
182 grid.creation_step = zeros(grid.nelements,1); % 0 by default
183 grid.refine_steps = 0; % initially set ref-counter to zero
185 if ~isempty(partition)
186 grid.vertex(grid.vertexindex(1:end-1,2)) = partition(2:end-1);
193 function [compress,new] = tpart_refine(this, lids, new_midpoints)
194 % function [compress,new] = tpart_refine(this, lids, new_midpoints)
195 % refines certain grid entities
198 % lids: ids of grid entities to be refined
199 % new_midpoints: the newly created vertices of the refined grid.
202 % compress: the ids of entities which are getting smaller due to the
204 % new: ids of the newly created elements
206 assert(this.dimension == 1);
207 gids = lid2gid(this, lids);
209 children = this.firstchild(gids);
211 if nargin == 3 && ~isempty(new_midpoints)
212 this.vertex(this.vertexindex(children,2)) = new_midpoints;
215 new = [children,children+1]';
219 res = check_consistency(grid);
221 leaf_element = coord2leaf_element(grid,coord);
227 ret =
get(grid,propertyname, varargin);
229 [p0, p1] = get_edges(grid,gid);
231 gids = get_leafgids(grid);
233 range = get_ranges_of_element(grid, element);
235 vols = get_volume(grid,gids);
237 lids = gid2lid(grid,gids);
239 gids = lid2gid(grid,lids);
241 p = plot(grid,params);
243 p = plot_grid(grid,params);
245 p = plot_leafelement_data(grid,data,params);
247 p = plot_leafvertex_data(grid,data,params);
249 ngrid = refine(grid, lids);
251 ngrid = remove_duplicate_vertices(grid , epsilon );
253 function gcopy=copy(grid)
257 % gcopy: a deep copy of
this instance also of type
cubegrid.
264 methods ( Access =
private )
266 function gridtmp = gen_plot_data(grid)
267 %function gridtmp = gen_plot_data(grid)
269 % Auxiliary function for 2d plotting.
270 % generation of a structure gridtmp with fields
271 % nelements, nvertices, nneigh, VI, X, Y, CX and CY representing
273 % as these quantities are required by the common 2d grid plot routines.
275 % Bernard Haasdonk 9.5.2007
277 elid = get(grid,'leafelements');
281 gridtmp.nelements = length(elid);
282 gridtmp.nvertices = grid.nvertices;
284 gridtmp.VI = grid.vertexindex(elid,[1 2 4 3]);
285 gridtmp.X = grid.vertex(:,1);
286 gridtmp.Y = grid.vertex(:,2);
288 % get X coordinates of vertices as vector
289 XX = grid.vertex(gridtmp.VI(:),1);
291 XX = reshape(XX,size(gridtmp.VI));
293 % get Y coordinates of vertices as vector
294 YY = grid.vertex(gridtmp.VI(:),2);
296 YY = reshape(YY,size(gridtmp.VI));
298 gridtmp.CX = mean(XX,2);
299 gridtmp.CY = mean(YY,2);
A hierarchical cubegrid of arbitrary dimension.
Base class for all grid classes.