def gather_design_region_fields( simulation: mp.Simulation, design_region_monitors: List[mp.DftFields], frequencies: List[float], ) -> List[List[onp.ndarray]]: """Collects the design region DFT fields from the simulation. Args: simulation: the simulation object. design_region_monitors: the installed design region monitors. frequencies: the frequencies to monitor. Returns: A list of lists. Each entry (list) in the overall list corresponds one-to- one with a declared design region. For each such contained list, the entries correspond to the field components that are monitored. The entries are ndarrays of rank 4 with dimensions (freq, x, y, (z-or-pad)). The design region fields are sampled on the *Yee grid*. This makes them fairly awkward to inspect directly. Their primary use case is supporting gradient calculations. """ design_region_fields = [] for monitor in design_region_monitors: fields_by_component = [] for component in _compute_components(simulation): fields_by_freq = [] for freq_idx, _ in enumerate(frequencies): fields = simulation.get_dft_array(monitor, component, freq_idx) fields_by_freq.append(_make_at_least_nd(fields)) fields_by_component.append(onp.stack(fields_by_freq)) design_region_fields.append(fields_by_component) return design_region_fields
def eval(self, sim: mp.Simulation) -> goos.NumericFlow: """Computes frequency-domain fields. Frequency domain fields are computed for all three components and stacked into one numpy array. Returns: A `NumericFlow` where the ith entry of the array corresponds to electric field component i (e.g. 0th entry is Ex). """ fields = np.stack([ sim.get_dft_array(self._dft_field, mp.Ex, 0), sim.get_dft_array(self._dft_field, mp.Ey, 0), sim.get_dft_array(self._dft_field, mp.Ez, 0) ], axis=0) if len(fields.shape) < 4: fields = np.expand_dims(fields, axis=self._expand_axis[0] + 1) return goos.NumericFlow(fields)
def eval(self, sim: mp.Simulation) -> goos.NumericFlow: # Retrieve the relevant tangential fields. fields = [] for comp in self._wg_mode.field_comps: fields.append( np.reshape(sim.get_dft_array(self._mon, comp, 0), self._wg_mode.xyzw[3].shape)) norms = _get_overlap_integral(self._wg_mode.mode_fields, fields, self._wg_mode.xyzw) if gridlock.axisvec2polarity(self._overlap.normal) > 0: val = 0.5 * (norms[0] + norms[1]) / self._mode_norm else: val = 0.5 * (norms[0] - norms[1]) / self._mode_norm return goos.NumericFlow(val * self._amp_factor)