Exemple #1
0
    def empty_run(self, sx, sy, animate=False):

        sources, refl_fr, trans_fr = self.set_source(sx, sy)

        sim = mp.Simulation(cell_size=mp.Vector3(sx, sy, self.sz),
                            geometry=[],
                            sources=sources,
                            boundary_layers=self.pml_layers,
                            k_point=self.k,
                            resolution=self.resolution)

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

        trans = sim.add_flux(self.fcen, self.df, self.nfreq, trans_fr)

        if animate:
            sim.run(mp.at_beginning(mp.output_epsilon),
                    mp.to_appended("ex", mp.at_every(0.6, mp.output_efield_z)),
                    until_after_sources=mp.stop_when_fields_decayed(25, mp.Ey, self.pt, 1e-3))
        else:
            sim.run(until_after_sources=mp.stop_when_fields_decayed(25, mp.Ey, self.pt, 1e-3))

        # for normalization run, save flux fields data for reflection plane
        self.store['straight_refl_data'] = sim.get_flux_data(refl)

        # save incident power for transmission plane
        self.store['flux_freqs'] = mp.get_flux_freqs(refl)
        self.store['straight_tran_flux'] = mp.get_fluxes(trans)
        self.store['straight_refl_flux'] = mp.get_fluxes(refl)
Exemple #2
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
Exemple #3
0
    def test_chunks(self):
        sxy = 10
        cell = mp.Vector3(sxy, sxy, 0)

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

        sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3())]

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

        sim = mp.Simulation(cell_size=cell,
                            boundary_layers=pml_layers,
                            sources=sources,
                            resolution=resolution,
                            split_chunks_evenly=False)

        sim.use_output_directory(temp_dir)

        top = mp.FluxRegion(center=mp.Vector3(0,+0.5*sxy-dpml), size=mp.Vector3(sxy-2*dpml,0), weight=+1.0)
        bot = mp.FluxRegion(center=mp.Vector3(0,-0.5*sxy+dpml), size=mp.Vector3(sxy-2*dpml,0), weight=-1.0)
        rgt = mp.FluxRegion(center=mp.Vector3(+0.5*sxy-dpml,0), size=mp.Vector3(0,sxy-2*dpml), weight=+1.0)
        lft = mp.FluxRegion(center=mp.Vector3(-0.5*sxy+dpml,0), size=mp.Vector3(0,sxy-2*dpml), weight=-1.0)

        tot_flux = sim.add_flux(fcen, 0, 1, top, bot, rgt, lft)

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

        sim.save_flux('tot_flux', tot_flux)
        sim1 = sim

        geometry = [mp.Block(center=mp.Vector3(), size=mp.Vector3(sxy, sxy, mp.inf), material=mp.Medium(index=3.5)),
                    mp.Block(center=mp.Vector3(), size=mp.Vector3(sxy-2*dpml, sxy-2*dpml, mp.inf), material=mp.air)]

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

        sim.use_output_directory(temp_dir)

        tot_flux = sim.add_flux(fcen, 0, 1, top, bot, rgt, lft)

        sim.load_minus_flux('tot_flux', tot_flux)

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

        self.assertAlmostEqual(86.90826609300862, mp.get_fluxes(tot_flux)[0])
Exemple #4
0
def runSimulation(thetaDegrees):
    thetaRadians = np.radians(thetaDegrees)
    kVector = mp.Vector3(np.sin(thetaRadians), 0,
                         np.cos(thetaRadians)).scale(minimumFrequency)
    simulation = mp.Simulation(cell_size=cellSize,
                               sources=sources,
                               resolution=resolution,
                               boundary_layers=pmlLayers,
                               k_point=kVector)

    incidentFluxMonitor = simulation.add_flux(frequency, frequencyWidth,
                                              numberFrequencies,
                                              incidentRegion)

    simulation.run(until_after_sources=mp.stop_when_fields_decayed(
        20, mp.Ex, transmissionMonitorLocation, powerDecayTarget))

    incidentFluxToSubtract = simulation.get_flux_data(incidentFluxMonitor)

    simulation = mp.Simulation(cell_size=cellSize,
                               sources=sources,
                               resolution=resolution,
                               boundary_layers=pmlLayers,
                               geometry=geometry,
                               k_point=kVector)

    transmissionRegion = mp.FluxRegion(center=transmissionMonitorLocation)
    transmissionFluxMonitor = simulation.add_flux(frequency, frequencyWidth,
                                                  numberFrequencies,
                                                  transmissionRegion)
    reflectionRegion = incidentRegion
    reflectionFluxMonitor = simulation.add_flux(frequency, frequencyWidth,
                                                numberFrequencies,
                                                reflectionRegion)
    simulation.load_minus_flux_data(reflectionFluxMonitor,
                                    incidentFluxToSubtract)

    simulation.run(until_after_sources=mp.stop_when_fields_decayed(
        20, mp.Ex, transmissionMonitorLocation, powerDecayTarget))

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

    frequencies = np.array(mp.get_flux_freqs(reflectionFluxMonitor))
    kx = kVector.x
    angles = np.arcsin(kx / frequencies)

    return angles, frequencies, R, T
Exemple #5
0
    def test_chunks(self):
        sxy = 10
        cell = mp.Vector3(sxy, sxy, 0)

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

        sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3())]

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

        sim = mp.Simulation(cell_size=cell,
                            boundary_layers=pml_layers,
                            sources=sources,
                            resolution=resolution,
                            split_chunks_evenly=False)

        top = mp.FluxRegion(center=mp.Vector3(0,+0.5*sxy-dpml), size=mp.Vector3(sxy-2*dpml,0), weight=+1.0)
        bot = mp.FluxRegion(center=mp.Vector3(0,-0.5*sxy+dpml), size=mp.Vector3(sxy-2*dpml,0), weight=-1.0)
        rgt = mp.FluxRegion(center=mp.Vector3(+0.5*sxy-dpml,0), size=mp.Vector3(0,sxy-2*dpml), weight=+1.0)
        lft = mp.FluxRegion(center=mp.Vector3(-0.5*sxy+dpml,0), size=mp.Vector3(0,sxy-2*dpml), weight=-1.0)

        tot_flux = sim.add_flux(fcen, 0, 1, top, bot, rgt, lft)

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

        sim.save_flux('tot_flux', tot_flux)
        sim1 = sim

        geometry = [mp.Block(center=mp.Vector3(), size=mp.Vector3(sxy, sxy, mp.inf), material=mp.Medium(index=3.5)),
                    mp.Block(center=mp.Vector3(), size=mp.Vector3(sxy-2*dpml, sxy-2*dpml, mp.inf), material=mp.air)]

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

        tot_flux = sim.add_flux(fcen, 0, 1, top, bot, rgt, lft)

        sim.load_minus_flux('tot_flux', tot_flux)

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

        self.assertAlmostEqual(86.90826609300862, mp.get_fluxes(tot_flux)[0])
