Esempio n. 1
0
    def test_synchronized_magnetic(self):
        # Issue 309
        cell = mp.Vector3(16, 8, 0)

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

        sources = [
            mp.Source(mp.ContinuousSource(frequency=0.15),
                      component=mp.Ez,
                      center=mp.Vector3(-7, 0))
        ]

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

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

        sim.run(mp.synchronized_magnetic(mp.output_bfield_y), until=10)
Esempio n. 2
0
    def test_synchronized_magnetic(self):
        # Issue 309
        cell = mp.Vector3(16, 8, 0)

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

        sources = [mp.Source(mp.ContinuousSource(frequency=0.15),
                             component=mp.Ez,
                             center=mp.Vector3(-7, 0))]

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

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

        sim.run(mp.synchronized_magnetic(mp.output_bfield_y), until=10)
Esempio n. 3
0
transmissionRegion = mp.FluxRegion(center=mp.Vector3(0, 0, materialThickness /
                                                     4))
transmissionFluxMonitor = simulation.add_flux(frequency, 0, 1,
                                              transmissionRegion)


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


simulation.run(mp.synchronized_magnetic(
    mp.at_every(animationTimestepDuration, updateField)),
               until=endTime)

incidentFlux = mp.get_fluxes(incidentFluxMonitor)[0]
transmittedFlux = mp.get_fluxes(transmissionFluxMonitor)[0]
print(transmittedFlux / incidentFlux)

fig = plt.figure()
ax = plt.axes(xlim=(-length / 2, length / 2), ylim=(-1, 1))
line, = ax.plot([], [], lw=2)
xData = np.linspace(-length / 2, length / 2, fieldData.shape[1])


def init():
    line.set_data([], [])
    return line,
