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])
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 ])
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.]]]])
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])
# 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]),
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
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
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])
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
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)
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