Пример #1
0
    def test_fields_at_kx(self):
        self.sim.k_point = mp.Vector3(3.5)
        h = mp.Harminv(mp.Hz, mp.Vector3(0.1234), self.fcen, self.df)
        self.sim.run(mp.after_sources(h), until_after_sources=300)

        expected = [
            (0.19990240131986522, 3.8522735413802275e-8),
            (0.3050067740183294, 4.720168254531566e-7),
            (0.4396104226078593, 1.6233300291010948e-6),
            (0.4582004346509184, 4.7150006592976396e-7),
            (0.5006556112859917, -0.0014396635723422887),
            (0.7405953267896378, -4.553109069353934e-5),
            (0.7627621012715363, -0.006700351645723407),
            (0.8243404528365005, -5.174379068176951e-4),
            (0.8255990399390389, -0.0016256261502000271),
            (0.9494859645499801, -0.005325208458639275),
            (0.9726561278186849, -0.0031192234222098274),
            (0.9855957702101914, -0.003945157134867143),
        ]

        self.assertTrue(h.modes)
        places = 4 if mp.is_single_precision() else 7
        for (r, i), m in zip(expected, h.modes):
            self.assertAlmostEqual(m.freq, r, places=places)
            self.assertAlmostEqual(m.decay, i, places=places)
Пример #2
0
def main(args):

    n = 3.4  # index of waveguide
    w = 1  # width of waveguide
    r = 1  # inner radius of ring
    pad = 4  # padding between waveguide and edge of PML
    dpml = 32  # thickness of PML

    sr = r + w + pad + dpml  # radial size (cell is from 0 to sr)
    dimensions = mp.CYLINDRICAL
    cell = mp.Vector3(sr, 0, 0)

    # in cylindrical coordinates, the phi (angular) dependence of the fields
    # is given by exp(i m phi), where m is given by:
    m = args.m

    geometry = [
        mp.Block(center=mp.Vector3(r + (w / 2)),
                 size=mp.Vector3(w, 1e20, 1e20),
                 material=mp.Medium(index=n))
    ]

    pml_layers = [mp.PML(dpml)]
    resolution = 20

    # If we don't want to excite a specific mode symmetry, we can just
    # put a single point source at some arbitrary place, pointing in some
    # arbitrary direction.  We will only look for TM modes (E out of the plane).

    fcen = args.fcen  # pulse center frequency
    df = args.df  # pulse frequency width
    sources = [
        mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ez,
                  center=mp.Vector3(r + 0.1))
    ]

    # note that the r -> -r mirror symmetry is exploited automatically

    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        boundary_layers=pml_layers,
                        resolution=resolution,
                        sources=sources,
                        dimensions=dimensions,
                        m=m)

    sim.run(mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)),
            until_after_sources=200)

    # Output fields for one period at the end.  (If we output
    # at a single time, we might accidentally catch the Ez field when it is
    # almost zero and get a distorted view.)  We'll append the fields
    # to a file to get an r-by-t picture.  We'll also output from -sr to -sr
    # instead of from 0 to sr.
    sim.run(mp.in_volume(
        mp.Volume(center=mp.Vector3(), size=mp.Vector3(2 * sr)),
        mp.at_beginning(mp.output_epsilon),
        mp.to_appended("ez", mp.at_every(1 / fcen / 20, mp.output_efield_z))),
            until=1 / fcen)
Пример #3
0
    def test_resonant_modes(self):
        self.sim.sources = [mp.Source(mp.GaussianSource(self.fcen, fwidth=self.df),
                                      mp.Hz, mp.Vector3())]

        self.sim.symmetries = [mp.Mirror(mp.Y, phase=-1),
                               mp.Mirror(mp.X, phase=-1)]

        h = mp.Harminv(mp.Hz, mp.Vector3(), self.fcen, self.df)
        self.sim.run(mp.at_beginning(mp.output_epsilon),
                     mp.after_sources(h),
                     until_after_sources=400)

        expected = [
            0.23445415346009466,
            -3.147812367338531e-4,
            372.40808234438254,
            5.8121430334347135,
            -3.763107485715599,
            -4.429450156854109,
        ]

        m = h.modes[0]
        res = [m.freq, m.decay, m.Q, abs(m.amp), m.amp.real, m.amp.imag]

        np.testing.assert_allclose(expected, res)
Пример #4
0
def example_cavity_harminv():
    from gdshelpers.parts.waveguide import Waveguide
    from shapely.geometry import Point

    wg = Waveguide((-6, 0), 0, 1.2)
    start_port = wg.current_port
    wg.add_straight_segment(6)
    center_port = wg.current_port
    wg.add_straight_segment(6)
    wgs = [Waveguide.make_at_port(port).add_straight_segment(4) for port in
           [start_port.inverted_direction, wg.current_port]]
    holes = geometric_union(
        [Point(x * sign, 0).buffer(.36) for x in [1.4 / 2 + x * 1 for x in range(3)] for sign in [-1, 1]])

    sim = Simulation(resolution=20, reduce_to_2d=True, padding=2, pml_thickness=1)
    sim.add_structure([wg.get_shapely_object().difference(holes)], wgs, mp.Medium(epsilon=13),
                      z_min=0, z_max=.33)

    sim.add_source(mp.GaussianSource(wavelength=1 / .25, fwidth=.2), mp.Hz, center_port, z=0)

    sim.init_sim()

    sim.plot(fields=mp.Hz)

    mp.simulation.display_run_data = lambda *args, **kwargs: None
    harminv = mp.Harminv(mp.Hz, mp.Vector3(), .25, .2)

    sim.run(mp.after_sources(harminv._collect_harminv()(harminv.c, harminv.pt)), until_after_sources=300)
    sim.plot(fields=mp.Hz)

    print(harminv._analyze_harminv(sim.sim, 100))
Пример #5
0
def main():
    geom = a_tapered_cavity()
    
    boundary_layers = get_boundary_layer(sim2d=False)
    
    fcen = 1/1.54
    df = 0.1
    sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), 
                         component=mp.Hz, 
                         center=mp.Vector3())]
    
    symmetries = [mp.Mirror(mp.X,+1), mp.Mirror(mp.Y,-1), mp.Mirror(mp.Z,+1)]
    
    sim = mp.Simulation(resolution=30, 
                        cell_size=mp.Vector3(20, 8, 8), 
                        geometry=geom, 
                        boundary_layers=boundary_layers, 
                        sources=sources,
                        symmetries=symmetries,
                        progress_interval=100,)
    
    h = mp.Harminv(mp.Hz, mp.Vector3(0, 0, 0), fcen, df)
    time_after_source = 500
    # Don't output eps anymore to save disk space
    sim.run(mp.after_sources(h),
            until_after_sources=time_after_source)
    
    visualize_sim_cell(sim)
    
    print("Modal Volume: {}".format(sim.modal_volume_in_box()))
Пример #6
0
    def test_resonant_modes(self):
        self.sim.sources = [
            mp.Source(mp.GaussianSource(self.fcen, fwidth=self.df), mp.Hz,
                      mp.Vector3())
        ]

        self.sim.symmetries = [
            mp.Mirror(mp.Y, phase=-1),
            mp.Mirror(mp.X, phase=-1)
        ]

        h = mp.Harminv(mp.Hz, mp.Vector3(), self.fcen, self.df)
        self.sim.run(mp.at_beginning(mp.output_epsilon),
                     mp.after_sources(h),
                     until_after_sources=400)

        expected = [
            0.23445415346009466,
            -3.147812367338531e-4,
            372.40808234438254,
            5.8121430334347135,
            -3.763107485715599,
            -4.429450156854109,
        ]

        m = h.modes[0]
        res = [m.freq, m.decay, m.Q, abs(m.amp), m.amp.real, m.amp.imag]

        np.testing.assert_allclose(expected, res)
Пример #7
0
    def run_all(self, time_after_sources=150, nfreq_ldos=200):
        self.time_after_sources = time_after_sources
        self.nfreq_ldos = nfreq_ldos

        self.harminv_instance = mp.Harminv(
            mp.Er, mp.Vector3(0, 0, self.source_position + self.shift),
            self.fcen, self.df)

        self.ldos_instance = mp.Ldos(self.fcen, self.df, self.nfreq_ldos)

        self._sim.run(mp.after_sources(self.harminv_instance),
                      mp.dft_ldos(ldos=self.ldos_instance),
                      until_after_sources=self.time_after_sources)

        self.ldos_results = np.transpose(
            np.array([self.ldos_instance.freqs(), self._sim.ldos_data]))

        self.q_results = []
        for mode in self.harminv_instance.modes:
            self.q_results.append(
                [1000 / mode.freq, mode.decay, mode.Q,
                 abs(mode.amp)])
        self.q_results = np.array(self.q_results)

        self.print_qs()
        self.plot_power()
        self.plot_ldos()
        self.plot_er_field()
Пример #8
0
def compute_resonant_mode(res):
    cell_size = mp.Vector3(1, 1, 0)

    rad = 0.301943

    fcen = 0.3
    df = 0.2 * fcen
    sources = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Hz,
                  center=mp.Vector3(-0.1057, 0.2094, 0))
    ]

    k_point = mp.Vector3(0.3892, 0.1597, 0)

    design_shape = mp.Vector3(1, 1, 0)
    design_region_resolution = 50
    Nx = int(design_region_resolution * design_shape.x)
    Ny = int(design_region_resolution * design_shape.y)
    x = np.linspace(-0.5 * design_shape.x, 0.5 * design_shape.x, Nx)
    y = np.linspace(-0.5 * design_shape.y, 0.5 * design_shape.y, Ny)
    xv, yv = np.meshgrid(x, y)
    design_params = np.sqrt(np.square(xv) + np.square(yv)) < rad
    filtered_design_params = gaussian_filter(design_params,
                                             sigma=3.0,
                                             output=np.double)

    matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny),
                              mp.air,
                              mp.Medium(index=3.5),
                              weights=filtered_design_params,
                              do_averaging=True,
                              beta=1000,
                              eta=0.5)

    geometry = [
        mp.Block(center=mp.Vector3(),
                 size=mp.Vector3(design_shape.x, design_shape.y, 0),
                 material=matgrid)
    ]

    sim = mp.Simulation(resolution=res,
                        cell_size=cell_size,
                        geometry=geometry,
                        sources=sources,
                        k_point=k_point)

    h = mp.Harminv(mp.Hz, mp.Vector3(0.3718, -0.2076), fcen, df)
    sim.run(mp.after_sources(h), until_after_sources=200)

    try:
        for m in h.modes:
            print("harminv:, {}, {}, {}".format(res, m.freq, m.Q))
        freq = h.modes[0].freq
    except:
        print("No resonant modes found.")

    sim.reset_meep()
    return freq
Пример #9
0
        def check_warnings(sim, h, should_warn=True):
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                sim.run(mp.after_sources(h), until_after_sources=5)

                if should_warn:
                    self.assertEqual(len(w), 1)
                    self.assertIn("Harminv", str(w[-1].message))
                else:
                    self.assertEqual(len(w), 0)
Пример #10
0
        def check_warnings(sim, h, should_warn=True):
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                sim.run(mp.after_sources(h), until_after_sources=5)

                if should_warn:
                    self.assertEqual(len(w), 1)
                    self.assertIn("Harminv", str(w[-1].message))
                else:
                    self.assertEqual(len(w), 0)
Пример #11
0
def main(args):
    resolution = 200
    sxy = 2
    dpml = 1
    sxy = sxy + 2 * dpml
    cell = mp.Vector3(sxy, sxy, 0)

    pml_layers = [mp.PML(dpml)]
    a = 1
    t = 0.1
    geometry = [
        mp.Block(mp.Vector3(a + 2 * t, a + 2 * t, 1e20),
                 material=mp.Medium(epsilon=-1e20)),
        mp.Block(mp.Vector3(a, a, 1e20), material=mp.Medium(epsilon=1.0))
    ]

    w = args.w
    if w > 0:
        geometry.append(
            mp.Block(center=mp.Vector3(a / 2),
                     size=mp.Vector3(2 * t, w, 1e20),
                     material=mp.Medium(epsilon=1.0)))

        fcen = math.sqrt(0.5) / a
        df = 0.2
        sources = [
            mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                      component=mp.Ez,
                      center=mp.Vector3())
        ]

        symmetries = [mp.Mirror(mp.Y)]

        Th = args.Th

        sim = mp.Simulation(cell_size=cell,
                            geometry=geometry,
                            boundary_layers=pml_layers,
                            sources=sources,
                            symmetries=symmetries,
                            resolution=resolution)

        h = mp.Harminv(mp.Ez, mp.Vector3(), fcen, df)
        sim.run(mp.after_sources(h), until_after_sources=Th)

        m = h.modes[0]
        f = m.freq
        Q = m.Q
        Vmode = 0.25 * a * a
        print("ldos0:, {}".format(Q / Vmode /
                                  (2 * math.pi * f * math.pi * 0.5)))

        sim.reset_meep()
        T = 2 * Q * (1 / f)
        sim.run(mp.dft_ldos(f, 0, 1), until_after_sources=T)
Пример #12
0
def main(args):

    n = 3.4     # index of waveguide
    w = 1       # width of waveguide
    r = 1       # inner radius of ring
    pad = 4     # padding between waveguide and edge of PML
    dpml = 32    # thickness of PML

    sr = r + w + pad + dpml  # radial size (cell is from 0 to sr)
    dimensions = mp.CYLINDRICAL
    cell = mp.Vector3(sr, 0, 0)

    # in cylindrical coordinates, the phi (angular) dependence of the fields
    # is given by exp(i m phi), where m is given by:
    m = args.m

    geometry = [mp.Block(center=mp.Vector3(r + (w / 2)),
                         size=mp.Vector3(w, mp.inf, mp.inf),
                         material=mp.Medium(index=n))]

    pml_layers = [mp.PML(dpml)]
    resolution = 20

    # If we don't want to excite a specific mode symmetry, we can just
    # put a single point source at some arbitrary place, pointing in some
    # arbitrary direction.  We will only look for Ez-polarized modes.

    fcen = args.fcen  # pulse center frequency
    df = args.df      # pulse frequency width
    sources = [mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                         component=mp.Ez,
                         center=mp.Vector3(r + 0.1))]

    # note that the r -> -r mirror symmetry is exploited automatically

    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        boundary_layers=pml_layers,
                        resolution=resolution,
                        sources=sources,
                        dimensions=dimensions,
                        m=m)

    sim.run(mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)),
            until_after_sources=200)

    # Output fields for one period at the end.  (If we output
    # at a single time, we might accidentally catch the Ez field when it is
    # almost zero and get a distorted view.)  We'll append the fields
    # to a file to get an r-by-t picture.  We'll also output from -sr to -sr
    # instead of from 0 to sr.
    sim.run(mp.in_volume(mp.Volume(center=mp.Vector3(), size=mp.Vector3(2 * sr)),
                         mp.at_beginning(mp.output_epsilon),
                         mp.to_appended("ez", mp.at_every(1 / fcen / 20, mp.output_efield_z))),
            until=1 / fcen)
Пример #13
0
def metal_cavity(w):
    resolution = 50
    sxy = 2
    dpml = 1
    sxy = sxy + 2 * dpml
    cell = mp.Vector3(sxy, sxy)

    pml_layers = [mp.PML(dpml)]
    a = 1
    t = 0.1
    geometry = [
        mp.Block(mp.Vector3(a + 2 * t, a + 2 * t, mp.inf), material=mp.metal),
        mp.Block(mp.Vector3(a, a, mp.inf), material=mp.air)
    ]

    geometry.append(
        mp.Block(center=mp.Vector3(a / 2),
                 size=mp.Vector3(2 * t, w, mp.inf),
                 material=mp.air))

    fcen = math.sqrt(0.5) / a
    df = 0.2
    sources = [
        mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ez,
                  center=mp.Vector3())
    ]

    symmetries = [mp.Mirror(mp.Y)]

    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        boundary_layers=pml_layers,
                        sources=sources,
                        symmetries=symmetries,
                        resolution=resolution)

    h = mp.Harminv(mp.Ez, mp.Vector3(), fcen, df)
    sim.run(mp.after_sources(h), until_after_sources=500)

    m = h.modes[0]
    f = m.freq
    Q = m.Q
    Vmode = 0.25 * a * a
    ldos_1 = Q / Vmode / (2 * math.pi * f * math.pi * 0.5)

    sim.reset_meep()

    T = 2 * Q * (1 / f)
    sim.run(mp.dft_ldos(f, 0, 1), until_after_sources=T)
    ldos_2 = sim.ldos_data[0]

    return ldos_1, ldos_2
def main():
    n = 3.4  # index of waveguide
    r = 1
    a = r  # inner radius of ring
    w = 1  # width of waveguide
    b = a + w  # outer radius of ring
    pad = 4  # padding between waveguide and edge of PML

    dpml = 2  # thickness of PML
    pml_layers = [mp.PML(dpml)]

    resolution = 100

    sr = b + pad + dpml  # radial size (cell is from 0 to sr)
    dimensions = mp.CYLINDRICAL  # coordinate system is (r,phi,z) instead of (x,y,z)
    cell = mp.Vector3(sr, 0, 0)

    m = 4

    geometry = [
        mp.Block(center=mp.Vector3(a + (w / 2)),
                 size=mp.Vector3(w, 1e20, 1e20),
                 material=mp.Medium(index=n))
    ]

    # Finding a resonance mode with a high Q-value (calculated with Harminv)

    fcen = 0.15  # pulse center frequency
    df = 0.1  # pulse width (in frequency)

    sources = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  mp.Hz,
                  mp.Vector3(r + 0.1),
                  amplitude=1)
    ]

    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        boundary_layers=pml_layers,
                        resolution=resolution,
                        sources=sources,
                        dimensions=dimensions,
                        m=m)

    h = mp.Harminv(mp.Hz, mp.Vector3(r + 0.1), fcen, df)
    sim.run(mp.after_sources(h), until_after_sources=200)

    print(f'Harminv found {len(h.modes)} resonant modes(s).')
    for mode in h.modes:
        print(f'The resonant mode with f={mode.freq} has Q={mode.Q}')
Пример #15
0
def main():
    # Some parameters to describe the geometry:
    eps = 13  # dielectric constant of waveguide
    w = 1.2  # width of waveguide
    r = 0.36  # radius of holes

    # The cell dimensions
    sy = 12  # size of cell in y direction (perpendicular to wvg.)
    dpml = 1  # PML thickness (y direction only!)

    cell = mp.Vector3(1, sy)

    b = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf),
                 material=mp.Medium(epsilon=eps))
    c = mp.Cylinder(radius=r)

    fcen = 0.25  # pulse center frequency
    df = 1.5  # pulse freq. width: large df = short impulse

    s = mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Hz,
                  center=mp.Vector3(0.1234))

    sym = mp.Mirror(direction=mp.Y, phase=-1)

    sim = mp.Simulation(cell_size=cell,
                        geometry=[b, c],
                        sources=[s],
                        symmetries=[sym],
                        boundary_layers=[mp.PML(dpml, direction=mp.Y)],
                        resolution=20)

    kx = False  # if true, do run at specified kx and get fields
    k_interp = 19  # # k-points to interpolate, otherwise

    if kx:
        sim.k_point = mp.Vector3(kx)

        sim.run(mp.at_beginning(mp.output_epsilon),
                mp.after_sources(
                    mp.Harminv(mp.Hz, mp.Vector3(0.1234), fcen, df)),
                until_after_sources=300)

        sim.run(mp.at_every(1 / fcen / 20, mp.output_hfield_z), until=1 / fcen)

    else:
        sim.run_k_points(
            300, mp.interpolate(k_interp,
                                [mp.Vector3(), mp.Vector3(0.5)]))
Пример #16
0
def main(args):
    resolution = 200
    sxy = 2
    dpml = 1
    sxy = sxy + 2 * dpml
    cell = mp.Vector3(sxy, sxy, 0)

    pml_layers = [mp.PML(dpml)]
    a = 1
    t = 0.1
    geometry = [mp.Block(mp.Vector3(a + 2 * t, a + 2 * t, mp.inf), material=mp.metal),
                mp.Block(mp.Vector3(a, a, mp.inf), material=mp.air)]

    w = args.w
    if w > 0:
        geometry.append(mp.Block(center=mp.Vector3(a / 2), size=mp.Vector3(2 * t, w, mp.inf),
                                 material=mp.air))

        fcen = math.sqrt(0.5) / a
        df = 0.2
        sources = [mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Ez,
                             center=mp.Vector3())]

        symmetries = [mp.Mirror(mp.Y)]

        Th = args.Th

        sim = mp.Simulation(cell_size=cell,
                            geometry=geometry,
                            boundary_layers=pml_layers,
                            sources=sources,
                            symmetries=symmetries,
                            resolution=resolution)

        h = mp.Harminv(mp.Ez, mp.Vector3(), fcen, df)
        sim.run(mp.after_sources(h), until_after_sources=Th)

        m = h.modes[0]
        f = m.freq
        Q = m.Q
        Vmode = 0.25 * a * a
        print("ldos0:, {}".format(Q / Vmode / (2 * math.pi * f * math.pi * 0.5)))

        sim.reset_meep()
        T = 2 * Q * (1 / f)
        sim.run(mp.dft_ldos(f, 0, 1), until_after_sources=T)
Пример #17
0
    def test_custom_source(self):
        n = 3.4
        w = 1
        r = 1
        pad = 4
        dpml = 2
        sxy = 2 * (r + w + pad + dpml)

        cell = mp.Vector3(sxy, sxy)

        geometry = [
            mp.Cylinder(r + w, material=mp.Medium(index=n)),
            mp.Cylinder(r, material=mp.air)
        ]

        boundary_layers = [mp.PML(dpml)]
        resolution = 10
        fcen = 0.15
        df = 0.1

        # Bump function
        def my_src_func(t):
            if t > 0 and t < 2:
                return math.exp(-1 / (1 - ((t - 1)**2)))
            return 0j

        sources = [
            mp.Source(src=mp.CustomSource(src_func=my_src_func, end_time=100),
                      component=mp.Ez,
                      center=mp.Vector3(r + 0.1))
        ]

        symmetries = [mp.Mirror(mp.Y)]

        sim = mp.Simulation(cell_size=cell,
                            resolution=resolution,
                            geometry=geometry,
                            boundary_layers=boundary_layers,
                            sources=sources,
                            symmetries=symmetries)

        h = mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)
        sim.run(mp.after_sources(h), until_after_sources=200)
        fp = sim.get_field_point(mp.Ez, mp.Vector3(1))

        self.assertAlmostEqual(fp, -0.021997617628500023 + 0j)
Пример #18
0
    def test_ring_cyl(self):
        expected = [
            0.11835455441250553,
            -6.907792691629741e-4,
            85.66741917133473,
            0.025701906263451237,
            -0.024027038833537524,
            -0.009126302124459489,
        ]

        h = mp.Harminv(mp.Ez, mp.Vector3(self.r + 0.1), self.fcen, self.df)
        self.sim.run(mp.after_sources(h), until_after_sources=200)

        m = h.modes[0]
        res = [m.freq, m.decay, m.Q, abs(m.amp), m.amp.real, m.amp.imag]

        np.testing.assert_allclose(expected, res)
Пример #19
0
def find_modes(filename, wvl=1.55, bw=0.05):
    # Read in the ring structure
    geometry = mp.get_GDSII_prisms(Si, filename, RING_LAYER, -100, 100)

    cell = mp.GDSII_vol(filename, SIMULATION_LAYER, zmin, zmax)

    src_vol0 = mp.GDSII_vol(filename, SOURCE0_LAYER, zmin, zmax)
    src_vol1 = mp.GDSII_vol(filename, SOURCE1_LAYER, zmin, zmax)

    mon_vol = mp.GDSII_vol(filename, MONITOR_LAYER, zmin, zmax)

    fcen = 1 / wvl
    df = bw * fcen

    src = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Hz,
                  volume=src_vol0),
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Hz,
                  volume=src_vol1,
                  amplitude=-1)
    ]

    sim = mp.Simulation(cell_size=cell.size,
                        geometry=geometry,
                        sources=src,
                        resolution=resolution,
                        boundary_layers=[mp.PML(dpml)],
                        default_material=SiO2)

    h = mp.Harminv(mp.Hz, mon_vol.center, fcen, df)

    sim.run(mp.after_sources(h), until_after_sources=100)

    plt.figure()
    sim.plot2D(fields=mp.Hz)
    plt.savefig('ring_resonator_Hz.png')

    wvl = np.array([1 / m.freq for m in h.modes])
    Q = np.array([m.Q for m in h.modes])

    sim.reset_meep()

    return wvl, Q
Пример #20
0
    def test_harminv(self):
        self.init()

        self.sim.run(
            mp.at_beginning(mp.output_epsilon),
            mp.after_sources(self.h),
            until_after_sources=300
        )
        m1, m2, m3 = self.h.modes

        self.assertAlmostEqual(m1.freq, 0.118101315147, places=4)
        self.assertAlmostEqual(m1.decay, -0.000731513241623, places=4)
        self.assertAlmostEqual(abs(m1.amp), 0.00341267634436, places=4)
        self.assertAlmostEqual(m1.amp.real, -0.00304951667301, places=4)
        self.assertAlmostEqual(m1.amp.imag, -0.00153192946717, places=4)

        fp = self.sim.get_field_point(mp.Ez, mp.Vector3(1, 1))
        self.assertAlmostEqual(fp, -0.08185972142450348)
Пример #21
0
    def get_q_values(self, time_after_sources=150):
        self.time_after_sources = time_after_sources

        # get q values at sources
        harminv_instance = mp.Harminv(
            mp.Er, mp.Vector3(0, 0, self.source_position + self.shift),
            self.fcen, self.df)
        self._sim.run(mp.after_sources(harminv_instance),
                      until_after_sources=self.time_after_sources)

        self.q_results = []
        for mode in harminv_instance.modes:
            self.q_results.append(
                [1000 / mode.freq, mode.decay, mode.Q,
                 abs(mode.amp)])
        self.q_results = np.array(self.q_results)

        self.print_qs()
Пример #22
0
    def test_custom_source(self):
        n = 3.4
        w = 1
        r = 1
        pad = 4
        dpml = 2
        sxy = 2 * (r + w + pad + dpml)

        cell = mp.Vector3(sxy, sxy)

        geometry = [
            mp.Cylinder(r + w, material=mp.Medium(index=n)),
            mp.Cylinder(r, material=mp.air)
        ]

        boundary_layers = [mp.PML(dpml)]
        resolution = 10
        fcen = 0.15
        df = 0.1

        # Bump function
        def my_src_func(t):
            if t > 0 and t < 2:
                return math.exp(-1 / (1 - ((t - 1)**2)))
            return 0j

        sources = [mp.Source(src=mp.CustomSource(src_func=my_src_func, end_time=100),
                             component=mp.Ez, center=mp.Vector3(r + 0.1))]

        symmetries = [mp.Mirror(mp.Y)]

        sim = mp.Simulation(cell_size=cell,
                            resolution=resolution,
                            geometry=geometry,
                            boundary_layers=boundary_layers,
                            sources=sources,
                            symmetries=symmetries)

        h = mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)
        sim.run(mp.after_sources(h), until_after_sources=200)
        fp = sim.get_field_point(mp.Ez, mp.Vector3(1))

        self.assertAlmostEqual(fp, -0.021997617628500023 + 0j)
Пример #23
0
def main():
    n = 3.4  # index of waveguide
    w = 1  # width of waveguide
    r = 1  # inner radius of ring
    pad = 4  # padding between waveguide and edge of PML
    dpml = 2  # thickness of PML
    sxy = 2 * (r + w + pad + dpml)  # cell size

    # Create a ring waveguide by two overlapping cylinders - later objects
    # take precedence over earlier objects, so we put the outer cylinder first.
    # and the inner (air) cylinder second.

    c1 = mp.Cylinder(radius=r + w, material=mp.Medium(index=n))
    c2 = mp.Cylinder(radius=r)

    # If we don't want to excite a specific mode symmetry, we can just
    # put a single point source at some arbitrary place, pointing in some
    # arbitrary direction.  We will only look for Ez-polarized modes.

    fcen = 0.15  # pulse center frequency
    df = 0.1  # pulse width (in frequency)

    src = mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz, mp.Vector3(r + 0.1))

    sim = mp.Simulation(cell_size=mp.Vector3(sxy, sxy),
                        geometry=[c1, c2],
                        sources=[src],
                        resolution=10,
                        symmetries=[mp.Mirror(mp.Y)],
                        boundary_layers=[mp.PML(dpml)])

    h = mp.Harminv(mp.Ex, mp.Vector3(r + 0.1), fcen, df)
    sim.run(mp.after_sources(h), until_after_sources=200)

    print(f'Harminv found {len(h.modes)} resonant modes(s).')
    for mode in h.modes:
        print(f'The resonant mode with f={mode.freq} has Q={mode.Q}')

    sim.plot2D(fields=mp.Ex,
           field_parameters={'alpha':0.8, 'cmap':'RdBu', 'interpolation':'none'},
           boundary_parameters={'hatch':'o', 'linewidth':1.5, 'facecolor':'y', 'edgecolor':'b', 'alpha':0.3})
    plt.show()
Пример #24
0
def main():
    n = 3.4  # index of waveguide
    w = 1  # width of waveguide
    r = 1  # inner radius of ring
    pad = 4  # padding between waveguide and edge of PML
    dpml = 2  # thickness of PML
    sxy = 2 * (r + w + pad + dpml)  # cell size

    # Create a ring waveguide by two overlapping cylinders - later objects
    # take precedence over earlier objects, so we put the outer cylinder first.
    # and the inner (air) cylinder second.

    c1 = mp.Cylinder(radius=r + w, material=mp.Medium(index=n))
    c2 = mp.Cylinder(radius=r)

    # If we don't want to excite a specific mode symmetry, we can just
    # put a single point source at some arbitrary place, pointing in some
    # arbitrary direction.  We will only look for Ez-polarized modes.

    fcen = 0.15  # pulse center frequency
    df = 0.1  # pulse width (in frequency)

    src = mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r + 0.1))

    sim = mp.Simulation(cell_size=mp.Vector3(sxy, sxy),
                        geometry=[c1, c2],
                        sources=[src],
                        resolution=10,
                        symmetries=[mp.Mirror(mp.Y)],
                        boundary_layers=[mp.PML(dpml)])

    sim.run(
        mp.at_beginning(mp.output_epsilon),
        mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)),
        until_after_sources=300
    )

    # Output fields for one period at the end.  (If we output
    # at a single time, we might accidentally catch the Ez field when it is
    # almost zero and get a distorted view.)
    sim.run(mp.at_every((1 / fcen / 20), mp.output_efield_z), until=(1 / fcen))
Пример #25
0
def main():
    n = 3.4                 # index of waveguide
    w = 1                   # width of waveguide
    r = 1                   # inner radius of ring
    pad = 4                 # padding between waveguide and edge of PML
    dpml = 2                # thickness of PML
    sxy = 2*(r+w+pad+dpml)  # cell size

    # Create a ring waveguide by two overlapping cylinders - later objects
    # take precedence over earlier objects, so we put the outer cylinder first.
    # and the inner (air) cylinder second.

    c1 = mp.Cylinder(radius=r+w, material=mp.Medium(index=n))
    c2 = mp.Cylinder(radius=r)

    # If we don't want to excite a specific mode symmetry, we can just
    # put a single point source at some arbitrary place, pointing in some
    # arbitrary direction.  We will only look for Ez-polarized modes.

    fcen = 0.15             # pulse center frequency
    df = 0.1                # pulse width (in frequency)

    src = mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r+0.1))

    sim = mp.Simulation(cell_size=mp.Vector3(sxy, sxy),
                        geometry=[c1, c2],
                        sources=[src],
                        resolution=10,
                        symmetries=[mp.Mirror(mp.Y)],
                        boundary_layers=[mp.PML(dpml)])

    sim.run(mp.at_beginning(mp.output_epsilon),
            mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r+0.1), fcen, df)),
            until_after_sources=300)

    # Output fields for one period at the end.  (If we output
    # at a single time, we might accidentally catch the Ez field when it is
    # almost zero and get a distorted view.)
    sim.run(mp.at_every(1/fcen/20, mp.output_efield_z), until=1/fcen)
Пример #26
0
    def test_harminv(self):
        self.init()

        self.sim.run(mp.at_beginning(mp.output_epsilon),
                     mp.after_sources(self.h),
                     until_after_sources=300)

        m1 = self.h.modes[0]

        self.assertAlmostEqual(m1.freq, 0.118101315147, places=4)
        self.assertAlmostEqual(m1.decay, -0.000731513241623, places=4)
        self.assertAlmostEqual(abs(m1.amp), 0.00341267634436, places=4)
        self.assertAlmostEqual(m1.amp.real, -0.00304951667301, places=4)
        self.assertAlmostEqual(m1.amp.imag, -0.00153192946717, places=3)

        v = mp.Vector3(1, 1)
        fp = self.sim.get_field_point(mp.Ez, v)
        ep = self.sim.get_epsilon_point(v)

        places = 5 if mp.is_single_precision() else 7
        self.assertAlmostEqual(ep, 11.559999999999999, places=places)
        self.assertAlmostEqual(fp, -0.08185972142450348, places=places)
Пример #27
0
def main(args):
    resolution = 20 # 20 pixels per unit 1 um
    eps = 80 # epsilon of cylinder medium
    Mat1 = mp.Medium(epsilon=eps) # definition of the material
    dimensions = mp.CYLINDRICAL

    r = args.r # the value of cylinder radius
    rl = args.rl # the r/l ration is given, to obtain the l value l=r/rl
    x = args.x
    dpml = args.dpml
    dair = args.dair
    m=args.m

    w=1*x  
    h = r/rl # the height of the cylinder
    sr = r + dair + dpml
    sz = h + 2*dair + 2*dpml
    w_max=1.8
    w_min=0.2
    dw=w_max-w_min

    boundary_layers = [mp.PML(dpml)]
    Cyl = mp.Cylinder(material=Mat1, radius=r, height=h, center=mp.Vector3(0,0,0)) # make a cylinder with given parameters
    geometry = [Cyl]
    cell_size = mp.Vector3(sr,0,sz)

    #sources = [ mp.Source(mp.ContinuousSource(frequency = w), component=mp.Hz, center=mp.Vector3(r+dair,0,0)) ]
    sources = [mp.Source(mp.GaussianSource(w, fwidth=dw), component=mp.Hz, center=mp.Vector3(r+dair,0,0))]
    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell_size,
                        boundary_layers=boundary_layers,
                        geometry=geometry,
                        sources=sources,
                        dimensions=dimensions,
                        m=m)
    sim.run(mp.in_volume(mp.Volume(center=mp.Vector3(), size=mp.Vector3(sr,0,sz)),
            mp.at_end(mp.output_epsilon, mp.output_efield_z)),
            mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(), w, dw)),
            until_after_sources=100)
Пример #28
0
              component=mp.Ez,
              center=mp.Vector3(r + 0.1))
]

# exploit the mirror symmetry in structure+source:
symmetries = [mp.Mirror(mp.Y)]

sim = mp.Simulation(cell_size=cell,
                    resolution=resolution,
                    geometry=geometry,
                    boundary_layers=pml_layers,
                    sources=sources,
                    symmetries=symmetries)

h1 = mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)
sim.run(mp.after_sources(h1), until_after_sources=300)

fields2 = sim.fields
sim.reset_meep()

fcen = 0.236
h2 = mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)
sim.run(mp.after_sources(h2), until_after_sources=300)


def overlap_integral(r, ez1, ez2):
    return ez1.conjugate() * ez2


res = sim.integrate2_field_function(fields2, [mp.Ez], [mp.Ez],
                                    overlap_integral)
Пример #29
0
    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        sources=[],
                        boundary_layers=[mp.PML(dpml)],
                        resolution=20)

    if args.resonant_modes:
        sim.sources.append(mp.Source(mp.GaussianSource(fcen, fwidth=df),
                                     component=mp.Hz,
                                     center=mp.Vector3()))

        sim.symmetries.append(mp.Mirror(mp.Y, phase=-1))
        sim.symmetries.append(mp.Mirror(mp.X, phase=-1))

        sim.run(mp.at_beginning(mp.output_epsilon),
                mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(), fcen, df)),
                until_after_sources=400)

        sim.run(mp.at_every(1 / fcen / 20, mp.output_hfield_z), until=1 / fcen)
    else:
        sim.sources.append(mp.Source(mp.GaussianSource(fcen, fwidth=df),
                                     component=mp.Ey,
                                     center=mp.Vector3(-0.5 * sx + dpml),
                                     size=mp.Vector3(0, w)))

        sim.symmetries.append(mp.Mirror(mp.Y, phase=-1))

        freg = mp.FluxRegion(center=mp.Vector3(0.5 * sx - dpml - 0.5),
                             size=mp.Vector3(0, 2 * w))

        # transmitted flux
Пример #30
0
def main(args):
    # Some parameters to describe the geometry:
    eps = 13  # dielectric constant of waveguide
    w = 1.2  # width of waveguide
    r = 0.36  # radius of holes
    d = 1.4  # defect spacing (ordinary spacing = 1)
    N = args.N  # number of holes on either side of defect

    # The cell dimensions
    sy = args.sy  # size of cell in y direction (perpendicular to wvg.)
    pad = 2  # padding between last hole and PML edge
    dpml = 1  # PML thickness

    sx = 2 * (pad + dpml + N) + d - 1  # size of cell in x direction

    cell = mp.Vector3(sx, sy, 0)

    blk = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf),
                   material=mp.Medium(epsilon=eps))

    geometry = [blk]

    for i in range(N):
        geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i)))
        geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d / 2 + i))))

    fcen = args.fcen  # pulse center frequency
    df = args.df  # pulse frequency width

    nfreq = 500  # number of frequencies at which to compute flux

    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        sources=[],
                        boundary_layers=[mp.PML(dpml)],
                        resolution=20)

    if args.resonant_modes:
        sim.sources.append(
            mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz, mp.Vector3()))

        sim.symmetries.append(mp.Mirror(mp.Y, phase=-1))
        sim.symmetries.append(mp.Mirror(mp.X, phase=-1))

        sim.run(  # mp.at_beginning(mp.output_epsilon),
            mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(), fcen, df)),
            until_after_sources=400)

        # sim.run(mp.at_every(1 / fcen / 20, mp.output_hfield_z), until=1 / fcen)

    else:
        sim.sources.append(
            mp.Source(mp.GaussianSource(fcen, fwidth=df),
                      mp.Ey,
                      mp.Vector3(dpml + (-0.5 * sx)),
                      size=mp.Vector3(0, w)))

        sim.symmetries.append(mp.Mirror(mp.Y, phase=-1))

        freg = mp.FluxRegion(center=mp.Vector3((0.5 * sx) - dpml - 0.5),
                             size=mp.Vector3(0, 2 * w))

        # transmitted flux
        trans = sim.add_flux(fcen, df, nfreq, freg)

        vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sx))

        sim.run(mp.at_beginning(mp.output_epsilon),
                mp.during_sources(
                    mp.in_volume(
                        vol,
                        mp.to_appended("hz-slice",
                                       mp.at_every(0.4, mp.output_hfield_z)))),
                until_after_sources=mp.stop_when_fields_decayed(
                    50, mp.Ey, mp.Vector3((0.5 * sx) - dpml - 0.5, 0), 1e-3))

        sim.display_fluxes(trans)  # print out the flux spectrum
Пример #31
0
def parallel_waveguide(s,xodd):
    geometry = [mp.Block(center=mp.Vector3(-0.5*(s+a)),
                         size=mp.Vector3(a,a,mp.inf),
                         material=Si),
                mp.Block(center=mp.Vector3(0.5*(s+a)),
                         size=mp.Vector3(a,a,mp.inf),
                         material=Si)]

    symmetries = [mp.Mirror(mp.X, phase=-1.0 if xodd else 1.0),
                  mp.Mirror(mp.Y, phase=-1.0)]

    sources = [mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                         component=mp.Ey,
                         center=mp.Vector3(-0.5*(s+a)),
                         size=mp.Vector3(a,a)),
               mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                         component=mp.Ey,
                         center=mp.Vector3(0.5*(s+a)),
                         size=mp.Vector3(a,a),
                         amplitude=-1.0 if xodd else 1.0)]

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell,
                        boundary_layers=pml_layers,
                        geometry=geometry,
                        symmetries=symmetries,
                        k_point=k_point,
                        sources=sources)

    h = mp.Harminv(mp.Ey, mp.Vector3(0.5*(s+a)), fcen, df)

    sim.run(mp.after_sources(h), until_after_sources=200)

    f = h.modes[0].freq
    print("freq:, {}, {}".format(s, f))

    sim.reset_meep()

    eig_sources = [mp.EigenModeSource(src=mp.GaussianSource(f, fwidth=df),
                                      size=mp.Vector3(a,a),
                                      center=mp.Vector3(-0.5*(s+a)),
                                      eig_kpoint=k_point,
                                      eig_match_freq=True,
                                      eig_parity=mp.ODD_Y),
                   mp.EigenModeSource(src=mp.GaussianSource(f, fwidth=df),
                                      size=mp.Vector3(a,a),
                                      center=mp.Vector3(0.5*(s+a)),
                                      eig_kpoint=k_point,
                                      eig_match_freq=True,
                                      eig_parity=mp.ODD_Y,
                                      amplitude=-1.0 if xodd else 1.0)]

    sim.change_sources(eig_sources)

    flux_reg = mp.FluxRegion(direction=mp.Z, center=mp.Vector3(), size=mp.Vector3(1.2*(2*a+s),1.2*a))
    wvg_flux = sim.add_flux(f, 0, 1, flux_reg)

    force_reg1 = mp.ForceRegion(mp.Vector3(0.5*s), direction=mp.X, weight=1.0, size=mp.Vector3(y=a))
    force_reg2 = mp.ForceRegion(mp.Vector3(0.5*s+a), direction=mp.X, weight=-1.0, size=mp.Vector3(y=a))
    wvg_force = sim.add_force(f, 0, 1, force_reg1, force_reg2)

    sim.run(until_after_sources=5000)

    flux = mp.get_fluxes(wvg_flux)[0]
    force = mp.get_forces(wvg_force)[0]
    
    sim.reset_meep()
    return flux, force
Пример #32
0
def main(args):
    resolution = 20 # pixels/um
    
    eps = 13      # dielectric constant of waveguide
    w = 1.2       # width of waveguide
    r = 0.36      # radius of holes
    d = 1.4       # defect spacing (ordinary spacing = 1)
    N = args.N    # number of holes on either side of defect

    sy = args.sy  # size of cell in y direction (perpendicular to wvg.)
    pad = 2       # padding between last hole and PML edge
    dpml = 1      # PML thickness

    sx = 2*(pad+dpml+N)+d-1  # size of cell in x direction

    cell = mp.Vector3(sx,sy,0)

    blk = mp.Block(size=mp.Vector3(mp.inf,w,mp.inf),
                   material=mp.Medium(epsilon=eps))

    geometry = [blk]

    for i in range(N):
        geometry.append(mp.Cylinder(r, center=mp.Vector3(d/2+i)))
        geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d/2+i))))

    fcen = args.fcen  # pulse center frequency
    df = args.df      # pulse frequency width
    nfreq = 500       # number of frequencies at which to compute flux

    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        sources=[],
                        boundary_layers=[mp.PML(dpml)],
                        resolution=20)

    if args.resonant_modes:
        sim.sources.append(mp.Source(mp.GaussianSource(fcen, fwidth=df),
                                     component=mp.Hz,
                                     center=mp.Vector3()))

        sim.symmetries.append(mp.Mirror(mp.Y, phase=-1))
        sim.symmetries.append(mp.Mirror(mp.X, phase=-1))

        sim.run(mp.at_beginning(mp.output_epsilon),
                mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(), fcen, df)),
                until_after_sources=400)

        sim.run(mp.at_every(1/fcen/20, mp.output_hfield_z), until=1/fcen)
    else:
        sim.sources.append(mp.Source(mp.GaussianSource(fcen, fwidth=df),
                                     component=mp.Ey,
                                     center=mp.Vector3(-0.5*sx+dpml),
                                     size=mp.Vector3(0,w)))

        sim.symmetries.append(mp.Mirror(mp.Y, phase=-1))

        freg = mp.FluxRegion(center=mp.Vector3(0.5*sx-dpml-0.5),
                             size=mp.Vector3(0,2*w))

        # transmitted flux
        trans = sim.add_flux(fcen, df, nfreq, freg)

        vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sx))

        sim.run(mp.at_beginning(mp.output_epsilon),
                mp.during_sources(mp.in_volume(vol, mp.to_appended("hz-slice", mp.at_every(0.4, mp.output_hfield_z)))),
                until_after_sources=mp.stop_when_fields_decayed(50, mp.Ey, mp.Vector3(0.5*sx-dpml-0.5), 1e-3))

        sim.display_fluxes(trans)  # print out the flux spectrum
Пример #33
0
def main(args):
    resolution = 30   # pixels/μm
    
    Si = mp.Medium(index=3.45)

    dpml = 1.0
    pml_layers = [mp.PML(dpml)]
    
    sx = 5
    sy = 3
    cell = mp.Vector3(sx+2*dpml,sy+2*dpml,0)

    a = 1.0     # waveguide width
    s = args.s  # waveguide separation distance

    geometry = [mp.Block(center=mp.Vector3(-0.5*(s+a)),
                         size=mp.Vector3(a,a,mp.inf),
                         material=Si),
                mp.Block(center=mp.Vector3(0.5*(s+a)),
                         size=mp.Vector3(a,a,mp.inf),
                         material=Si)]

    xodd = args.xodd
    symmetries = [mp.Mirror(mp.X, phase=-1.0 if xodd else 1.0),
                  mp.Mirror(mp.Y, phase=-1.0)]

    k_point = mp.Vector3(z=0.5)

    fcen = 0.22
    df = 0.06
    sources = [mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                         component=mp.Ey,
                         center=mp.Vector3(-0.5*(s+a)),
                         size=mp.Vector3(a,a)),
               mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                         component=mp.Ey,
                         center=mp.Vector3(0.5*(s+a)),
                         size=mp.Vector3(a,a),
                         amplitude=-1.0 if xodd else 1.0)]

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell,
                        boundary_layers=pml_layers,
                        geometry=geometry,
                        symmetries=symmetries,
                        k_point=k_point,
                        sources=sources)

    h = mp.Harminv(mp.Ey, mp.Vector3(0.5*(s+a)), fcen, df)

    sim.run(mp.after_sources(h), until_after_sources=200)

    f = h.modes[0].freq
    print("freq:, {}, {}".format(s, f))

    sim.reset_meep()

    eig_sources = [mp.EigenModeSource(src=mp.GaussianSource(f, fwidth=df),
                                      size=mp.Vector3(a,a),
                                      center=mp.Vector3(-0.5*(s+a)),
                                      eig_kpoint=k_point,
                                      eig_match_freq=True,
                                      eig_parity=mp.ODD_Y),
                   mp.EigenModeSource(src=mp.GaussianSource(f, fwidth=df),
                                      size=mp.Vector3(a,a),
                                      center=mp.Vector3(0.5*(s+a)),
                                      eig_kpoint=k_point,
                                      eig_match_freq=True,
                                      eig_parity=mp.ODD_Y,
                                      amplitude=-1.0 if xodd else 1.0)]

    sim.change_sources(eig_sources)

    flux_reg = mp.FluxRegion(direction=mp.Z, center=mp.Vector3(), size=mp.Vector3(1.2*(2*a+s),1.2*a))
    wvg_flux = sim.add_flux(f, 0, 1, flux_reg)

    force_reg1 = mp.ForceRegion(mp.Vector3(0.5*s), direction=mp.X, weight=1.0, size=mp.Vector3(y=a))
    force_reg2 = mp.ForceRegion(mp.Vector3(0.5*s+a), direction=mp.X, weight=-1.0, size=mp.Vector3(y=a))
    wvg_force = sim.add_force(f, 0, 1, force_reg1, force_reg2)

    sim.run(until_after_sources=5000)

    sim.display_fluxes(wvg_flux)
    sim.display_forces(wvg_force)
Пример #34
0
fcen = 0.15  # pulse center frequency
df = 0.1  # pulse frequency width
src = mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r + 0.1))

sim = mp.Simulation(cell_size=mp.Vector3(sxy, sxy),
                    geometry=[c1, c2],
                    sources=[src],
                    resolution=10,
                    boundary_layers=[mp.PML(dpml)])
plt.figure(dpi=150)
sim.plot2D()
plt.savefig('structureBox.png')

sim.run(mp.at_beginning(mp.output_epsilon),
        mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)),
        until_after_sources=300)

sim.reset_meep()
fcen = 0.118
df = 0.1
sim.sources = [
    mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r + 0.1))
]

# Start the simulation and get into steady state
sim.run(until=600)

# Prepare the animator and record the steady state response
f = plt.figure(dpi=150)
Animate = mp.Animate2D(sim, fields=mp.Ez, f=f, realtime=False, normalize=True)
Пример #35
0
def parallel_waveguide(s, xodd):
    geometry = [
        mp.Block(center=mp.Vector3(-0.5 * (s + a)),
                 size=mp.Vector3(a, a, mp.inf),
                 material=Si),
        mp.Block(center=mp.Vector3(0.5 * (s + a)),
                 size=mp.Vector3(a, a, mp.inf),
                 material=Si)
    ]

    symmetries = [
        mp.Mirror(mp.X, phase=-1.0 if xodd else 1.0),
        mp.Mirror(mp.Y, phase=-1.0)
    ]

    sources = [
        mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ey,
                  center=mp.Vector3(-0.5 * (s + a)),
                  size=mp.Vector3(a, a)),
        mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ey,
                  center=mp.Vector3(0.5 * (s + a)),
                  size=mp.Vector3(a, a),
                  amplitude=-1.0 if xodd else 1.0)
    ]

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell,
                        boundary_layers=pml_layers,
                        geometry=geometry,
                        symmetries=symmetries,
                        k_point=k_point,
                        sources=sources)

    h = mp.Harminv(mp.Ey, mp.Vector3(0.5 * (s + a)), fcen, df)

    sim.run(mp.after_sources(h), until_after_sources=200)

    f = h.modes[0].freq
    print("freq:, {}, {}".format(s, f))

    sim.reset_meep()

    eig_sources = [
        mp.EigenModeSource(src=mp.GaussianSource(f, fwidth=df),
                           size=mp.Vector3(a, a),
                           center=mp.Vector3(-0.5 * (s + a)),
                           direction=mp.Z,
                           eig_kpoint=k_point,
                           eig_match_freq=True,
                           eig_parity=mp.ODD_Y),
        mp.EigenModeSource(src=mp.GaussianSource(f, fwidth=df),
                           size=mp.Vector3(a, a),
                           center=mp.Vector3(0.5 * (s + a)),
                           direction=mp.Z,
                           eig_kpoint=k_point,
                           eig_match_freq=True,
                           eig_parity=mp.ODD_Y,
                           amplitude=-1.0 if xodd else 1.0)
    ]

    sim.change_sources(eig_sources)

    flux_reg = mp.FluxRegion(direction=mp.Z,
                             center=mp.Vector3(),
                             size=mp.Vector3(1.2 * (2 * a + s), 1.2 * a))
    wvg_flux = sim.add_flux(f, 0, 1, flux_reg)

    force_reg1 = mp.ForceRegion(mp.Vector3(0.5 * s),
                                direction=mp.X,
                                weight=1.0,
                                size=mp.Vector3(y=a))
    force_reg2 = mp.ForceRegion(mp.Vector3(0.5 * s + a),
                                direction=mp.X,
                                weight=-1.0,
                                size=mp.Vector3(y=a))
    wvg_force = sim.add_force(f, 0, 1, force_reg1, force_reg2)

    sim.run(until_after_sources=5000)

    flux = mp.get_fluxes(wvg_flux)[0]
    force = mp.get_forces(wvg_force)[0]

    sim.reset_meep()
    return flux, force
def main():
    n = 3.4  # index of waveguide
    r = 1
    a = r  # inner radius of ring
    w = 1  # width of waveguide
    b = a + w  # outer radius of ring
    pad = 4  # padding between waveguide and edge of PML

    dpml = 2  # thickness of PML
    pml_layers = [mp.PML(dpml)]

    resolution = 100

    sr = b + pad + dpml  # radial size (cell is from 0 to sr)
    dimensions = mp.CYLINDRICAL  # coordinate system is (r,phi,z) instead of (x,y,z)
    cell = mp.Vector3(sr, 0, 0)

    m = 4

    geometry = [
        mp.Block(center=mp.Vector3(a + (w / 2)),
                 size=mp.Vector3(w, 1e20, 1e20),
                 material=mp.Medium(index=n))
    ]

    # Finding a resonance mode with a high Q-value (calculated with Harminv)

    fcen = 0.15  # pulse center frequency
    df = 0.1  # pulse width (in frequency)

    sources = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  mp.Hz,
                  mp.Vector3(r + 0.1),
                  amplitude=1)
    ]

    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        boundary_layers=pml_layers,
                        resolution=resolution,
                        sources=sources,
                        dimensions=dimensions,
                        m=m)

    h = mp.Harminv(mp.Hz, mp.Vector3(r + 0.1), fcen, df)
    sim.run(mp.after_sources(h), until_after_sources=200)

    Harminv_freq_at_R = h.modes[0].freq

    sim.reset_meep()

    # now running the simulation that will be used with perturbation theory to calculate dw/dR

    fcen = Harminv_freq_at_R
    df = 0.01

    sources = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  mp.Hz,
                  mp.Vector3(r + 0.1),
                  amplitude=1)
    ]

    sim = mp.Simulation(cell_size=cell,
                        geometry=geometry,
                        boundary_layers=pml_layers,
                        resolution=resolution,
                        sources=sources,
                        dimensions=dimensions,
                        m=m)

    sim.run(until_after_sources=200)

    # now need to calculate the surface integrals that go into dw/dR. Fields parallel and perpendicular to the interface
    # AND at the inner and outer surfaces are treated differently, so each will be calculated separately.

    # section for fields at inner surface
    npts_inner = 10
    angles_inner = 2 * np.pi / npts_inner * np.arange(npts_inner)
    deps_inner = 1 - n**2
    deps_inv_inner = 1 - 1 / (n**2)

    # section for fields parallel to interface (Ez and Ep)
    parallel_fields_inner = []
    for angle in angles_inner:
        point = mp.Vector3(a, angle)
        e_z_field = abs(sim.get_field_point(mp.Ez, point))**2
        e_p_field = abs(sim.get_field_point(mp.Ep, point))**2
        e_parallel_field = e_z_field + e_p_field
        # fields have to be multiplied by Δε
        e_parallel_field = deps_inner * e_parallel_field
        parallel_fields_inner.append(e_parallel_field)

    # section for fields perpendicular to interface (Er)
    perpendicular_fields_inner = []
    for angle in angles_inner:
        point = mp.Vector3(a, angle)
        e_r_field = abs(sim.get_field_point(mp.Er, point))**2
        e_perpendicular_field = e_r_field
        # fields have to be multiplied by Δ(1/ε) and ε**2
        e_perpendicular_field = deps_inv_inner * (abs(
            sim.get_epsilon_point(point, Harminv_freq_at_R))**
                                                  2) * e_perpendicular_field
        perpendicular_fields_inner.append(e_perpendicular_field)

    # section for fields at outer surface
    npts_outer = npts_inner
    angles_outer = 2 * np.pi / npts_outer * np.arange(npts_outer)
    deps_outer = n**2 - 1
    deps_inv_outer = -1 + 1 / (n**2)

    # section for fields parallel to interface (Ez and Ep)    parallel_fields_outer = []
    parallel_fields_outer = []
    for angle in angles_outer:
        point = mp.Vector3(b, angle)
        e_z_field = abs(sim.get_field_point(mp.Ez, point))**2
        e_p_field = abs(sim.get_field_point(mp.Ep, point))**2
        e_parallel_field = e_z_field + e_p_field
        # fields have to be multiplied by Δε
        e_parallel_field = deps_outer * e_parallel_field
        parallel_fields_outer.append(e_parallel_field)

    # section for fields perpendicular to interface (Er)
    perpendicular_fields_outer = []
    for angle in angles_inner:
        point = mp.Vector3(b, angle)
        e_r_field = abs(sim.get_field_point(mp.Er, point))
        e_perpendicular_field = e_r_field**2
        # fields have to be multiplied by Δ(1/ε) and ε**2
        e_perpendicular_field = deps_inv_outer * (abs(
            sim.get_epsilon_point(point, Harminv_freq_at_R))**
                                                  2) * e_perpendicular_field
        perpendicular_fields_outer.append(e_perpendicular_field)

    numerator_surface_integral = 2 * np.pi * b * (
        mean([mean(parallel_fields_inner),
              mean(parallel_fields_outer)]) - mean([
                  mean(perpendicular_fields_inner),
                  mean(perpendicular_fields_outer)
              ]))
    denominator_surface_integral = sim.electric_energy_in_box(
        center=mp.Vector3((b + pad / 2) / 2), size=mp.Vector3(b + pad / 2))
    perturb_theory_dw_dR = -Harminv_freq_at_R * numerator_surface_integral / (
        4 * denominator_surface_integral)

    center_diff_dw_dR = []
    Harminv_freqs_at_R_plus_dR = []

    drs = np.logspace(start=-3, stop=-1, num=10)

    for dr in drs:
        sim.reset_meep()
        w = 1 + dr  # width of waveguide
        b = a + w
        print(f'The current dr is dr={dr}')
        if len(Harminv_freqs_at_R_plus_dR) == 0:
            fcen = Harminv_freq_at_R
        else:
            fcen = Harminv_freqs_at_R_plus_dR[-1]
        df = 0.01

        sources = [
            mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz,
                      mp.Vector3(r + 0.1))
        ]

        geometry = [
            mp.Block(center=mp.Vector3(a + (w / 2)),
                     size=mp.Vector3(w, 1e20, 1e20),
                     material=mp.Medium(index=n))
        ]

        sim = mp.Simulation(cell_size=cell,
                            geometry=geometry,
                            boundary_layers=pml_layers,
                            resolution=resolution,
                            sources=sources,
                            dimensions=dimensions,
                            m=m)

        h = mp.Harminv(mp.Hz, mp.Vector3(r + 0.1), fcen, df)
        sim.run(mp.after_sources(h), until_after_sources=200)

        Harminv_freq_at_R_plus_dR = h.modes[0].freq
        Harminv_freqs_at_R_plus_dR.append(Harminv_freq_at_R_plus_dR)

        dw_dR = (Harminv_freq_at_R_plus_dR - Harminv_freq_at_R) / dr
        center_diff_dw_dR.append(dw_dR)

    relative_errors_dw_dR = [
        abs((dw_dR - perturb_theory_dw_dR) / dw_dR)
        for dw_dR in center_diff_dw_dR
    ]

    perturb_predicted_freqs_at_R_plus_dR = [
        dr * perturb_theory_dw_dR + Harminv_freq_at_R for dr in drs
    ]
    relative_errors_freqs_at_R_plus_dR = [
        abs((perturb_predicted_freqs_at_R_plus_dR[i] -
             Harminv_freqs_at_R_plus_dR[i]) / Harminv_freqs_at_R_plus_dR[i])
        for i in range(len(Harminv_freqs_at_R_plus_dR))
    ]

    if mp.am_master():
        plt.figure(dpi=150)
        plt.loglog(drs, relative_errors_dw_dR, 'bo-', label='relative error')
        plt.grid(True, which='both', ls='-')
        plt.xlabel('perturbation amount $dr$')
        plt.ylabel('relative error between $dω/dR$')
        plt.legend(loc='upper right')
        plt.title(
            'Comparison of Perturbation Theory and \nCenter-Difference Calculations in Finding $dω/dR$'
        )
        plt.tight_layout()
        # plt.show()
        plt.savefig('ring_Hz_perturbation_theory.dw_dR_error.png')
        plt.clf()

        plt.figure(dpi=150)
        plt.loglog(drs,
                   relative_errors_freqs_at_R_plus_dR,
                   'bo-',
                   label='relative error')
        plt.grid(True, which='both', ls='-')
        plt.xlabel('perturbation amount $dr$')
        plt.ylabel('relative error between $ω(R+dR)$')
        plt.legend(loc='upper left')
        plt.title(
            'Comparison of resonance frequencies at $R+dR$ predicted by\nperturbation theory and found with Harminv'
        )
        plt.tight_layout()
        # plt.show()
        plt.savefig('ring_Hz_perturbation_theory.freqs_error.png')
        plt.clf()
Пример #37
0
def main(args):
    resolution = 30  # pixels/μm

    Si = mp.Medium(index=3.45)

    dpml = 1.0
    pml_layers = [mp.PML(dpml)]

    sx = 5
    sy = 3
    cell = mp.Vector3(sx + 2 * dpml, sy + 2 * dpml, 0)

    a = 1.0  # waveguide width
    s = args.s  # waveguide separation distance

    geometry = [
        mp.Block(center=mp.Vector3(-0.5 * (s + a)),
                 size=mp.Vector3(a, a, mp.inf),
                 material=Si),
        mp.Block(center=mp.Vector3(0.5 * (s + a)),
                 size=mp.Vector3(a, a, mp.inf),
                 material=Si)
    ]

    xodd = args.xodd
    symmetries = [
        mp.Mirror(mp.X, phase=-1.0 if xodd else 1.0),
        mp.Mirror(mp.Y, phase=-1.0)
    ]

    k_point = mp.Vector3(z=0.5)

    fcen = 0.22
    df = 0.06
    sources = [
        mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ey,
                  center=mp.Vector3(-0.5 * (s + a)),
                  size=mp.Vector3(a, a)),
        mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ey,
                  center=mp.Vector3(0.5 * (s + a)),
                  size=mp.Vector3(a, a),
                  amplitude=-1.0 if xodd else 1.0)
    ]

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell,
                        boundary_layers=pml_layers,
                        geometry=geometry,
                        symmetries=symmetries,
                        k_point=k_point,
                        sources=sources)

    h = mp.Harminv(mp.Ey, mp.Vector3(0.5 * (s + a)), fcen, df)

    sim.run(mp.after_sources(h), until_after_sources=200)

    f = h.modes[0].freq
    print("freq:, {}, {}".format(s, f))

    sim.reset_meep()

    eig_sources = [
        mp.EigenModeSource(src=mp.GaussianSource(f, fwidth=df),
                           size=mp.Vector3(a, a),
                           center=mp.Vector3(-0.5 * (s + a)),
                           eig_kpoint=k_point,
                           eig_match_freq=True,
                           eig_parity=mp.ODD_Y),
        mp.EigenModeSource(src=mp.GaussianSource(f, fwidth=df),
                           size=mp.Vector3(a, a),
                           center=mp.Vector3(0.5 * (s + a)),
                           eig_kpoint=k_point,
                           eig_match_freq=True,
                           eig_parity=mp.ODD_Y,
                           amplitude=-1.0 if xodd else 1.0)
    ]

    sim.change_sources(eig_sources)

    flux_reg = mp.FluxRegion(direction=mp.Z,
                             center=mp.Vector3(),
                             size=mp.Vector3(1.2 * (2 * a + s), 1.2 * a))
    wvg_flux = sim.add_flux(f, 0, 1, flux_reg)

    force_reg1 = mp.ForceRegion(mp.Vector3(0.5 * s),
                                direction=mp.X,
                                weight=1.0,
                                size=mp.Vector3(y=a))
    force_reg2 = mp.ForceRegion(mp.Vector3(0.5 * s + a),
                                direction=mp.X,
                                weight=-1.0,
                                size=mp.Vector3(y=a))
    wvg_force = sim.add_force(f, 0, 1, force_reg1, force_reg2)

    sim.run(until_after_sources=5000)

    sim.display_fluxes(wvg_flux)
    sim.display_forces(wvg_force)
Пример #38
0
                    resolution=10,
                    symmetries=[mp.Mirror(mp.Y)],
                    boundary_layers=[mp.PML(dpml)],
                    filename_prefix=prefix)

h = mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)

if not os.path.isdir(path):
    sav.new_dir(path)
os.chdir(path)

#%% SIMULATION: FREQUENCY

start = time()
sim.run(mp.at_beginning(mp.output_epsilon),
        mp.after_sources(h),
        until_after_sources=300)
end = time()
print("Enlapsed time: {:.2f}".format(end - start))

#%% SIMULATION: FIELDS

freqs = [h.modes[i][0] for i in range(len(h.modes))]

label = lambda w: "Freq-{:.3f}".format(w)

path_freqs = []
start = [start, time()]
for i, w in enumerate(freqs):

    sim.reset_meep()
simulation.load_minus_flux_data(reflectionFluxMonitor, incidentFluxToSubtract)


def updateField(sim):
    global fieldData
    fieldEx = np.real(
        sim.get_array(center=mp.Vector3(0, 0, 0),
                      size=cellSize,
                      component=mp.Ex))
    fieldData = np.vstack((fieldData, fieldEx))


simulation.run(
    #mp.at_every(animationTimestepDuration, updateField),
    mp.after_sources(
        mp.Harminv(mp.Ex, mp.Vector3(0, 0, layerCenters[10]), frequency,
                   frequencyWidth)),
    until_after_sources=400)

incidentFlux = np.array(mp.get_fluxes(incidentFluxMonitor))
transmittedFlux = np.array(mp.get_fluxes(transmissionFluxMonitor))
reflectedFlux = np.array(mp.get_fluxes(reflectionFluxMonitor))
R = -reflectedFlux / incidentFlux
T = transmittedFlux / incidentFlux
#print(T)
#print(R)
#print(R + T)

#frequencies = np.array(mp.get_flux_freqs(reflectionFluxMonitor))
#reflectionSpectraFigure = plt.figure()
#reflectionSpectraAxes = plt.axes(xlim=(frequency-frequencyWidth/2, frequency+frequencyWidth/2),ylim=(0, 1))
Пример #40
0
df = 0.010   # pulse width (in frequency)
sources = [mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Ez,
                     center=mp.Vector3(r + 0.1))]

# exploit the mirror symmetry in structure+source:
symmetries = [mp.Mirror(mp.Y)]

sim = mp.Simulation(cell_size=cell,
                    resolution=resolution,
                    geometry=geometry,
                    boundary_layers=pml_layers,
                    sources=sources,
                    symmetries=symmetries)

h1 = mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)
sim.run(mp.after_sources(h1), until_after_sources=300)

fields2 = sim.fields
sim.reset_meep()

fcen = 0.236
h2 = mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)
sim.run(mp.after_sources(h2), until_after_sources=300)


def overlap_integral(r, ez1, ez2):
    return ez1.conjugate() * ez2

res = sim.integrate2_field_function(fields2, [mp.Ez], [mp.Ez], overlap_integral)
print("overlap integral of mode at w and 2w: {}".format(abs(res)))