Пример #1
0
    mp.Block(center=mp.Vector3(y=Sy / 4),
             material=Si,
             size=mp.Vector3(0.5, Sy / 2, 0)),  # vertical waveguide
    mp.Block(center=design_region.center,
             size=design_region.size,
             material=design_variables),  # design region
    mp.Block(center=design_region.center,
             size=design_region.size,
             material=design_variables,
             e1=mp.Vector3(x=-1).rotate(mp.Vector3(z=1), np.pi / 2),
             e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), np.pi / 2))
]

sim = mp.Simulation(cell_size=cell_size,
                    boundary_layers=pml_layers,
                    geometry=geometry,
                    sources=source,
                    eps_averaging=False,
                    resolution=resolution)

TE_top = mpa.EigenmodeCoefficient(sim,
                                  mp.Volume(center=mp.Vector3(0, 1, 0),
                                            size=mp.Vector3(x=2)),
                                  mode=1)
ob_list = [TE_top]


def J(alpha):
    return npa.abs(alpha)**2


opt = mpa.OptimizationProblem(simulation=sim,
Пример #2
0
    def __init__(self, dir_name, wavelength, thy_absorb, cyt_absorb):
        self.base_directory = base_directory + str(dir_name)

        self.wavelength = wavelength
        self.thy_absorb = thy_absorb
        self.cyt_absorb = cyt_absorb
        self.frequency = 1 / wavelength
        # Calculate wavelengths dependent on RI
        self.wavelength_in_media = wavelength / ri_media
        self.wavelength_in_cytoplasm = wavelength / ri_cytoplasm
        self.wavelength_in_thylakoid = wavelength / ri_thylakoid
        max_freq = self.frequency - 0.01
        min_freq = self.frequency + 0.01
        self.pulse_width = abs(max_freq - min_freq)

        cell = mp.Vector3(sxx, sxy, sxz)
        pml_layers = [mp.PML(dpml)]

        thylakoid_material = mp.Medium(index=ri_thylakoid,
                                       D_conductivity=2 * math.pi *
                                       self.frequency * (thy_absorb /
                                                         (ri_thylakoid**2)))
        cytoplasm_material = mp.Medium(index=ri_cytoplasm,
                                       D_conductivity=2 * math.pi *
                                       self.frequency * (cyt_absorb /
                                                         (ri_cytoplasm**2)))

        thylakoid_region = mp.Sphere(radius=cell_radius,
                                     center=mp.Vector3(0, 0, 0),
                                     material=thylakoid_material)
        cytoplasm_region = mp.Sphere(radius=cell_radius - thylakoid_thickness,
                                     center=mp.Vector3(0, 0, 0),
                                     material=cytoplasm_material)
        geometry = [thylakoid_region, cytoplasm_region]

        # Sources
        kdir = mp.Vector3(1, 0, 0)  # direction of k (length is irrelevant)
        n = ri_media  # refractive index of material containing the source
        k = kdir.unit().scale(2 * math.pi * self.frequency *
                              n)  # k with correct length

        def pw_amp(k, x0):
            def _pw_amp(x):
                return cmath.exp(1j * k.dot(x + x0))

            return _pw_amp

        source = [
            mp.Source(
                mp.ContinuousSource(frequency=self.frequency,
                                    fwidth=self.pulse_width),  # along x axis
                component=mp.Ez,
                center=mp.Vector3(-0.5 * simulation_size, 0, 0),  # x, ,y ,z
                size=mp.Vector3(0, sxy, sxz),
                amp_func=pw_amp(k, mp.Vector3(x=-0.5 * simulation_size)))
        ]

        sim = mp.Simulation(
            cell_size=cell,
            sources=source,
            boundary_layers=pml_layers,
            resolution=resolution,
            geometry=geometry,
            default_material=mp.Medium(index=ri_media),
            force_complex_fields=complex_f,
            eps_averaging=eps_av,
        )

        def output_fields(sim):
            ez_output = open(base_directory + "Ez Field 650 HiAbs" + ".npy",
                             'wb')
            ez_array = sim.get_array(component=mp.Ez, cmplx=complex_f)
            ez_field_output = np.asarray(ez_array)
            np.save(ez_output, ez_field_output)
            ez_output.close()

            # ey_output = open(base_directory + "Ey Field 300 Std" + ".npy", 'wb')
            # ey_array = sim.get_array(component=mp.Ey, cmplx=complex_f)
            # ey_field_output = np.asarray(ey_array)
            # np.save(ey_output, ey_field_output)
            # ey_output.close()
            #
            # ex_output = open(base_directory + "Ex Field 300 std abs" + ".npy", 'wb')
            # ex_array = sim.get_array(component=mp.Ex, cmplx=complex_f)
            # ex_field_output = np.asarray(ex_array)
            # np.save(ex_output, ex_field_output)
            # ex_output.close()

            # eps_output = open(base_directory + "Refractive Index" + ".npy", 'wb')
            # eps_array = sim.get_array(component=mp.Dielectric, cmplx=complex_f)
            # np.save(eps_output, eps_array)
            # eps_output.close()

        sim.use_output_directory(self.base_directory)
        sim.run(mp.at_every(1, output_fields), until=t)
Пример #3
0
              component=comp,
              center=mp.Vector3(-sizex / 2, 0))
]

# Absorber on grating side because of field divergence at metal/pml interface
pml_layers = [
    mp.PML(pml_th, direction=mp.X),
    mp.Absorber(pml_th, direction=mp.Y)
]

# empty cell for reference run
geometry = []
sim = mp.Simulation(cell_size=cell,
                    boundary_layers=pml_layers,
                    geometry=geometry,
                    sources=sources,
                    resolution=resolution,
                    filename_prefix="data",
                    split_chunks_evenly=False)

# define monitors for further spectra calculation
mon_height = sizey
nfreq = 200
mon_skip = sizex / 20  # small skip from PML layers
refl_fr = mp.FluxRegion(center=mp.Vector3(-sizex / 2 + mon_skip, 0, 0),
                        size=mp.Vector3(0, mon_height, 0))
# flux region FFT region
refl = sim.add_flux(cfreq, fwidth, nfreq, refl_fr)

tran_fr = mp.FluxRegion(center=mp.Vector3(sizex / 2 - mon_skip, 0, 0),
                        size=mp.Vector3(0, mon_height, 0))
Пример #4
0
# create a transparent source that excites a right-going waveguide mode
modeNumber = 2
sources = [
    mp.EigenModeSource(src=mp.ContinuousSource(1/1.55), direction=mp.X,
                       center=mp.Vector3(),eig_band=modeNumber)
]


force_complex_fields = True  # so we can get time-average flux

resolution = 20

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

sim.run(
    mp.at_beginning(mp.output_epsilon),
    mp.at_end(mp.output_png(mp.Ex, "-a yarg -A $EPS -S3 -Zc dkbluered", rm_h5=False)),
    until=200
)

flux1 = sim.flux_in_box(mp.X, mp.Volume(center=mp.Vector3(-2.0), size=mp.Vector3(1.8, 6)))
flux2 = sim.flux_in_box(mp.X, mp.Volume(center=mp.Vector3(2.0), size=mp.Vector3(1.8, 6)))

