Simulating diffraction by an object in 2DΒΆ

Finite element simulation of the diffraction by an object illuminated by a plane wave or a line source. Calculation of scattering width and getting the field maps.

import numpy as np
import matplotlib.pyplot as plt
from pytheas import Scatt2D

plt.ion()

pi = np.pi

Then we need to instanciate the class Scatt2D:

fem = Scatt2D()
fem.rm_tmp_dir()
# We define first the opto-geometric parameters:

mum = 1  #: flt: the scale of the problem (here micrometers)
fem.lambda0 = 0.6 * mum  #: flt: incident wavelength
fem.pola = "TE"  #: str: polarization (TE or TM)
fem.theta_deg = 30.0  # 0: coming from top (y>0)
fem.hx_des = 1.0 * mum  #: flt: x thickness box
fem.hy_des = 1.0 * mum  #: flt: y thickness box
fem.h_pml = fem.lambda0  #: flt: thickness pml
fem.space2pml_L, fem.space2pml_R = fem.lambda0 * 2, fem.lambda0 * 2
fem.space2pml_T, fem.space2pml_B = fem.lambda0 * 2, fem.lambda0 * 2
fem.eps_des = 1  #: flt: permittivity design box
fem.eps_host = 1.0
fem.eps_incl = 11.0 - 1e-2 * 1j
#: mesh parameters, correspond to a mesh size of lambda_mesh/(n*parmesh),
#: where n is the refractive index of the medium
fem.lambda_mesh = 0.6 * mum  #: flt: incident wavelength
fem.parmesh_des = 10
fem.parmesh_incl = 10
fem.parmesh = 10
fem.parmesh_pml = fem.parmesh * 2 / 3

fem.Nix = 101
fem.Niy = 101

Here we define an ellipsoidal rod as the scatterer:

def ellipse(Rinclx, Rincly, rot_incl, x0, y0):
    c, s = np.cos(rot_incl), np.sin(rot_incl)
    Rot = np.array([[c, -s], [s, c]])
    nt = 360
    theta = np.linspace(-pi, pi, nt)
    x = Rinclx * np.sin(theta)
    y = Rincly * np.cos(theta)
    x, y = np.linalg.linalg.dot(Rot, np.array([x, y]))
    points = x + x0, y + y0
    return points


rod = ellipse(0.4 * mum, 0.2 * mum, 0, 0, 0)
fem.inclusion_flag = True

Initialize, build the scatterer, mesh and compute the solution:

fem.initialize()
fem.make_inclusion(rod)
fem.make_mesh()
fem.compute_solution()

Get the electric field and plot it:

fem.postpro_fields()
u_tot = fem.get_field_map("u_tot.txt")
fig, ax = plt.subplots()
E = u_tot.real
plt.imshow(E, cmap="RdBu_r", extent=(fem.domX_L, fem.domX_R, fem.domY_B, fem.domY_T))
plt.plot(rod[0], rod[1], "w")
plt.xlabel(r"$x$ ($\rm \mu$m)")
plt.ylabel(r"$y$ ($\rm \mu$m)")
plt.title(r"Electric Field (real part) (V/m)")
plt.colorbar()
plt.tight_layout()
../../_images/sphx_glr_plot_scatt_cyl_001.png

Do a near to far field transform and get the normalized scattering width:

ff = fem.postpro_fields_n2f()
theta = np.linspace(0, 2 * pi, 51)
scs = fem.normalized_scs(ff, theta)


fig, ax = plt.subplots()
plt.plot(theta / pi, scs, "-", c="#699545")
plt.xlabel(r"$\theta$ (rad)")
plt.ylabel(r" Normalized scattering width $\sigma/\lambda$")
ax.xaxis.set_ticks([0, 0.5, 1, 1.5, 2])
ax.xaxis.set_ticklabels(["0", "$\pi/2$", "$\pi$", "$3\pi/2$", "$2\pi$"])

scs_integ = np.trapz(scs, theta) / (2 * pi)
print("Normalized SCS", scs_integ)
../../_images/sphx_glr_plot_scatt_cyl_002.png

Out:

Normalized SCS 0.02572717419074843

Total running time of the script: ( 0 minutes 15.999 seconds)

Estimated memory usage: 16 MB

Gallery generated by Sphinx-Gallery