Exemple #6
0
def scat_sim():
    """perform scattering simulation"""

    scat = meep.Simulation(cell_size=cell,
                           boundary_layers=[pml],
                           geometry=geometry,
                           default_material=medium,
                           resolution=resolution)
    scat.init_fields()
    source(scat)

    flux_box_absorb = meep_ext.add_flux_box(scat, fcen, df, nfreq, [0, 0, 0],
                                            monitor_size)
    flux_box_scat = meep_ext.add_flux_box(scat, fcen, df, nfreq, [0, 0, 0],
                                          monitor_size)
    scat.load_minus_flux(norm_file_ext, flux_box_scat)

    scat.run(until_after_sources=meep.stop_when_fields_decayed(
        .5 * um,
        decay,
        pt=meep.Vector3(0, 0, monitor_size[2] / 2),
        decay_by=1e-5))

    return {
        'scattering': np.array(meep.get_fluxes(flux_box_scat)),
        'absorption': -np.array(meep.get_fluxes(flux_box_absorb)),
        'frequency': np.array(meep.get_flux_freqs(flux_box_scat))
    }
Exemple #7
0
def dimer_scat():
    """perform scattering simulation"""

    scat = meep.Simulation(cell_size=cell,
                           boundary_layers=[pml],
                           geometry=geometry,
                           resolution=resolution)
    scat.init_fields()
    source(scat)

    L = 2 * radius + 2 * particle_monitor_gap
    Fx = meep_ext.add_force_box(scat, fcen, df, nfreq, p2, [L, L, L], meep.X)
    Fy = meep_ext.add_force_box(scat, fcen, df, nfreq, p2, [L, L, L], meep.Y)
    Fz = meep_ext.add_force_box(scat, fcen, df, nfreq, p2, [L, L, L], meep.Z)

    # scat.run(until_after_sources=8*um)
    scat.run(until_after_sources=meep.stop_when_fields_decayed(
        .5 * um, meep.Ex, pt=p2 - meep.Vector3(0, 0, L / 2), decay_by=1e-7))

    return {
        'Fx': np.array(meep.get_forces(Fx)),
        'Fy': np.array(meep.get_forces(Fy)),
        'Fz': np.array(meep.get_forces(Fz)),
        'frequency': np.array(meep.get_force_freqs(Fx))
    }
Exemple #8
0
def norm_sim():
    """perform normalization simulation"""
    norm = meep.Simulation(cell_size=cell,
                           boundary_layers=[pml],
                           geometry=[],
                           default_material=medium,
                           resolution=resolution)
    norm.init_fields()
    source(norm)

    flux_box_inc = meep_ext.add_flux_box(norm, fcen, df, nfreq, [0, 0, 0],
                                         monitor_size)
    flux_inc = meep_ext.add_flux_plane(norm, fcen, df, nfreq, [0, 0, 0],
                                       [box[0], box[1], 0])

    norm.run(until_after_sources=meep.stop_when_fields_decayed(
        .5 * um,
        decay,
        pt=meep.Vector3(0, 0, monitor_size[2] / 2),
        decay_by=1e-3))

    norm.save_flux(norm_file_ext, flux_box_inc)

    return {
        'frequency': np.array(meep.get_flux_freqs(flux_inc)),
        'area': box[0] * box[1],
        'incident': np.asarray(meep.get_fluxes(flux_inc))
    }
Exemple #9
0
def main(args):

    resolution = 40
    cell_size = mp.Vector3(z=10)

    boundary_layers = [
        mp.PML(1, direction=mp.Z) if args.pml else mp.Absorber(1,
                                                               direction=mp.Z)
    ]

    sources = [
        mp.Source(src=mp.GaussianSource(1 / 0.803, fwidth=0.1),
                  center=mp.Vector3(),
                  component=mp.Ex)
    ]

    def print_stuff(sim):
        p = sim.get_field_point(mp.Ex, mp.Vector3())
        print("ex:, {}, {}".format(sim.meep_time(), p.real))

    sim = mp.Simulation(cell_size=cell_size,
                        resolution=resolution,
                        dimensions=1,
                        default_material=Al,
                        boundary_layers=boundary_layers,
                        sources=sources)

    sim.run(mp.at_every(10, print_stuff),
            until_after_sources=mp.stop_when_fields_decayed(
                50, mp.Ex, mp.Vector3(), 1e-6))
Exemple #10
0
def sim(separation):
    """perform scattering simulation"""
    L = separation + 2*radius + 2*pml_monitor_gap + 2*particle_monitor_gap + 2*pml.thickness
    cell = meep.Vector3(L,L,L)

    p1 = meep.Vector3(-separation/2, 0, 0)
    p2 = meep.Vector3(separation/2, 0, 0)
    geometry = [meep.Sphere(center=p1,
                         radius=radius, 
                         material=gold),
                meep.Sphere(center=p2,
                         radius=radius, 
                         material=gold)]

    scat = meep.Simulation(cell_size=cell,
                        boundary_layers=[pml],
                        geometry=geometry,
                        resolution=resolution)
    scat.init_fields()
    source(scat)

    L = 2*radius + 2*particle_monitor_gap
    Fx = meep_ext.add_force_box(scat, fcen, 0, 1, p2, [L,L,L], meep.X)
    Fy = meep_ext.add_force_box(scat, fcen, 0, 1, p2, [L,L,L], meep.Y)
    Fz = meep_ext.add_force_box(scat, fcen, 0, 1, p2, [L,L,L], meep.Z)

    # scat.run(until_after_sources=8*um)
    scat.run(until_after_sources=meep.stop_when_fields_decayed(.5*um, meep.Ex,
                pt=p2-meep.Vector3(0,0,L/2), decay_by=1e-5))

    return {'Fx': np.array(meep.get_forces(Fx))[0], 'Fy': np.array(meep.get_forces(Fy))[0], 'Fz': np.array(meep.get_forces(Fz))[0]}
Exemple #11
0
def norm_sim(monitor_size, unique_id):
    """perform normalization simulation with a given box size"""
    monitor_size = np.asarray(monitor_size)
    cell_size = monitor_size + 2 * pml_monitor_gap + 2 * pml.thickness
    cell = meep.Vector3(*cell_size)

    norm = meep.Simulation(cell_size=cell,
                           boundary_layers=[pml],
                           geometry=[],
                           resolution=resolution)
    norm.init_fields()
    source(norm)

    flux_inc = meep_ext.add_flux_plane(norm, fcen, 0, 1, [0, 0, 0],
                                       [2 * radius, 2 * radius, 0])
    flux_box_inc = meep_ext.add_flux_box(norm, fcen, 0, 1, [0, 0, 0],
                                         monitor_size)

    norm.run(until_after_sources=meep.stop_when_fields_decayed(
        .5 * um,
        meep.Ex,
        pt=meep.Vector3(0, 0, monitor_size[2] / 2),
        decay_by=1e-3))

    norm.save_flux(norm_file_ext.format(unique_id), flux_box_inc)

    return {
        'area': (2 * radius)**2,
        'norm': np.asarray(meep.get_fluxes(flux_inc))
    }
