Python光学仿真:基于Huygens-Fresnel原理的衍射算法实现与优化
本文深入解析Python光学仿真中的衍射算法,基于Huygens-Fresnel原理,将方形孔细分为n×n网格进行子波干涉计算。文章详细推导了考虑球面波衰减与倾斜因子的光强公式,并展示了如何通过矩阵运算优化基尔霍夫衍射代码,提升计算效率,为傅里叶光学仿真奠定基础。
Huygens-Fresnel原理与离散化模型
对于衍射现象,最经典的解释源于Huygens-Fresnel原理。该原理指出,波阵面上的每一点均可视为新的波源,发出子波,这些子波在空间中的相互干涉叠加便构成了衍射图样。这种将连续波前离散化为无数点源的观点,在逻辑上非常契合程序员的思维方式。
以光线照射方形孔为例,若将该方形孔划分为n×n个细密网格,则每个网格单元可近似看作一个小孔。这些小孔发出的子波相互干涉,即形成了衍射效应。随着网格细分程度的增加,这种离散近似能越来越逼近真实的物理衍射情形。假设矩孔处为等相位面,其网格坐标记为(i,j),矩孔到衍射屏的距离为d。对于衍射屏上任意一点P(x,y),其光强分布可通过叠加所有网格点的贡献来计算。

球面波衰减与倾斜因子修正
然而,前述基于平面矩孔的光强叠加模型存在缺陷。若假设矩孔上每个格点均为点光源,则光传播至衍射屏时应遵循球面波的衰减规律。此外,原模型忽略了从光源到矩孔过程中光线的传播方向差异,因此需要引入一个倾斜因子来修正。具体而言,坐标(i,j)处的点对衍射屏上(x,y)点的光强贡献应包含这一方向性修正。

基尔霍夫衍射的Python实现
#基尔霍夫衍射,衍射屏坐标范围-dGrid:dGrid,光源坐标(0,0)
#简单的矩孔衍射,dSource为光源到小孔的距离;dScreen为衍射屏到小孔距离
#dHole为矩孔网格尺寸;dGrid为衍射屏网格尺寸;nGrid为网格数目
def squareDiff(dSource=1,dScreen=1.4,dWave=1e-6,
dHole=3e-5,nGrid=100,dGrid=1e-5):
nX,nY = nGrid*np.array([1,1])
axisX = np.arange(-nX,nX+1)*dGrid
axisY = np.arange(-nY,nY+1)*dGrid
xAxis,yAxis = np.meshgrid(axisX,axisY) #此为衍射屏的x坐标
axisX = np.arange(-nX,nX+1)*dHole
axisY = np.arange(-nY,nY+1)*dHole
xHole,yHole = np.meshgrid(axisX,axisY) #此为矩孔的x坐标
dArrS = np.sqrt(xHole**2+yHole**2+dSource**2) #孔平面到光源的距离
nSide = int(nGrid*2+1) #格点个数
pane = np.zeros([nSide,nSide]) #衍射屏强度
for m in range(nSide):
for n in range(nSide):
dArr = np.sqrt((xHole-xAxis[m,n])**2+(yHole-yAxis[m,n])**2+dScreen**2)
pane[m,n] = np.sum(
np.cos(np.pi*2*(dArr+dArrS)/dWave)/dArr/dArrS)
pane = np.abs(pane)
pane = pane/np.max(np.array(pane))
fig = plt.figure()
ax = axd(fig)
ax.plot_surface(xAxis,yAxis,pane)
plt.show()
return pane, xAxis, yAxis
经过上述修正,最终的光强计算公式如下所示。


为了便于计算机处理,我们可以定义相应的矩阵索引方式,将物理坐标映射为数组下标。
基于矩阵运算的算法优化
#输入对于M*M矩阵的第一个值到N*N矩阵的距离,返回M(m,n)的距离矩阵
def getDisMat(dMat,N,m,n):
dMat = np.mat(dMat)
A = dMat[1:m,1:n]
B = dMat[1:m,0:N-n+1]
C = dMat[0:N-m+1,1:n]
D = dMat[0:N-m+1,0:N-n+1]
return np.vstack((np.hstack((np.flip(A),np.flipud(B))),np.hstack((np.fliplr(C),D)))) #stack矩阵拼接,flip翻转矩阵
基于上述索引定义,相应的算法实现需进行相应调整(其他逻辑保持不变)。
dArrS = np.sqrt(xHole**2+yHole**2+dSource**2) #孔平面到光源的距离
dScreen = np.sqrt( #衍射平上第(0,0)个点的距离矩阵
(xHole-xAxis[0,0])**2+(yHole-yAxis[0,0])**2+dScreen**2)
nSide = int(nGrid*2+1) #格点个数
pane = np.zeros([nSide,nSide]) #衍射屏强度
for m in range(nSide):
for n in range(nSide):
dArr = getDisMat(dScreen,nSide,m,n)
尽管上述优化在一定程度上改善了计算结构,但其本质仍受限于直观的逐点计算思维,因此性能提升极为有限。这种无脑式的遍历方式带来了显著的计算负担。在后续的傅里叶光学章节中,我们将探讨更高效的衍射计算方法。
以上即为Python光学仿真中关于衍射算法的初步理解与实现细节。如需了解更多Python光学仿真及衍射算法的相关内容,请持续关注本站发布的其他技术文章。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













