0001 function [Mobj] = read_gmsh_mesh(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 subname = 'read_gmsh_mesh';
0031 global ftbverbose
0032 if ftbverbose
0033 fprintf('\nbegin : %s \n', subname)
0034 end
0035
0036 have_bath = false;
0037 have_strings = false;
0038
0039
0040
0041
0042 Mobj = make_blank_mesh;
0043 coordinate = 'cartesian';
0044
0045
0046
0047
0048
0049 assert(mod(length(varargin), 2) == 0, 'incorrect usage of read_gmsh_mesh, use keyword pairs')
0050
0051
0052 have_msh = false;
0053 have_bath = false;
0054 have_lonlat = false;
0055 have_xy = false;
0056
0057 for i = 1:2:length(varargin) - 1
0058 keyword = lower(varargin{i});
0059
0060 assert(ischar(keyword), 'incorrect usage of read_gmsh_mesh')
0061
0062 switch keyword
0063 case 'msh'
0064 gmsh_msh = varargin{i + 1};
0065 have_msh = true;
0066 case 'bath'
0067 gmsh_bath = varargin{i + 1};
0068 have_bath = true;
0069 case 'coordinate'
0070 coord = varargin{i + 1};
0071 if strcmpi(coord, 'spherical')
0072 coordinate = 'spherical';
0073 have_lonlat = true;
0074 elseif strcmpi(coord, 'cartesian')
0075 coordinate = 'cartesian';
0076 have_xy = true;
0077 else
0078 warning('Unrecognised coordinate system (%s). Valid values are ''spherical'' and ''cartesian''.', coordinate)
0079 end
0080 case 'addcoriolis'
0081 val = varargin{i + 1};
0082 if val
0083 addCoriolis = true;
0084 else
0085 addCoriolis = false;
0086 end
0087 otherwise
0088 disp(varargin{i + 1})
0089 error('Can''t understand property: %s', varargin{i + 1});
0090
0091 end
0092 end
0093
0094
0095
0096
0097
0098 fid = fopen(gmsh_msh, 'rt');
0099 assert(fid >= 0, sprintf('file: %s does not exist\n', gmsh_msh));
0100
0101
0102 if ftbverbose
0103 fprintf('Reading from: %s\n', gmsh_msh)
0104 end
0105
0106
0107
0108
0109
0110
0111 lin = fgetl(fid);
0112 if strcmp(lin, '$NOD')
0113 fileformat = 1;
0114 elseif strcmp(lin, '$MeshFormat')
0115 fileformat = 2;
0116 lin = fgetl(fid);
0117 if feof(fid)
0118 fprintf(sprintf('Syntax error (no version) in: %s\n', filename));
0119 fileformat = 0;
0120 end
0121 form = sscanf(lin, '%f %d %d');
0122 if form(1) < 2
0123 fprintf(sprintf('Unknown mesh format: %s\n', lin));
0124 fileformat = 0;
0125 end
0126 if form(2) ~= 0
0127 fprintf('Sorry, this program can only read ASCII format\n');
0128 fileformat = 0;
0129 end
0130 fgetl(fid);
0131 if feof(fid)
0132 fprintf('Syntax error (no $EndMeshFormat) in: %s\n', filename);
0133 fileformat = 0;
0134 end
0135 lin = fgetl(fid);
0136 if feof(fid)
0137 fprintf('Syntax error (no $Nodes) in: %s\n', filename);
0138 fileformat = 0;
0139 end
0140 end
0141
0142 assert(logical(fileformat), 'Unrecognised mesh.')
0143
0144 nVerts = str2double(fgetl(fid));
0145
0146
0147 C = textscan(fid, '%d %f %f %f', nVerts);
0148 nid = C{1};
0149 x = C{2};
0150 y = C{3};
0151 z = C{4};
0152
0153 if have_lonlat
0154 lon = x;
0155 lat = y;
0156 else
0157 lon = zeros(size(x));
0158 lat = zeros(size(y));
0159 end
0160
0161
0162 lin = fgetl(fid); lin = fgetl(fid);
0163 assert(strcmp(lin, '$EndNodes'), 'Improperly formatted msh file.')
0164 lin = fgetl(fid);
0165 assert(strcmp(lin, '$Elements'), 'Improperly formatted msh file.')
0166 nElems = str2double(fgetl(fid));
0167
0168
0169 tri12 = nan(nElems, 3);
0170
0171
0172
0173
0174
0175 c1 = 1;
0176 c2 = 1;
0177 for i = 1:nElems
0178 lin = fgetl(fid);
0179 C = regexpi(lin, ' ', 'split');
0180 if str2double(C(2)) == 1
0181 tri12(c1, :) = str2double(C(end-2:end));
0182 c1 = c1 + 1;
0183 elseif str2double(C(2)) == 2
0184 tri12(c2, :) = str2double(C(end-2:end));
0185 c2 = c2 + 1;
0186
0187
0188 end
0189 end
0190 tri1 = tri12(1:c1, :);
0191 tri2 = tri12(c1 + 1:c1 + c2, :);
0192
0193
0194 tri2 = tri2(~isnan(tri2(:, 1)), :);
0195
0196
0197 nElems = size(tri2, 1);
0198
0199 have_lonlat = false;
0200 have_xy = false;
0201 if strcmpi(coordinate, 'spherical')
0202 lon = x;
0203 lat = y;
0204
0205
0206
0207 have_lonlat = true;
0208
0209
0210 if max(lon) > 360
0211 warning('You''ve specified spherical coordinates, but your upper longitude value exceeds 360 degrees. Are you sure you have spherical data?')
0212 end
0213 elseif strcmpi(coordinate, 'cartesian')
0214 have_xy = true;
0215 else
0216 warning('Unrecognised coordinate system (%s). Valid values are ''spherical'' and ''cartesian''.', coordinate)
0217 end
0218
0219 fclose(fid);
0220
0221
0222
0223
0224
0225 if have_bath
0226 bath_range = max(h) - min(h);
0227 if have_bath || bath_range == 0
0228 fid = fopen(gmsh_bath, 'rt');
0229 if fid < 0
0230 error('File: %s does not exist', gmsh_bath);
0231 else
0232 if ftbverbose; fprintf('reading gmsh bathymetry from: %s\n', gmsh_bath); end
0233 end
0234 lin = fgetl(fid);
0235 lin = fgetl(fid);
0236 lin = fgetl(fid);
0237 C = textscan(fid, '%s %d', 1);
0238 nVerts_tmp = C{2};
0239 C = textscan(fid, '%s %d', 1);
0240 nElems_tmp = C{2};
0241 if (nVerts - nVerts_tmp) * (nElems - nElems_tmp) ~= 0
0242 fprintf('Dimensions of bathymetry file do not match msh file\n')
0243 fprintf('Bathymetry nVerts: %d\n', nVerts_tmp)
0244 fprintf('Bathymetry nElems: %d\n', nElems_tmp)
0245 error('Stopping...')
0246 end
0247 lin = fgetl(fid);
0248 lin = fgetl(fid);
0249 lin = fgetl(fid);
0250 lin = fgetl(fid);
0251 C2 = textscan(fid, '%f', nVerts);
0252 h = C2{1};
0253 have_bath = true;
0254
0255 clear C2
0256 elseif bath_range ~= 0
0257 have_bath = true;
0258 end
0259
0260
0261 if sum(h > 0) < sum(h < 0)
0262 h = -h;
0263 end
0264 end
0265
0266
0267
0268
0269
0270 Mobj.nVerts = nVerts;
0271 Mobj.nElems = nElems;
0272 Mobj.nativeCoords = coordinate;
0273
0274 if have_lonlat
0275 Mobj.have_lonlat = have_lonlat;
0276 end
0277 if have_xy
0278 Mobj.have_xy = have_xy;
0279 end
0280 if have_bath
0281 Mobj.have_bath = have_bath;
0282 Mobj.h = h;
0283 end
0284 if have_strings
0285 Mobj.have_strings = have_strings;
0286 Mobj.read_obc_nodes = read_obc_nodes;
0287 end
0288 if exist('addCoriolis', 'var') && addCoriolis
0289 Mobj.have_cor = true;
0290 end
0291
0292 Mobj.x = x;
0293 Mobj.y = y;
0294 Mobj.z = z;
0295 Mobj.lon = lon;
0296 Mobj.lat = lat;
0297 Mobj.tri = tri2;
0298
0299 if ftbverbose
0300 fprintf('end : %s\n', subname)
0301 end