Exemple #12
0
def sim(separation, monitor_size, unique_id):
    """perform scattering simulation"""
    monitor_size = np.asarray(monitor_size)
    cell_size = monitor_size + 2*pml_monitor_gap + 2*pml.thickness
    cell = meep.Vector3(*cell_size)

    p1 = meep.Vector3(-separation/2, 0, 0)
    p2 = meep.Vector3(separation/2, 0, 0)
    geometry = [meep.Sphere(center=p1,
                         radius=radius, 
                         material=gold),
                meep.Sphere(center=p2,
                         radius=radius, 
                         material=gold)]

    scat = meep.Simulation(cell_size=cell,
                        boundary_layers=[pml],
                        geometry=geometry,
                        default_material=medium,
                        resolution=resolution)
    scat.init_fields()
    source(scat)

    flux_box_absorb = meep_ext.add_flux_box(scat, fcen, 0, 1, [0,0,0], monitor_size)
    flux_box_scat   = meep_ext.add_flux_box(scat, fcen, 0, 1, [0,0,0], monitor_size)
    scat.load_minus_flux(norm_file_ext.format(unique_id), flux_box_scat)

    # scat.run(until_after_sources=8*um)
    scat.run(until_after_sources=meep.stop_when_fields_decayed(.5*um, polarization,
                pt=p2 - meep.Vector3(0,0,monitor_size[2]/2), decay_by=1e-4))

    return {'scattering': np.array(meep.get_fluxes(flux_box_scat)), 'absorption': -np.array(meep.get_fluxes(flux_box_absorb))}
Exemple #13
0
def force_sim():
    """perform scattering simulation"""

    sim = meep.Simulation(cell_size=cell,
                          boundary_layers=[pml],
                          geometry=geometry,
                          default_material=medium,
                          resolution=resolution)
    sim.init_fields()
    source(sim)

    L = 2**.5 * W + 2 * particle_monitor_gap
    p = meep.Vector3(sep / 2, 0, 0)
    Fx_mon = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L, L, L], meep.X)
    Fy_mon = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L, L, L], meep.Y)
    Fz_mon = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L, L, L], meep.Z)

    sim.run(until_after_sources=meep.stop_when_fields_decayed(
        .5 * um,
        decay,
        pt=meep.Vector3(0, 0, monitor_size[2] / 2),
        decay_by=1e-5))

    Fx = np.array(meep.get_forces(Fx_mon))
    Fy = np.array(meep.get_forces(Fy_mon))
    Fz = np.array(meep.get_forces(Fz_mon))
    frequency = np.array(meep.get_force_freqs(Fx_mon))
    return dict(frequency=frequency, Fx=Fx, Fy=Fy, Fz=Fz)
Exemple #14
0
    def test_ldos(self):
        self.sim.run(
            mp.dft_ldos(self.fcen, 0, 1),
            until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-6)
        )

        self.assertAlmostEqual(self.sim.ldos_data[0], 1.011459560620368)
Exemple #15
0
def sim():
    """perform scattering simulation"""
    sim = meep.Simulation(cell_size=cell,
                          boundary_layers=[pml],
                          geometry=geometry,
                          default_material=medium,
                          resolution=resolution)
    sim.init_fields()
    sim.init_sim()
    source(sim)

    freq = 1 / (600 * nm)
    # dft = sim.add_dft_fields([meep.Ex, meep.Ey, meep.Ez], freq, freq, 1, center=meep.Vector3(0,0,0),
    # size=meep.Vector3(L,L,0))

    vol = meep.volume(meep.vec(-L / 2, -L / 2, 0), meep.vec(L / 2, L / 2, 0))
    dft = sim.fields.add_dft_fields([meep.Ex, meep.Ey, meep.Ez], vol, freq,
                                    freq, 1)

    sim.run(until_after_sources=meep.stop_when_fields_decayed(
        .5 * um, decay, pt=meep.Vector3(0, 0, box[2] / 2), decay_by=1e-5))
    # for i in range(100):
    # sim.fields.step()

    Ex = sim.get_dft_array(dft, meep.Ex, 0)
    Ey = sim.get_dft_array(dft, meep.Ey, 0)
    Ez = sim.get_dft_array(dft, meep.Ez, 0)
    E = np.array([Ex, Ey, Ez])

    return dict(E=E)
Exemple #16
0
    def run_with_straight_waveguide(self):
        self.init(no_bend=True)
        self.sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ez, self.pt, 1e-3))
        self.sim.save_flux('refl-flux', self.refl)

        expected = [
            (0.1, 3.65231563251e-05, 3.68932495077e-05),
            (0.10101010101, 5.55606718876e-05, 5.6065539588e-05),
            (0.10202020202, 8.38211697478e-05, 8.44909864736e-05),
            (0.10303030303, 0.000125411162229, 0.000126268639045),
            (0.10404040404, 0.000186089117531, 0.000187135303398),
            (0.105050505051, 0.000273848867869, 0.000275039134667),
            (0.106060606061, 0.000399674037745, 0.000400880269423),
            (0.107070707071, 0.00057849953593, 0.000579454087881),
            (0.108080808081, 0.000830418432986, 0.000830635406881),
            (0.109090909091, 0.00118217282661, 0.00118084271347),
            (0.110101010101, 0.00166896468348, 0.00166481944189),
            (0.111111111111, 0.00233661613864, 0.00232776318321),
            (0.112121212121, 0.00324409729096, 0.00322782257917),
            (0.113131313131, 0.00446642217385, 0.00443896468822),
            (0.114141414141, 0.0060978895019, 0.0060541922825),
            (0.115151515152, 0.00825561352398, 0.00818906047274),
            (0.116161616162, 0.0110832518495, 0.010985404883),
            (0.117171717172, 0.0147547920552, 0.0146151488236),
            (0.118181818182, 0.0194782085272, 0.0192840042241),
            (0.119191919192, 0.0254987474079, 0.0252348211592),
        ]

        res = list(
            zip(mp.get_flux_freqs(self.trans), mp.get_fluxes(self.trans),
                mp.get_fluxes(self.refl)))

        np.testing.assert_allclose(expected, res[:20])
Exemple #17
0
    def test_absorber(self):

        self.sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ex, mp.Vector3(), 1e-6))

        f = self.sim.get_field_point(mp.Ex, mp.Vector3())
        self.assertAlmostEqual(f.real, 4.789444250711607e-10, places=6)
Exemple #18
0
    def test_ldos(self):
        self.sim.run(
            mp.dft_ldos(self.fcen, 0, 1),
            until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-6)
        )

        self.assertAlmostEqual(self.sim.ldos_data[0], 1.011459560620368)
