Skip to content

Commit 738bc75

Browse files
fix(multiphysics): add delegation for necessary properties of a Simulation with MultiPhysicsMedium structures (#2487)
* fix: add delegation for _has_incompatibilities to MultiPhysicsMedium * fix tests for MultiPhysicsMedium simulation * extend test for MultiPhysicsMedium simulation slightly * fix: cover more cases for the multiphysicsmedium delegation * add multiphysicsmedium structure to full simulation test fixture to increase test coverage
1 parent 882e730 commit 738bc75

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

tests/test_components/test_simulation.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3566,3 +3566,66 @@ def test_sim_volumetric_structures_with_lumped_elements(tmp_path):
35663566
vol_structures = sim.volumetric_structures
35673567
assert len(vol_structures) == 2
35683568
assert np.isclose(vol_structures[1].geometry.bounding_box.size[0], 0, rtol=RTOL)
3569+
3570+
3571+
def test_create_sim_multiphysics():
3572+
s = td.Simulation(
3573+
run_time=1e-12,
3574+
size=(10, 10, 10),
3575+
grid_spec=td.GridSpec(wavelength=1.0),
3576+
medium=td.Medium(permittivity=1.0),
3577+
structures=[
3578+
td.Structure(
3579+
geometry=td.Box(size=(1, 1, 1), center=(-1, 0.5, 0.5)),
3580+
medium=td.MultiPhysicsMedium(
3581+
optical=td.Medium(permittivity=2.0),
3582+
charge=td.ChargeInsulatorMedium(permittivity=2),
3583+
name="SiO2",
3584+
),
3585+
),
3586+
],
3587+
)
3588+
3589+
3590+
def test_create_sim_multiphysics_with_incompatibilities():
3591+
modulated = td.Medium(
3592+
permittivity=2,
3593+
modulation_spec=td.ModulationSpec(
3594+
permittivity=td.SpaceTimeModulation(
3595+
time_modulation=td.ContinuousWaveTimeModulation(freq0=1e12, amplitude=1.1, phase=0),
3596+
)
3597+
),
3598+
)
3599+
assert modulated._has_incompatibilities
3600+
3601+
nonlinear = td.Medium(
3602+
nonlinear_spec=td.NonlinearSpec(
3603+
models=[
3604+
td.NonlinearSusceptibility(chi3=1.5),
3605+
td.TwoPhotonAbsorption(beta=1, sigma=1, tau=1, e_e=1, e_h=0.8, c_e=1, c_h=1),
3606+
td.KerrNonlinearity(n2=1),
3607+
],
3608+
num_iters=20,
3609+
)
3610+
)
3611+
with pytest.raises(pydantic.ValidationError):
3612+
s = td.Simulation(
3613+
run_time=1e-12,
3614+
size=(10, 10, 10),
3615+
grid_spec=td.GridSpec(wavelength=1.0),
3616+
medium=td.Medium(permittivity=1.0),
3617+
structures=[
3618+
td.Structure(
3619+
geometry=td.Box(size=(1, 1, 1), center=(-1, 0.5, 0.5)),
3620+
medium=nonlinear,
3621+
),
3622+
td.Structure(
3623+
geometry=td.Box(size=(1, 1, 1), center=(-1, 0.5, 0.5)),
3624+
medium=td.MultiPhysicsMedium(
3625+
optical=modulated,
3626+
charge=td.ChargeInsulatorMedium(permittivity=2),
3627+
name="SiO2",
3628+
),
3629+
),
3630+
],
3631+
)

tests/utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,14 @@ def make_custom_data(lims, unstructured):
664664
medium=td.Medium(permittivity=1.5),
665665
name="transformed_box",
666666
),
667+
td.Structure(
668+
geometry=td.Box(size=(1, 1, 1), center=(1, 1, 1)),
669+
medium=td.MultiPhysicsMedium(
670+
optical=td.Medium(permittivity=4.0),
671+
charge=td.ChargeInsulatorMedium(permittivity=2),
672+
name="SiO2",
673+
),
674+
),
667675
],
668676
sources=[
669677
td.UniformCurrentSource(

tidy3d/components/material/multi_physics.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,28 @@ def __getattr__(self, name: str):
139139
return None
140140

141141
DELEGATED_ATTRIBUTES = {
142-
"is_pec": self.optical,
143142
"_eps_plot": self.optical,
144143
"viz_spec": self.optical,
144+
"eps_diagonal_numerical": self.optical,
145+
"eps_complex_to_nk": self.optical,
146+
"nonlinear_spec": self.optical,
147+
"is_pec": self.optical,
148+
"is_time_modulated": self.optical,
149+
"is_nonlinear": self.optical,
150+
"is_fully_anisotropic": self.optical,
151+
"is_custom": self.optical,
152+
"is_isotropic": self.optical,
153+
"is_spatially_uniform": self.optical,
154+
"_incompatible_material_types": self.optical,
155+
"frequency_range": self.optical,
156+
"eps_model": self.optical,
145157
}
146158

159+
if name == "_has_incompatibilities":
160+
return (self.optical and self.optical._has_incompatibilities) or (
161+
self.charge and self.charge._has_incompatibilities
162+
)
163+
147164
if name in DELEGATED_ATTRIBUTES:
148165
sub = DELEGATED_ATTRIBUTES[name]
149166
if sub is None:

0 commit comments

Comments
 (0)