Ejemplo n.º 1
0
def cs_vs_wl(wavelength):
    geom = create_geometry(wavelength, pml_width=wavelength)
    pw = PlaneWave(wavelength=wavelength, angle=0, dim=2, domain=geom.mesh, degree=2)
    omega = 2 * np.pi * c / (wavelength * 1e-9)
    epsilon = dict(box=1, core=2, shell=epsilon_silver(omega))
    s = Scattering(
        geom,
        epsilon,
        mu,
        pw,
        degree=2,
        polarization="TE",
    )
    s.solve()
    cs = s.get_cross_sections()
    return cs["absorption"], cs
Ejemplo n.º 2
0
def test_simple(pmesh=10):
    polarization = "TM"
    degree = 2

    wavelength = 0.3
    options = {
        "General.NumThreads": 0,
        "Mesh.Algorithm": 6,
        "General.Verbosity": 2
    }
    geom = BoxPML(
        dim=2,
        box_size=(4 * wavelength, 4 * wavelength),
        pml_width=(wavelength, wavelength),
        options=options,
    )
    cyl = geom.add_circle(0, 0, 0, 0.2)
    cyl, box = geom.fragment(cyl, geom.box)
    geom.add_physical(box, "box")
    geom.add_physical(cyl, "cyl")
    geom.set_size("box", wavelength / pmesh)
    geom.set_size("cyl", wavelength / pmesh)
    t = -time.time()
    geom.build()
    t += time.time()
    print(f"mesh time: {t:.3f}s")
    epsilon = dict(box=1, cyl=3)
    mu = dict(box=1, cyl=1)
    pw = PlaneWave(wavelength=wavelength,
                   angle=0,
                   dim=2,
                   domain=geom.mesh,
                   degree=degree)
    s = Scattering(geom,
                   epsilon,
                   mu,
                   pw,
                   degree=degree,
                   polarization=polarization)
    u = s.solve()
    list_time()
Ejemplo n.º 3
0
def test_grating3d(degree=1):
    dolfin.parameters["form_compiler"]["quadrature_degree"] = 2

    ##  ---------- incident wave ----------
    p = 1000

    lambda0 = p * 3
    theta0 = 0 * np.pi / 180
    phi0 = 0 * np.pi / 180
    psi0 = 0 * np.pi / 180

    ##  ---------- geometry ----------

    period = (p, p)
    grooove_thickness = p / 20
    hole_radius = p / 4
    thicknesses = OrderedDict({
        "pml_bottom": lambda0,
        "substrate": lambda0 / 1,
        "groove": grooove_thickness,
        "superstrate": lambda0 / 1,
        "pml_top": lambda0,
    })

    ##  ---------- mesh ----------
    parmesh = 4

    parmesh_hole = parmesh * 1

    parmesh_groove = parmesh
    parmesh_pml = parmesh * 2 / 3

    mesh_params = dict({
        "pml_bottom": parmesh_pml,
        "substrate": parmesh,
        "groove": parmesh_groove * 2,
        "hole": parmesh_hole * 2,
        "superstrate": parmesh,
        "pml_top": parmesh_pml,
    })

    ##  ---------- materials ----------
    eps_groove = (1.75 - 1.5j)**2
    eps_hole = 1
    eps_substrate = 1.5**2

    epsilon = dict({
        "substrate": eps_substrate,
        "groove": eps_groove,
        "hole": eps_hole,
        "superstrate": 1,
    })
    mu = dict({"substrate": 1, "groove": 1, "hole": 1, "superstrate": 1})

    index = dict()
    for e, m in zip(epsilon.items(), mu.items()):
        index[e[0]] = np.mean(
            (np.array(e[1]).real.max() * np.array(m[1]).real.max())**0.5).real

    ##  ---------- build geometry ----------
    geom = Layered3D(period, thicknesses, finalize=False)

    groove = geom.layers["groove"]
    substrate = geom.layers["substrate"]
    superstrate = geom.layers["superstrate"]
    z0 = geom.z_position["groove"]

    hole = geom.add_cylinder(
        0,
        0,
        z0,
        0,
        0,
        z0 + grooove_thickness,
        hole_radius,
    )

    superstrate, substrate, hole, groove = geom.fragment(
        [superstrate, substrate, groove], hole)
    # hole, groove = geom.fragment(hole, groove)
    geom.add_physical(groove, "groove")
    geom.add_physical(hole, "hole")
    geom.add_physical(substrate, "substrate")
    geom.add_physical(superstrate, "superstrate")

    index["pml_top"] = index["substrate"]
    index["pml_bottom"] = index["substrate"]
    pmesh = {
        k: lambda0 / (index[k] * mesh_params[k])
        for k, p in mesh_params.items()
    }
    geom.set_mesh_size(pmesh)
    mesh_object = geom.build()

    pw = PlaneWave(
        wavelength=lambda0,
        angle=(np.pi / 2, 0, 0),
        dim=3,
        domain=geom.mesh,
        degree=degree,
    )
    bcs = {}
    s = Grating3D(
        geom,
        epsilon,
        mu,
        pw,
        boundary_conditions=bcs,
        degree=degree,
        periodic_map_tol=1e-6,
    )

    s.solve()
    list_time()
    print("  >> computing diffraction efficiencies")
    print("---------------------------------------")

    effs = s.diffraction_efficiencies(2,
                                      subdomain_absorption=True,
                                      orders=True)
    # effs = s.diffraction_efficiencies(2, subdomain_absorption=False, orders=True)
    pprint(effs)
    R = np.sum(effs["R"])
    T = np.sum(effs["T"])
    Q = sum([q for t in effs["Q"].values() for q in t.values()])
    print("ΣR = ", R)
    print("ΣT = ", T)
    print("ΣQ = ", Q)
    print("B  = ", effs["B"])
    list_time()
Ejemplo n.º 4
0
    geom.add_physical(shell, "shell")
    [geom.set_size(pml, lmin * 1) for pml in geom.pmls]
    geom.set_size("box", lmin)
    geom.set_size("core", 0.5 * lmin / ncore)
    geom.set_size("shell", 0.5 * lmin / nAg)
    geom.build()
    return geom


geom = create_geometry(wavelength, pml_width=wavelength)


##############################################################################
# Define the incident plane wave and materials

pw = PlaneWave(wavelength=wavelength, angle=0, dim=2, domain=geom.mesh, degree=2)
omega = 2 * np.pi * c / (wavelength * 1e-9)
epsilon = dict(box=1, core=eps_core, shell=epsilon_silver(omega))
mu = dict(box=1, core=1, shell=1)


##############################################################################
# Scattering problem

s = Scattering(
    geom,
    epsilon,
    mu,
    pw,
    degree=2,
    polarization="TE",
Ejemplo n.º 5
0
def test_maxwell2d():
    degree = 2
    wavelength = 0.3
    pmesh = 8
    lmin = wavelength / pmesh

    geom = BoxPML(
        dim=2,
        box_size=(4 * wavelength, 4 * wavelength),
        pml_width=(wavelength, wavelength),
    )
    cyl = geom.add_circle(0, 0, 0, 0.2)
    cyl, box = geom.fragment(cyl, geom.box)
    geom.add_physical(box, "box")
    geom.add_physical(cyl, "cyl")
    [geom.set_size(pml, lmin) for pml in geom.pmls]
    geom.set_size("box", lmin)
    geom.set_size("cyl", lmin)
    geom.build()
    mesh = geom.mesh_object["mesh"]
    markers = geom.mesh_object["markers"]["triangle"]
    mapping = geom.subdomains["surfaces"]

    epsilon = dict(box=1, cyl=3)
    mu = dict(box=1, cyl=1)

    stretch = 1 - 1j
    pmlx = PML("x",
               stretch=stretch,
               matched_domain="box",
               applied_domain="pmlx")
    pmly = PML("y",
               stretch=stretch,
               matched_domain="box",
               applied_domain="pmly")
    pmlxy = PML("xy",
                stretch=stretch,
                matched_domain="box",
                applied_domain="pmlxy")

    epsilon_coeff = Coefficient(epsilon,
                                geometry=geom,
                                pmls=[pmlx, pmly, pmlxy])
    mu_coeff = Coefficient(mu, geometry=geom, pmls=[pmlx, pmly, pmlxy])

    coefficients = epsilon_coeff, mu_coeff
    V = ComplexFunctionSpace(mesh, "CG", degree)

    pw = PlaneWave(wavelength=wavelength,
                   angle=0,
                   dim=2,
                   domain=mesh,
                   degree=degree)

    bcs = {}

    m = Maxwell2D(
        geom,
        coefficients,
        V,
        source=pw,
        boundary_conditions=bcs,
        source_domains="cyl",
        reference="box",
    )

    ###########################

    geom = BoxPML(
        dim=2,
        box_size=(4 * wavelength, 4 * wavelength),
        pml_width=(wavelength, wavelength),
    )
    cyl = geom.add_circle(0, 0, 0, 0.2)
    box = geom.cut(geom.box, cyl)
    geom.add_physical(box, "box")
    cyl_bnds = geom.get_boundaries("box")[-1]
    geom.add_physical(cyl_bnds, "cyl_bnds", dim=1)
    [geom.set_size(pml, lmin) for pml in geom.pmls]
    geom.set_size("box", lmin)
    geom.build(0)
    mesh = geom.mesh_object["mesh"]
    markers = geom.mesh_object["markers"]["triangle"]
    mapping = geom.subdomains["surfaces"]
    epsilon = dict(box=1, cyl=3)
    mu = dict(box=1, cyl=1)

    stretch = 1 - 1j
    pmlx = PML("x",
               stretch=stretch,
               matched_domain="box",
               applied_domain="pmlx")
    pmly = PML("y",
               stretch=stretch,
               matched_domain="box",
               applied_domain="pmly")
    pmlxy = PML("xy",
                stretch=stretch,
                matched_domain="box",
                applied_domain="pmlxy")

    epsilon_coeff = Coefficient(epsilon,
                                geometry=geom,
                                pmls=[pmlx, pmly, pmlxy])
    mu_coeff = Coefficient(mu, geometry=geom, pmls=[pmlx, pmly, pmlxy])

    coefficients = epsilon_coeff, mu_coeff
    function_space = ComplexFunctionSpace(mesh, "CG", degree)

    pw = PlaneWave(wavelength=wavelength,
                   angle=0,
                   dim=2,
                   domain=mesh,
                   degree=degree)

    bcs = {"cyl_bnds": "PEC"}

    maxwell = Maxwell2D(
        geom,
        coefficients,
        function_space,
        source=pw,
        boundary_conditions=bcs,
        source_domains="cyl",
        reference="box",
    )
    maxwell.build_boundary_conditions()
Ejemplo n.º 6
0
stretch = 1 - 1j
pml_top = PML("y",
              stretch=stretch,
              matched_domain="superstrate",
              applied_domain="pml_top")
pml_bottom = PML("y",
                 stretch=stretch,
                 matched_domain="substrate",
                 applied_domain="pml_bottom")
epsilon_coeff = Coefficient(epsilon, geometry=geom, pmls=[pml_top, pml_bottom])
mu_coeff = Coefficient(mu, geometry=geom, pmls=[pml_top, pml_bottom])
coefficients = epsilon_coeff, mu_coeff
function_space = ComplexFunctionSpace(geom.mesh, "CG", degree)
pw = PlaneWave(wavelength=lambda0,
               angle=np.pi / 4,
               dim=2,
               domain=geom.mesh,
               degree=degree)

from gyptis.stack import make_stack

out = make_stack(
    geom,
    coefficients,
    pw,
    polarization="TM",
    source_domains=["groove"],
    degree=1,
    dim=2,
)
bcs = {}
Ejemplo n.º 7
0
def test_scatterring3d(shared_datadir):
    degree = 1
    ## needed for surface integral in parallel (mpi)
    dolfin.parameters["ghost_mode"] = "shared_facet"
    dolfin.parameters["form_compiler"]["quadrature_degree"] = 2

    scs_file = shared_datadir / "sphere_diel.csv"
    benchmark = np.loadtxt(scs_file, delimiter=",")

    degree = 1

    pmesh = 1

    pmesh_scatt = 1 * pmesh

    eps_sphere = 4

    # plt.ion()
    plt.close("all")

    plt.plot(benchmark[:, 0], benchmark[:, 1], "k")

    SCSN = []
    Gamma = np.linspace(0.1, 5, 100)
    Gamma = [2]
    for gamma in Gamma:

        # gamma = 1.5

        R_sphere = 0.25
        circ = 2 * np.pi * R_sphere

        lambda0 = circ / gamma

        b = R_sphere * 3
        box_size = (b, b, b)
        pml_width = (lambda0, lambda0, lambda0)

        g = BoxPML3D(box_size=box_size, pml_width=pml_width)

        radius_cs_sphere = 0.8 * min(g.box_size) / 2
        box = g.box
        sphere = g.add_sphere(0, 0, 0, R_sphere)
        sphere_cross_sections = g.add_sphere(0, 0, 0, radius_cs_sphere)
        sphere, sphere_cross_sections, box = g.fragment(
            sphere, [sphere_cross_sections, box])

        g.add_physical([box, sphere_cross_sections], "box")
        g.add_physical(sphere, "sphere")
        # g.add_physical(sphere_cross_sections, "sphere_cross_sections")
        # surf = g.get_boundaries("sphere_cross_sections")[0]
        surf = g.get_boundaries(sphere_cross_sections, physical=False)[0]
        # g.remove(g.dimtag(sphere_cross_sections))
        g.add_physical(surf, "calc", dim=2)

        # g.add_physical(sphere_cross_sections, "sphere_cross_sections")
        smin = 1 * R_sphere / 2
        s = min(lambda0 / pmesh, smin)
        # s =lambda0 / pmesh

        smin_pml = lambda0 / (0.66 * pmesh)

        for coord in ["x", "y", "z", "xy", "xz", "yz", "xyz"]:
            g.set_mesh_size({"pml" + coord: smin_pml})

        g.set_size(box, s)
        g.set_size(sphere_cross_sections, s)
        g.set_size(surf, s, dim=2)
        s = min(lambda0 / (eps_sphere**0.5 * pmesh_scatt), smin)
        # s = lambda0 / (eps_sphere ** 0.5 * pmesh_scatt)
        g.set_size(sphere, s)

        g.build(0)

        epsilon = dict(sphere=eps_sphere, box=1)
        mu = dict(sphere=1, box=1)

        pw = PlaneWave(wavelength=lambda0,
                       angle=(0, 0, 0),
                       dim=3,
                       domain=g.mesh,
                       degree=degree)
        bcs = {}
        s = Scatt3D(
            g,
            epsilon,
            mu,
            pw,
            boundary_conditions=bcs,
            degree=degree,
        )

        s.solve()
        #
        # E = s.solution["diffracted"]
        # W = dolfin.FunctionSpace(g.mesh, "DG", 0)
        # dolfin.File("test.pvd") << project(E.module, W)
        #

        #
        #
        # import os
        #
        # os.system("paraview test.pvd")

        Z0 = np.sqrt(mu_0 / epsilon_0)
        S0 = 1 / (2 * Z0)

        # test = assemble(1*s.dS("calc"))
        # check = 4*np.pi*radius_cs_sphere**2
        #
        # print(test)
        #
        # print(check)
        n_out = g.unit_normal_vector
        Es = s.solution["diffracted"]
        inv_mu_coeff = s.coefficients[1].invert().as_subdomain()
        omega = s.source.pulsation

        Hs = inv_mu_coeff / Complex(0, dolfin.Constant(
            omega * mu_0)) * curl(Es)

        # Hs = s.inv_mu_coeff / (Complex(0,  s.omega * mu_0)) * curl(Es)

        Ps = dolfin.Constant(0.5) * cross(Es, Hs.conj).real
        Ws = -assemble(dot(n_out, Ps)("+") * s.dS("calc"))
        # Ws = -assemble(Es[0].real("+")* s.dS("calc"))

        Sigma_s = Ws / S0
        # S_sphere = R_sphere ** 2 * 4 * np.pi
        S_sphere = R_sphere**2 * np.pi

        Sigma_s_norm = Sigma_s / S_sphere
        print(Sigma_s_norm)
        SCSN.append(Sigma_s_norm)

        plt.plot(gamma, Sigma_s_norm, "or")