Exemple #19
0
def force_sim():
    """perform scattering simulation"""

    sim = meep.Simulation(cell_size=cell,
                        boundary_layers=[pml],
                        geometry=geometry,
                        default_material=medium,
                        resolution=resolution)
    sim.init_fields()
    source(sim)

    L = 2*radius + 2*particle_monitor_gap
    forces = {}
    for i in range(9):
        p = meep.Vector3(x[i], y[i], z[i])
        key = 'N{i}_F{c}'
        forces[key.format(i=i, c='x')] = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L,L,L], meep.X)
        forces[key.format(i=i, c='y')] = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L,L,L], meep.Y)
        forces[key.format(i=i, c='z')] = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L,L,L], meep.Z)

    sim.run(until_after_sources=meep.stop_when_fields_decayed(.5*um, decay,
                pt=meep.Vector3(0,0,monitor_size[2]/2), decay_by=1e-8))

    ret = {}
    for i in range(9):
        for c in ['x', 'y', 'z']:
            key = f'N{i}_F{c}'
            ret[key] = np.array(meep.get_forces(forces[key]))

    ret['frequency'] = np.array(meep.get_force_freqs(forces['N1_Fx']))
    return ret
Exemple #20
0
    def test_absorber(self):

        self.sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ex, mp.Vector3(), 1e-6))

        f = self.sim.get_field_point(mp.Ex, mp.Vector3())
        self.assertAlmostEqual(f.real, 3.218846961494622e-13, places=6)
Exemple #21
0
    def test_ldos_user_object(self):
        ldos = mp.Ldos(self.fcen, 0, 1)
        self.sim.run(mp.dft_ldos(ldos=ldos),
                     until_after_sources=mp.stop_when_fields_decayed(
                         50, mp.Ez, mp.Vector3(), 1e-6))

        self.assertAlmostEqual(self.sim.ldos_data[0], 1.011459560620368)
        self.assertEqual(len(mp.get_ldos_freqs(ldos)), 1)
Exemple #22
0
def main(args):

    resolution = 20
    cell_size = mp.Vector3(z=10)
    dimensions = 1

    # conversion factor fro eV to 1/um
    eV_um_scale = 1 / 1.23984193

    # Al, from Rakic et al., Applied Optics, vol. 32, p. 5274 (1998)
    Al_eps_inf = 1
    Al_plasma_frq = 14.98 * eV_um_scale

    Al_f0 = 0.523
    Al_frq0 = 1e-10
    Al_gam0 = 0.047 * eV_um_scale
    Al_sig0 = (Al_f0 * math.sqrt(Al_plasma_frq)) / (math.sqrt(Al_frq0))

    Al_f1 = 0.050
    Al_frq1 = 1.544 * eV_um_scale  # 803 nm
    Al_gam1 = 0.312 * eV_um_scale
    Al_sig1 = (Al_f1 * math.sqrt(Al_plasma_frq)) / (math.sqrt(Al_frq1))

    E_susceptibilities = [
        mp.DrudeSusceptibility(frequency=Al_frq0, gamma=Al_gam0,
                               sigma=Al_sig0),
        mp.LorentzianSusceptibility(frequency=Al_frq1,
                                    gamma=Al_gam1,
                                    sigma=Al_sig1)
    ]

    Al = mp.Medium(epsilon=Al_eps_inf, E_susceptibilities=E_susceptibilities)

    pml_layers = [
        mp.PML(1, direction=mp.Z) if args.pml else mp.Absorber(1,
                                                               direction=mp.Z)
    ]

    sources = [
        mp.Source(src=mp.GaussianSource(1 / 0.803, fwidth=0.1),
                  center=mp.Vector3(),
                  component=mp.Ex)
    ]

    def print_stuff(sim):
        print("ex:, {}, {}".format(sim.meep_time(),
                                   sim.get_field_point(mp.Ex, mp.Vector3())))

    sim = mp.Simulation(cell_size=cell_size,
                        resolution=resolution,
                        dimensions=dimensions,
                        default_material=Al,
                        boundary_layers=pml_layers,
                        sources=sources)

    sim.run(mp.at_every(10, print_stuff),
            until_after_sources=mp.stop_when_fields_decayed(
                50, mp.Ex, mp.Vector3(), 1e-6))
    def test_farfield(self):

        expected = [
            (0j, 0j,
             0.013561672901190156 - 0.014417985982674887j,
             -0.007972091889832573 + 0.008474039259808384j,
             -0.010972504173533907 + 0.011663526883728901j, 0j),
            (0j, 0j,
             0.013580605154131353 - 0.014437805790483897j,
             -0.00727747760452799 + 0.007735510886150803j,
             -0.011467448148229137 + 0.01218937654274057j, 0j),
            (0j, 0j,
             0.013623909088910181 - 0.0144248508451555j,
             -0.006563855061778871 + 0.0069485969930299695j,
             -0.011939764884917667 + 0.012639701096677738j, 0j),
            (0j, 0j,
             0.01366551237281673 - 0.014382588988355682j,
             -0.005818861980069385 + 0.006123274021053104j,
             -0.012366016128341942 + 0.013012805294365515j, 0j),
            (0j, 0j,
             0.013680914029322 - 0.014330104120260687j,
             -0.00503658263321274 + 0.005274864846985408j,
             -0.012721298907853191 + 0.013322780730790889j, 0j),
            (0j, 0j,
             0.013666069573084385 - 0.014288938849212545j,
             -0.004223325784559204 + 0.004415251197679649j,
             -0.01299830976630439 + 0.0135885339986728j, 0j),
            (0j, 0j,
             0.013636004904245425 - 0.014270749446931172j,
             -0.003391403389081595 + 0.003548797079942323j,
             -0.013208708739843122 + 0.013821337222637264j, 0j),
            (0j, 0j,
             0.013609442340491029 - 0.014273698854090303j,
             -0.0025503938754594265 + 0.0026744729386901805j,
             -0.013369492605877786 + 0.014019798855923278j, 0j),
            (0j, 0j,
             0.013595569402532206 - 0.014287439152148014j,
             -0.0017041572263699332 + 0.001790574472119783j,
             -0.013489487541122221 + 0.014173702684166192j, 0j),
            (0j, 0j,
             0.01359208053488311 - 0.014300667598824968j,
             -8.535506874711307e-4 + 8.978801355605307e-4j,
             -0.01356639388716244 + 0.01427136892007339j, 0j)
        ]

        self.sim.run(until_after_sources=mp.stop_when_fields_decayed(50, self.src_cmpt, mp.Vector3(), 1e-8))
        r = 1000
        npts = 100

        result = []
        for n in range(npts):
            ff = self.sim.get_farfield(
                self.nearfield,
                mp.Vector3(r * math.cos(2 * math.pi * (n / npts)),
                           r * math.sin(2 * math.pi * (n / npts))))
            result.append(ff)

        np.testing.assert_allclose(expected, result[-10:])
Exemple #24
0
    def test_force(self):

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

        self.sim.display_forces(self.myforce)
        f = mp.get_forces(self.myforce)

        self.assertAlmostEqual(f[0], -0.11039089113393187)
