Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add warning to complex-field nonlinearities #2068

Merged
merged 1 commit into from
Nov 14, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Inaccuracy in transforming gradients from edge to `PolySlab.vertices`.
- Bug in `run_async` where an adjoint simulation would sometimes be assigned to the wrong forward simulation.
- Validate against nonlinearity or modulation in `FullyAnisotropicMedium.from_diagonal`.
- Add warning to complex-field nonlinearities, which may require more careful physical interpretation.


## [2.7.6] - 2024-10-30
Expand Down
25 changes: 13 additions & 12 deletions tests/test_components/test_medium.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,15 +562,15 @@ def test_nonlinear_medium(log_capture):
)

# complex parameters
med = td.Medium(
nonlinear_spec=td.NonlinearSpec(
models=[
td.KerrNonlinearity(n2=-1 + 1j, n0=1),
],
num_iters=20,
with AssertLogLevel(log_capture, "WARNING", contains_str="preferred"):
med = td.Medium(
nonlinear_spec=td.NonlinearSpec(
models=[
td.KerrNonlinearity(n2=-1 + 1j, n0=1),
],
num_iters=20,
)
)
)
assert_log_level(log_capture, None)

# warn about deprecated api
med = td.Medium(nonlinear_spec=td.NonlinearSusceptibility(chi3=1.5))
Expand Down Expand Up @@ -621,10 +621,11 @@ def test_nonlinear_medium(log_capture):
with pytest.raises(ValidationError):
med = td.Medium(nonlinear_spec=td.NonlinearSpec(models=[td.KerrNonlinearity(n2=-1j, n0=1)]))

med = td.Medium(
nonlinear_spec=td.NonlinearSpec(models=[td.TwoPhotonAbsorption(beta=-1, n0=1)]),
allow_gain=True,
)
with AssertLogLevel(log_capture, "WARNING", contains_str="phenomenological"):
med = td.Medium(
nonlinear_spec=td.NonlinearSpec(models=[td.TwoPhotonAbsorption(beta=-1, n0=1)]),
allow_gain=True,
)

# automatic detection of n0 and freq0
n0 = 2
Expand Down
2 changes: 1 addition & 1 deletion tests/test_plugins/test_adjoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -1858,7 +1858,7 @@ def test_nonlinear_warn(log_capture):
)

# make the nonlinear objects to add to the JaxSimulation one by one
nl_model = td.KerrNonlinearity(n2=1)
nl_model = td.NonlinearSusceptibility(chi3=1)
nl_medium = td.Medium(nonlinear_spec=td.NonlinearSpec(models=[nl_model]))
struct_static_nl = struct_static.updated_copy(medium=nl_medium)
input_struct_nl = JaxStructureStaticMedium(geometry=struct.geometry, medium=nl_medium)
Expand Down
17 changes: 16 additions & 1 deletion tidy3d/components/medium.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,14 @@ def _hardcode_medium_freqs(

def _validate_medium(self, medium: AbstractMedium):
"""Check that the model is compatible with the medium."""
log.warning(
"Found a medium with a 'TwoPhotonAbsorption' nonlinearity. "
"This uses a phenomenological model based on complex fields, "
"so care should be taken in interpreting the results. For more "
"information on the model, see the documentation at "
"'https://docs.flexcompute.com/projects/tidy3d/en/latest/api/_autosummary/tidy3d.TwoPhotonAbsorption.html' or the following reference: "
"'N. Suzuki, \"FDTD Analysis of Two-Photon Absorption and Free-Carrier Absorption in Si High-Index-Contrast Waveguides,\" J. Light. Technol. 25, 9 (2007).'."
)
# if n0 is specified, we can go ahead and validate passivity
if self.n0 is not None:
self._validate_medium_freqs(medium, [])
Expand Down Expand Up @@ -481,7 +489,7 @@ class KerrNonlinearity(NonlinearModel):
The fields in this equation are complex-valued, allowing a direct implementation of the Kerr
nonlinearity. In contrast, the model :class:`.NonlinearSusceptibility` implements a
chi3 nonlinear susceptibility using real-valued fields, giving rise to Kerr nonlinearity
as well as third-harmonic generation. The relationship between the parameters is given by
as well as third-harmonic generation and other effects. The relationship between the parameters is given by
:math:`n_2 = \\frac{3}{4} \\frac{1}{\\varepsilon_0 c_0 n_0 \\operatorname{Re}(n_0)} \\chi_3`. The additional
factor of :math:`\\frac{3}{4}` comes from the usage of complex-valued fields for the Kerr
nonlinearity and real-valued fields for the nonlinear susceptibility.
Expand Down Expand Up @@ -538,6 +546,13 @@ def _hardcode_medium_freqs(

def _validate_medium(self, medium: AbstractMedium):
"""Check that the model is compatible with the medium."""
log.warning(
"Found a medium with a 'KerrNonlinearity'. Usually, "
"'NonlinearSusceptibility' is preferred, as it captures "
"additional physical effects by acting on the underlying real fields. "
"The relation between the parameters is "
"'chi3 = (4/3) * eps_0 * c_0 * n0 * Re(n0) * n2'."
)
# if n0 is specified, we can go ahead and validate passivity
if self.n0 is not None:
self._validate_medium_freqs(medium, [])
Expand Down
Loading