Beispiel #1
0
def main(save_folder: str,
         min_feature: float = 100,
         sim_3d: bool = False,
         visualize: bool = False) -> None:
    goos.util.setup_logging(save_folder)

    with goos.OptimizationPlan(save_path=save_folder) as plan:
        wg_in = goos.Cuboid(pos=goos.Constant([-2000, 0, 0]),
                            extents=goos.Constant([3000, 400, 220]),
                            material=goos.material.Material(index=3.45))
        wg_out = goos.Cuboid(pos=goos.Constant([0, 2000, 0]),
                             extents=goos.Constant([400, 3000, 220]),
                             material=goos.material.Material(index=3.45))

        def initializer(size):
            return np.random.random(size) * 0.2 + 0.5

        # Continuous optimization.
        var, design = goos.cubic_param_shape(
            initializer=initializer,
            pos=goos.Constant([0, 0, 0]),
            extents=[2000, 2000, 220],
            pixel_spacing=40,
            control_point_spacing=1.5 * min_feature,
            material=goos.material.Material(index=1),
            material2=goos.material.Material(index=3.45),
            var_name="var_cont")

        sigmoid_factor = goos.Variable(4, parameter=True, name="discr_factor")
        design = goos.cast(goos.Sigmoid(sigmoid_factor * (2 * design - 1)),
                           goos.Shape)
        eps = goos.GroupShape([wg_in, wg_out, design])

        # This node is purely for debugging purposes.
        eps_rendered = maxwell.RenderShape(
            design,
            region=goos.Box3d(center=[0, 0, 0], extents=[3000, 3000, 0]),
            mesh=maxwell.UniformMesh(dx=40),
            wavelength=1550,
        )
        if visualize:
            goos.util.visualize_eps(eps_rendered.get().array[2])

        obj, sim = make_objective_fdtd(eps, "cont", sim_3d=sim_3d)

        for factor in [4, 8]:
            sigmoid_factor.set(factor)
            goos.opt.scipy_minimize(
                obj,
                "L-BFGS-B",
                monitor_list=[sim["eps"], sim["field"], sim["overlap"], obj],
                max_iters=6,
                name="opt_cont{}".format(factor))

        plan.save()
        plan.run()

        if visualize:
            goos.util.visualize_eps(eps_rendered.get().array[2])
Beispiel #2
0
def test_render_pixelated_cont_shape():
    with goos.OptimizationPlan() as plan:

        def initializer(size):
            return [[1, 0], [0.5, 0.75], [0, 0.8], [1, 0.8]]

        var, design = goos.pixelated_cont_shape(
            initializer=initializer,
            pos=goos.Constant([200, 0, 0]),
            extents=[1000, 1000, 220],
            material=goos.material.Material(index=2),
            material2=goos.material.Material(index=4),
            pixel_size=[250, 500, 220])

        rect = goos.Cuboid(extents=goos.Constant([1000, 1000, 220]),
                           pos=goos.Constant([200, 0, 0]),
                           material=goos.material.Material(index=2))

        render = maxwell.RenderShape(
            design,
            region=goos.Box3d(center=[0, 0, 0], extents=[1500, 1500, 200]),
            mesh=maxwell.UniformMesh(dx=40),
            background=goos.material.Material(index=1.0),
            wavelength=1550)

        np.testing.assert_almost_equal(
            np.real(render.get().array[2][10:, 8, 3]), [
                1., 8.5, 16., 16., 16., 16., 16., 14.5, 10., 10., 10., 10.,
                10., 10., 4., 4., 4., 4., 4., 4., 13., 16., 16., 16., 16., 16.,
                8.5
            ])
Beispiel #3
0
def test_render_prism():
    with goos.OptimizationPlan() as plan:
        rect = goos.Cuboid(extents=goos.Constant([80, 80, 100]),
                           pos=goos.Constant([0, 0, 0]),
                           material=goos.material.Material(index=3.45))
        render = maxwell.RenderShape(
            rect,
            region=goos.Box3d(center=[0, 0, 0], extents=[160, 200, 40]),
            mesh=maxwell.UniformMesh(dx=40),
            background=goos.material.Material(index=1.0),
            wavelength=1550)

        np.testing.assert_array_almost_equal(
            render.get().array,
            [[[[1.], [1.], [1.], [1.], [1.]],
              [[1.], [1.], [11.9025], [11.9025], [1.]],
              [[1.], [1.], [11.9025], [11.9025], [1.]],
              [[1.], [1.], [1.], [1.], [1.]]],
             [[[1.], [1.], [1.], [1.], [1.]],
              [[1.], [3.725625], [6.45125], [3.725625], [1.]],
              [[1.], [6.45125], [11.9025], [6.45125], [1.]],
              [[1.], [3.725625], [6.45125], [3.725625], [1.]]],
             [[[1.], [1.], [1.], [1.], [1.]],
              [[1.], [1.], [6.45125], [6.45125], [1.]],
              [[1.], [1.], [11.9025], [11.9025], [1.]],
              [[1.], [1.], [6.45125], [6.45125], [1.]]]])
Beispiel #4
0
def main(save_folder: str, visualize: bool = False) -> None:
    goos.util.setup_logging(save_folder)

    params = Options()

    with goos.OptimizationPlan(save_path=save_folder) as plan:
        substrate = goos.Cuboid(
            pos=goos.Constant([
                params.coupler_len / 2, 0,
                -params.box_size - params.wg_thickness / 2 - 5000
            ]),
            extents=goos.Constant([params.coupler_len + 10000, 1000, 10000]),
            material=goos.material.Material(index=params.eps_wg))
        waveguide = goos.Cuboid(
            pos=goos.Constant([-params.wg_len / 2, 0, 0]),
            extents=goos.Constant(
                [params.wg_len, params.wg_width, params.wg_thickness]),
            material=goos.material.Material(index=params.eps_wg))

        wg_bottom = goos.Cuboid(
            pos=goos.Constant([
                params.coupler_len / 2, 0,
                -params.wg_thickness / 2 * params.etch_frac
            ]),
            extents=goos.Constant([
                params.coupler_len, params.wg_width,
                params.wg_thickness * (1 - params.etch_frac)
            ]),
            material=goos.material.Material(index=params.eps_wg))

        def initializer(size):
            return np.random.random(size)

        # Continuous optimization.
        var, design = goos.pixelated_cont_shape(
            initializer=initializer,
            pos=goos.Constant([
                params.coupler_len / 2, 0,
                params.wg_thickness / 2 * (1 - params.etch_frac)
            ]),
            extents=[
                params.coupler_len, params.wg_width,
                params.wg_thickness * params.etch_frac
            ],
            material=goos.material.Material(index=params.eps_bg),
            material2=goos.material.Material(index=params.eps_wg),
            pixel_size=[
                params.pixel_size, params.wg_width, params.wg_thickness
            ])

        obj, sim = make_objective(
            goos.GroupShape([substrate, waveguide, wg_bottom, design]), "cont",
            params)

        goos.opt.scipy_minimize(
            obj,
            "L-BFGS-B",
            monitor_list=[sim["eps"], sim["field"], sim["overlap"], obj],
            max_iters=60,
            name="opt_cont")

        # Prevent optimization from optimizing over continuous variable.
        var.freeze()

        # Run discretization.
        grating_var, height_var, design_disc = goos.grating.discretize_to_pixelated_grating(
            var,
            height_fracs=[0, 1],
            pixel_size=params.pixel_size,
            start_height_ind=1,
            end_height_ind=1,
            min_features=params.min_features,
            pos=[
                params.coupler_len / 2, 0,
                params.wg_thickness / 2 * (1 - params.etch_frac)
            ],
            extents=[
                params.coupler_len, params.wg_width,
                params.wg_thickness * params.etch_frac
            ],
            material=goos.material.Material(index=params.eps_bg),
            material2=goos.material.Material(index=params.eps_wg),
            grating_dir=0,
            grating_dir_spacing=20,
            etch_dir=2,
            etch_dir_divs=1)

        obj, sim = make_objective(
            goos.GroupShape([substrate, waveguide, wg_bottom, design_disc]),
            "disc", params)

        goos.opt.scipy_minimize(
            obj,
            "L-BFGS-B",
            monitor_list=[sim["eps"], sim["field"], sim["overlap"], obj],
            max_iters=100,
            name="opt_disc",
            ftol=1e-8)

        plan.save()
        plan.run()

        if visualize:
            goos.util.visualize_eps(sim["eps"].get().array[2])
