Fresnel 회절 적분은 convolution form 형태로 평가되는데
U(x2,y2)=U(x1,y1)∗[iλ△zeik△z ei2△zk(x12+y12)]
U(r2)=U(r1) ∗[iλ△zeik△zei2△zkr12]
2개의 FT를 이용하여 위 식 값을 결정하는데 convolution 정리를 씀.
(x1,y1)→f1→(x2,y2)
1. Fresnel 회절 적분의 angular spectrum 형태
U(r2)=F−1[f1,r2] H(f1) F[r1,f1] {U(r1)}
- H(f1) : free-space amplitude spread 함수(자유공간 전파의 transfer function)
- H(f1)=eik△ze−iπλ△z(fx12+fy12)
2. scaling 변수 도입
위의 convolution에서 eik△z를 제외, r1,r2를 사용하여 적분식에 나타낸다.
U(r2)=iλ△z1−∞∫∞U(r1) ei2△zk∣r2−r1∣2dr1
Tyler and Fried, Roberts만 scaling factor에 논의했다.
아래에서 m scaling 도입
∣r1−r2∣2=r22−2r2⋅r1+r12
=(r22+mr22−mr22)−2r2⋅r1+(r12+mr12−mr12)
=(r22+(1−m1) r22)−2r2⋅r1+[mr12+(1−m)r12]
=m[(mr2)2−2(mr2)⋅r1+r12]+(1−m1)r22+(1−m)r12
=m∣mr2−r1∣2−(m1−m) r22+(1−m)r12
이를 U(r2)에 대입
U(r2)=iλ△ze−i2△zkm1−mr22−∞∫∞U(r1) ei2△zk(1−m)r12 ei2△zkm∣mr2−r1∣2
아래를 정의하고 위 식에 대입하면
U′′(r1)=m1 U(r1)ei2△zk(1−m)r12
U(r2)=iλze−i2△zk(m1−m)r22−∞∫∞mU′′(r1)ei2△zkm∣mr2−r1∣2 dr1
scale된 좌표와 거리를 다음과 같이 정의하고
r2′=mr2
△z′=m△z
U(∙) 식에 scale된 좌표 r2=mr2′
U(mr2′)=iλze−i2△zkm(1−m)(r2′)2−∞∫∞mU′′(r1)ei2△zkm∣r2′−r1∣2dr1
△z=m△z′로 변환
U(mr2′)=iλz′e−i2△z′k(1−m)(r2′)2−∞∫∞U′′(r1)ei2△z′k∣r2′−r1∣2dr1
convolution 형태로 바꾸면
U(mr2′)=e−i2△z′k(1−m)(r2′)2−∞∫∞U′′(r1) h(r2′−r1) dr1
h(r1)=iλ△z′1ei2△z′kr12
propagation은 알려진 impulse response(amplitude spread function)를 가진 선형 시스템으로 취급할 수 있음
impulse response의 FT는 아래와 같은 amplitude transfer function이다.
F[r1,f1]h(r1)=H(f1)=e−iπλ△z′f12
convolution 정리를 사용하고, 원래의 좌표로 대체함으로써, 이 알고리즘 세부사항의 모든 detail을 유지하고 일부 단순화 가능
U′(mr2′)=F−1[f1,r2′] e−iπλ△z′f12F[r1,f1]{U′′(r1)}
U′(r2)=F−1[f1,mr2] e−iπλm△zf12F[r1,f1]{U′′(r1)}
U(r2)=e−i2△zkm(1−m)(mr2)2 F−1[f1,mr2] e−iπλm△zf12F[r1,f1]{m1U(r1)ei2△zk(1−m)r12}
=e−i2△zkm1−mr22 F−1[f1,mr2] e−iπλm△zf12 F[r1,f1]{m1U(r1) ei2△zk(1−m)r12}]
=Q[m△z−(1−m),r2] F−1[f1,mr2] Q2[−m△z,f1] F[r1,f1] Q[△z1−m,r1]{mU(r1)}
- Q[d,r]{U(r)}≡ei2kc∣r∣2 U(r)
- Q2[d,r]{U(r)}≡eiπλd∣r∣2 U(r)
angular-spectrum propagation 연산자의 표현을 가지기 때문에 grid source 평면에서 grid spacing인 δ1, spatial-frequency 평면에서 δf1, observation 평면에서 δ2를 구할 수 있다.
FT인 F[r1,f1]로부터 얻는
δf1=Nδ11
inverse FT인 F−1[f1,r2/m]로부터 얻는
δ2=Nδf1m=N(Nδ11)m=mδ1
이를 통해 일관성을 확인 또한,
1−m1=1−δ1δ21=δ1−δ2δ1
1−mm=1−δ1δ2δ1δ2=δ1−δ2δ2
3. 다른 anglular-specturm 공식을 위한 solution
∣r2−r1∣2=r22−2r2⋅r1+r12
=(r22+mr22−mr22)−2r2⋅r1+(r12+mr12−mr12)
=−mr22+(1+m1)r22−2r2⋅r1−mr12+(1+m)r12
=−mr22−2r2⋅r1−mr12+(1+m1)r22+(1+m)r12
=−m(∣mr2∣2+2(mr2)⋅r1+r12)+(1+m1)r22+(1+m)r12
=−m∣mr2+r1∣2+(m1+m)r22+(1+m)r12
m′=−m로 치환
=m′∣−m′r2+r1∣2+(−m′1−m′)r22+(1−m′)r12
=m′∣m′r2−r1∣2−(m′1−m′)r22+(1−m′)r12
여기서
m′ 대신에 m을 사용하면 원래 맨 위에 증명식하고 같아짐.
Angular-spectrum 형태의 회절을 ±m을 사용하여 구현한다면 2가지 식이 있음.
-
U(r2)=Q[m△zm−1,r2] F−1[f1,mr2] Q2[−m△z,f1]×F[r1,f1] Q[△z1−m,r1] m1{U(r1)}
-
U(r2)=Q[−m△z−m−1,r2] F−1[f1,−mr2] Q2[m△z,f1]×F[r1,f1] Q[△z1+m,r1] (m−1){U(r1)}
이를 한번에 식을 쓰면,
U(r2)=Q[m△zm±1,r2] F−1[f1,∓mr2] Q2[±m△z,f1]×F[r1,f1] Q[△z1±m,r1] (∓m1){U(r1)}
4. 코드 구현
4.1 함수 정의
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import fresnel
def ang_spec_prop(Uin, wavelength, d1, d2, distance):
k = 2*np.pi/wavelength
sc = np.arange(-N/2, N/2)*d1
x1, y1 = np.meshgrid(sc,sc);
r1sq = x1**2+y1**2
df1 = 1 / (N*d1)
fc = np.arange(-N/2, N/2)*df1
fX, fY = np.meshgrid(fc,fc)
fsq = fX**2+fY**2
m = d2/d1
oc = np.arange(-N/2, N/2)*d2
x2, y2 = np.meshgrid(oc, oc)
r2sq = x2**2+y2**2
Q1 = np.exp(1j*k*(1-m)/(2*distance) *r1sq)
Q2 = np.exp(-1j*2*np.pi**2*distance/(m*k) *fsq)
Q3 = np.exp(1j*k/2*(m-1)/(m*distance) *r2sq)
Uout = Q3*np.fft.ifft2(Q2*np.fft.fft2(Q1*Uin/m))
return x2, y2, Uout
def rect(x, a):
tmp = np.where(np.abs(x) < a/2, 1, 0)
return np.where(np.abs(tmp)==a/2, 0.5, tmp)
def fresnel_prop_square_ap(x2, y2, D1, wavelength, distance):
N_F = (D1/2)**2 / (wavelength * distance)
bigX = x2 / np.sqrt(wavelength*distance)
bigY = y2 / np.sqrt(wavelength*distance)
alpha1 = -np.sqrt(2)*(np.sqrt(N_F)+bigX)
alpha2 = np.sqrt(2)*(np.sqrt(N_F) -bigX)
beta1 = -np.sqrt(2)*(np.sqrt(N_F)+bigY)
beta2 = np.sqrt(2)*(np.sqrt(N_F)-bigY)
ca1, sa1 = fresnel(alpha1);
ca2, sa2 = fresnel(alpha2);
cb1, sb1 = fresnel(beta1);
cb2, sb2 = fresnel(beta2);
U = 1/(2*1j)*((ca2-ca1)+1j*(sa2-sa1))*((cb2-cb1)+1j*(sb2-sb1))
return U
4.2 전파 시뮬레이션
N=1024
L=1e-2
delta1 = L/N
D = 2e-3
wavelength = 1e-6
k = 2*np.pi / wavelength
distance = 1
sc = np.arange(-N/2, N/2)*delta1
x1, y1 = np.meshgrid(sc,sc)
aperture = rect(x1,D)*rect(y1,D)
delta2 = wavelength * distance / (N*delta1)
x2, y2, Uout = ang_spec_prop(aperture, wavelength, delta1, delta2, distance)
Uout_an = fresnel_prop_square_ap(x2[int(N/2)+1], 0, D, wavelength, distance)
Uout_an2 = fresnel_prop_square_ap(x2, y2, D, wavelength, distance)
Uout_shift = np.fft.fftshift(Uout)
plt.figure(figsize=(18,4))
plt.subplot(1,3,1)
plt.imshow(np.abs(aperture), cmap='gray', extent=(x1.min(),x1.max(), y1.min(),y1.max()))
plt.subplot(1,3,2)
plt.imshow(np.abs(Uout_shift), cmap='gray', extent=(x2.min(), x2.max(), y2.min(), y2.max()))
plt.subplot(1,3,3)
plt.imshow(np.abs(Uout_an2), cmap='gray', extent=(x2.min(), x2.max(), y2.min(), y2.max()))
plt.show()
4.3 단면 시각화
plt.figure(figsize=(16,6))
plt.subplot(1,2,1)
plt.xlim(-0.003,0.003)
plt.ylim(0,2.5)
plt.plot(x2[1], np.abs(Uout_an**2), marker='s')
plt.plot(x2[1], np.abs(Uout_shift[int(N/2)])**2, marker='x')
plt.subplot(1,2,2)
plt.xlim(-0.003,0.003)
plt.plot(x2[1], np.angle(Uout_an), marker='s')
plt.plot(x2[1], np.angle(Uout_shift[int(len(Uout_shift)/2)]), marker='x')
plt.show()