# averaged over y region of width 1.8
print("left-going flux = {}".format(flux1 / -1.8))
Пример #5
0
def simulate_metalens(metalens):
    # Setup the MEEP objects
    cell = mp.Vector3(metalens['sim_cell_width'], metalens['sim_cell_height'])
    # All around the simulation cell
    pml_layers = [mp.PML(metalens['pml_width'])]
    # Set up the sources
    sources = [
        mp.Source(src=mp.ContinuousSource(wavelength=metalens['wavelength'],
                                          width=metalens['source_width']),
                  component=mp.Ex,
                  amp_func=in_plane_dip_amp_func_Ex(metalens),
                  center=mp.Vector3(0, metalens['source_coord']),
                  size=mp.Vector3(2 * metalens['ws'], 0)),
        mp.Source(src=mp.ContinuousSource(wavelength=metalens['wavelength'],
                                          width=metalens['source_width']),
                  component=mp.Hz,
                  amp_func=in_plane_dip_amp_func_Hz(metalens),
                  center=mp.Vector3(0, metalens['source_coord']),
                  size=mp.Vector3(2 * metalens['ws'], 0))
    ]
    # Set up the symmetries
    syms = []
    if metalens['x_mirror_symmetry'] and (metalens['beta'] == 0
                                          or metalens['beta'] == np.pi / 2):
        syms.append(mp.Mirror(mp.X))
    sim = mp.Simulation(cell_size=cell,
                        boundary_layers=pml_layers,
                        geometry=metalens['geometry'],
                        force_complex_fields=metalens['complex_fields'],
                        symmetries=syms,
                        sources=sources,
                        resolution=metalens['resolution'])
    start_time = time.time()
    metalens['run_date'] = (
        datetime.datetime.now().strftime("%b %d %Y at %H:%M:%S"))
    mp.quiet(metalens['quiet'])
    sim.init_sim()

    # Branch if saving for making an animation
    if metalens['save_output']:
        sim.run(mp.to_appended(
            "ez-{sim_id}".format(**metalens),
            mp.at_every(metalens['simulation_time'] / 1000.,
                        mp.output_efield_z)),
                until=metalens['simulation_time'])
    else:
        sim.run(until=metalens['simulation_time'])

    # Compute the clock run time and grab the fields
    metalens['array_metadata'] = sim.get_array_metadata()
    metalens['run_time_in_s'] = time.time() - start_time
    metalens['fields'] = {
        'Ex': sim.get_array(component=mp.Ex).transpose(),
        'Ey': sim.get_array(component=mp.Ey).transpose(),
        'Hz': sim.get_array(component=mp.Hz).transpose()
    }
    metalens['eps'] = sim.get_epsilon().transpose()
    # Dump the result to disk
    if metalens['log_to_pkl'][0]:
        if metalens['log_to_pkl'][1] == '':
            pkl_fname = '%smetalens-%s.pkl' % (datadir, metalens['sim_id'])
        else:
            pkl_fname = metalens['log_to_pkl'][1]
        print(pkl_fname)
        pickle.dump(metalens, open(pkl_fname, 'wb'))
    return metalens
Пример #6
0
    def init(self, no_bend=False, gdsii=False):
        sx = 16
        sy = 32
        cell = mp.Vector3(sx, sy, 0)
        pad = 4
        w = 1
        wvg_ycen = -0.5 * (sy - w - (2 * pad))
        wvg_xcen = 0.5 * (sx - w - (2 * pad))
        height = 100
        data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                'data')
        gdsii_file = os.path.join(data_dir, 'bend-flux.gds')

        if no_bend:
            if gdsii:
                geometry = mp.get_GDSII_prisms(mp.Medium(epsilon=12),
                                               gdsii_file, 1)
            else:
                no_bend_vertices = [
                    mp.Vector3(-0.5 * sx - 5, wvg_ycen - 0.5 * w),
                    mp.Vector3(+0.5 * sx + 5, wvg_ycen - 0.5 * w),
                    mp.Vector3(+0.5 * sx + 5, wvg_ycen + 0.5 * w),
                    mp.Vector3(-0.5 * sx - 5, wvg_ycen + 0.5 * w)
                ]

                geometry = [
                    mp.Prism(no_bend_vertices,
                             height,
                             material=mp.Medium(epsilon=12))
                ]
        else:
            if gdsii:
                geometry = mp.get_GDSII_prisms(mp.Medium(epsilon=12),
                                               gdsii_file, 2)
            else:
                bend_vertices = [
                    mp.Vector3(-0.5 * sx, wvg_ycen - 0.5 * w),
                    mp.Vector3(wvg_xcen + 0.5 * w, wvg_ycen - 0.5 * w),
                    mp.Vector3(wvg_xcen + 0.5 * w, 0.5 * sy),
                    mp.Vector3(wvg_xcen - 0.5 * w, 0.5 * sy),
                    mp.Vector3(wvg_xcen - 0.5 * w, wvg_ycen + 0.5 * w),
                    mp.Vector3(-0.5 * sx, wvg_ycen + 0.5 * w)
                ]

                geometry = [
                    mp.Prism(bend_vertices,
                             height,
                             material=mp.Medium(epsilon=12))
                ]

        fcen = 0.15
        df = 0.1
        sources = [
            mp.Source(mp.GaussianSource(fcen, fwidth=df),
                      component=mp.Ez,
                      center=mp.Vector3(1 + (-0.5 * sx), wvg_ycen),
                      size=mp.Vector3(0, w))
        ]

        pml_layers = [mp.PML(1.0)]
        resolution = 10
        nfreq = 100

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

        if no_bend:
            fr = mp.FluxRegion(center=mp.Vector3((sx / 2) - 1.5, wvg_ycen),
                               size=mp.Vector3(0, w * 2))
        else:
            fr = mp.FluxRegion(center=mp.Vector3(wvg_xcen, (sy / 2) - 1.5),
                               size=mp.Vector3(w * 2, 0))

        self.trans = self.sim.add_flux(fcen, df, nfreq, fr)
        refl_fr = mp.FluxRegion(center=mp.Vector3((-0.5 * sx) + 1.5, wvg_ycen),
                                size=mp.Vector3(0, w * 2))

        self.refl = self.sim.add_flux(fcen, df, nfreq, refl_fr)

        if no_bend:
            self.pt = mp.Vector3((sx / 2) - 1.5, wvg_ycen)
        else:
            self.pt = mp.Vector3(wvg_xcen, (sy / 2) - 1.5)
Пример #7
0
             material=mp.Medium(epsilon=12))
]

fcen = 0.15
df = 0.1

sources = [
    mp.Source(mp.GaussianSource(fcen, fwidth=df),
              component=mp.Ez,
              center=mp.Vector3(-0.5 * sx + dpml, wvg_ycen, 0),
              size=mp.Vector3(0, w, 0))
]

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

# reflected flux
refl_fr = mp.FluxRegion(center=mp.Vector3(-0.5 * sx + dpml + 0.5, wvg_ycen, 0),
                        size=mp.Vector3(0, 2 * w, 0))

refl = sim.add_flux(fcen, df, nfreq, refl_fr)

# transmitted flux
tran_fr = mp.FluxRegion(center=mp.Vector3(0.5 * sx - dpml, wvg_ycen, 0),
                        size=mp.Vector3(0, 2 * w, 0))
tran = sim.add_flux(fcen, df, nfreq, tran_fr)
Пример #8
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=500)

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

    sim.reset_meep()
    return flux, force
Пример #9
0
    def run_mode_coeffs(self, mode_num, kpoint_func):

        resolution = 15

        w = 1  # width of waveguide
        L = 10  # length of waveguide

        Si = mp.Medium(epsilon=12.0)

        dair = 3.0
        dpml = 3.0

        sx = dpml + L + dpml
        sy = dpml + dair + w + dair + dpml
        cell_size = mp.Vector3(sx, sy, 0)

        prism_x = sx + 1
        prism_y = w / 2
        vertices = [
            mp.Vector3(-prism_x, prism_y),
            mp.Vector3(prism_x, prism_y),
            mp.Vector3(prism_x, -prism_y),
            mp.Vector3(-prism_x, -prism_y)
        ]

        geometry = [mp.Prism(vertices, height=mp.inf, material=Si)]

        boundary_layers = [mp.PML(dpml)]

        # mode frequency
        fcen = 0.20  # > 0.5/sqrt(11) to have at least 2 modes

        sources = [
            mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=0.5 * fcen),
                               eig_band=mode_num,
                               size=mp.Vector3(0, sy - 2 * dpml, 0),
                               center=mp.Vector3(-0.5 * sx + dpml, 0, 0),
                               eig_match_freq=True,
                               eig_resolution=32)
        ]

        sim = mp.Simulation(
            resolution=resolution,
            cell_size=cell_size,
            boundary_layers=boundary_layers,
            geometry=geometry,
            sources=sources,
            symmetries=[mp.Mirror(mp.Y, phase=1 if mode_num % 2 == 1 else -1)])

        xm = 0.5 * sx - dpml  # x-coordinate of monitor
        mflux = sim.add_mode_monitor(
            fcen, 0, 1,
            mp.ModeRegion(center=mp.Vector3(xm, 0),
                          size=mp.Vector3(0, sy - 2 * dpml)))
        mode_flux = sim.add_flux(
            fcen, 0, 1,
            mp.FluxRegion(center=mp.Vector3(xm, 0),
                          size=mp.Vector3(0, sy - 2 * dpml)))

        # sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(-0.5*sx+dpml,0), 1e-10))
        sim.run(until_after_sources=100)

        modes_to_check = [
            1, 2
        ]  # indices of modes for which to compute expansion coefficients
        res = sim.get_eigenmode_coefficients(mflux,
                                             modes_to_check,
                                             kpoint_func=kpoint_func)

        self.assertTrue(res.kpoints[0].close(mp.Vector3(0.604301, 0, 0)))
        self.assertTrue(res.kpoints[1].close(mp.Vector3(0.494353, 0, 0),
                                             tol=1e-2))
        self.assertTrue(res.kdom[0].close(mp.Vector3(0.604301, 0, 0)))
        self.assertTrue(res.kdom[1].close(mp.Vector3(0.494353, 0, 0),
                                          tol=1e-2))

        mode_power = mp.get_fluxes(mode_flux)[0]

        TestPassed = True
        TOLERANCE = 5.0e-3
        c0 = res.alpha[
            mode_num - 1, 0,
            0]  # coefficient of forward-traveling wave for mode #mode_num
        for nm in range(1, len(modes_to_check) + 1):
            if nm != mode_num:
                cfrel = np.abs(res.alpha[nm - 1, 0, 0]) / np.abs(c0)
                cbrel = np.abs(res.alpha[nm - 1, 0, 1]) / np.abs(c0)
                if cfrel > TOLERANCE or cbrel > TOLERANCE:
                    TestPassed = False

        self.sim = sim

        # test 1: coefficient of excited mode >> coeffs of all other modes
        self.assertTrue(TestPassed,
                        msg="cfrel: {}, cbrel: {}".format(cfrel, cbrel))
        # test 2: |mode coeff|^2 = power
        self.assertAlmostEqual(mode_power / abs(c0**2), 1.0, places=1)

        return res
Пример #10
0
def main(args):
    d = args.d

    cell_thickness = dpml + t_oxide + t_Si + t_air + dpml
    cell_zmax = 0.5 * cell_thickness if args.three_d else 0
    cell_zmin = -0.5 * cell_thickness if args.three_d else 0
    si_zmin = 0
    si_zmax = t_Si if args.three_d else 0

    # read cell size, volumes for source region and flux monitors,
    # and coupler geometry from GDSII file
    upper_branch = mp.get_GDSII_prisms(silicon, gdsII_file, UPPER_BRANCH_LAYER,
                                       si_zmin, si_zmax)
    lower_branch = mp.get_GDSII_prisms(silicon, gdsII_file, LOWER_BRANCH_LAYER,
                                       si_zmin, si_zmax)

    cell = mp.GDSII_vol(gdsII_file, CELL_LAYER, cell_zmin, cell_zmax)
    p1 = mp.GDSII_vol(gdsII_file, PORT1_LAYER, si_zmin, si_zmax)
    p2 = mp.GDSII_vol(gdsII_file, PORT2_LAYER, si_zmin, si_zmax)
    p3 = mp.GDSII_vol(gdsII_file, PORT3_LAYER, si_zmin, si_zmax)
    p4 = mp.GDSII_vol(gdsII_file, PORT4_LAYER, si_zmin, si_zmax)
    src_vol = mp.GDSII_vol(gdsII_file, SOURCE_LAYER, si_zmin, si_zmax)

    # displace upper and lower branches of coupler (as well as source and flux regions)
    if d != default_d:
        delta_y = 0.5 * (d - default_d)
        delta = mp.Vector3(y=delta_y)
        p1.center += delta
        p2.center -= delta
        p3.center += delta
        p4.center -= delta
        src_vol.center += delta
        cell.size += 2 * delta
        for np in range(len(lower_branch)):
            lower_branch[np].center -= delta
            for nv in range(len(lower_branch[np].vertices)):
                lower_branch[np].vertices[nv] -= delta
        for np in range(len(upper_branch)):
            upper_branch[np].center += delta
            for nv in range(len(upper_branch[np].vertices)):
                upper_branch[np].vertices[nv] += delta

    geometry = upper_branch + lower_branch

    if args.three_d:
        oxide_center = mp.Vector3(z=-0.5 * t_oxide)
        oxide_size = mp.Vector3(cell.size.x, cell.size.y, t_oxide)
        oxide_layer = [
            mp.Block(material=oxide, center=oxide_center, size=oxide_size)
        ]
        geometry = geometry + oxide_layer

    sources = [
        mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=df),
                           size=src_vol.size,
                           center=src_vol.center,
                           eig_match_freq=True)
    ]

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

    p1_region = mp.FluxRegion(volume=p1)
    flux1 = sim.add_flux(fcen, 0, 1, p1_region)
    p2_region = mp.FluxRegion(volume=p2)
    flux2 = sim.add_flux(fcen, 0, 1, p2_region)
    p3_region = mp.FluxRegion(volume=p3)
    flux3 = sim.add_flux(fcen, 0, 1, p3_region)
    p4_region = mp.FluxRegion(volume=p4)
    flux4 = sim.add_flux(fcen, 0, 1, p4_region)

    sim.run(until_after_sources=mp.stop_when_fields_decayed(
        50, mp.Ez, p3.center, 1e-9))

    p1_flux = mp.get_fluxes(flux1)
    p2_flux = mp.get_fluxes(flux2)
    p3_flux = mp.get_fluxes(flux3)
    p4_flux = mp.get_fluxes(flux4)

    mp.master_printf("data:, {}, {}, {}, {}".format(d,
                                                    -p2_flux[0] / p1_flux[0],
                                                    p3_flux[0] / p1_flux[0],
                                                    p4_flux[0] / p1_flux[0]))
Пример #11
0
    def refl_planar(self, theta, special_kz):
        resolution = 100  # pixels/um

        dpml = 1.0
        sx = 3 + 2 * dpml
        sy = 1 / resolution
        cell_size = mp.Vector3(sx, sy)
        pml_layers = [mp.PML(dpml, direction=mp.X)]

        fcen = 1.0  # source wavelength = 1 um

        k_point = mp.Vector3(z=math.sin(theta)).scale(fcen)

        sources = [
            mp.Source(mp.GaussianSource(fcen, fwidth=0.2 * fcen),
                      component=mp.Ez,
                      center=mp.Vector3(-0.5 * sx + dpml),
                      size=mp.Vector3(y=sy))
        ]

        sim = mp.Simulation(cell_size=cell_size,
                            boundary_layers=pml_layers,
                            sources=sources,
                            k_point=k_point,
                            special_kz=special_kz,
                            resolution=resolution)

        refl_fr = mp.FluxRegion(center=mp.Vector3(-0.25 * sx),
                                size=mp.Vector3(y=sy))
        refl = sim.add_flux(fcen, 0, 1, refl_fr)

        sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ez, mp.Vector3(), 1e-9))

        empty_flux = mp.get_fluxes(refl)
        empty_data = sim.get_flux_data(refl)
        sim.reset_meep()

        geometry = [
            mp.Block(material=mp.Medium(index=3.5),
                     size=mp.Vector3(0.5 * sx, mp.inf, mp.inf),
                     center=mp.Vector3(0.25 * sx))
        ]

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

        refl = sim.add_flux(fcen, 0, 1, refl_fr)
        sim.load_minus_flux_data(refl, empty_data)

        sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ez, mp.Vector3(), 1e-9))

        refl_flux = mp.get_fluxes(refl)

        Rmeep = -refl_flux[0] / empty_flux[0]
        return Rmeep
