☰
声子晶体梁带隙计算:12×12传递矩阵与Timoshenko梁模型详解
2026/10/5 7:24:45 网站建设 项目流程

简介:面向声子晶体梁带隙特性数值研究,提供一份基于Timoshenko梁理论的12×12传递矩阵MATLAB计算脚本。Timoshenko梁计入剪切变形与转动惯量,相比欧拉-伯努利梁更精确,适合宽梁、薄壁梁等结构;传递矩阵法将梁离散为若干子段,通过局部矩阵连乘获得全局传递矩阵,可高效处理周期性边界条件并求解频散关系。压缩包仅含1个m脚本,整体约2KB,代码模块包括参数定义、单元传递矩阵计算、全局矩阵组装、频率扫描与结果可视化,结构清晰,便于直接运行和二次修改。已有367人学习下载。读者可通过调整梁的几何尺寸、材料属性或周期排布参数,方便地复现带隙结构,观察频率响应曲线、带隙范围与模态形状,为声隔离、声过滤等实际工程应用提供理论支持与数值参考。

1. 十二乘十二的传递矩阵,到底在算声子晶体梁的什么

这片子聊的是一个很具体的计算问题:把声子晶体梁拆成周期单元,用 12×12 的传递矩阵扫出弯曲波带隙。这里的 12×12 不是装饰,是 Timoshenko 梁模型下每个截面状态量的自然维度;传递矩阵组装好之后,带隙位置、宽度、衰减常数一次全给出来。很多人第一次接触声子晶体梁,习惯直接套 Euler-Bernoulli 梁的四阶微分方程,觉得状态量四个就够了,结果算高阶带隙或者截面高宽比稍大时,带隙中心和实验差得离谱。适合的读者很明确:你在做周期梁、超材料梁、夹层梁的带隙分析,或者要给后续的有限周期透射率、实验验证铺一个可复现的基准算法,这篇文章就是给你一条从零搭起来的路径。

2. 为什么状态向量凑成12维:Timoshenko梁、双梁耦合与单胞矩阵

2.1 声子晶体梁的带隙来源:材料周期只是第一步

声子晶体梁本质上是一维周期结构。你沿梁长方向周期性地改变截面尺寸、材料参数,或者周期性地布置谐振单元,弯曲波在传播时就会在布拉格频率附近发生散射,某些频段内没有实数波数解,波传不过去,这就是带隙。计算带隙的手段有很多:平面波展开、有限元特征频率法、谱元法,以及本文要讲的传递矩阵法。传递矩阵法的好处是直观且省内存,尤其适合“先扫频、后看趋势”的前期设计:你不用建三维模型,单胞矩阵乘起来就能得到色散关系和有限周期透射率。

但声子晶体梁的麻烦在于梁理论的选择。Euler-Bernoulli 梁假设截面在变形后仍垂直于中性轴,忽略剪切变形和转动惯量,在长细比很大的细长梁、低频段是可靠的。可声子晶体梁为了压低频带隙,往往把梁做厚、做短,或者使用高宽比接近 1 的截面,此时剪切变形对挠度的贡献不可忽略,转动惯量对弯矩平衡的修正也开始显现。我一般在工程复现里直接上 Timoshenko 梁模型,把横向位移、截面转角、弯矩、剪力四个量全部显式写出来,剪切变形通过截面形状系数进入柔度项,转动惯量通过惯性力矩进入弯矩平衡。这样做的代价是状态量变多,但换来的好处是计算结果在高频段仍然可靠,不会在带隙边界上翻车。

2.2 Timoshenko梁与欧拉梁的分叉点:什么时候必须用12×12这套重工具

一个直观的判据是剪切变形的影响系数:当梁的截面高度与波长之比超过 0.1 时,Euler-Bernoulli 梁的相速度预测就会明显偏高。声子晶体梁带隙通常出现在第一布里渊区边界附近,对应的波长很短,正好落在这个误差区间。你如果拿 Euler-Bernoulli 梁算出的带隙中心频率去做实验,经常会发现差出 10% 到 20%,而且越往高阶带隙越离谱。

