Skip to content

overlap fails when bases are different #199

@AmitRotem

Description

@AmitRotem

overlap integral of 2 waveguides with different widths;

#
from collections import OrderedDict
import numpy as np
import shapely
from shapely.ops import clip_by_rect
from skfem import Basis, ElementTriP0
from skfem.io.meshio import from_meshio

from femwell.maxwell.waveguide import compute_modes
from femwell.mesh import mesh_from_OrderedDict
from femwell.visualization import plot_domains


def trapezoid(wg_width, wg_thickness, angle, x_shift=0.0, y_shift=0.0):
    lower_shift = wg_thickness*np.tan((90-angle)*np.pi/180)
    bottom_left  = (-wg_width/2+lower_shift, 0.0)
    bottom_right = (+wg_width/2-lower_shift, 0.0)
    top_left     = (-wg_width/2            , wg_thickness)
    top_right    = (+wg_width/2            , wg_thickness)
    core = shapely.geometry.Polygon((bottom_right, top_right, top_left, bottom_left))
    return shapely.affinity.translate(core, x_shift, y_shift)


def single_rail_setup(wg_width, wg_thickness=0.22, angle=80, clad_thickness=2.2, core_index=3.5, clad_index=1.444,
                      box_index=1.444, air_index=1.0003, max_height=None, env_shape_res=8, env_xfact=1,
                      wg_res=0.02, max_res=1, grading_dist=3):
    if max_height is None:
        max_height = min(wg_width, wg_thickness)*7
    # geometry
    core = trapezoid(wg_width, wg_thickness, angle)
    env = shapely.affinity.scale(core.buffer(max_height, resolution=env_shape_res), xfact=env_xfact)

    polygons = OrderedDict(
        core=core,
        sub=clip_by_rect(env, -np.inf, -np.inf, np.inf, 0),
        clad=clip_by_rect(env, -np.inf, 0, np.inf, clad_thickness),
    )
    if max_height>clad_thickness-wg_thickness:
        polygons['air'] = clip_by_rect(env, -np.inf, clad_thickness, np.inf, np.inf)

    # mesh
    resolutions = dict(core={"resolution": wg_res, "distance": grading_dist})
    mesh = from_meshio(mesh_from_OrderedDict(polygons, resolutions, default_resolution_max=max_res))

    # refraction index
    basis0 = Basis(mesh, ElementTriP0())
    epsilon = basis0.zeros()
    index_dict = {"core": core_index, "sub": box_index, "clad": clad_index}
    if max_height>clad_thickness-wg_thickness:
        index_dict["air"] = air_index
    for subdomain, n in index_dict.items():
        epsilon[basis0.get_dofs(elements=subdomain)] = n**2

    return basis0, epsilon, mesh


def single_rail(wavelength, num_modes=1, mode_order=2, **kwargs):
    # setup
    basis0, epsilon, mesh = single_rail_setup(**kwargs)
    # compute modes
    modes = compute_modes(basis0, epsilon, wavelength=wavelength, num_modes=num_modes, order=mode_order)
    return modes

mode1 = single_rail(1.56, wg_width=0.5)
mode2 = single_rail(1.56, wg_width=0.51)
mode1[0].calculate_overlap(mode2[0])

Seems to get pass this line (last changed in #140)

if basis_i == basis_j or (
np.isclose(basis_i.X, basis_j.X).all() and np.isclose(basis_i.W, basis_j.W).all()
):

and fail with

return A[0] * B[1] - A[1] * B[0]
           ~~~~~^~~~~~
ValueError: operands could not be broadcast together with shapes (2123,3) (2161,3)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions