Example #1
0
def adjoint_solver(design_params, mon_type):
    matgrid = mp.MaterialGrid(mp.Vector3(Nx,Ny),
                              mp.air,
                              silicon,
                              design_parameters=np.ones((Nx,Ny)))

    matgrid_region = mpa.DesignRegion(matgrid,
                                      volume=mp.Volume(center=mp.Vector3(),
                                                       size=mp.Vector3(design_shape.x,design_shape.y,0)))

    matgrid_geometry = [mp.Block(center=matgrid_region.center,
                                 size=matgrid_region.size,
                                 material=matgrid)]

    geometry = waveguide_geometry + matgrid_geometry

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

    if mon_type.name == 'EIGENMODE':
        obj_list = [mpa.EigenmodeCoefficient(sim,
                                             mp.Volume(center=mp.Vector3(0.5*sxy-dpml),
                                                       size=mp.Vector3(0,sxy,0)),1)]

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

    elif mon_type.name == 'DFT':
        obj_list = [mpa.FourierFields(sim,
                                      mp.Volume(center=mp.Vector3(0.5*sxy-dpml),
                                                size=mp.Vector3(0,sxy,0)),
                                      mp.Ez)]

        def J(mode_mon):
            return npa.abs(mode_mon[0,63])**2

    opt = mpa.OptimizationProblem(
        simulation = sim,
        objective_functions = J,
        objective_arguments = obj_list,
        design_regions = [matgrid_region],
        frequencies=[fcen],
        decay_fields=[mp.Ez])

    f, dJ_du = opt([design_params])

    sim.reset_meep()

    return f, dJ_du
def adjoint_solver_damping(design_params, frequencies=None, mat2=silicon):
    matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny),
                              mp.air,
                              mat2,
                              weights=np.ones((Nx, Ny)),
                              damping=3.14 * fcen)
    matgrid_region = mpa.DesignRegion(
        matgrid,
        volume=mp.Volume(center=mp.Vector3(),
                         size=mp.Vector3(design_region_size.x,
                                         design_region_size.y, 0)))

    matgrid_geometry = [
        mp.Block(center=matgrid_region.center,
                 size=matgrid_region.size,
                 material=matgrid)
    ]

    geometry = waveguide_geometry + matgrid_geometry

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

    if not frequencies:
        frequencies = [fcen]

    obj_list = [
        mpa.EigenmodeCoefficient(sim,
                                 mp.Volume(
                                     center=mp.Vector3(0.5 * sxy - dpml - 0.1),
                                     size=mp.Vector3(0, sxy - 2 * dpml, 0)),
                                 1,
                                 eig_parity=eig_parity)
    ]

    def J(mode_mon):
        return npa.power(npa.abs(mode_mon), 2)

    opt = mpa.OptimizationProblem(simulation=sim,
                                  objective_functions=J,
                                  objective_arguments=obj_list,
                                  design_regions=[matgrid_region],
                                  frequencies=frequencies,
                                  minimum_run_time=150)

    f, dJ_du = opt([design_params])

    sim.reset_meep()
    return f, dJ_du
def adjoint_solver_complex_fields(design_params, frequencies=None):
    matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny),
                              mp.air,
                              silicon,
                              weights=np.ones((Nx, Ny)))

    matgrid_region = mpa.DesignRegion(
        matgrid,
        volume=mp.Volume(center=mp.Vector3(),
                         size=mp.Vector3(design_region_size.x,
                                         design_region_size.y, 0)))

    geometry = [
        mp.Block(center=matgrid_region.center,
                 size=matgrid_region.size,
                 material=matgrid)
    ]

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

    if not frequencies:
        frequencies = [fcen]

    obj_list = [
        mpa.FourierFields(
            sim, mp.Volume(center=mp.Vector3(0.9), size=mp.Vector3(0.2, 0.5)),
            mp.Ez)
    ]

    def J(dft_mon):
        return npa.power(npa.abs(dft_mon[:, 3, 9]), 2)

    opt = mpa.OptimizationProblem(simulation=sim,
                                  objective_functions=J,
                                  objective_arguments=obj_list,
                                  design_regions=[matgrid_region],
                                  frequencies=frequencies)

    f, dJ_du = opt([design_params])

    sim.reset_meep()

    return f, dJ_du
Example #4
0
def adjoint_solver(design_params):

    design_variables = mp.MaterialGrid(mp.Vector3(Nr, 0, Nz), SiO2, Si)
    design_region = mpa.DesignRegion(
        design_variables,
        volume=mp.Volume(center=mp.Vector3(design_r / 2, 0, 0),
                         size=mp.Vector3(design_r, 0, design_z)))
    geometry = [
        mp.Block(center=design_region.center,
                 size=design_region.size,
                 material=design_variables)
    ]

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

    far_x = [mp.Vector3(5, 0, 20)]
    NearRegions = [
        mp.Near2FarRegion(center=mp.Vector3(
            design_r / 2, 0, (sz / 2 - dpml + design_z / 2) / 2),
                          size=mp.Vector3(design_r, 0, 0),
                          weight=+1)
    ]
    FarFields = mpa.Near2FarFields(sim, NearRegions, far_x)
    ob_list = [FarFields]

    def J(alpha):
        return npa.abs(alpha[0, 0, 0])**2

    opt = mpa.OptimizationProblem(simulation=sim,
                                  objective_functions=J,
                                  objective_arguments=ob_list,
                                  design_regions=[design_region],
                                  fcen=fcen,
                                  df=0,
                                  nf=1,
                                  maximum_run_time=1200)

    f, dJ_du = opt([design_params])
    sim.reset_meep()

    return f, dJ_du