Пример #12
0
               math.sqrt(3) / 2),
    mp.Vector3(0.5,
               math.sqrt(3) / 2),
    mp.Vector3(1, 0),
    mp.Vector3(0.5, -math.sqrt(3) / 2),
    mp.Vector3(-0.5, -math.sqrt(3) / 2)
]

geometry = [  #mp.Block(center=mp.Vector3(0,0,0), size=cell_size, material=mp.air),
    mp.Prism(vertices,
             height=1.9,
             material=mp.metal,
             center=mp.Vector3(0, 0, 0))
]

sim = mp.Simulation(resolution=50, cell_size=cell_size, geometry=geometry)

sim.init_sim()

eps_data = sim.get_epsilon()
#eps_data = sim.get_array()

#sim.plot3D(eps_data)

#from mayavi import mlab
#s = mlab.contour3d()
#mlab.show()
#mlab.savefig(filename='test2.png')

from mayavi import mlab
s = mlab.contour3d(eps_data, colormap="hsv")
Пример #13
0
#source=[mp.Source(mp.ContinuousSource(fcen,df,nfreq),
#                 component=mp.Ex,
#                 center=mp.Vector3(0,-0.90,0),
#                 size=mp.Vector3(sx-2.1,0,0))]

source = [
    mp.Source(mp.GaussianSource(fcen, df, nfreq),
              component=mp.Ex,
              center=mp.Vector3(0, -0.90, 0),
              size=mp.Vector3(sx - 2.1, 0, 0))
]
symmetries = [mp.Mirror(mp.X), mp.Mirror(mp.Z)]
sim = mp.Simulation(cell_size=cell,
                    geometry=geometry,
                    sources=source,
                    resolution=resolution,
                    boundary_layers=pml_layers,
                    filename_prefix='ref_slab')
pt = mp.Vector3(0, -0.90, 0)
sim.run(mp.dft_ldos(fcen, 0, nfreq),
        mp.at_beginning(mp.output_epsilon),
        mp.to_appended("ref_hz", mp.at_every(0.05, mp.output_hfield_z)),
        until_after_sources=mp.stop_when_fields_decayed(10, mp.Hz, pt, 1e-3))
#sim.run(mp.dft_ldos(fcen,0,nfreq),mp.at_beginning(mp.output_epsilon),mp.at_end(mp.output_efield_x),until=50)
eps_data1 = sim.get_array(center=mp.Vector3(0, 0, 0),
                          size=mp.Vector3(sx - 2, sy - 2, sz),
                          component=mp.Dielectric)
ex_data1 = sim.get_array(center=mp.Vector3(0, 0, 0),
                         size=mp.Vector3(sx - 2, sy - 2, sz),
                         component=mp.Ex)
hz_data1 = sim.get_array(center=mp.Vector3(0, 0, 0),
def grating(gp, gh, gdc, oddz):
    sx = dpml + dsub + gh + dpad + dpml
    sy = gp

    cell_size = mp.Vector3(sx, sy, 0)
    pml_layers = [mp.PML(thickness=dpml, direction=mp.X)]

    src_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * dsub, 0, 0)
    sources = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ez if oddz else mp.Hz,
                  center=src_pt,
                  size=mp.Vector3(0, sy, 0))
    ]

    symmetries = [mp.Mirror(mp.Y, phase=+1 if oddz else -1)]

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell_size,
                        boundary_layers=pml_layers,
                        k_point=k_point,
                        default_material=glass,
                        sources=sources,
                        symmetries=symmetries)

    mon_pt = mp.Vector3(0.5 * sx - dpml - 0.5 * dpad, 0, 0)
    flux_mon = sim.add_flux(
        fcen, df, nfreq, mp.FluxRegion(center=mon_pt,
                                       size=mp.Vector3(0, sy, 0)))

    sim.run(until_after_sources=100)

    input_flux = mp.get_fluxes(flux_mon)

    sim.reset_meep()

    geometry = [
        mp.Block(material=glass,
                 size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),
                 center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub), 0, 0)),
        mp.Block(material=glass,
                 size=mp.Vector3(gh, gdc * gp, mp.inf),
                 center=mp.Vector3(-0.5 * sx + dpml + dsub + 0.5 * gh, 0, 0))
    ]

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

    mode_mon = sim.add_flux(
        fcen, df, nfreq, mp.FluxRegion(center=mon_pt,
                                       size=mp.Vector3(0, sy, 0)))

    sim.run(until_after_sources=300)

    freqs = mp.get_eigenmode_freqs(mode_mon)
    res = sim.get_eigenmode_coefficients(
        mode_mon, [1],
        eig_parity=mp.ODD_Z + mp.EVEN_Y if oddz else mp.EVEN_Z + mp.ODD_Y)
    coeffs = res.alpha

    mode_wvl = [1 / freqs[nf] for nf in range(nfreq)]
    mode_tran = [
        abs(coeffs[0, nf, 0])**2 / input_flux[nf] for nf in range(nfreq)
    ]
    mode_phase = [np.angle(coeffs[0, nf, 0]) for nf in range(nfreq)]

    return mode_wvl, mode_tran, mode_phase
Пример #15
0
                            3**0.5 / 6 * radius_percentage),
                        material=mp.Medium(epsilon=eps_si_5200))
        ]

sources = [
    mp.Source(mp.GaussianSource(frequency=fcen, fwidth=fwidth), mp.Ez,
              mp.Vector3(-10.5, 0))
]

pml_layers = [mp.PML(plmWidth)]

resolution = 32

sim = mp.Simulation(cell_size=cell,
                    boundary_layers=pml_layers,
                    geometry=geometry,
                    default_material=mp.Medium(index=1),
                    sources=sources,
                    resolution=resolution)

sim.use_output_directory("wave_in_band_gap")


def myhello(thisSim):
    # print(-0.4*sx+sim.meep_time()*v)
    if (thisSim.meep_time() > 90):
        movingSources = []
        thisSim.change_sources(movingSources)
    return


