简介:这份资源是面向激光物理、光学工程方向的学习者与科研人员的一套MATLAB仿真代码包,围绕高斯光束传输与谐振腔设计展开,可用于课程设计、课题预研与系统方案验证。包内共95个文件,以67个m脚本、17个fig图形文件、5个mat数据文件为主,另含docx说明、pdf文档、md与txt说明及license,压缩包约27.37MB,脚本与图形结果配套,便于直接运行与对照分析。内容覆盖高斯光束传播模型、热效应分析、非线性频率变换、光束调节与匹配算法、稳定驻波谐振腔与行波谐振腔设计,以及ABCD矩阵计算等模块,并配有LG、HG光束与M2因子拟合等示例脚本。目前已有122人学习下载,适合希望从理论公式走向可运行代码、快速搭建仿真流程并理解谐振腔稳定性与光束质量评估的读者参考使用。
1. 激光高斯光束传输与谐振腔仿真:一套 MATLAB 代码包能替你省下多少试错
做激光器设计的人大概都有过这种经历:光路调了半天,腔镜位置微调几毫米,输出模式就从 TEM00 变成了乱七八糟的高阶模,功率也跟着掉。你怀疑是热透镜效应,又怀疑是腔长没匹配好,但手头没有趁手的仿真工具,只能靠反复试。这套基于 MATLAB 开发的激光高斯光束传输与谐振腔仿真代码包,针对的就是这类问题——它把高斯光束传播模型、ABCD 矩阵计算、稳定驻波谐振腔设计、行波谐振腔仿真、热效应分析、非线性频率变换以及光束调节与匹配算法整合在一起,让你在动手拧镜架之前,先在代码里把光路跑一遍。适合做固体激光器、光纤激光器、倍频与和频实验的研究生和工程师,也适合需要快速验证腔型设计的应用开发人员。MATLAB 在这里的角色不是炫技,而是把矩阵光学那套东西变成可复用、可参数扫描的脚本,省掉每次重新推导的麻烦。
2. 高斯光束传播模型与 ABCD 矩阵:从公式到可跑代码
2.1 为什么用 q 参数和 ABCD 矩阵描述光束传播
高斯光束在自由空间、透镜、介质界面中的传播,用 q 参数最省事。q 参数把光束的束腰半径和波前曲率半径打包成一个复数,传播一段距离 d 就是 q 加 d,过一个薄透镜就是取倒数再减焦距倒数再取倒数。ABCD 矩阵把光学元件写成 2×2 矩阵,q 的变换规则是 q' = (Aq + B)/(Cq + D)。这套方法的好处是:不管光路里有多少个元件,乘起来就是一个总矩阵,光束参数一步算出来。代码包里通常会把常见元件的 ABCD 矩阵封装成函数,比如自由空间、薄透镜、球面镜、介质平板。你只需要按光路顺序调用,不用每次手推。
常见做法是定义一个abcd_free_space(d)返回[1 d; 0 1],abcd_thin_lens(f)返回[1 0; -1/f 1],abcd_mirror(R)返回[1 0; -2/R 1]。然后写一个q_transform(q_in, M)做分式线性变换。这些函数不长,但能避免重复劳动。
2.2 用 MATLAB 实现 q 参数传播的最小代码
下面这段代码演示从束腰出发,经过一段自由空间和一个薄透镜后的 q 参数和光斑半径。你可以直接复制到 MATLAB 脚本里跑。
% 高斯光束 q 参数传播示例 lambda = 1064e-9; % 波长 1064 nm w0 = 0.5e-3; % 束腰半径 0.5 mm zR = pi * w0^2 / lambda; % 瑞利长度 q0 = 1i * zR; % 束腰处 q 参数 % 自由空间 200 mm d = 0.2; M_free = [1 d; 0 1]; q1 = (M_free(1,1)*q0 + M_free(1,2)) / (M_free(2,1)*q0 + M_free(2,2)); % 薄透镜 f = 300 mm f = 0.3; M_lens = [1 0; -1/f 1]; q2 = (M_lens(1,1)*q1 + M_lens(1,2)) / (M_lens(2,1)*q1 + M_lens(2,2)); % 计算光斑半径 w1 = sqrt(-lambda / (pi * imag(1/q1))); w2 = sqrt(-lambda / (pi * imag(1/q2))); fprintf('自由空间后光斑半径: %.4f mm\n', w1*1e3); fprintf('透镜后光斑半径: %.4f mm\n', w2*1e3);逻辑说明:先由束腰半径算瑞利长度,得到 q0。自由空间矩阵作用后得到 q1,透镜矩阵作用后得到 q2。光斑半径公式是 w = sqrt(-lambda / (pi * imag(1/q)))。参数说明:lambda 是波长,w0 是束腰半径,d 是传播距离,f 是透镜焦距。注意单位统一用米,输出时转成毫米。如果你改波长或束腰,瑞利长度会变,光斑变化趋势也会变。这个最小例子跑通后,就可以把多个元件串起来,写一个循环处理整个光路。
2.3 把 ABCD 矩阵扩展成光路链
实际光路不会只有一个透镜。代码包里一般会提供一个propagate_through_system函数,输入初始 q 和一个元胞数组,每个元素是一个 ABCD 矩阵,按顺序作用。这样你可以把腔镜、晶体、透镜、空气间隔都写进去。比如:
function q_out = propagate_through_system(q_in, matrices) q = q_in; for k = 1:length(matrices) M = matrices{k}; q = (M(1,1)*q + M(1,2)) / (M(2,1)*q + M(2,2)); end q_out = q; end调用时matrices = {M1, M2, M3, ...}。这个函数不检查物理合理性,所以你要自己保证矩阵顺序和光路方向一致。常见错误是把透镜矩阵写反,导致结果完全不对。建议每加一个元件就打印一次光斑半径,和直觉对比。
3. 稳定驻波谐振腔与行波谐振腔:腔型参数怎么设、怎么扫
3.1 驻波腔的稳定性条件与 g 参数
驻波腔由两面镜子组成,光在腔内往返。稳定性条件用 g1 = 1 - L/R1,g2 = 1 - L/R2 表示,要求 0 < g1*g2 < 1。满足这个条件,腔内光束才能自再现。代码包里通常有stability_plot函数,扫描 L、R1、R2 的范围,画出稳定区。你可以在图上直接看到哪些腔长组合是稳定的,哪些会进入非稳区。对于热透镜效应明显的激光器,晶体热焦距会改变实际 g 参数,所以稳定区会漂移。仿真时要把热透镜等效成一个可变焦距的薄透镜,放在晶体位置,然后重新计算 g 参数。
常见做法是:先固定 R1、R2,扫描 L 从 0.1 m 到 1 m,步长 1 mm,计算 g1*g2,找出乘积在 0 到 1 之间的区间。再在这个区间里选一个 L,计算腔内光斑半径分布,看晶体位置的光斑是否合适。如果光斑太小,功率密度太高,容易损伤;太大则模式匹配不好。这些判断在代码里就是几行循环和条件判断。
3.2 行波腔与驻波腔的仿真差异
行波腔(环形腔)光只朝一个方向走,没有驻波,所以不存在空间烧孔,适合需要单频输出的场合。仿真时,行波腔的 ABCD 矩阵是单向绕一圈,总矩阵作用后 q 参数要满足自再现条件:q = (Aq + B)/(Cq + D)。这等价于解一个二次方程,代码里可以用roots求。驻波腔则是往返一圈,总矩阵是 M_back * M_forward,然后同样要求自再现。两者的稳定性判据形式类似,但行波腔的 g 参数定义不同,通常用总矩阵的迹来判断:|(A+D)/2| < 1 稳定。
代码包里一般会分别提供design_standing_wave_cavity和design_traveling_wave_cavity两个入口。你输入镜片曲率、腔长、晶体热透镜焦距,它返回稳定区、光斑半径、束腰位置。对于行波腔,还要注意像散补偿,因为曲面镜斜入射会引入像散,需要两个方向的 q 参数分开算。这部分在代码里通常用两个独立的 ABCD 矩阵链处理。
3.3 参数扫描与结果可视化
仿真最大的价值是快速扫描参数。下面这段代码演示扫描腔长 L,计算驻波腔的稳定性因子和晶体处光斑半径。
R1 = 0.5; R2 = 0.5; % 镜片曲率半径 500 mm L_vec = linspace(0.1, 0.9, 200); w_crystal = zeros(size(L_vec)); stability = zeros(size(L_vec)); for idx = 1:length(L_vec) L = L_vec(idx); g1 = 1 - L/R1; g2 = 1 - L/R2; stability(idx) = g1 * g2; % 简化:假设晶体在腔中心,用 ABCD 计算光斑 M = [1 L/2; 0 1] * [1 0; -2/R1 1] * [1 L/2; 0 1]; q_in = 1i * pi * (0.3e-3)^2 / 1064e-9; % 假设束腰 0.3 mm q_out = (M(1,1)*q_in + M(1,2)) / (M(2,1)*q_in + M(2,2)); w_crystal(idx) = sqrt(-1064e-9 / (pi * imag(1/q_out))); end plot(L_vec, stability, 'b-', L_vec, w_crystal*1e3, 'r--'); xlabel('腔长 L (m)'); legend('g1*g2', '晶体处光斑半径 (mm)'); grid on;逻辑说明:循环改变 L,计算 g1*g2 和晶体处光斑。参数说明:R1、R2 是镜片曲率,L_vec 是腔长扫描范围,w_crystal 存储光斑半径。注意这里用了简化光路,实际代码包里会更精确地处理晶体位置和热透镜。你可以把w_crystal换成任意位置的光斑,只要改 ABCD 矩阵链。扫描结果如果发现稳定区很窄,说明腔型对腔长敏感,实验调节难度大,需要换镜片曲率。
4. 热效应分析与非线性频率变换:仿真里怎么塞进这些物理
4.1 热透镜效应的等效与参数设置
激光晶体吸收泵浦光后温度升高,折射率变化和端面形变共同作用,等效成一个焦距可变的薄透镜。热透镜焦距 f_th 与泵浦功率、晶体材料、冷却条件有关。常见做法是用经验公式:f_th = K / (P_abs * (dn/dT + alpha * n^3)),其中 K 是几何因子,P_abs 是吸收功率,dn/dT 是热光系数,alpha 是热膨胀系数。代码包里一般会提供一个thermal_lens_focal_length函数,输入泵浦功率和材料参数,返回 f_th。然后把这个 f_th 作为薄透镜插入 ABCD 矩阵链,重新计算腔的稳定性和光斑。
参数设置要注意:dn/dT 对 Nd:YAG 约 7.3e-6 /K,对 Yb:YAG 约 9e-6 /K,热膨胀系数约 7e-6 /K。这些数值不同材料差异大,代码包里通常用结构体存材料参数,你选材料就行。如果仿真结果和实验对不上,优先检查泵浦吸收功率是否算错,以及冷却是否理想。热透镜是动态的,泵浦功率一变,稳定区就漂,所以实际激光器要设计在热透镜变化范围内仍能稳定的腔型。
4.2 非线性频率变换的仿真思路
倍频、和频、差频这些非线性过程,仿真时通常用耦合波方程。代码包里可能提供shg_efficiency函数,输入基频光功率、晶体长度、非线性系数、相位匹配条件,返回倍频光功率。简化模型下,倍频效率 eta = tanh^2( sqrt(eta_0) ),其中 eta_0 是小信号转换效率,与功率密度和晶体长度平方成正比。你可以扫描基频光斑半径,看效率怎么变。光斑太小,功率密度高但走离效应严重;光斑太大,功率密度不够。仿真能帮你找最佳光斑。
常见做法是:先算基频光在晶体中的光斑半径,然后算功率密度,再算小信号效率,最后用 tanh^2 修正。代码里就是几个公式。注意相位匹配温度、角度这些参数要按实际晶体写。如果仿真效率远高于实验,检查是否忽略了走离、吸收、热退相位。
4.3 光束调节与匹配算法
光束匹配就是让入射光斑和腔模光斑在镜片上重合。代码包里一般有mode_matching函数,输入入射光束 q 参数和腔模 q 参数,返回需要的透镜焦距和位置。算法是:用两个透镜组成望远镜系统,改变光斑大小和曲率,使入射 q 变换后等于腔模 q。你可以用优化函数fminsearch找透镜位置和焦距。实际调节时,先按仿真值摆个大概,再用红外卡或相机细调。仿真能省掉盲目试的时间,但不能代替实际调节,因为镜片厚度、像差、装调误差都会影响。
5. 避坑与排查:仿真跑通但实验对不上时先查这几条
5.1 光斑半径算出来是虚数
现象:sqrt(-lambda/(pi*imag(1/q)))报错或结果为虚数。原因:q 参数的虚部符号不对,或者光束不是标准高斯光束。解决:检查初始 q 是否设为1i*zR,传播矩阵是否按顺序乘。如果 q 的虚部变成正数,说明光束已经发散到不满足近轴近似,或者矩阵有误。把每一步的 q 打印出来,看虚部是否始终为负。
5.2 稳定区扫描结果和教科书对不上
现象:g1*g2 曲线形状奇怪,稳定区位置偏移。原因:腔长定义搞错,比如把镜片间距当成光程,或者镜片曲率符号弄反。解决:确认 L 是两镜间距,R 正负按凹面镜为正、凸面镜为负的约定。代码包里通常有注释说明符号约定,别自己改。另外,如果腔内有介质,光程要除以折射率。
5.3 热透镜焦距设了但稳定区没变化
现象:改了泵浦功率,稳定区图没动。原因:热透镜没有插入 ABCD 矩阵链,或者插入位置不对。解决:检查thermal_lens_focal_length的输出是否传给了矩阵生成函数,以及透镜矩阵是否放在晶体位置。常见错误是把热透镜放在腔镜上,那当然不影响。
5.4 倍频效率仿真值高得离谱
现象:算出来效率 90%,实验只有 10%。原因:忽略了走离效应、吸收损耗、相位匹配带宽。解决:在代码里加走离长度修正,或者把效率乘以一个经验因子。更靠谱的做法是用耦合波方程数值求解,而不是 tanh^2 近似。如果代码包只提供近似,自己补一个损耗项。
5.5 MATLAB 版本兼容性导致函数报错
现象:在 MATLAB 2023b 能跑,在 2026b 报错。原因:某些函数行为变了,或者中文注释乱码导致解析错误。解决:把脚本保存为 UTF-8 编码,避免用中文变量名。如果用到movfile、parallel等函数,检查新版本是否改了参数。代码包里一般会写最低版本要求,别用太老的版本跑新代码。
6. 进阶技巧:用参数扫描和优化函数把腔型设计变成自动搜索
前面几章把单个模块跑通了,但实际设计腔型时,你面对的是多维参数空间:镜片曲率、腔长、晶体位置、热透镜焦距。手动一个个试太慢,我一般会写一个目标函数,用fminsearch或ga自动找最优。目标可以是最小化晶体处光斑半径的波动,或者最大化稳定区宽度。下面是一个示例:固定 R1、R2,优化 L 和晶体位置 x_c,使晶体处光斑在热透镜变化范围内尽量平稳。
function cost = cavity_cost(params) L = params(1); x_c = params(2); R1 = 0.5; R2 = 0.5; f_th_vec = [0.2, 0.3, 0.5]; % 热透镜焦距变化范围 w_vec = zeros(size(f_th_vec)); for k = 1:length(f_th_vec) f_th = f_th_vec(k); % 构建 ABCD 矩阵链:M1 - 自由空间 x_c - 热透镜 - 自由空间 L-x_c - M2 M = [1 x_c; 0 1] * [1 0; -1/f_th 1] * [1 L-x_c; 0 1] * [1 0; -2/R2 1]; q_in = 1i * pi * (0.3e-3)^2 / 1064e-9; q_out = (M(1,1)*q_in + M(1,2)) / (M(2,1)*q_in + M(2,2)); w_vec(k) = sqrt(-1064e-9 / (pi * imag(1/q_out))); end cost = std(w_vec); % 光斑波动越小越好 end % 优化 params0 = [0.4, 0.2]; params_opt = fminsearch(@cavity_cost, params0); fprintf('最优腔长: %.3f m, 晶体位置: %.3f m\n', params_opt(1), params_opt(2));逻辑说明:目标函数计算不同热透镜焦距下的晶体处光斑,取标准差作为代价。fminsearch从初始值开始搜索,找到使光斑波动最小的 L 和 x_c。参数说明:params0是初始猜测,f_th_vec是热透镜变化范围,根据你的泵浦功率范围设定。这个技巧能帮你找到对热透镜不敏感的腔型,实验上更稳。注意优化结果要检查物理合理性,比如 L 不能小于 x_c,镜片不能打架。
我自己的习惯是:先用扫描看大致趋势,再用优化找精确值,最后把优化结果代回扫描图确认。仿真不能保证实验一次成功,但能让你少走很多弯路。希望帮到你。
本文还有配套的精品资源,点击获取