0001 function gmsh_write_mesh(mdl, data, outfile)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 if ischar(mdl) && strcmp(mdl,'UNIT_TEST'); do_unit_test; return; end
0017
0018 is_img = (isfield(mdl, 'type') && strcmp(mdl.type, 'image')) || isfield(mdl, 'elem_data');
0019 is_imdl = (isfield(mdl, 'type') && strcmp(mdl.type, 'inv_model')) || isfield(mdl, 'fwd_model');
0020
0021 if nargin < 3
0022 outfile = data;
0023 data = [];
0024 end
0025
0026 if is_img && isempty(data)
0027 data = mdl.elem_data(:,1);
0028 end
0029 assert(isempty(data) || size(data,2) == 1, 'error: expect a single frame of data in gmsh_write_mesh');
0030
0031 if is_imdl || is_img
0032 if isfield(mdl, 'rec_model')
0033 mdl = mdl.rec_model;
0034 else
0035 mdl = mdl.fwd_model;
0036 end
0037 end
0038 assert(isempty(data) || size(data,1) == size(mdl.elems,1), 'error: expect a data to match number of elements in gmsh_write_mesh');
0039
0040 nn = size(mdl.nodes,1);
0041 ne = size(mdl.elems,1);
0042 ndim = size(mdl.nodes,2);
0043 assert((ndim >= 2) && (ndim <= 3), 'not 2D or 3D?!');
0044
0045 fid = fopen(outfile, 'w');
0046 fprintf(fid, '$MeshFormat\n');
0047 fprintf(fid, '4.1 0 8\n');
0048 fprintf(fid, '$EndMeshFormat\n');
0049
0050 nodes = [ mdl.nodes zeros(nn, 3 - ndim) ];
0051
0052
0053 [mdl, mat_vec] = prepare_materials(mdl, ne);
0054 numEntityBlocks = 1;
0055 try numEntityBlocks = numel(mdl.mat_idx); end
0056 numPhysicalNames = 0;
0057 try numPhysicalNames = numel(mdl.mat_idx); end
0058
0059 if numPhysicalNames
0060 fprintf(fid, '$PhysicalNames\n');
0061 fprintf(fid, '%d\n',numPhysicalNames);
0062 for i = 1:numPhysicalNames
0063 fprintf(fid, '%d %d "%s"\n', ndim, i, mdl.mat_names{i});
0064 end
0065 fprintf(fid, '$EndPhysicalNames\n');
0066 end
0067
0068 fprintf(fid, '$Entities\n');
0069 if ndim == 2
0070 fprintf(fid, '%d %d %d %d\n', 0, 0, numEntityBlocks, 0);
0071 else
0072 fprintf(fid, '%d %d %d %d\n', 0, 0, 0, numEntityBlocks);
0073 end
0074 for i = 1:numEntityBlocks
0075 physicalTag = 0;
0076 if numPhysicalNames, physicalTag = i; end
0077 if numEntityBlocks == 1
0078 idx = (1:ne)';
0079 else
0080 idx = reshape(mdl.mat_idx{i},[],1);
0081 end
0082 minlim = min(nodes(unique(mdl.elems(idx,:)), :));
0083 maxlim = max(nodes(unique(mdl.elems(idx,:)), :));
0084 fprintf(fid, '%d %f %f %f %f %f %f %d %d %d\n', ...
0085 i, ...
0086 minlim, ...
0087 maxlim, ...
0088 1, physicalTag, 0);
0089 end
0090 fprintf(fid, '$EndEntities\n');
0091
0092 fprintf(fid, '$Nodes\n');
0093 fprintf(fid, '%d %d %d %d\n', 1, nn, 1, nn);
0094 fprintf(fid, '%d %d %d %d\n', ndim, 0, 0, nn);
0095 fprintf(fid, '%d\n', 1:nn);
0096 fprintf(fid, '%f %f %f\n', nodes');
0097 fprintf(fid, '$EndNodes\n');
0098
0099 fprintf(fid, '$Elements\n');
0100 if ndim == 2
0101 type = 2;
0102 else
0103 type = 4;
0104 end
0105 fprintf(fid, '%d %d %d %d\n', numEntityBlocks, ne, 1, ne);
0106
0107 for i = 1:numEntityBlocks
0108 if isempty(mat_vec)
0109 neb = ne;
0110 idx = (1:ne)';
0111 else
0112 neb = numel(mdl.mat_idx{i});
0113 idx = mdl.mat_idx{i};
0114 end
0115 fprintf(fid, '%d %d %d %d\n', ndim, i, type, neb);
0116 elems = [idx mdl.elems(idx,:)];
0117 if ndim == 2
0118 fprintf(fid, '%d %d %d %d\n', elems');
0119 else
0120 fprintf(fid, '%d %d %d %d %d\n', elems');
0121 end
0122 end
0123 fprintf(fid, '$EndElements\n');
0124
0125 if ~isempty(data)
0126 fprintf(fid, '$ElementData\n');
0127 fprintf(fid, '%d\n', 1);
0128 name = 'gmsh_write_mesh output';
0129 if isfield(mdl, 'name')
0130 name = mdl.name;
0131 end
0132 fprintf(fid, '%s\n', name);
0133 fprintf(fid, '%d\n', 1);
0134 fprintf(fid, '%f\n', 0);
0135 fprintf(fid, '%d\n', 3);
0136 fprintf(fid, '%d\n', 0);
0137 fprintf(fid, '%d\n', 1);
0138 fprintf(fid, '%d\n', ne);
0139 data = [[1:ne]' data];
0140 fprintf(fid, '%d %f\n', data');
0141 fprintf(fid, '$EndElementData\n');
0142 end
0143 fclose(fid);
0144
0145 function [mdl, mat_vec] = prepare_materials(mdl, ne)
0146 mat_vec = [];
0147 if isfield(mdl, 'mat_idx') && ~isempty(mdl.mat_idx)
0148 mat_vec = zeros(ne,1);
0149 for i = 1:numel(mdl.mat_idx)
0150 idx = mdl.mat_idx{i};
0151 if any(mat_vec(idx))
0152 error('Materials are not unique');
0153 end
0154 mat_vec(idx) = i;
0155 end
0156 if isfield(mdl,'mat_names') && ~isempty(mdl.mat_names)
0157 assert(numel(mdl.mat_names) == numel(mdl.mat_idx),'Every mat_idx must have a name!')
0158 end
0159 if any(mat_vec==0)
0160 mdl.mat_idx(end+1) = {find(mat_vec==1)};
0161 if isfield(mdl,'mat_names')
0162 mdl.mat_names(end+1) = {'Background'};
0163 end
0164 end
0165 end
0166
0167
0168 function do_unit_test()
0169
0170
0171 outfile = tempname();
0172 selfdir = fileparts(which('gmsh_read_mesh'));
0173 mdl1 = gmsh_mk_fwd_model(fullfile(selfdir, 'tests/cube-4.1.msh'));
0174 mdl2 = gmsh_mk_fwd_model(fullfile(selfdir, 'tests/box-4.1.msh'));
0175 data1 = rand(size(mdl1.elems,1), 1);
0176 data2 = rand(size(mdl1.elems,1), 1);
0177 data3 = rand(size(mdl2.elems,1), 1);
0178
0179 gmsh_write_mesh(mdl1, data1, outfile);
0180 mdl = gmsh_mk_fwd_model(outfile);
0181 delete(outfile);
0182 unit_test_cmp('fmdl+data (nn)', mdl1.nodes, mdl.nodes);
0183 unit_test_cmp('fmdl+data (el)', mdl1.elems, mdl.elems);
0184
0185
0186 gmsh_write_mesh(mdl1, outfile);
0187 mdl = gmsh_mk_fwd_model(outfile);
0188 delete(outfile);
0189 unit_test_cmp('fmdl (nn)', mdl1.nodes, mdl.nodes);
0190 unit_test_cmp('fmdl (ee)', mdl1.elems, mdl.elems);
0191
0192
0193 img = mk_image(mdl1, data2);
0194 gmsh_write_mesh(img, data1, outfile);
0195 mdl = gmsh_mk_fwd_model(outfile);
0196 delete(outfile);
0197 unit_test_cmp('img+data (nn)', mdl1.nodes, mdl.nodes);
0198 unit_test_cmp('img+data (ee)', mdl1.elems, mdl.elems);
0199
0200
0201 img = mk_image(mdl1, data2);
0202 gmsh_write_mesh(img, outfile);
0203 mdl = gmsh_mk_fwd_model(outfile);
0204 delete(outfile);
0205 unit_test_cmp('img (nn)', mdl1.nodes, mdl.nodes);
0206 unit_test_cmp('img (ee)', mdl1.elems, mdl.elems);
0207
0208
0209 imdl = select_imdl(mdl1, {'Basic GN dif'});
0210
0211 gmsh_write_mesh(imdl, outfile);
0212 mdl = gmsh_mk_fwd_model(outfile);
0213 delete(outfile);
0214 unit_test_cmp('imdl+fmdl (nn)', mdl1.nodes, mdl.nodes);
0215 unit_test_cmp('imdl+fmdl (ee)', mdl1.elems, mdl.elems);
0216
0217
0218 gmsh_write_mesh(imdl, data1, outfile);
0219 mdl = gmsh_mk_fwd_model(outfile);
0220 delete(outfile);
0221 unit_test_cmp('imdl+fmdl+data (nn)', mdl1.nodes, mdl.nodes);
0222 unit_test_cmp('imdl+fmdl+data (ee)', mdl1.elems, mdl.elems);
0223
0224
0225 imdl.rec_model = mdl2;
0226
0227 gmsh_write_mesh(imdl, outfile);
0228 mdl = gmsh_mk_fwd_model(outfile);
0229 delete(outfile);
0230 unit_test_cmp('imdl+rmdl (nn)', mdl2.nodes, mdl.nodes);
0231 unit_test_cmp('imdl+rmdl (ee)', mdl2.elems, mdl.elems);
0232
0233
0234 gmsh_write_mesh(imdl, data3, outfile);
0235 mdl = gmsh_mk_fwd_model(outfile);
0236 delete(outfile);
0237 unit_test_cmp('imdl+rmdl+data (nn)', mdl2.nodes, mdl.nodes);
0238 unit_test_cmp('imdl+rmdl+data (ee)', mdl2.elems, mdl.elems);
0239