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 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 #3
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 #4
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 #5
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 #6
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 #7
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 #8
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 #9
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 #10
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 #11
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 #12
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))
    }
    def _stop(sim):

        if sim.round_time() <= dt + closure['t0']:
            return False
        else:
            previous_fields = closure['previous_fields']

            # Pull all the relevant frequency and spatial dft points
            relative_change = []
            current_fields = [[0 for di in d] for d in dims]
            for mi, m in enumerate(mon):
                for ic, cc in enumerate(c):
                    if isinstance(m,mp.DftFlux):
                        current_fields[mi][ic] = mp.get_fluxes(m)[fcen_idx]
                    elif isinstance(m,mp.DftFields):
                        current_fields[mi][ic] = atleast_3d(sim.get_dft_array(m, cc, fcen_idx))
                    else:
                        raise TypeError("Monitor of type {} not supported".format(type(m)))
                    relative_change_raw = np.abs(previous_fields[mi][ic] - current_fields[mi][ic]) / np.abs(previous_fields[mi][ic])
                    relative_change.append(np.mean(relative_change_raw.flatten())) # average across space and frequency
            relative_change = np.mean(relative_change) # average across monitors
            closure['previous_fields'] = current_fields
            closure['t0'] = sim.round_time()

            if mp.verbosity > 0:
                fmt = "DFT decay(t = {0:1.1f}): {1:0.4e}"
                print(fmt.format(sim.meep_time(), np.real(relative_change)))
            return relative_change <= decay_by and sim.round_time() >= minimum_run_time
Exemple #14
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 #15
0
    def test_dft_energy(self):
        resolution = 20
        cell = mp.Vector3(10, 5)
        geom = [mp.Block(size=mp.Vector3(mp.inf, 1, mp.inf), material=mp.Medium(epsilon=12))]
        pml = [mp.PML(1)]
        fsrc  = 0.15
        sources = [mp.EigenModeSource(src=mp.GaussianSource(frequency=fsrc, fwidth=0.2*fsrc),
                                      center=mp.Vector3(-3), size=mp.Vector3(y=5),
                                      eig_band=1, eig_parity=mp.ODD_Z+mp.EVEN_Y,
                                      eig_match_freq=True)]

        sim = mp.Simulation(resolution=resolution, cell_size=cell, geometry=geom,
                            boundary_layers=pml, sources=sources, symmetries=[mp.Mirror(direction=mp.Y)])

        flux = sim.add_flux(fsrc, 0, 1, mp.FluxRegion(center=mp.Vector3(3), size=mp.Vector3(y=5)))
        energy = sim.add_energy(fsrc, 0, 1, mp.EnergyRegion(center=mp.Vector3(3), size=mp.Vector3(y=5)))
        sim.run(until_after_sources=100)

        res = sim.get_eigenmode_coefficients(flux, [1], eig_parity=mp.ODD_Z+mp.EVEN_Y)
        mode_vg = res.vgrp[0]
        poynting_flux  = mp.get_fluxes(flux)[0]
        e_energy = mp.get_electric_energy(energy)[0]
        ratio_vg = (0.5 * poynting_flux) / e_energy
        m_energy = mp.get_magnetic_energy(energy)[0]
        t_energy = mp.get_total_energy(energy)[0]

        self.assertAlmostEqual(m_energy + e_energy, t_energy)
        self.assertAlmostEqual(ratio_vg, mode_vg, places=3)
Exemple #16
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))}
def compute_flux(m, n):
    if m == 2:
        sources = [
            mp.Source(mp.GaussianSource(fcen, fwidth=df),
                      component=mp.Ez,
                      center=mp.Vector3(sx * (-0.5 + n / ndipole),
                                        -0.5 * sy + dAg + 0.5 * dsub))
        ]
    else:
        sources = [
            mp.Source(mp.GaussianSource(fcen, fwidth=df),
                      component=mp.Ez,
                      center=mp.Vector3(0, -0.5 * sy + dAg + 0.5 * dsub),
                      size=mp.Vector3(sx, 0),
                      amp_func=src_amp_func(n))
        ]

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

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

    sim.run(until=run_time)

    flux = mp.get_fluxes(flux_mon)
    freqs = mp.get_flux_freqs(flux_mon)

    return freqs, flux
Exemple #18
0
    def test_eigsrc_kz(self, kz_2d):
        resolution = 30  # pixels/um

        cell_size = mp.Vector3(14, 14)

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

        geometry = [
            mp.Block(center=mp.Vector3(),
                     size=mp.Vector3(mp.inf, 1, mp.inf),
                     material=mp.Medium(epsilon=12))
        ]

        fsrc = 0.3  # frequency of eigenmode or constant-amplitude source
        bnum = 1  # band number of eigenmode
        kz = 0.2  # fixed out-of-plane wavevector component

        sources = [
            mp.EigenModeSource(src=mp.GaussianSource(fsrc, fwidth=0.2 * fsrc),
                               center=mp.Vector3(),
                               size=mp.Vector3(y=14),
                               eig_band=bnum,
                               eig_parity=mp.EVEN_Y,
                               eig_match_freq=True)
        ]

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

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

        sim.run(until_after_sources=50)

        res = sim.get_eigenmode_coefficients(tran, [1, 2],
                                             eig_parity=mp.EVEN_Y)

        total_flux = mp.get_fluxes(tran)[0]
        mode1_flux = abs(res.alpha[0, 0, 0])**2
        mode2_flux = abs(res.alpha[1, 0, 0])**2

        mode1_frac = 0.99
        self.assertGreater(mode1_flux / total_flux, mode1_frac)
        self.assertLess(mode2_flux / total_flux, 1 - mode1_frac)

        d = 3.5
        ez1 = sim.get_field_point(mp.Ez, mp.Vector3(2.3, -5.7, 4.8))
        ez2 = sim.get_field_point(mp.Ez, mp.Vector3(2.3, -5.7, 4.8 + d))
        ratio_ez = ez2 / ez1
        phase_diff = cmath.exp(1j * 2 * cmath.pi * kz * d)
        self.assertAlmostEqual(ratio_ez.real, phase_diff.real, places=10)
        self.assertAlmostEqual(ratio_ez.imag, phase_diff.imag, places=10)
Exemple #19
0
    def test_waveguide_flux(self):
        cell_size = mp.Vector3(10, 10, 0)

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

        rot_angles = range(
            0, 60, 20)  # rotation angle of waveguide, CCW around z-axis

        fluxes = []
        for t in rot_angles:
            rot_angle = math.radians(t)
            sources = [
                mp.EigenModeSource(src=mp.GaussianSource(1.0, fwidth=0.1),
                                   size=mp.Vector3(y=10),
                                   center=mp.Vector3(x=-3),
                                   direction=mp.NO_DIRECTION,
                                   eig_kpoint=mp.Vector3(
                                       math.cos(rot_angle),
                                       math.sin(rot_angle), 0),
                                   eig_band=1,
                                   eig_parity=mp.ODD_Z,
                                   eig_match_freq=True)
            ]

            geometry = [
                mp.Block(center=mp.Vector3(),
                         size=mp.Vector3(mp.inf, 1, mp.inf),
                         e1=mp.Vector3(1, 0, 0).rotate(mp.Vector3(0, 0, 1),
                                                       rot_angle),
                         e2=mp.Vector3(0, 1, 0).rotate(mp.Vector3(0, 0, 1),
                                                       rot_angle),
                         material=mp.Medium(index=1.5))
            ]

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

            tran = sim.add_flux(
                1.0, 0, 1,
                mp.FluxRegion(center=mp.Vector3(x=3), size=mp.Vector3(y=10)))

            sim.run(until_after_sources=100)

            fluxes.append(mp.get_fluxes(tran)[0])
            print("flux:, {:.2f}, {:.6f}".format(t, fluxes[-1]))

        self.assertAlmostEqual(fluxes[0], fluxes[1], places=0)
        self.assertAlmostEqual(fluxes[1], fluxes[2], places=0)

        # self.assertAlmostEqual(fluxes[0], fluxes[2], places=0)
        # sadly the above line requires a workaround due to the
        # following annoying numerical accident:
        # AssertionError: 100.33815231783535 != 99.81145343586365 within 0 places
        f0, f2 = fluxes[0], fluxes[2]
        self.assertLess(abs(f0 - f2), 0.5 * max(abs(f0), abs(f2)))
Exemple #20
0
 def get_flux_data_from_many(trans):
     # simulation data are saved in trans
     freqs = mp.get_flux_freqs(trans[0])
     fluxes = [mp.get_fluxes(tran) for tran in trans]
     data = np.column_stack((
         freqs,
         *fluxes,
     ))
     return data
Exemple #21
0
 def get_flux_data_from_one(ntran, nsize):
     # simulation data are saved in trans
     freqs = mp.get_flux_freqs(ntran)
     fluxes = mp.get_fluxes(ntran)
     data = np.column_stack((
         freqs,
         fluxes,
     ))
     data = np.insert(data, 1, nsize, axis=1)
     return data
Exemple #22
0
    def plot_power(self):
        flux_freqs = np.array(mp.get_flux_freqs(self.box_z2))
        flux_up = np.array(mp.get_fluxes(self.box_z2))
        flux_bot = np.array(mp.get_fluxes(self.box_z1))
        flux_side = np.array(mp.get_fluxes(self.box_r))
        flux_total = flux_bot + flux_up + flux_side

        flux_wvl = 1 / flux_freqs

        plt.figure(dpi=150)
        plt.plot(flux_wvl, flux_total, 'r-', label='Total emission')
        plt.plot(flux_wvl, flux_bot, 'g-', label='Bottom emission')
        plt.plot(flux_wvl, flux_side, 'y-', label='Side emission')
        plt.plot(flux_wvl, flux_up, 'b-', label='Upward emission')
        plt.legend(loc='upper right')
        plt.xlabel('Wavelength (µm)')
        plt.ylabel('Arbitrary intensity')

        return flux_freqs, flux_up, flux_bot, flux_side
 def my_display_fluxes(sim):
     nonlocal my_display_count
     nonlocal step_time
     freqs=mp.get_flux_freqs(trans[0])
     fluxes=[mp.get_fluxes(tran) for tran in trans]
     data=np.column_stack((freqs, *fluxes,))
     my.matrix_output(None,data,"{:10.3e}","flux")
     my_display_count+=1
     print('No. {} display at t={}'.format(
         my_display_count,step_time))
     mymeep.my_flush_step(sim)
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
Exemple #25
0
    def test_divide_parallel_processes(self):
        resolution = 20

        sxy = 4
        dpml = 1
        cell = mp.Vector3(sxy + 2 * dpml, sxy + 2 * dpml)

        pml_layers = [mp.PML(dpml)]

        n = mp.divide_parallel_processes(2)
        fcen = 1.0 / (n + 1)

        sources = [
            mp.Source(src=mp.GaussianSource(fcen, fwidth=0.2 * fcen),
                      center=mp.Vector3(),
                      component=mp.Ez)
        ]

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

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

        flux_box = self.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),
                                     decimation_factor=1)

        self.sim.run(until_after_sources=30)

        tot_flux = mp.get_fluxes(flux_box)[0]

        tot_fluxes = mp.merge_subgroup_data(tot_flux)
        fcens = mp.merge_subgroup_data(fcen)

        self.assertEqual(fcens[0], 1)
        self.assertEqual(fcens[1], 0.5)
        places = 4 if mp.is_single_precision() else 7
        self.assertAlmostEqual(tot_fluxes[0], 9.8628728533, places=places)
        self.assertAlmostEqual(tot_fluxes[1], 19.6537275387, places=places)
Exemple #26
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 #27
0
    def disk_run(self, sx, sy):

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

        sim = mp.Simulation(cell_size=mp.Vector3(sx, sy, self.sz),
                            geometry=self.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)

        # for normal run, load negated fields to subtract incident from refl. fields
        sim.load_minus_flux_data(refl, self.store['straight_refl_data'])

        sim.run(until_after_sources=mp.stop_when_fields_decayed(25, mp.Ey, self.pt, 1e-3))

        self.store['disk_refl_flux'] = mp.get_fluxes(refl)
        self.store['disk_tran_flux'] = mp.get_fluxes(trans)
Exemple #28
0
def simulation(sim, cell, det_dir, det_tran, det_tran_2, **simrun_args):
    #inicialitzo els dos detectors (a les diferents posicions)
    det_dir = det_dir  #Detectors(center=mp.Vector3(-4.25,0,0),size=mp.Vector3(0,5.0,0))
    det_tran = det_tran  #Detectors(center=mp.Vector3(3.25,0,0),size=mp.Vector3(0,5.0,0))
    det_tran_2 = det_tran_2
    #afegeixo els fluxos
    direct = sim.add_flux(Wave.fcen, Wave.df, Wave.nfreq, det_dir.detect_fr)
    tran = sim.add_flux(Wave.fcen, Wave.df, Wave.nfreq, det_tran.detect_fr)
    tran_2 = sim.add_flux(Wave.fcen, Wave.df, Wave.nfreq, det_tran_2.detect_fr)
    sim.run(**simrun_args)
    #prenc les dades per fer els dibuixos
    eps_data = sim.get_array(center=mp.Vector3(),
                             size=cell,
                             component=mp.Dielectric)
    ez_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Ez)
    #prenc les dades per fer les gràfiques
    flux_freqs = mp.get_flux_freqs(direct)
    direct_data = mp.get_fluxes(direct)
    tran_data = mp.get_fluxes(tran)
    tran_data_2 = mp.get_fluxes(tran_2)
    reset = sim.reset_meep()
    return eps_data, ez_data, flux_freqs, direct_data, tran_data, tran_data_2, reset
Exemple #29
0
def run_chi3(k_pow, amp=1):
    k = 10**k_pow
    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)

    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)))

    # Single frequency point at omega
    trans1 = sim.add_flux(
        fcen, 0, 1, mp.FluxRegion(mp.Vector3(0, 0, 0.5 * sz - dpml - 0.5)))

    # Singel frequency point at 3omega
    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))

    omega_flux = mp.get_fluxes(trans1)
    omega3_flux = mp.get_fluxes(trans3)
    freqs = mp.get_flux_freqs(trans)
    spectra = mp.get_fluxes(trans)

    return freqs, spectra, omega_flux, omega3_flux
Exemple #30
0
    def run_power(self, time_after_sources=100):

        self.time_after_sources = time_after_sources

        self._sim.run(until_after_sources=self.time_after_sources)

        flux_freqs = np.array(mp.get_flux_freqs(self.box_z2))
        flux_up = np.array(mp.get_fluxes(self.box_z2))
        flux_bot = np.array(mp.get_fluxes(self.box_z1))
        flux_side = np.array(mp.get_fluxes(self.box_r))
        flux_total = flux_bot + flux_up + flux_side

        max_uppower = max(flux_up)
        max_totalpower = max(flux_total)

        max_upindex = np.where(flux_up == max_uppower)
        maxwvl = 1 / flux_freqs[max_upindex]  # find the wavelength of maximum

        sum_upratio = sum(flux_up) / sum(
            flux_total)  # the ratio of total upward power
        max_upratio = max(flux_up) / max(
            flux_total
        )  # at the most productive wavelength, thr ratio of upward power

        flux_wvl = 1 / flux_freqs

        plt.figure(dpi=150)
        plt.axvline(x=maxwvl, color='b',
                    linestyle='--')  # mark where moset productive wavelength
        plt.plot(flux_wvl, flux_total, 'r-', label='Total emission')
        plt.plot(flux_wvl, flux_bot, 'g-', label='Bottom emission')
        plt.plot(flux_wvl, flux_side, 'y-', label='Side emission')
        plt.plot(flux_wvl, flux_up, 'b-', label='Upward emission')
        plt.legend(loc='upper right')
        plt.xlabel('Wavelength (µm)')
        plt.ylabel('Arbitrary intensity')

        return flux_freqs, flux_up, flux_bot, flux_side
Exemple #31
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 #32
0
def force_norm():
    """perform normalization simulation"""
    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, df, nfreq, [0,0,0], [2*radius, 2*radius, 0])

    norm.run(until_after_sources=meep.stop_when_fields_decayed(.5*um, decay,
                      pt=meep.Vector3(0,0,0), decay_by=1e-5))

    return {'frequency': np.array(meep.get_flux_freqs(flux_inc)), 'area': (2*radius)**2,
            'incident': np.asarray(meep.get_fluxes(flux_inc))}
Exemple #33
0
    def test_waveguide_flux(self):
        cell_size = mp.Vector3(10,10,0)

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

        rot_angles = range(0,60,20) # rotation angle of waveguide, CCW around z-axis

        fluxes = []
        for t in rot_angles:
            rot_angle = math.radians(t)
            sources = [mp.EigenModeSource(src=mp.GaussianSource(1.0,fwidth=0.1),
                                          size=mp.Vector3(y=10),
                                          center=mp.Vector3(x=-3),
                                          direction=mp.NO_DIRECTION,
                                          eig_kpoint=mp.Vector3(math.cos(rot_angle),math.sin(rot_angle),0),
                                          eig_band=1,
                                          eig_parity=mp.ODD_Z,
                                          eig_match_freq=True)]

            geometry = [mp.Block(center=mp.Vector3(),
                                 size=mp.Vector3(mp.inf,1,mp.inf),
                                 e1 = mp.Vector3(1,0,0).rotate(mp.Vector3(0,0,1), rot_angle),
                                 e2 = mp.Vector3(0,1,0).rotate(mp.Vector3(0,0,1), rot_angle),
                                 material=mp.Medium(index=1.5))]

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

            tran = sim.add_flux(1.0, 0, 1, mp.FluxRegion(center=mp.Vector3(x=3), size=mp.Vector3(y=10)))

            sim.run(until_after_sources=100)

            fluxes.append(mp.get_fluxes(tran)[0])
            print("flux:, {:.2f}, {:.6f}".format(t,fluxes[-1]))

        self.assertAlmostEqual(fluxes[0], fluxes[1], places=0)
        self.assertAlmostEqual(fluxes[1], fluxes[2], places=0)

        # self.assertAlmostEqual(fluxes[0], fluxes[2], places=0)
        # sadly the above line requires a workaround due to the
        # following annoying numerical accident:
        # AssertionError: 100.33815231783535 != 99.81145343586365 within 0 places
        f0,f2=fluxes[0],fluxes[2]
        self.assertLess( abs(f0-f2), 0.5*max(abs(f0),abs(f2)) )
Exemple #34
0
def norm_sim():
    """perform normalization simulation"""
    L = 2*radius + 2*pml_monitor_gap + 2*particle_monitor_gap + 2*pml.thickness
    cell = meep.Vector3(L,L,L)
    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])

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

    return {'area': (2*radius)**2, 'norm': np.asarray(meep.get_fluxes(flux_inc))}
Exemple #35
0
    def test_dft_energy(self):
        resolution = 20
        cell = mp.Vector3(10, 5)
        geom = [
            mp.Block(size=mp.Vector3(mp.inf, 1, mp.inf),
                     material=mp.Medium(epsilon=12))
        ]
        pml = [mp.PML(1)]
        fsrc = 0.15
        sources = [
            mp.EigenModeSource(src=mp.GaussianSource(frequency=fsrc,
                                                     fwidth=0.2 * fsrc),
                               center=mp.Vector3(-3),
                               size=mp.Vector3(y=5),
                               eig_band=1,
                               eig_parity=mp.ODD_Z + mp.EVEN_Y,
                               eig_match_freq=True)
        ]

        sim = mp.Simulation(resolution=resolution,
                            cell_size=cell,
                            geometry=geom,
                            boundary_layers=pml,
                            sources=sources,
                            symmetries=[mp.Mirror(direction=mp.Y)])

        flux = sim.add_flux(
            fsrc, 0, 1,
            mp.FluxRegion(center=mp.Vector3(3), size=mp.Vector3(y=5)))
        energy = sim.add_energy(
            fsrc, 0, 1,
            mp.EnergyRegion(center=mp.Vector3(3), size=mp.Vector3(y=5)))
        sim.run(until_after_sources=100)

        res = sim.get_eigenmode_coefficients(flux, [1],
                                             eig_parity=mp.ODD_Z + mp.EVEN_Y)
        mode_vg = res.vgrp[0]
        poynting_flux = mp.get_fluxes(flux)[0]
        e_energy = mp.get_electric_energy(energy)[0]
        ratio_vg = (0.5 * poynting_flux) / e_energy
        m_energy = mp.get_magnetic_energy(energy)[0]
        t_energy = mp.get_total_energy(energy)[0]

        self.assertAlmostEqual(m_energy + e_energy, t_energy)
        self.assertAlmostEqual(ratio_vg, mode_vg, places=3)
Exemple #36
0
def flux_monitor_cal(box_x1, box_x2, box_y1, box_y2, box_z1, box_z2):
    box_x1_flux = mp.get_fluxes(box_x1)
    box_x2_flux = mp.get_fluxes(box_x2)
    box_y1_flux = mp.get_fluxes(box_y1)
    box_y2_flux = mp.get_fluxes(box_y2)
    box_z1_flux = mp.get_fluxes(box_z1)
    box_z2_flux = mp.get_fluxes(box_z2)

    frqs = mp.get_flux_freqs(box_x1)
    p_flux = -(np.asarray(box_x1_flux) - np.asarray(box_x2_flux) +
               np.asarray(box_y1_flux) - np.asarray(box_y2_flux) +
               np.asarray(box_z1_flux) - np.asarray(box_z2_flux))
    return frqs, p_flux
Exemple #37
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 #38
0
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)
sim.load_minus_flux_data(refl, empty_data)
Exemple #39
0
def parallel_waveguide(s,xodd):
    geometry = [mp.Block(center=mp.Vector3(-0.5*(s+a)),
                         size=mp.Vector3(a,a,mp.inf),
                         material=Si),
                mp.Block(center=mp.Vector3(0.5*(s+a)),
                         size=mp.Vector3(a,a,mp.inf),
                         material=Si)]

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

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

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

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

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

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

    sim.reset_meep()

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

    sim.change_sources(eig_sources)

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

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

    sim.run(until_after_sources=5000)

    flux = mp.get_fluxes(wvg_flux)[0]
    force = mp.get_forces(wvg_force)[0]
    
    sim.reset_meep()
    return flux, force
Exemple #40
0
def pol_grating(d,ph,gp,nmode):
    sx = dpml+dsub+d+d+dpad+dpml
    sy = gp

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

    # 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=0.05*fcen), component=mp.Ez, center=src_pt, size=mp.Vector3(0,sy,0)),
               mp.Source(mp.GaussianSource(fcen,fwidth=0.05*fcen), 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))

    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=100)

    input_flux = mp.get_fluxes(tran_flux)
    input_flux_data = sim.get_flux_data(tran_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)

    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];
Exemple #41
0
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
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=mp.stop_when_fields_decayed(50, mp.Ez, mon_pt, 1e-9))

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)))
Exemple #42
0
    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),
                mp.Vector3(-0.5*Lt,-0.5*w1),
                mp.Vector3(-0.5*sx-1,-0.5*w1)]

    sim = mp.Simulation(resolution=resolution,
Exemple #43
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 #44
0
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)

pt = mp.Vector3(0.5*sx-dpml-0.5,wvg_ycen)

sim.run(until_after_sources=mp.stop_when_fields_decayed(50,mp.Ez,pt,1e-3))

# for normalization run, save flux fields data for reflection plane
straight_refl_data = sim.get_flux_data(refl)

# save incident power for transmission plane
straight_tran_flux = mp.get_fluxes(tran)

sim.reset_meep()

geometry = [mp.Block(mp.Vector3(sx-pad,w,mp.inf),center=mp.Vector3(-0.5*pad,wvg_ycen),material=mp.Medium(epsilon=12)),
            mp.Block(mp.Vector3(w,sy-pad,mp.inf),center=mp.Vector3(wvg_xcen,0.5*pad),material=mp.Medium(epsilon=12))]

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

# reflected flux
refl = sim.add_flux(fcen, df, nfreq, refl_fr)
Exemple #45
0
                    boundary_layers=pml_layers,
                    k_point=k,
                    default_material=glass,
                    sources=sources,
                    symmetries=symmetries)

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)))

if use_cw_solver:
  sim.init_sim()
  sim.solve_cw(tol, max_iters, L)
else:
  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()

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,
                    sources=sources,
                    symmetries=symmetries)
Exemple #46
0
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)
for n in range(npts):
    ff = sim.get_farfield(nearfield_box,
Exemple #47
0
def grating(gp,gh,gdc_list):
  sx = dpml+dsub+gh+dpad+dpml
  src_pt = mp.Vector3(-0.5*sx+dpml+0.5*dsub)
  mon_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad)
  geometry = [mp.Block(material=glass,
                       size=mp.Vector3(dpml+dsub,mp.inf,mp.inf),
                       center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub)))]

  num_cells = len(gdc_list)
  if num_cells == 1:
    sy = gp
    cell_size = mp.Vector3(sx,sy,0)

    sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df),
                         component=mp.Ez,
                         center=src_pt,
                         size=mp.Vector3(y=sy))]

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

    flux_obj = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy)))

    sim.run(until_after_sources=50)
    
    input_flux = mp.get_fluxes(flux_obj)
  
    sim.reset_meep()

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

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

    flux_obj = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy)))

    sim.run(until_after_sources=200)

    freqs = mp.get_eigenmode_freqs(flux_obj)
    res = sim.get_eigenmode_coefficients(flux_obj, [1], eig_parity=mp.ODD_Z+mp.EVEN_Y)
    coeffs = res.alpha

    mode_tran = abs(coeffs[0,0,0])**2/input_flux[0]
    mode_phase = np.angle(coeffs[0,0,0])
    if mode_phase > 0:
      mode_phase -= 2*np.pi
  
    return mode_tran, mode_phase
  
  else:    
    sy = num_cells*gp
    cell_size = mp.Vector3(sx,sy,0)

    sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df),
                         component=mp.Ez,
                         center=src_pt,
                         size=mp.Vector3(y=sy))]

    for j in range(num_cells):
      geometry.append(mp.Block(material=glass,
                               size=mp.Vector3(gh,gdc_list[j]*gp,mp.inf),
                               center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh,-0.5*sy+(j+0.5)*gp)))

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

    n2f_obj = sim.add_near2far(fcen, 0, 1, mp.Near2FarRegion(center=mon_pt, size=mp.Vector3(y=sy)))

    sim.run(until_after_sources=500)
    
    return abs(sim.get_farfields(n2f_obj, ff_res, center=mp.Vector3(focal_length), size=mp.Vector3(spot_length))['Ez'])**2
Exemple #48
0
  def run_binary_grating_oblique(self, theta):
  
    resolution = 30        # pixels/um

    dpml = 1.0             # PML thickness
    dsub = 1.0             # substrate thickness
    dpad = 1.0             # length of padding between grating and pml
    gp = 6.0               # grating period
    gh = 0.5               # grating height
    gdc = 0.5              # grating duty cycle

    sx = dpml+dsub+gh+dpad+dpml
    sy = gp

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

    # replace anisotropic PML with isotropic Absorber to attenuate parallel-directed fields of oblique source
    abs_layers = [mp.Absorber(thickness=dpml,direction=mp.X)] 

    wvl = 0.5              # center wavelength
    fcen = 1/wvl           # center frequency
    df = 0.05*fcen         # frequency width

    ng = 1.5
    glass = mp.Medium(index=ng)

    # rotation angle of incident planewave; CCW about Y axis, 0 degrees along +X axis
    theta_in = math.radians(theta)

    # k (in source medium) with correct length (plane of incidence: XY)
    k = mp.Vector3(math.cos(theta_in),math.sin(theta_in),0).scale(fcen*ng)

    symmetries = []
    eig_parity = mp.ODD_Z
    if theta_in == 0:
      k = mp.Vector3(0,0,0)
      symmetries = [mp.Mirror(mp.Y)]
      eig_parity += mp.EVEN_Y
  
    def pw_amp(k,x0):
      def _pw_amp(x):
        return cmath.exp(1j*2*math.pi*k.dot(x+x0))
      return _pw_amp

    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),
                         amp_func=pw_amp(k,src_pt))]

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

    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()

    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=abs_layers,
                        geometry=geometry,
                        k_point=k,
                        sources=sources,
                        symmetries=symmetries)

    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=100)

    nm_r = np.floor((fcen*ng-k.y)*gp)-np.ceil((-fcen*ng-k.y)*gp) # number of reflected orders
    if theta_in == 0:
      nm_r = nm_r/2 # since eig_parity removes degeneracy in y-direction
    nm_r = int(nm_r)

    res = sim.get_eigenmode_coefficients(refl_flux, range(1,nm_r+1), eig_parity=eig_parity)
    r_coeffs = res.alpha

    Rsum = 0
    for nm in range(nm_r):
      Rsum += abs(r_coeffs[nm,0,1])**2/input_flux[0]

    nm_t = np.floor((fcen-k.y)*gp)-np.ceil((-fcen-k.y)*gp)       # number of transmitted orders
    if theta_in == 0:
      nm_t = nm_t/2 # since eig_parity removes degeneracy in y-direction
    nm_t = int(nm_t)

    res = sim.get_eigenmode_coefficients(tran_flux, range(1,nm_t+1), eig_parity=eig_parity)
    t_coeffs = res.alpha

    Tsum = 0
    for nm in range(nm_t):
      Tsum += abs(t_coeffs[nm,0,0])**2/input_flux[0]

    r_flux = mp.get_fluxes(refl_flux)
    t_flux = mp.get_fluxes(tran_flux)
    Rflux = -r_flux[0]/input_flux[0]
    Tflux =  t_flux[0]/input_flux[0]

    self.assertAlmostEqual(Rsum,Rflux,places=2)
    self.assertAlmostEqual(Tsum,Tflux,places=2)
Exemple #49
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)
Exemple #50
0
    def run_mode_coeffs(self, mode_num, kpoint_func, nf=1, 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
        df   = 0.5*fcen

        source=mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=df),
                                  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=2*resolution)

        sim = mp.Simulation(resolution=resolution,
                            cell_size=cell_size,
                            boundary_layers=boundary_layers,
                            geometry=geometry,
                            sources=[source],
                            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, df, nf, mp.ModeRegion(center=mp.Vector3(xm,0), size=mp.Vector3(0,sy-2*dpml)))
        mode_flux = sim.add_flux(fcen, df, nf, 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=200)

        ##################################################
        # If the number of analysis frequencies is >1, we
        # are testing the unit-power normalization
        # of the eigenmode source: we observe the total
        # power flux through the mode_flux monitor (which
        # equals the total power emitted by the source as
        # there is no scattering in this ideal waveguide)
        # and check that it agrees with the prediction
        # of the eig_power() class method in EigenmodeSource.
        ##################################################
        if nf>1:
            power_observed=mp.get_fluxes(mode_flux)
            freqs=mp.get_flux_freqs(mode_flux)
            power_expected=[source.eig_power(f) for f in freqs]
            return freqs, power_expected, power_observed

        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
Exemple #51
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 #52
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)