Python光学仿真:基于Huygens-Fresnel原理的衍射算法实现与优化

巷口听风
巷口听风
发布时间:2026-10-14| 6人浏览过
原创

本文深入解析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光学仿真及衍射算法的相关内容,请持续关注本站发布的其他技术文章。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。