Skip to content

Commit 35edc0b

Browse files
committed
Replace complex fields implementation in certain nonlinearities
1 parent 00dd7c2 commit 35edc0b

File tree

5 files changed

+229
-108
lines changed

5 files changed

+229
-108
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
- Renamed `SkinDepthFitterParam` --> `SurfaceImpedanceFitterParam` used in `LossyMetalMedium`. `plot` in `LossyMetalMedium` now plots complex-valued surface impedance.
2222
- Changed plot_3d iframe url to tidy3d production environment.
2323
- `num_freqs` is now set to 3 by default for the `PlaneWave`, `GaussianBeam`, and `AnalyticGaussianBeam` sources, which makes the injection more accurate in broadband cases.
24+
- Nonlinear models `KerrNonlinearity` and `TwoPhotonAbsorption` now default to using the physical real fields instead of complex fields.
2425

2526
### Fixed
2627
- Make gauge selection for non-converged modes more robust.

tests/test_components/test_medium.py

+64-22
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,18 @@ def test_nonlinear_medium():
591591
)
592592
)
593593

594+
assert med._nonlinear_num_iters == 20
595+
assert td.Medium()._nonlinear_num_iters == 0
596+
assert td.Medium(nonlinear_spec=td.NonlinearSusceptibility(chi3=1.5))._nonlinear_num_iters == 1
597+
assert (
598+
td.Medium(
599+
nonlinear_spec=td.NonlinearSusceptibility(chi3=1.5, numiters=2)
600+
)._nonlinear_num_iters
601+
== 2
602+
)
603+
assert td.Medium()._nonlinear_models == []
604+
assert td.Medium(nonlinear_spec=td.NonlinearSpec())._nonlinear_models == []
605+
594606
# warn about deprecated api
595607
with AssertLogLevel("WARNING"):
596608
med = td.Medium(nonlinear_spec=td.NonlinearSusceptibility(chi3=1.5))
@@ -634,11 +646,15 @@ def test_nonlinear_medium():
634646
# active materials
635647
with pytest.raises(ValidationError):
636648
med = td.Medium(
637-
nonlinear_spec=td.NonlinearSpec(models=[td.TwoPhotonAbsorption(beta=-1, n0=1)])
649+
nonlinear_spec=td.NonlinearSpec(models=[td.TwoPhotonAbsorption(beta=-1, n0=1, freq0=1)])
638650
)
639651

640652
with pytest.raises(ValidationError):
641-
med = td.Medium(nonlinear_spec=td.NonlinearSpec(models=[td.KerrNonlinearity(n2=-1j, n0=1)]))
653+
med = td.Medium(
654+
nonlinear_spec=td.NonlinearSpec(
655+
models=[td.KerrNonlinearity(n2=-1j, n0=1, use_complex_fields=True)]
656+
)
657+
)
642658

643659
# automatic detection of n0 and freq0
644660
n0 = 2
@@ -662,26 +678,6 @@ def test_nonlinear_medium():
662678
assert n0 == nonlinear_spec.models[0]._get_n0(n0=None, medium=medium, freqs=[freq0])
663679
assert freq0 == nonlinear_spec.models[0]._get_freq0(freq0=None, freqs=[freq0])
664680

