benvial/gyptis

View on GitHub
examples/diffraction/plot_anisotropic_grating.py

Summary

Maintainability
A
0 mins
Test Coverage
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Benjamin Vial
# This file is part of gyptis
# Version: 1.0.2
# License: MIT
# See the documentation at gyptis.gitlab.io
"""
2D Anisotropic Grating
=======================

Example of diffraction grating with trapezoidal ridges made from an anisotropic material.
"""


from collections import OrderedDict

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1 import make_axes_locatable

import gyptis as gy

##############################################################################
# We will study this benchmark and compare with results
# given in :cite:p:`PopovGratingBook`.

fig, ax = plt.subplots(3, 2, figsize=(3.5, 5.5))


lambda0 = 633
period = 600

width_bottom, width_top = 500, 300
height = 600
eps_sub = 2.25
eps_rod = np.array([[2.592, 0.251, 0], [0.251, 2.592, 0], [0, 0, 2.829]])

pmesh = 10

thicknesses = OrderedDict(
    {
        "pml_bottom": 1 * lambda0,
        "substrate": 2 * lambda0,
        "groove": height * 1.5,
        "superstrate": 2 * lambda0,
        "pml_top": 1 * lambda0,
    }
)

mesh_param = dict(
    {
        "pml_bottom": pmesh * eps_sub**0.5,
        "substrate": pmesh * eps_sub**0.5,
        "groove": pmesh,
        "rod": pmesh * np.max(eps_rod) ** 0.5,
        "superstrate": pmesh,
        "pml_top": pmesh,
    }
)


geom = gy.Layered(2, period, thicknesses)
groove = geom.layers["groove"]
substrate = geom.layers["substrate"]
y0 = geom.y_position["groove"]
P = [geom.add_point(-width_bottom / 2, y0, 0)]
P.append(geom.add_point(width_bottom / 2, y0, 0))
P.append(geom.add_point(width_top / 2, y0 + height, 0))
P.append(geom.add_point(-width_top / 2, y0 + height, 0))
L = [
    geom.add_line(P[0], P[1]),
    geom.add_line(P[1], P[2]),
    geom.add_line(P[2], P[3]),
    geom.add_line(P[3], P[0]),
]
cl = geom.add_curve_loop(L)
rod = geom.add_plane_surface(geom.dimtag(cl, 1)[0])
substrate, groove, rod = geom.cut([substrate, groove], rod)
geom.add_physical(rod, "rod")
geom.add_physical(groove, "groove")
geom.add_physical(substrate, "substrate")
mesh_size = {d: lambda0 / param for d, param in mesh_param.items()}
geom.set_mesh_size(mesh_size)

geom.build(
    interactive=False,
    generate_mesh=True,
    write_mesh=True,
    read_info=True,
)
all_domains = geom.subdomains["surfaces"]
domains = [k for k in all_domains.keys() if k not in ["pml_bottom", "pml_top"]]

epsilon = {d: 1 for d in domains}
mu = {d: 1 for d in domains}

epsilon["substrate"] = eps_sub
epsilon["rod"] = eps_rod


nper = 8

for jangle, angle in enumerate([0, -20, -40]):
    angle_degree = angle * np.pi / 180

    pw = gy.PlaneWave(lambda0, angle_degree, dim=2)
    grating_TM = gy.Grating(geom, epsilon, mu, source=pw, polarization="TM", degree=2)
    grating_TM.solve()
    effs_TM = grating_TM.diffraction_efficiencies(2, orders=True)

    print(f"angle = {angle}, TM polarization")
    print("--------------------------------")
    print("R: ", effs_TM["R"])
    print("T: ", effs_TM["T"])

    ylim = geom.y_position["substrate"], geom.y_position["pml_top"]
    d = grating_TM.period
    vmin_TM, vmax_TM = -1.5, 1.7
    plt.sca(ax[jangle][0])
    per_plots, cb = grating_TM.plot_field(nper=nper)
    cb.remove()
    scatt_lines, layers_lines = grating_TM.plot_geometry(nper=nper, c="k")
    [layers_lines[i].remove() for i in [0, 1, 3, 4]]
    plt.ylim(ylim)
    plt.xlim(-d / 2, nper * d - d / 2)
    plt.axis("off")

    # TE

    grating_TE = gy.Grating(geom, epsilon, mu, source=pw, polarization="TE", degree=2)

    grating_TE.solve()
    effs_TE = grating_TE.diffraction_efficiencies(2, orders=True)

    H = grating_TE.solution["total"]
    print(f"angle = {angle}, TE polarization")
    print("--------------------------------")
    print("R: ", effs_TE["R"])
    print("T: ", effs_TE["T"])

    vmin_TE, vmax_TE = -2.5, 2.5
    plt.sca(ax[jangle][1])
    per_plots, cb = grating_TE.plot_field(nper=nper)
    cb.remove()
    scatt_lines, layers_lines = grating_TE.plot_geometry(nper=nper, c="k")
    [layers_lines[i].remove() for i in [0, 1, 3, 4]]
    plt.ylim(ylim)
    plt.xlim(-d / 2, nper * d - d / 2)
    plt.axis("off")

    ax[jangle][0].set_title(rf"$\theta = {angle}\degree$")
    ax[jangle][1].set_title(rf"$\theta = {angle}\degree$")


divider = make_axes_locatable(ax[0, 0])
cax = divider.new_vertical(size="5%", pad=0.5)
fig.add_axes(cax)
mTM = plt.cm.ScalarMappable(cmap="RdBu")
mTM.set_clim(vmin_TM, vmax_TM)

cbarTM = fig.colorbar(mTM, cax=cax, orientation="horizontal")
cax.set_title(r"${\rm Re}\, E_z$ (TM)")

divider = make_axes_locatable(ax[0, 1])
cax = divider.new_vertical(size="5%", pad=0.5)

mTE = plt.cm.ScalarMappable(cmap="RdBu")
mTE.set_clim(vmin_TE, vmax_TE)
fig.add_axes(cax)
cbarTE = fig.colorbar(mTE, cax=cax, orientation="horizontal")
cax.set_title(r"${\rm Re}\, H_z$ (TE)")

plt.tight_layout()
plt.subplots_adjust(wspace=-0.1, hspace=-0.3)