ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Kraken简正波仿真:传播损耗与阵元波形从原理到Matlab实现

Kraken简正波仿真:传播损耗与阵元波形从原理到Matlab实现

简介:该资源面向水声通信、海洋声学方向的研究人员与工程技术人员,提供基于Matlab的Kraken水声传播损耗计算与阵列接收波形分析工具,可用于声纳系统设计评估、水平阵与垂直阵接收性能分析等场景,适合具备一定水声基础的中高级学习者。压缩包共19个文件,约713KB,以12张jpg结果图、3个m脚本、1个mat数据文件为主,辅以docx公式说明、png任务流程图和md使用文档,涵盖传播损耗曲线、声场分布、阵元波形等可视化输出与可运行代码。已有1109人学习下载。读者可据此获得从环境参数输入到传播损耗计算、阵列因子与方向图模拟的完整流程,结合脚本注释理解算法逻辑,并通过结果图直观对照不同条件下的声传播差异,为自定义扩展与阵列配置优化提供参考。

1. 从一条“对不上”的波形说起:Kraken 到底在算什么

很多人第一次用 Kraken 做水声传播仿真,都会撞上一个反直觉的现象:明明声源级设得没问题,接收阵元画出来的波形却幅度忽大忽小,相位还跟理论上的球面扩展对不上。有人怀疑是网格太粗,有人怀疑是边界条件写错,折腾半天才发现——问题出在“传播损耗”和“阵元波形”这两件事本来就不是同一个物理量,却被当成一回事去校验。Kraken 作为简正波(normal mode)求解器,它输出的不是一条简单的衰减曲线,而是一整套模态叠加的场解;传播损耗是场强随距离的包络,阵元波形是各阶模态在接收点相干叠加后的时域结果。搞懂这两者怎么从同一个本征值问题里长出来,你才能解释那些“玄学”般的幅度跳变,也才能在 Matlab 里把 Kraken 的输出接对、用对。这篇就拆这条链路:从简正波方程到模态系数,再到传播损耗曲线和阵元时域波形,一层层落到实现细节。

2. 简正波求解器:Kraken 为什么先解本征值再谈传播

2.1 从波动方程到本征值问题:模态是怎么被“逼”出来的

水声传播在柱对称假设下,声压场可以写成距离和深度的分离形式。把简谐点源的波动方程做分离变量,深度方向会得到一个标准的 Sturm-Liouville 型本征值问题:算子作用在模态函数上等于本征值乘以模态函数,本征值的平方根就是水平波数。Kraken 的核心工作就是数值求解这个本征值问题,得到一组离散模态和对应的水平波数。这一步决定了后面所有东西——传播损耗的衰减斜率、阵元波形的干涉条纹,全部由这组本征值撑起来。

常见的实现思路是用有限差分把深度方向离散成网格,把微分算子变成三对角或带状矩阵,再用移位反幂法迭代求本征值和本征向量。Kraken 的输入文件里那些网格点数、深度范围、边界条件参数,本质上都是在描述这个离散化。网格太粗,高阶模态的本征值会偏,衰减算出来就不对;网格太细,计算量上去但精度未必线性提升。我一般会这么理解:这一步是在给整个场“定调”,调定歪了,后面波形怎么调都是错的。

2.2 模态系数:声源和边界条件如何决定“谁被激发”

解出本征值和模态函数只是拿到了一套“基”,真正决定每个模态被激发多少的是模态系数。它由声源深度处的模态函数值、声源强度以及归一化条件共同决定。换句话说,同样的海洋环境,声源放浅一点或深一点,激发的模态组合就不同,传播损耗曲线的形状会跟着变。这也是为什么有人换个声源深度就发现损耗曲线“翻车”——不是求解器坏了,是模态系数重新分配了。

在 Matlab 里对接 Kraken 输出时,模态系数通常需要从输出文件里读出来再和模态函数做加权。这里有个容易忽略的点:归一化方式不同,系数的量纲就不同,直接拿去算损耗会差一个常数因子。常见的做法是确认输出文件里的归一化约定,再统一到同一套单位下,否则后面阵元波形的绝对幅度永远对不上。

2.3 水平波数:传播损耗曲线的“斜率”从哪来

水平波数是本征值的平方根,它的实部决定相位随距离的变化,虚部决定衰减。传播损耗随距离的包络,本质上就是各阶模态按水平波数虚部衰减、再相干叠加的结果。近距离时高阶模态贡献大,损耗曲线可能有起伏;远距离高阶模态衰减殆尽,只剩低阶模态主导,曲线趋于平滑。这就是为什么传播损耗曲线不是一条单调直线,而是分段有“拐点”的。

