ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

飞秒锁模激光器仿真:Figure8_NALM腔设计与分步傅里叶法实现

飞秒锁模激光器仿真:Figure8_NALM腔设计与分步傅里叶法实现 简介这份资源面向从事超快光学与激光器设计的研究生、科研人员及仿真工程师聚焦非线性环路反射镜NALM锁模激光器的飞秒脉冲生成仿真帮助读者在实验前理解腔长、色散管理与非线性效应之间的耦合关系。压缩包共79个文件约98KB以61个m脚本为主体涵盖主程序、放大器、滤波器、耦合器与GNLSE求解器等模块另含少量git配置与系统隐藏文件便于直接运行与二次开发。内容围绕NPR锁模与verb6cj仿真展开包含孤子演化、色散波产生、级联仿真及多种求解器对比等典型场景可帮助读者快速搭建仿真框架、复现飞秒脉冲动态并优化锁模参数。目前已有820人学习下载适合需要系统理解NALM锁模机理、对照代码验证物理模型的进阶学习者。1. 从 Figure8 到 NALM一套飞秒锁模仿真到底在算什么飞秒激光器里最让人头疼的不是泵浦耦合也不是色散补偿而是“锁模”这件事到底能不能自启动、能不能稳定。很多做实验的同行调了几个月腔长、泵浦功率、偏振控制器都试遍了脉冲还是时有时无像玄学一样。Figure8_NALM 这套仿真方案就是冲着这个问题来的它用非线性放大环形镜NALM构造一个“8”字型腔通过数值求解脉冲在腔内往返演化把锁模的启动条件、稳定区间和脉冲参数提前算出来。你不需要先搭一台实物激光器就能在电脑上看到脉冲从噪声演化到飞秒孤子的全过程。这套东西适合两类人一是正在设计 NALM 锁模激光器、需要快速筛选腔参数的研究生和工程师二是已经搭好腔但脉冲不稳定、想从仿真里找原因的实验派。它不能替代实验但能帮你把“试错”从光学平台搬到代码里省下大量调光路的时间。2. NALM 与 Figure8 腔的数学骨架从耦合方程到可迭代的传输模型2.1 为什么 NALM 能等效可饱和吸收体NALM 的核心是一个 2×2 光纤耦合器把环形腔分成两段一段接增益光纤和泵浦另一段是纯无源光纤。脉冲进入耦合器后分成两路一路顺时针、一路逆时针传播两路经历不同的非线性相移和增益回到耦合器时干涉。关键点在于两路的非线性相移差与脉冲强度有关——强度高的部分相移差大干涉后透射率高强度低的部分相移差小透射率低。这就等效出一个“快可饱和吸收体”的效果而且响应时间在飞秒量级比半导体可饱和吸收镜SESAM快得多。Figure8 腔则是在 NALM 基础上再加一个环形镜形成两个环共享一段增益光纤的结构。主环提供增益和输出副环NALM提供等效可饱和吸收和负反馈。这种结构的好处是锁模自启动阈值低而且能承受较高的泵浦功率而不产生连续波损伤。仿真里要做的就是把两段光纤的增益、损耗、色散、非线性系数分别写进传输方程然后让脉冲在腔内循环迭代。2.2 分步傅里叶法求解非线性薛定谔方程脉冲在光纤中的演化用非线性薛定谔方程NLSE描述∂A/∂z -α/2 A - iβ2/2 ∂²A/∂T² iγ|A|²A其中 A(z,T) 是脉冲包络α 是损耗β2 是群速度色散γ 是非线性系数。仿真里最常用的数值解法是分步傅里叶法SSFM把光纤分成很多小段每段内先只考虑色散和损耗在频域乘一个相位因子再只考虑非线性在时域乘一个相位因子。这样交替进行精度取决于步长。下面是一个最小可运行的 SSFM 核心代码用 Python 写只依赖 numpyimport numpy as np def ssfm_step(A, dt, dz, beta2, gamma, alpha0.0): 单步分步傅里叶演化先色散损耗再非线性 A: 脉冲包络复数数组 dt: 时间步长 (ps) dz: 空间步长 (m) beta2: 群速度色散 (ps^2/m) gamma: 非线性系数 (1/(W*m)) alpha: 损耗 (1/m) N len(A) omega 2 * np.pi * np.fft.fftfreq(N, ddt) # 角频率 # 色散损耗算符频域 disp_op np.exp(-alpha * dz / 2 - 1j * beta2 * dz * omega**2 / 2) A_freq np.fft.fft(A) A_freq * disp_op A np.fft.ifft(A_freq) # 非线性算符时域 A * np.exp(1j * gamma * np.abs(A)**2 * dz) return A def propagate(A, L, dz, beta2, gamma, alpha0.0): 在长度 L 的光纤中传播 n_steps int(L / dz) for _ in range(n_steps): A ssfm_step(A, dt0.01, dzdz, beta2beta2, gammagamma, alphaalpha) return A逻辑说明ssfm_step里先做 FFT 到频域乘以色散和损耗的指数项再 IFFT 回时域乘以非线性的指数项。propagate就是循环调用。参数方面dt一般取脉冲宽度的 1/20 到 1/50dz要满足dz 1/(gamma*P_peak)和dz T0^2/|beta2|否则会引入数值误差。实际仿真里增益光纤的gamma约 0.005~0.01 /(W·m)beta2在 1.55 μm 附近约 -20 ps²/km无源光纤类似。这些值需要根据你实际用的光纤型号查手册不能随便填。2.3 把 NALM 干涉写进迭代耦合器与相移差在 Figure8 腔里每一圈要处理两次耦合器一次是主环到 NALM 的输入一次是 NALM 两路返回后的干涉。耦合器用分光比 ρ 描述比如 50:50 就是 ρ0.5。NALM 两路的相移差 Δφ 由非线性效应和增益决定Δφ γ * P_peak * L_NALM * (1 - 2ρ) 增益不对称项仿真里不需要解析这个公式而是直接把两路分别传播然后在耦合器处按场叠加def nalm_reflect(A_in, rho, L_nalm, dz, beta2, gamma, alpha, gain_factor1.0): NALM 反射输出两路传播后干涉 rho: 耦合器分光比输出端比例 gain_factor: 增益光纤的净增益简化处理 # 顺时针路先经过耦合器再传播 A_cw np.sqrt(1 - rho) * A_in A_cw propagate(A_cw, L_nalm, dz, beta2, gamma, alpha) A_cw * np.sqrt(gain_factor) # 逆时针路传播后再经过耦合器 A_ccw np.sqrt(rho) * A_in A_ccw propagate(A_ccw, L_nalm, dz, beta2, gamma, alpha) A_ccw * np.sqrt(gain_factor) # 干涉两路在耦合器处叠加 A_out np.sqrt(1 - rho) * A_cw np.sqrt(rho) * A_ccw return A_out这里gain_factor是简化写法实际应该把增益光纤的速率方程也耦合进去但为了先跑通锁模可以先用常数增益近似。等脉冲稳定后再换成动态增益模型看能量抖动。参数rho一般取 0.5 到 0.7太小会导致 NALM 反射率低锁模启动困难太大则非线性相移差不够脉冲容易分裂。3. 在本地跑通 Figure8 锁模仿真从参数文件到脉冲演化图3.1 环境准备与最小依赖这套仿真不需要 GPU普通笔记本就能跑。Python 3.8 以上装 numpy 和 matplotlib 即可。如果你要跑长腔比如 10 米以上或者高分辨率2^14 点以上建议用 numpy 的 FFT 多线程或者换 pyfftw。我一般会建一个虚拟环境避免和系统里的科学计算包冲突python -m venv venv_fig8 source venv_fig8/bin/activate # Windows 用 venv_fig8\Scripts\activate pip install numpy matplotlib注意不要用 conda 默认的 numpy有些版本 FFT 精度有问题会导致脉冲演化几步后出现数值噪声。如果发现脉冲能量不守恒先检查 numpy 版本换到 1.24 以上通常就好了。3.2 参数表腔长、色散、非线性与增益下面这张表是我在 1.55 μm 波段做 NALM 锁模仿真时常用的起始参数你可以直接抄然后根据自己光纤的参数微调。单位都标清楚了别混用。参数符号典型值单位说明主环长度L_main4.0m含增益光纤和输出耦合器NALM 环长L_nalm2.5m无源光纤为主群速度色散β2-22ps²/km标准单模光纤在 1550 nm非线性系数γ0.0061/(W·m)有效模场面积约 80 μm²耦合器分光比ρ0.6—输出端比例小信号增益g01.5dB/m掺铒光纤饱和能量E_sat100pJ增益饱和时间窗口T_max20ps对应 2^12 点dt≈0.005 ps空间步长dz0.01m每步 1 cm这些值不是唯一解但能让你在第一次运行时就看到脉冲从噪声收敛到孤子。如果跑 500 圈还没锁模先把 g0 提到 2.0 dB/m或者把 ρ 降到 0.5 试试。3.3 主循环500 圈往返与脉冲能量监测把前面的 SSFM 和 NALM 干涉串起来就是主循环。每一圈代表脉冲在 Figure8 腔里走一个完整往返。我习惯每圈记录脉冲峰值功率、能量和脉宽方便判断是否锁模。import numpy as np import matplotlib.pyplot as plt # 参数 N 4096 T_max 20.0 # ps dt T_max / N t np.arange(-N/2, N/2) * dt beta2 -22e-3 # ps^2/m注意单位换算-22 ps²/km -0.022 ps²/m gamma 0.006 alpha 0.0 L_main 4.0 L_nalm 2.5 rho 0.6 g0 1.5 / 4.343 # 换算成 1/m1.5 dB/m ≈ 0.345 /m E_sat 100e-12 # J dz 0.01 # 初始噪声脉冲 A 0.001 * (np.random.randn(N) 1j * np.random.randn(N)) # 加一个高斯种子帮助启动 A 0.01 * np.exp(-t**2 / (2 * 0.5**2)) energies [] peak_powers [] for round_trip in range(500): # 主环传播含增益 E_pulse np.sum(np.abs(A)**2) * dt gain g0 / (1 E_pulse / E_sat) A propagate(A, L_main, dz, beta2, gamma, alpha-gain) # 负损耗即增益 # NALM 反射 A nalm_reflect(A, rho, L_nalm, dz, beta2, gamma, alpha, gain_factor1.0) # 输出耦合假设 10% 输出 A_out np.sqrt(0.1) * A A np.sqrt(0.9) * A # 记录 energies.append(np.sum(np.abs(A)**2) * dt) peak_powers.append(np.max(np.abs(A)**2)) # 画图 fig, axes plt.subplots(2, 1, figsize(8, 6)) axes[0].plot(energies) axes[0].set_ylabel(Pulse energy (pJ)) axes[1].plot(peak_powers) axes[1].set_ylabel(Peak power (W)) axes[1].set_xlabel(Round trip) plt.tight_layout() plt.show()逻辑说明每圈先算当前脉冲能量用g0/(1E/E_sat)算饱和增益然后传给propagate时把alpha设成负值表示增益。NALM 反射里两路都乘了gain_factor1.0因为增益已经在主环里算过了。输出耦合用 10% 分光剩下 90% 继续循环。跑完 500 圈如果能量曲线从噪声涨到稳定值比如 50~100 pJ并且峰值功率收敛说明锁模成功。参数调整如果能量一直涨不收敛把E_sat调小或者把g0降到 1.0 dB/m。如果脉冲分裂成多个峰把rho调到 0.55 或者把L_nalm缩短到 2.0 m。这些调整没有固定公式但方向是增益太强会分裂NALM 相移差不够会锁不住。3.4 怎么看结果时域波形与光谱跑完主循环后把最终脉冲的时域和频域画出来确认是不是干净的孤子。时域上应该是一个光滑的 sech 型没有明显旁瓣光谱上应该有 Kelly 边带这是孤子锁模的典型特征。# 最终脉冲 A_final A spectrum np.abs(np.fft.fftshift(np.fft.fft(A_final)))**2 freq np.fft.fftshift(np.fft.fftfreq(N, ddt)) fig, axes plt.subplots(1, 2, figsize(10, 4)) axes[0].plot(t, np.abs(A_final)**2) axes[0].set_xlabel(Time (ps)) axes[0].set_ylabel(Power (W)) axes[1].plot(freq, 10*np.log10(spectrum 1e-20)) axes[1].set_xlabel(Frequency (THz)) axes[1].set_ylabel(PSD (dB)) plt.tight_layout() plt.show()如果时域波形有多个峰说明脉冲分裂需要降低增益或增加 NALM 的负反馈。如果光谱没有边带可能是色散符号不对——1.55 μm 处普通单模光纤是反常色散β2 为负如果你填了正值孤子无法形成。这些判断不需要精确计算看图就能定性。4. 避坑与排查Npr 锁模仿真里最容易翻车的 5 个地方4.1 脉冲不锁模能量一直涨现象跑了几百圈脉冲能量持续上升时域波形变成宽噪声没有收敛趋势。 原因增益饱和能量设得太大或者小信号增益太高导致脉冲能量超过孤子面积极限分裂成连续波。 解决把E_sat从 100 pJ 降到 50 pJ或者把g0从 1.5 dB/m 降到 1.0 dB/m。同时检查rho是否太小NALM 反射率不够等效可饱和吸收效果弱。4.2 脉冲分裂成多个峰现象最终时域波形出现两个或三个峰间隔几皮秒。 原因非线性相移差过大NALM 透射率曲线出现多峰或者色散长度太短脉冲在腔内分裂。 解决把L_nalm缩短 20%或者把rho从 0.6 调到 0.55。如果还不行把gamma降到 0.004相当于换用模场面积更大的光纤。4.3 数值噪声淹没脉冲现象跑了几十圈后脉冲被高频噪声覆盖FFT 频谱出现对称的杂散峰。 原因空间步长dz太大SSFM 的 split-step 误差累积或者时间窗口T_max太小脉冲尾部被截断产生反射。 解决把dz从 0.01 m 降到 0.005 m把N从 4096 提到 8192T_max保持 20 ps 不变。注意dt会变小计算量增加但精度明显改善。4.4 光谱没有 Kelly 边带现象光谱是光滑的钟形没有孤子特征边带。 原因色散符号填错或者非线性长度远大于色散长度脉冲没有形成孤子。 解决确认beta2是负值反常色散。如果用的是正常色散光纤需要换腔型或者加色散补偿。另外检查gamma是否太小导致非线性效应不足以平衡色散。4.5 增益饱和导致脉冲能量抖动现象能量曲线在稳定值附近上下波动幅度超过 10%。 原因增益恢复时间没有考虑或者E_sat设得太接近脉冲能量增益对能量变化过于敏感。 解决把E_sat提高到脉冲能量的 3~5 倍比如脉冲 50 pJ 时设E_sat200 pJ。如果还抖把增益模型换成动态速率方程但计算量会大很多建议先跑通常数增益再升级。5. 进阶技巧用 Npr 锁模参数扫描快速定位稳定区5.1 扫描耦合器分光比与 NALM 长度与其一个个试参数不如写个循环把rho从 0.5 到 0.7、L_nalm从 2.0 到 3.0 扫一遍看哪些组合能锁模。判断标准很简单跑 300 圈后脉冲能量标准差小于均值的 5%且时域波形单峰。下面是一个扫描框架def is_mode_locked(energies, threshold0.05): 判断最后 100 圈能量是否稳定 tail energies[-100:] return np.std(tail) / np.mean(tail) threshold results [] for rho in np.arange(0.5, 0.71, 0.05): for L_nalm in np.arange(2.0, 3.1, 0.25): # 重置脉冲跑 300 圈 A 0.001 * (np.random.randn(N) 1j * np.random.randn(N)) A 0.01 * np.exp(-t**2 / (2 * 0.5**2)) energies [] for rt in range(300): E_pulse np.sum(np.abs(A)**2) * dt gain g0 / (1 E_pulse / E_sat) A propagate(A, L_main, dz, beta2, gamma, alpha-gain) A nalm_reflect(A, rho, L_nalm, dz, beta2, gamma, alpha) A np.sqrt(0.9) * A energies.append(np.sum(np.abs(A)**2) * dt) locked is_mode_locked(energies) results.append((rho, L_nalm, locked, np.mean(energies[-50:]))) print(frho{rho:.2f}, L_nalm{L_nalm:.2f}, locked{locked}, E{np.mean(energies[-50:]):.1f} pJ)这个扫描大概跑十几分钟取决于你的 CPU。跑完把lockedTrue的组合画成散点图就能看到稳定区边界。我一般会优先选rho在 0.55~0.65、L_nalm在 2.2~2.6 m 之间的区域这些点对参数扰动不敏感实验上更容易复现。5.2 从仿真到实验的映射表仿真跑通后怎么把参数翻译到实验下面这张表是我自己用的对照不一定精确但方向不会错。仿真参数实验对应调整手段rho耦合器分光比换耦合器或熔融拉锥L_nalmNALM 环光纤长度剪光纤或加延迟线g0泵浦功率调泵浦电流E_sat增益光纤掺杂浓度与长度换光纤或调长度beta2光纤色散换色散补偿光纤或调整波长注意仿真里beta2是常数实验里色散随波长变化所以仿真锁模波长和实验可能有几纳米偏差。这不是 bug是模型简化。如果你需要精确匹配得把beta2写成波长的函数但计算量会翻倍。5.3 我踩过的坑与固定习惯我最开始跑这套仿真时犯过一个低级错误把beta2的单位当成 ps²/m结果填了 -22实际应该是 -0.022。脉冲跑了两圈就炸了我还以为是算法问题查了一整天才发现单位错了。从那以后我养成了一个习惯所有参数先写单位再写数值代码里用注释标清楚换算过程。另一个坑是dz设得太大脉冲能量不守恒后来固定用 0.005 m虽然慢一点但结果可信。如果你刚开始做建议先用小N比如 1024快速试参数跑通了再上高分辨率。这套 Figure8_NALM 仿真不能保证你实验一次成功但能帮你排除掉大部分明显不合理的腔参数省下反复熔接光纤的时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表