【有限元学习笔记】二维四边形单元位移动画云图可视化(有限元后处理)——MATLAB程序

前言

  在有限元求解完成后,需要对结果进行可视化,比如位移云图、应力云图和反力云图等。在前面一篇文章中已经实现了位移云图可视化(静态),本文章将继续使用MATLAB对二维四边形单元进行位移动画云图可视化。

准备数据

  第一步还是准备数据,节点和单元与前一篇文章相同,不同的是需要准备多个时刻的节点位移数据,下面提供了5个时刻的位移实例数据。

%% 准备数据
% 坐标
XYZ = [ 0 0;
        1 0;
        2 0;
        0 1;
        1 1;
        2 1;
        0 2;
        1 2;
        2 2;];

% 单元
EL = [  1 2	5 4;
        2 3	6 5;
        4 5	8 7;
        5 6	9 8;];

% 水平方向位移时刻t=0.00
DX0 = zeros(9,1);
% 水平方向位移时刻t=0.25
DX1 = [ 0; 0; 0; 0.0174337; 0.0151149; 0.0186553; 0.0318029; 0.0311055; 0.0330584;];
% 水平方向位移时刻t=0.50
DX2 = [ 0; 0; 0; 0.0348675; 0.0302299; 0.0373107; 0.0636058; 0.0622109; 0.0661167;];
% 水平方向位移时刻t=0.75
DX3 = [ 0; 0; 0; 0.0523012; 0.0453448; 0.055966; 0.0954087; 0.0933164; 0.0991751;];
% 水平方向位移时刻t=1.00
DX4 = [ 0; 0; 0; 0.0697349; 0.0604598; 0.0746214; 0.127212; 0.124422; 0.132233;];
% 所有时刻的水平位移
DX = [DX0, DX1, DX2, DX3, DX4];

% 竖直方向位移时刻t=0.00
DY0 = zeros(9,1);
% 竖直方向位移时刻t=0.25
DY1 = [ 0; 0; 0; -0.00104918; -0.0108555; -0.0209396; -0.00926313; -0.0219317; -0.0346498;];
% 竖直方向位移时刻t=0.50
DY2 = [ 0; 0; 0; -0.00209836; -0.021711; -0.0418792; -0.0185263; -0.0438634; -0.0692995;];
% 竖直方向位移时刻t=0.75
DY3 = [ 0; 0; 0; -0.00314755; -0.0325666; -0.0628188; -0.0277894; -0.0657951; -0.103949;];
% 竖直方向位移t=1
DY4 = [ 0; 0; 0; -0.00419673; -0.0434221; -0.0837584; -0.0370525; -0.0877267; -0.138599;];
% 所有时刻的竖直位移
DY = [DY0, DY1, DY2, DY3, DY4];

在这里插入图片描述
计算位移的模

% 位移的模
D = sqrt(DY.^2 + DX.^2);

  为了让整个动画云图的颜色栏采用同一个标准,还需要计算所有时刻位移的最大、最小值。同时,还需要计算坐标的最大、最小值,便于后面设置坐标轴范围。

% 位移模的最大最小值
Dmin = min(min(D));
Dmax = max(max(D));
Xmin = min(min(XYZ(:,1)));
Xmax = max(max(XYZ(:,1)));
Ymin = min(min(XYZ(:,2)));
Ymax = max(max(XYZ(:,2)));

  同样的,还有与Abaqus一致的配色方案。

% 颜色栏
Colormap = [0	0	1;
            0	0.364705882000000	1;
            0	0.725490196000000	1;
            0	1	0.909803922000000;
            0	1	0.545098039000000;
            0	1	0.180392157000000;
            0.180392157000000	1	0;
            0.545098039000000	1	0;
            0.909803922000000	1	0;
            1	0.725490196000000	0;
            1	0.364705882000000	0;
            1	0	0;];

绘图

  绘制动画云图只需要循环绘制每一时刻的位移云图即可,并且在每次绘制下一个云图前清除上一个的云图。下面这是在位移云图的基础上添加了循环的代码。位移云图的绘制可以查看上一篇文章——>点击转跳<——。