sim.run(mp.at_beginning(mp.output_epsilon),
Пример #16
0
def make_sim(cell, res, pml, dims, create_gv=True, k_point=False):
    sim = mp.Simulation(cell_size=cell, resolution=res, boundary_layers=pml, dimensions=dims, k_point=k_point)
    if create_gv:
        sim._create_grid_volume(False)
    return sim
Пример #17
0
    def test_refl_angular(self):
        resolution = 100

        dpml = 1.0
        sz = 10
        sz = sz + 2 * dpml
        cell_size = mp.Vector3(z=sz)
        pml_layers = [mp.PML(dpml)]

        wvl_min = 0.4
        wvl_max = 0.8
        fmin = 1 / wvl_max
        fmax = 1 / wvl_min
        fcen = 0.5 * (fmin + fmax)
        df = fmax - fmin
        nfreq = 50

        theta_r = math.radians(0)

        k = mp.Vector3(math.sin(theta_r), 0, math.cos(theta_r)).scale(fcen)

        dimensions = 1

        sources = [
            mp.Source(mp.GaussianSource(fcen, fwidth=df),
                      component=mp.Ex,
                      center=mp.Vector3(z=-0.5 * sz + dpml))
        ]

        sim = mp.Simulation(cell_size=cell_size,
                            boundary_layers=pml_layers,
                            sources=sources,
                            k_point=k,
                            dimensions=dimensions,
                            resolution=resolution)

        refl_fr = mp.FluxRegion(center=mp.Vector3(z=-0.25 * sz))
        refl = sim.add_flux(fcen, df, nfreq, refl_fr)

        sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ex, mp.Vector3(z=-0.5 * sz + dpml), 1e-9))

        empty_data = sim.get_flux_data(refl)
        sim.reset_meep()

        geometry = [
            mp.Block(mp.Vector3(mp.inf, mp.inf, 0.5 * sz),
                     center=mp.Vector3(z=0.25 * sz),
                     material=mp.Medium(index=3.5))
        ]

        sim = mp.Simulation(cell_size=cell_size,
                            geometry=geometry,
                            boundary_layers=pml_layers,
                            sources=sources,
                            k_point=k,
                            dimensions=dimensions,
                            resolution=resolution)

        refl = sim.add_flux(fcen, df, nfreq, refl_fr)
        sim.load_minus_flux_data(refl, empty_data)

        sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ex, mp.Vector3(z=-0.5 * sz + dpml), 1e-9))

        refl_flux = mp.get_fluxes(refl)
        freqs = mp.get_flux_freqs(refl)

        expected = [
            (1.25, -1.123696883299492e-6),
            (1.2755102040816326, -2.5749667658387866e-6),
            (1.3010204081632653, -5.70480204599006e-6),
            (1.3265306122448979, -1.2220464827582253e-5),
            (1.3520408163265305, -2.531247480206961e-5),
            (1.3775510204081631, -5.069850309492639e-5),
            (1.4030612244897958, -9.819256552437341e-5),
            (1.4285714285714284, -1.8390448659017395e-4),
            (1.454081632653061, -3.330762066794769e-4),
            (1.4795918367346936, -5.833650417163753e-4),
            (1.5051020408163263, -9.8807834237052e-4),
            (1.5306122448979589, -0.001618472171445976),
            (1.5561224489795915, -0.0025638388059825985),
            (1.5816326530612241, -0.003927863989816029),
            (1.6071428571428568, -0.005819831283556752),
            (1.6326530612244894, -0.008339881000982728),
            (1.658163265306122, -0.011558769654206626),
            (1.6836734693877546, -0.015494308354153143),
            (1.7091836734693873, -0.02008850084337135),
            (1.73469387755102, -0.025190871516857616),
            (1.7602040816326525, -0.030553756123198477),
            (1.7857142857142851, -0.03584404966066722),
            (1.8112244897959178, -0.040672967700428275),
            (1.8367346938775504, -0.04464118393086191),
            (1.862244897959183, -0.047392712128477496),
            (1.8877551020408156, -0.048667403362887635),
            (1.9132653061224483, -0.048341494285878264),
            (1.938775510204081, -0.04644739000778679),
            (1.9642857142857135, -0.043168390293742316),
            (1.9897959183673462, -0.0388094755730579),
            (2.0153061224489788, -0.03375052221907117),
            (2.0408163265306114, -0.02839209067703472),
            (2.066326530612244, -0.023104245646230648),
            (2.0918367346938767, -0.01818725699718267),
            (2.1173469387755093, -0.013849270759480073),
            (2.142857142857142, -0.010201733597436358),
            (2.1683673469387745, -0.007269616609175294),
            (2.193877551020407, -0.005011210495189995),
            (2.21938775510204, -0.0033417192031464896),
            (2.2448979591836724, -0.0021557351734376256),
            (2.270408163265305, -0.0013453062176115673),
            (2.2959183673469377, -8.121742663131631e-4),
            (2.3214285714285703, -4.7433135191915683e-4),
            (2.346938775510203, -2.6799188013374266e-4),
            (2.3724489795918355, -1.464781343401766e-4),
            (2.397959183673468, -7.745339273024636e-5),
            (2.423469387755101, -3.9621374769542025e-5),
            (2.4489795918367334, -1.9608458558430508e-5),
            (2.474489795918366, -9.38818477949983e-6),
            (2.4999999999999987, -4.3484671364929225e-6),
        ]

        np.testing.assert_allclose(expected,
                                   list(zip(freqs, refl_flux)),
                                   rtol=1e-6)
Пример #18
0
def main(args):

    resolution = args.res

    w1 = 1  # width of waveguide 1
    w2 = 2  # width of waveguide 2
    Lw = 10  # length of waveguide 1 and 2
    Lt = args.Lt  # taper length

    Si = mp.Medium(epsilon=12.0)

    dair = 3.0
    dpml = 5.0

    sx = dpml + Lw + Lt + Lw + dpml
    sy = dpml + dair + w2 + dair + dpml
    cell_size = mp.Vector3(sx, sy, 0)

    prism_x = sx + 1
    half_w1 = 0.5 * w1
    half_w2 = 0.5 * w2
    half_Lt = 0.5 * Lt

    if Lt > 0:
        vertices = [
            mp.Vector3(-prism_x, half_w1),
            mp.Vector3(-half_Lt, half_w1),
            mp.Vector3(half_Lt, half_w2),
            mp.Vector3(prism_x, half_w2),
            mp.Vector3(prism_x, -half_w2),
            mp.Vector3(half_Lt, -half_w2),
            mp.Vector3(-half_Lt, -half_w1),
            mp.Vector3(-prism_x, -half_w1)
        ]
    else:
        vertices = [
            mp.Vector3(-prism_x, half_w1),
            mp.Vector3(prism_x, half_w1),
            mp.Vector3(prism_x, -half_w1),
            mp.Vector3(-prism_x, -half_w1)
        ]

    geometry = [mp.Prism(vertices, height=mp.inf, material=Si)]

    boundary_layers = [mp.PML(dpml)]

    # mode wavelength
    lcen = 6.67

    # mode frequency
    fcen = 1 / lcen

    sources = [
        mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=0.2 * fcen),
                           component=mp.Ez,
                           size=mp.Vector3(0, sy - 2 * dpml, 0),
                           center=mp.Vector3(-0.5 * sx + dpml + 0.2 * Lw, 0,
                                             0),
                           eig_match_freq=True,
                           eig_parity=mp.ODD_Z + mp.EVEN_Y)
    ]

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

    xm = -0.5 * sx + dpml + 0.5 * Lw  # x-coordinate of monitor
    mode_monitor = sim.add_eigenmode(
        fcen, 0, 1,
        mp.FluxRegion(center=mp.Vector3(xm, 0),
                      size=mp.Vector3(0, sy - 2 * dpml)))

    sim.run(until_after_sources=mp.stop_when_fields_decayed(
        50, mp.Ez, mp.Vector3(xm, 0, 0), 1e-9))

    coeffs = sim.get_eigenmode_coefficients(mode_monitor, [1])

    print("mode:, {}, {:.8f}, {:.8f}".format(Lt,
                                             abs(coeffs[0, 0, 0])**2,
                                             abs(coeffs[0, 0, 1])**2))
