2 % A triangular conforming grid in two dimensions.
4 % General geometrical information is stored including neighbour
5 % information. Therefore also boundary neighbour relations can be
6 % specified. Boundary edges can be marked by
"painting rectangles": the
7 % edges with midpoints within such a rectangle are marked accordingly.
8 % By
this boundary edges can be marked
for later special use. Much
9 % (partially redundant) information is stored in the grid, which might be
10 % useful in simulations.
13 % number of interior edges
16 % number of boundary edges
24 % constructor of a triangular conform grid in 2 dimensions with following
28 % loaded from file, -1 as outer neighbour indices)
31 % -# the field grid_initfile is existent in params. Then the file is read
32 % and a pointlist p and a triangle. Procedure is then executing the
33 % following constructor
34 % -# a structured equidistant triangle grid is generated
35 % -
'params.xnumintervals' : number of elements along x directions
36 % -
'params.ynumintervals' : number of elements along y directions
37 % -
'params.xrange,yrange' : intervals covered along the axes
39 % with the optional fields
40 % -
'params.bnd_rect_corner1' : coordinates of lower corner of to
41 % be marked boundaries
42 % -
'params.bnd_rect_corner2' : coordinates of upper corner of to
43 % be marked boundaries
44 % -
'params.bnd_rect_index': integer index to be set on the edges
45 % in the above defined rectangle. Should not be positive integer
46 % in the range of the number of elements. use negative indices for
47 % certain later discrimination.
49 % For the last three optional boundary settings, also multiple
50 % rectangles can be straightforwardly defined by accepting matrix
51 % of columnwise corners1, corners2 and a vector of indices for the
52 % different rectangles.
54 % triangle-data with certain options.
55 % - p is assumed to be a 2 x npoints matrix with coordinates
56 % - t is assumed to be a XX x ntriangles matrix, but only first three
57 % rows are used == vertex indices, in clockwise order as default, all
58 % nondefined edges are set to -1, then the following
"rectangles" are
59 % set as specified in params
61 % Using this class, grids from PDETOOLS can be used:
64 % %%% => generate your grid and export
'p' and
't' to MATLAB workspace
66 % save(
'mygrid',
'p',
't')
67 % grid =
triagrid(struct(
'grid_initfile',
'mygrid'));
70 % perhaps later: constructor by duneDGF-file?
71 % perhaps later: contructor-flag: full vs non-full
72 % => only compute redundant information if required.
75 % 'varargin' : variable number of input arguments, see above for description
76 % of possible configurations.
79 % 'grid' : generated triagrid
81 % generated fields of grid:
82 % nelements: number of elements
83 % nvertices: number of vertices
85 % A : vector of element area
86 % Ainv : vector of inverted element area
87 % X : vector of vertex x-coordinates
88 % Y : vector of vertex y-coordinates
89 % VI : matrix of vertex indices: 'VI(i,j)' is the global index of j-th
91 % CX : vector of centroid x-values
92 % CY : vector of centroid y-values
93 % NBI : 'NBI(i,j) = ' element index of j-th neighbour of element i
94 % boundary faces are set to -1 or negative values are requested by
95 % 'params.boundary_type'
96 % INB : 'INB(i,j) = ' local edge number in 'NBI(i,j)' leading from
97 % element 'NBI(i,j)' to element 'i', i.e. satisfying
98 % 'NBI(NBI(i,j), INB(i,j)) = i'
99 % EL : 'EL(i,j) = ' length of edge from element 'i' to neighbour 'j'
100 % DC : 'DC(i,j) = ' distance from centroid of element i to NB j
101 % for boundary elements, this is the distance to the reflected
102 % element (for use in boundary treatment)
103 % NX : 'NX(i,j) = ' x-coordinate of unit outer normal of edge from el
105 % NY : 'NY(i,j) = ' y-coordinate of unit outer normal of edge from el
107 % ECX : 'ECX(i,j) = ' x-coordinate of midpoint of edge from el 'i' to NB 'j'
108 % ECY : 'ECY(i,j) = ' y-coordinate of midpoint of edge from el 'i' to NB 'j'
109 % SX : vector of x-coordinates of point `S_i` (for rect: identical to
111 % SY : vector of y-coordinate of point `S_j` (for rect: identical to
113 % ESX : 'ESX(i,j) = ' x-coordinate of point `S_{ij}` on edge el i to NB j
114 % ESY :
'ESY(i,j) = ' y-coordinate of point `S_{ij}` on edge el i to NB j
115 % DS :
'DS(i,j) = ' distance from `S_i` of element i to `S_j` of NB j
116 %
for boundary elements,
this is the distance to the reflected
117 % element (
for use in boundary treatment)
118 % hmin : minimal element-diameter
119 % alpha: geometry bound (simultaneously satisfying `\alpha \cdot h_i^d
120 % \leq A(T_i)`, `\alpha \cdot \mbox{diam}(T_i) \leq h_i^{d-1}` and
121 % `\alpha \cdot h_i \leq `dist(midpoint `i` to any neigbour) )
122 % JIT : Jacobian inverse transposed 'JIT(i,:,:)' is a 2x2-matrix of the Jac.
123 % Inv. Tr. on element 'i'
125 % \note for diffusion-discretization with FV-schemes, points `S_i` must exist,
126 % such that `S_i S_j` is perpendicular to edge 'i j', the intersection points
127 % are denoted `S_{ij}`
130 % Bernard Haasdonk 9.5.2007
132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 if (nargin==1) & isa(varargin{1},
'triagrid')
137 fnames = fieldnames(varargin{1});
138 for i=1:length(fnames)
139 grid.(fnames{i}) = varargin{1}.(fnames{i});
144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145 %
default constructor: unit square
147 % p = [0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.5 1.0; ...
148 % 0.0 0.0 0.0 0.5 0.5 0.5 1.0 1.0 1.0 ];
149 % t = [1 2 2 3 4 5 5 6; ...
150 % 2 5 3 6 5 8 6 9; ...
155 % mark boundary in rectangle from [-1,-1] to [+2,+2] with index -1
156 params.bnd_rect_corner1 = [-1,-1]';
157 params.bnd_rect_corner2 = [2 2]
';
158 params.bnd_rect_index = [-1];
160 params = varargin{1};
161 if isfield(params,'grid_initfile
')
162 [~, ~, ext] = fileparts(params.grid_initfile);
165 tmp = load(params.grid_initfile);
169 [p, t] = triagrid.read_msh(params.grid_initfile);
171 error('File name extension not supported in grid initialization
');
174 nx = params.xnumintervals;
175 ny = params.ynumintervals;
176 nvertices =(nx+1)*(ny+1);
178 dx = (params.xrange(2)-params.xrange(1))/nx;
179 dy = (params.yrange(2)-params.yrange(1))/ny;
181 % set vertex coordinates
182 vind = (1:(nx+1)*(ny+1));
183 X = mod(vind-1,nx+1) * dx + params.xrange(1);
184 Y = floor((vind-1)/(nx+1))*dy + params.yrange(1);
187 % identify triangles:
193 all_ind = 1:(nx+1)*(ny+1);
194 % index vector of lower left corners, i.e. not last col/row
195 lc_ind = find((mod(all_ind,nx+1)~=0) & (all_ind < (nx+1)*ny));
196 t1 = [lc_ind;lc_ind+1;lc_ind+2+nx]; % lower triangles
197 t2 = [lc_ind;lc_ind+nx+2;lc_ind+nx+1]; % upper triangles
200 else % read p-e-t information from varargin
206 params = varargin{3};
209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 % construct from p,t and params
216 % nx = params.xnumintervals;
217 % ny = params.ynumintervals;
219 grid.nelements = size(t,2);
220 grid.nvertices = size(p,2);
223 % set vertex coordinates
227 % set element vertex indices: numbering counterclockwise
228 % counterclockwise, edge j connects vertex j and j+1
232 %
get areas of grid-cells after VI and X,Y are available
234 % A(a b c) = 0.5 |Det ((b-a) (c-a)) |
235 grid.A = abs(area_triangle(...
236 [grid.X(grid.VI(:,1)), ...
237 grid.Y(grid.VI(:,1))], ...
238 [grid.X(grid.VI(:,2)), ...
239 grid.Y(grid.VI(:,2))], ...
240 [grid.X(grid.VI(:,3)), ...
241 grid.Y(grid.VI(:,3))]));
243 % a11 = grid.X(grid.VI(:,2))-grid.X(grid.VI(:,1));
244 % a21 = grid.Y(grid.VI(:,2))-grid.Y(grid.VI(:,1));
245 % a12 = grid.X(grid.VI(:,3))-grid.X(grid.VI(:,1));
246 % a22 = grid.Y(grid.VI(:,3))-grid.Y(grid.VI(:,1));
247 % grid.A = 0.5 * (a11.*a22 - a21.*a12);
248 grid.Ainv = grid.A.^(-1);
250 % midpoint coordinates of grid-cells
251 % equals cog of corners
253 % coordinates of vertices: XX(elnum, vnum)
254 XX = reshape(grid.X(grid.VI(:)),size(grid.VI));
255 YY = reshape(grid.Y(grid.VI(:)),size(grid.VI));
256 grid.CX = mean(XX,2);
257 grid.CY = mean(YY,2);
259 % edge-vectors: [DX(el,edge) DX (el,edge)]
260 DX = [XX(:,2:3), XX(:,1)] - XX;
261 DY = [YY(:,2:3), YY(:,1)] - YY;
263 % matrix with edge-lengths
264 grid.EL = sqrt(DX.^2 + DY.^2);
266 % matrix with (unit) normal components
267 grid.NX = grid.EL.^(-1) .* DY;
268 grid.NY = - grid.EL.^(-1) .* DX;
270 % matrix with edge-midpoint-coordinates
271 % this computation yields epsilon-differing edge-midpoints on
272 % neighbouring elements, perhaps solve later.
273 grid.ECX = XX + DX * 0.5;
274 grid.ECY = YY + DY * 0.5;
276 %%% determine indices of neighbouring elements, default: -1
277 NBI = -1 * ones(grid.nelements, grid.nneigh);
278 INB = zeros(grid.nelements, grid.nneigh);
279 % and now it gets complicated...
281 % setup edge list e(1,i), e(2,i) are the point indices of the i-th edge
282 % eid(i) is the element number, which has the edge
283 % led(i) : local edge number, which is the edge
285 ee = zeros(2,grid.nelements*3);
286 % li = [1 2 2 3 3 1 4 5 5 6 6 4 ... ]
287 li = 1:grid.nelements*3;
289 li = reshape(li,6,grid.nelements);
290 li = [li(2:end,:); li(1,:)];
291 li = reshape(li,2,grid.nelements*3);
293 ee = sort(ee); % now smallest vindex above
294 elid = repmat(1:grid.nelements,3,1);
296 led = repmat((1:3)',1,grid.nelements);
299 % generate sort key from both indices
300 key = ee(1,:) + grid.nvertices * ee(2,:);
301 [keysort, ind] = sort(key);
303 elid_sort = elid(ind);
306 % find indices of duplicates by simple forward difference
307 % => these are inner edges!
309 diff = keysort(1:end-1) - [keysort(2:end)];
310 inner_edges = find(diff==0);
312 % prepare entries in NBI: for all i in inner_edges
313 % NBI(elid_sort(i),led_sort(i)) = elid_sort(i+1);
314 % INB(elid_sort(i),led_sort(i)) = led_sort(i+1);
317 li = sub2ind(size(NBI),...
318 elid_sort(inner_edges),...
319 led_sort(inner_edges));
320 NBI(li) = elid_sort(inner_edges+1);
321 INB(li) = led_sort(inner_edges+1);
322 li = sub2ind(size(NBI),...
323 elid_sort(inner_edges+1),...
324 led_sort(inner_edges+1));
325 NBI(li) = elid_sort(inner_edges);
326 INB(li) = led_sort(inner_edges);
328 % % find all element-pairs, which have a common edge
329 % % i.e. neighs(i,1) and neighs(i,2) are two elements, which
330 % % have the same edge i, where this edge is the
331 % % eind(i,1)-th edge (1..3) in the first element
332 % % eind(i,2)-th edge (1..3) in the first element
334 % nedges = max(t(:));
335 % ehist = hist(t(:),1:nedges);
337 % error('edge occuring in more than 2 triangles!!');
339 % inner_edges = find(ehist==2);
340 % neighs = zeros(length(inner_edges),2);
341 % eind = zeros(length(inner_edges),2);
343 % % somehow map edge-numbers => triangle numbers
344 % % need two of them, as occasionally global and local edge numbers
346 % % edgemap1(i,locedgenum) = elementno if edge i is local edge in elementno
347 % % edgemap2(i,locedgenum) = elementno if edge i is local edge in elementno
349 % edgemap1 = nan * ones(nedges,grid.nneigh);%
351 % [locedgenum,triangnum] = ind2sub(size(t),1:length(t(:)));
352 % li = sub2ind(size(edgemap1),t(:),locedgenum(:));
353 % edgemap1(li) = triangnum; % here due to duplicates, only the last
356 % % remove these entries from t and repeat for 2nd edgemap
358 % [edgenum,locedgenum] = find(~isnan(edgemap1));
359 % li = sub2ind(size(edgemap1),edgenum(:),locedgenum(:));
361 % li2 = sub2ind(size(t2),locedgenum(:),edgemap1(li));
365 % edgemap2 = nan * ones(nedges,grid.nneigh);
366 % nonzeros = find(t2~=0);
368 % [locedgenum,triangnum] = ind2sub(size(t2),1:length(nonzeros));
369 % li = sub2ind(size(edgemap2),t2(nonzeros),locedgenum(:));
370 % edgemap2(li) = triangnum;
371 % % now together edgemap1 and edgemap 2 represent the edge information.
373 % % extract inner edges
374 % edgemap = [edgemap1(inner_edges,:), edgemap2(inner_edges,:)];
375 % % check, that exactly two entries per row are non-nan
376 % entries = sum(~isnan(edgemap),2);
377 % if (min(entries)~=2) | max(entries)~=2
378 % disp('error in neighbour detection, please check');
382 % [mi, imi] = min(edgemap,[],2);
383 % [ma, ima] = max(edgemap,[],2);
387 % % then fill NBI and INB in a vectorized way, i.e.
389 % % NBI(neighs(i,1), eind(i,1)) = neighs(i,2);
390 % % NBI(neighs(i,2), eind(i,2)) = neighs(i,1);
391 % % INB(neighs(i,1), eind(i,1)) = eind(i,2);
392 % % INB(neighs(i,2), eind(i,2)) = eind(i,1);
394 % l1 = sub2ind( size(NBI), neighs(:,1) , eind(:,1));
395 % l2 = sub2ind( size(NBI), neighs(:,2) , eind(:,2));
396 % NBI(l1) = neighs(:,2);
397 % NBI(l2) = neighs(:,1);
398 % INB(l1) = eind(:,2);
399 % INB(l2) = eind(:,1);
401 % search non-inner boundaries and their midpoints
404 SX = grid.ECX(li(:));
405 SY = grid.ECY(li(:));
407 % default-boundary = -1
408 bnd_ind = -1 * ones(length(li),1);
410 if isfield(params,'bnd_rect_index')
411 if isfield(params,'boundary_type')
412 error(['Do not specify both bnd_rect_index and boundary_type', ...
415 if (max(params.bnd_rect_index)>0)
416 error('boundary indices must be negative!');
418 if size(params.bnd_rect_corner1,1) == 1
419 params.bnd_rect_corner1 = params.bnd_rect_corner1';
421 if size(params.bnd_rect_corner2,1) == 1
422 params.bnd_rect_corner2 = params.bnd_rect_corner2';
424 for i = 1:length(params.bnd_rect_index)
425 indx = (SX > params.bnd_rect_corner1(1,i)) & ...
426 (SX < params.bnd_rect_corner2(1,i)) & ...
427 (SY > params.bnd_rect_corner1(2,i)) & ...
428 (SY < params.bnd_rect_corner2(2,i));
429 bnd_ind(indx) = params.bnd_rect_index(i);
432 if isfield(params,'boundary_type')
433 bnd_ind = params.boundary_type([SX(:),SY(:)],params);
437 NBI(li) = bnd_ind'; % set neighbours to boundary
442 % check grid consistency:
443 nonzero = find(NBI>0); % vector with vector-indices
444 [i,j] = ind2sub(size(NBI), nonzero); % vectors with matrix indices
445 NBIind = NBI(nonzero); % vector with global neighbour indices
446 INBind = INB(nonzero);
447 i2 = sub2ind(size(NBI),NBIind, INBind);
450 % plot_element_data(grid,grid.NBI,params);
451 disp('neighbour indices are not consistent!!');
455 % matrix with centroid-distances
456 grid.DC = nan * ones(size(grid.CX,1),grid.nneigh);
457 nonzero = find(grid.NBI>0);
458 [elind, nbind] = ind2sub(size(grid.NBI),nonzero);
460 CXX = repmat(grid.CX(:),1,grid.nneigh);
461 CYY = repmat(grid.CY(:),1,grid.nneigh);
464 CXN(nonzero) = grid.CX(grid.NBI(nonzero));
467 CYN(nonzero) = grid.CY(grid.NBI(nonzero));
469 DC = sqrt((CXX-CXN).^2 + (CYY - CYN).^2);
471 grid.DC(nonzero) = DC(nonzero);
473 % computation of boundary distances: twice the distance to the border
475 nondef = find(isnan(grid.DC));
477 [elind, nind] = ind2sub(size(grid.DC),nondef);
478 nind_plus_one = nind + 1;
479 i = find(nind_plus_one > grid.nneigh);
480 nind_plus_one(i) = 1;
481 nondef_plus_one = sub2ind(size(grid.DC),elind,nind_plus_one);
482 nondef_plus_one = nondef_plus_one(:)';
484 d = zeros(length(nondef),1);
486 q = [grid.CX(elind)'; grid.CY(elind)'];
487 p1 = [grid.X(grid.VI(nondef)), ...
488 grid.Y(grid.VI(nondef))];
489 p2 = [grid.X(grid.VI(nondef_plus_one)), ...
490 grid.Y(grid.VI(nondef_plus_one))];
492 grid.DC(nondef) = 2 * dist_point_line(q,p1,p2);
494 % make entries of ECX, ECY exactly identical for neighbouring elements!
495 % currently by construction a small eps deviation is possible.
496 %averaging over all pairs is required
497 nonzero = find(grid.NBI>0); % vector with vector-indices
498 [i,j] = ind2sub(size(grid.NBI), nonzero); % vectors with matrix indices
499 NBIind = NBI(nonzero); % vector with global neighbour indices
500 INBind = INB(nonzero); % vector with local edge indices
501 i2 = sub2ind(size(NBI),NBIind, INBind);
502 % determine maximum difference in edge-midpoints, but exclude
503 % symmetry boundaries by relative error < 0.0001
504 diffx = abs(grid.ECX(nonzero)-grid.ECX(i2));
505 diffy = abs(grid.ECY(nonzero)-grid.ECY(i2));
506 fi = find ( (diffx/(max(grid.X)-min(grid.X)) < 0.0001) & ...
507 (diffy/(max(grid.Y)-min(grid.Y)) < 0.0001) );
514 grid.ECX(nonzero(fi)) = 0.5*(grid.ECX(nonzero(fi))+ grid.ECX(i2(fi)));
515 grid.ECY(nonzero(fi)) = 0.5*(grid.ECY(nonzero(fi))+ grid.ECY(i2(fi)));
517 % for diffusion discretization: Assumption of points with
518 % orthogonal connections to edges. Distances and intersections
519 % determined here. For triangles, this can simply be the
520 % circumcenters and the corresponding intersections
522 q = [grid.X(grid.VI(:,1)), ...
523 grid.Y(grid.VI(:,1))];
524 p1 = [grid.X(grid.VI(:,2)), ...
525 grid.Y(grid.VI(:,2))];
526 p2 = [grid.X(grid.VI(:,3)), ...
527 grid.Y(grid.VI(:,3))];
528 S = circumcenter_triangle(q,p1,p2);
532 % compute DS for inner edges (identical as DC computation!)
533 grid.DS = nan * ones(size(grid.CX,1),grid.nneigh);
534 nonzero = find(grid.NBI>0);
535 [elind, nbind] = ind2sub(size(grid.NBI),nonzero);
537 SXX = repmat(grid.SX(:),1,grid.nneigh);
538 SYY = repmat(grid.SY(:),1,grid.nneigh);
541 SXN(nonzero) = grid.SX(grid.NBI(nonzero));
544 SYN(nonzero) = grid.SY(grid.NBI(nonzero));
546 DS = sqrt((SXX-SXN).^2 + (SYY - SYN).^2);
548 grid.DS(nonzero) = DS(nonzero);
550 % computation of boundary distances: twice the distance to the border
552 nondef = find(isnan(grid.DS));
554 [elind, nind] = ind2sub(size(grid.DS),nondef);
555 nind_plus_one = nind + 1;
556 i = find(nind_plus_one > grid.nneigh);
557 nind_plus_one(i) = 1;
558 nondef_plus_one = sub2ind(size(grid.DS),elind,nind_plus_one);
559 nondef_plus_one = nondef_plus_one(:)';
561 d = zeros(length(nondef),1);
563 q = [grid.SX(elind)'; grid.SY(elind)'];
564 p1 = [grid.X(grid.VI(nondef)), ...
565 grid.Y(grid.VI(nondef))];
566 p2 = [grid.X(grid.VI(nondef_plus_one)), ...
567 grid.Y(grid.VI(nondef_plus_one))];
571 grid.DS(nondef) = 2 * dist_point_line(q,p1,p2);
573 if ~isempty(find(isnan(grid.DS)))
574 error('nans produced in grid generation!');
577 % intersections of S_i are the centroids of edges
581 % compute geometry constants for CFL-condition
582 h = max(grid.EL,[],2); % elementwise maximum edgelength
584 % alpha1 * h_j^2 <= |T_j|
585 alpha1 = min(grid.A .* h.^(-2));
586 % alpha2 * |boundary T_j| <= h_j
588 alpha2 = min(h .* b.^(-1));
589 % alpha3 h_j <= d_jl, d_jl distance of circumcenters
590 alpha3 = min(min(grid.DS,[],2) .* h.^(-1));
591 grid.alpha = min([alpha1,alpha2,alpha3]);
594 % disp(['Caution: Grid-geometry constant alpha less/equal zero', ...
595 % ' problematic ' ...
596 % ' in automatic CFL-conditions!']);
599 % DF = [(p2-p1) (p3-p1)] a 2x2 matrix
600 DF = zeros(grid.nelements,2,2); % jacobian
601 DF(:,1,1) = XX(:,2)-XX(:,1);
602 DF(:,2,1) = YY(:,2)-YY(:,1);
603 DF(:,1,2) = XX(:,3)-XX(:,1);
604 DF(:,2,2) = YY(:,3)-YY(:,1);
605 DetDF = DF(:,1,1).*DF(:,2,2)- DF(:,2,1).*DF(:,1,2); % determinant
606 DetDFinv = DetDF.^(-1);
607 JIT = zeros(grid.nelements,2,2);
608 % inversetransposed of A = (a,b; c,d) is A^-1 = 1/det A (d,-c; -b,a);
609 JIT(:,1,1)=DF(:,2,2).*DetDFinv;
610 JIT(:,1,2)=-DF(:,2,1).*DetDFinv;
611 JIT(:,2,1)=-DF(:,1,2).*DetDFinv;
612 JIT(:,2,2)=DF(:,1,1).*DetDFinv;
615 if (size(JIT,1)>=5) &(max(max(abs(...
616 transpose(reshape(JIT(5,:,:),2,2))*...
617 reshape(DF(5,:,:),2,2)-eye(2)...
619 error('error in JIT computation!');
623 grid.JIT = JIT; % perhaps later also store area, etc.
625 grid.nedges_boundary = length(find(grid.NBI<0));
627 grid.nedges_interior = 0.5*(3*grid.nelements - grid.nedges_boundary);
628 if ~isequal(ceil(grid.nedges_interior), ...
629 grid.nedges_interior);
630 error('number of inner edges odd!!!');
640 gridp = gridpart(grid,eind);
642 lcoord = llocal2local(grid, faceinds, llcoord);
644 glob = local2global(grid, einds, loc, params);
646 p = plot(gird, params);
648 grid = set_nbi(grid, nbind, values);
650 function gcopy = copy(grid)
654 % gcopy:
object of type
triagrid. This is a deep copy of the current instance.
664 [C, G] = aff_trafo_glob2loc(x0, y0);
666 [C, G] = aff_trafo_loc2glob(x0, y0);
668 [C, G] = aff_trafo_orig2ref(x0, y0, varargin);
670 loc = global2local(grid, elementid, glob);
672 micro2macro = micro2macro_map(microgrid, macrogrid);
674 [p, t] = read_msh(filename);
function r = verbose(level, message, messageId)
This function displays messages depending on a message-id and/or a level. Aditionally you can set/res...
A triangular conforming grid in two dimensions.
Base class for all grid classes.