Ejemplo n.º 1
0
def make_objective_fdfd(eps: goos.Shape, stage: str, sim_3d: bool):
    dx = 20
    if sim_3d:
        sim_z_extent = 2500
        src_z_extent = 1000
        pml_thickness = [10 * dx] * 6
        timing_comp = 1
        solver = "maxwell_cg"
    else:
        sim_z_extent = 0
        src_z_extent = 20
        pml_thickness = [10 * dx] * 4 + [0] * 2
        timing_comp = 2
        solver = "local_direct"

    sim = maxwell.fdfd_simulation(
        name="sim_{}".format(stage),
        wavelength=1550,
        eps=eps,
        solver=solver,
        sources=[
            maxwell.WaveguideModeSource(center=[-1400, 0, 0],
                                        extents=[0, 2500, src_z_extent],
                                        normal=[1, 0, 0],
                                        mode_num=0,
                                        power=1),
        ],
        simulation_space=maxwell.SimulationSpace(
            mesh=maxwell.UniformMesh(dx=dx),
            sim_region=goos.Box3d(
                center=[0, 0, 0],
                extents=[4000, 4000, sim_z_extent],
            ),
            pml_thickness=pml_thickness),
        background=goos.material.Material(index=1.0),
        outputs=[
            maxwell.Epsilon(name="eps"),
            maxwell.ElectricField(name="field"),
            maxwell.WaveguideModeOverlap(name="overlap",
                                         center=[0, 1400, 0],
                                         extents=[2500, 0, src_z_extent],
                                         normal=[0, 1, 0],
                                         mode_num=0,
                                         power=1),
        ],
    )

    obj = goos.rename(-goos.abs(sim["overlap"]), name="obj_{}".format(stage))
    return obj, sim
Ejemplo n.º 2
0
def make_objective(eps: goos.Shape, stage: str, sim_3d: bool):
    if sim_3d:
        sim_z_extent = 2500
        solver_info = maxwell.MaxwellSolver(solver="maxwell_cg",
                                            err_thresh=1e-2)
        pml_thickness = [400] * 6
    else:
        sim_z_extent = 40
        solver_info = maxwell.DirectSolver()
        pml_thickness = [400, 400, 400, 400, 0, 0]

    sim = maxwell.fdfd_simulation(
        name="sim_{}".format(stage),
        wavelength=1550,
        eps=eps,
        solver_info=solver_info,
        sources=[
            maxwell.WaveguideModeSource(center=[-1400, 0, 0],
                                        extents=[0, 2500, 1000],
                                        normal=[1, 0, 0],
                                        mode_num=0,
                                        power=1)
        ],
        simulation_space=maxwell.SimulationSpace(
            mesh=maxwell.UniformMesh(dx=40),
            sim_region=goos.Box3d(
                center=[0, 0, 0],
                extents=[4000, 4000, sim_z_extent],
            ),
            pml_thickness=pml_thickness),
        background=goos.material.Material(index=1.0),
        outputs=[
            maxwell.Epsilon(name="eps"),
            maxwell.ElectricField(name="field"),
            maxwell.WaveguideModeOverlap(name="overlap",
                                         center=[0, 1400, 0],
                                         extents=[2500, 0, 1000],
                                         normal=[0, 1, 0],
                                         mode_num=0,
                                         power=1),
        ],
    )

    obj = goos.rename(-goos.abs(sim["overlap"]), name="obj_{}".format(stage))
    return obj, sim
Ejemplo n.º 3
0
def make_objective_fdtd(eps: goos.Shape, stage: str, sim_3d: bool):
    if sim_3d:
        sim_z_extent = 2500
        src_z_extent = 1000
        pml_thickness = [400, 400, 400, 400, 400, 400]
        # Dominant E-component is Ey.
        timing_comp = 1
        # Simulate across 4 cores.
        sim_cores = 4
    else:
        sim_z_extent = 0
        src_z_extent = 0
        # No PMLs in the vertical direction for 2D.
        pml_thickness = [400, 400, 400, 400, 0, 0]
        # Dominant E-component is Ez.
        timing_comp = 2
        # Simulate using only a single CPU.
        sim_cores = 1

    sim = meep.fdtd_simulation(
        name="sim_{}".format(stage),
        eps=eps,
        sources=[
            meep.WaveguideModeSource(center=[-1400, 0, 0],
                                     extents=[0, 2500, src_z_extent],
                                     normal=[1, 0, 0],
                                     mode_num=0,
                                     power=1,
                                     wavelength=1550,
                                     bandwidth=100),
        ],
        sim_space=meep.SimulationSpace(dx=20,
                                       sim_region=goos.Box3d(
                                           center=[0, 0, 0],
                                           extents=[4000, 4000, sim_z_extent],
                                       ),
                                       pml_thickness=pml_thickness),
        # `SimulationTiming` handles termination condition for FDTD.
        # In this case, we rely on Meep's `stop_when_fields_decayed` which
        # waits until the field component indexed by `timing_comp`
        # at pos (0, 0, 0) has decayed (after the source has finished).
        sim_timing=meep.SimulationTiming(stopping_conditions=[
            meep.StopWhenFieldsDecayed(
                time_increment=100,
                component=timing_comp,
                pos=[0, 0, 0],
                threshold=1e-4,
            )
        ]),
        background=goos.material.Material(index=1.0),
        outputs=[
            meep.Epsilon(name="eps", wavelength=1550),
            meep.ElectricField(name="field", wavelength=1550),
            meep.WaveguideModeOverlap(name="overlap",
                                      wavelength=1550,
                                      center=[0, 1400, 0],
                                      extents=[2500, 0, src_z_extent],
                                      normal=[0, 1, 0],
                                      mode_num=0,
                                      power=1),
        ],
        sim_cores=sim_cores,
    )

    obj = goos.rename(-goos.abs(sim["overlap"]), name="obj_{}".format(stage))
    return obj, sim
Ejemplo n.º 4
0
def make_objective(eps: goos.Shape, stage: str, params: Options):
    """Creates the objective.

    The function sets up the simulation and the objective function for the
    grating optimization. The simulation is a FDFD simulation with a
    Gaussian beam source that couples into a the waveguide.
    The optimization minimizes `(1 - coupling_eff)**2` where `coupling_eff` is
    the fiber-to-chip coupling efficiency.

    Args:
        eps: The permittivity distribution, including the waveguide and
            grating.
        stage: Name of the optimization stage. Used to name the nodes.
        params: Options for the optimization problem.

    Returns:
        A tuple `(obj, sim)` where `obj` is the objective and `sim` is the
        simulation.
    """
    solver = "local_direct"

    sim_left_x = -params.wg_len
    sim_right_x = params.coupler_len + params.buffer_len
    pml_thick = params.dx * 10
    sim_z_center = (params.wg_thickness / 2 + params.beam_dist -
                    params.box_size) / 2
    sim_z_extent = (params.wg_thickness + params.beam_dist + params.box_size +
                    2000 + pml_thick * 2)

    sim = maxwell.fdfd_simulation(
        name="sim_{}".format(stage),
        wavelength=params.wlen,
        eps=eps,
        solver=solver,
        sources=[
            maxwell.GaussianSource(
                w0=params.beam_width / 2,
                center=[
                    params.coupler_len / 2, 0,
                    params.wg_thickness / 2 + params.beam_dist
                ],
                extents=[params.beam_extents, 0, 0],
                normal=[0, 0, -1],
                power=1,
                theta=np.deg2rad(params.source_angle_deg),
                psi=np.pi / 2,
                polarization_angle=0,
                normalize_by_sim=True)
        ],
        simulation_space=maxwell.SimulationSpace(
            mesh=maxwell.UniformMesh(dx=params.dx),
            sim_region=goos.Box3d(
                center=[(sim_left_x + sim_right_x) / 2, 0, sim_z_center],
                extents=[sim_right_x - sim_left_x, 0, sim_z_extent],
            ),
            pml_thickness=[pml_thick, pml_thick, 0, 0, pml_thick, pml_thick]),
        background=goos.material.Material(index=params.eps_bg),
        outputs=[
            maxwell.Epsilon(name="eps"),
            maxwell.ElectricField(name="field"),
            maxwell.WaveguideModeOverlap(name="overlap",
                                         center=[-params.wg_len / 2, 0, 0],
                                         extents=[0, 1000, 2000],
                                         normal=[-1, 0, 0],
                                         mode_num=0,
                                         power=1),
        ],
    )

    obj = (1 - goos.abs(sim["overlap"]))**2
    obj = goos.rename(obj, name="obj_{}".format(stage))
    return obj, sim
Ejemplo n.º 5
0
def test_simulate_wg_opt():
    with goos.OptimizationPlan() as plan:
        wg_in = goos.Cuboid(pos=goos.Constant([-2000, 0, 0]),
                            extents=goos.Constant([3000, 800, 40]),
                            material=goos.material.Material(index=3.45))
        wg_out = goos.Cuboid(pos=goos.Constant([2000, 0, 0]),
                             extents=goos.Constant([3000, 800, 40]),
                             material=goos.material.Material(index=3.45))

        def initializer(size):
            # Set the seed immediately before calling `random` to ensure
            # reproducibility.
            np.random.seed(247)
            return np.random.random(size) * 0.1 + np.ones(size) * 0.7

        var, design = goos.pixelated_cont_shape(
            initializer=initializer,
            pos=goos.Constant([0, 0, 0]),
            extents=[1000, 800, 40],
            pixel_size=[40, 40, 40],
            material=goos.material.Material(index=1),
            material2=goos.material.Material(index=3.45),
        )
        eps = goos.GroupShape([wg_in, wg_out, design])
        sim = meep.FdtdSimulation(
            eps=eps,
            sources=[
                meep.WaveguideModeSource(
                    center=[-1000, 0, 0],
                    extents=[0, 2500, 0],
                    normal=[1, 0, 0],
                    mode_num=2,
                    power=1,
                    wavelength=1550,
                    bandwidth=100,
                )
            ],
            sim_space=meep.SimulationSpace(
                dx=40,
                sim_region=goos.Box3d(
                    center=[0, 0, 0],
                    extents=[4000, 4000, 0],
                ),
                pml_thickness=[400, 400, 400, 400, 0, 0]),
            sim_timing=meep.SimulationTiming(stopping_conditions=[
                meep.StopWhenFieldsDecayed(
                    time_increment=50,
                    component=2,
                    pos=[0, 0, 0],
                    threshold=1e-6,
                )
            ], ),
            background=goos.material.Material(index=1.0),
            outputs=[
                meep.Epsilon(wavelength=1550),
                meep.ElectricField(wavelength=1550),
                meep.WaveguideModeOverlap(wavelength=1550,
                                          center=[1000, 0, 0],
                                          extents=[0, 2500, 0],
                                          normal=[1, 0, 0],
                                          mode_num=0,
                                          power=1),
            ])

        obj = -goos.abs(sim[2])

        import meep as mp
        mp.quiet()
        goos.opt.scipy_minimize(obj,
                                "L-BFGS-B",
                                monitor_list=[obj],
                                max_iters=5)
        plan.run()

        # Check that we can optimize. We choose something over 60% as
        # incorrect gradients will typically not reach this point.
        assert obj.get().array < -0.85

        # As a final check, compare simulation results against Maxwell.
        # Note that dx = 40 for Meep is actually too innaccurate. We therefore
        # resimulate the final structure for both Meep and Maxwell.
        from spins.goos_sim import maxwell
        sim_fdfd = maxwell.fdfd_simulation(
            wavelength=1550,
            eps=eps,
            sources=[
                maxwell.WaveguideModeSource(
                    center=[-1000, 0, 0],
                    extents=[0, 2500, 0],
                    normal=[1, 0, 0],
                    mode_num=2,
                    power=1,
                )
            ],
            simulation_space=maxwell.SimulationSpace(
                mesh=maxwell.UniformMesh(dx=20),
                sim_region=goos.Box3d(
                    center=[0, 0, 0],
                    extents=[4000, 4000, 0],
                ),
                pml_thickness=[400, 400, 400, 400, 0, 0]),
            background=goos.material.Material(index=1.0),
            outputs=[
                maxwell.Epsilon(),
                maxwell.ElectricField(),
                maxwell.WaveguideModeOverlap(center=[1000, 0, 0],
                                             extents=[0, 2500, 0],
                                             normal=[1, 0, 0],
                                             mode_num=0,
                                             power=1),
            ],
            solver="local_direct")

        sim_fdtd_hi = meep.FdtdSimulation(
            eps=eps,
            sources=[
                meep.WaveguideModeSource(
                    center=[-1000, 0, 0],
                    extents=[0, 2500, 0],
                    normal=[1, 0, 0],
                    mode_num=2,
                    power=1,
                    wavelength=1550,
                    bandwidth=100,
                )
            ],
            sim_space=meep.SimulationSpace(
                dx=20,
                sim_region=goos.Box3d(
                    center=[0, 0, 0],
                    extents=[4000, 4000, 0],
                ),
                pml_thickness=[400, 400, 400, 400, 0, 0]),
            sim_timing=meep.SimulationTiming(stopping_conditions=[
                meep.StopWhenFieldsDecayed(
                    time_increment=50,
                    component=2,
                    pos=[0, 0, 0],
                    threshold=1e-6,
                )
            ], ),
            background=goos.material.Material(index=1.0),
            outputs=[
                meep.Epsilon(wavelength=1550),
                meep.ElectricField(wavelength=1550),
                meep.WaveguideModeOverlap(wavelength=1550,
                                          center=[1000, 0, 0],
                                          extents=[0, 2500, 0],
                                          normal=[1, 0, 0],
                                          mode_num=0,
                                          power=1),
            ])
        fdtd_hi_power = goos.abs(sim_fdtd_hi[2])**2
        fdfd_power = goos.abs(sim_fdfd[2])**2

        # Check that power is correct within 0.5%.
        assert np.abs(fdfd_power.get().array - fdtd_hi_power.get().array) < 0.005