%% 绘图
f = figure('Name','位移云图');
hold on
width = 550;      %宽度,像素数
height = 400;     %高度
left = 200;       %距屏幕左下角水平距离
bottem = 200;     %距屏幕左下角垂直距离
f.Position = [left,bottem,width,height];

NT = size(D,2); % 位移云图动画帧数
for k = 1:NT

    XYZ1 = XYZ + [DX(:,k),DY(:,k)];    % 更新坐标

    patch('Faces',EL,'Vertices',XYZ1,'FaceVertexCData',D(:,k),'FaceColor','interp','EdgeColor','k');
    axis tight      % 坐标轴紧凑格式
    axis off        % 关闭坐标轴显示
    
    % 将图向左移动, 为绘制颜色栏做准备
    ax = gca;
    PositionNew = get(ax,'Position');
    PositionNew(1) = 0.08;      % 更改图形距离左边界的距离
    set(gca,'Position',PositionNew);
    
    % 绘制颜色栏
    Co = colorbar('eastoutside');   % 设置颜色栏位移图像外侧
    colormap(Colormap)  % 设置颜色栏
    set(gca, 'FontName','Times New Roman', 'FontSize',14)   % 设置字体字号
    Co.Label.String = 'U, Magnitude';  % 设置颜色栏标题
    
    % 设置颜色栏显示标签个数
    NTicks = 13;    % 标签个数
    [cmin, cmax] = caxis;
    Co.Ticks = linspace(cmin,cmax,NTicks)';
    
    % 设置颜色栏的刻度标签为科学计数法
    yt = Co.Ticks; % 获取刻度位置
    yt_labels = arrayfun(@(x) sprintf('%.3e', x), yt, 'UniformOutput', false); % 将刻度位置转换为科学计数法格式的字符串
    Co.YTickLabel = yt_labels; % 设置刻度标签

end

  下面是效果图,可以看到有几个问题:1.下一时刻的图绘制在了上一时刻的图上面;2.颜色栏的范围不统一;3.颜色栏的位置没有固定;4.原本最底下的边应该是固定的,但是现在产生了移动。
在这里插入图片描述

细节调整

清除上一时刻的绘图

  清除上一时刻的绘图只需要在循环开始时,使用cla清除绘图区即可,下面是部分代码。

NT = size(D,2); % 位移云图动画帧数
for k = 1:NT

    cla                 % 清除上一次的绘图

    XYZ1 = XYZ + [DX(:,k),DY(:,k)];    % 更新坐标

    patch('Faces',EL,'Vertices',XYZ1,'FaceVertexCData',D(:,k),'FaceColor','interp','EdgeColor','k');

在这里插入图片描述

统一颜色栏范围

  设置统一颜色栏范围只需要在绘制颜色栏后,使用caxis对颜色栏进行设置即可,下面是部分代码。代码中的Dmin和Dmax表示所有时刻位移的最大、最小值,在前面准备数据的时候已经提前计算了。

    % 绘制颜色栏
    Co = colorbar('eastoutside');   % 设置颜色栏位移图像外侧
    colormap(Colormap)  % 设置颜色栏
    set(gca, 'FontName','Times New Roman', 'FontSize',14)   % 设置字体字号
    Co.Label.String = 'U, Magnitude';  % 设置颜色栏标题
    
    caxis([Dmin,Dmax]); % 设置颜色栏的最大最小范围
    
    % 设置颜色栏显示标签个数
    NTicks = 13;    % 标签个数
    [cmin, cmax] = caxis;
    Co.Ticks = linspace(cmin,cmax,NTicks)';

在这里插入图片描述

固定颜色栏位置

  在第一个循环时获取颜色栏的位置,然后在后面的每一个循环中将颜色栏设置成第一个颜色栏的位置,部分代码如下。其中,Co表示颜色栏的实例变量,前面绘制颜色栏的时候已经进行了赋值,具体见上一个代码块。

    % 让颜色栏保持同一个位置
    if k == 1
        colorbarPosition = get(Co,'Position');
    else
        Co.Position = colorbarPosition;
    end

