Diffraction by a thin Wire

Issue #4 closed
Ivan Ostrovsky created an issue

Hey there!
I'm trying to simulate diffraction from a thin wire.
Unfortunately, I'm not able to get the famous Sinc from 12.
It seems increasing the grid or spacing does not improve the results.
Slit diffraction worked perfectly.
Attaching pictures and code below.

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np

from diffractio import degrees, mm, plt, sp, um, np
from diffractio.scalar_fields_XY import Scalar_field_XY
from diffractio.utils_drawing import draw_several_fields
from diffractio.scalar_masks_XY import Scalar_mask_XY
from diffractio.scalar_sources_XY import Scalar_source_XY
from diffractio.scalar_masks_XZ import Scalar_mask_XZ

from matplotlib import rcParams

rcParams['figure.figsize']=(7,5)
rcParams['figure.dpi']=125

num_pixels = 5000

length = 20 * mm
x0 = np.linspace(-length / 2, length / 2, num_pixels)
y0 = np.linspace(-length / 2, length / 2, num_pixels)
wavelength = 0.8 * um

u1 = Scalar_source_XY(x=x0, y=y0, wavelength=wavelength)
# u1.gauss_beam(r0 = (0,0), w0 = 12*mm)
u1.plane_wave(A=1, theta=0 * degrees, phi=0 * degrees)
# u1.laguerre_beam(p=2, l=1, r0=(0 * um, 0 * um), w0=7 * um, z=0.01 * um)

t1 = Scalar_mask_XY(x=x0, y=y0, wavelength=wavelength)
slit_x_size = 0.1*mm
slit_y_size = 12*mm
t1.wire(0.1*mm, num_pixels, length)

u2 = u1 * t1

u3 = u2.RS(z=500*mm, new_field=True)

u4 = u2.RS(z=1000*mm, new_field=True)

draw_several_fields((u2, u3, u4), titles=('mask', '500*mm,', '1000*mm'))

u3.draw_profile(point1 = (0, -5000), point2 = (0, 5000), kind='intensity')
u4.draw_profile(point1 = (0, -5000), point2 = (0, 5000), kind='intensity')

I’ve added a really basic function (just for this use) in Scalar_masks_XY:

def wire(self, size, N, size_of_grid):
    N2 = int(N/2)
    spacing = size_of_grid/N
    width = int(size/spacing)
    N_low_y = N2 - width
    N_high_y = N2 + width + 1
    u = zeros(shape(self.X))
    u[0:N_low_y, :] = 1
    u[N_high_y:, :] = 1
    self.u = u

It doesn’t work with gaussian aperture as well.

Is there a simpler way to do it? Why the Sinc does not come?

Update: I’ve digged dipper into the problem and I can acctually get the sinc function I want with the correct minimas (x = m * L * wavelength / slit_size) but with a lot of oscillations like you see above.

Thanks in advance,

Ivan

Comments (8)

  1. LUIS MIGUEL SANCHEZ BREA repo owner

    Dear Ivan.

    Thank you for your feedback.

    The wire function is ok. There is one similar implemented in diffractio: slit.

    I send you a code where you can find the sinc function for the far field… for the near field it is something different (Fresnel diffraction):

    from diffractio import degrees, mm, plt, sp, um, np
    from diffractio.scalar_fields_XY import Scalar_field_XY
    from diffractio.scalar_masks_XY import Scalar_mask_XY
    from diffractio.scalar_sources_XY import Scalar_source_XY

    from matplotlib import rcParams

    rcParams['figure.figsize']=(7,5)
    rcParams['figure.dpi']=125

    num_pixels = 2048

    length = 2 * mm
    x0 = np.linspace(-length / 2, length / 2, num_pixels)
    y0 = np.linspace(-length / 2, length / 2, num_pixels)
    wavelength = 0.8 * um

    u1 = Scalar_source_XY(x=x0, y=y0, wavelength=wavelength)

    u1.plane_wave(A=1, theta=0 * degrees, phi=0 * degrees)

    t1 = Scalar_mask_XY(x=x0, y=y0, wavelength=wavelength)
    t1.slit(x0=0, size=0.1*mm, angle=0.0)
    u2 = u1 * t1

    u3 = u2.RS(z=5*mm, new_field=True, verbose=True)
    u3.draw_profile(point1 = (-250,0), point2 = (250,0), kind='intensity');

    u5 = u2.RS(z=50*mm, amplification=(3,1), new_field=True, verbose=True)
    u5.draw_profile(point1 = (-3000,0), point2 = (3000,0), kind='intensity');

    As there is Y symmetry you can also use the X (or the XZ) framework. More pixelation is possible and faster results are obtained.

    Also, you can obtain the far field using the wire (slit), introducing a lens, and propagating to the focal distance of the lens..

    Regards

    Luis Miguel.

  2. Ivan Ostrovsky reporter

    Thanks you very much for the answer.

    I indeed used the slit function first and everything was fine, my problem is specifically with diffraction from a wire.

    I propagate the beam in the code I sent here for 0.5m and 1m which is well in the Fraunhofer regime (The condition for Fraunhofer diffraction according to Wikipedia is W^2/(L*wavelength) << 1 where W is the slit width and L is the length to the screen).

    I believe there is some kind of a numeric issue in the propagation algorithm, because without the oscillations you see in the graphs I attached the minimas are actually in the correct place for a sinc(m * L*wavelength / W, m is an integer).

    Best,

    Ivan

  3. LUIS MIGUEL SANCHEZ BREA repo owner

    Sorry, Ivan, for the delay in my answer (summer vacations).

    The far field diffraction pattern for a slit is I = I_0 sinc^2 ( pi x d / z ) where sin(theta) approx x / z, and sinc(x) = sin(x) / x. d is the diameter of the slit.

    With the numbers of my simulation (lambda = 0.8 um, z = 50 mm, d = 0.1 mm) the position of the first minimum is 400 um, which is in accordance to the last profile (minima at 400, 800, 1200, ….) .

    I think that the problem with your simulation is that the position of the first minimum is masked by the diffraction pattern of the outer square. Light is diffracted by outer edges, which also produce diffraction.

    If you make the complementary diffraction pattern

    t1 = wire(t1, 0.1_mm, num_pixels, length)_
    t1.u=1-t1.u

    the diffraction pattern is clear:

    Luis Miguel.

  4. Ivan Ostrovsky reporter

    It seems right since it indeed works better with small beams (meaning there is less reflection from the boundries).

    Thanks

  5. Log in to comment