Beispiel #5
0
# the following line and set `out_folder_name` somewhere else.
out_folder_name = "bend90_" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
out_folder = os.path.join(os.getcwd(), out_folder_name)
if (not os.path.exists(out_folder)):
    os.makedirs(out_folder)

## Setup logging and Optimization Plan. ##
plan = goos.OptimizationPlan(save_path=out_folder)
'''
Define the constant background structures that will not be changed
during the design. In this case, these are the input and output waveguides.
'''
with plan:
    # Define input waveguide.
    wg_in = goos.Cuboid(pos=goos.Constant([-2000, 0, 0]),
                        extents=goos.Constant([3000, 400, 220]),
                        material=goos.material.Material(index=1))
    # Define output waveguide.
    wg_out = goos.Cuboid(pos=goos.Constant([0, 2000, 0]),
                         extents=goos.Constant([400, 3000, 220]),
                         material=goos.material.Material(index=1))

    # Group these background structures together.
    eps_background_structures = goos.GroupShape([wg_in, wg_out])
    '''
Visualize the constant background structures we just defined.
'''
with plan:
    eps_rendered = maxwell.RenderShape(
        eps_background_structures,
        region=goos.Box3d(center=[0, 0, 0], extents=[3000, 3000, 0]),
Beispiel #6
0
def test_simulate_wg_straight_2d_multicore():
    with goos.OptimizationPlan() as plan:
        eps = goos.Cuboid(pos=goos.Constant([0, 0, 0]),
                          extents=goos.Constant([6000, 500, 40]),
                          material=goos.material.Material(index=3.45))
        sim = meep.FdtdSimulation(
            eps=eps,
            sources=[
                meep.WaveguideModeSource(
                    center=[-500, 0, 0],
                    extents=[0, 2500, 0],
                    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, 0],
                ),
                pml_thickness=[800, 800, 800, 800, 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),
                meep.WaveguideModeOverlap(wavelength=1550,
                                          center=[-1000, 0, 0],
                                          extents=[0, 2500, 0],
                                          normal=[-1, 0, 0],
                                          mode_num=0,
                                          power=1),
                meep.WaveguideModeOverlap(wavelength=1550,
                                          center=[0, 0, 0],
                                          extents=[0, 2500, 0],
                                          normal=[1, 0, 0],
                                          mode_num=0,
                                          power=1),
                meep.WaveguideModeOverlap(wavelength=1500,
                                          center=[0, 0, 0],
                                          extents=[0, 2500, 0],
                                          normal=[1, 0, 0],
                                          mode_num=0,
                                          power=1,
                                          normalize=True),
                meep.WaveguideModeOverlap(wavelength=1500,
                                          center=[0, 0, 0],
                                          extents=[0, 2500, 0],
                                          normal=[1, 0, 0],
                                          mode_num=0,
                                          power=1,
                                          normalize=False),
            ],
            sim_cores=2,
        )

        out = sim.get()

        # Plot the fields.
        #import matplotlib.pyplot as plt
        #eps = out[0].array
        #plt.imshow(eps)

        #plt.figure()
        #field = out[1].array
        #plt.imshow(np.real(field[2]))

        #plt.show()

        # Power transmitted should be unity but numerical dispersion could
        # affect the actual transmitted power. Last time we checked, the power
        # ~0.96.
        # 1550 nm overlap.
        assert np.abs(out[4].array)**2 >= 0.96
        assert np.abs(out[4].array)**2 <= 1.04
        # 1525 nm overlap (with normalization)
        assert np.abs(out[5].array)**2 >= 0.96
        assert np.abs(out[5].array)**2 <= 1.04

        # The unnormalized power should be roughly ~30%.
        assert np.abs(out[6].array)**2 < 0.40
        assert np.abs(out[6].array)**2 > 0.20

        # Check that waveguide power is roughly constant along waveguide.
        np.testing.assert_allclose(np.abs(out[2].array)**2,
                                   np.abs(out[4].array)**2,
                                   rtol=1e-2)

        # Check that we get minimal leakage of power flowing backwards.
        assert np.abs(out[3].array)**2 / np.abs(out[2].array)**2 < 0.01
