Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions tidy3d/components/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,6 @@ def plot_field(
val: Literal["real", "imag", "abs"] = "real",
freq: float = None,
time: float = None,
cbar: bool = None,
eps_alpha: float = 0.2,
ax: Ax = None,
**kwargs,
Expand All @@ -558,10 +557,10 @@ def plot_field(
What part of the field to plot (in )
freq: float = None
If monitor is a :class:`FieldMonitor`, specifies the frequency (Hz) to plot the field.
Also sets the frequency at which the permittivity is evaluated at (if dispersive).
By default, chooses permittivity as frequency goes to infinity.
time: float = None
if monitor is a :class:`FieldTimeMonitor`, specifies the time (sec) to plot the field.
cbar: bool = True
if True (default), will include colorbar
eps_alpha : float = 0.2
Opacity of the structure permittivity.
Must be between 0 and 1 (inclusive).
Expand Down Expand Up @@ -589,11 +588,11 @@ def plot_field(
xr_data = monitor_data.data_dict.get(field_name).data

# select the frequency or time value
if "f" in monitor_data.coords:
if "f" in xr_data.coords:
if freq is None:
raise DataError("'freq' must be supplied to plot a FieldMonitor.")
field_data = xr_data.interp(f=freq)
elif "t" in monitor_data.coords:
elif "t" in xr_data.coords:
if time is None:
raise DataError("'time' must be supplied to plot a FieldMonitor.")
field_data = xr_data.interp(t=time)
Expand All @@ -620,14 +619,22 @@ def plot_field(
field_data = abs(field_data)

# plot the field
xy_coords = list("xyz")
xy_coords.pop(axis)
field_data.plot(ax=ax, x=xy_coords[0], y=xy_coords[1])
xy_coord_labels = list("xyz")
xy_coord_labels.pop(axis)
x_coord_label, y_coord_label = xy_coord_labels
field_data.plot(ax=ax, x=x_coord_label, y=y_coord_label)

# plot the simulation epsilon
ax = self.simulation.plot_structures_eps(
freq=freq, cbar=cbar, x=x, y=y, z=z, alpha=eps_alpha, ax=ax
freq=freq, cbar=False, x=x, y=y, z=z, alpha=eps_alpha, ax=ax
)

# set the limits based on the xarray coordinates min and max
x_coord_values = field_data.coords[x_coord_label]
y_coord_values = field_data.coords[y_coord_label]
ax.set_xlim(min(x_coord_values), max(x_coord_values))
ax.set_ylim(min(y_coord_values), max(y_coord_values))

return ax

def export(self, fname: str) -> None:
Expand Down
24 changes: 24 additions & 0 deletions tidy3d/components/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,30 @@ def amp_time(self, time: float) -> complex:
Complex-valued source amplitude at that time..
"""

def spectrum(self, times: Array[float], freqs: Array[float], dt: float) -> complex:
"""Complex-valued source spectrum as a function of frequency

Parameters
----------
times : np.ndarray
Times to use to evaluate spectrum Fourier transform.
(Typically the simulation time mesh).
freqs : np.ndarray
Frequencies in Hz to evaluate spectrum at.
dt : float or np.ndarray
Time step to weight FT integral with.
If array, use to weigh each of the time intervals in ``times``.

Returns
-------
np.ndarray
Complex-valued array (of len(freqs)) containing spectrum at those frequencies.
"""

# (Nf, Nt) matrix that gives DFT when matrix multiplied with signal
dft_matrix = np.exp(2j * np.pi * freqs[:, None] * times) / (2 * np.pi)
return dt * dft_matrix @ self.amp_time(times)

@add_ax_if_none
def plot(self, times: Array[float], ax: Ax = None) -> Ax:
"""Plot the complex-valued amplitude of the source time-dependence.
Expand Down