workbench绘制好网格后点击生成Mapdl输入文件,导出的格式是.dat,启动Mechanical APDL 导入.dat,cdwrite,db,test,cdb命令导出成.cdb文件,在matlab中进行节点的修改,重新写入.cdb文件。通过在workbench的外部模型导入,直接使用修改后的网格进行有限元仿真。
matlab程序如下:
clc; clear;
% === 启动并行池(基于线程的轻量加速) ===
if isempty(gcp('nocreate'))
parpool('threads');
end
% === 文件读取 ===
filename = "D:\ANASYS results\CDB\test222.cdb";
fid = fopen(filename, 'r');
raw_lines = {};
in_nblock = false;
format_line_idx = 0;
nblock_end_idx = 0;
while ~feof(fid)
line = fgetl(fid);
raw_lines{end+1} = line; %#ok<AGROW>
if contains(line, 'NBLOCK')
in_nblock = true;
elseif in_nblock && startsWith(strtrim(line), '(')
format_line_idx = length(raw_lines); % 格式说明行索引
elseif in_nblock && ~isempty(regexp(line, '^\s*\d+', 'once'))
% 正常数据行
elseif in_nblock
in_nblock = false;
nblock_end_idx = length(raw_lines);
end
end
fclose(fid);
% === 提取 NBLOCK 数据行 ===
data_lines = raw_lines(format_line_idx+1 : nblock_end_idx-1);
n_lines = length(data_lines);
% === 预分配 ===
node_ids = zeros(n_lines, 1);
coords = zeros(n_lines, 3);
% === 并行解析节点数据 ===
parfor i = 1:n_lines
line = data_lines{i};
if isempty(strtrim(line)), continue; end
if length(line) < 90
line = [line repmat(' ', 1, 90-length(line))];
end
node_ids(i) = str2double(line(1:9));
coords(i, :) = [str2double(line(28:48)), ...
str2double(line(49:69)), ...
str2double(line(70:90))];
end
% === 显示部分节点 ===
disp('前5个节点坐标:');
disp(table(node_ids(1:5), coords(1:5,1), coords(1:5,2), coords(1:5,3), ...
'VariableNames', {'NodeID', 'X', 'Y', 'Z'}));
%% === z = -10 平面分割并上下移动 ===
upper_idx = coords(:,3) > -10;
lower_idx = ~upper_idx;
coords_new = coords;
coords_new=changecoords(coords);
%% === 科学计数法修正函数(E+01 -> E+001)===
fixE = @(s) regexprep(fix_leading_space(s), 'E([\+\-])(\d{1,2})$', 'E$10$2');
% === 构造新数据行 ===
new_data_lines = data_lines;
for i = 1:n_lines
if isempty(strtrim(data_lines{i})), continue; end
node_id = node_ids(i);
x = fixScientific(coords_new(i, 1));
y = fixScientific(coords_new(i, 2));
z = fixScientific(coords_new(i, 3));
new_line = sprintf('%9d%9d%9d%s%s%s', node_id, 0, 0, x, y, z);
new_data_lines{i} = new_line;
end
% === 构造完整新文件 ===
output_file = "D:\ANASYS results\CDB\output333.cdb";
fid = fopen(output_file, 'w');
for i = 1:format_line_idx
fprintf(fid, '%s\n', raw_lines{i});
end
for i = 1:n_lines
fprintf(fid, '%s\n', new_data_lines{i});
end
fprintf(fid, 'N,UNBL,LOC, -1,\n');
for i = nblock_end_idx+1 : length(raw_lines)
fprintf(fid, '%s\n', raw_lines{i});
end
fclose(fid);
disp(['✅ 修改后的 .cdb 文件已保存至:' output_file]);
%% === 可视化验证 ===
figure;
scatter3(coords(:,1), coords(:,2), coords(:,3), 0.1, 'k.');
title('原始节点坐标');
figure;
scatter3(coords_new(:,1), coords_new(:,2), coords_new(:,3), 0.1, 'k.');
title('新节点坐标');
%% === 科学计数法修正函数 ===
% 确保三位指数并处理前导空格
function str = fixScientific(num)
% 使用21位宽度,13位小数的科学计数法
str = sprintf('%21.13E', num);
% 处理指数部分为3位数
str = regexprep(str, 'E([\+\-])(\d{1,2})$', 'E$10$2');
% 移除所有前导空格
str = strtrim(str);
% 确保总长度为21,正数添加一个前导空格
if num >= 0
str = [' ' str];
end
% 如果长度不足21,在前面补充需要的空格
if length(str) < 21
str = [repmat(' ', 1, 21-length(str)) str];
end
end