MATLAB实战:贝塞尔高斯光束自由传输仿真全流程(附完整代码)

MATLAB实战:贝塞尔高斯光束自由传输仿真全流程(附完整代码) MATLAB实战贝塞尔高斯光束自由传输仿真全流程附完整代码光学仿真在现代科研和工程应用中扮演着越来越重要的角色。贝塞尔高斯光束作为一种特殊的光束类型因其在自由空间中传输时横截面强度分布保持不变的特性在激光加工、光学捕获和生物医学成像等领域有着广泛应用。本文将带你从零开始在MATLAB中完整实现贝塞尔高斯光束的自由传输仿真不仅包含核心代码实现还会深入解析每个步骤背后的物理意义和数学原理。1. 贝塞尔高斯光束基础与仿真准备贝塞尔高斯光束是贝塞尔函数与高斯函数的乘积所描述的光场分布。这种光束最显著的特点是无衍射特性——在一定传播距离内其横向强度分布几乎不发生变化。这种特性源于贝塞尔函数的数学性质使其在需要长距离稳定传输的应用场景中极具价值。1.1 仿真环境配置在开始仿真前我们需要确保MATLAB环境已准备就绪% 检查必要工具箱是否安装 if ~license(test,Image_Toolbox) error(需要安装Image Processing Toolbox以支持图像处理功能); end % 清空工作区并关闭所有图形窗口 clear; close all; clc;推荐配置MATLAB R2020b或更高版本Image Processing Toolbox用于结果可视化至少8GB内存处理大型矩阵时更流畅1.2 关键物理参数设置光束仿真的准确性很大程度上取决于参数设置的合理性。以下是需要定义的核心参数参数名称符号示例值单位物理意义波长λ632.8e-9m激光波长初始束腰半径w₀0.1e-3m光束最窄处的半径传播距离z_final2m仿真终止位置计算区域大小L4*w₀m模拟区域的边长网格点数N512-空间分辨率% 基本参数设置 lambda 632.8e-9; % 波长 [m] w0 0.1e-3; % 初始束腰半径 [m] z_final 2; % 最终传播距离 [m] L 4*w0; % 计算区域大小 [m] N 512; % 网格点数2. 初始光场构建与可视化2.1 空间坐标系统建立建立合适的坐标系是光场计算的基础。我们采用笛卡尔坐标系并在横向(x,y)平面上进行离散化% 创建空间坐标网格 x linspace(-L/2, L/2, N); y x; [X,Y] meshgrid(x,y); [~, r] cart2pol(X,Y); % 转换为极坐标计算径向距离提示网格点数N的选择需要在计算精度和内存消耗之间取得平衡。对于大多数应用512×512的网格已经足够。2.2 贝塞尔高斯光束数学表达贝塞尔高斯光束的复振幅可以表示为U(r,z0) Jₙ(αr) * exp(-r²/w₀²)其中Jₙ为n阶贝塞尔函数本文使用0阶α为与光束特性相关的参数w₀为高斯部分的束腰半径% 贝塞尔高斯光束参数 n 0; % 贝塞尔函数阶数 alpha 2.405/w0; % 第一个零点的位置参数 % 初始光场计算 J0 besselj(n, alpha*r); % 0阶贝塞尔函数 Gaussian exp(-(X.^2 Y.^2)/w0^2); % 高斯包络 U0 J0 .* Gaussian; % 初始光场2.3 初始光场可视化直观展示初始光场有助于验证参数设置的合理性figure(Name,初始光场分布,Position,[100 100 800 400]) subplot(1,2,1) imagesc(x,y,abs(U0).^2); title(强度分布); xlabel(x [m]); ylabel(y [m]); axis square; colormap(hot); colorbar; subplot(1,2,2) plot(x,abs(U0(N/2,:)).^2); title(横向强度剖面); xlabel(x [m]); ylabel(强度); grid on;3. 自由空间传输模拟3.1 角谱传播理论光束传播的核心是解决亥姆霍兹方程。我们采用角谱法进行数值模拟其基本原理是对初始光场进行二维傅里叶变换得到角谱乘以传播相位因子exp(ikₓz)进行逆傅里叶变换得到传播后的光场传播相位因子为H(fₓ,f_y) exp(i2πz√(1/λ² - fₓ² - f_y²))% 频率空间坐标设置 df 1/L; % 频率分辨率 fx (-N/2:N/2-1)*df; % 空间频率坐标 [FX,FY] meshgrid(fx,fx); % 角谱传播函数 k 2*pi/lambda; % 波数 H (z) exp(1i*2*pi*z*sqrt((1/lambda)^2 - FX.^2 - FY.^2));3.2 分步传播实现为实现稳定传播并观察光束演化我们采用分步传播策略% 传播参数设置 dz z_final/100; % 传播步长 z 0:dz:z_final; % 传播距离数组 % 初始化传播过程存储 U U0; % 初始光场 U_prop zeros(N,N,length(z)); % 存储各位置光场 U_prop(:,:,1) U0; % 存储初始光场 % 角谱传播主循环 for iz 2:length(z) % 当前传播距离 current_z z(iz); % 傅里叶变换得到角谱 U_hat fft2(U); % 应用传播相位因子 U_hat U_hat .* fftshift(H(dz)); % 逆傅里叶变换得到传播后光场 U ifft2(U_hat); % 存储当前光场 U_prop(:,:,iz) U; end注意实际编程中应使用fftshift和ifftshift确保频率分量正确排列上述代码已做简化处理。4. 结果分析与可视化4.1 传播过程动态展示创建动态图展示光束随传播距离的演变figure(Name,光束传播动态,Position,[100 100 800 600]) for iz 1:5:length(z) imagesc(x,y,abs(U_prop(:,:,iz)).^2); title([传播距离 z ,num2str(z(iz),%.2f), m]); xlabel(x [m]); ylabel(y [m]); axis square; colormap(hot); colorbar; drawnow; end4.2 关键位置强度分布对比选取几个特征位置进行详细对比分析z_select [0 0.5 1 2]; % 选择的传播距离[m] idx round(z_select/dz) 1; figure(Name,不同传播距离强度分布,Position,[100 100 1200 400]) for i 1:length(idx) subplot(1,length(idx),i) imagesc(x,y,abs(U_prop(:,:,idx(i))).^2); title([z ,num2str(z_select(i)), m]); axis square; colormap(hot); colorbar; end4.3 光束宽度变化分析定量分析光束宽度随传播距离的变化% 计算各位置光束半径 beam_radius zeros(size(z)); for iz 1:length(z) I abs(U_prop(:,:,iz)).^2; [~,max_idx] max(I(:)); [row,col] ind2sub(size(I),max_idx); r_profile sqrt((X-X(row,col)).^2 (Y-Y(row,col)).^2); beam_radius(iz) sqrt(sum(sum(r_profile.^2.*I))/sum(sum(I))); end % 绘制光束半径变化曲线 figure plot(z,beam_radius*1e3,LineWidth,2); xlabel(传播距离 z [m]); ylabel(光束半径 [mm]); title(光束半径随传播距离变化); grid on;5. 完整代码与优化建议5.1 完整仿真代码整合function bessel_gauss_beam_propagation() % 参数设置 lambda 632.8e-9; % 波长 [m] w0 0.1e-3; % 初始束腰半径 [m] z_final 2; % 最终传播距离 [m] L 4*w0; % 计算区域大小 [m] N 512; % 网格点数 n 0; % 贝塞尔函数阶数 % 空间坐标 x linspace(-L/2, L/2, N); y x; [X,Y] meshgrid(x,y); [~, r] cart2pol(X,Y); % 初始光场 alpha 2.405/w0; J0 besselj(n, alpha*r); Gaussian exp(-(X.^2 Y.^2)/w0^2); U0 J0 .* Gaussian; % 角谱传播设置 df 1/L; fx (-N/2:N/2-1)*df; [FX,FY] meshgrid(fx,fx); k 2*pi/lambda; H (z) exp(1i*2*pi*z*sqrt((1/lambda)^2 - FX.^2 - FY.^2)); % 传播参数 dz z_final/100; z 0:dz:z_final; U U0; U_prop zeros(N,N,length(z)); U_prop(:,:,1) U0; % 传播循环 for iz 2:length(z) U_hat fft2(U); U_hat U_hat .* fftshift(H(dz)); U ifft2(U_hat); U_prop(:,:,iz) U; end % 可视化 figure(Name,光束传播结果,Position,[100 100 1200 500]) z_show [0 0.5 1 2]; idx round(z_show/dz) 1; for i 1:length(z_show) subplot(2,length(z_show),i) imagesc(x,y,abs(U_prop(:,:,idx(i))).^2); title([z ,num2str(z_show(i)), m]); axis square; colormap(hot); colorbar; subplot(2,length(z_show),ilength(z_show)) plot(x,abs(U_prop(N/2,:,idx(i))).^2); xlabel(x [m]); ylabel(强度); grid on; end end5.2 性能优化技巧内存管理对于长距离传播考虑每隔一定步长存储结果而非每一步使用single精度而非double可减少内存占用计算加速% 启用多线程计算 if exist(maxNumCompThreads,file) maxNumCompThreads(automatic); end % 使用GPU加速需Parallel Computing Toolbox if gpuDeviceCount 0 U0 gpuArray(U0); FX gpuArray(FX); FY gpuArray(FY); end参数扫描自动化% 自动扫描不同alpha参数 alpha_range linspace(1,5,5)/w0; results cell(length(alpha_range),1); for ia 1:length(alpha_range) % 修改alpha值后重新运行仿真 % 存储结果到results{ia} end在实际项目中我发现将传播过程封装为独立函数可以大大提高代码复用率。例如将角谱传播部分单独封装后可以轻松应用于其他类型光束的传播仿真。此外对于需要长时间运行的仿真添加进度显示功能会极大改善用户体验% 添加进度条 hWait waitbar(0,正在计算传播过程...); for iz 2:length(z) % ...传播计算代码... waitbar(iz/length(z),hWait); end close(hWait);