-
Notifications
You must be signed in to change notification settings - Fork 1
/
load_gmsh2.m
238 lines (216 loc) · 7.49 KB
/
load_gmsh2.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
function msh = load_gmsh4(filename, which)
%% Reads a mesh in msh format, version 1 or 2
% Usage:
% To define all variables m.LINES, M.TRIANGLES, etc
% (Warning: This creates a very large structure. Do you really need it?)
% m = load_gmsh4('a.msh')
%
% To define only certain variables (for example TETS and HEXS)
% m = load_gmsh4('a.msh', [ 5 6])
%
% To define no variables (i.e. if you prefer to use m.ELE_INFOS(i,2))
% m = load_gmsh4('a.msh', -1)
% m = load_gmsh4('a.msh', [])
%
% Copyright (C) 2007 JP Moitinho de Almeida ([email protected])
% and R Lorphevre(r(point)lorphevre(at)ulg(point)ac(point)be)
%
% based on load_gmsh.m supplied with gmsh-2.0
% Structure msh always has the following elements:
%
% msh.MIN, msh.MAX - Bounding box
% msh.nbNod - Number of nodes
% msh.nbElm - Total number of elements
% msh.nbType(i) - Number of elements of type i (i in 1:19)
% msh.POS(i,j) - j'th coordinate of node i (j in 1:3, i in 1:msh.nbNod)
% msh.ELE_INFOS(i,1) - id of element i (i in 1:msh.nbElm)
% msh.ELE_INFOS(i,2) - type of element i
% msh.ELE_INFOS(i,3) - number of tags for element i
% msh.ELE_INFOS(i,4) - Dimension (0D, 1D, 2D or 3D) of element i
% msh.ELE_TAGS(i,j) - Tags of element i (j in 1:msh.ELE_INFOS(i,3))
% msh.ELE_NODES(i,j) - Nodes of element i (j in 1:k, with
% k = msh.NODES_PER_TYPE_OF_ELEMENT(msh.ELE_INFOS(i,2)))
%
% These elements are created if requested:
%
% msh.nbLines - number of 2 node lines
% msh.LINES(i,1:2) - nodes of line i
% msh.LINES(i,3) - tag (WHICH ?????) of line i
%
% msh.nbTriangles - number of 2 node triangles
% msh.TRIANGLES(i,1:3) - nodes of triangle i
% msh.TRIANGLES(i,4) - tag (WHICH ?????) of triangle i
%
% Etc
% These definitions need to be updated when new elemens types are added to gmsh
%
% msh.Types{i}{1} Number of an element of type i
% msh.Types{i}{2} Dimension (0D, 1D, 2D or 3D) of element of type i
% msh.Types{i}{3} Name to add to the structure with elements of type i
% msh.Types{i}{4} Name to add to the structure with the number of elements of type i
%
nargchk(1, 2, nargin);
msh.Types = { ...
{ 2, 1, 'LINES', 'nbLines'}, ... % 1
{ 3, 2, 'TRIANGLES', 'nbTriangles'}, ...
{ 4, 2, 'QUADS', 'nbQuads'}, ...
{ 4, 3, 'TETS', 'nbTets'}, ...
{ 8, 3, 'HEXAS', 'nbHexas'}, ... %5
{ 6, 3, 'PRISMS', 'nbPrisms'}, ...
{ 5, 3, 'PYRAMIDS', 'nbPyramids'}, ...
{ 3, 1, 'LINES3', 'nbLines3'}, ...
{ 6, 2, 'TRIANGLES6', 'nbTriangles6'}, ...
{ 9, 2, 'QUADS9', 'nbQuads9'}, ... % 10
{ 10, 3, 'TETS10', 'nbTets10'}, ...
{ 27, 3, 'HEXAS27', 'nbHexas27'}, ...
{ 18, 3, 'PRISMS18', 'nbPrisms18'}, ...
{ 14, 3, 'PYRAMIDS14', 'nbPyramids14'}, ...
{ 1, 0, 'POINTS', 'nbPoints'}, ... % 15
{ 8, 3, 'QUADS8', 'nbQuads8'}, ...
{ 20, 3, 'HEXAS20', 'nbHexas20'}, ...
{ 15, 3, 'PRISMS15', 'nbPrisms15'}, ...
{ 13, 3, 'PYRAMIDS13', 'nbPyramids13'}, ...
};
ntypes = length(msh.Types);
if (nargin==1)
which = 1:ntypes;
else
if isscalar(which) && which == -1
which = [];
end
end
% Could check that "which" is properlly defined....
fid = fopen(filename, 'r');
fileformat = 0; % Assume wrong file
tline = fgetl(fid);
if (feof(fid))
disp (sprintf('Empty file: %s', filename));
msh = [];
return;
end
%% Read mesh type
if (strcmp(tline, '$NOD'))
fileformat = 1;
elseif (strcmp(tline, '$MeshFormat'))
fileformat = 2;
tline = fgetl(fid);
if (feof(fid))
disp (sprintf('Syntax error (no version) in: %s', filename));
fileformat = 0;
end
[ form ] = sscanf( tline, '%f %d %d');
if (form(1) ~= 2)
disp (sprintf('Unknown mesh format: %s', tline));
fileformat = 0;
end
if (form(2) ~= 0)
disp ('Sorry, this program can only read ASCII format');
fileformat = 0;
end
fgetl(fid); % this should be $EndMeshFormat
if (feof(fid))
disp (sprintf('Syntax error (no $EndMeshFormat) in: %s', filename));
fileformat = 0;
end
tline = fgetl(fid); % this should be $Nodes
if (feof(fid))
disp (sprintf('Syntax error (no $Nodes) in: %s', filename));
fileformat = 0;
end
end
if (~fileformat)
msh = [];
return
end
%% Read nodes
if strcmp(tline, '$NOD') || strcmp(tline, '$Nodes')
msh.nbNod = fscanf(fid, '%d', 1);
aux = fscanf(fid, '%g', [4 msh.nbNod]);
msh.POS = aux(2:4,:)';
numids = max(aux(1,:));
IDS = zeros(1, numids);
IDS(aux(1,:)) = 1:msh.nbNod; % This may not be an identity
msh.MAX = max(msh.POS);
msh.MIN = min(msh.POS);
fgetl(fid); % End previous line
fgetl(fid); % Has to be $ENDNOD $EndNodes
else
disp (sprintf('Syntax error (no $Nodes/$NOD) in: %s', filename));
fileformat = 0;
end
%% Read elements
tline = fgetl(fid);
if strcmp(tline,'$ELM') || strcmp(tline, '$Elements')
msh.nbElm = fscanf(fid, '%d', 1);
% read all info about elements into aux (it is faster!)
aux = fscanf(fid, '%g', inf);
start = 1;
msh.ELE_INFOS = zeros(msh.nbElm, 4); % 1 - id, 2 - type, 3 - ntags, 4 - Dimension
msh.ELE_NODES = zeros(msh.nbElm,6); % i - Element, j - ElNodes
if (fileformat == 1)
ntags = 2;
else
ntags = 3; % just a prediction
end
msh.ELE_TAGS = zeros(msh.nbElm, ntags); % format 1: 1 - physical number, 2 - geometrical number
% format 2: 1 - physical number, 2 - geometrical number, 3 - mesh partition number
msh.nbType = zeros(ntypes,1);
for I = 1:msh.nbElm
if (fileformat == 2)
finnish = start + 2;
msh.ELE_INFOS(I, 1:3) = aux(start:finnish);
ntags = aux(finnish);
start = finnish + 1;
finnish = start + ntags -1;
msh.ELE_TAGS(I, 1:ntags) = aux(start:finnish);
start = finnish + 1;
else
finnish = start + 1;
msh.ELE_INFOS(I, 1:2) = aux(start:finnish);
start = finnish + 1; % the third element is nnodes, which we get from the type
msh.ELE_INFOS(I, 3) = 2;
finnish = start + 1;
msh.ELE_TAGS(I, 1:2) = aux(start:finnish);
start = finnish + 2;
end
type = msh.ELE_INFOS(I, 2);
msh.nbType(type) = msh.nbType(type) + 1;
msh.ELE_INFOS(I, 4) = msh.Types{type}{2};
nnodes = msh.Types{type}{1};
finnish = start + nnodes - 1;
msh.ELE_NODES(I, 1:nnodes) = IDS(aux(start:finnish));
start=finnish + 1;
end
fgetl(fid); % Has to be $ENDELM or $EndElements
else
disp (sprintf('Syntax error (no $Elements/$ELM) in: %s', filename));
fileformat = 0;
end
if (fileformat == 0)
msh = [];
end
fclose(fid);
%% This is used to create the explicit lists for types of elements
for i = which
if (~isempty(msh.Types{i}{3}))
cmd = sprintf('msh.%s=msh.nbType(%d);', msh.Types{i}{4}, i);
eval(cmd);
% Dimension
cmd = sprintf('msh.%s=zeros(%d,%d);', msh.Types{i}{3}, msh.nbType(i), msh.Types{i}{1}+1);
eval(cmd);
% Clear nbType for counting, next loop will recompute it
msh.nbType(i) = 0;
end
end
for i = 1:msh.nbElm
type = msh.ELE_INFOS(i,2);
if (find(which == type))
if (~isempty(msh.Types{type}{3}))
msh.nbType(type) = msh.nbType(type)+1;
aux=[ msh.ELE_NODES(i,1:msh.Types{type}{1}), msh.ELE_TAGS(i,1) ];
cmd = sprintf('msh.%s(%d,:)=aux;', msh.Types{type}{3}, msh.nbType(type));
eval(cmd);
end
end
end
return;