声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2665|回复: 5

[线性振动] 多自由度瞬态动力学强迫响应计算==Newmark&Runge-Kutta

[复制链接]
发表于 2015-10-14 11:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
本帖最后由 mxlzhenzhu 于 2015-10-14 11:47 编辑
  1. %% 多自由度系统瞬态响应分析,New-mark Beta,适用于非比例阻尼,非线性刚度,非线性阻尼;
  2. %% Inputs:
  3. % K Stiff matrix
  4. % C Damping matrix, Structural Damping will be transformed to viscous
  5. % damping.
  6. % M Mass matrix
  7. % fi_set Force excitation DOFs.
  8. % Force Force matrix for every i_set
  9. % R_set Output DOFs, Disp, Velo,Acc output in cell format.

  10. %% mxl.2015-5-24
  11. % 单位制不做规定;默认自由度序号为从1到N
  12. % 在本程序中没有考虑非线性刚度 K=K(t),非线性阻尼C=C(t)这类问题,后续可以添加;
  13. % 输入默认为:x(0)=0,x'(0)=1;t 表示时间;
  14. % 强迫位移,强迫速度和强迫加速度功能没有考虑;
  15. % 结构阻尼输入的时候,转换为等效粘性阻尼的功能还没有添加;
  16. % 输出请求为位移,速度和加速度,不含应力;
  17. clear
  18. clc


  19. dt=0.0001;
  20. t=[0:dt:10]';% 延迟计算时间到15秒,可以看到明显的数值阻尼
  21. method='Newmark';% Runge-Kutta,Runge-Kutta
  22. % M=0.2533;
  23. % K0=10;
  24. % C=0.592;
  25. m1=2e2;m2=5e3;
  26. k1=2e6;k2=1.5e6;
  27. c1=1000;c2=2000;

  28. M=diag([m1,m2]);
  29. C=[
  30. c1+c2,-c2;
  31. -c2,c2;
  32. ];
  33. K0=[
  34. k1+k2,-k2;
  35. -k2,k2;
  36. ];


  37. fi_set=1;
  38. Force=5*sin(pi*t/0.6);



  39. N=size(M,1);

  40. initial_disp=zeros(N,1);% You may change it.
  41. initial_velo=[0;1];% You may change it.
  42. initial_acc=[];% You may change it.

  43. R_set=[1]';
  44. % %---------------------------------------------------------------------%
  45. % (1)Input check
  46. % %---------------------------------------------------------------------%

  47. if max(fi_set)>N
  48. error('fi_set is wrongly set.');
  49. end

  50. if numel(fi_set)-size(Force,2)
  51. error('Input force must keep in consistence.');
  52. end

  53. if isempty(dt)
  54. error('You must specify or calculate time step.');
  55. end

  56. if strcmp(method,'Newmark')
  57. if isempty(initial_disp)||isempty(initial_velo)
  58. error('You must specify the initial states.');
  59. end
  60. end
  61. if max(R_set)>N||isempty(R_set)
  62. error('Response DOFs are badly set.')
  63. end



  64. %-----初始化输出-----%
  65. Nsteps=numel(t);
  66. disp=zeros(Nsteps,numel(R_set));% 这是用来保存R_set 位移结果的;
  67. velo=zeros(Nsteps,numel(R_set));% 这是用来保存R_set 速度结果的;
  68. acc=zeros(Nsteps,numel(R_set));% 这是用来保存R_set 加速度结果的;
  69. Fi=zeros(N,1);

  70. update_disp=zeros(N,1);% 这是用来保存运算中全局位移结果的;
  71. update_velo=zeros(N,1);% 这是用来保存运算中全局速度结果的;
  72. update_acc=zeros(N,1);% 这是用来保存运算中全局加速度结果的;

  73. Inv_M=inv(M);
  74. % %---------------------------------------------------------------------%
  75. % (2)New-Mark Beta
  76. % gama=0.5;0.1667<=beta<=0.25,beta=0.25 is suggested.
  77. % %---------------------------------------------------------------------%
  78. gama=0.5;beta=0.25;
  79. disp(['Gama= ',num2str(gama),'Beta= ',num2str(beta)]);
  80. a2=1/beta/dt;a0=a2/dt;a1=a2*gama;
  81. a3=1/2/beta-1;a4=gama/beta-1;a5=dt/2*(a4-1);

  82. % if strcmp(method,'Newmark')
  83. for loop=1:Nsteps
  84. if loop>1


  85. disp(loop,:)=initial_disp(R_set,1)';% 保存请求的计算结果
  86. velo(loop,:)=initial_velo(R_set,1)';
  87. acc(loop,:)=initial_acc(R_set,1)';
  88. if loop==Nsteps
  89. break;
  90. end
  91. %---we may update the K in the line in nonlinear problem----%
  92. % K=Ki+a0*M+a1*C;

  93. Fi=zeros(N,1);
  94. for loopf=1:numel(fi_set)
  95. Fi(fi_set(loopf),1)=Force(loop,loopf);
  96. end
  97. Fi=Fi+M*(a0*initial_disp+a2*initial_velo+a3*initial_acc)+...
  98. C*(a1*initial_disp+a4*initial_velo+a5*initial_acc);


  99. update_disp=K\Fi;
  100. update_velo=a1*(update_disp-initial_disp)-a4*initial_velo-a5*initial_acc;
  101. update_acc =a0*(update_disp-initial_disp)-a2*initial_velo-a3*initial_acc;


  102. initial_disp=update_disp;% 将本次结果保存,下一次迭代时作为初值
  103. initial_velo=update_velo;
  104. initial_acc =update_acc;
  105. else
  106. for loopf=1:numel(fi_set)
  107. Fi(fi_set(loopf),1)=Force(loop,loopf);
  108. end

  109. disp(loop,:)=initial_disp(R_set,1)';
  110. velo(loop,:)=initial_velo(R_set,1)';
  111. if isempty(initial_acc)
  112. initial_acc=Inv_M*(Fi-C*initial_velo-K0*initial_disp);
  113. acc(loop,:)=initial_acc(R_set,1)';
  114. else
  115. acc(loop,:)=initial_acc(R_set,1)';
  116. end


  117. K=K0+a0*M+a1*C;% 对于线性系统,以后K都不会变


  118. Fi=Fi+M*(a0*initial_disp+a2*initial_velo+a3*initial_acc)+...
  119. C*(a1*initial_disp+a4*initial_velo+a5*initial_acc);

  120. update_disp=K\Fi;
  121. update_velo=a1*(update_disp-initial_disp)-a4*initial_velo-a5*initial_acc;
  122. update_acc =a0*(update_disp-initial_disp)-a2*initial_velo-a3*initial_acc;

  123. initial_disp=update_disp;% 将本次结果保存,下一次迭代时作为初值
  124. initial_velo=update_velo;
  125. initial_acc =update_acc;
  126. end



  127. end % end of for
  128. % end % end of if
  129. subplot(2,1,1)
  130. plot(t,disp)
  131. hold on
  132. plot(t,velo(:,1),'r')
  133. hold off
  134. legend('disp','velo')
  135. title('Newmark')
  136. % axis(gca,[0,max(t),-2e-5, 4e-5])
  137. % %---------------------------------------------------------------------%
  138. % (3)Runge-Kutta,注意R-K 可以应用于一般非线性的求解,因此很厉害的;
  139. % 请参考盛宏玉书上308页内容。
  140. % %---------------------------------------------------------------------%
  141. % R-K 方法要求 输入刚度,质量,阻尼,载荷,以及非线性方程的形式;
  142. % 初始条件只需给定初始位移和初始速度,初始加速度可以由此计算得到
  143. disp=zeros(Nsteps,numel(R_set));% 这是用来保存R_set 位移结果的;
  144. velo=zeros(Nsteps,numel(R_set));% 这是用来保存R_set 速度结果的;
  145. acc=zeros(Nsteps,numel(R_set));% 这是用来保存R_set 加速度结果的;
  146. % if strcmp(method,'Runge-Kutta')

  147. % A=[
  148. % zeros(size(M)),eye(N);
  149. % -Inv_M*K,-inv_M*C;
  150. % ];
  151. initial_disp=zeros(N,1);% You may change it.
  152. initial_velo=[0;1];% You may change it.
  153. initial_acc=[];% You may change it.

  154. for loop=1:Nsteps
  155. if loop>1

  156. if loop==Nsteps
  157. break;
  158. end

  159. Fn1=zeros(N,1);
  160. for loopf=1:numel(fi_set)
  161. Fn1(fi_set(loopf),1)=Force(loop,loopf);
  162. end


  163. Kd1=Inv_M*(-K0*initial_disp-C*initial_velo+Fn1);% 这就是一般非线性的表达式,可以另外写为一个函数单独调用
  164. Kd2=Inv_M*(-K0*(initial_disp+0.5*dt*initial_velo)-C*(initial_velo+0.5*dt*Kd1)+0.5*(Fn1+Fn0));
  165. Kd3=Inv_M*(-K0*(initial_disp+0.5*dt*initial_velo+0.25*dt^2*Kd1)-C*(initial_velo+0.5*dt*Kd2)+0.5*(Fn0+Fn1));
  166. Kd4=Inv_M*(-K0*(initial_disp+dt*initial_velo+0.5*dt^2*Kd2)-C*(initial_velo+dt*Kd3)+Fn1);

  167. Fn0=Fn1;% 保存上一次的载荷,两个时间步之间的就用平均值

  168. update_disp=initial_disp+dt*initial_velo+(dt^2)/6*(Kd1+Kd2+Kd3); % Kdi是第二组R-K法系数
  169. update_velo=initial_velo+dt/6*(Kd1+2*Kd2+2*Kd3+Kd4);
  170. update_acc =Kd1;


  171. initial_disp=update_disp;% 将本次结果保存,下一次迭代时作为初值
  172. initial_velo=update_velo;
  173. initial_acc=update_acc;

  174. disp(loop,:)=initial_disp(R_set,1)';% 保存输出
  175. velo(loop,:)=initial_velo(R_set,1)';
  176. acc(loop,:)=initial_acc(R_set,1)';

  177. else


  178. disp(loop,:)=initial_disp(R_set,1)';
  179. velo(loop,:)=initial_velo(R_set,1)';
  180. if isempty(initial_acc)
  181. Fn0=zeros(N,1);
  182. for loopf=1:numel(fi_set)
  183. Fn0(fi_set(loopf),1)=Force(loop,loopf);
  184. end


  185. initial_acc=Inv_M*(Fn0-C*initial_velo-K0*initial_disp);
  186. acc(loop,:)=initial_acc(R_set,1)';
  187. else
  188. acc(loop,:)=initial_acc(R_set,1)';
  189. end


  190. end



  191. end

  192. % end



  193. subplot(2,1,2)
  194. plot(t,disp)
  195. hold on
  196. plot(t,velo(:,1),'r')
  197. hold off
  198. legend('disp','velo')
  199. title('Runge-Kutta')
  200. % axis(gca,[0,max(t),-2e-5, 4e-5])
  201. % %---------------------------------------------------------------------%
  202. % (4)Post-Processing
  203. % %---------------------------------------------------------------------%


  204. % %---------------------------------------------------------------------%
  205. % (5)
  206. % %---------------------------------------------------------------------%
复制代码





本帖被以下淘专辑推荐:

回复
分享到:

使用道具 举报

 楼主| 发表于 2015-10-14 11:52 | 显示全部楼层
瞬态动力学计算有很多算法,模态瞬态法是一种;另外,就是直接积分法,其中大多数存在稳定性和数值阻尼问题,而Newmark和Runge-Kutta算法用得比较多。在此分享这个程序。


论坛上的程序也多有人讨论和分享过,可是代码可读性差,移植性差,逻辑结构可能不怎么清楚,因此发一个自己的程序,自诩容易看懂得多。

发表于 2015-10-18 17:55 | 显示全部楼层
老师您好,我的二阶动力学方程为(112个)(M C K F)都是时间t的函数

fangcheng.png
按照p308页下面的那个的那种不变化为一阶方程,而是直接用龙格库塔对其求解,结合上面的程序,我的编程如下:

clc
clear

tt=0:0.1:1;       %%这里我也取过0:0.01:1
for ij=1:length(tt)
   t=tt(ij)

dt=0.001;%%步长也换过0.01,0.0001

%%%以下程序就是求时间t时刻的 M K F C (是时变的)

M=。。。

K=。。。

F=。。。

C= 。。。
%%%

Inv_M=inv(M);

if ij==1
q=zeros(112,1);                      %%初始位移
q1d=zeros(112,1);                  %%初始速度
q2d=Inv_M*(QA-K*q-C*q1d);%%初始加速度
end
if ij>1
  qq=q;
  qq1d=q1d;
  qq2d=q2d;   


Kd1=Inv_M*(-K*qq-C*qq1d+F);
Kd2=Inv_M*(-K*(qq+0.5*dt*qq1d)-C*(qq1d+0.5*dt*Kd1)+F);    %这里的F  看公式是(tn+1/2*dt)
Kd3=Inv_M*(-K*(qq+0.5*dt*qq1d+0.25*dt^2*Kd1)-C*(qq1d+0.5*dt*Kd2)+F);
Kd4=Inv_M*(-K*(qq+dt*qq1d+0.5*dt^2*Kd2)-C*(qq1d+dt*Kd3)+F);

update_disp=qq+dt*qq1d+(dt^2)/6*(Kd1+Kd2+Kd3);  
update_velo=qq1d+dt/6*(Kd1+2*Kd2+2*Kd3+Kd4);
update_acc =Kd1;

q=update_disp;      %  保存结果,下一次迭代时作为初值
q1d=update_velo;
q2d=update_acc;



    q107=q(107);%q的第107行是要求的X速度
    q108=q(108);%q的第108行是要求的y速度
    q109=q(109);%q的第109行是要求的z速度
    qqq1(ij)=q107;%%保存到qqq中
    qqq2(ij)=q108;%%
    qqq3(ij)=q109;%%

end  %%%%%%%%%%%%%%%       我也试着放在这里
   %q107=q(107);%q的第107行是要求的X速度
    %q108=q(108);%q的第108行是要求的y速度
    %q109=q(109);%q的第109行是要求的z速度
    %qqq1(ij)=q107;%%保存到qqq中
    %qqq2(ij)=q108;%%
    %qqq3(ij)=q109;%%