Ejemplo n.º 6
0
def make_objective(eps: goos.Shape, stage: str):
    sim_z_extent = 1800
    simcenter_positon_z = 300
    sources_wx = 8000
    sources_wy = 8000
    solver_info = maxwell.MaxwellSolver(solver="maxwell_cg", err_thresh=1e-2)
    pml_thickness = [400, 400, 400, 400, 400, 400]
    sources_position_z = 800
    wavelength = 635
    background = goos.material.Material(index=1.0)
    simulation_space = maxwell.SimulationSpace(
        mesh=maxwell.UniformMesh(dx=50),
        sim_region=goos.Box3d(
            center=[0, 0, simcenter_positon_z],
            extents=[10000, 10000, sim_z_extent],
        ),
        pml_thickness=pml_thickness)
    sources1 = [
        maxwell.LaguerreGaussianSource(w0=1400,
                                       center=[0, 0, sources_position_z],
                                       beam_center=[0, 0, sources_position_z],
                                       extents=[sources_wx, sources_wy, 0],
                                       normal=[0, 0, -1],
                                       theta=0,
                                       psi=0,
                                       m=2,
                                       p=0,
                                       polarization_angle=0,
                                       power=1),
    ]
    sources2 = [
        maxwell.LaguerreGaussianSource(w0=1400,
                                       center=[0, 0, sources_position_z],
                                       beam_center=[0, 0, sources_position_z],
                                       extents=[sources_wx, sources_wy, 0],
                                       normal=[0, 0, -1],
                                       theta=0,
                                       psi=0,
                                       m=3,
                                       p=0,
                                       polarization_angle=0,
                                       power=1),
    ]
    sources3 = [
        maxwell.LaguerreGaussianSource(w0=1400,
                                       center=[0, 0, sources_position_z],
                                       beam_center=[0, 0, sources_position_z],
                                       extents=[sources_wx, sources_wy, 0],
                                       normal=[0, 0, -1],
                                       theta=0,
                                       psi=0,
                                       m=-3,
                                       p=0,
                                       polarization_angle=0,
                                       power=1),
    ]
    sources4 = [
        maxwell.LaguerreGaussianSource(w0=1400,
                                       center=[0, 0, sources_position_z],
                                       beam_center=[0, 0, sources_position_z],
                                       extents=[sources_wx, sources_wy, 0],
                                       normal=[0, 0, -1],
                                       theta=0,
                                       psi=0,
                                       m=-2,
                                       p=0,
                                       polarization_angle=0,
                                       power=1),
    ]
    sources5 = [
        maxwell.LaguerreGaussianSource(w0=1400,
                                       center=[0, 0, sources_position_z],
                                       beam_center=[0, 0, sources_position_z],
                                       extents=[sources_wx, sources_wy, 0],
                                       normal=[0, 0, -1],
                                       theta=0,
                                       psi=0,
                                       m=1,
                                       p=0,
                                       polarization_angle=0,
                                       power=1),
    ]
    sources6 = [
        maxwell.LaguerreGaussianSource(w0=1400,
                                       center=[0, 0, sources_position_z],
                                       beam_center=[0, 0, sources_position_z],
                                       extents=[sources_wx, sources_wy, 0],
                                       normal=[0, 0, -1],
                                       theta=0,
                                       psi=0,
                                       m=-1,
                                       p=0,
                                       polarization_angle=0,
                                       power=1),
    ]
    sources7 = [
        maxwell.LaguerreGaussianSource(w0=1400,
                                       center=[0, 0, sources_position_z],
                                       beam_center=[0, 0, sources_position_z],
                                       extents=[sources_wx, sources_wy, 0],
                                       normal=[0, 0, -1],
                                       theta=0,
                                       psi=0,
                                       m=0,
                                       p=0,
                                       polarization_angle=0,
                                       power=1),
    ]
    outputs = [
        maxwell.Epsilon(name="eps"),
        maxwell.ElectricField(name="field"),
        maxwell.WaveguideModeOverlap(name="overlap1",
                                     center=[1600, -4500, 0],
                                     extents=[800, 0, 400],
                                     normal=[0, -1, 0],
                                     mode_num=0,
                                     power=1),
        maxwell.WaveguideModeOverlap(name="overlap2",
                                     center=[-1600, -4500, 0],
                                     extents=[800, 0, 400],
                                     normal=[0, -1, 0],
                                     mode_num=0,
                                     power=1),
        maxwell.WaveguideModeOverlap(name="overlap3",
                                     center=[1600, 4500, 0],
                                     extents=[800, 0, 400],
                                     normal=[0, 1, 0],
                                     mode_num=0,
                                     power=1),
        maxwell.WaveguideModeOverlap(name="overlap4",
                                     center=[-1600, 4500, 0],
                                     extents=[800, 0, 400],
                                     normal=[0, 1, 0],
                                     mode_num=0,
                                     power=1),
        maxwell.WaveguideModeOverlap(name="overlap5",
                                     center=[4500, -1600, 0],
                                     extents=[0, 800, 400],
                                     normal=[1, 0, 0],
                                     mode_num=0,
                                     power=1),
        maxwell.WaveguideModeOverlap(name="overlap6",
                                     center=[4500, 1600, 0],
                                     extents=[0, 800, 400],
                                     normal=[1, 0, 0],
                                     mode_num=0,
                                     power=1),
        maxwell.WaveguideModeOverlap(name="overlap7",
                                     center=[-4500, 0, 0],
                                     extents=[0, 800, 400],
                                     normal=[-1, 0, 0],
                                     mode_num=0,
                                     power=1),
    ]
    sim1 = maxwell.fdfd_simulation(
        name="sim1_{}".format(stage),
        wavelength=wavelength,
        eps=eps,
        solver_info=solver_info,
        sources=sources1,
        simulation_space=simulation_space,
        background=background,
        outputs=outputs,
    )
    sim2 = maxwell.fdfd_simulation(
        name="sim2_{}".format(stage),
        wavelength=wavelength,
        eps=eps,
        solver_info=solver_info,
        sources=sources2,
        simulation_space=simulation_space,
        background=background,
        outputs=outputs,
    )
    sim3 = maxwell.fdfd_simulation(
        name="sim3_{}".format(stage),
        wavelength=wavelength,
        eps=eps,
        solver_info=solver_info,
        sources=sources3,
        simulation_space=simulation_space,
        background=background,
        outputs=outputs,
    )
    sim4 = maxwell.fdfd_simulation(
        name="sim4_{}".format(stage),
        wavelength=wavelength,
        eps=eps,
        solver_info=solver_info,
        sources=sources4,
        simulation_space=simulation_space,
        background=background,
        outputs=outputs,
    )
    sim5 = maxwell.fdfd_simulation(
        name="sim5_{}".format(stage),
        wavelength=wavelength,
        eps=eps,
        solver_info=solver_info,
        sources=sources5,
        simulation_space=simulation_space,
        background=background,
        outputs=outputs,
    )
    sim6 = maxwell.fdfd_simulation(
        name="sim6_{}".format(stage),
        wavelength=wavelength,
        eps=eps,
        solver_info=solver_info,
        sources=sources6,
        simulation_space=simulation_space,
        background=background,
        outputs=outputs,
    )
    sim7 = maxwell.fdfd_simulation(
        name="sim7_{}".format(stage),
        wavelength=wavelength,
        eps=eps,
        solver_info=solver_info,
        sources=sources7,
        simulation_space=simulation_space,
        background=background,
        outputs=outputs,
    )

    obj1 = goos.rename(
        ((goos.abs(sim1["overlap1"]) - 12)**2 + goos.abs(sim1["overlap2"])**2 +
         goos.abs(sim1["overlap3"])**2 + goos.abs(sim1["overlap4"])**2 +
         goos.abs(sim1["overlap5"])**2 + goos.abs(sim1["overlap6"])**2 +
         goos.abs(sim1["overlap7"])**2),
        name="obj1_{}".format(stage))
    obj2 = goos.rename(
        (goos.abs(sim2["overlap1"])**2 +
         (goos.abs(sim2["overlap2"]) - 12)**2 + goos.abs(sim2["overlap3"])**2 +
         goos.abs(sim2["overlap4"])**2 + goos.abs(sim2["overlap5"])**2 +
         goos.abs(sim2["overlap6"])**2 + goos.abs(sim2["overlap7"])**2),
        name="obj2_{}".format(stage))
    obj3 = goos.rename(
        (goos.abs(sim3["overlap1"])**2 + goos.abs(sim3["overlap2"])**2 +
         (goos.abs(sim3["overlap3"]) - 12)**2 + goos.abs(sim3["overlap4"])**2 +
         goos.abs(sim3["overlap5"])**2 + goos.abs(sim3["overlap6"])**2 +
         goos.abs(sim3["overlap7"])**2),
        name="obj3_{}".format(stage))
    obj4 = goos.rename(
        (goos.abs(sim4["overlap1"])**2 + goos.abs(sim4["overlap2"])**2 +
         goos.abs(sim4["overlap3"])**2 +
         (goos.abs(sim4["overlap4"]) - 12)**2 + goos.abs(sim4["overlap5"])**2 +
         goos.abs(sim4["overlap6"])**2 + goos.abs(sim4["overlap7"])**2),
        name="obj4_{}".format(stage))
    obj5 = goos.rename(
        (goos.abs(sim5["overlap1"])**2 + goos.abs(sim5["overlap2"])**2 +
         goos.abs(sim5["overlap3"])**2 + goos.abs(sim5["overlap4"])**2 +
         (goos.abs(sim5["overlap5"]) - 12)**2 + goos.abs(sim5["overlap6"])**2 +
         goos.abs(sim5["overlap7"])**2),
        name="obj5_{}".format(stage))
    obj6 = goos.rename(
        (goos.abs(sim6["overlap1"])**2 + goos.abs(sim6["overlap2"])**2 +
         goos.abs(sim6["overlap3"])**2 + goos.abs(sim6["overlap4"])**2 +
         goos.abs(sim6["overlap5"])**2 +
         (goos.abs(sim6["overlap6"]) - 12)**2 + goos.abs(sim6["overlap7"])**2),
        name="obj5_{}".format(stage))
    obj7 = goos.rename(
        (goos.abs(sim7["overlap1"])**2 + goos.abs(sim7["overlap2"])**2 +
         goos.abs(sim7["overlap3"])**2 + goos.abs(sim7["overlap4"])**2 +
         goos.abs(sim7["overlap5"])**2 + goos.abs(sim7["overlap6"])**2 +
         (goos.abs(sim7["overlap7"]) - 12)**2),
        name="obj5_{}".format(stage))
    obj = obj1 + obj2 + obj3 + obj4 + 2 * obj5 + 2 * obj6 + 8 * obj7
    return obj, sim1, sim2, sim3, sim4, sim5, sim6, sim7