Пример #19
0
def pol_grating(d, ph, gp, nmode):
    sx = dpml + dsub + d + d + dpad + dpml
    sy = gp

    cell_size = mp.Vector3(sx, sy, 0)
    pml_layers = [mp.PML(thickness=dpml, direction=mp.X)]

    # twist angle of nematic director; from equation 1b
    def phi(p):
        xx = p.x - (-0.5 * sx + dpml + dsub)
        if (xx >= 0) and (xx <= d):
            return math.pi * p.y / gp + ph * xx / d
        else:
            return math.pi * p.y / gp - ph * xx / d + 2 * ph

    # return the anisotropic permittivity tensor for a uniaxial, twisted nematic liquid crystal
    def lc_mat(p):
        # rotation matrix for rotation around x axis
        Rx = mp.Matrix(mp.Vector3(1, 0, 0),
                       mp.Vector3(0, math.cos(phi(p)), math.sin(phi(p))),
                       mp.Vector3(0, -math.sin(phi(p)), math.cos(phi(p))))
        lc_epsilon = Rx * epsilon_diag * Rx.transpose()
        lc_epsilon_diag = mp.Vector3(lc_epsilon[0].x, lc_epsilon[1].y,
                                     lc_epsilon[2].z)
        lc_epsilon_offdiag = mp.Vector3(lc_epsilon[1].x, lc_epsilon[2].x,
                                        lc_epsilon[2].y)
        return mp.Medium(epsilon_diag=lc_epsilon_diag,
                         epsilon_offdiag=lc_epsilon_offdiag)

    geometry = [
        mp.Block(center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub)),
                 size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),
                 material=mp.Medium(index=n_0)),
        mp.Block(center=mp.Vector3(-0.5 * sx + dpml + dsub + d),
                 size=mp.Vector3(2 * d, mp.inf, mp.inf),
                 material=lc_mat)
    ]

    # linear-polarized planewave pulse source
    src_pt = mp.Vector3(-0.5 * sx + dpml + 0.3 * dsub, 0, 0)
    sources = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ez,
                  center=src_pt,
                  size=mp.Vector3(0, sy, 0)),
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ey,
                  center=src_pt,
                  size=mp.Vector3(0, sy, 0))
    ]

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell_size,
                        boundary_layers=pml_layers,
                        k_point=k_point,
                        sources=sources,
                        default_material=mp.Medium(index=n_0))

    refl_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * dsub, 0, 0)
    refl_flux = sim.add_flux(
        fcen, 0, 1, mp.FluxRegion(center=refl_pt, size=mp.Vector3(0, sy, 0)))

    sim.run(until_after_sources=100)

    input_flux = mp.get_fluxes(refl_flux)
    input_flux_data = sim.get_flux_data(refl_flux)

    sim.reset_meep()

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

    refl_flux = sim.add_flux(
        fcen, 0, 1, mp.FluxRegion(center=refl_pt, size=mp.Vector3(0, sy, 0)))
    sim.load_minus_flux_data(refl_flux, input_flux_data)

    tran_pt = mp.Vector3(0.5 * sx - dpml - 0.5 * dpad, 0, 0)
    tran_flux = sim.add_flux(
        fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0, sy, 0)))

    sim.run(until_after_sources=300)

    res1 = sim.get_eigenmode_coefficients(tran_flux,
                                          range(1, nmode + 1),
                                          eig_parity=mp.ODD_Z + mp.EVEN_Y)
    res2 = sim.get_eigenmode_coefficients(tran_flux,
                                          range(1, nmode + 1),
                                          eig_parity=mp.EVEN_Z + mp.ODD_Y)
    angles = [math.degrees(math.acos(kdom.x / fcen)) for kdom in res1.kdom]

    return input_flux[0], angles, res1.alpha[:, 0, 0], res2.alpha[:, 0, 0]
Пример #20
0
sx = 40
sy = 6
cell_size = mp.Vector3(sx + 2 * dpml, sy)

v0 = 1.0  # pulse center frequency
a = 0.2   # Gaussian envelope half-width
b = -0.5  # linear chirp rate (positive: up-chirp, negative: down-chirp)
t0 = 15   # peak time


def chirp(t): return np.exp(1j * 2 * np.pi * v0 * (t - t0)) * \
    np.exp(-a * (t - t0)**2 + 1j * b * (t - t0)**2)


sources = [mp.Source(src=mp.CustomSource(src_func=chirp),
                     center=mp.Vector3(-0.5 * sx),
                     size=mp.Vector3(y=sy),
                     component=mp.Ez)]

sim = mp.Simulation(cell_size=cell_size,
                    boundary_layers=pml_layers,
                    resolution=resolution,
                    k_point=mp.Vector3(),
                    sources=sources,
                    symmetries=[mp.Mirror(mp.Y)])

sim.run(mp.in_volume(mp.Volume(center=mp.Vector3(), size=mp.Vector3(sx, sy)),
                     mp.at_every(2.7, mp.output_efield_z)),
        until=t0 + 50)
Пример #21
0
    def wvg_flux(self, res, att_coeff):
        """
        Computes the Poynting flux in a single-mode waveguide at two
        locations (5 and 10 μm) downstream from the source given the
        grid resolution res (pixels/μm) and material attenuation
        coefficient att_coeff (dB/cm).
        """

        cell_size = mp.Vector3(14., 14.)

        pml_layers = [mp.PML(thickness=2.)]

        w = 1.  # width of waveguide

        fsrc = 0.15  # frequency (in vacuum)

        # note: MPB can only compute modes of lossless material systems.
        #       The imaginary part of ε is ignored and the launched
        #       waveguide mode is therefore inaccurate. For small values
        #       of imag(ε) (which is proportional to att_coeff), this
        #       inaccuracy tends to be insignificant.
        sources = [
            mp.EigenModeSource(src=mp.GaussianSource(fsrc, fwidth=0.2 * fsrc),
                               center=mp.Vector3(-5.),
                               size=mp.Vector3(y=10.),
                               eig_parity=mp.EVEN_Y + mp.ODD_Z)
        ]

        # ref: https://en.wikipedia.org/wiki/Mathematical_descriptions_of_opacity
        # Note that this is the loss of a planewave, which is only approximately
        # the loss of a waveguide mode.  In principle, we could compute the latter
        # semi-analytically if we wanted to run this unit test to greater accuracy
        # (e.g. to test convergence with resolution).
        n_eff = np.sqrt(12.) + 1j * (1 / fsrc) * (dB_cm_to_dB_um *
                                                  att_coeff) / (4 * np.pi)
        eps_eff = n_eff * n_eff
        # ref: https://meep.readthedocs.io/en/latest/Materials/#conductivity-and-complex
        sigma_D = 2 * np.pi * fsrc * np.imag(eps_eff) / np.real(eps_eff)

        geometry = [
            mp.Block(center=mp.Vector3(),
                     size=mp.Vector3(mp.inf, w, mp.inf),
                     material=mp.Medium(epsilon=np.real(eps_eff),
                                        D_conductivity=sigma_D))
        ]

        sim = mp.Simulation(cell_size=cell_size,
                            resolution=res,
                            boundary_layers=pml_layers,
                            sources=sources,
                            geometry=geometry,
                            symmetries=[mp.Mirror(mp.Y)])

        tran1 = sim.add_flux(
            fsrc, 0, 1,
            mp.FluxRegion(center=mp.Vector3(x=0.), size=mp.Vector3(y=10.)))

        tran2 = sim.add_flux(
            fsrc, 0, 1,
            mp.FluxRegion(center=mp.Vector3(x=5.), size=mp.Vector3(y=10.)))

        sim.run(until_after_sources=20)

        return mp.get_fluxes(tran1)[0], mp.get_fluxes(tran2)[0]
Пример #22
0
    mp.Source(mp.GaussianSource(fcen, fwidth=0.1 * fcen, is_integrated=True),
              center=mp.Vector3(-0.5 * s + dpml),
              size=mp.Vector3(0, s),
              component=mp.Ez)
]

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

geometry = [
    mp.Cylinder(material=SiO2, center=mp.Vector3(), radius=r, height=mp.inf)
]

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

dft_fields = sim.add_dft_fields([mp.Dz, mp.Ez],
                                fcen,
                                0,
                                1,
                                center=mp.Vector3(),
                                size=mp.Vector3(2 * r, 2 * r),
                                yee_grid=True)

