137 lines
4.2 KiB
Matlab
137 lines
4.2 KiB
Matlab
function export_comsol_normE_from_dat(varargin)
|
||
%EXPORT_COMSOL_NORME_FROM_DAT 按 dat 中 Vertex 顺序从 COMSOL 插值 normE
|
||
%
|
||
% export_comsol_normE_from_dat
|
||
% export_comsol_normE_from_dat('normExpr', 'ewfd.Ex*conj(ewfd.Ex)+...')
|
||
% export_comsol_normE_from_dat('exExpr', 'ewfd.Ex', 'eyExpr', 'ewfd.Ey', 'ezExpr', 'ewfd.Ez')
|
||
%
|
||
% 若 normExpr 未指定或为空,将自动探测 Ex/Ey/Ez 并组合成 normE。
|
||
% 若模型没有预定义 normE 变量(emw.normE 报错即属此类),请用自动探测或手动指定分量。
|
||
|
||
opts = parseOpts(varargin);
|
||
|
||
datPath = opts.datFile;
|
||
if ~isfile(datPath)
|
||
error('找不到网格文件: %s(请先 getMesh + export 生成 SBCmesh.dat)', datPath);
|
||
end
|
||
if ~isfile(opts.mphFile)
|
||
error('找不到 COMSOL 模型: %s', opts.mphFile);
|
||
end
|
||
|
||
[V, nbr] = load_dat_vertices(datPath);
|
||
fprintf('已从 %s 读取 %d 个顶点(dat 顺序)\n', datPath, nbr);
|
||
|
||
model = mphload(opts.mphFile);
|
||
coord = V.'; % mphinterp: 3×N
|
||
|
||
probeCoord = mean(V, 1).';
|
||
if opts.autoDetect
|
||
info = resolve_comsol_e_field(model, probeCoord);
|
||
if isempty(opts.exExpr)
|
||
opts.exExpr = info.exExpr;
|
||
opts.eyExpr = info.eyExpr;
|
||
opts.ezExpr = info.ezExpr;
|
||
end
|
||
if isempty(opts.normExpr)
|
||
opts.normExpr = info.normExpr;
|
||
end
|
||
end
|
||
|
||
if isempty(opts.normExpr)
|
||
if isempty(opts.exExpr)
|
||
error(['未指定 normExpr,且自动探测失败。\n', ...
|
||
'请先运行 probe_comsol_fields,或手动传入 ex/ey/ez 表达式。']);
|
||
end
|
||
opts.normExpr = sprintf('sqrt(%s*conj(%s)+%s*conj(%s)+%s*conj(%s))', ...
|
||
opts.exExpr, opts.exExpr, opts.eyExpr, opts.eyExpr, opts.ezExpr, opts.ezExpr);
|
||
end
|
||
|
||
fprintf('正在插值 normE 表达式:\n %s\n', opts.normExpr);
|
||
normE = mphinterp(model, opts.normExpr, 'coord', coord);
|
||
normE = real(normE(:));
|
||
|
||
if numel(normE) ~= nbr
|
||
error('插值结果长度 %d 与顶点数 %d 不一致', numel(normE), nbr);
|
||
end
|
||
|
||
nanMask = isnan(normE) | isinf(normE);
|
||
if any(nanMask)
|
||
warning('export_comsol_normE:NaN', ...
|
||
'%d 个顶点插值为 NaN/Inf(可能落在网格外或未求解)', nnz(nanMask));
|
||
end
|
||
|
||
if opts.exportComponents
|
||
fprintf('正在插值 Ex/Ey/Ez ...\n');
|
||
Ex = mphinterp(model, opts.exExpr, 'coord', coord);
|
||
Ey = mphinterp(model, opts.eyExpr, 'coord', coord);
|
||
Ez = mphinterp(model, opts.ezExpr, 'coord', coord);
|
||
end
|
||
|
||
if ~exist(opts.outDir, 'dir')
|
||
mkdir(opts.outDir);
|
||
end
|
||
|
||
writeNormE(fullfile(opts.outDir, 'normE'), normE);
|
||
|
||
if opts.exportComponents
|
||
writeComplexField(fullfile(opts.outDir, 'Ex'), Ex);
|
||
writeComplexField(fullfile(opts.outDir, 'Ey'), Ey);
|
||
writeComplexField(fullfile(opts.outDir, 'Ez'), Ez);
|
||
end
|
||
|
||
if opts.exportTable
|
||
T = [(1:nbr).', V, normE];
|
||
writematrix(T, fullfile(opts.outDir, 'vertex_normE.dat'), 'Delimiter', 'tab');
|
||
end
|
||
|
||
metaFile = fullfile(opts.outDir, 'comsol_expr.txt');
|
||
fid = fopen(metaFile, 'w');
|
||
if fid > 0
|
||
fprintf(fid, 'normExpr=%s\n', opts.normExpr);
|
||
fprintf(fid, 'exExpr=%s\n', opts.exExpr);
|
||
fprintf(fid, 'eyExpr=%s\n', opts.eyExpr);
|
||
fprintf(fid, 'ezExpr=%s\n', opts.ezExpr);
|
||
fclose(fid);
|
||
end
|
||
|
||
fprintf('已写出 %s\n', fullfile(opts.outDir, 'normE'));
|
||
fprintf(' max(normE) = %.12g\n', max(normE(~nanMask)));
|
||
fprintf(' 行顺序与 %s 的 Vertex 第 1..%d 行一一对应\n', datPath, nbr);
|
||
end
|
||
|
||
function opts = parseOpts(args)
|
||
p = inputParser;
|
||
p.addParameter('mphFile', 'SBC.mph', @ischar);
|
||
p.addParameter('datFile', 'SBCmesh.dat', @ischar);
|
||
p.addParameter('normExpr', '', @ischar);
|
||
p.addParameter('exExpr', '', @ischar);
|
||
p.addParameter('eyExpr', '', @ischar);
|
||
p.addParameter('ezExpr', '', @ischar);
|
||
p.addParameter('outDir', 'OutFile_comsol', @ischar);
|
||
p.addParameter('exportComponents', false, @islogical);
|
||
p.addParameter('exportTable', true, @islogical);
|
||
p.addParameter('autoDetect', true, @islogical);
|
||
p.parse(args{:});
|
||
opts = p.Results;
|
||
end
|
||
|
||
function writeNormE(path, normE)
|
||
fid = fopen(path, 'w');
|
||
if fid < 0
|
||
error('无法写入: %s', path);
|
||
end
|
||
c = onCleanup(@() fclose(fid));
|
||
fprintf(fid, '//\n');
|
||
fprintf(fid, '%.12g\n', normE);
|
||
end
|
||
|
||
function writeComplexField(path, field)
|
||
fid = fopen(path, 'w');
|
||
if fid < 0
|
||
error('无法写入: %s', path);
|
||
end
|
||
c = onCleanup(@() fclose(fid));
|
||
fprintf(fid, '//\n');
|
||
fprintf(fid, '%.12g %.12g\n', [real(field(:)), imag(field(:))].');
|
||
end
|