【ANSYS模态分析】Ansys Modal Analysis Tutorial Part3

Ansys Modal Analysis Tutorial Part3

creation time: 2024/8/16

上一节,我们已经将 ANSYS 中获得的数据导出。

这一节,我们将想办法将 ANSYS 导出的数据导入 MATLAB,转化成 .mat 文件。

读取 *PRINT 命令导出的数据

  1. 新建 RawTxtMatData 文件夹,新建 cvtAnsysTxt2Mat.m 脚本:

    image-20240816163125767

  2. 将 ANSYS 导出的 .txt 文件复制进 RawTxt 文件夹:

    image-20240816163223190

  3. 修改并运行 cvtAnsysTxt2Mat.m 脚本,结果保存在 MatData 文件夹中:

    image-20240816163337298

    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 命令导出的数据

  1. 如果有 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
    
  2. 或者使用以下函数(可能存在错误):

    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
    
  3. HBMAT 导出的质量、刚度、阻尼矩阵应与 *PRINT 导出的矩阵一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值