# closed box surrounding cylinder for computing total incoming flux
flux_box = sim.add_flux(
    fcen, 0, 1,
Пример #23
0
    def test_check_material_frequencies(self):
        mat = mp.Medium(valid_freq_range=mp.FreqRange(min=10, max=20))
        invalid_sources = [
            [mp.Source(mp.GaussianSource(5, fwidth=1), mp.Ez, mp.Vector3())],
            [
                mp.Source(mp.ContinuousSource(10, fwidth=1), mp.Ez,
                          mp.Vector3())
            ],
            [mp.Source(mp.GaussianSource(10, width=1), mp.Ez, mp.Vector3())],
            [mp.Source(mp.GaussianSource(20, width=1), mp.Ez, mp.Vector3())],
        ]

        cell_size = mp.Vector3(5, 5)
        resolution = 5

        def check_warnings(sim, should_warn=True):
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                sim.run(until=5)

                if should_warn:
                    self.assertEqual(len(w), 1)
                    self.assertIn("material", str(w[-1].message))
                else:
                    self.assertEqual(len(w), 0)

        geom = [mp.Sphere(0.2, material=mat)]

        for s in invalid_sources:
            # Check for invalid extra_materials
            sim = mp.Simulation(cell_size=cell_size,
                                resolution=resolution,
                                sources=s,
                                extra_materials=[mat])
            check_warnings(sim)

            # Check for invalid geometry materials
            sim = mp.Simulation(cell_size=cell_size,
                                resolution=resolution,
                                sources=s,
                                geometry=geom)
            check_warnings(sim)

        valid_sources = [[
            mp.Source(mp.GaussianSource(15, fwidth=1), mp.Ez, mp.Vector3())
        ], [mp.Source(mp.ContinuousSource(15, width=5), mp.Ez, mp.Vector3())]]

        for s in valid_sources:
            sim = mp.Simulation(cell_size=cell_size,
                                resolution=resolution,
                                sources=s,
                                extra_materials=[mat])
            check_warnings(sim, False)

        # Check DFT frequencies

        # Invalid extra_materials
        sim = mp.Simulation(cell_size=cell_size,
                            resolution=resolution,
                            sources=valid_sources[0],
                            extra_materials=[mat])
        fregion = mp.FluxRegion(center=mp.Vector3(0, 1),
                                size=mp.Vector3(2, 2),
                                direction=mp.X)
        sim.add_flux(15, 6, 2, fregion)
        check_warnings(sim)

        # Invalid geometry material
        sim = mp.Simulation(cell_size=cell_size,
                            resolution=resolution,
                            sources=valid_sources[0],
                            geometry=geom)
        sim.add_flux(15, 6, 2, fregion)
        check_warnings(sim)
Пример #24
0
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(3):
    geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i)))

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

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

# add sources
sim.sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df),
               mp.Hz, mp.Vector3())]

# run until sources are finished (and no later)
sim._run_sources_until(0, [])

# get 1D and 2D array slices
xMin = -0.25 * sx
xMax = +0.25 * sx
yMin = -0.15 * sy
yMax = +0.15 * sy
Пример #25
0
    mp.Block(material=glass,
             size=mp.Vector3(sr, 0, dpml + dsub),
             center=mp.Vector3(0.5 * sr, 0, -0.5 * sz + 0.5 * (dpml + dsub)))
]

for n in range(zN - 1, -1, -1):
    geometry.append(
        mp.Block(material=glass if n % 2 == 0 else mp.vacuum,
                 size=mp.Vector3(r[n], 0, zh),
                 center=mp.Vector3(0.5 * r[n], 0,
                                   -0.5 * sz + dpml + dsub + 0.5 * zh)))

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

## near-field monitor
n2f_obj = sim.add_near2far(
    frq_cen, 0, 1,
    mp.Near2FarRegion(center=mp.Vector3(0.5 * (sr - dpml), 0, 0.5 * sz - dpml),
                      size=mp.Vector3(sr - dpml)),
    mp.Near2FarRegion(center=mp.Vector3(sr - dpml, 0,
                                        0.5 * sz - 0.5 * (dsub + zh + dpad)),
                      size=mp.Vector3(z=dsub + zh + dpad)))

sim.run(until_after_sources=100)
Пример #26
0
    def test_mode_decomposition(self):
        resolution = 10
        w1 = 1
        w2 = 2
        Lw = 2
        dair = 3.0
        dpml = 5.0
        sy = dpml + dair + w2 + dair + dpml
        half_w1 = 0.5 * w1
        half_w2 = 0.5 * w2
        Si = mp.Medium(epsilon=12.0)
        boundary_layers = [mp.PML(dpml)]
        lcen = 6.67
        fcen = 1 / lcen
        symmetries = [mp.Mirror(mp.Y)]
        Lt = 2
        sx = dpml + Lw + Lt + Lw + dpml
        cell_size = mp.Vector3(sx, sy, 0)
        prism_x = sx + 1
        half_Lt = 0.5 * Lt
        src_pt = mp.Vector3(-0.5 * sx + dpml + 0.2 * Lw, 0, 0)
        sources = [
            mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=0.2 * fcen),
                               component=mp.Ez,
                               center=src_pt,
                               size=mp.Vector3(0, sy - 2 * dpml, 0),
                               eig_match_freq=True,
                               eig_parity=mp.ODD_Z + mp.EVEN_Y)
        ]

        vertices = [
            mp.Vector3(-prism_x, half_w1),
            mp.Vector3(prism_x, half_w1),
            mp.Vector3(prism_x, -half_w1),
            mp.Vector3(-prism_x, -half_w1)
        ]

        sim = mp.Simulation(
            resolution=resolution,
            cell_size=cell_size,
            boundary_layers=boundary_layers,
            geometry=[mp.Prism(vertices, height=mp.inf, material=Si)],
            sources=sources,
            symmetries=symmetries)

        mon_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * Lw, 0, 0)
        flux = sim.add_flux(
            fcen, 0, 1,
            mp.FluxRegion(center=mon_pt, size=mp.Vector3(0, sy - 2 * dpml, 0)))

        sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ez, src_pt, 1e-9))

        incident_coeffs, vgrp, kpoints = sim.get_eigenmode_coefficients(
            flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y)
        incident_flux = mp.get_fluxes(flux)
        incident_flux_data = sim.get_flux_data(flux)

        sim.reset_meep()

        vertices = [
            mp.Vector3(-prism_x, half_w1),
            mp.Vector3(-half_Lt, half_w1),
            mp.Vector3(half_Lt, half_w2),
            mp.Vector3(prism_x, half_w2),
            mp.Vector3(prism_x, -half_w2),
            mp.Vector3(half_Lt, -half_w2),
            mp.Vector3(-half_Lt, -half_w1),
            mp.Vector3(-prism_x, -half_w1)
        ]

        sim = mp.Simulation(
            resolution=resolution,
            cell_size=cell_size,
            boundary_layers=boundary_layers,
            geometry=[mp.Prism(vertices, height=mp.inf, material=Si)],
            sources=sources,
            symmetries=symmetries)

        refl_flux = sim.add_flux(
            fcen, 0, 1,
            mp.FluxRegion(center=mon_pt, size=mp.Vector3(0, sy - 2 * dpml, 0)))
        sim.load_minus_flux_data(refl_flux, incident_flux_data)

        sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ez, src_pt, 1e-9))

        coeffs, vgrp, kpoints = sim.get_eigenmode_coefficients(
            refl_flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y)
        taper_flux = mp.get_fluxes(refl_flux)

        self.assertAlmostEqual(abs(coeffs[0, 0, 1])**2 /
                               abs(incident_coeffs[0, 0, 0])**2,
                               -taper_flux[0] / incident_flux[0],
                               places=4)
Пример #27
0
# glass substrate

sources = [
    mp.Source(mp.ContinuousSource(wavelength=0.450, end_time=20),
              component=mp.Ez,
              center=mp.Vector3(-3, 0))
]

firstfr = mp.FluxRegion(center=mp.Vector3(-2, 0, 0), size=mp.Vector3(0, 30))

secfr = mp.FluxRegion(center=mp.Vector3(4, 0, 0), size=mp.Vector3(0, 30))

sim = mp.Simulation(cell_size=cell,
                    k_point=mp.Vector3(),
                    default_material=mp.Medium(index=1.6),
                    boundary_layers=pml_layers,
                    geometry=[],
                    sources=sources,
                    resolution=resolution)

before_block = sim.add_flux(1 / 0.450, 0.5, 5, firstfr)

sim.plot2D(eps_parameters={"cmap": "brg"},
           boundary_parameters={
               'hatch': 'o',
               'linewidth': 1.5,
               'facecolor': 'y',
               'edgecolor': 'y',
               'alpha': 0.7
           })
