rbmatlab 0.10.01
|
00001 classdef cubegrid < gridbase 00002 % A hierarchical cubegrid of arbitrary dimension 00003 % 00004 % This is an axis parallel hexaedral grid, with non-conform refinement 00005 % structure. All vertices are explicitly generated and stored. Only practical 00006 % for low dimensions, i.e. 1 to 4 or perhaps 5. 00007 00008 00009 properties 00010 dimension; % dimension of grid/number of coordinates per vertex 00011 00012 vertex; % 'vertex(i,j)' is the j-th coordinate of i-th vertex point 00013 00014 % 'vertexindex(id,j)' is the index of j-th vertex of element 'id' 00015 vertexindex; 00016 00017 level; % 'level(id)' equals refinement level of element 'id' 00018 00019 isleaf; % 'isleaf(id)' indicates, wether element 'id' is leaf or not 00020 00021 firstchild; % 'firstchild(id)' indicates the lowest-index of a child element 00022 00023 % number of refinement-steps, that have been performed on the grid so far 00024 refine_steps; 00025 00026 % 'creation_step(id)' stores the refinement step number that has led to the 00027 % element 'id'. 00028 creation_step; 00029 00030 end 00031 00032 methods 00033 00034 function grid= cubegrid(varargin) 00035 %function cubegrid(varargin) 00036 % constructor of a hierarchical cubegrid 00037 % 00038 % Preliminaries: 00039 % In the following 00040 % - 'gid' denotes global element indices, i.e. also covering non-leaf 00041 % elements, 00042 % - 'lid' denotes indices for leaf indices. 00043 % . 00044 % Conversion can be performed by 'gids = lid2gid(grid,lid)' 00045 % Conversion can be performed by 'lids = gid2lid(grid,gid)' 00046 % 00047 % The constructor has the following 00048 % Synopsis: 00049 % 00050 % - 'cubegrid()' : construction of a default cubegrid (2d unit square) 00051 % - 'cubegrid(cgrid)' : copy-constructor 00052 % - 'cubegrid(params)': generate cubegrid with certain options. The 00053 % argument 'params' requires the following fields: 00054 % -# 'range' : cell array of intervals, where the array lengths 00055 % determine the grid dimension 00056 % -# 'numintervals': vector with number of intervals per dimension 00057 % 00058 % perhaps later: constructor by duneDGF-file? 00059 % 00060 % generated fields of grid: 00061 % dimension : dimension of grid/number of coordinates per vertex 00062 % nelements : number of overall elements (leaf + nonleaf); 00063 % nvertices : number of vertices; 00064 % vertex : 'vertex(i,j) = 'j-th coordinate of 'i'-th vertex point 00065 % vertexindex : 'vertexindex(id,j) = ' index of 'j'-th vertex of element 'id' 00066 % level : 'level(id) = ' level, i.e. refinement steps of element id 00067 % isleaf : 'isleaf(id) = ' 0 or 1 whether element id is leaf or not 00068 % refine_steps : number of refinement-steps, that have been performed 00069 % on the grid so far 00070 % creation_step : 'creation_step(id) ' stores the refinement step number 00071 % that has led to the element 'id'. 00072 00073 % Bernard Haasdonk 1.3.2007 00074 00075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00076 % default constructor: unit square 00077 if (nargin==0) 00078 grid.dimension = 2; 00079 %range = {[0,1],[0,1]}; 00080 %numintervals = {1,1}; 00081 grid.nelements = 1; 00082 grid.nvertices = 4; 00083 % list of vertex vectors: rowwise coordinates 00084 % => vectex(i,j) : j-th coordinate of i-th vector 00085 grid.vertex = [0 1 0 1; ... 00086 0 0 1 1]'; 00087 % vertex-index vectors: i-th row contains indices of element i 00088 % element_vertices(i,j): index of j-th vertex of element i 00089 grid.vertexindex = [1 2 3 4]; 00090 grid.firstchild = 0; 00091 grid.level = zeros(grid.nelements,1); % everything level 0 by default 00092 grid.isleaf = ones(grid.nelements,1); % everything leaf by default 00093 grid.creation_step = zeros(grid.nelements,1); % 0 by default 00094 grid.refine_steps = 0; % initially set ref-counter to zero 00095 00096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00097 % copy constructor 00098 elseif isa(varargin{1},'cubegrid') 00099 grid= varargin{1}; 00100 00101 00102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00103 % construct from params 00104 else 00105 if isnumeric(varargin{1}) && size(varargin{1},1)==1 00106 partition = varargin{1}; 00107 % creat t partition 00108 params.numintervals = length(partition)-1; 00109 params.range = {partition([1,end])}; 00110 else 00111 partition = []; 00112 00113 params = varargin{1}; 00114 end 00115 grid.dimension = length(params.range); 00116 % abbreviation 00117 dim = grid.dimension; 00118 grid.nelements = prod(params.numintervals); 00119 grid.nvertices = prod(params.numintervals+1); 00120 00121 % generate vertices 00122 rangevec ={}; 00123 for i=1:dim 00124 ni = params.numintervals(i); 00125 ra = params.range{i}; 00126 rangevec{i} = (0:ni) * (ra(2) - ra(1)) / ni + ra(1); 00127 end; 00128 vi = cell(1,dim); 00129 if (dim > 1) 00130 [vi{:}] = ndgrid(rangevec{:}); 00131 else 00132 vi{1} = rangevec{1}; 00133 end; 00134 ve = zeros(grid.nvertices,0); 00135 for i=1:dim 00136 ve = [ve, vi{i}(:)]; 00137 end; 00138 grid.vertex = ve; 00139 00140 % generate element vertex index lists 00141 % list for first element is clear, others obtained by shifting 00142 % suitably: 00143 % 1D: [0, 1] 00144 % 2D: [0, 1, intervals(1)+1, intervals(1)+2] 00145 % 3D: [ 2D, 2D + (intervals(1)+1)*(intervals(2)+1)], 00146 % ... doubling plus npoints-product 00147 00148 ref_elem_indices = [0 1]; 00149 npoints = params.numintervals + 1; 00150 for i=2:dim 00151 ref_elem_indices = [ref_elem_indices, ... 00152 ref_elem_indices + prod(npoints(1:(i-1)))]; 00153 end; 00154 00155 % generate list of starting points 00156 % volume of starting indices: 00157 % generate vertices 00158 indexvec ={}; 00159 for i=1:dim 00160 indexvec{i} = 0:(params.numintervals(i)-1); 00161 end; 00162 vi = cell(1,dim); 00163 if dim > 1 00164 [vi{:}] = ndgrid(indexvec{:}); 00165 else 00166 vi{1} = indexvec{1}; 00167 end; 00168 % starting indices = 1+ vi{1} + npoints(1)*vi{2} + npoints(1)*npoints(2)*vi{3} 00169 ve = ones(grid.nelements,1); 00170 for i=1:dim 00171 ve = ve + prod(npoints(1:(i-1))) * vi{i}(:); 00172 end; 00173 00174 % for each starting point: attach shifted array 00175 grid.vertexindex = ... 00176 repmat(ve,1,length(ref_elem_indices)) + ... 00177 repmat(ref_elem_indices,length(ve),1); 00178 grid.firstchild = zeros(grid.nelements,1); 00179 00180 grid.level = zeros(grid.nelements,1); % everything level 0 by default 00181 grid.isleaf = ones(grid.nelements,1); % everything leaf by default 00182 grid.creation_step = zeros(grid.nelements,1); % 0 by default 00183 grid.refine_steps = 0; % initially set ref-counter to zero 00184 00185 if ~isempty(partition) 00186 grid.vertex(grid.vertexindex(1:end-1,2)) = partition(2:end-1); 00187 end 00188 00189 end 00190 00191 end 00192 00193 function [compress,new] = tpart_refine(this, lids, new_midpoints) 00194 % function [compress,new] = tpart_refine(this, lids, new_midpoints) 00195 % refines certain grid entities 00196 % 00197 % Parameters: 00198 % lids: ids of grid entities to be refined 00199 % new_midpoints: the newly created vertices of the refined grid. 00200 % 00201 % Return values: 00202 % compress: the ids of entities which are getting smaller due to the 00203 % refinement. 00204 % new: ids of the newly created elements 00205 00206 assert(this.dimension == 1); 00207 gids = lid2gid(this, lids); 00208 refine(this, lids); 00209 children = this.firstchild(gids); 00210 00211 if nargin == 3 && ~isempty(new_midpoints) 00212 this.vertex(this.vertexindex(children,2)) = new_midpoints; 00213 end 00214 compress = lids; 00215 new = [children,children+1]'; 00216 end 00217 00218 00219 res = check_consistency(grid); 00220 00221 leaf_element = coord2leaf_element(grid,coord); 00222 00223 demo(dummy); 00224 00225 display(grid); 00226 00227 ret = get(grid,propertyname, varargin); 00228 00229 [p0, p1] = get_edges(grid,gid); 00230 00231 gids = get_leafgids(grid); 00232 00233 range = get_ranges_of_element(grid, element); 00234 00235 vols = get_volume(grid,gids); 00236 00237 lids = gid2lid(grid,gids); 00238 00239 gids = lid2gid(grid,lids); 00240 00241 p = plot(grid,params); 00242 00243 p = plot_grid(grid,params); 00244 00245 p = plot_leafelement_data(grid,data,params); 00246 00247 p = plot_leafvertex_data(grid,data,params); 00248 00249 ngrid = refine(grid, lids); 00250 00251 ngrid = remove_duplicate_vertices(grid , epsilon ); 00252 00253 function gcopy=copy(grid) 00254 % a deep copy of the cubegrid 00255 % 00256 % return values: 00257 % gcopy: a deep copy of this instance also of type cubegrid. 00258 gcopy = cubegrid(grid); 00259 end 00260 00261 00262 end 00263 00264 methods ( Access = private ) 00265 00266 function gridtmp = gen_plot_data(grid) 00267 %function gridtmp = gen_plot_data(grid) 00268 % 00269 % Auxiliary function for 2d plotting. 00270 % generation of a structure gridtmp with fields 00271 % nelements, nvertices, nneigh, VI, X, Y, CX and CY representing 00272 % the leaf level of the grid 00273 % as these quantities are required by the common 2d grid plot routines. 00274 00275 % Bernard Haasdonk 9.5.2007 00276 00277 elid = get(grid,'leafelements'); 00278 00279 gridtmp = cubegrid(); 00280 00281 gridtmp.nelements = length(elid); 00282 gridtmp.nvertices = grid.nvertices; 00283 gridtmp.nneigh = 4; 00284 gridtmp.VI = grid.vertexindex(elid,[1 2 4 3]); 00285 gridtmp.X = grid.vertex(:,1); 00286 gridtmp.Y = grid.vertex(:,2); 00287 00288 % get X coordinates of vertices as vector 00289 XX = grid.vertex(gridtmp.VI(:),1); 00290 % reshape to matrix 00291 XX = reshape(XX,size(gridtmp.VI)); 00292 00293 % get Y coordinates of vertices as vector 00294 YY = grid.vertex(gridtmp.VI(:),2); 00295 % reshape to matrix 00296 YY = reshape(YY,size(gridtmp.VI)); 00297 00298 gridtmp.CX = mean(XX,2); 00299 gridtmp.CY = mean(YY,2); 00300 end 00301 00302 00303 end 00304 end 00305