Exemple #25
0
def monitor_until(geo=None, until=None, **kwargs):
    geo = kwargs_to_geo(geo, **kwargs)
    stop_kwarg = dict()
    if until is None:
        monitor_point = mp.Vector3(monitor_x(geo), 0, 0)
        stop_kwarg['until_after_sources'] = mp.stop_when_fields_decayed(
            20, mp.Ey, monitor_point, 1e-3)
    else:
        stop_kwarg['until'] = until
    return stop_kwarg
Exemple #26
0
def main(args):

    resolution = args.res

    sz = args.sz
    cell_size = mp.Vector3(0, 0, sz)

    lambda_min = 0.4
    lambda_max = 0.8
    fmax = 1 / lambda_min
    fmin = 1 / lambda_max
    fcen = 0.5 * (fmax + fmin)
    df = fmax - fmin

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

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

    if args.empty:
        geometry = []
    else:
        geometry = [
            mp.Block(mp.Vector3(mp.inf, mp.inf, 0.5 * sz),
                     center=mp.Vector3(0, 0, 0.25 * sz),
                     material=fused_quartz)
        ]

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

    refl_fr = mp.FluxRegion(center=mp.Vector3(0, 0, -0.25 * sz))

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

    if not args.empty:
        sim.load_minus_flux('refl-flux', refl)

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

    if args.empty:
        sim.save_flux('refl-flux', refl)

    sim.display_fluxes(refl)
Exemple #27
0
    def test_ldos_user_object(self):
        ldos = mp.Ldos(self.fcen, 0, 1)
        self.sim.run(mp.dft_ldos(ldos=ldos),
                     until_after_sources=mp.stop_when_fields_decayed(
                         50, mp.Ez, mp.Vector3(), 1e-6))

        self.assertAlmostEqual(self.sim.ldos_data[0], 1.011459560620368)
        freqs = ldos.freqs()
        self.assertEqual(ldos.freq_min, freqs[0] * 2 * math.pi)
        self.assertEqual(ldos.nfreq, 1)
        self.assertEqual(ldos.dfreq, 0)
Exemple #28
0
def main(args):

    sz = 100  # size of cell in z direction
    fcen = 1 / 3.0  # center frequency of source
    df = fcen / 20.0  # frequency width of source
    amp = args.amp  # amplitude of source
    k = 10**args.logk  # Kerr susceptibility
    dpml = 1.0  # PML thickness

    # We'll use an explicitly 1d simulation.  Setting dimensions=1 will actually
    # result in faster execution than just using two no-size dimensions.  However,
    # in this case Meep requires us to use E in the x direction (and H in y),
    # and our one no-size dimension must be z.
    dimensions = 1
    cell = mp.Vector3(0, 0, sz)
    pml_layers = mp.PML(dpml)
    resolution = 20

    # to put the same material in all space, we can just set the default material
    # and pass it to the Simulation constructor
    default_material = mp.Medium(index=1, chi3=k)

    sources = mp.Source(mp.GaussianSource(fcen, fwidth=df),
                        component=mp.Ex,
                        center=mp.Vector3(0, 0, -0.5 * sz + dpml),
                        amplitude=amp)

    # frequency range for flux calculation
    nfreq = 400
    fmin = fcen / 2.0
    fmax = fcen * 4

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

    # trans = sim.add_flux(0.5 * (fmin + fmax), fmax - fmin, nfreq,
    #                      mp.FluxRegion(mp.Vector3(0, 0, 0.5*sz - dpml - 0.5)))
    trans1 = sim.add_flux(
        fcen, 0, 1, mp.FluxRegion(mp.Vector3(0, 0, 0.5 * sz - dpml - 0.5)))
    trans3 = sim.add_flux(
        3 * fcen, 0, 1, mp.FluxRegion(mp.Vector3(0, 0, 0.5 * sz - dpml - 0.5)))

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

    # sim.display_fluxes(trans)
    print("harmonics:, {}, {}, {}, {}".format(k, amp,
                                              mp.get_fluxes(trans1)[0],
                                              mp.get_fluxes(trans3)[0]))
Exemple #29
0
    def test_ldos_user_object(self):
        ldos = mp.Ldos(self.fcen, 0, 1)
        self.sim.run(
            mp.dft_ldos(ldos=ldos),
            until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-6)
        )

        self.assertAlmostEqual(self.sim.ldos_data[0], 1.011459560620368)
        freqs = ldos.freqs()
        self.assertEqual(ldos.freq_min, freqs[0] * 2 * math.pi)
        self.assertEqual(ldos.nfreq, 1)
        self.assertEqual(ldos.dfreq, 0)
Exemple #30
0
    def test_force(self):

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

        # Test store and load of force as numpy array
        fdata = self.sim.get_force_data(self.myforce)
        self.sim.load_force_data(self.myforce, fdata)

        self.sim.display_forces(self.myforce)
        f = mp.get_forces(self.myforce)

        self.assertAlmostEqual(f[0], -0.11039089113393187)
Exemple #31
0
    def test_force(self):

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

        # Test store and load of force as numpy array
        fdata = self.sim.get_force_data(self.myforce)
        self.sim.load_force_data(self.myforce, fdata)

        self.sim.display_forces(self.myforce)
        f = mp.get_forces(self.myforce)

        self.assertAlmostEqual(f[0], -0.11039089113393187)
Exemple #32
0
    def test_3rd_harm_1d(self):

        expected_harmonics = [0.01, 1.0, 221.89548712071553, 1.752960413399477]

        self.sim.run(
            until_after_sources=mp.stop_when_fields_decayed(
                50, mp.Ex, mp.Vector3(0, 0, (0.5 * self.sz) - self.dpml - 0.5), 1e-6
            )
        )

        harmonics = [self.k, self.amp, mp.get_fluxes(self.trans1)[0], mp.get_fluxes(self.trans3)[0]]

        np.testing.assert_allclose(expected_harmonics, harmonics)
Exemple #33
0
def main(args):

    sz = 100          # size of cell in z direction
    fcen = 1 / 3.0    # center frequency of source
    df = fcen / 20.0  # frequency width of source
    amp = args.amp    # amplitude of source
    k = 10**args.logk # Kerr susceptibility
    dpml = 1.0        # PML thickness

    # We'll use an explicitly 1d simulation.  Setting dimensions=1 will actually
    # result in faster execution than just using two no-size dimensions.  However,
    # in this case Meep requires us to use E in the x direction (and H in y),
    # and our one no-size dimension must be z.
    dimensions = 1
    cell = mp.Vector3(0, 0, sz)
    pml_layers = mp.PML(dpml)
    resolution = 20

    # to put the same material in all space, we can just set the default material
    # and pass it to the Simulation constructor
    default_material = mp.Medium(index=1, chi3=k)

    sources = mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ex,
                        center=mp.Vector3(0, 0, -0.5*sz + dpml), amplitude=amp)

    # frequency range for flux calculation
    nfreq = 400
    fmin = fcen / 2.0
    fmax = fcen * 4

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

    # trans = sim.add_flux(0.5 * (fmin + fmax), fmax - fmin, nfreq,
    #                      mp.FluxRegion(mp.Vector3(0, 0, 0.5*sz - dpml - 0.5)))
    trans1 = sim.add_flux(fcen, 0, 1,
                          mp.FluxRegion(mp.Vector3(0, 0, 0.5*sz - dpml - 0.5)))
    trans3 = sim.add_flux(3 * fcen, 0, 1,
                          mp.FluxRegion(mp.Vector3(0, 0, 0.5*sz - dpml - 0.5)))

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

    # sim.display_fluxes(trans)
    print("harmonics:, {}, {}, {}, {}".format(k, amp, mp.get_fluxes(trans1)[0], mp.get_fluxes(trans3)[0]))
