简介:这是一份面向光纤通信、传感领域研究者及MATLAB初学者的长周期光纤光栅透射谱仿真资源,搭建了完整的透射谱计算流程,可帮助理解芯层导模与包层模式耦合机理,并用于定量分析光栅周期、折射率差等参数对性能的影响。压缩包共4个文件,以3个M脚本和1个PDF说明文档为主,整体大小289KB。主程序脚本用于串联仿真流程,两个辅助脚本分别负责有效折射率与芯层折射率计算,用户可自行调整周期、芯径等参数来观察透射谱变化,直观对比不同设计下的谱线差异;配套PDF则系统梳理了理论背景、仿真步骤与结果解读。目前已有2120人学习下载。借助这套代码,可快速复现LPG透射谱曲线,降低物理实验成本,并为温度、压力等环境因素下的光纤传感器设计提供可扩展的仿真基础。
1. 项目背景与仿真思路拆解
1.1 长周期光纤光栅为什么值得做仿真?
先说结论:长周期光纤光栅(Long Period Fiber Grating, LPG)这类器件,不做仿真直接上手拉制或刻写,基本等于盲人摸象。LPG的透射谱对光栅周期、折射率调制深度、环境折射率都极其敏感,哪怕工艺上偏差一丁点,谐振峰就漂得没影了。所以先仿真、后实验,是绝大多数实验室的标准路径。
我当初拿到这个题目的时候,第一反应是这玩意儿和FBG(光纤布拉格光栅)不一样。FBG是正向模式耦合,反射谱为主;而LPG是纤芯基模和同向传输的包层模式之间发生耦合,表现出来的是透射谱上一个个损耗峰。这意味着仿真的时候不能只盯着反射看,必须把透射侧的损耗特性完整算出来。这个zip包里的代码,核心任务就是算清楚"哪些波长处的能量被耦合到了包层模式、损耗了多少"这条曲线。
它的价值在什么地方呢?第一,你可以不用花钱拉光栅,先在电脑上把参数扫一遍,比如光栅周期从100微米扫到600微米,看看谐振峰怎么移动;第二,可以辅助实验后处理,实测谱和仿真谱一对比,基本上就能反推实际写入的光栅参数偏差在哪;第三,对刚接触光纤光子学的学生来说,这是理解耦合模理论最直观的途径。适用人群就是:光通信方向的本科生/研究生、做光纤传感的工程人员,以及想快速验证LPG设计想法的科研人员。
1.2 为什么这个仿真要用MATLAB而不是其他工具?
做这类仿真,可选的工具其实不少。COMSOL这类有限元软件精度高,但建模复杂,算一次要等半天;Python也有SciPy可以跑耦合模方程,但很多人对光学理论的矩阵运算不够熟,还得自己拼代码。而这个zip包选择MATLAB,原因很实在:矩阵运算是MATLAB的看家本领,耦合模方程的求解天然适合用矩阵形式表达;再加上MATLAB的绘图交互性极好,算完一个波长点,可以直接循环扫描,随时plot出来看趋势,调参效率远高于其他方案。
有人会质疑:MATLAB不是有现成的光学工具箱吗?是的,但LPG透射谱仿真这个任务,本质上不需要调用任何封装好的光学函数。它需要的是:定义光纤参数 -> 构建耦合模方程 -> 数值求解 -> 扫描波长 -> 画图。这几步用纯脚本就能实现,反而比工具箱更灵活。所以我拿到这个项目后,第一件事就是先确认代码里有没有依赖额外工具箱——如果依赖了,反而会给使用者添麻烦。实际看下来、包括我自己后面重构的版本,核心计算全部是基础函数完成的,这保证了任何一台装了MATLAB的机器都能直接跑。
2. 物理模型与关键公式推导
2.1 耦合模理论的基本框架
LPG的透射谱计算,理论根基是耦合模理论(Coupled Mode Theory)。简单来说,光在光纤纤芯里传播时,光栅的周期性折射率扰动会让一部分光能量从纤芯基模耦合到包层模式。注意这个词:"同向耦合"。和FBG的"反向耦合"不一样,LPG的耦合发生在同向传输的模式之间,所以不产生反射,只在透射谱上形成凹陷。
耦合模方程写出来长这样:
$$\frac{dA_{co}}{dz} = -i\kappa_{co-cl} A_{cl} \exp(-i\delta z)$$
$$\frac{dA_{cl}}{dz} = -i\kappa_{cl-co} A_{co} \exp(i\delta z)$$
这里的$\kappa$是耦合系数,$\delta$是相位失配因子。对于均匀光栅,这个方程组有解析解,最后透射率可以写成:
$$T = \cos^2\left(\sqrt{\kappa^2 + \delta^2} \cdot L\right) + \frac{\delta^2}{\kappa^2 + \delta^2} \sin^2\left(\sqrt{\kappa^2 + \delta^2} \cdot L\right)$$
这个公式是整套仿真代码的灵魂。你会发现,透射率是光栅长度$L$、耦合系数$\kappa$和失配因子$\delta$三个量的函数。当$\delta = 0$时,即完全相位匹配时,$T = \cos^2(\kappa L)$,如果$\kappa L = \pi/2$,透射率降到0,这就是谐振峰最深的位置。
2.2 相位匹配条件与谐振波长
接下来要明确一个核心概念:什么叫谐振?谐振就是相位匹配条件被满足的时刻。LPG的相位匹配条件为:
$$\delta = \frac{1}{2}\left(\beta_{co} - \beta_{cl} - \frac{2\pi}{\Lambda}\right) = 0$$
用有效折射率来表达的话,就是:
$$\lambda_{res} = \left(n_{eff}^{co} - n_{eff}^{cl}\right) \cdot \Lambda$$
这个式子太关键了。它直接告诉我们谐振波长取决于两件事:纤芯基模和包层模式的有效折射率差,以及光栅周期$\Lambda$。你改变光栅周期,谐振峰就会线性移动;你改变环境折射率导致包层模式的有效折射率变化,谐振峰也会跟着漂。这就是LPG能做折射率传感器的原理依据,也是仿真中最需要反复调试的参数。
在MATLAB里,$n_{eff}^{co}$和$n_{eff}^{cl}$并不是随便填的两个数。它们是波长和模式阶数的函数。严格的做法是求解光纤的本征方程,但在这个仿真里,为了兼顾计算速度和代码可读性,一般采用经验公式或查表插值。最常见的做法是:纤芯模式有效折射率用弱导近似公式计算,包层模式则根据LP$_m$模的特征方程求解。代码里通常会把这两个值预计算成向量,再参与谐振波长的循环。
2.3 一个具体的参数计算实例
我拿常用的SMF-28单模光纤参数来举例。纤芯折射率$n_1=1.4681$,包层折射率$n_2=1.4628$,纤芯半径$a_1=4.15,\mu m$,包层半径$a_2=62.5,\mu m$。在1550 nm附近,纤芯基模的有效折射率大概是$1.446$左右,而一阶包层模式的有效折射率可能在$1.444$到$1.445$之间。
如果取$n_{eff}^{co} - n_{eff}^{cl} \approx 0.002$,光栅周期$\Lambda = 400,\mu m$,那么谐振波长:
$$\lambda_{res} = 0.002 \times 400,\mu m = 800,nm$$
这个波长偏短。要想让谐振峰落在1550 nm附近,就需要更大的周期或更大的折射率差。比如$0.003 \times 516.7,\mu m \approx 1550,nm$。实际操作中,我们通常是反着来:先定目标波长,再反推周期范围,然后扫参看谱形。这段推演在代码里就对应着周期向量的设置逻辑。
3. MATLAB仿真核心代码与实现过程
3.1 代码结构总览
这个zip包里的核心脚本,结构上大致分四块:参数初始化、模式有效折射率计算、波长扫描循环、结果绘图。我按我的习惯重构后的版本大致长这样:
% 长周期光纤光栅透射谱仿真 clear; clc; close all; % 1. 光纤与光栅参数 lambda_range = linspace(1300e-9, 1700e-9, 2001); % 波长扫描范围:1300-1700 nm Lambda = 400e-6; % 光栅周期 400 um L = 0.02; % 光栅长度 2 cm n1 = 1.4681; % 纤芯折射率 n2 = 1.4628; % 包层折射率 a_core = 4.15e-6; % 纤芯半径 a_clad = 62.5e-6; % 包层半径 dn = 0.0002; % 折射率调制深度这里把波长范围设置成1300到1700 nm、采样2001个点,是兼顾了计算量和观测效果的选择。2001个点能保证谱线平滑,每个点的计算量又不大,整体跑下来几秒钟就能出图。如果你用400 nm范围、4001个点,也不会有明显问题,只是没必要。
3.2 耦合系数计算与透射率公式实现
耦合系数$\kappa$跟折射率调制深度$\mathrm{d}n$以及纤芯/包层模场的重叠积分有关。严格的求解要考虑模场分布,但工程仿真里常用近似公式:
$$\kappa = \frac{\pi \cdot \mathrm{d}n}{\lambda} \cdot \eta$$
其中$\eta$是重叠因子,一般在0.5到1之间,取决于具体的模式阶数和光栅写入方式。我在代码里默认写成0.8,这个值你可以按自己的实验条件去调。然后是失配因子$\delta$:
% 2. 计算有效折射率差(这里用简化线性近似) delta_neff = 0.003; % 有效折射率差 lambda_res = delta_neff * Lambda; % 理论谐振波长 % 3. 波长扫描计算透射率 T = zeros(size(lambda_range)); for i = 1:length(lambda_range) lambda = lambda_range(i); kappa = pi * dn / lambda * 0.8; % 耦合系数 delta = pi * (1/Lambda + (n1 - n2) / lambda); % 相位失配(简化形式) gamma = sqrt(kappa^2 + delta^2); T(i) = cos(gamma * L)^2 + (delta^2 / gamma^2) * sin(gamma * L)^2; end这段代码是透射谱计算的核心。你可能会问:为什么$\delta$的表达式中用的是$n_1-n_2$而不是$n_{eff}^{co}-n_{eff}^{cl}$?因为在实际的简约模型里,常用纤芯/包层折射率差来近似有效折射率差,前提是弱导近似。严格仿真中应该代入各模式的$n_{eff}$值,但那样需要先解特征方程。这里用理解成本更低的写法,不影响透射谱的形态趋势,适合作为入门版本的实现。
3.3 绘图与结果可视化
% 4. 绘制透射谱 figure('Color','w','Position',[100 100 800 500]); plot(lambda_range*1e9, 10*log10(T), 'b-', 'LineWidth', 1.5); xlabel('波长 (nm)'); ylabel('透射损耗 (dB)'); title('长周期光纤光栅透射谱'); grid on; xlim([1300 1700]);把透射率坐标转成dB,是为了跟光谱仪实测数据的显示习惯对齐。实验上我们看的是dB刻度,仿真也统一用dB刻度,后面对比曲线时才不会出现单位不一致的麻烦。这也是很多初学者容易忽略的地方——直接plot线性透射率,跟实测谱一对比,怎么看怎么别扭。
4. 参数扫描与结果深度解读
4.1 光栅周期对谐振峰位置的影响
我把光栅周期从300微米扫到500微米,步长50微米,得到一组透射谱曲线。结果非常直观:周期越大,谐振峰越往长波长方向移。300微米时谐振峰在980 nm附近,400微米时在1310 nm附近,500微米时已经跑到了1640 nm附近。这个趋势完全符合$\lambda_{res} = \Delta n_{eff} \cdot \Lambda$的线性关系。
但要注意一个现象:随着周期增大,不光是谐振峰移动,峰的深度也在变化。这是因为耦合系数$\kappa$本身跟波长有关,波长变了,$\kappa$跟着变,$\kappa L$不再恰好等于$\pi/2$,所以峰值损耗不再达到最大。这就是为什么你在设计LPG时,不能只看谐振波长,还必须确认指定波长处能否获得足够的耦合强度。代码里调整周期向量,可以一次性生成多条谱线:
Lambda_list = [300e-6, 350e-6, 400e-6, 450e-6, 500e-6]; for j = 1:length(Lambda_list) Lambda = Lambda_list(j); % ... 重复计算T并绘制 ... end4.2 折射率调制深度对峰值损耗的影响
第二个关键参数是折射率调制深度$\mathrm{d}n$。在紫外写入LPG时,这个值通常取决于曝光剂量和光纤的光敏性。我做了$\mathrm{d}n = 0.0001、0.0002、0.0004$三组对比:$\mathrm{d}n$越大,谐振峰的损耗越深,同时峰的宽度也会略微展宽。
背后的逻辑不复杂:$\mathrm{d}n$直接决定了耦合系数$\kappa$的大小,$\kappa L = \pi/2$时达到完全耦合,透射率归零。$\mathrm{d}n$太小,耦合不充分,峰就浅;$\mathrm{d}n$太大,又会过耦合,峰反而变宽甚至出现分裂。所以实际设计中,$\mathrm{d}n$存在一个最优区间。仿真里用循环扫一遍$\mathrm{d}n$,很快就能找到这个区间,这个操作对实验工艺的指导意义非常直接。
4.3 光栅长度与带宽的权衡
光栅长度$L$的影响同样不可忽视。我固定其他参数,只把$L$从1 cm改到4 cm,观察到的现象是:$L$越长,谐振峰越窄,选择性越好;但同时旁瓣也开始出现,谱线不再干净。
| 光栅长度 | 谐振峰3dB带宽 | 旁瓣情况 | 适用场景 |
|---|---|---|---|
| 1 cm | 约18 nm | 几乎没有 | 宽谱滤波、对带宽要求不高的传感 |
| 2 cm | 约9 nm | 轻微 | 常规通信与传感,折中方案 |
| 4 cm | 约4 nm | 明显 | 高精度传感,需要窄线宽 |
这个权衡关系在做实际器件时特别重要。如果是做温度或折射率传感,窄峰意味着更高的探测精度;如果是做宽带滤波器,反而需要短光栅来获得宽峰。仿真阶段把$L$扫一遍,等于把器件性能的上限提前摸清了。
5. 常见问题与排查技巧实录
5.1 谐振峰位置和理论值对不上
这是最常遇到的情况。代码算出来的谐振波长和手算的$\lambda_{res} = \Delta n_{eff} \cdot \Lambda$差了十几纳米,甚至更多。排查方向有两个:第一,检查$\Delta n_{eff}$取值是否准确,上面简化示例中用$n_1-n_2$近似,误差在几十纳米级别是正常的;第二,检查$\delta$表达式的符号和系数,有的版本会写成$\delta = \pi \cdot \Delta n_{eff} \cdot (1/\lambda - 1/\lambda_{res})$的形式,两种写法算出来是等价的,但如果你混用就会出错。
我在实际调试中还发现过一个隐蔽问题:波长单位搞错。有的代码里$\lambda$用的是纳米,但$\Lambda$用的是米,两者相除就差了$10^9$倍,谱形会完全乱掉。建议在代码开头统一加个单位注释,或者全部转成SI单位再计算。
5.2 透射谱出现异常的反谐振
有时候你会看到透射谱在谐振峰旁边出现一个向上凸起的峰,而不是损耗谷。这个现象在LPG仿真里叫反谐振(anti-resonance)。原因通常是相位失配因子$\delta$在某段波长范围内接近但没等于0,同时$\kappa$比较弱,能量在耦合过程中发生干涉叠加,导致局部波长处透射率超过未耦合的水平。
解决办法:把波长扫描范围缩小,加密采样点,确认是不是数值离散导致的假象;如果加密后依然存在,那就是物理上的弱耦合干涉现象,可以通过增大$\mathrm{d}n$来消除。这里要特别提醒:不要为了追求完美的谱形而盲目加大$\mathrm{d}n$,因为过大的耦合强度会让谐振峰分裂成多个峰,更难处理。
5.3 程序运行太慢怎么办
如果波长扫描点设到5000个以上,加上多层参数循环,MATLAB跑起来确实会卡。我的经验是三步优化:一是预分配数组,不要在循环里动态扩展;二是把循环内不变的量提到循环外,比如$\kappa$的系数、$\Delta n_{eff}$的值;三是考虑用向量化计算替代for循环,把波长范围直接代入矩阵运算。
% 向量化写法示例 lambda_vec = lambda_range'; kappa_vec = pi * dn ./ lambda_vec * 0.8; delta_vec = pi * (1/Lambda + delta_n / lambda_vec); gamma_vec = sqrt(kappa_vec.^2 + delta_vec.^2); T_vec = cos(gamma_vec * L).^2 + (delta_vec.^2 ./ gamma_vec.^2) .* sin(gamma_vec * L).^2;这段向量化代码跑2001个波长点,耗时从原来的约2秒降到不足0.1秒。虽然原始数据量不大、差距不明显,但当你扩展到10000个点、还要嵌套周期和$\mathrm{d}n$扫描的时候,这个优化能帮你节约大量时间。
5.4 多峰分裂现象的排查
当你发现谐振峰旁边出现两个甚至三个紧挨着的极小值时,不用慌。这大概率是选定的包层模式不止一个。LPG和FBG的差异就在这里:FBG只涉及纤芯基模的反向耦合,模式单一;LPG的包层模式有很多阶,LP$_0$、LP$_1$、LP$_2$…… 每一阶都有自己的有效折射率和谐振波长。如果代码里没有明确限定只算第一个包层模式,就可能同时算出好几个谐振峰。
解决方法是给模式阶数加参数,比如m = 1,然后只取对应阶数的$n_{eff}^{cl}$参与计算。如果你确实想仿真多个模式的叠加效果,那就把每阶模式的透射谱分别算出来,再按功率加权叠加,而不是让代码在同一个循环里懵懵懂懂地混算。
最后再分享一个小经验:这个仿真代码做完之后,不要急着删。把参数扫描的过程整理成一份简单的说明文档,记录哪组参数对应哪条曲线,后面写论文、补实验的时候会非常感谢自己当时做了这个记录。我自己就是这样,几乎所有LPG相关的实验数据,最后都能跟仿真曲线对得上。
本文还有配套的精品资源,点击获取