☰
悬臂梁连续体振动模型:从欧拉-伯努利方程到Matlab模态分析实战
2026/10/6 3:58:46 网站建设 项目流程

悬臂梁连续体振动模型,是结构动力学里最经典的分布参数问题,也是我每年都会拿出来重新跑一遍的“基本功”。所谓连续体,就是不把梁拆成有限个弹簧和质量块,而是把整根梁看作质量和刚度连续分布的弹性体,用偏微分方程直接描述它在任意位置、任意时刻的横向振动行为,再用Matlab完成特征方程求解、振型计算和自由振动响应的模拟。这套模型看起来偏理论,实际上工程价值非常直接:悬臂梁结构在机械臂、精密平台、叶片简化模型里到处都是,有了连续体解析解,你才能给有限元结果、实验数据一个可靠的对照基准。

这篇内容适合两类人。一类是刚接触结构振动、想用代码把欧拉-伯努利梁跑通的学生;另一类是平时用ANSYS、Abaqus做分析,但对解析解感到陌生、想回头验证一下手头模型的工程师。我会从方程推导一直讲到可运行的Matlab代码,再把求根、振型、时程响应这些环节里容易踩的坑挨个说清楚。Matlab版本要求不高,R2019b以上就够,也不需要任何额外工具箱。

1. 为什么先选连续体模型

1.1 三种建模方式到底差在哪

我不止一次被问到:既然有限元软件这么强,为什么还要花时间推导连续体解析解?我的回答通常是先看下面这张对比逻辑:

模型类型基本思路优势短板
连续体模型整根梁用PDE描述,质量刚度连续分布解析解精确,振型正交、物理意义清晰只适合规则几何、简单边界
集中质量模型梁离散成若干质量块加无质量弹簧直观、手算可行精度依赖分段数,高阶误差明显
有限元模型单元离散化,形函数近似位移场适用复杂结构、载荷、边界条件网格敏感,结果需要收敛性验证

很多初学者以为有限元是“更先进的”连续体方法,这个理解对但不完整。实际上,经典有限元正是从连续体方程出发做离散逼近的,它和解析解的关系是近似与精确的关系,不是两个独立流派。你一旦理解了连续体解,再看有限元里位移形函数、刚度矩阵怎么组装、为什么加密网格会逼近同一个频率,思路会完全不同。

还有一个常被忽视的点:连续体模型拥有无穷多阶固有频率和振型,这是它的本质特性,也是离散模型理解起来最困难的地方。集中质量模型给N个自由度,就只能得到N阶固有频率;而一根实际梁的振动频带理论上一直延伸到无穷。高阶模态对冲击响应、声辐射这类问题的影响非常大,如果从一开始只停留在“有限自由度”的思维里,后面做减振降噪会有很大的认知盲区。

1.2 欧拉-伯努利梁的适用边界要心里有数

用连续体模型求解悬臂梁,默认采用的是欧拉-伯努利梁理论。它有两个核心假设:第一,变形前垂直于中性轴的截面,变形后仍然垂直于中性轴,对应“平截面假设”;第二,忽略剪切变形和截面转动惯量,梁的弯曲仅由弯矩引起。

这意味着,这套解析解对“细长梁”很准,对“深梁”则可能跑偏。工程上常用长细比 L/h 来判断:当 L/h 大于10甚至20时,一阶低阶模态的剪切变形影响通常很小,欧拉-伯努利梁理论已经足够;当 L/h 小于5,或者关心高频高阶模态时,就需要考虑铁木辛柯梁理论,它额外引入了剪切变形和转动惯量两个修正项。

我们后面算例用的梁,长度1米、高度0.01米,长细比100,完全落在欧拉-伯努利梁的舒适区。如果你拿同样的代码去算一根又粗又短的悬臂梁,就会发现解析频率比有限元结果偏高,因为真实梁的剪切变形降低了等效刚度。这一点务必提前记住,省得后面拿着代码到处套用出问题。

2. 连续体振动的核心方程与推导逻辑

2.1 四阶偏微分方程是怎么来的

要写出悬臂梁横向自由振动的连续体方程,过程并不复杂,核心就两步。

第一步是微元体力平衡。取长度为 dx 的梁微元,横向剪力 V 和惯性力 ρA dx·∂²w/∂t² 平衡,得到剪力沿梁长的导数关系。第二步是弯矩与曲率的关系:M = EI·∂²w/∂x²,而剪力又是弯矩的导数:V = ∂M/∂x。把这两个关系代入平衡方程,消去剪力和弯矩,就得到著名的欧拉-伯努利梁自由振动方程:

EI·∂⁴w/∂x⁴ + ρA·∂²w/∂t² = 0

注意这里 w 是梁的横向位移,EI 是抗弯刚度,ρA 是单位长度质量。方程里每一项的物理意义都很明确:第一项描述弯曲变形带来的弹性恢复力,第二项描述微元的惯性力。整体上就是“惯性力 + 弹性力 = 0”,和弹簧振子方程 ma + kx = 0 异曲同工,区别只是这里每个无穷小微元都在参与振动物理系统。

2.2 分离变量:空间振型和时间简谐

连续体方程是偏微分方程,直接求解不方便,所以用分离变量法,假设:

w(x,t) = W(x)·q(t)

这里 W(x) 只决定梁的振型形状,q(t) 只决定这个形状随时间如何变化。把上式代回方程,整理后可以得到两个常微分方程。其中一个方程的解就是简谐运动:

q''(t) + ω²q(t) = 0

这说明一旦梁按某个振型自由振动,它在该振型上的时间响应就是正弦或余弦函数。另一个方程是关于 W(x) 的四阶常微分方程,如果定义无量纲参数:

β⁴ = ω²ρA/(EI)

就可以得到 W⁗(x) - β⁴W(x) = 0。这个四阶常微分方程的通解是双曲正弦、双曲余弦、正弦、余弦四个基函数的线性组合。到这里,后续所有代码都围绕这个通解和四个边界条件展开。

2.3 边界条件如何浓缩成特征方程

悬臂梁的边界条件一共四个:固定端位移和转角为零,自由端弯矩和剪力为零。写成数学形式是:

W(0)=0, W'(0)=0, EI·W''(L)=0, EI·W'''(L)=0

把通解代入这四个条件,会得到一个关于待定系数的齐次线性方程组。这个方程组要有非零解,系数行列式必须等于零。经过一番整理,最终得到的不是频率方程,而是关于无量纲参数 r = βL 的一个超越方程:

cos(r)·cosh(r) + 1 = 0

这个方程没有闭合解,只能数值求解。它每一组根对应一阶固有模态,根从小到大依次排列,就对应第一阶、第二阶、第三阶……的振动模式。得到特征根 r_n 后,固有圆频率由下式给出:

ω_n = r_n² · sqrt(EI/(ρA·L⁴))

对应的振型函数为:

W_n(x) = cosh(β_n x) - cos(β_n x) + k_n·(sin(β_n x) - sinh(β_n x))

其中 k_n = (cosh(r_n) + cos(r_n))/(sinh(r_n) + sin(r_n))。

这里我提醒一句:不同教材振型函数写法可能略有差异,有的用正号,有的用负号,但本质是同一个公式,因为 k_n 的取值会跟着调节,最后画出来的归一化振型是完全一致的。你只要选定一种自洽的写法,从特征方程到振型一路用到底,就不会出问题。

3. Matlab代码实现:一行行拆开讲

3.1 参数设置与无量纲化思路

写代码的第一步是定义结构和物理参数。我这里用钢制矩形截面悬臂梁做演示:长度1米,宽0.05米,高0.01米。材料用结构钢,弹性模量E=210GPa,密度ρ=7850kg/m³。之所以选这组数据,是因为它对应一条实实在在的钢尺,算出来的频率量级大家可以凭直觉判断是否合理。

在这个阶段,我强烈建议先把无量纲特征根 r_n 求出来,因为它和材料无关,只由边界条件决定。这也是整个连续体模型里最有价值的部分。带物理量纲的频率换算放到后面再做,否则一旦结果不对,你根本分不清是方程推导错了还是单位换算错了。

clear; clc; close all; % 悬臂梁几何与材料参数(钢制矩形截面) E = 210e9; % 弹性模量,Pa rho = 7850; % 材料密度,kg/m^3 L = 1.0; % 梁长,m b = 0.05; % 截面宽度,m h = 0.01; % 截面高度,m A = b*h; % 截面面积,m^2 I = b*h^3/12; % 截面惯性矩,m^4

3.2 特征根求解:先画图定位再精化

特征方程 cos(r)·cosh(r)+1=0 属于超越方程,直接求解析值不现实。我的习惯是分两步走:先用一个很小的步长扫描整个区间,找出所有符号发生变化的区间,确定大概的根位置;再用 fzero 在每个小区间内精化,得到高精度数值解。

这一步看起来简单,但特别容易翻车。如果扫描步长取得太大,就可能跳过相邻很近的两个根,尤其在高阶区间,根与根的间距会逐渐趋近于 π,但低阶区域的第一个根只有1.875,如果你从0开始用步长1去扫,第一个根所在的区间就会被漏掉。反过来,步长取得太小,计算量上来了,但其实也没必要。实际经验是步长取0.1左右,对前十几阶根都非常安全。

% 求特征方程 cos(r)*cosh(r)+1=0 的前N个根 N = 4; % 取前四阶 r = zeros(N,1); % 无量纲特征根 r = beta*L step = 0.1; r_min = 1e-6; r_max = 50; grid_r = r_min:step:r_max; idx = 0; for i = 1:length(grid_r)-1 r1 = grid_r(i); r2 = grid_r(i+1); if (cos(r1)*cosh(r1)+1) * (cos(r2)*cosh(r2)+1) < 0 idx = idx + 1; r(idx) = fzero(@(x) cos(x)*cosh(x)+1, [r1, r2]); if idx >= N break; end end end % 如果扫描区间内没找齐,用高阶渐近公式补根 for n = idx+1:N r(n) = (n - 0.5)*pi; end

渐近公式 (n-0.5)π 非常实用,悬臂梁第n阶无量纲特征根的高阶近似就是它。比如第五阶真实值是14.1372,而 4.5π 等于14.1372,几乎一致。所以当你要算十几阶模态时,可以直接用这个公式初始化,再拿牛顿法或fzero修正,效率高得多。

3.3 振型函数与归一化

特征根有了,振型函数就可以直接套公式。这里要特别注意双曲函数在自变量较大时增长极快,高阶模态时指数项可能会变得非常大,但只要 r_n 在几十以内,Matlab的double精度完全扛得住。

归一化的方式我选最大绝对值归一化,也就是让每阶振型的最大位移等于1。这样做的好处是画图直观、方便对比。另外还有一种质量归一化,把振型按 ∫ρA·W²dx=1 归一化,在模态叠加和响应分析里更常用。两种都可以,关键是一旦选定就要全程统一,不要算频率用一套、算响应换另一套,容易出现莫名其妙的系数错误。

% 振型计算与归一化 x = linspace(0, L, 400)'; modes = zeros(length(x), N); for n = 1:N beta = r(n)/L; k = (cosh(r(n)) + cos(r(n))) / (sinh(r(n)) + sin(r(n))); W = cosh(beta*x) - cos(beta*x) + k*(sin(beta*x) - sinh(beta*x)); modes(:,n) = W / max(abs(W)); end % 画前四阶振型 figure('Color','w'); plot(x/L, modes(:,1:N), 'LineWidth', 1.8); grid on; xlabel('x/L'); ylabel('归一化振型 W_n'); legend('第1阶','第2阶','第3阶','第4阶','Location','northwest'); title('悬臂梁连续体模型前四阶振型');

关于振型图,有两点值得说。第一,第n阶振型的节点数等于 n-1,也就是一阶没有节点、二阶有一个节点、三阶有两个节点,以此类推。这是判断振型计算结果是否正确的快速规则。第二,节点位置是由边界条件决定的,不随材料参数变化,所以你用钢材、用铝材,画出来的归一化振型形状完全重合,变的只有固有频率和振型在时间响应里的参与程度。

3.4 自由振动时程:模态叠加法

连续体模型的自由响应,本质是把初始位移和初始速度投影到各阶模态上,再分别按各自的固有频率做简谐运动,最后叠加。这就是模态叠加法。

计算模态坐标的初始值需要用到模态质量。数值积分用 trapz 足矣,不需要更精细的积分方案。我这里故意选了一个比较“有内容”的初始位移:悬臂梁端部受集中力作用下的静挠度曲线。这条曲线包含多阶模态成分,用它作初始条件,自由振动时程里就能明显看到高阶模态的贡献,而不是只有单一频率的纯简谐波。

静挠度公式是 w(x) = F·x²·(3L-x)/(6EI),我按自由端初始挠度5毫米反算集中力F。这个初始条件本身不是某一阶纯模态,所以能直观演示模态叠加的威力。

% 固有圆频率和频率 omega = r.^2 * sqrt(E*I / (rho*A*L^4)); freq = omega / (2*pi); % 初始条件:端部集中力静挠度,自由端初位移5mm F = 0.005 * 3*E*I / L^3; w0 = F * x.^2 .* (3*L - x) / (6*E*I); v0 = zeros(size(x)); % 计算模态坐标初始值 Nmodes = N; M_n = zeros(Nmodes,1); A_n = zeros(Nmodes,1); B_n = zeros(Nmodes,1); for n = 1:Nmodes M_n(n) = trapz(x, rho*A*modes(:,n).^2); A_n(n) = trapz(x, rho*A*modes(:,n).*w0) / M_n(n); B_n(n) = trapz(x, rho*A*modes(:,n).*v0) / (M_n(n)*omega(n)); end % 时间响应:取三倍一阶固有周期 T1 = 2*pi / omega(1); t = linspace(0, 3*T1, 1200); w_tip = zeros(size(t)); legendStr = {'总响应'}; figure('Color','w'); hold on; for n = 1:Nmodes qt = A_n(n)*cos(omega(n)*t) + B_n(n)*sin(omega(n)*t); w_tip = w_tip + qt*modes(end,n); plot(t, qt*modes(end,n)*1000, '--', 'LineWidth', 0.8); legendStr{end+1} = sprintf('第%d阶贡献', n); end plot(t, w_tip*1000, 'LineWidth', 1.8); grid on; xlabel('时间 (s)'); ylabel('自由端位移 (mm)'); legend(legendStr); title('悬臂梁自由端自由振动时程(模态叠加法)');

我特别提醒一点:模态截断是这套方法绕不开的话题。严格来说,连续体有无穷多阶模态,代码里只取了四阶,所以响应是一个近似结果。初始位移里的高阶成分被截断了,时程曲线在一开始会有一点点偏差,随后主要由前四阶主导。想验证截断误差,直接加大 N 重新跑一遍对比即可,这也是理解“模态收敛性”最直观的一种方式。

3.5 把代码拼成完整脚本

上面几段代码是按逻辑顺序拆开的,变量名保持一致,从上到下按顺序复制到同一个脚本里就能直接运行。完整流程为:先定义物理参数,求解无量纲特征根,再由特征根算出固有频率和振型,最后用静挠度作为初始条件算时程响应。

运行时你会看到三个输出:命令行打印前四阶无量纲特征根和固有频率;一张前四阶振型图;一张自由端位移时程图。振型图里应该看到一阶无节点、二阶一个节点、三阶两个节点、四阶三个节点的典型形态。时程图里总响应和四阶模态贡献曲线一起显示,其中第一阶贡献占主导,其余阶次负责叠加出细微的波纹。这就是连续体模型和单自由度模型的直观区别,也是这套代码最有说服力的地方。

4. 算例验证:频率、振型与物理直觉

4.1 前四阶频率结果与手工核对

我用前面那组钢制矩形截面参数实际算了一轮,结果如下:

阶次无量纲特征根 r_n圆频率 ω_n (rad/s)频率 f_n (Hz)
11.875152.498.35
24.6941329.0052.36
37.8548921.20146.63
410.99551805.30287.33

这些数值符不符合物理直觉?一根一米长、五厘米宽、一厘米厚的钢尺,捏住一端让它自由振动,第一阶频率大约8赫兹,这个数据和我平时拿尺子试振的感受是吻合的。两侧频率比值大约是1:6.27:17.55:34.39,对应特征根平方的比值 1:6.27:17.55:34.39,这个比值只由边界条件决定。

4.2 振型图和正交性检查

除了看节点数,还可以用数值方法验证正交性。理论上,连续体振型满足:

∫₀ᴸ ρA·W_i(x)·W_j(x)dx = 0,当 i ≠ j

在代码里算积分矩阵,用trapz对每一对振型做数值积分,会得到一个近似对角矩阵,对角占主导,非对角元接近零,但不会严格等于0,因为trapz是数值积分,存在离散误差。这是连续体模型区别于离散模型的一个重要性质:正是因为振型正交,模态叠加法的“各阶独立响应再叠加”才有成立的数学基础。

实际项目里,正交性还是一个极好的排错工具。如果你的振型函数算错了,正交性矩阵往往会出现肉眼可见的非对角大值;如果矩阵接近对角,基本说明方程和边界条件处理对了大半。

4.3 与离散模型或有限元结果交叉验证

我在调试这类代码时,通常会额外建一个粗网格有限元模型做交叉验证。你可以用ANSYS、Abaqus,或者自己写一个简单的欧拉梁单元刚度矩阵和质量矩阵,在Matlab里求广义特征值。当梁的网格数量达到20个单元以上时,前四阶固有频率和解析解的误差一般都能控制在1%以内,网格越密越逼近连续体解。

如果对不上,先别急着怀疑有限元,优先级是这样的:先查单位制,E是不是用成了GPa代入Pa;再查截面惯性矩公式是不是把 b 和 h 弄反了;然后查梁单元是不是用的欧拉-伯努利理论;最后检查固定端约束是否把平动和转动全都锁住了。这些环节按顺序排查,大多数“解析解和有限元对不上”的问题都能解决。

5. 常见问题与排查技巧实录

5.1 特征根漏根、跳根怎么办

最典型的症状是代码跑出来第一阶特征根直接跳到4.69,把1.875漏了。原因几乎都是扫描步长过大或者扫描起始点离0太远。还有一个隐藏问题:第一个根在 r=1.875 附近,而函数 cos(r)·cosh(r)+1 在 r=0 处的值是2,在第一个根之后振荡越来越密集,如果步长取到0.5,可能会在某个高阶区间跨过两个根之间的一个极小正峰,导致漏根。解决办法很简单:扫描步长取0.1,必要时把fzero的初始区间打印出来确认每一个根的位置都在区间内。另外,算完所有根后可以顺手检查 r 数组是否严格单调递增,且相邻间隔约等于π,这是一个非常高效的体检方式。

5.2 振型图像错乱:先查量纲和归一化

振型图如果出现端部大幅翘起、形状不对称、曲线锯齿状,多半是单位搞混,比如计算 cosh(βx) 时 β 的单位是 rad/m,x 却用了毫米;或者 L 用了1米,x 用了毫米向量,导致 βx 不是无量纲值,双曲函数自变量被放大了1000倍,结果必然发散。另一种情况是归一化时用了 max(W) 而不是 max(abs(W)),如果某阶振型的最大值横跨正负两侧,用 max(W) 归一化会让负向峰值超过1,图看起来就不对。我写代码时一定会加 max(abs(W)),这个坑太隐蔽。

5.3 频率数值差几个数量级:单位制背锅

频率算出来差6个数量级,十有八九是弹性模量没从 GPa 换成 Pa。比如把 E=210 代入公式,而不是 210e9,这个错误在公式层面完全看不出来,因为量纲检查很难在代码里自动完成。我的做法是在代码注释里专门写清每个变量的单位,算完之后用常识做量级检查:一根普通钢尺的一阶频率在5到20赫兹,如果算出来是0.008赫兹,那不用怀疑,单位肯定错了。

5.4 与商业软件对不上:别忘边界条件和梁理论

同样是悬臂梁,ANSYS默认的梁单元可能有平动自由度约束但转动自由度没锁紧,或者用了考虑剪切变形的梁单元理论,结果在低阶上差百分之几。这些问题在细长梁上不突出,在深梁上非常明显。对比时务必确认:材料密度是质量密度而不是重量密度;几何单位统一;固定端自由度全部约束;单元类型与欧拉-伯努利假设匹配。如果这些都符合,但高频段仍有差异,那不是谁算错了,而是连续体解析解天然忽略了剪切变形,高频模态对剪切更敏感,需要切到铁木辛柯梁理论才能对齐。

6. 实操心得和后续扩展

几个长期形成的习惯聊一聊。第一,先求无量纲特征根再带物理量纲,这是整个流程里最不容易出错的做法,因为 r_n 只由边界条件决定,可以独立验证,物理参数只是最后乘上去的比例因子。我把这根弦绷得很紧,几乎每次都会在无水印草稿上把 r_n 和教材值对一遍再往后走。

第二,画图比数值列表更能发现问题。我计算前总会把特征方程曲线画出来,把求到的根用散点标记上去,一眼就能看出有没有漏根,比单纯打印数值可靠得多。对振型和时程图也同理,曲线形状是否符合物理直觉,是比“数值精度几个小数位”更先需要检查的指标。

第三,动画是理解模态叠加最好的工具。把每一时刻的梁形变画成连续动画,你就能看到自由端位移除了主频大周期,还有高阶模态叠加出来的细微波纹。这个动画用Matlab的animatedline就可以实现,帧率不用太高,20帧左右即可。做一次动画,比盯着地看十遍静态图都有用。

后续扩展方向,我建议从三个角度出发。一是加激励,把自由振动改成谐波激励下的稳态响应,看共振峰的出现位置和各阶阻尼的影响;二是换理论,把欧拉-伯努利梁升级为铁木辛柯梁,对比深梁的修正效果;三是组合验证,把解析频率和有限元结果放在同一张收敛曲线图上,画出“频率-网格数”的收敛趋势,你会对有限元方法的逼近过程有更深的理解。这套连续体模型是一块很好的“知识跳板”,向下能连接有限元离散逼近,向上能衔接弹性波传播和结构声学,值得多花时间玩透。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询