Beispiel #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, 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
Beispiel #8
0
def main(save_folder: str,
         min_feature: float = 100,
         use_cubic: bool = True,
         visualize: bool = False) -> None:
    goos.util.setup_logging(save_folder)

    with goos.OptimizationPlan(save_path=save_folder) as plan:
        wg_1 = goos.Cuboid(pos=goos.Constant([1600, -4500, 0]),
                           extents=goos.Constant([600, 1000, 230]),
                           material=goos.material.Material(index=3.45))
        wg_2 = goos.Cuboid(pos=goos.Constant([-1600, -4500, 0]),
                           extents=goos.Constant([600, 1000, 230]),
                           material=goos.material.Material(index=3.45))
        wg_3 = goos.Cuboid(pos=goos.Constant([1600, 4500, 0]),
                           extents=goos.Constant([600, 1000, 230]),
                           material=goos.material.Material(index=3.45))
        wg_4 = goos.Cuboid(pos=goos.Constant([-1600, 4500, 0]),
                           extents=goos.Constant([600, 1000, 230]),
                           material=goos.material.Material(index=3.45))
        wg_5 = goos.Cuboid(pos=goos.Constant([4500, -1600, 0]),
                           extents=goos.Constant([1000, 600, 230]),
                           material=goos.material.Material(index=3.45))
        wg_6 = goos.Cuboid(pos=goos.Constant([4500, 1600, 0]),
                           extents=goos.Constant([1000, 600, 230]),
                           material=goos.material.Material(index=3.45))
        wg_7 = goos.Cuboid(pos=goos.Constant([-4500, 0, 0]),
                           extents=goos.Constant([1000, 600, 230]),
                           material=goos.material.Material(index=3.45))
        substrate = goos.Cuboid(pos=goos.Constant([0, 0, -500]),
                                extents=goos.Constant([11000, 11000, 770]),
                                material=goos.material.Material(index=1.4))

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

        # Continuous optimization.
        var, design = goos.pixelated_cont_shape(
            initializer=initializer,
            pos=goos.Constant([0, 0, 0]),
            extents=[8000, 8000, 230],
            material=goos.material.Material(index=1),
            material2=goos.material.Material(index=3.45),
            pixel_size=[50, 50, 230],
            var_name="var_cont")

        sigmoid_factor = goos.Variable(4, parameter=True, name="discr_factor")
        design = goos.cast(goos.Sigmoid(sigmoid_factor * (2 * design - 1)),
                           goos.Shape)
        eps = goos.GroupShape(
            [wg_1, wg_2, wg_3, wg_4, wg_5, wg_6, wg_7, design, substrate])

        # This node is purely for debugging purposes.
        eps_rendered = maxwell.RenderShape(
            eps,
            region=goos.Box3d(center=[0, 0, 0], extents=[10000, 10000, 0]),
            mesh=maxwell.UniformMesh(dx=50),
            wavelength=635,
        )
        if visualize:
            goos.util.visualize_eps(eps_rendered.get().array[2])

        obj, sim1, sim2, sim3, sim4, sim5, sim6, sim7 = make_objective(
            eps, "cont")

        for factor in [4, 8, 12]:
            sigmoid_factor.set(factor)
            goos.opt.scipy_minimize(
                obj,
                "L-BFGS-B",
                monitor_list=[
                    sim1["eps"], sim1["field"], sim1["overlap1"],
                    sim1["overlap2"], sim1["overlap3"], sim1["overlap4"],
                    sim1["overlap5"], sim1["overlap6"], sim1["overlap7"],
                    sim2["eps"], sim2["field"], sim2["overlap1"],
                    sim2["overlap2"], sim2["overlap3"], sim2["overlap4"],
                    sim2["overlap5"], sim2["overlap6"], sim2["overlap7"],
                    sim3["eps"], sim3["field"], sim3["overlap1"],
                    sim3["overlap2"], sim3["overlap3"], sim3["overlap4"],
                    sim3["overlap5"], sim3["overlap6"], sim3["overlap7"],
                    sim4["eps"], sim4["field"], sim4["overlap1"],
                    sim4["overlap2"], sim4["overlap3"], sim4["overlap4"],
                    sim4["overlap5"], sim4["overlap6"], sim4["overlap7"],
                    sim5["eps"], sim5["field"], sim5["overlap1"],
                    sim5["overlap2"], sim5["overlap3"], sim5["overlap4"],
                    sim5["overlap5"], sim5["overlap6"], sim5["overlap7"],
                    sim6["eps"], sim6["field"], sim6["overlap1"],
                    sim6["overlap2"], sim6["overlap3"], sim6["overlap4"],
                    sim6["overlap5"], sim6["overlap6"], sim6["overlap7"],
                    sim7["eps"], sim7["field"], sim7["overlap1"],
                    sim7["overlap2"], sim7["overlap3"], sim7["overlap4"],
                    sim7["overlap5"], sim7["overlap6"], sim7["overlap7"], obj
                ],
                max_iters=25,
                name="opt_cont{}".format(factor))

        plan.save()
        plan.run()

        if visualize:
            goos.util.visualize_eps(eps_rendered.get().array[2])