把 Timoshenko 梁写成状态空间形式后,每个截面的状态量是轴向位移、横向位移、截面转角、轴力、剪力、弯矩六个分量。为什么是六个?因为弯曲和轴向振动在直梁里通常解耦,但程序里一旦要处理轴向力耦合、或者后续要拼装任意方向的子结构,把轴向位移和轴力一起放进状态向量反而省事。于是单根 Timoshenko 梁段的场传递矩阵是 6×6。

那 12×12 从哪来?常见的声子晶体梁模型里,有一种是双梁夹层结构:上梁、下梁各占一个 Timoshenko 梁,中间是弹性连接层。上下梁之间靠分布式刚度互相牵扯,位移差直接产生内力,无法分别独立求解。这时把上梁的六个状态量和下梁的六个状态量合并成一个 12 维状态向量,层间耦合就变成 A 矩阵里的线性刚度项,整个单胞的传递矩阵自然就是 12×12。这套模型能同时覆盖“上下梁材料不同”“中间层刚度可变”“层间转动耦合”这些实际设计变量,比单独的周期散射体模型更贴近夹层声子晶体梁的实物。

2.3 12个状态量的落位:轴向、横向、转角与内力的配对

我习惯把 12 个状态量按固定顺序排布,方便后面写矩阵时不出错。状态向量 y 依次是:上梁的轴向位移 u1、横向位移 w1、截面转角 ψ1、轴力 N1、剪力 Q1、弯矩 M1,然后下梁的轴向位移 u2、横向位移 w2、截面转角 ψ2、轴力 N2、剪力 Q2、弯矩 M2。传递矩阵 T 的作用是 y_right = T × y_left,把单胞左端面的 12 个分量映射到右端面。

这样排布有一个直接好处:上下梁之间的耦合项可以写成非常干净的刚度矩阵叠加。中间弹性层的纵向刚度 k_lon 连接 u1 和 u2,剪切刚度 k_sh 连接 w1 和 w2,转动刚度 k_rot 连接 ψ1 和 ψ2。这些耦合项加到 A 矩阵的对应行列里,整个系统就是一个标准的 12 阶常微分方程组。你不需要去记忆复杂的四阶微分方程通解,只需要在每个短梁段内求解这个状态方程的传递矩阵,再把所有段乘起来,就能得到任意长度和任意层间刚度的单胞传递矩阵。这也是我推荐用状态空间数值格式的原因:公式推导一次到位,后面改参数只改矩阵系数,不碰算法骨架。

3. 把12×12传递矩阵搭起来:数值状态空间格式与可运行脚本

3.1 分段积分求场矩阵:expm是黑匣子但很好用

直接解析推导 Timoshenko 双梁系统的 12×12 传递矩阵不是不行,通解表达式会很长,而且层间刚度一加进去,符号推导就爆炸。工程上更常见的做法是先把控制方程写成状态空间形式 dy/dx = A(x) y,然后把梁段切成若干小段,每段内假设材料参数和耦合刚度保持不变,用矩阵指数 expm(A × ds) 得到这一段的状态转移矩阵。把所有小段的转移矩阵按顺序乘起来,就是整个单胞的 12×12 传递矩阵。

矩阵指数这个概念对很多人来说是黑匣子,但实际用起来很稳。你只要保证 A 矩阵拼得对,分段数足够,expm 的结果就是这段微分方程组的精确积分。相比龙格库塔逐步积分,expm 不累积局部截断误差,且每段的计算量只跟矩阵规模有关。12×12 的矩阵指数在 scipy 里一秒钟能算几千个频率点,扫频根本不用担心性能。

3.2 最小Python实现:从材料参数到单胞矩阵

下面这段脚本是我在工程复现中最常用的骨架,它包含三个部分:构造单层 Timoshenko 梁的状态矩阵、拼出带层间耦合的 12×12 矩阵、积分得到单胞传递矩阵。代码不依赖任何自编公式,全部由物理方程直接推导。

