-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
425b972
commit 79fe521
Showing
5 changed files
with
160 additions
and
1 deletion.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"""Tests mode objects.""" | ||
import pytest | ||
import pydantic | ||
import tidy3d as td | ||
from tidy3d.log import SetupError | ||
import matplotlib.pylab as plt | ||
|
||
|
||
def test_apodization(): | ||
|
||
a = td.ApodizationSpec(width=0.2) | ||
a = td.ApodizationSpec(start=1, width=0.2) | ||
a = td.ApodizationSpec(end=2, width=0.2) | ||
a = td.ApodizationSpec(start=1, end=2, width=0.2) | ||
|
||
|
||
def test_end_lt_start(): | ||
with pytest.raises(SetupError): | ||
_ = td.ApodizationSpec(start=2, end=1, width=0.2) | ||
|
||
|
||
def test_no_width(): | ||
with pytest.raises(SetupError): | ||
_ = td.ApodizationSpec(start=1, end=2) | ||
with pytest.raises(SetupError): | ||
_ = td.ApodizationSpec(start=1) | ||
with pytest.raises(SetupError): | ||
_ = td.ApodizationSpec(end=2) | ||
|
||
|
||
def test_negative_times(): | ||
with pytest.raises(pydantic.ValidationError): | ||
_ = td.ApodizationSpec(start=-2, end=-1, width=0.2) | ||
|
||
with pytest.raises(pydantic.ValidationError): | ||
_ = td.ApodizationSpec(start=1, end=2, width=-0.2) | ||
|
||
with pytest.raises(pydantic.ValidationError): | ||
_ = td.ApodizationSpec(start=1, end=2, width=0) | ||
|
||
|
||
def test_plot(): | ||
|
||
run_time = 1.0e-13 | ||
times = [0, 2.0e-14, 4.0e-14, 6.0e-14, 8.0e-14, 1.0e-13] | ||
|
||
a = td.ApodizationSpec(start=0.2 * run_time, end=0.8 * run_time, width=0.02 * run_time) | ||
a.plot(times) | ||
|
||
fig, ax = plt.subplots(1, 1) | ||
a.plot(times, ax=ax) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
"""Defines specification for apodization.""" | ||
|
||
import pydantic as pd | ||
import numpy as np | ||
|
||
from .base import Tidy3dBaseModel | ||
from ..constants import SECOND | ||
from ..log import SetupError | ||
from .types import ArrayLike, Ax | ||
from .viz import add_ax_if_none | ||
|
||
|
||
class ApodizationSpec(Tidy3dBaseModel): | ||
"""Stores specifications for the apodizaton of frequency-domain monitors. | ||
Example | ||
------- | ||
>>> apod_spec = ApodizationSpec(start=1, end=2, width=0.5) | ||
""" | ||
|
||
start: pd.NonNegativeFloat = pd.Field( | ||
None, | ||
title="Start Interval", | ||
description="Defines the time at which the start apodization ends.", | ||
units=SECOND, | ||
) | ||
|
||
end: pd.NonNegativeFloat = pd.Field( | ||
None, | ||
title="End Interval", | ||
description="Defines the time at which the end apodization begins.", | ||
units=SECOND, | ||
) | ||
|
||
width: pd.PositiveFloat = pd.Field( | ||
None, | ||
title="Apodization Width", | ||
description="Characteristic decay length of the apodization function.", | ||
units=SECOND, | ||
) | ||
|
||
@pd.validator("end", always=True, allow_reuse=True) | ||
def end_greater_than_start(cls, val, values): | ||
"""Ensure end is greater than or equal to start.""" | ||
start = values.get("start") | ||
if val is not None and start is not None and val < start: | ||
raise SetupError("End apodization begins before start apodization ends.") | ||
return val | ||
|
||
@pd.validator("width", always=True, allow_reuse=True) | ||
def width_provided(cls, val, values): | ||
"""Check that width is provided if either start or end apodization is requested.""" | ||
start = values.get("start") | ||
end = values.get("end") | ||
if (start is not None or end is not None) and val is None: | ||
raise SetupError("Apodization width must be set.") | ||
return val | ||
|
||
@add_ax_if_none | ||
def plot(self, times: ArrayLike[float, 1], ax: Ax = None) -> Ax: | ||
"""Plot the apodization function. | ||
Parameters | ||
---------- | ||
times : np.ndarray | ||
Array of times (seconds) to plot source at. | ||
To see source time amplitude for a specific :class:`Simulation`, | ||
pass ``simulation.tmesh``. | ||
ax : matplotlib.axes._subplots.Axes = None | ||
Matplotlib axes to plot on, if not specified, one is created. | ||
Returns | ||
------- | ||
matplotlib.axes._subplots.Axes | ||
The supplied or created matplotlib axes. | ||
""" | ||
times = np.array(times) | ||
amp = np.ones_like(times) | ||
|
||
if self.start is not None: | ||
start_ind = times < self.start | ||
time_scaled = (times[start_ind] - self.start) / self.width | ||
amp[start_ind] *= np.exp(-0.5 * time_scaled**2) | ||
|
||
if self.end is not None: | ||
end_ind = times > self.end | ||
time_scaled = (times[end_ind] - self.end) / self.width | ||
amp[end_ind] *= np.exp(-0.5 * time_scaled**2) | ||
|
||
ax.plot(times, amp, color="blueviolet") | ||
ax.set_xlabel("time (s)") | ||
ax.set_title("apodization function") | ||
ax.set_aspect("auto") | ||
return ax |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters