用MATLAB实现悬臂梁有限元分析:从Hermite单元到弯矩图
2026/9/16 11:38:38 网站建设 项目流程

简介:面向结构力学与数值仿真学习者,这份资源提供基于有限元法求解悬臂梁弯曲问题的完整MATLAB实现。代码采用参数化编程,矩阵参数可灵活更改,注释细致,便于二次开发与算法理解;同时附带可直接运行的案例数据,适用于计算机、电子信息工程、数学等专业的学生完成课程设计、期末大作业或毕业设计。压缩包共包含13个文件,其中9个为.m脚本、3个为.jl脚本、1个为.md说明文档,能够同时展示MATLAB与Julia两种语言实现,并覆盖形函数、单元刚度矩阵、全局刚度矩阵组装等核心模块,有助于对照理解有限元求解流程。代码模块划分清晰,参数调整方便,可直接替换材料参数或梁截面尺寸进行扩展验证。整包仅7KB,轻量便于快速获取。目前已有182人学习浏览,对于需要短时间掌握悬臂梁有限元建模思路的读者而言,是一份高效实用的参考。

1. 悬臂梁弯曲问题:材料力学公式失效时的通用解法

材料力学课本能直接给出悬臂梁自由端的挠度、转角闭式解,可一旦换成变截面、分段均布载荷或需要在同一根梁上组合集中力和分布力,手推公式就会很狼狈。有限元法把梁离散成有限个欧拉-伯努利梁单元,每个单元用 Hermite 形函数描述挠度和转角,再组装成整体刚度方程求解。这个算例在结构分析和有限元入门里是标准练习,因为不依赖任何有限元工具箱,核心代码可以控制在 60 行以内。下面从控制方程的弱形式开始推,把这一段在一个 MATLAB 脚本里完整跑通,并和解析解比较,最后告诉你如何从位移结果里再把弯矩图恢复出来。

2. 有限元法求解梁弯曲问题的理论基础

2.1 控制方程与弱形式:为何要先做变分处理

对等截面欧拉-伯努利梁,静力弯曲控制方程为

EI v'''' = q(x)

有限元法不直接解这个四阶常微分方程,而是把它变成虚功方程:设 w 为满足固定端约束的虚位移场,对全梁分部积分后得到

∫ EI v'' w'' dx = ∫ q w dx

这个形式只要求积分里有二阶导数,单元插值函数只需保证 C1 连续。悬臂梁在两个边界上的本质条件只有固定端 v(0)=0 和 θ(0)=v'(0)=0,自由端的弯距与剪力是自然边界条件,求解后自动满足。所以做约束处理时只删两个自由度,整根梁的 K 矩阵不会出现零主元。

2.2 Hermite形函数与四阶刚度矩阵的物理含义

单元每个节点有挠度和转角两个自由度,于是两节点单元的自由度顺序记为 [v1, θ1, v2, θ2]。用局部坐标 ξ=x/Le 定义的四条三次 Hermite 基函数是

N1 = 1 - 3ξ² + 2ξ³,对应节点1单位挠度; N2 = Le(ξ - 2ξ² + ξ³),对应节点1单位转角; N3 = 3ξ² - 2ξ³,对应节点2单位挠度; N4 = Le(ξ³ - ξ²),对应节点2单位转角。

它们保证单元两端挠度和转角各自连续,这正是一维梁单元与桁架杆单元最本质的区别。把 N'' 代入单元势能积分,得四阶单元刚度矩阵

| 12 EI/Le^3 6 EI/Le^2 -12 EI/Le^3 6 EI/Le^2 | | 6 EI/Le^2 4 EI/Le -6 EI/Le^2 2 EI/Le | | -12 EI/Le^3 -6 EI/Le^2 12 EI/Le^3 -6 EI/Le^2 | | 6 EI/Le^2 2 EI/Le -6 EI/Le^2 4 EI/Le |

第一列的含义是:让 v1=1 而其余自由度为零,需要在节点1施加向上的力 12EI/Le³ 和逆时针弯矩 6EI/Le²,同时节点2配套向下力 -12EI/Le³ 和逆时针弯矩 6EI/Le²。其余各列同理。这样理解的好处是组装时能直观检查力的平衡:任意一列四个分量之和,力方向分量和应为零,弯矩分量和应等于该列力对单元形心的矩。

2.3 一致载荷向量和固定端约束的数学处理

均布载荷 q 在单元左右节点上的等效节点力不是简单地 qLe/2 分到两个节点,还伴随一对端部等效弯矩。推导得到的载荷向量为

fe = qLe/12 [6, Le, 6, -Le]^T

其中第二个自由度方向在坐标取向右为正、顺时针转角为正时,左端等效弯矩为 +qLe²/12,右端为 -qLe²/12。不要漏写这个弯矩项,否则粗网格下端部挠度和转角都会偏小。集中力 P 作用在节点 j 时,只需在全局载荷向量 F(2j-1) 处叠加 P;集中弯矩 M 作用在节点 j 则叠加到 F(2j)。整体求解采用“先组装、后约束”的流程,把固定端自由度从方程组中剔除,只解自由自由度子块,避免对全矩阵做手工行交换。

3. MATLAB实现:从节点坐标到挠度曲线的完整脚本

3.1 物理参数与网格生成:统一单位是第一要务

这里的实现按经典三步走:生成节点、组装、加约束求解。整个流程的数学基础非常对称,单元数增加时,只有 K 和 F 变化。一个直接的参数与网格部分如下。

clearvars; close all; clc; % 物理参数,采用 m-N-Pa 一致单位制 E = 210e9; % 弹性模量 b = 0.03; % 梁宽 h = 0.06; % 梁高 I = b*h^3/12; % 惯性矩 L = 1.0; % 悬臂梁长度 q = -1000; % 均布线载荷, N/m 向下取负 % 网格 nEl = 8; % 单元数 nnp = nEl + 1; % 节点数 x = linspace(0, L, nnp)'; Le = diff(x); % 每单元长度

不少初学实现栽在单位制:长度用了 mm 而弹性模量用 Pa(即 N/m²),惯性矩按 mm⁴代入,EI 直接差 10^12 倍。这里统一按米、牛顿、帕斯卡计算,最后绘图时再转成毫米。

3.2 组装全局矩阵:自由度编号与稀疏矩阵

全局自由度编号规则是节点 i 对应 2i-1(挠度)、2i(转角)。单元左节点编号 n1=e,右节点 n2=e+1,于是单元自由度映射为 edof = [2n1-1, 2n1, 2n2-1, 2n2],直接靠这个索引做四阶矩阵的 scatter 叠加。组装循环见下面代码块。

nDofs = 2*nnp; K = sparse(nDofs, nDofs); F = zeros(nDofs, 1); for e = 1:nEl ke = beamStif(E, I, Le(e)); fe = beamLoad(q, Le(e)); n1 = e; n2 = e + 1; edof = [2*n1-1, 2*n1, 2*n2-1, 2*n2]; K(edof, edof) = K(edof, edof) + ke; F(edof) = F(edof) + fe; end

稀疏矩阵 K 在这里不是可有可无的优化:单元数为几百时满矩阵也能算,过千后稀疏与稀疏分解的速度差异就到数量级。MATLAB 的sparse会在重复索引叠加时自动累加,不需要自己处理冲突。

3.3 两个子函数:单元刚度与一致载荷向量

function ke = beamStif(E, I, Le) % Hermite 梁单元刚度,自由度顺序 [v1, th1, v2, th2] ke = E*I/Le^3 * [ 12 6*Le -12 6*Le; 6*Le 4*Le^2 -6*Le 2*Le^2; -12 -6*Le 12 -6*Le; 6*Le 2*Le^2 -6*Le 4*Le^2]; end function fe = beamLoad(q, Le) % 均布载荷一致节点力;q 向上为正,转角自由度按逆时针为正 fe = q*Le/12 * [6; Le; 6; -Le]; end

这里的关键是符号约定:全梁规定挠度向上为正、转角逆时针为正。将 q 取负后,自由端挠度数值为负,正好对应向下挠曲。如果原先设计为“向下为正”的计算体系,需要把这一条在模块入口处统一,否则后续恢复弯矩图时会栽在正负号问题上。

3.4 边界处理、求解与解析解对比

固定端节点编号为1,需要约束的全局自由度是 1 和 2。实现上不修改 K 矩阵,而是先选出自由自由度索引,求解后再把结果回填到完整的位移向量。

fixedDofs = [1 2]; freeDofs = setdiff(1:nDofs, fixedDofs); u = zeros(nDofs, 1); u(freeDofs) = K(freeDofs, freeDofs) \ F(freeDofs); v = u(1:2:end); % 节点挠度 th = u(2:2:end); % 节点转角 % 解析解用于验证 x_fine = linspace(0, L, 201)'; v_exact = q * x_fine.^2 .* (6*L^2 - 4*L*x_fine + x_fine.^2) / (24*E*I); fprintf('自由端 FEM 挠度 : %.6f mm\n', v(end)*1000); fprintf('自由端解析解 : %.6f mm\n', v_exact(end)*1000);

运行要点:nEl 取 8 时自由端挠度已经有 4 位有效数字。解析解取均布载荷悬臂梁端部公式 v(L) = qL⁴/(8EI),快速自检时可以用这条公式心算数量级。

4. 验证与误差分析:用解析解检验代码是否写对

4.1 解析解对照公式与误差定义

悬臂梁均布载荷 q 作用下,距离固定端 x 处的挠度为 v(x) = qx²(6L² - 4Lx + x²)/(24EI),端部特例 v(L) = qL⁴/(8EI)。另一类常用算例是自由端受集中力 P,解为 v(L) = PL³/(3EI)、θ(L) = PL²/(2EI)。验证时建议同时测这两组:集中力直接加在节点,自由度载荷向量构造简单;均布载荷则检验一致载荷向量是否写对。定义相对误差为 err = |v_FEM(L) - v_exact(L)| / |v_exact(L)|,这个量在细网格下应当随单元数增加单调下降。

4.2 网格收敛性测试:算到收敛阶就不再需要怀疑代码

找收敛阶比看单一误差更有说服力。做法是分别用 1、2、4、8、16、32 个单元跑同一问题,记录自由端挠度误差,再用相邻网格的误差比算收敛阶。对 Hermite 梁单元,理论上自由端挠度以 O(Le⁴) 收敛,即加密一倍误差应缩小为约 1/16,log-log 曲线的斜率接近 4。接着给出扫网格的脚本。

nElList = [1, 2, 4, 8, 16, 32]; err = zeros(size(nElList)); for i = 1:numel(nElList) v_end = solveBeam(E, I, L, q, nElList(i)); err(i) = abs(v_end - q*L^4/(8*E*I)) / abs(q*L^4/(8*E*I)); end order = -log(err(2:end) ./ err(1:end-1)) ./ log(nElList(2:end) ./ nElList(1:end-1));

这里的收敛阶是相邻两次网格加密之后计算出来的局部斜率。若代码无误,order 数值会很快逼近 4;若组装索引写错,误差曲线会不收敛或在某个网格密度卡住。自由端集中力算例的载荷施加点恰在节点时,Hermite 单元能精确满足节点条件,误差几乎为零,因此更适合检查边界条件是否约束住刚体自由度,不适合用来检验网格收敛行为。

4.3 三个高频坑:奇异矩阵、符号约定、单位复核

实际编写中,K 矩阵“接近奇异”几乎总是由两个原因引起:忘加固定端约束,或者约束自由度设置成了 [1] 而不是 [1 2]。只约束挠度时梁仍可绕固定端转动,方程组在数学上仍奇异;MATLAB 的\会给出 NaN 或巨大的数值结果。符号约定问题更隐蔽:均布载荷向下时,有些代码习惯把“下”定义成正方向,于是整个载荷向量符号体系翻转,端部挠度结果本身仍对称,但若之后要恢复弯矩,内力的符号会与材料力学常用约定相反。最后,强制建议在程序开头打印 EI 与 qL⁴/(8EI) 的数量级,如果自由端挠度输出是 10^-6 而不是 10^-3 量级,先查自己的单位,不要先怀疑矩阵组错。

5. 进阶技巧:从位移恢复弯矩图与批量参数扫描

5.1 恢复单元内力矩:不要在节点处直接取弯矩

位移解是有限元直接输出,但工程报告通常还需要弯矩图。常见做法是取单元内部一个点计算 EI·v'',避免在单元边界处出现不连续。均匀网格下最简单的恢复办法是用单元两端的转角和挠度直接计算单元中点弯矩。对 Hermite 单元,二阶导在单元内线性变化,取 ξ=0.5 时表达式为:

M_mid = EI * (6(v1 - v2)/Le² + (θ1 + θ2)/Le)

符号按前面约定的“挠度向上为正”来。数值验证时可直接对比均布载荷下的解析弯矩 M(x) = -q(L-x)²/2。若结果在中部吻合而固定端附近偏差偏大,是粗网格解的弯矩不连续造成的,加密网格后该现象消失。

M_mid = zeros(nEl, 1); for e = 1:nEl n1 = e; n2 = e + 1; Le = x(n2) - x(n1); d2v = 6*(v(n1) - v(n2))/Le^2 + (th(n1) + th(n2))/Le; M_mid(e) = E*I*d2v; end

这段代码与直接提取节点弯矩相比,避开了单元交界面处内力突变带来的锯齿。绘图时将 M_mid 画在单元中点并用stairs或分段直线连接,就能得到一张平滑的弯矩分布图。

5.2 封装求解函数做多工况批量扫描

到这里脚本已能解决单工况,继续优化一下复用性:把“输入 E, I, L, q, nEl → 输出自由端挠度”封装成函数 solveBeam,再用 MATLAB 结构体打包一组截面尺寸做参数扫描。例如要比较梁高 h 从 40mm 到 100mm 变化时端部挠度,只需循环调用。这种封装一旦成型,换个载荷类型或改变约束条件,改动的只是载荷向量和约束自由度两行代码。扫参时注意把 nEl 设成够用且固定的值,避免网格变化和物理变化混在同一张图里。

这套实现没有任何工具箱依赖,从单元刚度矩阵到弯矩恢复全部可读、可改,非常适合继续往变截面梁、温度载荷和材料非线性方向扩展。下一处要修改的往往是单元刚度矩阵的积分过程,而不是整个求解框架。

本文还有配套的精品资源,点击获取

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

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

立即咨询