예제 #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
예제 #2
0
파일: bend90.py 프로젝트: zizai/spins-b
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
예제 #3
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
예제 #4
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
예제 #5
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)
예제 #6
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