声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 8397|回复: 28

[经典算法] 迭代法求变截面欧拉梁的固有特性(In C/C++)

  [复制链接]
发表于 2010-10-28 15:28 | 显示全部楼层 |阅读模式

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

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

x
一种经典的结构动力特性数值分析方法。


总的来说,就是首先通过理论推导构造出递推式:

{实际振型} = f({实际振型});//这里,f(x)实际上是一个四次积分。

然后假设一个振型,带入递推式,具体为:


  1. 任意给定{假设振型};

  2. while( abs({修正振型} - {假设振型}) < 1e-5)
  3. {
  4.     {修正振型} = f({假设振型});

  5.     {假设振型} = {修正振型} ;
  6. }
复制代码

递推式是根据欧拉梁横向振动方程得到的,以公式居多,就作为附件吧(附件[理论基础.doc]即是)。

某变截面梁的前三阶振型:
1.jpg


还是挺像回事儿的哈。

PS:附件[计算结果.doc]是根据本文代码中硬编码的梁模型计算得到的结果。

源代码是:


  1. // VibrateStyle.cpp : 定义控制台应用程序的入口点。
  2. // 结构·第三·振型计算
  3. #include "stdafx.h"
  4. #include <iostream>
  5. #include <iomanip>
  6. #include <fstream>
  7. #include <math.h>
  8. /********************宏,命名空间*****************/
  9. #define MAXNUM 11
  10. #define STOPLINE 0.000001
  11. #define SHOW_DETAIL
  12. #define OUTPUT(K)  cout<<"****结果****"<<endl;\
  13.   cout<<K<<"阶共振 "<<w##K<<endl;for(int i=0;i<MAXNUM;++i){cout<<Shape_##K[i]<<endl;}
  14. using namespace std;
  15. /***********************常量表********************/
  16. //密度
  17. const double Dens=2850;
  18. //弹性模量
  19. const double E=71.54e9;
  20. //截面惯性矩
  21. const double I[MAXNUM]=
  22. {
  23.     0.0279e-8,0.0212e-8,0.0157e-8,0.0108e-8,0.0084e-8,
  24.     0.0061e-8,0.0045e-8,0.0037e-8,0.0032e-8,0.0030e-8,
  25.     0.0030e-8
  26. };
  27. //截面面积
  28. const double A[MAXNUM]=
  29. {
  30.     1.70e-4,1.46e-4,1.26e-4,1.09e-4,0.96e-4,
  31.     0.86e-4,0.77e-4,0.73e-4,0.70e-4,0.68e-4,
  32.     0.68e-4
  33. };
  34. //截面相对积分步长
  35. const double dx=0.01;
  36. //共振频率
  37. double w1,w2,w3;
  38. //各阶振型数据
  39. double Shape_1[MAXNUM];
  40. double Shape_2[MAXNUM];
  41. double Shape_3[MAXNUM];
  42. /********************函数声明区*******************/
  43. bool IfStop(double PreY[MAXNUM],double NextY[MAXNUM]);//收敛判据
  44. double Integral(int k,double PreY[MAXNUM]);//四重积分
  45. void Comp(void (*f_Adjust)(double NextY[MAXNUM]),double Shape[MAXNUM],double &w);//计算振型的函数
  46. void Adjust_2ndorder(double NextY[MAXNUM]);//二阶振型的调整函数
  47. void Adjust_3rdorder(double NextY[MAXNUM]);//三阶振型的调整函数
  48. int _tmain(int argc, _TCHAR* argv[])
  49. {
  50.    //打开文件等等
  51.    ofstream OutPutFile;
  52.    OutPutFile.open("re.plt",ios::out);
  53.    /*********计算并输出到屏幕***********/
  54.    Comp(NULL,Shape_1,w1);OUTPUT(1)
  55.    Comp(Adjust_2ndorder,Shape_2,w2);OUTPUT(2)
  56.    Comp(Adjust_3rdorder,Shape_3,w3);OUTPUT(3)
  57.    /**********结果记录到文件************/
  58.    OutPutFile<<"第一阶"<<endl;
  59.    for(int i=0;i<MAXNUM;++i)
  60.        OutPutFile<<0.1*i<<"  "<<Shape_1[i]<<endl;
  61.    OutPutFile<<"第二阶"<<endl;
  62.    for(int i=0;i<MAXNUM;++i)
  63.       OutPutFile<<0.1*i<<"  "<<Shape_2[i]<<endl;
  64.    OutPutFile<<"第三阶"<<endl;
  65.    for(int i=0;i<MAXNUM;++i)
  66.       OutPutFile<<0.1*i<<"  "<<Shape_3[i]<<endl;
  67.    system("pause");
  68.    OutPutFile.close();
  69.    return 0;
  70. }
  71. void Comp(void (*f_Adjust)(double NextY[MAXNUM]),double Shape[MAXNUM],double &w)
  72. {
  73.    //初始振型
  74.    double PreY[MAXNUM]={0.1,0.1,0.1,0.1,0.1,0,1};
  75.    //迭代振型
  76.    double NextY[MAXNUM]={0.0};
  77.    while(1)
  78.    {
  79.         #ifdef SHOW_DETAIL
  80.         cout<<"****Test****"<<endl;
  81.         for(int i=0;i<MAXNUM;++i)
  82.               cout<<PreY[i]<<endl;
  83.         system("pause");
  84.         system("cls");
  85.         #endif
  86.         //计算四重积分
  87.         for(int i=0;i<MAXNUM;++i)
  88.         NextY[i]=Integral(i,PreY);
  89.         //归一化
  90.         for(int i=0;i<MAXNUM;++i)
  91.               NextY[i]=NextY[i]/NextY[MAXNUM-1];
  92.         //根据正交条件调整
  93.         if(f_Adjust)
  94.               f_Adjust(NextY);
  95.         //判断收敛
  96.         if(!IfStop(PreY,NextY))
  97.              break;
  98.         //迭代
  99.         for(int i=0;i<MAXNUM;++i)
  100.              PreY[i]=NextY[i];
  101.    }
  102.    //记录当前收敛解
  103.    for(int i=0;i<MAXNUM;++i)
  104.         PreY[i]=NextY[i];
  105.    //计算共振频率
  106.    w=pow(E/Dens/Integral(MAXNUM-1,PreY),0.5);
  107.    //记录到全局变量
  108.    for(int i=0;i<MAXNUM;++i)
  109.         Shape[i]=NextY[i];
  110. }
  111. bool IfStop(double PreY[MAXNUM],double NextY[MAXNUM])
  112. {
  113.    double Sum=0;
  114.    for(int i=0;i<MAXNUM;++i)
  115.        Sum+=pow(PreY[i]-NextY[i],2);
  116.    if(pow(Sum,0.5)<STOPLINE)
  117.        return false;//停止迭代
  118.    return true;//继续迭代
  119. }
  120. double Integral(int k,double PreY[MAXNUM])
  121. {
  122.     int i,j,p,q;
  123.     double Sum_1=0,Sum_2=0,Sum_3=0,Sum_4=0;
  124.     i=j=p=q=1;
  125.     for(q=1;q<=k;++q)
  126.     {
  127.         Sum_2=0;
  128.         for(p=1;p<=q;++p)
  129.         {
  130.               Sum_3=0;
  131.               for(j=p;j<MAXNUM;++j)
  132.               {
  133.                      Sum_4=0;
  134.                      for(i=j;i<MAXNUM;++i)
  135.                      {
  136.                             Sum_4+=A[i]*PreY[i]*dx;
  137.                       }
  138.                       Sum_3+=Sum_4*dx;
  139.               }
  140.               Sum_2+=Sum_3/I[p]*dx;
  141.         }
  142.         Sum_1+=Sum_2*dx;
  143.    }
  144.    return Sum_1;
  145. }
  146. void Adjust_2ndorder(double NextY[MAXNUM])
  147. {
  148.        double C12=0,B11=0,a1;
  149.        for(int i=1;i<MAXNUM;++i)
  150.        {
  151.               C12+=A[i]*NextY[i]*Shape_1[i];
  152.               B11+=A[i]*Shape_1[i]*Shape_1[i];
  153.        }
  154.        a1=C12/B11;
  155.        for(int i=0;i<MAXNUM;++i)
  156.        {
  157.               NextY[i]=NextY[i]-a1*Shape_1[i];
  158.        }
  159.        return;
  160. }
  161. void Adjust_3rdorder(double NextY[MAXNUM])
  162. {
  163.        double C13=0,C23=0,B11=0,B22=0,a1,a2;
  164.        for(int i=1;i<MAXNUM;++i)
  165.        {
  166.        C13+=A[i]*NextY[i]*Shape_1[i];
  167.        C23+=A[i]*NextY[i]*Shape_2[i];
  168.        B11+=A[i]*Shape_1[i]*Shape_1[i];
  169.        B22+=A[i]*Shape_2[i]*Shape_2[i];
  170.        }
  171.        a1=C13/B11;
  172.        a2=C23/B22;
  173.        for(int i=0;i<MAXNUM;++i)
  174.        {
  175.               NextY[i]=NextY[i]-a1*Shape_1[i]-a2*Shape_2[i];
  176.        }
  177.        return;
  178. }
