平行平面谐振腔自再现模式的MATLAB数值迭代与仿真分析
2026/9/17 3:04:25 网站建设 项目流程

简介:这是一套用于激光器谐振腔模拟分析的MATLAB源码包,面向光学工程、激光物理专业的高校学生与科研人员,也适合需要快速判断谐振腔模式、评估稳定性的工程师。压缩包共六个文件,大小仅22KB,代码部分包含四个脚本,承担主程序、多镜元模式计算、稳定区分析、腔内模尺寸求解等任务;随附一份文本,归纳了简单平行平面谐振腔自再现模式的特点,另有使用说明文档,方便对照运行和二次修改。整套程序基于MATLAB 2020b环境编写,设计让使用者直接替换数据即可出结果,新手也能较快入手;借助配套说明,读者既能复现模拟流程,也能掌握谐振腔模式分析、稳定区绘制的关键思路,适用于课程设计、毕业设计或科研预研。当前已有两百一十三人学习下载,值得相关方向参考。

1. 为什么说平行平面谐振腔的“自再现模式”只能靠数值迭代

激光器谐振腔的模拟分析里,平行平面腔是最容易被低估的结构。手边的MATLAB跑上一组腔参数,ABCD矩阵告诉你它落在稳定区,可真正看输出镜上的光斑,基模并不是均匀平面波,而是一圈圈菲涅耳边纹叠加后的复杂场分布。要解释这种场,必须回到Fox-Li自再现迭代:让初始场在腔内往返传播,直到归一化后的场复现。这个资源包正是围绕简单平行平面谐振腔自再现模式展开的:先由multi_element_mode.m这类函数完成多元件腔矩阵组装,再由迭代得到模式场和衍射损耗。适合正在做激光器腔型设计、用MATLAB做光学仿真,或者准备研究生课程中谐振腔案例的人。

2. 从Fox-Li迭代到多元件谐振腔的矩阵建模

2.1 自再现模式的定义与迭代收敛条件

谐振腔里真正能稳定工作的模式,是在腔内往返一周后,除了一个复常数外场分布不变。这个复常数包含相位变化和每趟的能量损耗。所谓自再现,并不是要求光强严格不变,而是要求模式形状不变,整体幅度按同一比例缩放。

数值上最直观的做法是Fox-Li迭代。取任意初始场,比如均匀振幅分布或者带一点随机扰动,然后让它依次经过腔镜反射、自由空间衍射、另一侧腔镜反射,完成一次往返。将结果归一化到同一能量水平,再作为下一轮输入。每次都记录场分布变化量,当变化量小到阈值以下,就说迭代收敛了。这个收敛后的场,就是谐振腔的自再现模式,也就是所谓的主模。

需要注意的是,迭代收敛不是必然发生。如果腔的菲涅耳数很小,衍射损耗极大,大部分能量在几次往返内就散光了,归一化会放大数值噪声,场分布可能一直跳变。常见处理是给初始场一个微小的高斯扰动,让基模自然显现,而不是让初始场严格均匀。

2.2 多元件腔的ABCD矩阵与衍射模型的衔接

谐振腔里往往不只有两面镜,还有增益介质的热透镜、调制器、扩束镜等。这类多元件腔可以用2×2的ABCD矩阵记录光线坐标变换,稳定性判据也由矩阵元给出。但ABCD矩阵只能描述理想化的高斯光束,对腔镜的硬边衍射、高阶模、光阑效应无能为力。要得到完整的模式场分布,需要在每个元件之间做衍射积分。

我在拆这套代码时,会把传输看作两步:元件只改变相位分布,自由空间传播才引入衍射。比如一个曲率半径为R的镜面,反射时乘上的相位因子是exp(-i·k·(x²+y²)/R);一段长度为L的均匀区域,用菲涅耳衍射积分或角谱方法传播。这样ABCD矩阵和数值衍射就统一进同一个往返算子。multi_element_mode_function.m这个函数名,看起来就是按这个思路做的:先把各个元件的ABCD矩阵级联成往返矩阵,再在需要输出场分布的位置调用衍射传播。

2.3 资源包内m文件的分工与调用顺序

把压缩包解压后,会看到多个m文件、一份txt说明和一份Markdown文档。主入口是main.m,它会调用其余函数。下表是这份压缩包里,我按名称和常见使用习惯归纳的分工,具体注释以包内md文档为准。

