/ concept-collection / mesh-pde-solver
Sign in
concept-collection / mesh-pde-solver
mesh-pde-solver / matlab / load_gmsh_quads.m
56 lines · 1.8 KBCodeBlameHistory
28f8ec1mesh-pde-solver: upload a quad mesh, solve PDEs on the surface in-browserJeremy Magland 1function msh = load_gmsh_quads(filename)
2%LOAD_GMSH_QUADS Minimal Gmsh MSH 2.2 ASCII reader for all-quad meshes.
3% Returns a struct with POS (n-by-3 node coordinates) and QUADS
4% (m-by-5: four 1-based node indices plus a tag), the layout that
5% surfacemesh.fromGmsh expects.
6%
7% Only the canonical form written by this app's converter is supported:
8% sequential node ids starting at 1, and 4-node quadrangle elements
9% (type 3) with exactly two tags.
11txt = fileread(filename);
13block = extract_block(txt, '$Nodes', '$EndNodes');
14vals = sscanf(block, '%f');
15nn = vals(1);
16if numel(vals) ~= 1 + 4*nn
17 error('load_gmsh_quads:badNodes', 'Unexpected $Nodes layout.');
18end
19data = reshape(vals(2:end), 4, nn);
20if any(data(1, :) ~= 1:nn)
21 error('load_gmsh_quads:badNodes', 'Node ids must be sequential from 1.');
22end
23pos = data(2:4, :)';
25block = extract_block(txt, '$Elements', '$EndElements');
26vals = sscanf(block, '%f');
27ne = vals(1);
28% Each element line: id type(=3) ntags(=2) tag tag n1 n2 n3 n4
29if numel(vals) ~= 1 + 9*ne
30 error('load_gmsh_quads:badElements', ...
31 'Expected only 4-node quadrangles with two tags.');
32end
33data = reshape(vals(2:end), 9, ne);
34if any(data(2, :) ~= 3)
35 error('load_gmsh_quads:badElements', ...
36 'Expected only 4-node quadrangle elements (type 3).');
37end
38idx = data(6:9, :)';
39if any(idx(:) < 1) || any(idx(:) > nn)
40 error('load_gmsh_quads:badElements', 'Element node index out of range.');
41end
42quads = [idx, ones(ne, 1)];
44msh = struct();
45msh.POS = pos;
46msh.QUADS = quads;
47end
49function block = extract_block(txt, startMarker, endMarker)
50i1 = strfind(txt, startMarker);
51i2 = strfind(txt, endMarker);
52if isempty(i1) || isempty(i2)
53 error('load_gmsh_quads:badFile', 'Missing %s section.', startMarker);
54end
55block = txt(i1(1) + length(startMarker) : i2(1) - 1);
56end
moveopenescclose