复制代码

理论基础.doc

87.5 KB, 下载次数: 30

计算结果.doc

96 KB, 下载次数: 23

回复
分享到:

使用道具 举报

发表于 2010-10-29 09:04 | 显示全部楼层
做数值计算也好几年了,怎么除了我毕业论文写了一个通用的计算椭圆、抛物、双曲方程的那个程序超过百行,其他的就纯数值处理上从没有超过百行的。
 楼主| 发表于 2010-10-29 09:14 | 显示全部楼层
回复 smtmobly 的帖子

呃……我写的这些个数值程序可都是200-300行的……有限元就更长了……
发表于 2010-10-29 09:35 | 显示全部楼层
有限元也没那么长吧!
当然你不能把矩阵运算的代码算进去!

点评

www.91xs.cc/book/55/ 魔天记  发表于 2014-8-14 12:33
发表于 2010-10-29 09:38 | 显示全部楼层
一般有限元一次元是比较好的!我都用一次元,在一次元基础上用外推和插值,结果会比高次元好很多的,当然比如是那些奇异性问题效果不见得好,但是特殊问题,高次也没啥用啊!
个人观点

点评

赞成: 3.0
赞成: 3
你能详细说说“在一次元的基础上外推和插值”的意思么?  发表于 2010-10-29 12:12
 楼主| 发表于 2010-10-29 09:39 | 显示全部楼层
回复 smtmobly 的帖子

当然要算矩阵运算,一般是变半带宽压缩,还有方程组的求解也要算……
老师说了,不许用MATLAB,要自己写!
发表于 2010-10-29 09:41 | 显示全部楼层
是自己写,方程组的求解,有标准算法啊!你用什么
发表于 2010-10-29 09:42 | 显示全部楼层
下降法和超松弛就足够了吧
 楼主| 发表于 2010-10-29 09:52 | 显示全部楼层
回复 smtmobly 的帖子

对,我用的是列主元高斯消去法和超松弛迭代
发表于 2010-10-29 12:20 | 显示全部楼层
一次元最简单,而且光滑性要求也较低,只比常元高。
关于有限元、差分等算法的外推可以看《分裂外推与组合技巧》吕涛的书。
外推和组合是基于模型的一种后处理方法,这本书里说的比较详细。我的所有的外推上的
知识都是这本书里的!效果很好。
 楼主| 发表于 2010-10-29 12:25 | 显示全部楼层
回复 smtmobly 的帖子

我一般也倾向于线性单元,但是会构造简单的等效模型换用高次的单元试算一下,确认差别不大再放心使用线性单元。谢谢你的指点,这是我没有听说和涉及过的方面,谢谢你!
发表于 2010-10-29 12:35 | 显示全部楼层
回复 Rainyboy 的帖子

客气了!高次的效果好,说明光滑性好,那么低次的外推与组合效果一定很好的。
现在很多算法,比如什么多尺度在一定程度上是一种组合或者外推,组合和外推的差别有时候很难区分。(形式上),理论上就完全不一样。
关键还是看你计算的模型是什么类型的。
考虑基于模型的这种组合方法,会让你在模型层面上去考虑,使用有限元还是差分,或者在某些区域使用有限元,另一个区域使用差分。甚至边界元、谱方法等。比您点评的那个四阶方程的例子实际上就是谱方法的一个特例。
基于模型的考虑,思路会更宽阔,并且将目光放在主流算法的基本点上,不至于陷入到一些特别艰深的问题中去
 楼主| 发表于 2010-10-29 12:51 | 显示全部楼层
回复 smtmobly 的帖子

说得是,也许我常见的工作是迅速实现一种计算方法(这种方法只要在计算空间上可行、时间上可接受就差不多了),然后就开始调整参数,分析对比结果,算个寿命算个应力什么的,反而对方法本身没有那么敏感了……呵呵
发表于 2010-10-29 12:55 | 显示全部楼层
有效就好哈!其他就当做玩了
发表于 2010-11-15 17:00 | 显示全部楼层
不错的东西啊,帮你顶啊...
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

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

GMT+8, 2024-4-27 09:40 , Processed in 0.091600 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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