5 %% Reads a mesh in msh format,
version 1 or 2
8 % To define all variables m.LINES,
M.TRIANGLES, etc
9 % (Warning: This creates a very large structure. Do you really need it?)
12 % To define only certain variables (
for example TETS and HEXS)
15 % To define no variables (i.e.
if you prefer to use m.ELE_INFOS(i,2))
19 % Copyright (C) 2007 JP Moitinho de Almeida (moitinho@civil.ist.utl.pt)
20 % and R Lorphevre(r(point)lorphevre(at)ulg(point)ac(point)be)
22 % based on
load_gmsh.m supplied with gmsh-2.0
24 % Structure msh always has the following elements:
26 % msh.MIN, msh.MAX - Bounding box
27 % msh.nbNod - Number of nodes
28 % msh.nbElm - Total number of elements
29 % msh.nbType(i) - Number of elements of type i (i in 1:19)
30 % msh.POS(i,j) - j'th coordinate of node i (j in 1:3, i in 1:msh.nbNod)
31 % msh.ELE_INFOS(i,1) - id of element i (i in 1:msh.nbElm)
32 % msh.ELE_INFOS(i,2) - type of element i
33 % msh.ELE_INFOS(i,3) - number of tags for element i
34 % msh.ELE_INFOS(i,4) - Dimension (0D, 1D, 2D or 3D) of element i
35 % msh.ELE_TAGS(i,j) - Tags of element i (j in 1:msh.ELE_INFOS(i,3))
36 % msh.ELE_NODES(i,j) - Nodes of element i (j in 1:
k, with
37 %
k = msh.NODES_PER_TYPE_OF_ELEMENT(msh.ELE_INFOS(i,2)))
39 % These elements are created if requested:
41 % msh.nbLines - number of 2 node lines
42 % msh.LINES(i,1:2) - nodes of line i
43 % msh.LINES(i,3) - tag (WHICH ?????) of line i
45 % msh.nbTriangles - number of 2 node triangles
46 % msh.TRIANGLES(i,1:3) - nodes of triangle i
47 % msh.TRIANGLES(i,4) - tag (WHICH ?????) of triangle i
51 % These definitions need to be updated when new elemens types are added to gmsh
53 % msh.Types{i}{1} Number of an element of type i
54 % msh.Types{i}{2} Dimension (0D, 1D, 2D or 3D) of element of type i
55 % msh.Types{i}{3} Name to add to the structure with elements of type i
56 % msh.Types{i}{4} Name to add to the structure with the number of elements of type i
59 nargchk(1, 2, nargin);
62 { 2, 1,
'LINES',
'nbLines'}, ... % 1
63 { 3, 2,
'TRIANGLES',
'nbTriangles'}, ...
64 { 4, 2,
'QUADS',
'nbQuads'}, ...
65 { 4, 3,
'TETS',
'nbTets'}, ...
66 { 8, 3,
'HEXAS',
'nbHexas'}, ... %5
67 { 6, 3,
'PRISMS',
'nbPrisms'}, ...
68 { 5, 3,
'PYRAMIDS',
'nbPyramids'}, ...
69 { 3, 1,
'LINES3',
'nbLines3'}, ...
70 { 6, 2,
'TRIANGLES6',
'nbTriangles6'}, ...
71 { 9, 2,
'QUADS9',
'nbQuads9'}, ... % 10
72 { 10, 3,
'TETS10',
'nbTets10'}, ...
73 { 27, 3,
'HEXAS27',
'nbHexas27'}, ...
74 { 18, 3,
'PRISMS18',
'nbPrisms18'}, ...
75 { 14, 3,
'PYRAMIDS14',
'nbPyramids14'}, ...
76 { 1, 0,
'POINTS',
'nbPoints'}, ... % 15
77 { 8, 3,
'QUADS8',
'nbQuads8'}, ...
78 { 20, 3,
'HEXAS20',
'nbHexas20'}, ...
79 { 15, 3,
'PRISMS15',
'nbPrisms15'}, ...
80 { 13, 3,
'PYRAMIDS13',
'nbPyramids13'}, ...
83 ntypes = length(msh.Types);
88 if isscalar(which) && which == -1
93 % Could check that
"which" is properlly defined....
95 fid = fopen(filename,
'r');
96 fileformat = 0; % Assume wrong file
100 disp (sprintf(
'Empty file: %s', filename));
106 if (strcmp(tline,
'$NOD'))
108 elseif (strcmp(tline,
'$MeshFormat'))
112 disp (sprintf('Syntax error (no
version) in: %s', filename));
115 [ form ] = sscanf( tline, '%f %d %d');
117 disp (sprintf('Unknown mesh format: %s', tline));
121 disp ('Sorry, this program can only read ASCII format');
124 fgetl(fid); % this should be $EndMeshFormat
126 disp (sprintf('Syntax error (no $EndMeshFormat) in: %s', filename));
129 tline = fgetl(fid); % this should be $Nodes
131 disp (sprintf('Syntax error (no $Nodes) in: %s', filename));
143 if strcmp(tline, '$NOD') || strcmp(tline, '$Nodes')
144 msh.nbNod = fscanf(fid, '%d', 1);
145 aux = fscanf(fid, '%g', [4 msh.nbNod]);
146 msh.POS = aux(2:4,:)';
147 numids = max(aux(1,:));
148 IDS = zeros(1, numids);
149 IDS(aux(1,:)) = 1:msh.nbNod; % This may not be an identity
150 msh.MAX = max(msh.POS);
151 msh.MIN = min(msh.POS);
152 fgetl(fid); % End previous line
153 fgetl(fid); % Has to be $ENDNOD $EndNodes
155 disp (sprintf('Syntax error (no $Nodes/$NOD) in: %s', filename));
161 if strcmp(tline,'$ELM') || strcmp(tline, '$Elements')
162 msh.nbElm = fscanf(fid, '%d', 1);
163 % read all info about elements into aux (it is faster!)
164 aux = fscanf(fid, '%g', inf);
166 msh.ELE_INFOS = zeros(msh.nbElm, 4); % 1 -
id, 2 - type, 3 - ntags, 4 - Dimension
167 msh.ELE_NODES = zeros(msh.nbElm,6); % i - Element, j - ElNodes
171 ntags = 3; % just a prediction
173 msh.ELE_TAGS = zeros(msh.nbElm, ntags); % format 1: 1 - physical number, 2 - geometrical number
174 % format 2: 1 - physical number, 2 - geometrical number, 3 - mesh partition number
175 msh.nbType = zeros(ntypes,1);
179 msh.ELE_INFOS(I, 1:3) = aux(start:finnish);
180 ntags = aux(finnish);
182 finnish = start + ntags -1;
183 msh.ELE_TAGS(I, 1:ntags) = aux(start:finnish);
187 msh.ELE_INFOS(I, 1:2) = aux(start:finnish);
188 start = finnish + 1; % the third element is nnodes, which we get from the type
189 msh.ELE_INFOS(I, 3) = 2;
191 msh.ELE_TAGS(I, 1:2) = aux(start:finnish);
194 type = msh.ELE_INFOS(I, 2);
195 msh.nbType(type) = msh.nbType(type) + 1;
196 msh.ELE_INFOS(I, 4) = msh.Types{type}{2};
197 nnodes = msh.Types{type}{1};
198 finnish = start + nnodes - 1;
199 msh.ELE_NODES(I, 1:nnodes) = IDS(aux(start:finnish));
202 fgetl(fid); % Has to be $ENDELM or $EndElements
204 disp (sprintf(
'Syntax error (no $Elements/$ELM) in: %s', filename));
214 %% This is used to create the
explicit lists
for types of elements
218 cmd = sprintf(
'msh.%s=msh.nbType(%d);', msh.Types{i}{4}, i);
221 cmd = sprintf(
'msh.%s=zeros(%d,%d);', msh.Types{i}{3}, msh.nbType(i), msh.Types{i}{1}+1);
223 % Clear nbType
for counting, next loop will recompute it
229 type = msh.ELE_INFOS(i,2);
230 if (find(which == type))
231 if (~
isempty(msh.Types{type}{3}))
232 msh.nbType(type) = msh.nbType(type)+1;
233 aux=[ msh.ELE_NODES(i,1:msh.Types{type}{1}), msh.ELE_TAGS(i,1) ];
234 cmd = sprintf(
'msh.%s(%d,:)=aux;', msh.Types{type}{3}, msh.nbType(type));