XIAN-FEM-2026June/三维matlab代码/matlab 3D一阶基+散射边界条件/load_SBCmesh_dat.m

122 lines
3.4 KiB
Matlab
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function mesh = load_SBCmesh_dat(datFile)
%LOAD_SBCMESH_DAT 读取 OpticsFEM/COMSOL 导出的 SBCmesh.dat1-based 索引)。
% 与 3D opticsfem-master Mesh_3D 读入格式一致,供 main.m 与 C++ 共用同一网格。
fid = fopen(datFile, 'r');
if fid < 0
error('无法打开网格文件: %s', datFile);
end
cleanup = onCleanup(@() fclose(fid));
tag = read_tag(fid);
assert(strcmp(tag, 'NbrVertex'), 'Expected NbrVertex');
mesh.NbrVertex = read_int(fid);
tag = read_tag(fid);
assert(strcmp(tag, 'Vertex'), 'Expected Vertex');
mesh.Vertex = reshape(fscanf(fid, '%f', mesh.NbrVertex * 3), 3, []).';
tag = read_tag(fid);
assert(strcmp(tag, 'NbrTet'), 'Expected NbrTet');
mesh.NbrTet = read_int(fid);
tag = read_tag(fid);
assert(strcmp(tag, 'Tet'), 'Expected Tet');
mesh.Tet = reshape(fscanf(fid, '%d', mesh.NbrTet * 4), 4, []).';
tag = read_tag(fid);
assert(strcmp(tag, 'DomainOfTet'), 'Expected DomainOfTet');
mesh.DomainOfTet = fscanf(fid, '%d', mesh.NbrTet);
tag = read_tag(fid);
assert(strcmp(tag, 'NbrEdge'), 'Expected NbrEdge');
mesh.NbrEdge = read_int(fid);
tag = read_tag(fid);
assert(strcmp(tag, 'Edge'), 'Expected Edge');
mesh.Edge = reshape(fscanf(fid, '%d', mesh.NbrEdge * 2), 2, []).';
tag = read_tag(fid);
assert(strcmp(tag, 'EdgeOfTet'), 'Expected EdgeOfTet');
mesh.EdgeOfTet = reshape(fscanf(fid, '%d', mesh.NbrTet * 6), 6, []).';
tag = read_tag(fid);
assert(strcmp(tag, 'NbrTri'), 'Expected NbrTri');
mesh.NbrTri = read_int(fid);
tag = read_tag(fid);
assert(strcmp(tag, 'Tri'), 'Expected Tri');
mesh.Tri = reshape(fscanf(fid, '%d', mesh.NbrTri * 3), 3, []).';
tag = read_tag(fid);
assert(strcmp(tag, 'DomainOfTri'), 'Expected DomainOfTri');
mesh.DomainOfTri = fscanf(fid, '%d', mesh.NbrTri);
tag = read_tag(fid);
assert(strcmp(tag, 'ConnOfTri'), 'Expected ConnOfTri');
mesh.ConnOfTri = reshape(fscanf(fid, '%d', mesh.NbrTri * 2), 2, []).';
tag = read_tag(fid);
assert(strcmp(tag, 'NormOfFace'), 'Expected NormOfFace');
nbrNorm = read_int(fid);
maxDom = 14;
mesh.NormOfFace = zeros(maxDom, 3);
for k = 1:nbrNorm
row = fscanf(fid, '%f', 4);
if numel(row) < 4
error('NormOfFace 第 %d 条记录不完整(文件可能被截断)', k);
end
domainId = round(row(1));
if domainId > maxDom
extra = zeros(domainId, 3);
extra(1:maxDom, :) = mesh.NormOfFace;
mesh.NormOfFace = extra;
maxDom = domainId;
end
mesh.NormOfFace(domainId, :) = row(2:4);
end
% 仅对仍为 0 的 SBC 模板域补默认PBC 网格 1..9 已在 dat 中给出)
defaults = {
1, [-1, 0, 0];
2, [0, -1, 0];
3, [0, 0, -1];
4, [0, 0, 1];
5, [0, 1, 0];
8, [0, 0, 1];
14, [1, 0, 0];
};
for k = 1:size(defaults, 1)
d = defaults{k, 1};
if norm(mesh.NormOfFace(d, :)) < 1e-30
mesh.NormOfFace(d, :) = defaults{k, 2};
end
end
if min(mesh.EdgeOfTet(:)) < 1
error(['SBCmesh.dat 中 EdgeOfTet 必须为 1-based最小值=%d。' ...
'请使用 export_SBCmesh_to_dat 或修正后再读。'], min(mesh.EdgeOfTet(:)));
end
fprintf('已加载 %s: NbrTet=%d, NbrEdge=%d, NbrTri=%d\n', ...
datFile, mesh.NbrTet, mesh.NbrEdge, mesh.NbrTri);
end
function tag = read_tag(fid)
tag = '';
while true
line = fgetl(fid);
if ~ischar(line)
error('Unexpected end of mesh file.');
end
line = strtrim(line);
if ~isempty(line)
tag = line;
return;
end
end
end
function value = read_int(fid)
value = fscanf(fid, '%d', 1);
end