Exemple #34
0
    def test_3rd_harm_1d(self):

        expected_harmonics = [0.01, 1.0, 221.89548712071553, 1.752960413399477]

        self.sim.run(
            until_after_sources=mp.stop_when_fields_decayed(
                50, mp.Ex, mp.Vector3(0, 0, (0.5 * self.sz) - self.dpml - 0.5), 1e-6
            )
        )

        harmonics = [self.k, self.amp, mp.get_fluxes(self.trans1)[0], mp.get_fluxes(self.trans3)[0]]

        tol = 3e-5 if mp.is_single_precision() else 1e-7
        self.assertClose(expected_harmonics, harmonics, epsilon=tol)
Exemple #35
0
    def test_ninety_degree_bend(self):
        # We have to run the straight waveguide version first to generate the 'refl-flux'
        # file that this test uses. We can't just prepend run_with_straight_waveguide
        # with 'test_' because execution order of unit tests isn't deterministic.
        self.run_with_straight_waveguide()
        self.sim = None
        self.init()
        self.sim.load_minus_flux('refl-flux', self.refl)
        self.sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ez, self.pt, 1e-3))

        expected = [
            (0.09999999999999999, 1.8392235204829767e-5,
             -7.259467687598002e-6),
            (0.10101010101010101, 2.7629932558236724e-5,
             -1.1107162110079347e-5),
            (0.10202020202020202, 4.1001228946782745e-5,
             -1.687561915798036e-5),
            (0.10303030303030304, 6.018966076122556e-5,
             -2.5425779493709066e-5),
            (0.10404040404040406, 8.758554071933231e-5, -3.794958119189475e-5),
            (0.10505050505050507, 1.2656696778129198e-4,
             -5.612512808928115e-5),
            (0.10606060606060609, 1.817948859871414e-4, -8.232188174309142e-5),
            (0.10707070707070711, 2.594514094902856e-4,
             -1.1981531280672989e-4),
            (0.10808080808080812, 3.6736164837695035e-4,
             -1.7300125173897737e-4),
            (0.10909090909090914, 5.150131339048232e-4, -2.476730940385436e-4),
            (0.11010101010101016, 7.136181099374187e-4,
             -3.5145561406042276e-4),
            (0.11111111111111117, 9.76491765781944e-4, -4.944142331545938e-4),
            (0.11212121212121219, 0.001320033637882244, -6.897357105189368e-4),
            (0.11313131313131321, 0.0017653940714397098,
             -9.543556354451615e-4),
            (0.11414141414141422, 0.0023404727796352857,
             -0.0013095604571818236),
            (0.11515151515151524, 0.0030813962415392098, -0.00178176942635486),
            (0.11616161616161626, 0.00403238648982478, -0.0024036650652026112),
            (0.11717171717171727, 0.005243320443599316, -0.003215529845495731),
            (0.11818181818181829, 0.0067654019326068, -0.004266367104375331),
            (0.11919191919191931, 0.008646855439680507, -0.005614491919262783),
        ]

        res = list(
            zip(mp.get_flux_freqs(self.trans), mp.get_fluxes(self.trans),
                mp.get_fluxes(self.refl)))

        np.testing.assert_allclose(expected, res[:20])
Exemple #36
0
    def test_3rd_harm_1d(self):

        expected_harmonics = [0.01, 1.0, 221.89548712071553, 1.752960413399477]

        self.sim.run(until_after_sources=mp.stop_when_fields_decayed(
            50, mp.Ex, mp.Vector3(0, 0, (0.5 * self.sz) - self.dpml -
                                  0.5), 1e-6))

        harmonics = [
            self.k, self.amp,
            mp.get_fluxes(self.trans1)[0],
            mp.get_fluxes(self.trans3)[0]
        ]

        np.testing.assert_allclose(expected_harmonics, harmonics)
Exemple #37
0
def main(args):

    resolution = 40
    cell_size = mp.Vector3(z=10)

    boundary_layers = [mp.PML(1, direction=mp.Z) if args.pml else mp.Absorber(1, direction=mp.Z)]

    sources = [mp.Source(src=mp.GaussianSource(1 / 0.803, fwidth=0.1),
                         center=mp.Vector3(),
                         component=mp.Ex)]

    def print_stuff(sim):
        p = sim.get_field_point(mp.Ex, mp.Vector3())
        print("ex:, {}, {}".format(sim.meep_time(), p.real))

    sim = mp.Simulation(cell_size=cell_size,
                        resolution=resolution,
                        dimensions=1,
                        default_material=Al,
                        boundary_layers=boundary_layers,
                        sources=sources)

    sim.run(mp.at_every(10, print_stuff),
            until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(), 1e-6))
Exemple #38
0
    vertices = [mp.Vector3(-0.5*sx-1,0.5*w1),
                mp.Vector3(0.5*sx+1,0.5*w1),
                mp.Vector3(0.5*sx+1,-0.5*w1),
                mp.Vector3(-0.5*sx-1,-0.5*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_x+0.7*Lw)
    flux = sim.add_flux(fcen,0,1,mp.FluxRegion(center=mon_pt,size=mp.Vector3(y=sy-2*dpml_y)))

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

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

    sim.reset_meep()

    # linear taper
    vertices = [mp.Vector3(-0.5*sx-1,0.5*w1),
                mp.Vector3(-0.5*Lt,0.5*w1),
                mp.Vector3(0.5*Lt,0.5*w2),
                mp.Vector3(0.5*sx+1,0.5*w2),
                mp.Vector3(0.5*sx+1,-0.5*w2),
                mp.Vector3(0.5*Lt,-0.5*w2),
Exemple #39
0
                    symmetries=symmetries,
                    boundary_layers=pml_layers)

nearfield_box = sim.add_near2far(fcen, 0, 1,
                                 mp.Near2FarRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)),
                                 mp.Near2FarRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1),
                                 mp.Near2FarRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)),
                                 mp.Near2FarRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1))

flux_box = sim.add_flux(fcen, 0, 1,
                        mp.FluxRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)),
                        mp.FluxRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1),
                        mp.FluxRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)),
                        mp.FluxRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1))

sim.run(until_after_sources=mp.stop_when_fields_decayed(50, src_cmpt, mp.Vector3(), 1e-8))

near_flux = mp.get_fluxes(flux_box)[0]

r = 1000/fcen      # half side length of far-field square box OR radius of far-field circle
res_ff = 1         # resolution of far fields (points/μm)
far_flux_box = (nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=r), size=mp.Vector3(2*r)), res_ff)[0]
               - nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=-r), size=mp.Vector3(2*r)), res_ff)[0]
               + nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(r), size=mp.Vector3(y=2*r)), res_ff)[0]
               - nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(-r), size=mp.Vector3(y=2*r)), res_ff)[0])

npts = 100         # number of points in [0,2*pi) range of angles
angles = 2*math.pi/npts*np.arange(npts)

E = np.zeros((npts,3),dtype=np.complex128)
H = np.zeros((npts,3),dtype=np.complex128)
Exemple #40
0
    def test_absorber(self):

        self.sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(), 1e-6))

        f = self.sim.get_field_point(mp.Ex, mp.Vector3())
        self.assertAlmostEqual(f.real, 3.218846961494622e-13, places=6)
Exemple #41
0
df = 0.2                           # pulse width (in frequency)

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

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

d1 = 0.2

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

nearfield = sim.add_near2far(
    fcen, 0, 1,
    mp.Near2FarRegion(mp.Vector3(0, 0.5 * w + d1), size=mp.Vector3(2 * dpml - sx)),
    mp.Near2FarRegion(mp.Vector3(-0.5 * sx + dpml, 0.5 * w + 0.5 * d1), size=mp.Vector3(0, d1), weight=-1.0),
    mp.Near2FarRegion(mp.Vector3(0.5 * sx - dpml, 0.5 * w + 0.5 * d1), size=mp.Vector3(0, d1))
)

sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Hz, mp.Vector3(0.12, -0.37), 1e-8))

d2 = 20
h = 4

sim.output_farfields(nearfield, "spectra-{}-{}-{}".format(d1, d2, h), resolution,
                     where=mp.Volume(mp.Vector3(0, (0.5 * w) + d2 + (0.5 * h)),
                                     size=mp.Vector3(sx - 2 * dpml, h)))
Exemple #42
0
fcen = 0.5*(fmax+fmin)
df = fmax-fmin
nfreq = 50

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

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

refl_fr = mp.FluxRegion(center=mp.Vector3(0,0,-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(), 1e-9))

empty_flux = mp.get_fluxes(refl)
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(0,0,0.25*sz), material=fused_quartz) ]

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

refl = sim.add_flux(fcen, df, nfreq, refl_fr)
Exemple #43
0
    def test_transmission_spectrum(self):
        expected = [
            (0.15, 7.218492264696595e-6),
            (0.1504008016032064, 6.445696315927592e-6),
            (0.1508016032064128, 5.140949243632777e-6),
            (0.15120240480961922, 3.6159747936427164e-6),
            (0.15160320641282563, 2.263940553705969e-6),
            (0.15200400801603203, 1.4757165844336744e-6),
            (0.15240480961923844, 1.5491803919142815e-6),
            (0.15280561122244485, 2.612053246626972e-6),
            (0.15320641282565126, 4.577504371188737e-6),
            (0.15360721442885766, 7.1459089162998185e-6),
            (0.15400801603206407, 9.856622013418823e-6),
            (0.15440881763527048, 1.2182309227954296e-5),
            (0.1548096192384769, 1.3647726444709649e-5),
            (0.1552104208416833, 1.3947420613633674e-5),
            (0.1556112224448897, 1.303466755716231e-5),
            (0.1560120240480961, 1.115807915037775e-5),
            (0.15641282565130252, 8.832335196969796e-6),
            (0.15681362725450892, 6.743645773127985e-6),
            (0.15721442885771533, 5.605913756087576e-6),
            (0.15761523046092174, 5.996668564026961e-6),
            (0.15801603206412815, 8.209400611614078e-6),
            (0.15841683366733456, 1.2158641936828497e-5),
            (0.15881763527054096, 1.73653230513453e-5),
            (0.15921843687374737, 2.303382576477893e-5),
            (0.15961923847695378, 2.821180350795834e-5),
            (0.1600200400801602, 3.200359292911769e-5),
            (0.1604208416833666, 3.3792624373001934e-5),
            (0.160821643286573, 3.342171394788991e-5),
            (0.1612224448897794, 3.1284866146526904e-5),
            (0.16162324649298582, 2.830022088581398e-5),
            (0.16202404809619222, 2.5758413657344014e-5),
            (0.16242484969939863, 2.506899997971769e-5),
            (0.16282565130260504, 2.7453508915303887e-5),
            (0.16322645290581145, 3.365089813497114e-5),
            (0.16362725450901786, 4.370486834112e-5),
            (0.16402805611222426, 5.689050715055283e-5),
            (0.16442885771543067, 7.181133157470506e-5),
            (0.16482965931863708, 8.666168027415369e-5),
            (0.16523046092184349, 9.961094123261317e-5),
            (0.1656312625250499, 1.0923388232657953e-4),
            (0.1660320641282563, 1.1489334204708105e-4),
            (0.1664328657314627, 1.1698318060032011e-4),
            (0.16683366733466912, 1.169621456132733e-4),
            (0.16723446893787552, 1.1714995241571987e-4),
            (0.16763527054108193, 1.2030783847222252e-4),
            (0.16803607214428834, 1.2907652919660887e-4),
        ]

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

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

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

        trans = self.sim.add_flux(self.fcen, self.df, self.nfreq, freg)

        self.sim.run(
            until_after_sources=mp.stop_when_fields_decayed(
                50, mp.Ey, mp.Vector3((0.5 * self.sx) - self.dpml - 0.5, 0), 1e-1)
        )

        res = zip(mp.get_flux_freqs(trans), mp.get_fluxes(trans))

        for e, r in zip(expected, res):
            np.testing.assert_allclose(e, r)
Exemple #44
0
    def run_bend_flux(self, from_gdsii_file):
        # Normalization run
        self.init(no_bend=True, gdsii=from_gdsii_file)
        self.sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, self.pt, 1e-3))
        # Save flux data for use in real run below
        fdata = self.sim.get_flux_data(self.refl)

        expected = [
            (0.1, 3.65231563251e-05, 3.68932495077e-05),
            (0.10101010101, 5.55606718876e-05, 5.6065539588e-05),
            (0.10202020202, 8.38211697478e-05, 8.44909864736e-05),
            (0.10303030303, 0.000125411162229, 0.000126268639045),
            (0.10404040404, 0.000186089117531, 0.000187135303398),
            (0.105050505051, 0.000273848867869, 0.000275039134667),
            (0.106060606061, 0.000399674037745, 0.000400880269423),
            (0.107070707071, 0.00057849953593, 0.000579454087881),
            (0.108080808081, 0.000830418432986, 0.000830635406881),
            (0.109090909091, 0.00118217282661, 0.00118084271347),
            (0.110101010101, 0.00166896468348, 0.00166481944189),
            (0.111111111111, 0.00233661613864, 0.00232776318321),
            (0.112121212121, 0.00324409729096, 0.00322782257917),
            (0.113131313131, 0.00446642217385, 0.00443896468822),
            (0.114141414141, 0.0060978895019, 0.0060541922825),
            (0.115151515152, 0.00825561352398, 0.00818906047274),
            (0.116161616162, 0.0110832518495, 0.010985404883),
            (0.117171717172, 0.0147547920552, 0.0146151488236),
            (0.118181818182, 0.0194782085272, 0.0192840042241),
            (0.119191919192, 0.0254987474079, 0.0252348211592),
        ]

        res = list(zip(mp.get_flux_freqs(self.trans), mp.get_fluxes(self.trans), mp.get_fluxes(self.refl)))

        tolerance = 1e-2 if from_gdsii_file else 1e-3
        compare_arrays(self, np.array(expected), np.array(res[:20]), tol=tolerance)

        # Real run
        self.sim = None
        self.init(gdsii=from_gdsii_file)
        # Load flux data obtained from normalization run
        self.sim.load_minus_flux_data(self.refl, fdata)
        self.sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, self.pt, 1e-3))

        expected = [
            (0.09999999999999999, 1.8392235204829767e-5, -7.259467687598002e-6),
            (0.10101010101010101, 2.7629932558236724e-5, -1.1107162110079347e-5),
            (0.10202020202020202, 4.1001228946782745e-5, -1.687561915798036e-5),
            (0.10303030303030304, 6.018966076122556e-5, -2.5425779493709066e-5),
            (0.10404040404040406, 8.758554071933231e-5, -3.794958119189475e-5),
            (0.10505050505050507, 1.2656696778129198e-4, -5.612512808928115e-5),
            (0.10606060606060609, 1.817948859871414e-4, -8.232188174309142e-5),
            (0.10707070707070711, 2.594514094902856e-4, -1.1981531280672989e-4),
            (0.10808080808080812, 3.6736164837695035e-4, -1.7300125173897737e-4),
            (0.10909090909090914, 5.150131339048232e-4, -2.476730940385436e-4),
            (0.11010101010101016, 7.136181099374187e-4, -3.5145561406042276e-4),
            (0.11111111111111117, 9.76491765781944e-4, -4.944142331545938e-4),
            (0.11212121212121219, 0.001320033637882244, -6.897357105189368e-4),
            (0.11313131313131321, 0.0017653940714397098, -9.543556354451615e-4),
            (0.11414141414141422, 0.0023404727796352857, -0.0013095604571818236),
            (0.11515151515151524, 0.0030813962415392098, -0.00178176942635486),
            (0.11616161616161626, 0.00403238648982478, -0.0024036650652026112),
            (0.11717171717171727, 0.005243320443599316, -0.003215529845495731),
            (0.11818181818181829, 0.0067654019326068, -0.004266367104375331),
            (0.11919191919191931, 0.008646855439680507, -0.005614491919262783),

        ]

        res = list(zip(mp.get_flux_freqs(self.trans), mp.get_fluxes(self.trans), mp.get_fluxes(self.refl)))

        tolerance = 1e-2 if from_gdsii_file else 1e-3
        compare_arrays(self, np.array(expected), np.array(res[:20]), tol=tolerance)
Exemple #45
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)
Exemple #46
0
def main(args):
    resolution = 20 # pixels/um
    
    eps = 13      # dielectric constant of waveguide
    w = 1.2       # width of waveguide
    r = 0.36      # radius of holes
    d = 1.4       # defect spacing (ordinary spacing = 1)
    N = args.N    # number of holes on either side of defect

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

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

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

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

    geometry = [blk]

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

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

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

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

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

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

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

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

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

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

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

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

        sim.display_fluxes(trans)  # print out the flux spectrum
Exemple #47
0
    def test_farfield(self):
        resolution = 50
        sxy = 4
        dpml = 1
        cell = mp.Vector3(sxy+2*dpml,sxy+2*dpml,0)

        pml_layers = mp.PML(dpml)

        fcen = 1.0
        df = 0.4

        sources = mp.Source(src=mp.GaussianSource(fcen,fwidth=df),
                            center=mp.Vector3(),
                            component=mp.Ez)

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

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

        nearfield_box = sim.add_near2far(fcen, 0, 1,
                                         mp.Near2FarRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)),
                                         mp.Near2FarRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1),
                                         mp.Near2FarRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)),
                                         mp.Near2FarRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1))

        flux_box = sim.add_flux(fcen, 0, 1,
                                mp.FluxRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)),
                                mp.FluxRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1),
                                mp.FluxRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)),
                                mp.FluxRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1))

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

        near_flux = mp.get_fluxes(flux_box)[0]

        r = 1000/fcen      # radius of far field circle
        npts = 100         # number of points in [0,2*pi) range of angles
        E = np.zeros((npts,3),dtype=np.complex128)
        H = np.zeros((npts,3),dtype=np.complex128)
        for n in range(npts):
            ff = sim.get_farfield(nearfield_box,
                                  mp.Vector3(r*math.cos(2*math.pi*n/npts),
                                             r*math.sin(2*math.pi*n/npts)))
            E[n,:] = [np.conj(ff[j]) for j in range(3)]
            H[n,:] = [ff[j+3] for j in range(3)]

        Px = np.real(np.multiply(E[:,1],H[:,2])-np.multiply(E[:,2],H[:,1]))
        Py = np.real(np.multiply(E[:,2],H[:,0])-np.multiply(E[:,0],H[:,2]))
        Pr = np.sqrt(np.square(Px)+np.square(Py))
        far_flux_circle = np.sum(Pr)*2*np.pi*r/len(Pr)

        rr = 20/fcen      # length of far field square box
        far_flux_square = (nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=0.5*rr), size=mp.Vector3(rr)), resolution)[0]
                           - nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=-0.5*rr), size=mp.Vector3(rr)), resolution)[0]
                           + nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(0.5*rr), size=mp.Vector3(y=rr)), resolution)[0]
                           - nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(-0.5*rr), size=mp.Vector3(y=rr)), resolution)[0])

        print("flux:, {:.6f}, {:.6f}, {:.6f}".format(near_flux,far_flux_circle,far_flux_square))

        self.assertAlmostEqual(near_flux, far_flux_circle, places=2)
        self.assertAlmostEqual(far_flux_circle, far_flux_square, places=2)
        self.assertAlmostEqual(far_flux_square, near_flux, places=2)
Exemple #48
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))

        res = sim.get_eigenmode_coefficients(flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y)
        incident_coeffs = res.alpha
        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))

        res = sim.get_eigenmode_coefficients(refl_flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y)
        coeffs = res.alpha
        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)