利用 FFT 模拟菲涅尔衍射积分

利用 FFT 模拟菲涅尔衍射积分

一束光线穿过一个孔径为 S ′ S' S 的平面,在距离平面为 L L L 的时候,其波函数可以由菲涅尔积分定义:

Ψ ( r , t ) = C ∫ S ′ e i k ∣ r − r ′ ∣ ∣ r − r ′ ∣ cos ⁡ ( θ ) d 2 r ′ , w i t h C = k Ψ 0 e − i t w 2 π i \Psi(\mathbf{r}, t) = C \int_{S'} \frac{e^{ik|r-r'|}}{|r-r'|} \cos(\theta)d^2r', \quad with \quad C = \frac{k \Psi_{0} e^{-itw}}{2 \pi i} Ψ(r,t)=CSrreikrrcos(θ)d2r,withC=2πikΨ0eitw

基于菲涅尔近似,在角度接近 0 度的时候,上式可以简化为:

∣ r − r ′ ∣ ≈ z + ( x − x ′ ) 2 + ( y − y ′ ) 2 2 z |r - r'| \approx z + \frac{(x - x')^2 + (y - y')^2}{2z} rrz+2z(xx)2+(yy)2

并且可以假设:

∣ r − r ′ ∣ ≈ L |r - r'| \approx L rrL

菲涅尔积分可以变成:

Ψ ( r , t ) = R ∫ − ∞ ∞ ∫ − ∞ ∞ f ( x ′ , y ′ ) e i k 2 z ( x ′ 2 + y ′ 2 ) e − i k x z x ′ − i k y z y ′ d x ′ d y ′ \Psi(\mathbf{r}, t) = R \int_{-\infty}^{\infty} \int_{-\infty}^{\infty} f(x', y') e^{\frac{ik}{2z}(x'^2 + y'^2)} e^{-\frac{ikx}{z}x'-\frac{iky}{z}y'} dx'dy' Ψ(r,t)=Rf(x,y)e2zik(x2+y2)ezikxxzikyydxdy

w i t h R = k Ψ 0 e i ( k z − t w ) 2 π i z e i k x 2 + y 2 2 z with \quad R = \frac{k \Psi_{0} e^{i(kz - tw)}}{2 \pi i z} e^{ik \frac{x^2 + y^2}{2z}} withR=2πizkΨ0ei(kztw)eik2zx2+y2

f ( x ′ , y ′ ) = { 1  if  ( x ′ , y ′ ) ∈ S ′ 0  if  ( x ′ , y ′ ) ∉ S ′ f(x', y') = \begin{cases} 1 & \text{ if } (x', y')\in S' \\ 0 & \text{ if } (x', y')\notin S' \end{cases} f(x,y)={10 if (x,y)S if (x,y)/S

上式可以转换成傅里叶变换的形式:

Ψ ( r , t ) = R ⋅ F [ f ( x ′ , y ′ ) e i k 2 z ( x ′ 2 + y ′ 2 ) ] \Psi(\mathbf{r}, t) = R \cdot \mathcal{F}[f(x', y') e^{\frac{ik}{2z}(x'^2 + y'^2)}] Ψ(r,t)=RF[f(x,y)e2zik(x2+y2)]

F [ f ( x ′ , y ′ ) e i k 2 z ( x ′ 2 + y ′ 2 ) ] = ∫ − ∞ ∞ ∫ − ∞ ∞ f ( x ′ , y ′ ) e i k 2 z ( x ′ 2 + y ′ 2 ) e − i k x z x ′ − i k y z y ′ d x ′ d y ′ \mathcal{F}[f(x', y') e^{\frac{ik}{2z}(x'^2 + y'^2)}] = \int_{-\infty}^{\infty} \int_{-\infty}^{\infty} f(x', y') e^{\frac{ik}{2z}(x'^2 + y'^2)} e^{-\frac{ikx}{z}x'-\frac{iky}{z}y'} dx'dy' F[f(x,y)e2zik(x2+y2)]=f(x,y)e2zik(x2+y2)ezikxxzikyydxdy

为了便于计算,我们可以将连续域内的 ( x ′ , y ′ ) (x', y') (x,y) 进行离散化,比如,可以将 ( x ′ , y ′ ) ∈ [ − L x , L x ] × [ − L y , L y ] (x', y') \in [-L_x, L_x] \times [-L_y, L_y] (x,y)[Lx,Lx]×[Ly,Ly] 划分成等间距的 N x , N y N_x, N_y Nx,Ny 份:

x n x ′ = { − L x + n x 2 L x N x , 0 ≤ n x ≤ N x − 1 } x'_{n_x} = \left \{ -L_x + n_x \frac{2L_x}{N_x}, \quad 0 \leq n_x \leq N_x -1 \right \} xnx={Lx+nxNx2Lx,0nxNx1}

y n y ′ = { − L y + n y 2 L y N y , 0 ≤ n y ≤ N y − 1 } y'_{n_y} = \left \{ -L_y + n_y \frac{2L_y}{N_y}, \quad 0 \leq n_y \leq N_y -1 \right \} yny={Ly+nyNy2Ly,0nyNy1}

接下来,就可以定义离散傅里叶变换:

G ( u x , u y ) = ∑ n x = 0 N x − 1 ∑ n y = 0 N y − 1 g ( x n x ′ , y n y ′ ) e − i 2 π u x n x N x − i 2 π u y n y N y G(u_x, u_y) = \sum_{n_x = 0}^{N_x -1} \sum_{n_y =0}^{N_y -1} g(x'_{n_x}, y'_{n_y})e^{-i2\pi u_x \frac{n_x}{N_x} - i 2 \pi u_y \frac{n_y}{N_y} } G(ux,uy)=nx=0Nx1ny=0Ny1g(xnx,yny)ei2πuxNxnxi2πuyNyny

在距离为 L 的平面上,

x u x = ( u x − N x / 2 ) L λ 2 L x x_{u_x} = \frac{(u_x - N_x / 2)L \lambda}{2 L_x} xux=2Lx(uxNx/2)Lλ

y u x = ( u y − N y / 2 ) L λ 2 L y y_{u_x} = \frac{ (u_y - N_y / 2)L \lambda}{ 2 L_y} yux=2Ly(uyNy/2)Lλ


### 代码转载自:
##  https://rafael-fuente.github.io/solving-the-diffraction-integral-with-the-fast-fourier-transform-fft-and-python.html

import numpy as np
import matplotlib.pyplot as plt

class Sheet():
    def __init__(self,extentX, extentY, Nx, Ny):
        self.x = np.linspace(extentX[0],extentX[1],Nx)
        self.y = np.linspace(extentY[0],extentY[1],Ny)
        self.xx,self.yy = np.meshgrid(self.x, self.y)

        self.Nx = int(Nx)
        self.Ny = int(Ny)
        self.f = np.zeros((int(self.Ny), int(self.Nx)))

    def rectangular_slit(self,x0, y0, lx, ly):
        """
        Creates a slit centered at the point (x0, y0) with width lx and height ly
        """
        self.f += np.select( [((self.xx > (x0 - lx/2) ) & (self.xx < (x0 + lx/2) )) & ((self.yy > (y0 - ly/2) ) & (self.yy < (y0 + ly/2) )),  True], [1, 0])
        
Lx = 1.4
Ly = 0.4

Nx= 2500
Ny= 1500

sheet = Sheet(extentX = [-Lx, Lx] , extentY = [-Ly, Ly], Nx= Nx, Ny= Ny)

#slit separation 
mm = 1e-3
D = 500 * mm

sheet.rectangular_slit(x0 = -D/2, y0 = 0, lx = 22 * mm , ly = 88 * mm)
sheet.rectangular_slit(x0 = +D/2, y0 = 0, lx = 22 * mm , ly = 88 * mm)


# distance from slit to the screen (mm)
z = 5000

# wavelength (mm)
λ = 18.5*1e-7
k = 2*np.pi/λ

fft_c = np.fft.fft2(sheet.f * np.exp(1j * k/(2*z) *(sheet.xx**2 + sheet.yy**2)))
c = np.fft.fftshift(fft_c)

fig = plt.figure(figsize=(6, 6))
ax1 = fig.add_subplot(2,1,1)  
ax2 = fig.add_subplot(2,1,2,sharex=ax1, yticklabels=[])

abs_c = np.absolute(c)

#screen size mm
Lx_screen = Nx*z*λ/(4*Lx)
Ly_screen = Ny*z*λ/(4*Ly)

x_max = (np.pi/Lx * (Nx//2 - 1))*z*λ/(2*np.pi)
y_max = (np.pi/Ly * (Ny//2 - 1))*z*λ/(2*np.pi)

ax1.imshow(abs_c, extent = [-Lx_screen, Lx_screen, -Ly_screen,Ly_screen], cmap ='gray', interpolation = "bilinear", aspect = 'auto')

ax2.plot(np.linspace(-Lx_screen,Lx_screen, len(abs_c[0])), abs_c[len(abs_c)//2]**2)

ax1.set_ylabel("y (mm)")
ax2.set_xlabel("x (mm)")
ax2.set_ylabel("Probability Density $|\psi|^{2}$")
ax1.set_xlim([-2,2])
ax2.set_xlim([-2,2])
ax1.set_ylim([-1,1])
plt.setp(ax1.get_xticklabels(), visible=False)
plt.show()

在这里插入图片描述

在这里插入图片描述

参考文献:
https://rafael-fuente.github.io/solving-the-diffraction-integral-with-the-fast-fourier-transform-fft-and-python.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值