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 test_render_cylinder(): with goos.OptimizationPlan() as plan: cyl = goos.Cylinder(pos=goos.Constant([0, 0, 0]), radius=goos.Constant(60), height=goos.Constant(60), material=goos.material.Material(index=3.45)) render = maxwell.RenderShape( cyl, region=goos.Box3d(center=[0, 0, 0], extents=[200, 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.], [2.20393657], [8.15133225], [8.14708434], [2.20801505]], [[1.], [4.81696873], [9.176875], [9.176875], [4.81254501]], [[1.], [2.20393657], [8.15133225], [8.14708434], [2.20801505]], [[1.], [1.], [1.], [1.], [1.]]], [[[1.], [1.], [1.], [1.], [1.]], [[1.], [2.20452237], [4.81426614], [2.20733312], [1.]], [[1.], [8.1503488], [9.176875], [8.14865466], [1.]], [[1.], [8.1503488], [9.176875], [8.14865466], [1.]], [[1.], [2.20452237], [4.81426614], [2.20733312], [1.]]], [[[1.], [1.], [1.], [1.], [1.]], [[1.], [1.06734618], [5.08385966], [5.07819579], [1.07209387]], [[1.], [5.0825484], [11.9025], [11.9025], [5.08028954]], [[1.], [5.0825484], [11.9025], [11.9025], [5.08028954]], [[1.], [1.06734618], [5.08385966], [5.07819579], [1.07209387]]]])
def test_pixelated_multietch_grating_fit_edge_locs(): # Grating defined in xz-plane. with goos.OptimizationPlan() as plan: height_index = goos.Variable([2, 0, 1, 2], parameter=True) edge_locs_target = goos.Variable([0, 1, 1.5, 2], parameter=True) grating_target = goos.grating.PixelatedGrating( edge_locs_target, height_index=height_index, height_fracs=[0, 0.5, 1], pos=[0, 0, 0], extents=[2, 10, 0.220], material=goos.material.Material(index=1), material2=goos.material.Material(index=3.5), grating_dir=0, grating_dir_spacing=0.5, etch_dir_divs=2, use_edge_locs=True) edge_locs = goos.Variable([0, 0.8, 1.6, 2]) grating = goos.grating.PixelatedGrating( edge_locs, height_index=height_index, height_fracs=[0, 0.5, 1], pos=[0, 0, 0], extents=[2, 10, 0.220], material=goos.material.Material(index=1), material2=goos.material.Material(index=3.5), grating_dir=0, grating_dir_spacing=0.5, etch_dir_divs=2, use_edge_locs=True) from spins.goos_sim import maxwell region = goos.Box3d(center=[0, 0, 0], extents=[3, 11, 0.5]) mesh = maxwell.UniformMesh(dx=0.1) eps_diff = goos.Norm( maxwell.RenderShape( grating, region=region, mesh=mesh, wavelength=1.55) - maxwell.RenderShape( grating_target, region=region, mesh=mesh, wavelength=1.55)) goos.opt.scipy_minimize(eps_diff, "L-BFGS-B", max_iters=20) plan.run() np.testing.assert_almost_equal(grating.get().array, grating_target.get().array)
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_pixelated_multietch_grating_xz_gradient(use_edge_locs, params, pol): # Brute force calculate the gradient. # Grating defined in xz-plane. with goos.OptimizationPlan() as plan: edge_locs = goos.Variable(params) height_index = goos.Variable([0, 1, 0, 1]) grating = goos.grating.PixelatedGrating( edge_locs, height_index=height_index, height_fracs=[0.4, 1], pos=[0, 0, 0], extents=[2, 10, 0.220], material=goos.material.Material(index=1), material2=goos.material.Material(index=3.5), grating_dir=0, grating_dir_spacing=0.5, etch_dir_divs=4, etch_polarity=pol, use_edge_locs=use_edge_locs) from spins.goos_sim import maxwell shape = maxwell.RenderShape(grating, region=goos.Box3d(center=[0, 0, 0], extents=[4, 10, 0.220]), mesh=maxwell.UniformMesh(dx=0.25), wavelength=1550) np.random.seed(247) obj = goos.dot(shape, np.random.random(shape.get().array.shape)) val_orig = edge_locs.get().array step = 1e-5 grad_num = np.zeros_like(val_orig) for i in range(len(val_orig)): delta = np.zeros_like(val_orig) delta[i] = 1 edge_locs.set(val_orig + step * delta) f_plus = obj.get(run=True).array edge_locs.set(val_orig - step * delta) f_minus = obj.get(run=True).array grad_num[i] = (f_plus - f_minus) / (2 * step) grad_backprop = obj.get_grad([edge_locs])[0].array_grad np.testing.assert_allclose(grad_backprop, grad_num)
def test_render_pixelated_cont_shape_grad(): 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=[200, 0, 0], extents=[1000, 1000, 220], material=goos.material.Material(index=2), material2=goos.material.Material(index=4), pixel_size=[250, 500, 220]) 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) # Compute a random objective function to test gradient. np.random.seed(247) obj = goos.dot(np.random.random(render.get().array.shape), render) 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)
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]), mesh=maxwell.UniformMesh(dx=40), wavelength=635, ) goos.util.visualize_eps(eps_rendered.get().array[2]) ''' Define and initialize the design region. ''' with plan: # Use random initialization, where each pixel is randomly assigned # a value in the range [0.3,0.7]. def initializer(size): # Set the seed immediately before calling `random` to ensure # reproducibility. np.random.seed(247) return np.random.random(size) * 0.2 + 0.5
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_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