%%%%%%%%%%%%%
     
end

figure(1)
plot(tt,qqq1,'b')     
title('x位移')
xlabel('时间t/s')
ylabel('位移/m')

figure(2)
plot(tt,qqq2,'m')
title('y位移')
xlabel('时间t/s')
ylabel('位移/m')




出来的数据(区间是分了十一份)


0        -0.0346758535292791        -15365335555923.0        -7.52481294950494e+27        -3.68121477935759e+42        -1.79891687691818e+57        -8.78113256011268e+71        -4.28158412948546e+86        -2.08529717616388e+101        -1.01446242889355e+116        -4.92950756226880e+130
能劳烦看一下吗,找了好长时间了,没有找到原因。
谢谢谢谢谢谢

发表于 2015-10-18 19:41 | 显示全部楼层
发表于 2015-10-18 19:46 | 显示全部楼层
这是我的变系数动力学方程:
                                            
fangcheng.png
按照书中308页下边的那种龙格库塔的方法,结合您的帖子上面的程序,不做变换化为一阶方程,而直接用龙哥-库塔对其求解。我的编程思路大致如下:
clc
clear
%%%%%%%%%%%%%%%%%%%%%%%
            
Ixy=0.81*10^-8;
Ixz=0.56*10^-2;
Iyx=0.81*10^-8;
Iyy=0.66432;      
Iyz=1.166*10^-7;
Izx=0.56*10^-2;
Izy=1.166*10^-7;
Izz=0.64;
密度,质量 转动惯量等已知是的赋值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tt=0:0.01:1; %%%%%%这里也试过0.001,0.0001
for ij=1:length(tt)
   t=tt(ij)
dt=0.01;%%%%%%%%%步长也试过0.1,0.0001
。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。
M=
K=
F=
C=
。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。%%%%%句号中间是求M K F C (都是关于t的函数)  
Inv_M=inv(M);
if ij==1
q=zeros(112,1);%%%%初始位移
q1d=zeros(112,1);   %%%%初始速度
q2d=Inv_M*(QA-K*q-C*q1d); %%%%初始加速度
end
if ij>1
  qq=q;
  qq1d=q1d;
  qq2d=q2d;  
Kd1=Inv_M*(-K*qq-C*qq1d+F);%  
Kd2=Inv_M*(-K*(qq+0.5*dt*qq1d)-C*(qq1d+0.5*dt*Kd1)+F);
Kd3=Inv_M*(-K*(qq+0.5*dt*qq1d+0.25*dt^2*Kd1)-C*(qq1d+0.5*dt*Kd2)+F);
Kd4=Inv_M*(-K*(qq+dt*qq1d+0.5*dt^2*Kd2)-C*(qq1d+dt*Kd3)+F);
update_disp=qq+dt*qq1d+(dt^2)/6*(Kd1+Kd2+Kd3);%  
update_velo=qq1d+dt/6*(Kd1+2*Kd2+2*Kd3+Kd4);
update_acc =Kd1;
q=update_disp;
q1d=update_velo;
q2d=update_acc;
q107=q(107); %%%x位移
    q108=q(108); %%%y位移
    q109=q(109); %%%y位移
   qqq1(ij)=q107;
   qqq2(ij)=q108;
   qqq3(ij)=q109;
end  
   
end
  
figure(1)
plot(tt,qqq1,'b')%%%x位移   
title('&#206;&#187;ò&#198;')
xlabel('ê±&#188;&#228;t/s')
ylabel('&#206;&#187;ò&#198;/m')
figure(2)
plot(tt,qqq2,'m')%%%y位移
title('&#203;ù&#182;è')
xlabel('ê±&#188;&#228;t/s')
ylabel('&#206;&#187;ò&#198;/m')
figure(3)
plot(tt,qqq3,'m')%%%z位移
title('&#203;ù&#182;è')
xlabel('ê±&#188;&#228;t/s')
ylabel('&#206;&#187;ò&#198;/m')

wengti.docx

23.55 KB, 下载次数: 19

程序

 楼主| 发表于 2015-10-20 16:32 | 显示全部楼层
oneonly 发表于 2015-10-18 19:46
这是我的变系数动力学方程:                                            http://forum.vibunion.com/th ...

这个程序就是专门为你发的,你自己再看看吧。
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-4-19 17:08 , Processed in 0.059521 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表