KerMor  0.9
Model order reduction for nonlinear dynamical systems and nonlinear approximation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BaseGeometry.m
Go to the documentation of this file.
1 namespace fem{
2 namespace geometry{
3 
4 
5 /* (Autoinserted by mtoc++)
6  * This source code has been filtered by the mtoc++ executable,
7  * which generates code that can be processed by the doxygen documentation tool.
8  *
9  * On the other hand, it can neither be interpreted by MATLAB, nor can it be compiled with a C++ compiler.
10  * Except for the comments, the function bodies of your M-file functions are untouched.
11  * Consequently, the FILTER_SOURCE_FILES doxygen switch (default in our Doxyfile.template) will produce
12  * attached source files that are highly readable by humans.
13  *
14  * Additionally, links in the doxygen generated documentation to the source code of functions and class members refer to
15  * the correct locations in the source code browser.
16  * However, the line numbers most likely do not correspond to the line numbers in the original MATLAB source files.
17  */
18 
20  :public handle {
28  public:
29 
64 
65 
67 
68 
81 
82 
96 
98 
99 
100  public: /* ( Dependent ) */
101 
103 
105 
107 
109 
110 
144  public:
145 
146 
147 
148  FaceNormals = "[-1 1 0 0 0 0\
149  0 0 -1 1 0 0\
150  0 0 0 0 -1 1]";
168  FaceDims = logical("[0 0 1 1 1 1\
169  1 1 0 0 1 1\
170  1 1 1 1 0 0]");
171 
172 
174 
175 
176  public:
177 
178 
180  }
181 
182 
183  function plot(withdofnr,elem,pm) {
184 
185  if nargin < 4
186  if nargin < 3
187  elem = 1:this.NumElements;
188  if nargin < 2
189  withdofnr = false;
190  end
191  end
192  pm = PlotManager;/* (false,1,2); */
193 
194  pm.LeaveOpen= true;
195  end
196 
197  p = this.Nodes;
198  h = pm.nextPlot(" geometry ",sprintf(" Geometry (%s) ",class(this)), " x [mm] ", " y [mm] ");
199  plot3(h,p(1,:),p(2,:),p(3,:)," k. "," MarkerSize ",14);
200  hold(h," on ");
201  for k = 1:length(elem)
202  el = this.Elements(elem(k),:);
203  center = sum(p(:,el),2)/this.DofsPerElement;
204  text(center(1),center(2),center(3),sprintf(" E_{%d} ",elem(k))," Parent ",h," Color "," m ");
205  /* Plot local numbering for first element */
206  if k == 1
207  off = .04;
208  for i = 1:this.DofsPerElement
209  text(off+p(1,el(i)),off+p(2,el(i)),off+p(3,el(i)),sprintf(" %d ",i)," Parent ",h," Color "," r ");
210  end
211  for i = 1:6
212  facenodes = p(:,el(this.MasterFaces(i,:)));
213  mid = mean(facenodes,2);
214  text(mid(1),mid(2),mid(3),sprintf(" F_%d ",i)," Parent ",h," Color "," k ");
215  end
216  end
217  end
218  eg = this.Edges;
219  for i = 1:size(eg,1)
220  plot3(h,[p(1,eg(i,1)) p(1,eg(i,2))],[p(2,eg(i,1)) p(2,eg(i,2))],[p(3,eg(i,1)) p(3,eg(i,2))]," r ");
221  end
222  if withdofnr
223  for k = 1:this.NumNodes
224  text(p(1,k),p(2,k),p(3,k),sprintf(" %d ",k)," Parent ",h," Color "," k ");
225  end
226  end
227  zlabel(" z [mm] ");
228  view(h,[52 30]);
229  daspect([1 1 1]);
230 
231  if nargin < 3
232  pm.done;
233  end
234  }
235 
236 
237 
238  function bounds = getBoundingBox(marginfac) {
239  if nargin < 2
240  marginfac = 1;
241  end
242  m = min(this.Nodes,[],2)*marginfac;
243  M = max(this.Nodes,[],2)*marginfac;
244  bounds = [m(1) M(1) m(2) M(2) m(3) M(3)];
245  }
246 
247 
248  function commonidx = getCommonNodesWith(other) {
249  commonidx = Utils.findVecInMatrix(this.Nodes,other.Nodes);
250  }
251 
252 
253  function swapYZ() {
254  error(" not implemented ");
255  }
256 
257 
258  function copy = scale(factor) {
259  mc = metaclass(this);
260  pts = this.Nodes * factor;
261  cubes = this.Elements;
262  eval(sprintf(" copy = %s(pts,cubes); ",mc.Name));
263  }
264 
265 
266  function reverseAxis(dim) {
267  this.reverseElementAxis(dim, 1:this.NumElements);
268  }
269 
270 
271  function [sub , nodeidx , faces ] = getSubMesh(elems,faces) {
272  newelems = this.Elements(elems,:)^t;
273  nodeidx = unique(newelems(:)," stable ");
274  newnodes = this.Nodes(:,nodeidx);/* #ok
275  * Fit element node reference indices */
276 
277  invidx(nodeidx) = 1:length(nodeidx);
278  newelems = invidx(newelems)^t;/* #ok */
279 
280  sub = eval([class(this) " (newnodes, newelems) "]);
281 
282  /* Auto-detect which faces are included for the submesh's
283  * elements if none are specified */
284  if nargin < 3
285  isface = false(1,size(this.NumFaces,2));
286  for k = elems
287  isface = isface | this.Faces(1,:) == k;
288  end
289  faces = find(isface);
290  end
291  sub.Faces= this.Faces(:,faces);
292 
293  /* Fit face reference indices */
294  invidx = [];
295  invidx(elems) = 1:length(elems);
296  sub.Faces(1,:) = invidx(sub.Faces(1,:));
297  sub.faceComputations;
298  }
299 
300 
301  function toCMGUI(folder,name) {
302  if nargin < 3
303  name = " musclegeom ";
304  if nargin < 2
305  folder = pwd;
306  end
307  end
308  /* % exnode file */
309  exnode = fullfile(folder,[name " .exnode "]);
310  f = fopen(exnode," w+ ");
311  fprintf(f," Group name : %s\n ",name);
312  fprintf(f," #Fields=1\n ");
313  fprintf(f," 1) coordinates, coordinate, rectangular cartesian, #Components=3\n ");
314  fprintf(f," x. Value index= 1, #Derivatives= 0\n ");
315  fprintf(f," y. Value index= 2, #Derivatives= 0\n ");
316  fprintf(f," z. Value index= 3, #Derivatives= 0\n ");
317  for n = 1:this.NumNodes
318  fprintf(f," Node:\t%d\n ",n);
319  fprintf(f," %E\n ",this.Nodes(:,n));
320  end
321  fclose(f);
322 
323  /* % exelem file */
324  exelem = fullfile(folder,[name " .exelem "]);
325  f = fopen(exelem," w+ ");
326  fprintf(f," Group name : %s\n ",name);
327  /* fprintf(f,'#Fields=0\n'); */
328 
329  /* 1D elements - lines */
330  fprintf(f," Shape. Dimension=1\n ");
331  for e = 1:size(this.Edges,1)
332  fprintf(f," Element: 0 0 %d\n ",e);
333  end
334 
335  /* 2D elements - faces */
336  fprintf(f," Shape. Dimension=2\n ");
337  for fa = 1:size(this.Faces,2)
338  fprintf(f," Element: 0 %d 0\n ",fa);
339  fprintf(f," Faces:\n ");
340  elem = this.Faces(1,fa);
341  /* PatchFacesIdx returns the node positions in an order you can
342  * derive lines from it, MasterFaces doesn't */
343  facenodeidx = this.Elements(elem,this.PatchFacesIdx(this.Faces(2,fa),:));
344  /* Insert last edge closing the face */
345  facenodeidx = sort([facenodeidx; facenodeidx(2:end) facenodeidx(1)]);
346  edgenumbers = Utils.findVecInMatrix(this.Edges^t,facenodeidx);
347  fprintf(f," 0 0 %d\n ",edgenumbers);
348  end
349 
350  /* 3D elements */
351  fprintf(f," Shape. Dimension=3\n ");
352  fprintf(f," #Scale factor sets=0\n ");
353  fprintf(f," #Nodes=0\n ");
354 /* fprintf(f,'#Nodes=%d\n',size(this.Elements,2)); */
355  fprintf(f," #Fields=0\n ");
356 /* fprintf(f,'1) coordinates, coordinate, rectangular cartesian, #Components=3\n');
357  * fprintf(f,'x. l.Lagrange*l.Lagrange*l.Lagrange, no modify, standard node based.\n');
358  * fprintf(f,'y. l.Lagrange*l.Lagrange*l.Lagrange, no modify, standard node based.\n');
359  * fprintf(f,'z. l.Lagrange*l.Lagrange*l.Lagrange, no modify, standard node based.\n'); */
360  for m = 1:this.NumElements
361  fprintf(f," Element: %d 0 0\n ",m);
362  /* See if this element has any faces */
363  facesofelem = find(this.Faces(1,:) == m);
364  if ~isempty(facesofelem)
365  fprintf(f," Faces:\n ");
366  fprintf(f," 0 %d 0\n ",facesofelem);
367  end
368  fprintf(f," Nodes: %s\n ",sprintf(" %d\t ",this.Elements(m,:)));
369  end
370 
371  fclose(f);
372  }
373 
374 
375 
376  protected:
377 
378  function faces = computeFaces() {
379  if this.NumElements > 1
380  inner = zeros(this.NumElements,6);
381  for Afaceidx = 1:6
382  for Bfaceidx = 1:6
383  if Afaceidx ~= Bfaceidx
384  /* Also sort the element node indices in case of
385  * nonidentical numbering within each element */
386  A = sort(this.Elements(:,this.MasterFaces(Afaceidx,:)),2);
387  B = sort(this.Elements(:,this.MasterFaces(Bfaceidx,:)),2);
388  for l = 1:this.NumElements
389  opposing = sum(abs(A - circshift(B,l-1)),2) == 0;
390  if any(opposing)
391  opposedto = circshift(opposing,-(l-1));
392  inner(opposing, Afaceidx) = find(opposedto);
393  inner(opposedto, Bfaceidx) = find(opposing);
394  end
395  end
396  end
397  end
398  end
399  [elemnr, facenr] = find(inner == 0);
400  faces = [elemnr facenr]^t;
401  else
402  mf = size(this.MasterFaces,1);
403  faces = [ones(1,mf); 1:mf];
404  end
405  this.faceComputations(faces);
406  }
421  function faceComputations(faces) {
422  if ~isempty(this.PatchFacesIdx)
423  if nargin < 2
424  faces = this.Faces;
425  end
426  nf = size(faces,2);
427  ppf = this.PatchesPerFace;
428  /* np = size(this.PatchFacesIdx,1); */
429  pf = zeros(nf*ppf,size(this.PatchFacesIdx,2));
430  for k=1:nf
431  elem = faces(1,k);
432  face = faces(2,k);
433  pos = (face-1)*ppf + (1:ppf);
434  patchidx = this.PatchFacesIdx(pos,:);
435  pf((k-1)*ppf+(1:ppf),:) = reshape(this.Elements(elem,patchidx),ppf,[]);
436  end
437  this.PatchFaces= pf;
438  end
439  }
447  function checkOrientation() {
448  return;
449  oi = this.OrientationCheckIndices;
450  pi = ProcessIndicator(" %s: Checking orientation of %d elements in x,y,z directions ",3*this.NumElements,false,class(this),this.NumElements);
451  for dim = 1:3
452  for e = 1:this.NumElements
453  chk = diff(reshape(this.Nodes(dim,this.Elements(e,oi(:,:,dim)" ) "),size(oi,2),[]),[],1);
454  if any(chk <= 0)
455  if all(chk < 0)
456  this.reverseElementAxis(dim, e);
457  /* fprintf('Axis %d has negative orientation. Reversing element %d\n',dim,e); */
458  else
459  [ip,jp] = find(chk > 0);
460  [in,jn] = find(chk < 0);
461  [is,js] = find(chk == 0);
462  if ~isempty(is)
463  errel = this.Elements(e,oi(js,[is is+1]^t,dim));
464  fprintf(" \n%s: Degenerate element nr %3d in dimension %d: %3d equal! Nodes %s (%s)\n ",...
465  class(this),e,dim,length(is),int2str(errel),num2str(this.Nodes(dim,errel)));
466  else
467  if length(ip) > length(in)
468  i = in; j = jn;
469  str = " positive ";
470  reverse = false;
471  else
472  i = ip; j = jp;
473  str = " negative ";
474  reverse = true;
475  end
476  errel = this.Elements(e,oi(j,[i i+1],dim));
477  fprintf(" \n%s: Opposite orientation in dimension %d in mainly %s oriented element nr %3d (%3d pos/%3d neg): Nodes %s (%s)\n ",...
478  class(this),dim,str,e,length(ip),length(in),int2str(errel),num2str(this.Nodes(dim,errel)));
479  if reverse
480  this.reverseElementAxis(dim, e);
481  end
482  end
483  end
484  end
485  pi.step;
486  end
487  end
488  pi.stop;
489  }
490 
491 
492  private:
493 
494  function reverseElementAxis(dim,e) {
495  this.Elements(e,:) = this.Elements(e,this.ReverseAxesIndices(dim,:));
496  }
497 
498 
499  public:
500 
501 
502 #if 0 //mtoc++: 'get.NumElements'
503 function nc = NumElements() {
504  nc = size(this.Elements,1);
505  }
506 
507 #endif
508 
509 
510 
511 #if 0 //mtoc++: 'get.NumNodes'
512 function nc = NumNodes() {
513  nc = size(this.Nodes,2);
514  }
515 
516 #endif
517 
518 
519 
520 #if 0 //mtoc++: 'get.NumFaces'
521 function nf = NumFaces() {
522  nf = size(this.Faces,2);
523  }
524 
525 #endif
526 
527 
528 
529 
530 #if 0 //mtoc++: 'get.NodesPerFace'
531 function npf = NodesPerFace() {
532  npf = size(this.MasterFaces,2);
533  }
534 
535 #endif
536 
537 
538 
539 #if 0 //mtoc++: 'get.Width'
540 function w = Width() {
541  w = max(this.Nodes(1,:))-min(this.Nodes(1,:));
542  }
543 
544 #endif
545 
546 
547 
548 #if 0 //mtoc++: 'get.Depth'
549 function w = Depth() {
550  w = max(this.Nodes(2,:))-min(this.Nodes(2,:));
551  }
552 
553 #endif
554 
555 
556 
557 #if 0 //mtoc++: 'get.Height'
558 function w = Height() {
559  w = max(this.Nodes(3,:))-min(this.Nodes(3,:));
560  }
561 
562 #endif
563 
564 
565  public: /* ( Static ) */
566 
567  static function res = test_DemoGrids() {
568  fem.geometry.RegularHex8Grid(1:3);
569  fem.geometry.RegularHex8Grid(1:3,1:4);
570  fem.geometry.RegularHex8Grid(1:3,1:4,-1:3);
571  fem.geometry.RegularHex8Grid(1:3,1:4,-1:3,.2);
572  fem.geometry.RegularHex20Grid(1:2);
573  fem.geometry.RegularHex20Grid(1:2,0:2);
574  fem.geometry.RegularHex20Grid(-1:1,1:3,-1:1);
575  fem.geometry.RegularHex20Grid(-1:1,1:2,-1:1,.2);
576  res = true;
577  }
578 
579 
580  static function test_subMesh() {
581  g = fem.geometry.RegularHex27Grid(-1:1,1:2,-1:1,.2);
582  [sg, node] = g.getSubMesh(1:3:g.NumElements);
583  sg.plot;
584  g = fem.geometry.RegularHex8Grid(-20:1,1:4,-1:1,.2);
585  [sg, node] = g.getSubMesh([1 5 9 10 15 56 79 99]);
586  sg.plot;
587  }
588 
589 
590 
627 };
628 }
629 }
630 
Collection of generally useful functions.
Definition: Utils.m:17
Elements
m x p index vector for all p nodes of m elements
Definition: BaseGeometry.m:41
static function res = test_DemoGrids()
Definition: BaseGeometry.m:567
Nodes
n x 3 position vector of nodes
Definition: BaseGeometry.m:30
function copy = scale(factor)
Definition: BaseGeometry.m:258
PatchFacesIdx
The indices of the nodes suitable for creating a patch surface object.
Definition: BaseGeometry.m:69
function commonidx = getCommonNodesWith(other)
Definition: BaseGeometry.m:248
static function idx = findVecInMatrix(A, b)
Finds column vectors inside a matrix.
Definition: Utils.m:259
function bounds = getBoundingBox(marginfac)
Definition: BaseGeometry.m:238
function toCMGUI(folder, name)
Definition: BaseGeometry.m:301
sort
ort the handle objects in any array in ascending or descending order.
reshape
hanges the dimensions of the handle object array to the specified dimensions. See the MATLAB reshape ...
Depth
Returns the Depth of the geometry (y-range)
Definition: BaseGeometry.m:122
PlotManager: Small class that allows the same plots generated by some script to be either organized a...
Definition: PlotManager.m:17
Matlab's base handle class (documentation generation substitute)
A boolean value.
logical LeaveOpen
Flag indicating if the plots should be left open once the PlotManager is deleted (as variable) ...
Definition: PlotManager.m:213
Height
Returns the Height of the geometry (z-range)
Definition: BaseGeometry.m:133
Edges
2 x k index vector for edges between two points
Definition: BaseGeometry.m:52
static function test_subMesh()
Definition: BaseGeometry.m:580
Speed test * all(1:3)
function faceComputations(faces)
% Also compute the PatchFaces index matrix
Definition: BaseGeometry.m:421
function faces = computeFaces()
Computes the outward faces of this fem.geometry.
Definition: BaseGeometry.m:378
FaceNormals
Faces are: Idx : 1 2 3 4 5 6 Face: X- X+ Y- Y+ Z- Z+ Pos: Left Right Front Rear Bottom Top...
Definition: BaseGeometry.m:148
Width
Returns the width of the geometry (x-range)
Definition: BaseGeometry.m:111
Faces
A 2 x N_F vector containing the element number in the first row and the face number on that element i...
Definition: BaseGeometry.m:83
function [ sub , nodeidx , faces ] = getSubMesh(elems, faces)
Definition: BaseGeometry.m:271
function reverseAxis(dim)
Definition: BaseGeometry.m:266
function plot(withdofnr, elem, pm)
Definition: BaseGeometry.m:183
ProcessIndicator: A simple class that indicates process either via waitbar or text output...