import numpy as np from scipy.linalg import expm, eig def single_layer_A(omega, E, G, rho, A, I, kappa): """单层 Timoshenko 梁的状态矩阵,状态顺序为 u, w, psi, N, Q, M。""" A_mat = np.zeros((6, 6), dtype=float) # du/dx = N / EA A_mat[0, 3] = 1.0 / (E * A) # dw/dx = psi + Q / (kappa G A) A_mat[1, 2] = 1.0 A_mat[1, 4] = 1.0 / (kappa * G * A) # dpsi/dx = M / EI A_mat[2, 5] = 1.0 / (E * I) # dN/dx = -rho A omega^2 u A_mat[3, 0] = -rho * A * omega**2 # dQ/dx = -rho A omega^2 w A_mat[4, 1] = -rho * A * omega**2 # dM/dx = Q + rho I omega^2 psi A_mat[5, 2] = rho * I * omega**2 A_mat[5, 4] = 1.0 return A_mat def cell_matrix_12x12(omega, params, nseg=8): """ 双梁夹层单胞的 12x12 传递矩阵。 params 中包含上下梁材料/截面参数和中间层刚度 k_lon, k_sh, k_rot。 """ p = params L_cell = p["L_cell"] ds = L_cell / nseg A_up = single_layer_A( omega, p["E_up"], p["G_up"], p["rho_up"], p["A_up"], p["I_up"], p["kappa_up"] ) A_dn = single_layer_A( omega, p["E_dn"], p["G_dn"], p["rho_dn"], p["A_dn"], p["I_dn"], p["kappa_dn"] ) A12 = np.zeros((12, 12), dtype=float) A12[:6, :6] = A_up A12[6:, 6:] = A_dn # 中间层纵向刚度:N1 与 N2 方程中的耦合项 k_lon = p["k_lon"] A12[3, 6] += k_lon # dN1/dx 受 u2 影响 A12[3, 0] -= k_lon A12[9, 0] += k_lon # dN2/dx 受 u1 影响 A12[9, 6] -= k_lon # 中间层剪切刚度:Q1 与 Q2 方程中的耦合项 k_sh = p["k_sh"] A12[4, 7] += k_sh A12[4, 1] -= k_sh A12[10, 1] += k_sh A12[10, 7] -= k_sh # 中间层转动刚度:M1 与 M2 方程中的耦合项 k_rot = p["k_rot"] A12[5, 8] += k_rot A12[5, 2] -= k_rot A12[11, 2] += k_rot A12[11, 8] -= k_rot # 分段积分,按顺序乘起来得到单胞矩阵 T_cell = np.eye(12) U = expm(A12 * ds) for _ in range(nseg): T_cell = U @ T_cell return T_cell

这段代码的逻辑很直白:先拼出单层状态矩阵,再通过索引把上下梁的状态矩阵塞进 12×12 的大矩阵,第三部分把层间耦合刚度加到对应行列。耦合项的正负号需要特别留意:对上述状态向量的定义,N1 方程里出现的是 k_lon 乘以 (u2 - u1),所以对应 A12[3, 6] 加正号、A12[3, 0] 减正号;下梁 N2 方程正好相反。剪切刚度和转动刚度同理,按位移差的方向确定符号。如果符号颠倒了,算出来的单胞矩阵就不再是无阻尼保守系统,特征值的倒数对称性会被破坏,后期排查会非常痛苦。

参数说明上,nseg 控制分段数,最小可以取 4,我一般取 8 到 16,这个值直接影响高频段的收敛性。omega 的扫频步长决定带隙边界的分辨率,建议先粗扫认形态,再在带隙边界附近加密。中间层刚度的量级不要拍脑袋,先按弹性模量除以厚度估算,再扫一个数量级范围看带隙变化趋势。

3.3 扫频判带隙:特征值模长与色散曲线的读法

拿到单胞矩阵 T_cell 之后,带隙计算实际是求解 Bloch 特征值问题。周期结构的传播条件要求单胞两端的状态向量满足 Bloch 关系 y_right = λ y_left,其中 λ = exp(i k L_cell)。于是问题变成求 T_cell 的特征值,看它们是否落在单位圆上。完全无阻尼的情况下,如果某个频率点所有特征值模长都等于 1,这个频段是通带,弯曲波能传播;只要存在模长明显偏离 1 的特征值,对应频段就是带隙,波衰减的程度由 |λ| 的对数决定。

我一般在程序里直接扫频,把每个频率点的最大特征值模长取出来画一条曲线,逻辑如下:

def scan_gaps(omega_list, params, nseg=8): """返回每个频率点对应的最大特征值模长""" max_abs = [] for w in omega_list: T = cell_matrix_12x12(w, params, nseg=nseg) evs = eig(T)[0] max_abs.append(np.max(np.abs(evs))) return np.array(max_abs)

