Ansys Modal Analysis Tutorial Part3
creation time: 2024/8/16
上一节,我们已经将 ANSYS 中获得的数据导出。
这一节,我们将想办法将 ANSYS 导出的数据导入 MATLAB,转化成 .mat 文件。
读取 *PRINT 命令导出的数据
-
新建
RawTxt
和MatData
文件夹,新建cvtAnsysTxt2Mat.m
脚本: -
将 ANSYS 导出的
.txt
文件复制进RawTxt
文件夹: -
修改并运行
cvtAnsysTxt2Mat.m
脚本,结果保存在MatData
文件夹中:cvtAnsysTxt2Mat.m
脚本内容:%% 将 ANSYS 中使用 *PRINT 输出的数据转化为 mat 格式并保存 % author: Richard % version: % date: 2024-07-04 - 初次建立 % 2024-08-16 - 修改调整 % brief: % atention: %% cvtAnsysTxt2Mat.m ————————————————————%% clc; clear; close all; %% READ ————————————————————%% MapForward = readAnsysTxt('RawTxt\MapForward.txt', 'VEC', 'R'); Phi = readAnsysTxt('RawTxt\Phi.txt', 'MAT', 'R'); %% SAVE ————————————————————%% save MatData\MapForward.mat MapForward save MatData\Phi.mat Phi; %% Function:读取 ANSYS TXT function mat = readAnsysTxt(file_name, MatorVec, RorC) %READANSYSTXT % date: 2024-08-16 % brief: 读取 ANSYS TXT % atention: % Input: % file_name - 文件名 % MatorVec - 对象是矩阵还是向量,'MAT' \ 'VEC' % RorC - 对象是实数还是复数,'R' \ 'C' % Output: % mat - 以 mat 格式返回矩阵(或向量) % --------- % 读取数据文件 txt = fileread(file_name); % 按行分割并获取数据的行数 lines = strsplit(txt, '\n'); line_num = length(lines); % 获取矩阵大小 % 向量模式 if strcmpi(MatorVec, 'vec') % 从后往前匹配 [row, col] 格式 pattern1 = '\[(\d+)\]'; for i = line_num:-1:1 line = lines{i}; if ~isempty(line) % 使用正则表达式匹配 matches = regexp(line, pattern1, 'tokens'); if ~isempty(matches) % 提示匹配结果 disp(['文件 ', file_name, '第', num2str(i), '行匹配结果:']) for j = 1:length(matches) disp(matches{j}) end % 获取矩阵大小 Mat_Size = [str2double(matches{end}), 1]; % 跳出循环 break; end end end % 矩阵模式 elseif strcmpi(MatorVec, 'mat') % 从后往前匹配 [row, col] 格式 pattern1 = '\[(\d+),\s*(\d+)\]'; for i = line_num:-1:1 line = lines{i}; if ~isempty(line) % 使用正则表达式匹配 matches = regexp(line, pattern1, 'tokens'); if ~isempty(matches) % 提示匹配结果 disp(['文件 ', file_name, '第', num2str(i), '行匹配结果:']) for j = 1:length(matches) disp(matches{j}) end % 获取矩阵大小 Mat_Size = [str2double(matches{end}{1}), str2double(matches{end}{2})]; % 跳出循环 break; end end end else error('矩阵 \ 向量 选项设置错误') end % 提示矩阵大小 disp(['文件 ', file_name, ',矩阵大小:']); disp(Mat_Size); % 创建空矩阵 mat = zeros(Mat_Size); % 获取矩阵数据 % 向量模式 if strcmpi(MatorVec, 'vec') % 实数模式 if strcmpi(RorC, 'r') % 匹配 [row]: value 格式 pattern1 = '\[(\d+)\]\s*:\s*(\d+)'; % value 为整数 pattern2 = '\[(\d+)\]\s*:\s*([-+]?\d*\.\d+([eE][-+]?\d+)?)'; % value 为科学计数法 for i = 1:line_num line = lines{i}; if ~isempty(line) % 使用正则表达式匹配 matches = regexp(line, pattern1, 'tokens'); if isempty(matches) matches = regexp(line, pattern2, 'tokens'); if isempty(matches) continue; end end % 提示匹配结果 disp(['文件 ', file_name, '第', num2str(i), '行匹配结果:']) for j = 1:length(matches) disp(matches{j}) end % 赋值 for j = 1:length(matches) idx = str2double(matches{j}(1)); value = str2double(matches{j}(2)); mat(idx) = value; end end end % 复数模式 elseif strcmpi(RorC, 'c') % 匹配 [row]: value1 value2 格式 pattern1 = '\[(\d+)\]\s*:\s*(\d+)\s*(\d+)'; % value 为整数 pattern2 = '\[(\d+)\]\s*:\s*([-+]?\d*\.\d+([eE][-+]?\d+)?)\s*([-+]?\d*\.\d+([eE][-+]?\d+)?)'; % value 为科学计数法 for i = 1:line_num line = lines{i}; if ~isempty(line) % 使用正则表达式匹配 matches = regexp(line, pattern1, 'tokens'); if isempty(matches) matches = regexp(line, pattern2, 'tokens'); if isempty(matches) continue; end end % 提示匹配结果 disp(['文件 ', file_name, '第', num2str(i), '行匹配结果:']) for j = 1:length(matches) disp(matches{j}) end % 赋值 for j = 1:length(matches) idx = str2double(matches{j}(1)); value1 = str2double(matches{j}(2)); value2 = str2double(matches{j}(3)); mat(idx) = value1 + 1i*value2; end end end else error('实数 \ 复数 选项设置错误') end % 矩阵模式 elseif strcmpi(MatorVec, 'mat') % 实数模式 if strcmpi(RorC, 'r') % 匹配 [row,col]: value 格式 pattern1 = '\[\s*(\d+),\s*(\d+)\]\s*:\s*([-+]?\d*\.\d+([eE][-+]?\d+)?)'; % value 为科学计数法 pattern2 = '\[\s*(\d+),\s*(\d+)\]\s*:\s*(\d+)'; % value 为整数 for i = 1:line_num line = lines{i}; if ~isempty(line) % 使用正则表达式匹配 matches = regexp(line, pattern1, 'tokens'); if isempty(matches) matches = regexp(line, pattern2, 'tokens'); if isempty(matches) continue; end end % 提示匹配结果 disp(['文件 ', file_name, '第', num2str(i), '行匹配结果:']) for j = 1:length(matches) disp(matches{j}) end % 赋值 for j = 1:length(matches) idx1 = str2double(matches{j}(1)); idx2 = str2double(matches{j}(2)); value = str2double(matches{j}(3)); mat(idx1, idx2) = value; end end end % 复数模式 elseif strcmpi(RorC, 'c') % 匹配 [row,col]: value1 value2 格式 pattern1 = '\[\s*(\d+),\s*(\d+)\]\s*:\s*([-+]?\d*\.\d+([eE][-+]?\d+)?)\s*([-+]?\d*\.\d+([eE][-+]?\d+)?)'; % value 为科学计数法 pattern2 = '\[\s*(\d+),\s*(\d+)\]\s*:\s*(\d+)\s*(\d+)'; % value 为整数 for i = 1:line_num line = lines{i}; if ~isempty(line) % 使用正则表达式匹配 matches = regexp(line, pattern1, 'tokens'); if isempty(matches) matches = regexp(line, pattern2, 'tokens'); if isempty(matches) continue; end end % 提示匹配结果 disp(['文件 ', file_name, '第', num2str(i), '行匹配结果:']) for j = 1:length(matches) disp(matches{j}) end % 赋值 for j = 1:length(matches) idx1 = str2double(matches{j}(1)); idx2 = str2double(matches{j}(2)); value1 = str2double(matches{j}(3)); value2 = str2double(matches{j}(4)); mat(idx1, idx2) = value1 + 1i*value2; end end end else error('实数 \ 复数 选项设置错误') end else error('矩阵 \ 向量 选项设置错误') end end
读取 HBMAT 命令导出的数据
-
如果有
hb_to_msm.m
函数文件,可以使用以下函数:function matrix = fctn_readHBMAT(file_name) % brief: 读取ANSYS数据 % author: Richard % time: 2024/7/4 % 读取数据文件 matrix = hb_to_msm(file_name); % 将稀疏矩阵转换为double类型 matrix = full(matrix); % 利用下三角阵生成对称矩阵 matrix = matrix + matrix' - diag(diag(matrix)); end
-
或者使用以下函数(可能存在错误):
function [matrix, right_vector] = fctn_readHBMAT(file_name) % brief: 读取ANSYS数据 % author: Richard % time: 2024/7/4 % 读取数据文件 dats = fileread(file_name); % 按行分割 lines = strsplit(dats, '\n'); % 获取数据的行数 num_of_rows = length(lines); % 第二行包含索引信息,使用正则表达式提取 pattern = '[-+]?\d*\.?\d+([eE][-+]?\d+)?'; numbers = regexp(lines{2}, pattern, 'match'); rows_of_data = str2double(numbers{1}); % 总行数,不包括文件头 rows_of_matrixColPointer = str2double(numbers{2}); % 矩阵列指针的总行数 rows_of_matrixRowIndex = str2double(numbers{3}); % 矩阵行索引的总行数 rows_of_matrixElement = str2double(numbers{4}); % 矩阵元素数值总行数 rows_of_rightVector = str2double(numbers{5}); % 右边项总行数 % 第三行包含矩阵信息,使用正则表达式提取 pattern = '[-+]?\d*\.?\d+([eE][-+]?\d+)?'; numbers = regexp(lines{3}, pattern, 'match'); rows_of_matrix = str2double(numbers{1}); % 矩阵行数 cols_of_matrix = str2double(numbers{2}); % 矩阵列数 num_of_matrixRowIndex = str2double(numbers{3}); % 矩阵行索引数(对组装后的矩阵,该值等于矩阵行索引数) % Step1:重建列指针 % 从第 idx1_start = num_of_rows - rows_of_data 开始,往后是列指针索引 idx1_start = num_of_rows - rows_of_data; % 列指针索引起始行 % 新建索引向量 idx1_vector = zeros(rows_of_matrixRowIndex,1); % 零初始化列指针索引 col_cnt = 1; % 列索引计数器 % 读取索引 for i = idx1_start+1 : idx1_start + rows_of_matrixColPointer-1 idx1_vector(str2double(lines{i-1}):str2double(lines{i})-1) = col_cnt; % 将 x 个元素赋值为当前的列索引 col_cnt = col_cnt+1; % 列索引计数器 + 1 end % Step2:重建行索引 % 从第 idx2_start = idx1_start + rows_of_matrixColPointer 开始,往后是行索引 idx2_start = idx1_start + rows_of_matrixColPointer; % 新建索引向量 idx2_vector = zeros(rows_of_matrixRowIndex,1); % 读取索引 for i = idx2_start : idx2_start + rows_of_matrixRowIndex-1 idx2_vector(i - idx2_start + 1) = str2double(lines{i}); end % Step3:重建数据 % 从第 idx3_start = idx2_start + rows_of_matrixRowIndex 开始,往后是数据 idx3_start = idx2_start + rows_of_matrixRowIndex; % 新建索引向量 idx3_vector = zeros(rows_of_matrixElement,1); % 读取索引 for i = idx3_start : idx3_start + rows_of_matrixElement-1 % 使用正则表达式提取数值 pattern = '[-+]?\d*\.?\d+([eE][-+]?\d+)?'; numbers = regexp(lines{i}, pattern, 'match'); % 数据采用了科学计数法表示 if length(numbers) == 1 idx3_vector(i - idx3_start + 1) = str2double(numbers{1}); elseif length(numbers) == 2 idx3_vector(i - idx3_start + 1) = str2double(numbers{1}) * 10^(str2double(numbers{2})); else disp('Wrong.') end end % Step4:重建右端向量 if rows_of_rightVector ~= 0 % 从第 idx4_start = idx3_start + rows_of_matrixElement 开始,往后是右端项 idx4_start = idx3_start + rows_of_matrixElement; % 新建右端项向量 idx4_vector = zeros(rows_of_rightVector,1); % 读取索引 for i = idx4_start : idx4_start + rows_of_rightVector-1 % 使用正则表达式提取数值 pattern = '[-+]?\d*\.?\d+([eE][-+]?\d+)?'; numbers = regexp(lines{i}, pattern, 'match'); % 数据采用了科学计数法表示 if length(numbers) == 1 idx4_vector(i - idx4_start + 1) = str2double(numbers{1}); elseif length(numbers) == 2 idx4_vector(i - idx4_start + 1) = str2double(numbers{1}) * 10^(str2double(numbers{2})); else disp('Wrong.') end end end % 复制右端项 right_vector = idx4_vector; % 新建稀疏矩阵 matrix = sparse ( idx2_vector, idx1_vector, idx3_vector, rows_of_matrix, cols_of_matrix); % 将稀疏矩阵转换为 Double 类型 matrix = full(matrix); % 利用下三角阵生成对称矩阵 matrix = matrix + matrix' - diag(diag(matrix)); end
-
HBMAT
导出的质量、刚度、阻尼矩阵应与*PRINT
导出的矩阵一致。