(self)
| 306 | ) # place the appropriate adjoint sources |
| 307 | |
| 308 | def adjoint_run(self): |
| 309 | # set up adjoint sources and monitors |
| 310 | self.prepare_adjoint_run() |
| 311 | |
| 312 | # flip the m number |
| 313 | if utils._check_if_cylindrical(self.sim): |
| 314 | self.sim.change_m(-self.sim.m) |
| 315 | |
| 316 | # flip the k point |
| 317 | if self.sim.k_point: |
| 318 | self.sim.change_k_point(-1 * self.sim.k_point) |
| 319 | |
| 320 | self.adjoint_design_region_monitors = [] |
| 321 | for ar in range(len(self.objective_functions)): |
| 322 | # Reset the fields |
| 323 | self.sim.restart_fields() |
| 324 | self.sim.clear_dft_monitors() |
| 325 | |
| 326 | # Update the sources |
| 327 | self.sim.change_sources(self.adjoint_sources[ar]) |
| 328 | |
| 329 | # register design dft fields |
| 330 | self.adjoint_design_region_monitors.append( |
| 331 | utils.install_design_region_monitors( |
| 332 | self.sim, |
| 333 | self.design_regions, |
| 334 | self.frequencies, |
| 335 | self.decimation_factor, |
| 336 | ) |
| 337 | ) |
| 338 | self.sim._evaluate_dft_objects() |
| 339 | |
| 340 | # Adjoint run |
| 341 | self.sim.run( |
| 342 | *self.step_funcs, |
| 343 | until_after_sources=mp.stop_when_dft_decayed( |
| 344 | self.decay_by, self.minimum_run_time, self.maximum_run_time |
| 345 | ), |
| 346 | ) |
| 347 | |
| 348 | # reset the m number |
| 349 | if utils._check_if_cylindrical(self.sim): |
| 350 | self.sim.change_m(-self.sim.m) |
| 351 | |
| 352 | # reset the k point |
| 353 | if self.sim.k_point: |
| 354 | self.sim.change_k_point(-1 * self.sim.k_point) |
| 355 | |
| 356 | # update optimizer's state |
| 357 | self.current_state = "ADJ" |
| 358 | |
| 359 | def calculate_gradient(self): |
| 360 | # Iterate through all design regions and calculate gradient |
no test coverage detected