665-
# two photon absorption is phenomenological
666-
with AssertLogLevel("WARNING", contains_str="phenomenological"):
667-
med = td.Medium(
668-
nonlinear_spec=td.NonlinearSpec(models=[td.TwoPhotonAbsorption(beta=-1, n0=1)]),
669-
allow_gain=True,
670-
)
671-
sim.updated_copy(medium=med, path="structures/0")
672-
673-
# complex parameters
674-
with AssertLogLevel("WARNING", contains_str="preferred"):
675-
med = td.Medium(
676-
nonlinear_spec=td.NonlinearSpec(
677-
models=[
678-
td.KerrNonlinearity(n2=-1 + 1j, n0=1),
679-
],
680-
num_iters=20,
681-
)
682-
)
683-
sim.updated_copy(medium=med, path="structures/0")
684-
685681
# subsection with nonlinear materials needs to hardcode source info
686682
sim2 = sim.updated_copy(center=(-4, -4, -4), path="sources/0")
687683
sim2 = sim2.updated_copy(
@@ -696,13 +692,27 @@ def test_nonlinear_medium():
696692
source2 = source.updated_copy(source_time=source_time2)
697693
with pytest.raises(SetupError):
698694
sim.updated_copy(sources=[source, source2])
695+
with pytest.raises(SetupError):
696+
sim.updated_copy(sources=[])
699697

700698
# but if we provided it, it's ok
701699
nonlinear_spec = td.NonlinearSpec(models=[td.KerrNonlinearity(n2=1, n0=1)])
702700
structure = structure.updated_copy(medium=medium.updated_copy(nonlinear_spec=nonlinear_spec))
703701
sim = sim.updated_copy(structures=[structure])
704702
assert 1 == nonlinear_spec.models[0]._get_n0(n0=1, medium=medium, freqs=[1, 2])
705703

704+
nonlinear_spec = td.NonlinearSpec(models=[td.TwoPhotonAbsorption(beta=1, n0=1)])
705+
structure = structure.updated_copy(medium=medium.updated_copy(nonlinear_spec=nonlinear_spec))
706+
sim = sim.updated_copy(structures=[structure])
707+
with pytest.raises(SetupError):
708+
sim = sim.updated_copy(structures=[structure], sources=[source, source2])
709+
with pytest.raises(SetupError):
710+
sim = sim.updated_copy(structures=[structure], sources=[])
711+
nonlinear_spec = td.NonlinearSpec(models=[td.TwoPhotonAbsorption(beta=1, n0=1, freq0=1)])
712+
structure = structure.updated_copy(medium=medium.updated_copy(nonlinear_spec=nonlinear_spec))
713+
sim = sim.updated_copy(structures=[structure])
714+
assert 1 == nonlinear_spec.models[0]._get_freq0(freq0=1, freqs=[1, 2])
715+
706716
# active materials with automatic detection of n0
707717
nonlinear_spec_active = td.NonlinearSpec(models=[td.TwoPhotonAbsorption(beta=-1)])
708718
medium_active = medium.updated_copy(nonlinear_spec=nonlinear_spec_active)
@@ -727,6 +737,38 @@ def test_nonlinear_medium():
727737
with pytest.raises(ValidationError):
728738
td.Medium2D(ss=modulated, tt=modulated)
729739

740+
# some parameters must be real now, unless we use old implementation
741+
_ = td.TwoPhotonAbsorption(beta=1j, use_complex_fields=True)
742+
with pytest.raises(pydantic.ValidationError):
743+
_ = td.TwoPhotonAbsorption(beta=1j)
744+
_ = td.KerrNonlinearity(n2=1j, use_complex_fields=True)
745+
with pytest.raises(pydantic.ValidationError):
746+
_ = td.KerrNonlinearity(n2=1j)
747+
748+
# consistent complex fields
749+
_ = td.NonlinearSpec(
750+
models=[
751+
td.TwoPhotonAbsorption(beta=1, use_complex_fields=True),
752+
td.KerrNonlinearity(n2=1, use_complex_fields=True),
753+
]
754+
)
755+
with pytest.raises(pydantic.ValidationError):
756+
_ = td.NonlinearSpec(
757+
models=[
758+
td.TwoPhotonAbsorption(beta=1, use_complex_fields=True),
759+
td.KerrNonlinearity(n2=1, use_complex_fields=False),
760+
]
761+
)
762+
763+
# warn if using old implementation
764+
with AssertLogLevel("WARNING", contains_str="use_complex_fields"):
765+
med = td.Medium(
766+
nonlinear_spec=td.NonlinearSpec(
767+
models=[td.KerrNonlinearity(n2=1, use_complex_fields=True)]
768+
)
769+
)
770+
_ = sim.updated_copy(medium=med, path="structures/0")
771+
730772

731773
def test_custom_medium():
732774
Nx, Ny, Nz, Nf = 4, 3, 1, 1

tests/test_components/test_simulation.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3073,7 +3073,7 @@ def test_fixed_angle_sim():
30733073
permittivity=3,
30743074
nonlinear_spec=td.NonlinearSpec(
30753075
models=[
3076-
td.KerrNonlinearity(n2=-1 + 1j, n0=1),
3076+
td.KerrNonlinearity(n2=1, n0=1),
30773077
],
30783078
num_iters=20,
30793079
),

0 commit comments

Comments
 (0)