文件作用运行方式
main.m设定腔参数,组织计算流程直接运行
multi_element_mode_function.m多元件腔的往返矩阵或模式计算函数被main调用
multi_element_mode.m模式迭代主函数被main调用
mode_size_in_cavity.m计算腔内束腰、镜面光斑尺寸被main调用
StableArea_uv_highpower.m绘制稳定区图,支持高功率热透镜参数被main调用
简单平行平面谐振腔自再现模式特点,模拟分析.txt文字说明平行平面腔模式特点,仅供阅读不需要运行
使用说明文档.md运行步骤与参数说明无需运行

如果要自己重写一个简化版的多元件矩阵级联,核心是这样的:

function M_total = build_cavity_matrix(elements) % elements: cell array,每个元素是一段光学元件的2x2矩阵 % 光从左侧出发,逐段经过元件,总的往返矩阵按列左乘 M_total = eye(2); for k = 1:numel(elements) M_total = elements{k} * M_total; end end

这里的逻辑是:光线从谐振腔某一参考面出发,依次经过列表中的元件,每经过一个元件,就把它的矩阵左乘到当前累计矩阵上。调用时,如果腔内顺序是透镜、自由空间、平面镜,就把这三个矩阵按顺序放进elements数组。返回值M_total可用于判断稳定性,也可以进一步转换为衍射算子的传输参数。

3. 把资源包跑起来:main.m的调用关系与参数准备

3.1 运行环境与文件放置

这个资源包基于MATLAB 2020b开发,向下兼容大多数函数。如果你的版本更旧,只要不是刻意用了新语法,也能跑起来。第一步把压缩包里所有m文件和文档解压到同一个目录。路径最好不要带中文,因为某些MATLAB版本对UTF-8路径支持不好,容易在读取md或写入结果时出现乱码。

打开MATLAB,将当前文件夹切换到该目录。在命令行窗口输入which main.m,如果能返回完整路径,说明文件已经被识别。直接在编辑器里双击打开main.m,点运行按钮。程序会在命令窗口打印计算进度,并弹出模式分布图。跑通之前不要急着改参数,先用默认参数运行成功,再替换成自己的腔参数。

3.2 main.m的调用关系与参数替换

main.m里通常会先定义波长、腔长、镜面曲率半径、采样点数和迭代次数,然后按顺序调用表2里的函数。下面这段是根据这类项目常见做法写的调用框架,结构上与原包等价,但不是包内原始代码。

% main.m 示意:平行平面谐振腔自再现模式 clear; close all; clc; % 用户参数区 lambda = 1064e-9; % 波长,Nd:YAG激光器常用1064 nm L = 100e-3; % 腔长,单位m R1 = Inf; % 全反镜曲率半径,Inf表示平面镜 R2 = Inf; % 输出镜曲率半径 D = 10e-3; % 镜面有效孔径边长 N = 256; % 采样网格数 n_max = 100; % 最大迭代次数 % 计算腔参数与稳定区 StableArea_uv_highpower(L, R1, R2, lambda); % 计算腔内模尺寸 w0 = mode_size_in_cavity(L, R1, R2, lambda); % 运行自再现迭代 [field, loss, iter] = multi_element_mode(L, R1, R2, lambda, D, N, n_max); % 显示结果 fprintf('单程损耗: %.4f%%\n', loss * 100); fprintf('束腰半径: %.3f mm\n', w0 * 1e3); figure; imagesc(abs(field).^2); axis square; title('输出镜上的自再现模式光强分布');

参数区里的lambda、L、R1、R2决定腔的稳定性质。R1=Inf表示第一面镜是平面镜,R2=Inf就是平行平面腔。如果你做的是平凹腔,把R2改成正值,比如0.5表示曲率半径0.5 m。D是镜面有效孔径,在数值上承担硬边光阑角色,直接影响衍射损耗,不要随意取太大或太小。

这些参数的含义和推荐初值可以先按下面的表格设置,等程序跑通后再根据激光器实际结构逐项替换。

参数含义推荐初值
lambda激光波长1064e-9
L腔长100e-3
R1全反镜曲率半径Inf 或 1
R2输出镜曲率半径Inf 或 0.5
D孔径边长10e-3
N采样网格数256

