Mathematica衍射图案生成咨询:复现指定远场衍射效果
在Mathematica中复现远场径向衍射强度图
核心前提说明
假设你第一张图中的方程是夫琅禾费圆孔衍射(最常见的径向远场衍射场景),其远场强度分布由艾里函数描述,这是解析解,比直接用NIntegrate更高效且准确。如果你的原始方程是积分形式,也可以通过优化积分参数来求解。
方案1:用解析解快速实现(推荐)
远场强度的解析表达式为:
$$I(r) = I_0 \left( \frac{2 J_1\left( \frac{2\pi a r}{\lambda R} \right)}{\frac{2\pi a r}{\lambda R}} \right)^2$$
其中:
- $I_0$:中心强度(归一化后可设为1)
- $a$:衍射孔径半径
- $\lambda$:入射光波长
- $R$:观察屏到孔径的远场距离(满足 $R \gg a^2/\lambda$)
- $r$:观察屏径向位置
Mathematica代码
(* 参数配置 *) I0 = 1; a = 0.001; (* 孔径半径,单位米 *) R = 1; (* 远场距离,单位米 *) λList = {400*10^-9, 550*10^-9, 700*10^-9}; (* 蓝、绿、红三种波长 *) (* 定义强度函数,处理r=0的奇点 *) I[r_, λ_] := If[r == 0, I0, I0*(2 BesselJ[1, (2 π a r)/(λ R)] / ((2 π a r)/(λ R)))^2] (* 绘制多波长对比图 *) Plot[Evaluate[I[r, #] & /@ λList], {r, 0, 5*10^-3}, PlotLegends -> Placed[Map[ToString[#*10^9] <> " nm" &, λList], Right], AxesLabel -> {"径向位置 r (m)", "相对强度 I/I0"}, PlotRange -> All, BaseStyle -> {FontSize -> 12}]
方案2:用NIntegrate求解原始积分方程
如果你的原始方程是菲涅耳衍射的积分形式(远场下可简化为夫琅禾费近似),积分式为:
$$U(r) = \frac{e^{ikR}}{iλR} \int_0^a \int_0^{2π} e^{ik \frac{ρ r \cosφ}{R}} ρ dρ dφ$$
强度 $I(r) = |U(r)|^2$
优化后的NIntegrate实现
(* 参数同方案1 *) I0 = 1; a = 0.001; R = 1; λList = {400*10^-9, 550*10^-9, 700*10^-9}; (* 定义波数 *) k[λ_] := 2 π / λ (* 复振幅积分,设置精度参数避免求解失败 *) U[r_, λ_] := (Exp[I k[λ] R]/(I λ R)) * NIntegrate[ρ Exp[I k[λ] (ρ r Cos[φ])/R], {ρ, 0, a}, {φ, 0, 2 π}, PrecisionGoal -> 6, WorkingPrecision -> 15, MaxRecursion -> 20] (* 计算强度,归一化到中心强度 *) IIntegrated[r_, λ_] := Abs[U[r, λ]]^2 / Abs[U[0, λ]]^2 (* 绘图 *) Plot[Evaluate[IIntegrated[r, #] & /@ λList], {r, 0, 5*10^-3}, PlotLegends -> Placed[Map[ToString[#*10^9] <> " nm" &, λList], Right], AxesLabel -> {"径向位置 r (m)", "相对强度 I/I0"}, PlotRange -> All, BaseStyle -> {FontSize -> 12}]
解决NIntegrate失败的关键:
- 精度控制:添加
PrecisionGoal、WorkingPrecision和MaxRecursion参数,避免数值计算中出现精度不足或递归次数不够的问题 - 奇点处理:r=0时单独计算中心强度,用于归一化
- 极坐标权重:积分时不要遗漏极坐标下的$\rho$权重项,这是很多人用NIntegrate出错的原因
- 远场近似:确保$R$满足远场条件,否则积分结果会偏离夫琅禾费衍射图案
如果你的原始方程是其他孔径(如环形、矩形),只需修改解析函数或积分范围即可。例如环形孔径的强度为内外半径对应的艾里函数差值的平方。
内容的提问来源于stack exchange,提问作者SGoo
相关产品推荐
相关产品推荐