在这里插入图片描述
  从上图中可以看到,虽然颜色栏的位置已经固定了,但是可以观察到颜色栏标签的颜色在不断加深。这是因为清除绘图区的时候没有把颜色栏标签清除,导致了颜色栏标签不断绘制叠加,致使颜色加深。

清除颜色栏标签叠加

  与清除绘图区类似,只需要在循环开始时将颜色栏清除即可,下面是部分代码。

    cla                 % 清除上一次的绘图
    colorbar('off')     % 关闭上一次的颜色栏

    XYZ1 = XYZ + [DX(:,k),DY(:,k)];    % 更新坐标

在这里插入图片描述

固定坐标轴范围

  上图中,原本最底下的边应该是固定的,但是现在产生了移动。这是因为每次绘制坐标轴范围都在改变,需要进行固定,在循环中添加下面这段代码即可。代码中的Xmin、Ymin、Xmax和Ymax表示坐标的最大、最小值,在前面准备数据的时候已经提前计算了,后面的1.1或者1.0是为了防止变形后云图超出坐标轴的最大范围而乘的系数。

    % 固定横纵坐标范围
    xlim([Xmin,Xmax*1.1])
    ylim([Ymin,Ymax*1.0])

在这里插入图片描述

保存动画云图

  将下面的代码放入循环的最后,即可保存动画云图,DelayTime表示一帧(一个时刻)的动画播放时间。

    % 保存动态图
    frame=getframe(gcf);
    imind=frame2im(frame);
    [imind,cm] = rgb2ind(imind,256);
    DelayTime = 0.50;   % 单帧播放时间
    if k == 1
         imwrite(imind,cm,'位移动画云图.gif','gif', 'Loopcount',inf,'DelayTime',DelayTime);
    else
         imwrite(imind,cm,'位移动画云图.gif','gif','WriteMode','append','DelayTime',DelayTime);
    end

MATLAB可视化结果
在这里插入图片描述
Abaqus可视化结果
在这里插入图片描述
  可以看到,MATLAB可视化结果与Abaqus可视化结果一致。

总代码

  位移动画云图可视化的总代码如下,后续还会更新MATLAB应力云图(高斯点外插、节点平均)的教程,制作不易,别忘了关注和点赞喔

clc;clear;close all
set(0,'defaultfigurecolor','w');

%% 准备数据
% 坐标
XYZ = [ 0 0;
        1 0;
        2 0;
        0 1;
        1 1;
        2 1;
        0 2;
        1 2;
        2 2;];

% 单元
EL = [  1 2	5 4;
        2 3	6 5;
        4 5	8 7;
        5 6	9 8;];

% 水平方向位移时刻t=0.00
DX0 = zeros(9,1);
% 水平方向位移时刻t=0.25
DX1 = [ 0; 0; 0; 0.0174337; 0.0151149; 0.0186553; 0.0318029; 0.0311055; 0.0330584;];
% 水平方向位移时刻t=0.50
DX2 = [ 0; 0; 0; 0.0348675; 0.0302299; 0.0373107; 0.0636058; 0.0622109; 0.0661167;];
% 水平方向位移时刻t=0.75
DX3 = [ 0; 0; 0; 0.0523012; 0.0453448; 0.055966; 0.0954087; 0.0933164; 0.0991751;];
% 水平方向位移时刻t=1.00
DX4 = [ 0; 0; 0; 0.0697349; 0.0604598; 0.0746214; 0.127212; 0.124422; 0.132233;];
% 所有时刻的水平位移
DX = [DX0, DX1, DX2, DX3, DX4];

% 竖直方向位移时刻t=0.00
DY0 = zeros(9,1);
% 竖直方向位移时刻t=0.25
DY1 = [ 0; 0; 0; -0.00104918; -0.0108555; -0.0209396; -0.00926313; -0.0219317; -0.0346498;];
% 竖直方向位移时刻t=0.50
DY2 = [ 0; 0; 0; -0.00209836; -0.021711; -0.0418792; -0.0185263; -0.0438634; -0.0692995;];
% 竖直方向位移时刻t=0.75
DY3 = [ 0; 0; 0; -0.00314755; -0.0325666; -0.0628188; -0.0277894; -0.0657951; -0.103949;];
% 竖直方向位移t=1
DY4 = [ 0; 0; 0; -0.00419673; -0.0434221; -0.0837584; -0.0370525; -0.0877267; -0.138599;];
% 所有时刻的竖直位移
DY = [DY0, DY1, DY2, DY3, DY4];

