材料力学求解器-刚架与桁架杆系的计算机求解(附matlab代码)
材料力学是一门非常成熟的学科,里面有大量的已经成熟的计算方法、计算模型。然而在掌握了基本原理之后,求解问题的主要时间都花在了计算上面。这时,则完全可以利用计算机采用数值方法进行快速求解。
本文的参考文献很简单,就是 单辉祖 编写的 材料力学第3版下册(或者说是第II册),第18章的内容。
还是惯例声明:本人没有相关的工程应用经验,只是纯粹对相关算法感兴趣才写此博客。所以如果有错误,欢迎在评论区指正,不胜感激。本文主要关注于算法的实现,对于实际应用等问题本人没有任何经验,所以也不再涉及。
1 刚架的计算机求解
1.1位移法与刚度矩阵
计算机求解刚架的原理主要是位移法和刚度矩阵。
基本思路为:
1 定义划分单元与节点
2 列出每个节点的载荷F
3 求解每个单元的刚度矩阵Km
4 把所有单元的刚度矩阵相加,得到总的刚度矩阵K
5 利用位移法与胡克定律F=K*D,求解出位移D
6 根据位移,反推出其余受力
以书上的例18-4,举例说明
1 定义划分单元与节点
上面的刚架,可以很轻易的划分出单元与节点,包含4个节点与3和单元。此外,刚度矩阵的方法要求把受力点算作节点。
2 列出每个节点的载荷F
对于刚架来说,每个节点受力包含Fx、Fy、Me三个力。所以F是一个3*4=12个元素的列向量。
外加的力载荷只有2号节点处的三个力。所以,列向量F可以写作:
[ 0 0 0 F x − F y − M e 0 0 0 0 0 0 ] ′ \left[ \begin{matrix} 0&0&0&Fx&-Fy&-Me&0&0&0&0&0&0\\ \end{matrix} \right] ' [000Fx−Fy−Me000000]′
这里’代表转置。
外加力的方向定义为与x、y轴方向相同为正。力矩定义为逆时针为正。
3 求解每个单元的刚度矩阵Km
首先是局部坐标系下,列出刚度矩阵
之后,以③号单元为例,3号单元的两个节点分别为i=2和j=4。
单独某个单元的刚度矩阵Km如下:
[ E A L 0 0 − E A L 0 0 0 12 E I L 3 6 E I L 2 0 − 12 E I L 3 6 E I L 2 0 6 E I L 2 4 E I L 0 − 6 E I L 2 2 E I L − E A L 0 0 E A L 0 0 0 − 12 E I L 3 − 6 E I L 2 0 12 E I L 3 − 6 E I L 2 0 6 E I L 2 2 E I L 0 − 6 E I L 2 4 E I L ] \left[ \begin{matrix} \frac{EA}{L}& 0& 0& -\frac{EA}{L}& 0& 0\\ 0& \frac{12EI}{L^3}& \frac{6EI}{L^2}& 0& -\frac{12EI}{L^3}& \frac{6EI}{L^2}\\ 0& \frac{6EI}{L^2}& \frac{4EI}{L}& 0& -\frac{6EI}{L^2}& \frac{2EI}{L}\\ -\frac{EA}{L}& 0& 0& \frac{EA}{L}& 0& 0\\ 0& -\frac{12EI}{L^3}& -\frac{6EI}{L^2}& 0& \frac{12EI}{L^3}& -\frac{6EI}{L^2}\\ 0& \frac{6EI}{L^2}& \frac{2EI}{L}& 0& -\frac{6EI}{L^2}& \frac{4EI}{L}\\ \end{matrix} \right] ⎣⎢⎢⎢⎢⎢⎢⎡LEA00−LEA000L312EIL26EI0−L312EIL26EI0L26EIL4EI0−L26EIL2EI−LEA00LEA000−L312EI−L26EI0L312EI−L26EI0L26EIL2EI0−L26EIL4EI⎦⎥⎥⎥⎥⎥⎥⎤
其中E是弹性模量,A是横截面积,L是单元的长度,I是惯性矩。
之后旋转单元,将单元转换为全局坐标系下
K m = T ′ ∗ K m ∗ T Km=T'*Km*T Km=T′∗Km∗T
其中旋转矩阵T为:
[ cos α sin α 0 0 0 0 − sin α cos α 0 0 0 0 0 0 1 0 0 0 0 0 0 cos α sin α 0 0 0 0 − sin α cos α 0 0 0 0 0 0 1 ] \left[ \begin{matrix} \cos \alpha& \sin \alpha& 0& 0& 0& 0\\ -\sin \alpha& \cos \alpha& 0& 0& 0& 0\\ 0& 0& 1& 0& 0& 0\\ 0& 0& 0& \cos \alpha& \sin \alpha& 0\\ 0& 0& 0& -\sin \alpha& \cos \alpha& 0\\ 0& 0& 0& 0& 0& 1\\ \end{matrix} \right] ⎣⎢⎢⎢⎢⎢⎢⎡cosα−sinα0000sinαcosα0000001000000cosα−sinα0000sinαcosα0000001⎦⎥⎥⎥⎥⎥⎥⎤
之后还需要把这个6*6的局部刚度矩阵,拓展到12*12的全局刚度矩阵。方法就是:将局部刚度矩阵的1-3行移动到12*12全局矩阵中的3*i-2到3*i行(也就是4-6行),将4-6行移动到12*12全局矩阵中的3*j-2到3*j行(也就是10-12行)。列也同理。
4 把所有单元的刚度矩阵相加,得到总的刚度矩阵K
这一步就是将所有单元得到的刚度矩阵相加就行。
5 利用位移法与胡克定律F=K*D,求解出位移D
这里用到matlab里的
D=K\F;
就可以直接求解出D。
此外,如果有固定约束(比如固定端约束了x,y,theta三个自由度),需要用到乘大数法。
比如位移D列向量中的第i个分量被约束住了,规定要移动Di,则将刚度矩阵K的i行i列乘以一个很大的数(比如a=10E12),记为a*Kii。并且将载荷向量F中的第i行,更改为a*Kii*Di。
6 根据位移,反推出其余受力
这个可以根据梁弯曲受力的挠度公式,待定系数反求出受力。也可以根据之前得到的局部坐标系下的刚度矩阵,求解受力。
1.2 matlab程序
clear
clc
close all
%材料力学求解器
%平面刚架
%% 1前处理,划分定义节点与单元,输入初始条件
Node=4;%节点数量
Element=3;%单元数量
%节点位置,每一行分别为x、y
N_xy=[
0,1;
1,1;
2,1;
1,0
];
%单元属性【节点i,节点j,弹性模量E,横截面积A,惯性矩I】
El_ijEAI=[
1 ,2 ,210E9 ,2E3*10^(-3*2) ,3E6*10^(-3*4) ;
2 ,3 ,210E9 ,2E3*10^(-3*2) ,3E6*10^(-3*4) ;
2 ,4 ,210E9 ,2E3*10^(-3*2) ,3E6*10^(-3*4) ;
];
%定义节点处施加的力的大小,顺序为Fx1,Fy1,Me1, Fx2,Fy2,Me2, Fx3,...
%这里例子中,F=[0;0;0;20E3;-20E3;-40E3;0;0;0;0;0;0];
F=zeros(3*Node,1);
F(4)=20E3;
F(5)=-20E3;
F(6)=-40E3;
%定义位移约束,顺序为X1,Y1,T1, X2,Y2,T2, X3,...
%后面为约束具体的值
%这里例子中,1,2,3,7,8,9,10,11,12都是0位移约束
Move_Limit=[1,2,3,7,8,9,10,11,12;
0,0,0,0,0,0,0,0,0];
%% 2采用刚度矩阵方法计算
D=SolveStiffnessMethod(Node,Element,N_xy,El_ijEAI,F,Move_Limit);
%% 3后处理
%3.1求解变形后的图形
Scale_X=1000;%位移变形放大系数(宁小勿大)
Scale_T=0.5/max(abs( D(3:3:3*Node) ));%角度变形放大系数(宁小勿大)
%Scale_T=100;%角度变形放大系数(宁小勿大)
figure(1)
hold on
%绘制变形前的图像
for m=1:Element
%原先节点的坐标位置
xyI=N_xy(El_ijEAI(m,1),:);
xyJ=N_xy(El_ijEAI(m,2),:);
plot([xyI(1),xyJ(1)],[xyI(2),xyJ(2)],'b')
end
%绘制变形后的图像
for m=1:Element
Node_I=El_ijEAI(m,1);
Node_J=El_ijEAI(m,2);
%原先节点的坐标位置
xyI=N_xy(Node_I,:);
xyJ=N_xy(Node_J,:);
%变形后的节点坐标位置
xyIJ_New=[xyI'+Scale_X*D(3*Node_I-2:3*Node_I-1),xyJ'+Scale_X*D(3*Node_J-2:3*Node_J-1)];
%原先的节点对应的夹角
Theta_IJ=angle((xyJ(1)-xyI(1))+(xyJ(2)-xyI(2))*1i);
%变形后的节点对应的角度
DirI=[cos( Theta_IJ+Scale_T*D(3*Node_I) ) ; sin( Theta_IJ+Scale_T*D(3*Node_I) )];
DirJ=[cos( Theta_IJ+Scale_T*D(3*Node_J) ) ; sin( Theta_IJ+Scale_T*D(3*Node_J) )];
%生成样条曲线
cs3 = spline([1,2],[DirI,xyIJ_New,DirJ]);
yy=ppval(cs3,linspace(1,2));
%绘制
plot(yy(1,:),yy(2,:),'r')
end
hold off
axis equal
%3.2求解变形后的弯矩图
Scale_M=1E-5;%弯矩变形放大系数(默认1)
figure()
hold on
%绘制原先的图像
for m=1:Element
%原先节点的坐标位置
xyI=N_xy(El_ijEAI(m,1),:);
xyJ=N_xy(El_ijEAI(m,2),:);
plot([xyI(1),xyJ(1)],[xyI(2),xyJ(2)],'b')
end
%绘制力矩图
for m=1:Element
%旋转杆件,回到局部坐标系
Node_I=El_ijEAI(m,1);
Node_J=El_ijEAI(m,2);
E=El_ijEAI(m,3);
A=El_ijEAI(m,4);
I=El_ijEAI(m,5);
xyI=N_xy(Node_I,:);
xyJ=N_xy(Node_J,:);
L=sqrt(sum((xyI-xyJ).^2));
Theta_IJ=angle((xyJ(1)-xyI(1))+(xyJ(2)-xyI(2))*1i);
%计算水平梁的变形
T=RotateMatrixT(xyI,xyJ);
D_IJ=[D(3*Node_I-2:3*Node_I);D(3*Node_J-2:3*Node_J)];
DT=T'*D_IJ;
%根据弯矩公式反推弯矩
Me_abcd=[0,0,1,0;
0.5*L^2,L,1,0;
0,0,0,1;
L^3/6,L^2/2,L,1]/E/I;
abcd=Me_abcd\[DT(3);DT(6);DT(4);DT(5)];
%绘图
x1=linspace(0,L);
y1=abcd(1)*x1+abcd(2);
y1=Scale_M*y1;
%旋转xy
xy2=[cos(Theta_IJ),-sin(Theta_IJ);sin(Theta_IJ),cos(Theta_IJ)]*[x1;y1];
%将0点平移到xyI上
xy2=xy2+xyI';
%plot(xy2(1,:),xy2(2,:),'r')
patch([xyI(1),xy2(1,:),xyJ(1)],[xyI(2),xy2(2,:),xyJ(2)],'k','FaceAlpha',0.5)
end
hold off
axis equal
%3.3 输出每个单元的受力,每个单元计算6个力,分别为I端点的Fx,Fy,Me和J端点的Fx,Fy,Me
FxFyMeIJ=zeros(Element,6);
for m=1:Element
Node_I=El_ijEAI(m,1);
Node_J=El_ijEAI(m,2);
E=El_ijEAI(m,3);
A=El_ijEAI(m,4);
I=El_ijEAI(m,5);
xyI=N_xy(Node_I,:);
xyJ=N_xy(Node_J,:);
L=sqrt(sum((xyI-xyJ).^2));
Theta_IJ=angle((xyJ(1)-xyI(1))+(xyJ(2)-xyI(2))*1i);
%旋转杆件,回到局部坐标系
T=RotateMatrixT(xyI,xyJ);
D_IJ=[D(3*Node_I-2:3*Node_I);D(3*Node_J-2:3*Node_J)];
DT=T*D_IJ;
%计算受力
FxI=-E*A/L*DT(4)+E*A/L*DT(1);
FxJ=E*A/L*DT(4)-E*A/L*DT(1);
FyI=-12*E*I/L^3*DT(5)+6*E*I/L^2*DT(6)+12*E*I/L^3*DT(2)+6*E*I/L^2*DT(3);
FyJ=12*E*I/L^3*DT(5)-6*E*I/L^2*DT(6)-12*E*I/L^3*DT(2)-6*E*I/L^2*DT(3);
MeI=-6*E*I/L^2*DT(5)+2*E*I/L*DT(6)+6*E*I/L^2*DT(2)+4*E*I/L*DT(3);
MeJ=-6*E*I/L^2*DT(5)+4*E*I/L*DT(6)+6*E*I/L^2*DT(2)+2*E*I/L*DT(3);
FxFyMeIJ(m,:)=[FxI,FyI,MeI,FxJ,FyJ,MeJ];
end
FxFyMeIJ( abs(FxFyMeIJ) < (max(abs(FxFyMeIJ))/1E10) )=0;
D( abs(D) < (max(abs(D))/1E10) )=0;
%输出
Str_Output1=char(zeros(Node+1,60)+32);%32\12288
Str_Output1(1,1:3)='节 点';
Str_Output1(1,14:17)='水平位移';
Str_Output1(1,34:37)='竖直位移';
Str_Output1(1,54:57)='转 角';
for m=2:Node+1
Str_Output1(m,2:3)=num2str(m-1,'%02.f');
Str_Output1(m,4:5)=char(12288);
Str_Output1(m,12:23)=num2str(D(3*m-5),'%+10.5e');
Str_Output1(m,24:28)=char(12288);
Str_Output1(m,30:41)=num2str(D(3*m-4),'%+10.5e');
Str_Output1(m,42:46)=char(12288);
Str_Output1(m,48:59)=num2str(D(3*m-3),'%+10.5e');
end
Str_Output1
Str_Output2=char(zeros(2*Element+1,60)+32);
Str_Output2(1,1:3)='单 元';
Str_Output2(1,14:16)='横向力';
Str_Output2(1,34:36)='切向力';
Str_Output2(1,54:56)='力 矩';
for m=1:Element
Str_Output2(2*m,2:3)=num2str(m-1,'%02.f');
Str_Output2(2*m,4:5)=char(12288);
Str_Output2(2*m,12:23)=num2str(FxFyMeIJ(m,1),'%+10.5e');
Str_Output2(2*m,24:28)=char(12288);
Str_Output2(2*m,30:41)=num2str(FxFyMeIJ(m,2),'%+10.5e');
Str_Output2(2*m,42:46)=char(12288);
Str_Output2(2*m,48:59)=num2str(FxFyMeIJ(m,3),'%+10.5e');
Str_Output2(2*m+1,4:5)=char(12288);
Str_Output2(2*m+1,12:23)=num2str(FxFyMeIJ(m,4),'%+10.5e');
Str_Output2(2*m+1,24:28)=char(12288);
Str_Output2(2*m+1,30:41)=num2str(FxFyMeIJ(m,5),'%+10.5e');
Str_Output2(2*m+1,42:46)=char(12288);
Str_Output2(2*m+1,48:59)=num2str(FxFyMeIJ(m,6),'%+10.5e');
end
Str_Output2
%% 一些自定义函数
function T=RotateMatrixT(xyI,xyJ)
xI=xyI(1);
yI=xyI(2);
xJ=xyJ(1);
yJ=xyJ(2);
L=sqrt((xJ-xI)^2+(yJ-yI)^2);
T=eye(6);
T(1,1)=(xJ-xI)/L;T(1,2)=(yJ-yI)/L;T(2,1)=-(yJ-yI)/L;T(2,2)=(xJ-xI)/L;
T(4,4)=(xJ-xI)/L;T(4,5)=(yJ-yI)/L;T(5,4)=-(yJ-yI)/L;T(5,5)=(xJ-xI)/L;
end
function D=SolveStiffnessMethod(Node,Element,N_xy,El_ijEAI,F,Move_Limit)
K_El=zeros(3*Node,3*Node,Element);
for m=1:Element
%每个单元的属性
Node_I=El_ijEAI(m,1);
Node_J=El_ijEAI(m,2);
E=El_ijEAI(m,3);
A=El_ijEAI(m,4);
I=El_ijEAI(m,5);
%两端节点的坐标
xyI=N_xy(Node_I,:);
xyJ=N_xy(Node_J,:);
L=sqrt(sum((xyI-xyJ).^2));
%每个单元对应的刚度矩阵
%计算系数
KFxu=E*A/L;
KFyv=12*E*I/L^3;
KFyt=6*E*I/L^2;
KMev=6*E*I/L^2;
KMet=4*E*I/L;
%刚度矩阵
%Node_I=1;Node_J=2;
K_El_m=zeros(6);
K_El_m(1,1)=KFxu;
K_El_m(2,2)=KFyv;K_El_m(2,3)=KFyt;
K_El_m(3,2)=KMev;K_El_m(3,3)=KMet;
K_El_m(1,4)=-KFxu;
K_El_m(2,5)=-KFyv;K_El_m(2,6)=KFyt;
K_El_m(3,5)=-KMev;K_El_m(3,6)=KMet;
K_El_m(4,1)=-KFxu;
K_El_m(5,2)=-KFyv;K_El_m(5,3)=-KFyt;
K_El_m(6,2)=KMev;K_El_m(6,3)=KMet;
K_El_m(4,4)=KFxu;
K_El_m(5,5)=KFyv;K_El_m(5,6)=-KFyt;
K_El_m(6,5)=-KMev;K_El_m(6,6)=KMet;
%旋转杆件
T=RotateMatrixT(xyI,xyJ);
K_El_m_T=T'*K_El_m*T;
%扩展到全局方程中,II、IJ、JI、JJ节点方程与K_El_m_T中的相同,其余全是0
K_El_m_S=zeros(3*Node,3*Node);
K_El_m_S(Node_I*3-2:Node_I*3-0,Node_I*3-2:Node_I*3-0)=K_El_m_T(1:3,1:3);
K_El_m_S(Node_I*3-2:Node_I*3-0,Node_J*3-2:Node_J*3-0)=K_El_m_T(1:3,4:6);
K_El_m_S(Node_J*3-2:Node_J*3-0,Node_I*3-2:Node_I*3-0)=K_El_m_T(4:6,1:3);
K_El_m_S(Node_J*3-2:Node_J*3-0,Node_J*3-2:Node_J*3-0)=K_El_m_T(4:6,4:6);
%保存到K_El里
K_El(:,:,m)=K_El_m_S;
end
%整体的包含各个元素的刚度矩阵
K=sum(K_El,3);
a=1E12;%放大系数
%利用乘大数法,模拟位移约束的影响
for m=1:size(Move_Limit,2)
n=Move_Limit(1,m);
K(n,n)=a*K(n,n);
F(n)=K(n,n)*Move_Limit(2,m);
end
%求解位移结果
D=K\F;
end
输出得到的变形图如下。这里变形为了展示效果有所夸张,实际变形基本看不出来。
输出的力矩分布图如下:
输出的计算结果如下:
'节 点 水平位移 竖直位移 转 角 '
' 01 +0.00000e+00 +0.00000e+00 +0.00000e+00 '
' 02 +4.72998e-05 -4.59643e-05 -5.31466e-03 '
' 03 +0.00000e+00 +0.00000e+00 +0.00000e+00 '
' 04 +0.00000e+00 +0.00000e+00 +0.00000e+00 '
'单 元 横向力 切向力 力 矩 '
' 00 -1.98659e+04 -1.97419e+04 -6.52272e+03 '
' +1.98659e+04 +1.97419e+04 -1.32192e+04 '
' 01 +1.98659e+04 -2.04369e+04 -1.35667e+04 '
' -1.98659e+04 +2.04369e+04 -6.87021e+03 '
' 02 +1.93050e+04 -1.97318e+04 -1.32141e+04 '
' -1.93050e+04 +1.97318e+04 -6.51767e+03 '
2 桁架的计算机求解
求解思路与之前的刚架是一致的。因为这里只涉及到二力杆,所以刚度方程简化了不少。
求解顺序还是如下:
1 定义划分单元与节点
2 列出每个节点的载荷F
3 求解每个单元的刚度矩阵Km
4 把所有单元的刚度矩阵相加,得到总的刚度矩阵K
5 利用位移法与胡克定律F=K*D,求解出位移D
6 根据位移,反推出其余受力
1 定义划分单元与节点
这个只需要把每一个杆定义为一个单元即可。
2 列出每个节点的载荷F
对于二力杆来说,每个节点受力包含Fx、Fy两个力,不存在力矩。相比较刚架少了一个力,总的力只有2m个。
外加力的方向定义为与x、y轴方向相同为正。
3 求解每个单元的刚度矩阵Km
这里局部坐标系的刚度矩阵变成了4*4的矩阵。分别对应Fxi,Fyi,Fxj,Fyj。
[ E A L 0 − E A L 0 0 0 0 0 − E A L 0 E A L 0 0 0 0 0 ] \left[ \begin{matrix} \frac{EA}{L}& 0& -\frac{EA}{L}& 0 \\ 0& 0& 0& 0 \\ -\frac{EA}{L}& 0& \frac{EA}{L}& 0\\ 0& 0& 0& 0\\ \end{matrix} \right] ⎣⎢⎢⎡LEA0−LEA00000−LEA0LEA00000⎦⎥⎥⎤
其中E是弹性模量,A是横截面积,L是单元的长度。
之后旋转单元,将单元转换为全局坐标系下
K m = T ′ ∗ K m ∗ T Km=T'*Km*T Km=T′∗Km∗T
其中旋转矩阵T为:
[ cos α sin α 0 0 − sin α cos α 0 0 0 0 cos α sin α 0 0 − sin α cos α ] \left[ \begin{matrix} \cos \alpha& \sin \alpha& 0& 0\\ -\sin \alpha& \cos \alpha& 0& 0\\ 0& 0& \cos \alpha& \sin \alpha\\ 0& 0& -\sin \alpha& \cos \alpha\\ \end{matrix} \right] ⎣⎢⎢⎡cosα−sinα00sinαcosα0000cosα−sinα00sinαcosα⎦⎥⎥⎤
之后还需要把这个4*4的局部刚度矩阵,拓展到全局刚度矩阵。方法同之前的刚架。
4 把所有单元的刚度矩阵相加,得到总的刚度矩阵K
这一步就是将所有单元得到的刚度矩阵相加就行。
5 利用位移法与胡克定律F=K*D,求解出位移D
这里用到matlab里的
D=K\F;
就可以直接求解出D。
此外,如果有固定约束(比如固定端约束了x,y两个自由度),需要用到乘大数法。
比如位移D列向量中的第i个分量被约束住了,规定要移动Di,则将刚度矩阵K的i行i列乘以一个很大的数(比如a=10E12),记为a*Kii。并且将载荷向量F中的第i行,更改为a*Kii*Di。
6 根据位移,反推出其余受力
对于二力杆来说,方程很简单,只需要带入到局部坐标系中求解出压力就行。
还是以书上例题为例:
matlab代码如下:
clear
clc
close all
%材料力学求解器
%平面二力杆系
%% 1前处理,划分定义节点与单元,输入初始条件
Node=4;%节点数量
Element=6;%单元数量
%节点位置,每一行分别为x、y
N_xy=[
0,0;
0,2;
1,2;
1,0
];
%单元属性【节点i,节点j,弹性模量E,横截面积A】
El_ijEA=[
1 ,2 ,200E9 ,100*10^(-3*2) ;
2 ,3 ,200E9 ,100*10^(-3*2) ;
3 ,4 ,200E9 ,100*10^(-3*2) ;
1 ,4 ,200E9 ,100*10^(-3*2) ;
1 ,3 ,200E9 ,100*10^(-3*2) ;
2 ,4 ,200E9 ,100*10^(-3*2) ;
];
%定义节点处施加的力的大小,顺序为Fx1,Fy1, Fx2,Fy2, Fx3,...
F=zeros(2*Node,1);
F(4)=-3E3;
F(5)= 1E3;
F(6)=-2E3;
%定义位移约束,顺序为X1,Y1, X2,Y2, X3,...
%后面为约束具体的值
%这里例子中,1,2,8都是0位移约束
Move_Limit=[1,2,8;
0,0,0];
%检测
if size(N_xy,1)~=Node || size(El_ijEA,1)~=Element
error('输入有误')
end
%% 2采用刚度矩阵方法计算
D=SolveStiffnessMethod(Node,Element,N_xy,El_ijEA,F,Move_Limit);
%% 3后处理
%3.1计算轴力
F_IJ=zeros(Element,1);
for m=1:Element
Node_I=El_ijEA(m,1);
Node_J=El_ijEA(m,2);
E=El_ijEA(m,3);
A=El_ijEA(m,4);
xyI=N_xy(Node_I,:);
xyJ=N_xy(Node_J,:);
L=sqrt(sum((xyI-xyJ).^2));
Theta_IJ=angle((xyJ(1)-xyI(1))+(xyJ(2)-xyI(2))*1i);
%旋转杆件,回到局部坐标系
T=RotateMatrixT(xyI,xyJ);
D_IJ=[D(2*Node_I-1:2*Node_I);D(2*Node_J-1:2*Node_J)];
DT=T*D_IJ;
%计算受力
FxI=-E*A/L*DT(1)+E*A/L*DT(3);
F_IJ(m,:)=FxI;
end
%3.2求解变形后的图形
Scale_X=200;%位移变形放大系数(宁小勿大)
%绘制颜色条
N_color=6;
mcp=[[linspace(1,1/(N_color-1),N_color-1)',zeros(N_color-1,1),zeros(N_color-1,1)];...
[zeros(N_color,1),zeros(N_color,1),linspace(0,1,N_color)']];
mcp=flipud(mcp);
Max_F=max(abs(F_IJ));
ColorIndex=round(F_IJ/Max_F*(N_color-1))+N_color;
%颜色索引
figure(1)
hold on
%绘制变形前的图像
for m=1:Element
%原先节点的坐标位置
xyI=N_xy(El_ijEA(m,1),:);
xyJ=N_xy(El_ijEA(m,2),:);
plot([xyI(1),xyJ(1)],[xyI(2),xyJ(2)],'color',[0.5,0.5,0.5])
end
%绘制变形后的图像
for m=1:Element
Node_I=El_ijEA(m,1);
Node_J=El_ijEA(m,2);
%原先节点的坐标位置
xyI=N_xy(Node_I,:);
xyJ=N_xy(Node_J,:);
%变形后的节点坐标位置
xyIJ_New=[xyI'+Scale_X*D(2*Node_I-1:2*Node_I),xyJ'+Scale_X*D(2*Node_J-1:2*Node_J)];
%绘制
plot(xyIJ_New(1,:),xyIJ_New(2,:),'color',mcp(ColorIndex(m),:),'linewidth',1.5)
end
hold off
axis equal
caxis([-Max_F,Max_F])
colormap(mcp)
colorbar()
%% 一些自定义函数
function T=RotateMatrixT(xyI,xyJ)
xI=xyI(1);
yI=xyI(2);
xJ=xyJ(1);
yJ=xyJ(2);
L=sqrt((xJ-xI)^2+(yJ-yI)^2);
T=eye(4);
T(1,1)=(xJ-xI)/L;T(1,2)=(yJ-yI)/L;T(2,1)=-(yJ-yI)/L;T(2,2)=(xJ-xI)/L;
T(3,3)=(xJ-xI)/L;T(3,4)=(yJ-yI)/L;T(4,3)=-(yJ-yI)/L;T(4,4)=(xJ-xI)/L;
end
function D=SolveStiffnessMethod(Node,Element,N_xy,El_ijEA,F,Move_Limit)
K_El=zeros(2*Node,2*Node,Element);
for m=1:Element
%每个单元的属性
Node_I=El_ijEA(m,1);
Node_J=El_ijEA(m,2);
E=El_ijEA(m,3);
A=El_ijEA(m,4);
%两端节点的坐标
xyI=N_xy(Node_I,:);
xyJ=N_xy(Node_J,:);
L=sqrt(sum((xyI-xyJ).^2));
%每个单元对应的刚度矩阵
%计算系数
KFxu=E*A/L;
%刚度矩阵
%Node_I=1;Node_J=2;
K_El_m=zeros(4);
K_El_m(1,1)=KFxu;
K_El_m(1,3)=-KFxu;
K_El_m(3,1)=-KFxu;
K_El_m(3,3)=KFxu;
%旋转杆件
T=RotateMatrixT(xyI,xyJ);
K_El_m_T=T'*K_El_m*T;
%扩展到全局方程中,II、IJ、JI、JJ节点方程与K_El_m_T中的相同,其余全是0
K_El_m_S=zeros(2*Node,2*Node);
K_El_m_S(Node_I*2-1:Node_I*2-0,Node_I*2-1:Node_I*2-0)=K_El_m_T(1:2,1:2);
K_El_m_S(Node_I*2-1:Node_I*2-0,Node_J*2-1:Node_J*2-0)=K_El_m_T(1:2,3:4);
K_El_m_S(Node_J*2-1:Node_J*2-0,Node_I*2-1:Node_I*2-0)=K_El_m_T(3:4,1:2);
K_El_m_S(Node_J*2-1:Node_J*2-0,Node_J*2-1:Node_J*2-0)=K_El_m_T(3:4,3:4);
%保存到K_El里
K_El(:,:,m)=K_El_m_S;
end
%整体的包含各个元素的刚度矩阵
K=sum(K_El,3);
a=1E11;%放大系数
%利用乘大数法,模拟位移约束的影响
for m=1:size(Move_Limit,2)
n=Move_Limit(1,m);
K(n,n)=a*K(n,n);
F(n)=K(n,n)*Move_Limit(2,m);
end
%求解位移结果
D=K\F;
end
输出的图像结果:
变形同样被放大了,实际变形几乎看不出来。颜色显示了每根杆的受力情况。