Example #5
0
def build_straight_wg_simulation(
    wg_width=0.5,
    wg_padding=1.0,
    wg_length=1.0,
    pml_width=1.0,
    source_to_pml=0.5,
    source_to_monitor=0.1,
    frequencies=[1 / 1.55],
    gaussian_rel_width=0.2,
    sim_resolution=20,
    design_region_resolution=20,
):
    """Builds a simulation of a straight waveguide with a design region segment."""
    design_region_shape = (1.0, wg_width)

    # Simulation domain size
    sx = 2 * pml_width + 2 * wg_length + design_region_shape[0]
    sy = 2 * pml_width + 2 * wg_padding + max(
        wg_width,
        design_region_shape[1],
    )

    # Mean / center frequency
    fmean = onp.mean(frequencies)

    si = mp.Medium(index=3.4)
    sio2 = mp.Medium(index=1.44)

    sources = [
        mp.EigenModeSource(
            mp.GaussianSource(frequency=fmean,
                              fwidth=fmean * gaussian_rel_width),
            eig_band=1,
            direction=mp.NO_DIRECTION,
            eig_kpoint=mp.Vector3(1, 0, 0),
            size=mp.Vector3(0, wg_width + 2 * wg_padding, 0),
            center=[-sx / 2 + pml_width + source_to_pml, 0, 0],
        ),
        mp.EigenModeSource(
            mp.GaussianSource(frequency=fmean,
                              fwidth=fmean * gaussian_rel_width),
            eig_band=1,
            direction=mp.NO_DIRECTION,
            eig_kpoint=mp.Vector3(-1, 0, 0),
            size=mp.Vector3(0, wg_width + 2 * wg_padding, 0),
            center=[sx / 2 - pml_width - source_to_pml, 0, 0],
        ),
    ]
    nx, ny = int(design_region_shape[0] * design_region_resolution), int(
        design_region_shape[1] * design_region_resolution)
    mat_grid = mp.MaterialGrid(
        mp.Vector3(nx, ny),
        sio2,
        si,
        grid_type='U_DEFAULT',
    )

    design_regions = [
        mpa.DesignRegion(
            mat_grid,
            volume=mp.Volume(
                center=mp.Vector3(),
                size=mp.Vector3(
                    design_region_shape[0],
                    design_region_shape[1],
                    0,
                ),
            ),
        )
    ]

    geometry = [
        mp.Block(center=mp.Vector3(x=-design_region_shape[0] / 2 -
                                   wg_length / 2 - pml_width / 2),
                 material=si,
                 size=mp.Vector3(wg_length + pml_width, wg_width,
                                 0)),  # left wg
        mp.Block(center=mp.Vector3(x=+design_region_shape[0] / 2 +
                                   wg_length / 2 + pml_width / 2),
                 material=si,
                 size=mp.Vector3(wg_length + pml_width, wg_width,
                                 0)),  # right wg
        mp.Block(center=design_regions[0].center,
                 size=design_regions[0].size,
                 material=mat_grid),  # design region
    ]

    simulation = mp.Simulation(
        cell_size=mp.Vector3(sx, sy),
        boundary_layers=[mp.PML(pml_width)],
        geometry=geometry,
        sources=sources,
        resolution=sim_resolution,
    )

    monitor_centers = [
        mp.Vector3(-sx / 2 + pml_width + source_to_pml + source_to_monitor),
        mp.Vector3(sx / 2 - pml_width - source_to_pml - source_to_monitor),
    ]
    monitor_size = mp.Vector3(y=wg_width + 2 * wg_padding)

    monitors = [
        mpa.EigenmodeCoefficient(simulation,
                                 mp.Volume(center=center, size=monitor_size),
                                 mode=1,
                                 forward=forward) for center in monitor_centers
        for forward in [True, False]
    ]
    return simulation, sources, monitors, design_regions, frequencies
Example #6
0
                       direction=mp.NO_DIRECTION,
                       eig_kpoint=kpoint,
                       size=source_size,
                       center=source_center)
]

design_region_resolution = 10
Nx = design_region_resolution
Ny = design_region_resolution

design_variables = mp.MaterialGrid(mp.Vector3(Nx, Ny),
                                   SiO2,
                                   Si,
                                   grid_type='U_SUM')
design_region = mpa.DesignRegion(design_variables,
                                 volume=mp.Volume(center=mp.Vector3(),
                                                  size=mp.Vector3(1, 1, 0)))

geometry = [
    mp.Block(center=mp.Vector3(x=-Sx / 4),
             material=Si,
             size=mp.Vector3(Sx / 2, 0.5, 0)),  # horizontal waveguide
    mp.Block(center=mp.Vector3(y=Sy / 4),
             material=Si,
             size=mp.Vector3(0.5, Sy / 2, 0)),  # vertical waveguide
    mp.Block(center=design_region.center,
             size=design_region.size,
             material=design_variables),  # design region
    mp.Block(center=design_region.center,
             size=design_region.size,
             material=design_variables,