Esempio n. 4
0
def main():
    # Prefix all output files with the command line argument
    file_prefix = sys.argv[1]
    # Number of pixels per micron
    resolution = 200
    # Simulation volume (um)
    cell_x = 0
    cell_y = 5
    cell_z = 5
    # Refractive indicies
    index_si = 3.6  # previously 3.4467
    index_sio2 = 1.444
    # Durations in units of micron/c
    duration = 10
    num_timesteps = duration * resolution
    # Absorbing layer on boundary
    pml = 0.5
    # Geometry
    src_buffer = pml / 16
    nbn_buffer = src_buffer
    nbn_length = cell_x - 2 * pml - src_buffer - nbn_buffer
    nbn_center_x = (src_buffer + nbn_buffer) / 2
    wavelength = 1.55
    waveguide_width = 0.750  # 750 nm
    waveguide_height = 0.750  # 110 nm
    plane_shift_y = 0

    # nbn is 10/8 times thicker than in reality to have enough simulation pixels
    # so we reduce its absorption by a factor of 5/4 to compensate
    nbn_thickness_comp = 250 / resolution

    nbn_thickness = 0.008 * nbn_thickness_comp  # Actually 8 nm, but simulating this for 2 grid points
    nbn_width = 0.100  # 100 nm
    nbn_spacing = 0.120  # 120 nm

    # Also compensate the difference in index by the same amount
    nbn_base_index = 5.23  # Taken from Hu thesis p86
    nbn_index = (5.23 - index_si) / nbn_thickness_comp + index_si
    nbn_base_k = 5.82  # Taken from Hu thesis p86
    nbn_k = nbn_base_k / nbn_thickness_comp
    conductivity = 2 * math.pi * wavelength * nbn_k / nbn_index

    flux_length = cell_x - 2 * pml - 4 * src_buffer

    # Generate simulation obejcts
    cell = mp.Vector3(cell_x, cell_y, cell_z)
    freq = 1 / wavelength
    src_pt = mp.Vector3(-cell_x / 2 + pml + src_buffer, 0, 0)
    output_slice = mp.Volume(center=mp.Vector3(),
                             size=(cell_x, cell_y, cell_z))

    # Log important quantities
    print('ABSORBING RUN')
    print('File prefix: {}'.format(file_prefix))
    print('Duration: {}'.format(duration))
    print('Resolution: {}'.format(resolution))
    print('Dimensions: {} um, {} um, {} um'.format(cell_x, cell_y, cell_z))
    print('Wavelength: {} um'.format(wavelength))
    print('Si thickness: {} um'.format(waveguide_height))
    print('NbN thickness: {} um'.format(nbn_thickness))
    print('Si index: {}; SiO2 index: {}'.format(index_si, index_sio2))
    print('Absorber dimensions: {} um, {} um, {} um'.format(
        nbn_length, nbn_thickness, nbn_width))
    print('Absorber n (base value): {} ({}), k: {} ({})'.format(
        nbn_index, nbn_base_index, nbn_k, nbn_base_k))
    print('Absorber compensation for thickness: {}'.format(nbn_thickness_comp))
    print('Flux length: {} um'.format(flux_length))
    print('\n\n**********\n\n')

    default_material = mp.Medium(epsilon=1)

    # Physical geometry of the simulation
    geometry = [
        mp.Block(mp.Vector3(mp.inf, cell_y, mp.inf),
                 center=mp.Vector3(0, -cell_y / 2 + plane_shift_y, 0),
                 material=mp.Medium(epsilon=index_sio2)),
        mp.Block(mp.Vector3(mp.inf, waveguide_height, waveguide_width),
                 center=mp.Vector3(0, waveguide_height / 2 + plane_shift_y, 0),
                 material=mp.Medium(epsilon=index_si))
    ]

    # Absorber will only be appended to geometry for the second simulation
    absorber = [
        mp.Block(mp.Vector3(nbn_length, nbn_thickness, nbn_width),
                 center=mp.Vector3(
                     nbn_center_x, waveguide_height +
                     nbn_thickness / nbn_thickness_comp / 2 + plane_shift_y,
                     nbn_spacing / 2),
                 material=mp.Medium(epsilon=nbn_index,
                                    D_conductivity=conductivity)),
        mp.Block(mp.Vector3(nbn_length, nbn_thickness, nbn_width),
                 center=mp.Vector3(
                     nbn_center_x, waveguide_height +
                     nbn_thickness / nbn_thickness_comp / 2 + plane_shift_y,
                     -nbn_spacing / 2),
                 material=mp.Medium(epsilon=nbn_index,
                                    D_conductivity=conductivity)),
    ]

    # geometry += absorber

    # Calculate eigenmode source
    src_max_y = cell_y - 2 * pml
    src_max_z = cell_z - 2 * pml
    src_y = src_max_y / 2
    src_z = src_max_z / 2  # min(3 * waveguide_width, src_max_z)

    src_center_y = waveguide_height / 2 + plane_shift_y  # plane_shift_y

    sources = [
        mp.EigenModeSource(src=mp.ContinuousSource(frequency=freq),
                           center=mp.Vector3(0, src_center_y, 0),
                           size=mp.Vector3(0, src_y, src_z),
                           eig_match_freq=True,
                           eig_parity=mp.ODD_Z,
                           eig_band=1)
    ]

    pml_layers = [mp.PML(pml)]

    # Pass all simulation parameters to meep
    sim = mp.Simulation(
        cell_size=cell,
        boundary_layers=pml_layers,
        geometry=geometry,
        sources=sources,
        resolution=resolution,
        # eps_averaging=False,
        default_material=default_material,
        symmetries=[mp.Mirror(mp.Z, phase=-1)])
    """
    # Create flux monitors to calculate transmission and absorption
    fr_y = cell_y - 2 * pml
    fr_z = cell_z - 2 * pml

    # Reflected flux
    refl_fr = mp.FluxRegion(center=mp.Vector3(-0.5 * cell_x + pml + 2 * src_buffer, 0, 0),
                            size=mp.Vector3(0, fr_y, fr_z))
    refl = sim.add_flux(freq, 0, 1, refl_fr)

    # Transmitted flux
    tran_fr = mp.FluxRegion(center=mp.Vector3(0.5 * cell_x - pml - 2 * src_buffer, 0, 0),
                            size=mp.Vector3(0, fr_y, fr_z))
    tran = sim.add_flux(freq, 0, 1, tran_fr)
    """

    # Run simulation, outputting the epsilon distribution and the fields in the
    # x-y plane every 0.25 microns/c
    sim.run(mp.at_beginning(mp.output_epsilon),
            mp.to_appended(
                "pwr",
                mp.in_volume(
                    output_slice,
                    mp.at_every(0.03,
                                mp.synchronized_magnetic(mp.output_tot_pwr)))),
            until=duration)

    print('\n\n**********\n\n')

    sim.fields.synchronize_magnetic_fields()
    """
    # For normalization run, save flux fields data for reflection plane
    no_absorber_refl_data = sim.get_flux_data(refl)
    # Save incident power for transmission plane
    no_absorber_tran_flux = mp.get_fluxes(tran)

    print("Flux: {}".format(no_absorber_tran_flux[0]))
    """
    eps_data = sim.get_array(center=mp.Vector3(z=(nbn_spacing + nbn_width) /
                                               2),
                             size=mp.Vector3(cell_x, cell_y, cell_z),
                             component=mp.Dielectric)
    eps_cross_data = sim.get_array(center=mp.Vector3(x=cell_x / 4),
                                   size=mp.Vector3(0, cell_y, cell_z),
                                   component=mp.Dielectric)

    max_field = 1.5

    # Plot epsilon distribution
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_data, interpolation='spline36', cmap='binary')
        plt.axis('off')
        plt.tight_layout()
        plt.savefig(file_prefix + '_Eps_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Eps_A.png')

    # Plot field on x-y plane
    ez_data = sim.get_array(center=mp.Vector3(),
                            size=mp.Vector3(cell_x, cell_y, cell_z),
                            component=mp.Ez)
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_data, interpolation='spline36', cmap='binary')
        plt.imshow(ez_data, interpolation='spline36', cmap='RdBu', alpha=0.9)
        plt.axis('off')
        plt.tight_layout()
        plt.savefig(file_prefix + '_Ez_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Ez_A.png')

    # Plot energy density on y-z plane
    energy_data = sim.get_array(center=mp.Vector3(),
                                size=mp.Vector3(0, cell_y, cell_z),
                                component=mp.EnergyDensity)
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_cross_data, interpolation='spline36', cmap='binary')
        plt.imshow(energy_data,
                   interpolation='spline36',
                   cmap='hot',
                   alpha=0.9)
        plt.axis('off')
        plt.tight_layout()
        plt.savefig(file_prefix + '_Pwr1_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Pwr1_A.png')
    """
    # Plot cross-sectional fields at several locations to ensure seeing nonzero fields
    num_x = 4
    num_y = 3
    fig, ax = plt.subplots(num_x, num_y)
    fig.suptitle('Cross Sectional Ez Fields')

    for i in range(num_x * num_y):
        monitor_x = i * (cell_x / 4) / (num_x * num_y)
        ez_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x), size=mp.Vector3(0, cell_y, cell_z), component=mp.Ez)
        ax_num = i // num_y, i % num_y
        if mp.am_master():
            ax[ax_num].imshow(eps_cross_data, interpolation='spline36', cmap='binary')
            ax[ax_num].imshow(ez_cross_data, interpolation='spline36', cmap='RdBu', alpha=0.9, norm=ZeroNormalize(vmax=np.max(max_field)))
            ax[ax_num].axis('off')
            ax[ax_num].set_title('x = {}'.format(round(cell_x/4 + i / resolution, 3)))
    if mp.am_master():
        plt.savefig(file_prefix + '_Ez_CS_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Ez_CS_A.png')

    fig_e, ax_e = plt.subplots(num_x, num_y)
    fig_e.suptitle('Cross Sectional Energy Density')

    for i in range(num_x * num_y):
        monitor_x = i * (cell_x / 4) / (num_x * num_y)
        energy_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x), size=mp.Vector3(0, cell_y, cell_z), component=mp.EnergyDensity)
        ax_num = i // num_y, i % num_y
        if mp.am_master():
            ax_e[ax_num].imshow(eps_cross_data, interpolation='spline36', cmap='binary')
            ax_e[ax_num].imshow(energy_cross_data, interpolation='spline36', cmap='hot', alpha=0.9)
            ax_e[ax_num].axis('off')
            ax_e[ax_num].set_title('x = {}'.format(round(cell_x/4 + i / resolution, 3)))
    if mp.am_master():
        plt.savefig(file_prefix + '_Pwr_CS_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Pwr_CS_A.png')
    """
    print('\n\n**********\n\n')

    # Reset simulation for absorption run
    """
    sim.reset_meep()

    geometry += absorber

    sim = mp.Simulation(cell_size=cell,
                        boundary_layers=pml_layers,
                        geometry=geometry,
                        sources=sources,
                        resolution=resolution,
                        eps_averaging=False,
                        default_material=default_material,
                        symmetries=[mp.Mirror(mp.Z, phase=-1)])

    refl = sim.add_flux(freq, 0, 1, refl_fr)
    tran = sim.add_flux(freq, 0, 1, tran_fr)

    sim.load_minus_flux_data(refl, no_absorber_refl_data)

    # Run simulation with absorber
    sim.run(mp.at_beginning(mp.output_epsilon),
            mp.to_appended("ez_z0",
                           mp.in_volume(output_slice,
                                        mp.at_every(0.25, mp.output_efield_z))),
            until=duration)

    print('\n\n**********\n\n')

    # Calculate transmission and absorption
    absorber_refl_flux = mp.get_fluxes(refl)
    absorber_tran_flux = mp.get_fluxes(tran)

    transmittance = absorber_tran_flux[0] / no_absorber_tran_flux[0]
    reflectance = absorber_refl_flux[0] / no_absorber_tran_flux[0]
    absorption = 1 - transmittance
    penetration_depth = - nbn_length / math.log(transmittance)

    print('Flux: {}'.format(absorber_tran_flux[0]))
    print("Transmittance: %f" % transmittance)
    print("Reflectance: %f" % reflectance)
    print("Absorption: {} over {} um".format(absorption, nbn_length))
    print("lambda = {} mm".format(penetration_depth / 1000))

    eps_data = sim.get_array(center=mp.Vector3(z=(nbn_spacing + nbn_width) / 2), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Dielectric)

    max_field = 1

    # Plot epsilon distribution with absorber
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary')
        plt.axis('off')
        plt.savefig(file_prefix + '_Eps_B.png', dpi=300)
        print('Saved ' + file_prefix + '_Eps_B.png')

    # Plot fields in x-y plane with absorber
    ez_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Ez)
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary')
        plt.imshow(ez_data.transpose(), interpolation='spline36', cmap='RdBu', alpha=0.9)
        plt.axis('off')
        plt.savefig(file_prefix + '_Ez_B.png', dpi=300)
        print('Saved ' + file_prefix + '_Ez_B.png')

    # Plot field cross sections with absorber
    eps_cross_data = sim.get_array(center=mp.Vector3(x=cell_x/4), size=mp.Vector3(0, cell_y, cell_z), component=mp.Dielectric)
    num_x = 4
    num_y = 3
    fig, ax = plt.subplots(num_x, num_y)
    fig.suptitle('Cross Sectional Ez Fields')
    for i in range(num_x * num_y):
        monitor_x = cell_x/4 + i / resolution
        ez_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x), size=mp.Vector3(0, cell_y, cell_z), component=mp.Ez)
        ax_num = i // num_y, i % num_y
        if mp.am_master():
            ax[ax_num].imshow(eps_cross_data, interpolation='spline36', cmap='binary')
            ax[ax_num].imshow(ez_cross_data, interpolation='spline36', cmap='RdBu', alpha=0.9, norm=ZeroNormalize(vmax=np.max(max_field)))
            ax[ax_num].axis('off')
            ax[ax_num].set_title('x = {}'.format(round(cell_x/4 + i / resolution, 3)))
    if mp.am_master():
        plt.savefig(file_prefix + '_Ez_CS_B.png', dpi=300)
        print('Saved ' + file_prefix + '_Ez_CS_B.png')

    print('\n\n**********\n\n')
    """

    print('Program finished.')