예제 #1
0
    def _test_1d(self, sym):
        # A z=30 cell, split into three fragments of size 10 each, with a block
        # covering the middle fragment.

        # flux covering first fragment, near2far covering second, force covering third
        dft_vecs = make_dft_vecs(
            [mp.FluxRegion(mp.Vector3(z=-10), size=mp.Vector3(z=10))],
            [mp.Near2FarRegion(mp.Vector3(), size=mp.Vector3(z=10))],
            [mp.ForceRegion(mp.Vector3(z=10), direction=mp.X, size=mp.Vector3(z=10))]
        )

        fs = self.get_fragment_stats(mp.Vector3(z=10), mp.Vector3(z=30), 1, dft_vecs=dft_vecs, sym=sym)

        self.assertEqual(len(fs), 3)

        # First and last fragments have no geometry, only default_material
        for i in [0, 2]:
            self.check_stats(fs[i], 0, 0, 0, 0, 0)

        # Second fragment contains entire block
        sym_factor = 2 if sym else 1
        self.check_stats(fs[1],
                         a_eps=100 / sym_factor,
                         a_mu=100 / sym_factor,
                         nonlin=300 / sym_factor,
                         susc=300 / sym_factor,
                         cond=300 / sym_factor)

        # Check DFT regions
        self.assertEqual(fs[0].num_dft_pixels, 10240)
        self.assertEqual(fs[1].num_dft_pixels, 17120)
        self.assertEqual(fs[2].num_dft_pixels, 23840)
예제 #2
0
    def _test_1d(self, sym, pml=[]):
        # A z=30 cell, with a size 10 block in the middle.

        # flux covering first 10 units, near2far covering second 10, and force covering third
        dft_vecs = make_dft_vecs(
            [mp.FluxRegion(mp.Vector3(z=-10), size=mp.Vector3(z=10))],
            [mp.Near2FarRegion(mp.Vector3(), size=mp.Vector3(z=10))], [
                mp.ForceRegion(
                    mp.Vector3(z=10), direction=mp.X, size=mp.Vector3(z=10))
            ])

        fs = self.get_fragment_stats(mp.Vector3(z=10),
                                     mp.Vector3(z=30),
                                     1,
                                     dft_vecs=dft_vecs,
                                     sym=sym,
                                     pml=pml)

        sym_factor = 2 if sym else 1
        self.check_stats(fs,
                         a_eps=100 / sym_factor,
                         a_mu=100 / sym_factor,
                         nonlin=300 / sym_factor,
                         susc=300 / sym_factor,
                         cond=300 / sym_factor)

        # Check DFT regions
        self.assertEqual(fs.num_dft_pixels, 40800)
        self.fs = fs
예제 #3
0
    def _test_3d(self, sym):
        # A 30 x 30 x 30 cell with a 10 x 10 x 10 block placed at the center, split
        # into 27 10 x 10 x 10 fragments

        # flux covering lower-front-left fragment, near2far covering lower-middle-left,
        # force covering lower-back-left
        dft_vecs = make_dft_vecs(
            [mp.FluxRegion(mp.Vector3(-10, -10, -10), size=mp.Vector3(10, 10, 10))],
            [mp.Near2FarRegion(mp.Vector3(-10, -10, 0), size=mp.Vector3(10, 10, 10))],
            [mp.ForceRegion(mp.Vector3(-10, -10, 10), direction=mp.X, size=mp.Vector3(10, 10, 10))]
        )
        fs = self.get_fragment_stats(mp.Vector3(10, 10, 10), mp.Vector3(30, 30, 30), 3, dft_vecs=dft_vecs, sym=sym)

        self.assertEqual(len(fs), 27)

        # All fragments besides the middle one have no geometry, only default_material
        for i in range(27):
            if i == 13:
                continue
            self.check_stats(fs[i], 0, 0, 0, 0, 0)

        # Middle fragments contains entire block
        idx = 13
        sym_factor = 8 if sym else 1
        self.check_stats(fs[idx],
                         a_eps=10000 / sym_factor,
                         a_mu=10000 / sym_factor,
                         nonlin=30000 / sym_factor,
                         susc=30000 / sym_factor,
                         cond=30000 / sym_factor)

        # Check DFT regions
        self.assertEqual(fs[0].num_dft_pixels, 256000)
        self.assertEqual(fs[1].num_dft_pixels, 428000)
        self.assertEqual(fs[2].num_dft_pixels, 596000)
예제 #4
0
    def setUp(self):

        resolution = 20
        cell = mp.Vector3(10, 10)
        pml_layers = mp.PML(1.0)
        fcen = 1.0
        df = 1.0
        sources = mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
                            center=mp.Vector3(),
                            component=mp.Ez)

        self.sim = mp.Simulation(resolution=resolution,
                                 cell_size=cell,
                                 boundary_layers=[pml_layers],
                                 sources=[sources])

        fr = mp.ForceRegion(mp.Vector3(y=1.27),
                            direction=mp.Y,
                            size=mp.Vector3(4.38))
        self.myforce = self.sim.add_force(fcen, 0, 1, fr, decimation_factor=1)
        self.myforce_decimated = self.sim.add_force(fcen,
                                                    0,
                                                    1,
                                                    fr,
                                                    decimation_factor=10)
예제 #5
0
    def _test_2d(self, sym):
        # A 30 x 30 cell, with a 10 x 10 block in the middle, split into 9 10 x 10 fragments.

        # flux covering top-left fragment, near2far covering top-middle, force covering top-right
        dft_vecs = make_dft_vecs(
            [mp.FluxRegion(mp.Vector3(-10, 10), size=mp.Vector3(10, 10))],
            [mp.Near2FarRegion(mp.Vector3(0, 10), size=mp.Vector3(10, 10))], [
                mp.ForceRegion(mp.Vector3(10, 10),
                               direction=mp.X,
                               size=mp.Vector3(10, 10))
            ])
        fs = self.get_fragment_stats(mp.Vector3(10, 10),
                                     mp.Vector3(30, 30),
                                     2,
                                     dft_vecs=dft_vecs,
                                     sym=sym)

        self.assertEqual(len(fs), 9)

        # Check fragment boxes
        self.assertEqual(fs[0].box.low.x, -15)
        self.assertEqual(fs[0].box.low.y, -15)
        self.assertEqual(fs[0].box.high.x, -5)
        self.assertEqual(fs[0].box.high.y, -5)

        self.assertEqual(fs[1].box.low.x, -15)
        self.assertEqual(fs[1].box.low.y, -5)
        self.assertEqual(fs[1].box.high.x, -5)
        self.assertEqual(fs[1].box.high.y, 5)

        self.assertEqual(fs[2].box.low.x, -15)
        self.assertEqual(fs[2].box.low.y, 5)
        self.assertEqual(fs[2].box.high.x, -5)
        self.assertEqual(fs[2].box.high.y, 15)

        # All fragments besides the middle one have no geometry, only default_material
        for i in [0, 1, 2, 3, 5, 6, 7, 8]:
            self.check_stats(fs[i], 0, 0, 0, 0, 0)

        # Middle fragment contains entire block
        idx = 4
        sym_factor = 4 if sym else 1
        self.check_stats(fs[idx],
                         a_eps=10000 / sym_factor,
                         a_mu=10000 / sym_factor,
                         nonlin=30000 / sym_factor,
                         susc=30000 / sym_factor,
                         cond=30000 / sym_factor)

        # Check DFT regions
        for i in [0, 3, 6]:
            self.assertEqual(fs[i].num_dft_pixels, 0)

        self.assertEqual(fs[1].num_dft_pixels, 8224)
        self.assertEqual(fs[4].num_dft_pixels, 11792)
        self.assertEqual(fs[7].num_dft_pixels, 21824)

        self.assertEqual(fs[2].num_dft_pixels, 411200)
        self.assertEqual(fs[5].num_dft_pixels, 589600)
        self.assertEqual(fs[8].num_dft_pixels, 1091200)
예제 #6
0
    def _test_3d(self, sym, pml=[]):
        # A 30 x 30 x 30 cell with a 10 x 10 x 10 block placed at the center

        # flux covering lower-front-left 10x10x10, near2far covering lower-middle-left,
        # force covering lower-back-left
        dft_vecs = make_dft_vecs([
            mp.FluxRegion(mp.Vector3(-10, -10, -10),
                          size=mp.Vector3(10, 10, 10))
        ], [
            mp.Near2FarRegion(mp.Vector3(-10, -10, 0),
                              size=mp.Vector3(10, 10, 10))
        ], [
            mp.ForceRegion(mp.Vector3(-10, -10, 10),
                           direction=mp.X,
                           size=mp.Vector3(10, 10, 10))
        ])
        fs = self.get_fragment_stats(mp.Vector3(10, 10, 10),
                                     mp.Vector3(30, 30, 30),
                                     3,
                                     dft_vecs=dft_vecs,
                                     sym=sym,
                                     pml=pml)

        sym_factor = 8 if sym else 1
        self.check_stats(fs,
                         a_eps=1000000 / sym_factor,
                         a_mu=1000000 / sym_factor,
                         nonlin=3000000 / sym_factor,
                         susc=3000000 / sym_factor,
                         cond=3000000 / sym_factor)

        # Check DFT regions
        self.assertEqual(fs.num_dft_pixels, 102000000)
        self.fs = fs
예제 #7
0
    def test_cyl(self):
        # A 30 x 30 cell, with a 10 x 10 block in the middle

        # flux covering top-left fragment, near2far covering top-middle, force covering top-right
        dft_vecs = make_dft_vecs([
            mp.FluxRegion(mp.Vector3(-10, z=10), size=mp.Vector3(10, z=10))
        ], [mp.Near2FarRegion(mp.Vector3(0, z=10), size=mp.Vector3(10, z=10))],
                                 [
                                     mp.ForceRegion(mp.Vector3(10, z=10),
                                                    direction=mp.X,
                                                    size=mp.Vector3(10, z=10))
                                 ])
        fs = self.get_fragment_stats(mp.Vector3(10, 0, 10),
                                     mp.Vector3(30, 0, 30),
                                     mp.CYLINDRICAL,
                                     dft_vecs=dft_vecs)
        self.assertEqual(fs.box.low.x, -15)
        self.assertEqual(fs.box.low.z, -15)
        self.assertEqual(fs.box.high.x, 15)
        self.assertEqual(fs.box.high.z, 15)
        self.check_stats(fs,
                         a_eps=10000,
                         a_mu=10000,
                         nonlin=30000,
                         susc=30000,
                         cond=30000)
        self.assertEqual(fs.num_dft_pixels, 2040000)
예제 #8
0
    def _test_2d(self, sym, pml=[]):
        # A 30 x 30 cell, with a 10 x 10 block in the middle

        # flux covering top-left 10x10, near2far covering top-middle 10x10, force covering top-right
        dft_vecs = make_dft_vecs(
            [mp.FluxRegion(mp.Vector3(-10, 10), size=mp.Vector3(10, 10))],
            [mp.Near2FarRegion(mp.Vector3(0, 10), size=mp.Vector3(10, 10))],
            [mp.ForceRegion(mp.Vector3(10, 10), direction=mp.X, size=mp.Vector3(10, 10))]
        )
        fs = self.get_fragment_stats(mp.Vector3(10, 10), mp.Vector3(30, 30), 2,
                                     dft_vecs=dft_vecs, sym=sym, pml=pml)

        # Check fragment boxes
        self.assertEqual(fs.box.low.x, -15)
        self.assertEqual(fs.box.low.y, -15)
        self.assertEqual(fs.box.high.x, 15)
        self.assertEqual(fs.box.high.y, 15)

        # Middle fragment contains entire block
        sym_factor = 4 if sym else 1
        self.check_stats(fs,
                         a_eps=90000 / sym_factor,
                         a_mu=90000 / sym_factor,
                         nonlin=30000 / sym_factor,
                         susc=30000 / sym_factor,
                         cond=30000 / sym_factor)

        # Check DFT regions
        self.assertEqual(fs.num_dft_pixels, 2040000)
        self.fs = fs
예제 #9
0
    def test_cyl(self):
        # A 30 x 30 cell, with a 10 x 10 block in the middle, split into 9 10 x 10 fragments.

        # flux covering top-left fragment, near2far covering top-middle, force covering top-right
        dft_vecs = make_dft_vecs([
            mp.FluxRegion(mp.Vector3(-10, z=10), size=mp.Vector3(10, z=10))
        ], [mp.Near2FarRegion(mp.Vector3(0, z=10), size=mp.Vector3(10, z=10))],
                                 [
                                     mp.ForceRegion(mp.Vector3(10, z=10),
                                                    mp.X,
                                                    size=mp.Vector3(10, z=10))
                                 ])
        fs = self.get_fragment_stats(mp.Vector3(10, 0, 10),
                                     mp.Vector3(30, 0, 30),
                                     mp.CYLINDRICAL,
                                     dft_vecs=dft_vecs)

        self.assertEqual(len(fs), 9)

        # Check fragment boxes
        self.assertEqual(fs[0].box.low.x, -15)
        self.assertEqual(fs[0].box.low.z, -15)
        self.assertEqual(fs[0].box.high.x, -5)
        self.assertEqual(fs[0].box.high.z, -5)

        self.assertEqual(fs[1].box.low.x, -15)
        self.assertEqual(fs[1].box.low.z, -5)
        self.assertEqual(fs[1].box.high.x, -5)
        self.assertEqual(fs[1].box.high.z, 5)

        self.assertEqual(fs[2].box.low.x, -15)
        self.assertEqual(fs[2].box.low.z, 5)
        self.assertEqual(fs[2].box.high.x, -5)
        self.assertEqual(fs[2].box.high.z, 15)

        # All fragments besides the middle one have no geometry, only default_material
        for i in [0, 1, 2, 3, 5, 6, 7, 8]:
            self.check_stats(fs[i], 0, 0, 0, 0, 0)

        # Middle fragment contains entire block
        idx = 4
        self.check_stats(fs[idx],
                         a_eps=1000,
                         a_mu=1000,
                         nonlin=3000,
                         susc=3000,
                         cond=3000)

        # Check DFT regions
        for i in [0, 3, 6]:
            self.assertEqual(fs[i].num_dft_pixels, 0)

        self.assertEqual(fs[1].num_dft_pixels, 10240)
        self.assertEqual(fs[4].num_dft_pixels, 17120)
        self.assertEqual(fs[7].num_dft_pixels, 23840)

        self.assertEqual(fs[2].num_dft_pixels, 51200)
        self.assertEqual(fs[5].num_dft_pixels, 85600)
        self.assertEqual(fs[8].num_dft_pixels, 119200)
예제 #10
0
def force_box_2d(position, size, component):
    """create 4 force planes (2D) to calculate the component of a force"""
    force_x1 = meep.ForceRegion(center=position - meep.Vector3(0, size[1] / 2),
                                size=meep.Vector3(size[0], 0),
                                direction=component,
                                weight=-1)
    force_x2 = meep.ForceRegion(center=position + meep.Vector3(0, size[1] / 2),
                                size=meep.Vector3(size[0], 0),
                                direction=component,
                                weight=1)

    force_y1 = meep.ForceRegion(center=position - meep.Vector3(size[0] / 2, 0),
                                size=meep.Vector3(0, size[1]),
                                direction=component,
                                weight=-1)
    force_y2 = meep.ForceRegion(center=position + meep.Vector3(size[0] / 2, 0),
                                size=meep.Vector3(0, size[1]),
                                direction=component,
                                weight=1)

    return [force_x1, force_x2, force_y1, force_y2]
예제 #11
0
def force_box(position, size, component):
    """create 6 force planes to calculate the component of a force"""
    position = meep.Vector3(*position)
    size = meep.Vector3(*size)

    force_x1 = meep.ForceRegion(center=position -
                                meep.Vector3(size[0] / 2, 0, 0),
                                size=meep.Vector3(0, size[1], size[2]),
                                weight=-1,
                                direction=component)

    force_x2 = meep.ForceRegion(center=position +
                                meep.Vector3(size[0] / 2, 0, 0),
                                size=meep.Vector3(0, size[1], size[2]),
                                weight=1,
                                direction=component)

    force_y1 = meep.ForceRegion(center=position -
                                meep.Vector3(0, size[1] / 2, 0),
                                size=meep.Vector3(size[0], 0, size[2]),
                                weight=-1,
                                direction=component)

    force_y2 = meep.ForceRegion(center=position +
                                meep.Vector3(0, size[1] / 2, 0),
                                size=meep.Vector3(size[0], 0, size[2]),
                                weight=1,
                                direction=component)

    force_z1 = meep.ForceRegion(center=position -
                                meep.Vector3(0, 0, size[2] / 2),
                                size=meep.Vector3(size[0], size[1], 0),
                                weight=-1,
                                direction=component)

    force_z2 = meep.ForceRegion(center=position +
                                meep.Vector3(0, 0, size[2] / 2),
                                size=meep.Vector3(size[0], size[1], 0),
                                weight=1,
                                direction=component)

    return [force_x1, force_x2, force_y1, force_y2, force_z1, force_z2]
예제 #12
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)
예제 #13
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
예제 #14
0
                       component=mp.Ey,
                       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(new_sources)

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

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

runtime = 5000
sim.run(until_after_sources=runtime)
sim.display_fluxes(wvg_pwr)
sim.display_forces(wvg_force)
예제 #15
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 if xodd else 1),
        mp.Mirror(mp.Y, phase=-1)
    ]

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

    sim.init_sim()
    EigenmodeData = sim.get_eigenmode(0.22,
                                      mp.Z,
                                      mp.Volume(center=mp.Vector3(),
                                                size=mp.Vector3(sx, sy)),
                                      2 if xodd else 1,
                                      k_point,
                                      match_frequency=False,
                                      parity=mp.ODD_Y)

    fcen = EigenmodeData.freq
    print("freq:, {}, {}, {}".format("xodd" if xodd else "xeven", s, fcen))

    sim.reset_meep()

    eig_sources = [
        mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=0.1 * fcen),
                           size=mp.Vector3(sx, sy),
                           center=mp.Vector3(),
                           eig_band=2 if xodd else 1,
                           eig_kpoint=k_point,
                           eig_match_freq=False,
                           eig_parity=mp.ODD_Y)
    ]

    sim.change_sources(eig_sources)

    flux_reg = mp.FluxRegion(direction=mp.Z,
                             center=mp.Vector3(),
                             size=mp.Vector3(sx, sy))
    wvg_flux = sim.add_flux(fcen, 0, 1, flux_reg)

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

    sim.run(until_after_sources=1500)

    flux = mp.get_fluxes(wvg_flux)[0]
    force = mp.get_forces(wvg_force)[0]
    print("data:, {}, {}, {}, {}, {}".format("xodd" if xodd else "xeven", s,
                                             flux, force, -force / flux))

    sim.reset_meep()
    return flux, force