Beispiel #9
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
Beispiel #10
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)
Beispiel #11
0
def test_simulate_2d():
    with goos.OptimizationPlan() as plan:
        sim_region = goos.Box3d(center=[0, 0, 0], extents=[4000, 4000, 40])
        sim_mesh = maxwell.UniformMesh(dx=40)

        waveguide = goos.Cuboid(pos=goos.Constant([0, 0, 0]),
                                extents=goos.Constant([6000, 500, 40]),
                                material=goos.material.Material(index=3.45))

        eps = maxwell.RenderShape(waveguide,
                                  region=sim_region,
                                  mesh=sim_mesh,
                                  background=goos.material.Material(index=1.0),
                                  wavelength=1550)

        sim = maxwell.SimulateNode(
            wavelength=1550,
            simulation_space=maxwell.SimulationSpace(
                sim_region=sim_region,
                mesh=sim_mesh,
                pml_thickness=[400, 400, 400, 400, 0, 0],
            ),
            eps=eps,
            sources=[
                maxwell.WaveguideModeSource(
                    center=[-500, 0, 0],
                    extents=[0, 2500, 0],
                    normal=[1, 0, 0],
                    mode_num=0,
                    power=1,
                )
            ],
            solver_info=maxwell.DirectSolver(),
            outputs=[
                maxwell.Epsilon(name="eps"),
                maxwell.ElectricField(name="fields"),
                maxwell.WaveguideModeOverlap(name="overlap_forward",
                                             wavelength=1550,
                                             center=[1000, 0, 0],
                                             extents=[0, 2500, 0],
                                             normal=[1, 0, 0],
                                             mode_num=0,
                                             power=1),
                maxwell.WaveguideModeOverlap(name="overlap_backward",
                                             wavelength=1550,
                                             center=[-1000, 0, 0],
                                             extents=[0, 2500, 0],
                                             normal=[-1, 0, 0],
                                             mode_num=0,
                                             power=1),
                maxwell.WaveguideModeOverlap(name="overlap_forward2",
                                             wavelength=1550,
                                             center=[0, 0, 0],
                                             extents=[0, 2500, 0],
                                             normal=[1, 0, 0],
                                             mode_num=0,
                                             power=1),
            ])
        out = sim.get()

        # Power transmitted should be unity but numerical dispersion could
        # affect the actual transmitted power.
        assert np.abs(out[4].array)**2 >= 0.99
        assert np.abs(out[4].array)**2 <= 1.01

        # Check that waveguide power is roughly constant along waveguide.
        np.testing.assert_allclose(np.abs(out[2].array)**2,
                                   np.abs(out[4].array)**2,
                                   rtol=1e-2)

        # Check that we get minimal leakage of power flowing backwards.
        assert np.abs(out[3].array)**2 < 0.01