def test_rename(temp_context): class NewConstant(goos.Function): node_type = "goos.new_constant" def __init__(self, value: np.ndarray): super().__init__() self._value = np.array(value) def eval(self, inputs: List[flows.NumericFlow]) -> flows.NumericFlow: return flows.NumericFlow(self._value) def grad(self, inputs: List[flows.NumericFlow], grad_val: flows.NumericFlow) -> List[flows.NumericFlow]: return [flows.NumericFlow(np.zeros_like(self._value))] with goos.OptimizationPlan() as plan: orig_node = NewConstant(3, name="old_node") new_node = goos.rename(orig_node, "new_node") # Make sure that the name is correct. assert new_node._goos_name == "new_node" # Ensure that the node type is correct. assert isinstance(new_node, NewConstant) # Ensure that basic operations hold. assert (new_node + 4).get() == 7
def main(save_folder: str): goos.util.setup_logging(save_folder) with goos.OptimizationPlan(save_path=save_folder) as plan: x = goos.Variable(3, name="x") y = goos.Variable(1, name="y") obj = goos.rename((x + y)**2 + (y - 2)**2, name="obj") # First optimize only `x`. y.freeze() goos.opt.scipy_minimize(obj, "L-BFGS-B", max_iters=10) # Now do co-optimization. y.thaw() goos.opt.scipy_minimize(obj, "L-BFGS-B", max_iters=10) plan.save() plan.run() # More efficient to call `eval_nodes` when evaluating multiple nodes # at the same time. x_val, y_val, obj_val = plan.eval_nodes([x, y, obj]) print("x: {}, y: {}, obj: {}".format(x_val.array, y_val.array, obj_val.array))
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
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
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
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
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