odak.wave.adaptive_sampling_angular_spectrum¶
A definition to calculate adaptive sampling angular spectrum based beam propagation. For more Zhang, Wenhui, Hao Zhang, and Guofan Jin. "Adaptive-sampling angular spectrum method with full utilization of space-bandwidth product." Optics Letters 45.16 (2020): 4416-4419.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
field |
np.complex |
Complex field (MxN). |
required |
k |
odak.wave.wavenumber |
Wave number of a wave, see odak.wave.wavenumber for more. |
required |
distance |
float |
Propagation distance. |
required |
dx |
float |
Size of one single pixel in the field grid (in meters). |
required |
wavelength |
float |
Wavelength of the electric field. |
required |
Returns:
Type | Description |
---|---|
np.complex |
Final complex field (MxN). |
Source code in odak/wave/classical.py
def adaptive_sampling_angular_spectrum(field, k, distance, dx, wavelength):
"""
A definition to calculate adaptive sampling angular spectrum based beam propagation. For more Zhang, Wenhui, Hao Zhang, and Guofan Jin. "Adaptive-sampling angular spectrum method with full utilization of space-bandwidth product." Optics Letters 45.16 (2020): 4416-4419.
Parameters
----------
field : np.complex
Complex field (MxN).
k : odak.wave.wavenumber
Wave number of a wave, see odak.wave.wavenumber for more.
distance : float
Propagation distance.
dx : float
Size of one single pixel in the field grid (in meters).
wavelength : float
Wavelength of the electric field.
Returns
-------
result : np.complex
Final complex field (MxN).
"""
iflag = -1
eps = 10**(-12)
nv, nu = field.shape
l = nu*dx
x = np.linspace(-l/2, l/2, nu)
y = np.linspace(-l/2, l/2, nv)
X, Y = np.meshgrid(x, y)
fx = np.linspace(-1./2./dx, 1./2./dx, nu)
fy = np.linspace(-1./2./dx, 1./2./dx, nv)
FX, FY = np.meshgrid(fx, fy)
forig = 1./2./dx
fc2 = 1./2*(nu/wavelength/np.abs(distance))**0.5
ss = np.abs(fc2)/forig
zc = nu*dx**2/wavelength
K = nu/2/np.amax(np.abs(fx))
m = 2
nnu2 = m*nu
nnv2 = m*nv
fxn = np.linspace(-1./2./dx, 1./2./dx, nnu2)
fyn = np.linspace(-1./2./dx, 1./2./dx, nnv2)
if np.abs(distance) > zc*2:
fxn = fxn*ss
fyn = fyn*ss
FXN, FYN = np.meshgrid(fxn, fyn)
Hn = np.exp(1j*k*distance*(1-(FXN*wavelength)**2-(FYN*wavelength)**2)**0.5)
FX = FXN/np.amax(FXN)*np.pi
FY = FYN/np.amax(FYN)*np.pi
t_2 = nufft2(field, FX*ss, FY*ss, size=[nnv2, nnu2], sign=iflag, eps=eps)
FX = FX/np.amax(FX)*np.pi
FY = FY/np.amax(FY)*np.pi
result = nuifft2(Hn*t_2, FX*ss, FY*ss, size=[nv, nu], sign=-iflag, eps=eps)
return result