COMSOL学习笔记(一)曲线图数据导出
一、直接画图
点击COMSOL 6.4中的曲线图的图像快照并调整字号,直接画图。


二、导出数据→matlab处理→origin作图
1. 导出数据
首先,在结果的导出中,添加数据。

其次,选好数据集,然后在表达式中输入我们要导出的扫参变量和对应的电场值。

2. Matlab整理数据
将comsol导出的txt数据整理成适合画图的origin数据:
c
clc; clear; close all;
%% ========= 1) 文件名 =========
filename = 'rp_rr.txt'; % 你的 COMSOL 导出文件
%% ========= 2) 读入文本 =========
fid = fopen(filename, 'r');
if fid == -1
error('无法打开文件: %s', filename);
end
C = textscan(fid, '%s', 'Delimiter', '\n', 'Whitespace', '');
fclose(fid);
lines = C{1};
%% ========= 3) 找表头 =========
header_idx = find(contains(lines, 'ec.Ez'), 1, 'first');
if isempty(header_idx)
error('没找到包含 ec.Ez 的表头行,请检查导出文件格式。');
end
data_lines = lines(header_idx+1:end);
%% ========= 4) 提取 Rp, rr, z, Ez =========
% 按你当前导出的格式:
% r, z, Rp, rr, Rp(m), rr(m), z(m), ec.Ez
rawData = [];
for i = 1:length(data_lines)
line = strtrim(data_lines{i});
if isempty(line)
continue;
end
nums = regexp(line, '[-+]?\d*\.?\d+(?:[Ee][-+]?\d+)?', 'match');
vals = str2double(nums);
if numel(vals) >= 8
Rp = vals(3);
rr = vals(4);
z = vals(7);
Ez = vals(8);
rawData = [rawData; Rp, rr, z, Ez]; %#ok<AGROW>
end
end
if isempty(rawData)
error('没有成功提取到数据。');
end
%% ========= 5) 删除异常点 =========
rawData = rawData(all(~isnan(rawData), 2), :);
% 删除接近 0 的假端点
threshold = 1e-15;
rawData = rawData(abs(rawData(:,4)) > threshold, :);
%% ========= 6) 排序 =========
data_sorted = sortrows(rawData, [1 2 3]);
%% ========= 7) 去重 =========
% 对每组 (Rp, rr, z),只保留 |Ez| 最大的那个
[groupKeys, ~, groupID] = unique(data_sorted(:,1:3), 'rows');
uniqueData = zeros(size(groupKeys,1), 4);
for k = 1:size(groupKeys,1)
idx = (groupID == k);
sub = data_sorted(idx, :);
[~, imax] = max(abs(sub(:,4)));
uniqueData(k, :) = sub(imax, :);
end
outData = sortrows(uniqueData, [1 2 3]);
%% ========= 8) 保存四列表(给 MATLAB 自己检查) =========
outFile1 = 'comsol_sorted_for_matlab.txt';
fid = fopen(outFile1, 'w');
fprintf(fid, 'Rp\trr\tarc_length\tEz\n');
fclose(fid);
dlmwrite(outFile1, outData, '-append', 'delimiter', '\t', 'precision', '%.15g');
%% ========= 9) 生成给 Origin 的"宽表" =========
Rp_list = unique(outData(:,1));
rr_list = unique(outData(:,2));
curveNames = {};
curveData = {};
for i = 1:length(Rp_list)
for j = 1:length(rr_list)
mask = abs(outData(:,1)-Rp_list(i)) < 1e-12 & ...
abs(outData(:,2)-rr_list(j)) < 1e-12;
tmp = outData(mask, :);
if isempty(tmp)
continue;
end
tmp = sortrows(tmp, 3); % 按 arc_length 排序
curveNames{end+1} = sprintf('Rp_%g_rr_%g', Rp_list(i), rr_list(j)); %#ok<SAGROW>
curveData{end+1} = tmp(:, [3 4]); %#ok<SAGROW> % [arc_length, Ez]
end
end
% 取公共横坐标(默认所有曲线采样点一致)
x_ref = curveData{1}(:,1);
n = length(x_ref);
m = length(curveData);
Y = nan(n, m);
for k = 1:m
tmp = curveData{k};
% 如果某条曲线点数一致且横坐标一致,直接填
if length(tmp(:,1)) == n && max(abs(tmp(:,1)-x_ref)) < 1e-12
Y(:,k) = tmp(:,2);
else
% 若有少量不一致,插值到公共横坐标
Y(:,k) = interp1(tmp(:,1), tmp(:,2), x_ref, 'linear', NaN);
end
end
wideData = [x_ref, Y];
%% ========= 10) 写出给 Origin 的宽表 =========
outFile2 = 'comsol_wide_for_origin.txt';
fid = fopen(outFile2, 'w');
% 表头
fprintf(fid, 'arc_length');
for k = 1:length(curveNames)
fprintf(fid, '\t%s', curveNames{k});
end
fprintf(fid, '\n');
% 数据
for i = 1:size(wideData,1)
fprintf(fid, '%.15g', wideData(i,1));
for j = 2:size(wideData,2)
fprintf(fid, '\t%.15g', wideData(i,j));
end
fprintf(fid, '\n');
end
fclose(fid);
fprintf('已保存:\n');
fprintf('1) %s (四列表,给 MATLAB 检查)\n', outFile1);
fprintf('2) %s (宽表,给 Origin 画多曲线)\n', outFile2);
%% ========= 11) MATLAB 里画所有曲线 =========
figure;
hold on; grid on;
for k = 1:m
plot(x_ref, Y(:,k), 'LineWidth', 1);
end
xlabel('Arc length (m)');
ylabel('E_z (V/m)');
title('COMSOL exported data plotted in MATLAB');
xlim([0, 2]);
ylim([-1.45e-9, -0.7e-9]);
ax = gca;
ax.YAxis.Exponent = -9;
hold off;
3. origin作图
将txt文件直接拖入到origin中,然后绘制折线图。
