Skip to content

Commit

Permalink
Added KerrMedium
Browse files Browse the repository at this point in the history
  • Loading branch information
caseyflex committed Jul 11, 2023
1 parent 7f7739f commit 9b90b0c
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- `KerrMedium` with chi3 nonlinear susceptibility.
- Source with arbitrary user-specified time dependence through `CustomSourceTime`.

### Changed
Expand Down
27 changes: 27 additions & 0 deletions tests/sims/simulation_2_3_0.json
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,33 @@
"subpixel": false
}
},
{
"geometry": {
"type": "Box",
"center": [
-1.0,
0.5,
0.5
],
"size": [
1.0,
1.0,
1.0
]
},
"name": null,
"type": "Structure",
"medium": {
"name": null,
"frequency_range": null,
"allow_gain": false,
"type": "KerrMedium",
"permittivity": 1.0,
"conductivity": 0.0,
"numiters": 20,
"chi3": 0.1
}
},
{
"geometry": {
"type": "PolySlab",
Expand Down
4 changes: 4 additions & 0 deletions tests/test_components/test_medium.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,3 +410,7 @@ def test_fully_anisotropic_media():

assert all(np.isin(np.round(perm_d), np.round(np.diag(perm_diag))))
assert all(np.isin(np.round(cond_d), np.round(np.diag(cond_diag))))


def test_nonlinear_medium():
med = td.KerrMedium(chi3=1.5, numiters=20)
7 changes: 7 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,13 @@ def prepend_tmp(path):
),
medium=custom_sellmeier,
),
Structure(
geometry=Box(
size=(1, 1, 1),
center=(-1.0, 0.5, 0.5),
),
medium=KerrMedium(chi3=0.1, numiters=20),
),
Structure(
geometry=PolySlab(
vertices=[(-1.5, -1.5), (-0.5, -1.5), (-0.5, -0.5)], slab_bounds=[-1, 1]
Expand Down
3 changes: 2 additions & 1 deletion tidy3d/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .components.medium import CustomMedium, CustomPoleResidue
from .components.medium import CustomSellmeier, FullyAnisotropicMedium
from .components.medium import CustomLorentz, CustomDrude, CustomDebye, CustomAnisotropicMedium
from .components.medium import KerrMedium
from .components.transformation import RotationAroundAxis

# structures
Expand Down Expand Up @@ -82,7 +83,7 @@
from .material_library.parametric_materials import Graphene

# for docs
from .components.medium import AbstractMedium
from .components.medium import AbstractMedium, AbstractNonlinearMedium
from .components.geometry import Geometry
from .components.source import Source, SourceTime
from .components.monitor import Monitor
Expand Down
56 changes: 56 additions & 0 deletions tidy3d/components/medium.py
Original file line number Diff line number Diff line change
Expand Up @@ -2927,6 +2927,61 @@ class CustomAnisotropicMediumInternal(CustomAnisotropicMedium):
)


class AbstractNonlinearMedium(AbstractMedium, ABC):
"""Abstract nonlinear medium.
Note
----
The nonlinear constitutive relation is solved iteratively; it may not converge
for large nonlinearities. Increasing `numiters` can help with convergence.
"""

numiters: pd.PositiveInt = pd.Field(
1,
title="Number of iterations",
description="Number of iterations for solving nonlinear constitutive relation.",
)


class KerrMedium(AbstractNonlinearMedium, Medium):
"""Kerr medium described by an instantaneous chi3 nonlinear susceptibility, as in the
expression below for the nonlinear polarization.
Note
----
.. math::
P_{NL} = \\epsilon_0 \\chi_3 |E|^2 E
Note
----
The nonlinear constitutive relation is solved iteratively; it may not converge
for large nonlinearities. Increasing `numiters` can help with convergence.
Note
----
For complex fields (e.g. when using Bloch boundary conditions), the nonlinearity
is applied separately to the real and imaginary parts, so that the above equation
holds when both E and :math:`P_{NL}` are replaced by their real or imaginary parts.
Since the physical fields are real, it wouldn't make sense to apply the instantaneous
nonlinearity directly to the complex fields.
Note
----
Different field components do not interact nonlinearly. For example,
when calculating :math:`P_{NL, x}`, we approximate :math:`|E|^2 \\approx |E_x|^2`.
This approximation is valid when the E field is predominantly polarized along one
of the x, y, or z axes.
Example
-------
>>> medium = KerrMedium(chi3=1)
"""

chi3: float = pd.Field(..., title="Chi3", description="Chi3 nonlinear susceptibility.")


# types of mediums that can be used in Simulation and Structures

MediumType3D = Union[
Expand All @@ -2946,6 +3001,7 @@ class CustomAnisotropicMediumInternal(CustomAnisotropicMedium):
CustomDebye,
CustomDrude,
CustomAnisotropicMedium,
KerrMedium,
]


Expand Down

0 comments on commit 9b90b0c

Please sign in to comment.