Пример #28
0
    mp.Source(mp.GaussianSource(fcen, fwidth=df),
              component=mp.Ez,
              center=mp.Vector3(src_pos, 0, 0),
              size=mp.Vector3(0, sy, 0))
]

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

glass = mp.Medium(index=1.5)

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

sim = mp.Simulation(resolution=resolution,
                    cell_size=cell_size,
                    boundary_layers=pml_layers,
                    k_point=k_point,
                    default_material=glass,
                    sources=sources,
                    symmetries=symmetries)

nfreq = 21
xm = 0.5 * sx - dpml - 0.5 * dpad
eig_mon = sim.add_flux(
    fcen, df, nfreq,
    mp.FluxRegion(center=mp.Vector3(xm, 0, 0), size=mp.Vector3(0, sy, 0)))

sim.run(until_after_sources=mp.stop_when_fields_decayed(
    50, mp.Ez, mp.Vector3(xm, 0, 0), 1e-9))

coeffs0, vgrps0, kpoints0 = sim.get_eigenmode_coefficients(
    eig_mon, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y)
Пример #29
0
N0 = 37                # initial population density of ground state
Rp = 0.0051            # pumping rate of ground to excited state
# so for example, these parameters have D_0 (SALT) = 0.0693.

# Make the actual medium in MEEP:
transitions = [mp.Transition(1, 2, pumping_rate=Rp, frequency=freq_21, gamma=gamma_21,
                             sigma_diag=mp.Vector3(sigma_21,0,0)),
               mp.Transition(2, 1, transition_rate=rate_21)]
ml_atom = mp.MultilevelAtom(sigma=1, transitions=transitions, initial_populations=[N0])
two_level = mp.Medium(index=ncav, E_susceptibilities=[ml_atom])

# Specify the cavity geometry:
geometry = [mp.Block(center=mp.Vector3(z=-0.5*sz+0.5*Lcav)),
                     size=mp.Vector3(mp.inf,mp.inf,Lcav), material=two_level)]

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

sim.init_sim()

def field_func(p):
    return 1 if p.z==-0.5*sz + 0.5*Lcav else 0

sim.fields.initialize_field(mp.Ex, field_func)

# Specify the end time:
endt = 7000
# Note that the total number of time steps run is endt*resolution*2. This is the origin of the extra
Пример #30
0
def standard(metalens):
    metalens['run_date'] = int(time())
    matter = mp.Medium(epsilon=metalens['epsilon'])

    pillar_locs = list(
        product(
            [-metalens['pillar_separation'], metalens['pillar_separation']],
            [-metalens['pillar_separation'], metalens['pillar_separation']]))
    pillar_locs.append((0, 0))

    pillars = [
        mp.Cylinder(radius=metalens['pillar_radius'],
                    height=metalens['pillar_height'],
                    center=mp.Vector3(x, y, 0),
                    material=matter) for x, y in pillar_locs
    ]

    substrate = [
        mp.Block(size=mp.Vector3(metalens['sim_cell_width'],
                                 metalens['sim_cell_width'],
                                 metalens['sim_cell_width'] / 2),
                 center=mp.Vector3(0, 0, -metalens['sim_cell_width'] / 4),
                 material=matter)
    ]
    geometry = substrate + pillars
    cell = mp.Vector3(metalens['sim_cell_width'], metalens['sim_cell_width'],
                      metalens['sim_cell_width'])
    pml = [mp.PML(metalens['PML_width'])]
    source = [
        mp.Source(src=mp.ContinuousSource(wavelength=metalens['wavelength']),
                  component=mp.Ex,
                  center=mp.Vector3(0, 0, -metalens['sim_cell_width'] / 4),
                  size=mp.Vector3(0, 0, 0))
    ]
    symmetries = []
    for symmetry in metalens['symmetries']:
        if symmetry == 'x':
            symmetries.append(mp.Mirror(mp.X))
        if symmetry == 'y':
            symmetries.append(mp.Mirror(mp.Y))
    sim = mp.Simulation(cell_size=cell,
                        boundary_layers=pml,
                        geometry=geometry,
                        force_complex_fields=metalens['complex_fields'],
                        symmetries=symmetries,
                        sources=source,
                        resolution=metalens['resolution'])
    start_time = time()
    mp.quiet(metalens['quiet'])
    # mp.verbosity(3)
    sim.init_sim()
    metalens['time_for_init'] = (time() - start_time)
    start_time = time()
    #sim.run(mp.at_end(mp.output_efield(sim)),until=metalens['sim_time'])
    sim.run(until=metalens['sim_time'])
    metalens['time_for_running'] = time() - start_time
    start_time = time()
    sim.filename_prefix = 'standard_candle-%d' % metalens['run_date']
    print(sim.filename_prefix)
    mp.output_efield(sim)
    mp.output_hfield(sim)

    # print("collecting fields...")
    # h5_fname = 'candle-{run_date}.h5'.format(run_date = metalens['run_date'])
    # if metalens['save_fields_to_h5'] and rank ==0:#(not os.path.exists(h5_fname)):
    #     metalens['h5_fname'] = h5_fname
    #     h5_file = h5py.File(h5_fname,'w', driver='mpio', comm=MPI.COMM_WORLD)
    #     fields = h5_file.create_group('fields')
    #     Ex = np.transpose(sim.get_array(component=mp.Ex),(2,1,0))
    #     metalens['voxels'] = Ex.shape[0]**3
    #     metalens['voxels'] = Ex.shape[0]**3
    #     metalens['above_pillar_index'] = int(Ex.shape[0]/2. + 3*metalens['pillar_height']*metalens['resolution']/2)
    #     mp.output_efield('test')
    #     fields.create_dataset('Ex',
    #            data=Ex)
    #     del Ex
    #     fields.create_dataset('Ey',
    #            data=np.transpose(sim.get_array(component=mp.Ey),(2,1,0)))
    #     fields.create_dataset('Ez',
    #            data=np.transpose(sim.get_array(component=mp.Ez),(2,1,0)))
    #     fields.create_dataset('Hx',
    #            data=np.transpose(sim.get_array(component=mp.Hx),(2,1,0)))
    #     fields.create_dataset('Hy',
    #            data=np.transpose(sim.get_array(component=mp.Hy),(2,1,0)))
    #     fields.create_dataset('Hz',
    #            data=np.transpose(sim.get_array(component=mp.Hz),(2,1,0)))
    #     h5_file.close()
    # else:
    #     metalens['fields'] = {
    #       'Ex': np.transpose(sim.get_array(component=mp.Ex),(2,1,0)),
    #       'Ey': np.transpose(sim.get_array(component=mp.Ey),(2,1,0)),
    #       'Ez': np.transpose(sim.get_array(component=mp.Ez),(2,1,0)),
    #       'Hx': np.transpose(sim.get_array(component=mp.Hx),(2,1,0)),
    #       'Hy': np.transpose(sim.get_array(component=mp.Hy),(2,1,0)),
    #       'Hz': np.transpose(sim.get_array(component=mp.Hz),(2,1,0))
    #       }
    #     metalens['voxels'] = metalens['fields']['Ex'].shape[0]**3
    #     metalens['above_pillar_index'] = int(metalens['fields']['Ex'].shape[0]/2. + 3*metalens['pillar_height']*metalens['resolution']/2)
    metalens['voxels'] = int((8 * metalens['resolution'])**3)
    metalens['time_for_saving_fields'] = round(time() - start_time, 0)
    metalens['max_mem_usage_in_Gb'] = metalens[
        'num_cores'] * resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1E6
    metalens['max_mem_usage_in_Gb'] = round(metalens['max_mem_usage_in_Gb'], 2)
    metalens['summary'] = '''init time = {time_for_init:.1f} s
    running simulation = {time_for_running:.1f} s
    saving fields = {time_for_saving_fields:.1f} s
    num voxels = {voxels}
    max memory usage = {max_mem_usage_in_Gb:.2f} Gb'''.format(**metalens)
    metalens['pkl_fname'] = 'standard-candle-%d.pkl' % metalens['run_date']
    return metalens