这条曲线在带隙区间会明显凸起,因为特征值成对出现且互为倒数,当最大模长大于 1 时,必然存在小于 1 的配对值,波呈指数衰减。画色散曲线则要更细一步:对每个频率点取出特征值相位实部和模长虚部,把实波数画在一边,把衰减常数画在另一边。我常用的约定是:横轴频率,左纵轴实波数 Re(k),右纵轴衰减常数 Im(k),带隙在右半图表现为衰减常数从零跳升的区间。

用这个判据时要设一个容差,不然数值噪声会让你把通带误判成带隙。我习惯把容差设成 0.05 到 0.1:最大特征值模长大于 1.05 或小于 0.95 才认为是带隙。如果扫频步长很粗,带隙边界会平移到假位置,所以定位带隙边界时要把步长加密到赫兹量级。

3.4 试算参数表:先复现,再改造

下面是铝-橡胶双梁夹层结构的一组常见参数,适合做第一个跑通案例。铝层做上下梁,橡胶层做中间连接。这个组合的好处是材料参数大家都很熟,且阻抗差异足够大,带隙明显,跑完和文献趋势能对上。

参数上梁(铝)下梁(铝)说明
弹性模量 E70 GPa70 GPa各向同性
剪切模量 G26.9 GPa26.9 GPa铝典型值
密度 ρ2730 kg/m³2730 kg/m³密度差异不大没关系
截面高×宽4 mm × 20 mm4 mm × 20 mm高宽比接近 0.2
截面形状系数 κ5/65/6矩形截面
惯性矩 I1.07e-10 m⁴1.07e-10 m⁴矩形截面公式
单胞长度 L_cell0.1 m0.1 m决定第一带隙频率量级

中间层的纵向刚度 k_lon 先按 1e7 N/m² 起步,剪切刚度 k_sh 按橡胶剪切模量除以厚度估算,转动刚度 k_rot 在初始阶段直接设 0,等模型跑通再加。频率扫描范围建议从 100 Hz 扫到 5000 Hz,第一带隙通常出现在几百赫兹到两千赫兹之间。如果带隙位置和你预想差太远,优先检查单胞长度和截面尺寸,而不是去调材料参数。

4. 常见问题排查:矩阵奇异、假带隙、耦合刚度玄学

4.1 现象一:算出来的带隙中心和实验差一截

把结果拿去和实验对比时差出百分之二三十,这是最常见的翻车现场。原因多半不是你程序写错了,而是梁模型选得不对或者参数没对上。Euler-Bernoulli 梁在弯曲波波长较短时会高估相速度,带隙中心频率整体偏高。还有一种情况是实验件的高宽比和模型不一致,截面形状系数 κ 给错,比如矩形截面应该用 5/6,结果有人按圆形截面给成 0.9,剪切柔度偏小,带隙也会飘。

解决的办法分两步。第一步,把模型的参数表和实验件的几何参数逐项核对,特别是截面高度、宽度和单胞长度,这三个量直接决定惯性矩和单胞周期。第二步,做一个模型切换测试:把剪切变形和转动惯量项全部设成极小值,对比 Euler-Bernoulli 和 Timoshenko 的带隙边界,如果差异超过 5%,就说明你的工作频段已经进入必须用 Timoshenko 模型的区间,不要再去迁就简化模型。

4.2 现象二:通带里出现假禁带

扫频曲线在某个通带频率出现一根突兀的尖峰,看起来像带隙,但用有限周期模型算透射率时这个频段却没有衰减,这就是假禁带。假禁带通常来自特征值排序跳变。特征值是复数,它们在复平面上随着频率移动,到某一点时两条特征值曲线交叉,程序按模长排序后会把不同枝的特征值混在一起,导致模长突变。

解决办法是不要只看单个特征值,而是看整组特征值的对称性。无阻尼系统里特征值成对互为倒数,如果某一枝跳变破坏了这种对称性,基本可以断定是排序问题。我在扫频循环里会做一步连续性追踪:对当前频率点的特征向量和上一频率点的特征向量做内积匹配,内积最大的才认为是同一枝,这样能有效避免排序跳变。更省事的方案是直接用最大特征值模长判断带隙,因为成对对称性保证最大模长在通带里恒为 1,假跳变会被容差过滤掉。