% 位移的模
D = sqrt(DY.^2 + DX.^2);

% 位移模的最大最小值
Dmin = min(min(D));
Dmax = max(max(D));
Xmin = min(min(XYZ(:,1)));
Xmax = max(max(XYZ(:,1)));
Ymin = min(min(XYZ(:,2)));
Ymax = max(max(XYZ(:,2)));

% 颜色栏
Colormap = [0	0	1;
            0	0.364705882000000	1;
            0	0.725490196000000	1;
            0	1	0.909803922000000;
            0	1	0.545098039000000;
            0	1	0.180392157000000;
            0.180392157000000	1	0;
            0.545098039000000	1	0;
            0.909803922000000	1	0;
            1	0.725490196000000	0;
            1	0.364705882000000	0;
            1	0	0;];

%% 绘图
f = figure('Name','位移云图');
hold on
width = 550;      %宽度,像素数
height = 400;     %高度
left = 200;       %距屏幕左下角水平距离
bottem = 200;     %距屏幕左下角垂直距离
f.Position = [left,bottem,width,height];

NT = size(D,2); % 位移云图动画帧数
for k = 1:NT

    cla                 % 清除上一次的绘图
    colorbar('off')     % 关闭上一次的颜色栏

    XYZ1 = XYZ + [DX(:,k),DY(:,k)];    % 更新坐标

    patch('Faces',EL,'Vertices',XYZ1,'FaceVertexCData',D(:,k),'FaceColor','interp','EdgeColor','k');
    axis tight      % 坐标轴紧凑格式
    axis off        % 关闭坐标轴显示

    % 固定横纵坐标范围
    xlim([Xmin,Xmax*1.1])
    ylim([Ymin,Ymax*1.0])
    
    % 将图向左移动, 为绘制颜色栏做准备
    ax = gca;
    PositionNew = get(ax,'Position');
    PositionNew(1) = 0.08;      % 更改图形距离左边界的距离
    set(gca,'Position',PositionNew);
    
    % 绘制颜色栏
    Co = colorbar('eastoutside');   % 设置颜色栏位移图像外侧
    colormap(Colormap)  % 设置颜色栏
    set(gca, 'FontName','Times New Roman', 'FontSize',14)   % 设置字体字号
    Co.Label.String = 'U, Magnitude';  % 设置颜色栏标题

    caxis([Dmin,Dmax]); % 设置颜色栏的最大最小范围
    
    % 设置颜色栏显示标签个数
    NTicks = 13;    % 标签个数
    [cmin, cmax] = caxis;
    Co.Ticks = linspace(cmin,cmax,NTicks)';
    
    % 设置颜色栏的刻度标签为科学计数法
    yt = Co.Ticks; % 获取刻度位置
    yt_labels = arrayfun(@(x) sprintf('%.3e', x), yt, 'UniformOutput', false); % 将刻度位置转换为科学计数法格式的字符串
    Co.YTickLabel = yt_labels; % 设置刻度标签

    % 让颜色栏保持同一个位置
    if k == 1
        colorbarPosition = get(Co,'Position');
    else
        Co.Position = colorbarPosition;
    end

    % 保存动态图
    frame=getframe(gcf);
    imind=frame2im(frame);
    [imind,cm] = rgb2ind(imind,256);
    DelayTime = 0.50;   % 单帧播放时间
    if k == 1
         imwrite(imind,cm,'位移动画云图.gif','gif', 'Loopcount',inf,'DelayTime',DelayTime);
    else
         imwrite(imind,cm,'位移动画云图.gif','gif','WriteMode','append','DelayTime',DelayTime);
    end

end

总结

  这只是一个基础的示例,实际中还会有更具体的、更细致的要求,这就需要再做额外调整;另外本人也仍在学习中,这只是个人的学习笔记,可能还有一些不足之处,欢迎指正。

  • 16
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Infww

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值