Ejemplo n.º 7
0
def test_simulate_wg_opt():
    with goos.OptimizationPlan() as plan:
        wg_in = goos.Cuboid(pos=goos.Constant([-2000, 0, 0]),
                            extents=goos.Constant([3000, 800, 220]),
                            material=goos.material.Material(index=3.45))
        wg_out = goos.Cuboid(pos=goos.Constant([2000, 0, 0]),
                             extents=goos.Constant([3000, 800, 220]),
                             material=goos.material.Material(index=3.45))

        def initializer(size):
            # Set the seed immediately before calling `random` to ensure
            # reproducibility.
            np.random.seed(247)
            return np.random.random(size) * 0.1 + np.ones(size) * 0.5

        var, design = goos.pixelated_cont_shape(
            initializer=initializer,
            pos=goos.Constant([0, 0, 0]),
            extents=[1000, 800, 220],
            pixel_size=[40, 40, 40],
            material=goos.material.Material(index=1),
            material2=goos.material.Material(index=3.45),
        )
        eps = goos.GroupShape([wg_in, wg_out, design])
        sim = maxwell.fdfd_simulation(
            eps=eps,
            wavelength=1550,
            solver="local_direct",
            sources=[
                maxwell.WaveguideModeSource(
                    center=[-1000, 0, 0],
                    extents=[0, 2500, 0],
                    normal=[1, 0, 0],
                    mode_num=2,
                    power=1,
                )
            ],
            simulation_space=maxwell.SimulationSpace(
                mesh=maxwell.UniformMesh(dx=40),
                sim_region=goos.Box3d(
                    center=[0, 0, 0],
                    extents=[4000, 4000, 40],
                ),
                pml_thickness=[400, 400, 400, 400, 0, 0]),
            background=goos.material.Material(index=1.0),
            outputs=[
                maxwell.Epsilon(),
                maxwell.ElectricField(),
                maxwell.WaveguideModeOverlap(wavelength=1550,
                                             center=[1000, 0, 0],
                                             extents=[0, 2500, 0],
                                             normal=[1, 0, 0],
                                             mode_num=0,
                                             power=1),
            ])

        obj = -goos.abs(sim[2])

        goos.opt.scipy_minimize(obj,
                                "L-BFGS-B",
                                monitor_list=[obj],
                                max_iters=15)
        plan.run()

        assert obj.get().array < -0.90
Ejemplo n.º 8
0
def test_simulate_wg_opt_grad():
    with goos.OptimizationPlan() as plan:
        wg_in = goos.Cuboid(pos=goos.Constant([-2000, 0, 0]),
                            extents=goos.Constant([3000, 800, 220]),
                            material=goos.material.Material(index=3.45))
        wg_out = goos.Cuboid(pos=goos.Constant([2000, 0, 0]),
                             extents=goos.Constant([3000, 800, 220]),
                             material=goos.material.Material(index=3.45))

        def initializer(size):
            # Set the seed immediately before calling `random` to ensure
            # reproducibility.
            np.random.seed(247)
            return np.random.random(size)

        var, design = goos.pixelated_cont_shape(
            initializer=initializer,
            pos=goos.Constant([0, 0, 0]),
            extents=[1000, 800, 220],
            pixel_size=[500, 400, 220],
            material=goos.material.Material(index=1),
            material2=goos.material.Material(index=3.45),
        )
        eps = goos.GroupShape([wg_in, wg_out, design])
        sim = maxwell.fdfd_simulation(
            eps=eps,
            wavelength=1550,
            solver="local_direct",
            sources=[
                maxwell.WaveguideModeSource(
                    center=[-1000, 0, 0],
                    extents=[0, 2500, 0],
                    normal=[1, 0, 0],
                    mode_num=2,
                    power=1,
                )
            ],
            simulation_space=maxwell.SimulationSpace(
                mesh=maxwell.UniformMesh(dx=40),
                sim_region=goos.Box3d(
                    center=[0, 0, 0],
                    extents=[4000, 4000, 40],
                ),
                pml_thickness=[400, 400, 400, 400, 0, 0]),
            background=goos.material.Material(index=1.0),
            outputs=[
                maxwell.Epsilon(),
                maxwell.ElectricField(),
                maxwell.WaveguideModeOverlap(wavelength=1550,
                                             center=[1000, 0, 0],
                                             extents=[0, 2500, 0],
                                             normal=[1, 0, 0],
                                             mode_num=0,
                                             power=1),
            ])

        obj = -goos.abs(sim[2])

        adjoint_grad = obj.get_grad([var])[0].array_grad

        # Calculate brute force gradient.
        var_val = var.get().array
        eps = 0.001
        num_grad = np.zeros_like(var_val)
        for i in range(var_val.shape[0]):
            for j in range(var_val.shape[1]):
                temp_val = var_val.copy()
                temp_val[i, j] += eps
                var.set(temp_val)
                fplus = obj.get(run=True).array

                temp_val = var_val.copy()
                temp_val[i, j] -= eps
                var.set(temp_val)
                fminus = obj.get(run=True).array

                num_grad[i, j] = (fplus - fminus) / (2 * eps)

        np.testing.assert_array_almost_equal(adjoint_grad, num_grad, decimal=3)