lambda越小,菲涅耳数越大,模式越接近几何光学预测;N越大,计算越慢但空间分辨率越高。一般先取128做快速试算,确认趋势正确再用256或512出图。迭代次数n_max可以设置成固定值,但更稳妥的方法是用前后两次场分布的相对变化作停止条件,这部分放在第6章展开。

3.3 自再现迭代核心循环

为了让你知道这些函数内部在做什么,我写了一个可直接运行的平行平面腔Fox-Li迭代函数。它采用角谱传播,两次传播对应一次往返,并且在两面镜上都做了孔径截断。

function [field, loss, n_iter] = fox_li_2d(lambda, L, D, N, n_max) dx = D / N; x = (-D/2 + dx/2 : dx : D/2); % 坐标中心对齐 [X, Y] = meshgrid(x); field = ones(N, N); aperture = double(abs(X) <= D/2 & abs(Y) <= D/2); field = field .* aperture; fx = (-1/(2*dx) : 1/(N*dx) : 1/(2*dx) - 1/(N*dx)); [FX, FY] = meshgrid(fx); H = exp(1i * pi * lambda * L * (FX.^2 + FY.^2)); for n_iter = 1:n_max field = field / sqrt(sum(abs(field(:)).^2) * dx^2); % 先归一化 field_prev = field; field = ifft2(fft2(field_prev) .* H); field = field .* aperture; field = ifft2(fft2(field) .* H); field = field .* aperture; energy = sum(abs(field(:)).^2) * dx^2; field = field / sqrt(energy); loss = 1 - energy; change = norm(field - field_prev, 'fro') / norm(field_prev, 'fro'); if change < 1e-5 break; end end end

这个函数先用均匀振幅场出发,但在每次迭代前把输入场归一化到总能量为1,这样loss的定义始终对应从能量1出发的单程损耗。两次ifft2之间夹着一次镜面截断,等价于场在两面平面镜间完成一次往返。第一次截断在输出镜,第二次截断在全反镜,两个孔径尺寸都用D控制。收敛判定用的是前后两轮归一化场的相对范数,比单纯看损耗稳定更能捕捉模式形状的变化。

回到资源包:multi_element_mode.m这类函数,内部基本就是这一段逻辑,加上多元件矩阵的相位修正。只要理解了上面的内核,改参数不再有黑箱感。

4. 稳定区与模式尺寸:StableArea_uv_highpower与mode_size_in_cavity实战

4.1 稳定区图的判据与高功率热透镜修正

对两镜腔,定义g1 = 1 - L/R1,g2 = 1 - L/R2,稳定条件为0 < g1*g2 < 1。StableArea_uv_highpower.m里的uv,通常就是把g1和g2映射成u=1-L/R1、v=1-L/R2这两个无量纲量。高功率激光器里,增益介质受热会产生等效透镜,焦距随泵浦功率变化,所以这个函数还会把热透镜等效焦距并进稳定图。这比单纯画u-v矩形要实用得多。

实际用的时候,先在参数区设置好腔长和镜面曲率,再调用函数。它会在新窗口里画出稳定区,亮色区域代表满足稳定条件的参数组合,深色代表非稳区。下面是一个可以自己跑一遍的稳定区扫描脚本:

% 扫描稳定区,并叠加高功率热透镜工作线 L = 0.1; % 腔长0.1 m lambda = 1064e-9; u = linspace(0.1, 1.9, 301); v = linspace(0.1, 1.9, 301); [U, V] = meshgrid(u, v); g1g2 = U .* V; stable = (g1g2 > 0) & (g1g2 < 1); imagesc(u, v, stable'); colormap(gray); hold on; % 典型热透镜扫描线:v随泵浦功率从0.2变到1.2 pump = linspace(0.2, 1.2, 50); plot(1 - L./pump, pump, 'r-', 'LineWidth', 1.5); xlabel('u = 1 - L/R1'); ylabel('v = 1 - L/R2'); title('谐振腔稳定区与高功率热透镜工作线');

这段代码先构建u和v的二维网格,用U.*V同时落在0到1之间作为稳定条件。imagesc绘制的矩阵按照行方向对应y轴,所以取了转置来避免图像上下颠倒。红色工作线表示随泵浦功率改变,热透镜焦距变化时,腔的g参数沿某条曲线移动。如果这条线穿出稳定区,意味着泵浦功率超过某一阈值后,谐振腔会从稳定走向非稳。

这个脚本的逻辑非常简单,StableArea_uv_highpower.m里还会把衍射损耗、镜面光斑尺寸一起画成子图。观察工作线在稳定区内的穿越位置,可以确定安全泵浦范围,这是高功率固体激光器设计里非常重要的一步。

4.2 用mode_size_in_cavity核对高斯模尺寸

得到稳定区之后,下一步是计算腔内的模式尺寸。mode_size_in_cavity.m的作用是在给定腔长、镜面曲率半径和波长时,输出束腰位置和两个镜面上的光斑半径。它内部用的是高斯光束q参数变换:在参考面上写出q参数,用ABCD矩阵传播到任意位置,再从1/q的虚部提取光斑尺寸。

调用方式通常是这样:

% 平凹腔实例:R1=Inf,R2=0.5 m,腔长0.4 m L = 0.4; R1 = Inf; R2 = 0.5; lambda = 632.8e-9; % He-Ne波长 [w1, w2, z0] = mode_size_in_cavity(L, R1, R2, lambda); fprintf('全反镜上光斑半径: %.3f mm\n', w1*1e3); fprintf('输出镜上光斑半径: %.3f mm\n', w2*1e3); fprintf('束腰位置距输出镜: %.3f m\n', z0);

这里w1和w2是两个腔镜上的1/e²光斑半径。对于平凹腔,束腰在平面镜处,所以z0通常接近0。如果改成双凹腔,束腰会落在两个镜面之间,模拟分析和实验调试时,可以把倍频晶体或调Q晶体放在束腰附近,获得最大能量密度。

用同一个腔参数,把mode_size_in_cavity的结果与第3章Fox-Li迭代得到的光斑宽度放在一起对比,可以验证数值结果是否落在稳定范围内。下表是一个典型对照关系,具体数值随参数变化,但趋势一致。

腔型g1*g2镜面光斑半径自再现迭代光斑宽度一致性
平行平面1很大,接近孔径受衍射孔径决定仅当孔径远大于解析模宽度时一致
平凹腔0.5中等中等较好
共焦腔0最小最小很好

这里的“自再现迭代光斑宽度”用二阶矩定义,而解析公式用1/e²定义,两者在相同物理尺度下相差一个接近常数的比例。如果发现数值结果比解析计算大出数倍,先检查孔径是不是选得不够大,或者迭代没收敛,而不是急着调镜面曲率半径。

5. 高阶模与衍射损耗:从模拟结果里提取物理量

5.1 模式场分布与高阶模的投影

谐振腔的Fox-Li迭代收敛后,得到的是基模还是高阶模,取决于初始场和腔的几何结构。平行平面腔里,高损耗的高阶模往往在迭代中逐渐衰减,但有些高阶模的损耗与基模接近,会在输出光斑里留下多个瓣或暗环。为了区分模式,常见做法是将模拟场投影到一组厄米-高斯基函数上,得到各阶系数。

如果只想快速判断模拟结果中是否混杂高阶模,可以用强度二阶矩估计光束质量。下面这个脚本沿x方向积分光强,计算x方向的二阶矩宽度:

% 从二维场提取x方向二阶矩宽度 function wx = second_moment_width(field, x) I = sum(abs(field).^2, 2); % 沿y方向积分 I = I(:)'; P = sum(I); if P == 0 wx = NaN; return; end xc = sum(I .* x) / P; % 一阶矩,即质心 wx = sqrt(2 * sum(I .* (x - xc).^2) / P); % 二阶矩宽度 end

这段代码先对二维场做纵向求和,得到一维强度分布I。然后计算一阶矩xc和二阶矩。乘以sqrt(2)是为了把方差折算成高斯光束的1/e²半径。如果计算得到的wx与解析高斯模宽度一致,说明迭代结果主要是基模;如果wx明显偏大,说明模场中存在高阶成分或边缘衍射效应。

调用时注意x坐标要与场矩阵的行方向对应。假设第3章的场field是按[X,Y]网格计算的,那么x实际上是一维行向量,sum(abs(field).^2, 2)得到的是每个x坐标位置上的总强度,正好与x一一对应。这种写法在MATLAB的meshgrid约定下是安全的。

5.2 衍射损耗随菲涅耳数的变化

衍射损耗是谐振腔的重要设计指标,在Fox-Li迭代中直接表现为能量衰减。菲涅耳数Nf = a²/(lambda·L),其中a是镜面半径。Nf越大,衍射损耗越小;Nf越接近1,损耗快速增长。平行平面腔的基模单程损耗在Nf≈1时可达百分之几到十几,远高于稳定球面腔。

用资源包里的multi_element_mode.m跑不同孔径D,可以得到一条损耗随菲涅耳数变化的曲线。下表是常见趋势的量化描述,不是某个特定腔的精确数据,只用来判断代码结果是否合理。

菲涅耳数 Nf基模单程损耗量级迭代收敛速度
< 0.5高损耗,归一化后噪声大慢,可能不收敛
0.5 ~ 2中等损耗,边缘衍射明显中等
2 ~ 10低损耗,模式接近高斯
> 10极低损耗,需要更多迭代步才能稳定快但需要高精度归一化

如果算出的损耗偏离这个趋势太多,问题通常出在采样或孔径定义上。比如把D直接设成镜面直径而不是半径,菲涅耳数会差4倍,损耗曲线整体移位。先确认口径定义,再检查网格间距。

实际设计里,模拟得到的单程损耗还要折算到输出耦合镜的透射率上。比如,若模拟损耗为2%,输出镜透射率取10%,则总单程损耗为12%。通过对比不同孔径D下的损耗曲线,可以选择一个损耗对孔径变化不敏感的工作点,避免机械对准误差导致功率大幅波动。

5.3 模式迭代中的归一化陷阱

在自再现迭代里,归一化方式会影响损耗记录。常见做法是在每次往返后,将场乘以1/sqrt(energy),把总能量恢复为1。这样一来的loss就是不被归一化的原始能量衰减量。但如果有人在循环里把归一化因子也算进损耗,就会出现“平均损耗恒为零”的假象。

另一个陷阱是最开始迭代的瞬态段。初始均匀场在平行平面腔里会先经历剧烈振荡,前10次迭代的损耗可能为负,因为数值噪声被放大,不要直接读这段结果。我一般会跳过前20轮,再统计loss的平均值和方差。

对高功率腔来说,热透镜会改变等效腔长,模拟时要在每次迭代后重新判断ABCD矩阵是否变化。这一点和StableArea_uv_highpower.m里的热透镜参数是配套的,使用高功率工作线时,记得把热焦距代入再跑一次损耗曲线。

6. 网格采样与收敛性控制的几个实操技巧

6.1 角谱传播的采样条件

角谱法要求网格满足近轴奈奎斯特条件。经验上,相邻网格的相位差不能超过π,否则混叠会把伪影当成真实衍射。实际使用时可以按菲涅耳数判断:网格数N和孔径D确定后,令菲涅耳数Nf = (D/2)²/(lambda·L)。当Nf > 0.1且网格线密度N/D足够大,角谱结果基本可信。反过来说,如果你把D取成1 cm、lambda取1064 nm、L取0.1 m,Nf约235,并不代表需要特别大的N,而是说明硬边衍射会在边缘产生高频分量,网格太粗会直接把边缘结构抹平。

一般做法是先令N=128试跑,观察光斑是否出现非对称条纹;如果条纹方向与网格方向一致,说明是混叠或伪影,要把N提高一倍再跑。不要一上来就N=1024,因为FFT在1024×1024上的多次迭代会明显拖慢程序。

6.2 收敛停止条件与迭代次数

代码中常用norm(field - field_prev, 'fro') / norm(field_prev, 'fro')作为相对变化量。这个量比看损耗稳定更严格,因为损耗可以连续20次不变而场仍在缓慢旋转。阈值一般取1e-5到1e-7。如果做批量参数扫描,可以设成固定50次迭代,但要记录最后一次的损耗变化,用于筛选不收敛的样本。

% 批量运行时保存收敛状态 if change < 1e-5 converged = true; else converged = false; end

6.3 边界孔径的软处理

平行平面腔模拟中的硬边孔径会产生真实的边缘衍射,但数值上也会引入振铃。常见做法是给孔径乘上一个m阶超高斯窗,m取4或6。这样做能抑制振幅振荡,但会稍微低估边缘衍射损耗。若目标是精确复现实验测量的损耗,建议先用硬边孔径跑一组粗网格,再用软边孔径做局部验证,两者之间的差可以看作数值误差的上界。在批量扫描参数时,建议先跑粗网格定趋势,再用细网格复算,最后记下每次运行的网格尺寸、孔径大小和损耗,方便回看哪些点出现伪模。

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

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

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

立即咨询