4.3 现象三:矩阵乘法越乘越不收敛

分段数从 8 加到 16,带隙边界不收敛,甚至单胞矩阵的数值奇异,这时候问题出在状态矩阵的动态范围上。Timoshenko 梁状态向量里包含内力和位移,量纲差了好几个数量级,位移大概是毫米级,内力是千牛级,两者乘在一起后矩阵条件数很容易爆炸。尤其在高频段,A12 矩阵的特征值虚部很大,expm 的结果会很强地放大微小数值误差。

解决思路是给状态向量做量纲归一化。我习惯在拼 A12 之前把力分量除一个参考力 F_ref,把弯矩除一个参考弯矩 M_ref,位移和转角保持不变,矩阵变为无量纲形式。这样 expm 的动态范围小很多,分段数加到 32 之后结果依然稳定。也可以反过来,把位移分量乘一个大数,但不如归一化力分量直观。即使不打算改代码骨架,至少要做分段收敛性检验:nseg 从 4 到 32,带隙边界变化小于 2% 才算收敛。

4.4 现象四:中间层刚度扫不出带隙

耦合刚度 k_sh、k_lon 设了一大堆值,带隙纹丝不动。这个现象很常见,尤其是把 k_lon 设得超大时,上下梁被完全锁成一体,系统退化成一根厚梁,带隙只能靠布拉格散射产生。反过来,k_sh 设得太小,上下梁几乎独立,夹层梁退化成两根孤立梁,带隙主要来自单根梁自身的长度周期,和你要设计的夹层带隙不是一回事。

处理这类问题的核心是先扫刚度-频率二维图:横轴频率、纵轴 k_sh 的对数值,用颜色画最大特征值模长。这样你能一眼看出带隙从哪里冒出来、刚度在哪个量级范围内有效。我一般在 1e6 到 1e10 内按对数取 20 个点扫描,看带隙是否连续移动。如果整个二维图里都没有明显的高衰减区,再回头检查 A12 耦合项的符号,尤其是转动刚度 k_rot,它经常因为正负号反了而把带隙直接抹掉。

5. 验证与进阶:用透射率校核带隙,把单胞矩阵当积木

5.1 有限周期透射率的计算是做实验前最该补的一步。单胞矩阵求出的色散带隙是无限周期结构的性质,实验件只有有限周期,结果会因为端部反射和近场效应产生偏差。把 N 个单胞矩阵按顺序连乘,得到总传递矩阵 T_total = T_cell^N,然后在一端施加力和位移边界条件,另一端提取响应位移,位移比就是透射率。代码实现里我通常只用两块:一段连乘循环,一段线性方程求解。边界条件建议两端都用自由边界,左边给单位剪力,右边提取横向位移,虽然和实验夹持方式不完全一致,但作为带隙验证已经足够。

5.2 与 FEM 或实验对齐时,我按下面三个可执行校验来验收。第一,检查单胞矩阵特征值成对倒数对称性,误差超过 1% 说明代码里有符号或参数错误。第二,做分段收敛检验,带隙边界随 nseg 变化的漂移量控制在 2% 以内;这个检验同时也是判断 Timoshenko 梁模型是否必要的手段。第三,对比有限周期透射率的陷波频率和无限周期带隙边界,两者偏差通常不应超过一个扫频步长;如果偏差变大,优先怀疑中间层刚度参数估算不准。

最后讲一个我自己的习惯。每次新建一个声子晶体梁项目,我都会把材料参数、截面尺寸、单胞长度、扫频范围和分段数存成一个配置字典,每个算例只改配置,不改算法。这样做的好处是复现快,换材料、换截面只需要一次扫描就能看到全部带隙变化,不用在代码里翻来翻去。之前有一次我把上梁和下梁的惯性矩写反了,结果带隙中心偏了一个数量级,查了半天才在配置里发现低级笔误。那之后我每次跑完都顺手把矩阵无量纲化、把特征值对称性打印出来看一眼,能省下大量排错时间。这套 12×12 传递矩阵方法本身不难,难的是把每个环节都做得有据可查。希望帮到你。

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

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

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

立即咨询