理解这一点,你在 Matlab 里画损耗曲线时就不会盲目拟合一条指数衰减。正确的做法是按模态逐阶算贡献,再叠加,而不是拿总场直接套一个球面扩展公式。下面这段伪代码展示了从本征值到损耗的基本链路:

% 假设已从 Kraken 输出读入:k(水平波数,复数)、phi(模态函数,深度×模态)、coef(模态系数) r = 100:100:10000; % 距离向量,单位米 loss = zeros(size(r)); for i = 1:length(r) % 逐阶模态叠加:exp(1i*k*r) 含相位与衰减,1/sqrt(k*r) 是柱面扩展因子 field = sum(coef .* phi(recv_depth_idx, :) .* ... exp(1i * k * r(i)) ./ sqrt(k * r(i))); loss(i) = -20 * log10(abs(field)); % 传播损耗,单位 dB end

这段代码里k的虚部直接控制衰减速度,coef和phi的乘积决定每个模态的权重,1/sqrt(k*r)是柱面扩展的几何因子。参数recv_depth_idx是接收深度在网格上的索引,取错深度,波形和损耗都会偏。实际使用时还要注意k的符号约定,不同版本输出可能差一个共轭,导致相位反向。

3. 传播损耗:为什么曲线会“分段”而不是一条直线

3.1 模态衰减与干涉:损耗曲线的两种成因

传播损耗曲线上的起伏,来源有两个:一是模态自身的指数衰减,二是模态之间的干涉。近距离段,多个模态的相位差随距离变化,叠加后幅度出现周期性起伏,这就是所谓的干涉条纹;远距离段,高阶模态衰减掉,只剩少数低阶模态,干涉减弱,曲线变得平滑。把这两种成因混在一起看,就会觉得曲线“不规律”;分开看,每一段都能对应到具体的模态行为。

在 Matlab 里验证这一点,可以逐阶画单模态的损耗曲线,再画叠加后的总曲线,对比起伏出现的位置是否和模态相位差的变化周期吻合。这个对比做一次,比看十页公式都直观。

3.2 柱面扩展与球面扩展:损耗公式里的几何因子

很多人习惯用球面扩展的 20log10(r) 去套水声传播,但简正波在柱对称假设下,几何扩展是柱面性质的,表现为 1/sqrt(r),对应 10log10(r) 的衰减斜率。这就是为什么直接用球面扩展公式去校验 Kraken 结果会对不上——几何因子选错了。实际海洋中还有吸收、海底衰减等额外损失,这些体现在水平波数的虚部里,而不是单独加一个经验项。

常见的实现思路是把几何扩展和介质吸收分开处理:几何部分由 1/sqrt(k*r) 承担,吸收部分由 k 的虚部承担。两者叠加才是完整的传播损耗。如果你的 Matlab 脚本里只写了 20log10(r) 而没处理 k 的虚部,远距离损耗会明显偏小,波形幅度也会偏大。

3.3 从频域到损耗曲线:单频与宽带的差别

Kraken 一次求解对应一个频率。传播损耗曲线如果是单频的,直接按上面的链路算即可;如果是宽带,需要对每个频点分别求解再合成,或者用宽带简正波方法。这里容易踩的坑是:拿单频结果去代表宽带,损耗曲线的频率依赖被抹掉,阵元波形也会丢失色散特征。水声信道的色散正是来自不同频率的模态群速度不同,单频求解根本体现不出来。

所以在 Matlab 里做宽带仿真时,频率循环是绕不开的。每个频点解一次本征值,得到该频点的模态和波数,再在时域合成。计算量上去了,但这是拿到真实波形的必要代价。

4. 阵元接收波形:模态叠加怎么变成时域信号

4.1 频域场到时间序列:逆傅里叶变换的那一步

阵元接收波形本质上是把频域场解做逆傅里叶变换。每个频点得到的是该频率下的复声压,乘以源谱后对所有频点做 IFFT,才得到时域波形。这一步里,源谱的形状直接决定波形的包络和持续时间;源谱设成窄带,波形就长而平滑;设成宽带,波形就短而尖锐。很多人波形画出来“不像”,问题往往出在源谱没设对,而不是传播计算错了。

在 Matlab 里,频域场通常存成一个频率×深度的矩阵,IFFT 沿频率维做。注意频率采样间隔要满足时域不混叠,否则波形会出现周期性重复,看起来像“回声”,其实是采样问题。

4.2 模态群速度与时域到达结构

不同模态的群速度不同,它们在时域上到达接收点的时间就不同,这就是多途结构的来源。阵元波形上看到的多个“包”,往往对应不同模态或同一模态的不同群速度分支。把每个模态单独做 IFFT,再在时域上标出到达时间,就能和群速度曲线对上。这个验证做一次,你对波形的理解会从“一条曲线”变成“一组有物理意义的到达”。

群速度由水平波数对频率的导数决定,数值上可以用相邻频点的波数差来近似。差分步长选得太大,群速度会偏;选得太小,数值噪声会放大。常见的做法是取适中的频率间隔,再对结果做平滑。

4.3 阵元位置与幅度加权:为什么换个阵元波形就变

接收阵元在深度方向上的位置不同,模态函数在该深度的取值就不同,各模态的权重随之改变,波形自然不同。这就是为什么同一个传播环境,不同阵元的波形幅度和干涉条纹会有差异。阵元靠近模态函数的节点时,该模态贡献接近零,波形上对应的成分就消失。

在 Matlab 里做阵元波形对比时,建议固定源和频率,只改接收深度索引,逐点画出来。这样能直观看到模态函数零点对波形的影响,也能帮你判断某个阵元波形“异常”到底是传播问题还是位置选在了节点附近。

5. 避坑与排查:Kraken 对接 Matlab 时最容易翻车的几处

5.1 现象:损耗曲线整体偏移一个常数;原因:归一化约定不一致;解决:统一量纲后再比较

这是最常见的翻车点。Kraken 输出文件的归一化方式和你在 Matlab 里假设的不一致,损耗曲线就会整体平移,形状对但绝对值错。排查方法是先算一个已知解析解的简单环境,对比绝对幅度,确认归一化因子后再套到复杂环境。不要一上来就拿实测数据拟合,先把量纲对齐。

5.2 现象:阵元波形出现周期性重复;原因:频率采样间隔过大导致时域混叠;解决:加密频率采样或加窗

波形上出现不该有的“回声”,先查频率采样。频率间隔对应的时域周期如果小于你关心的信号长度,就会混叠。解决方法是减小频率间隔,或者在 IFFT 前对频域数据加窗抑制截断效应。这个坑在宽带仿真里尤其常见,因为频率点多了容易图省事跳着取。

5.3 现象:远距离损耗偏小;原因:只用了几何扩展,漏了波数虚部的吸收;解决:确认 k 为复数并正确参与衰减

如果 Matlab 脚本里把水平波数当成实数处理,衰减就只剩几何扩展,远距离损耗会明显偏小。检查方法是看 k 的虚部是否非零,以及在 exp(1ikr) 里是否保留了虚部。有些读取脚本为了省事只取实部,这就是血泪经验的来源。

5.4 现象:高阶模态贡献异常大;原因:网格太粗导致本征值求解偏差;解决:加密网格并检查收敛性

网格分辨率不够时,高阶模态的本征值误差大,衰减算不准,波形上高阶成分会异常突出。排查方法是做网格收敛测试:网格加密一倍,看损耗曲线和波形是否稳定。如果不稳定,说明还没收敛,继续加密或调整边界条件。

5.5 现象:波形相位与理论反向;原因:波数符号或傅里叶变换约定不一致;解决:统一正负号约定并做单模态验证

相位反向往往来自 exp 的符号约定或 IFFT 的方向。不同工具对正频率的定义可能差一个共轭。排查方法是取单模态、单频点,手算相位随距离的变化,和脚本输出对比。确认约定后,在全流程里统一,不要中途换约定。

6. 设计取舍:为什么简正波方法值得你花时间抠细节

简正波方法的核心取舍在于:它把三维传播问题降成了本征值问题加模态叠加,计算效率高、物理图像清晰,但前提是环境近似柱对称、水平变化不剧烈。如果你的场景是深海近场或强水平变化,简正波假设会失效,这时候耦合模态或抛物方程方法更合适。Kraken 的价值不在于它是万能解,而在于它把“模态”这个中间层暴露给你,让你能逐阶检查、逐阶验证。这种可解释性是很多黑箱求解器给不了的。

在 Matlab 里对接 Kraken,真正花时间的不是写循环,而是把归一化、符号约定、几何因子这几件事对齐。对齐之后,传播损耗和阵元波形就是同一套模态数据的两种视图,改一个参数两边都能解释。我自己的习惯是:每次换环境或换频段,先跑一个单模态、单频点的最小案例,确认幅度和相位都对得上,再放开到全模态、宽带。这个习惯帮我省掉了大量“波形不对但不知道从哪查”的时间。从那以后我每次接新的传播输出,都强制走一遍单模态验证,再谈叠加。希望帮到你。

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

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进