Thermally tuned waveguide
Contents
Thermally tuned waveguide#
In this example we use Tidy3D’s heat solver to investigate tuning of a straight rectangular waveguide using a heating strip.
[1]:
import numpy as np
from matplotlib import pyplot as plt
import tidy3d as td
import tidy3d.web as web
Setup Simulation Scene#
The simulation setup consists of a silicon waveguide in a silicon dioxide cladding on top of a silicon wafer. The heating strip is placed in the cladding above the waveguide. Let us define basic geometric parameters of simulated structures.
[2]:
# in um
w_sim = 16 # simulation width
h_buffer = 1 # vertical simulation buffer
h_clad = 2.8 # thickness of cladding
h_box = 2 # thickness of buried oxide
h_wafer = 0.5 # wafer thickness
# waveguide parameters
w_core = 0.5
h_core = 0.22
# heater parameters
h_heater = 0.14
w_heater = 2
d_heater = 2 # distance between heater and waveguide
We will place the wafer’s top surface at location \(z=0\). Let us define vertical locations of each structure. Note that we will model buried oxide and cladding as a single structure since they are made of the same material.
[3]:
z_wafer = -h_wafer / 2
z_core = h_box + h_core / 2
z_heater = h_box + h_core + d_heater + h_heater / 2
box_clad_max = h_box + h_clad
box_clad_min = (
-h_wafer / 2
) # make structures overlap to ensure no gaps due to numerical roundoff errors
h_box_clad = box_clad_max - box_clad_min
z_box_clad = (box_clad_max + box_clad_min) / 2
z_sim = (h_box + h_clad - h_wafer) / 2
h_sim = h_box + h_clad + h_wafer + 2 * h_buffer
Define optic and thermal properties of materials.
[4]:
Si_n = 3.4777 # Si refraction index
Si_n_slope = 1.86e-4 # Si thermo-optic coefficient dn/dT, 1/K
Si_k = 148e-12 # Si thermal conductivity, W / (um * K)
Si_s = 0.71 * 2.33e-12 # Si volumetric heat capacity, J / (um^3 * K)
SiO2_n = 1.444 # SiO2 refraction index
SiO2_n_slope = 1e-5 # SiO2 thermo-optic coefficient dn/dT, 1/K
SiO2_k = 1.38e-12 # SiO2 thermal conductivity, W/(um*K)
SiO2_s = 0.709 * 2.203e-12 # SiO2 volumetric heat capacity, J / (um^3 * K)
TiN_k = 28e-12 # TiN thermal conductivity W/(um*K)
TiN_s = 0.598 * 5240e-12 # TiN volumetric heat capacityJ / (um^3 * K)
TiN_sigma = 2.3e6 # Electric conductivity of TiN, S/m
Convert refraction indices into permittivity values.
[5]:
Si_eps = Si_n**2
Si_eps_slope = 2 * Si_n * Si_n_slope
SiO2_eps = SiO2_n**2
SiO2_eps_slope = 2 * SiO2_n * SiO2_n_slope
Create material classes containing relevant information for each medium. Note that we use class PerturbationMedium to specify sensitivity of optic properties to temperature and field heat_spec
to specify thermal properties. Optic characteristics of the heating strip material is modeled as a perfect electric conductor.
[6]:
Si = td.PerturbationMedium(
permittivity=Si_eps,
permittivity_perturbation=td.ParameterPerturbation(
heat=td.LinearHeatPerturbation(coeff=Si_eps_slope, temperature_ref=300)
),
heat_spec=td.SolidSpec(
conductivity=Si_k,
capacity=Si_s,
),
name="Si",
)
SiO2 = td.PerturbationMedium(
permittivity=SiO2_eps,
permittivity_perturbation=td.ParameterPerturbation(
heat=td.LinearHeatPerturbation(coeff=SiO2_eps_slope, temperature_ref=300)
),
heat_spec=td.SolidSpec(
conductivity=SiO2_k,
capacity=SiO2_s,
),
name="SiO2",
)
TiN = td.PECMedium(
heat_spec=td.SolidSpec(
conductivity=TiN_k,
capacity=TiN_s,
),
name="TiN",
)
air = td.Medium(heat_spec=td.FluidSpec(), name="air")
Create structures representing waveguide, heater, cladding, and wafer.
[7]:
core = td.Structure(
geometry=td.Box(center=(0, 0, z_core), size=(w_core, td.inf, h_core)),
medium=Si,
)
heater = td.Structure(
geometry=td.Box(center=(0, 0, z_heater), size=(w_heater, td.inf, h_heater)),
medium=TiN,
name="heater",
)
box_clad = td.Structure(
geometry=td.Box(center=(0, 0, z_box_clad), size=(td.inf, td.inf, h_box_clad)),
medium=SiO2,
)
wafer = td.Structure(
geometry=td.Box(center=(0, 0, z_wafer), size=(td.inf, td.inf, h_wafer)),
medium=Si,
name="wafer",
)
Pack structures into a simulation scene.
[8]:
scene = td.Scene(
medium=air,
structures=[box_clad, core, heater, wafer],
)
Visual validation of the setup.
[9]:
scene.plot(
y=0, hlim=[-w_sim / 2, w_sim / 2], vlim=[z_sim - h_sim / 2, z_sim + h_sim / 2]
)
plt.show()

Setup Heat Simulation#
We assume that the bottom of the wafer is maintained at temperature \(T=300\) K and ignore heat transfer at the cladding/air boundary. In this simulation setup these boundary conditions can be set using MediumMediumInterface placement. Note since no other boundary conditions are specified, the other sides of the simulation box will be treated as insulating boundary conditions.
Convective cooling/heating at the cladding/air boundary can be easily taken into account using ConvectionBC boundary conditions.
[10]:
bc_bottom = td.HeatBoundarySpec(
placement=td.MediumMediumInterface(mediums=["Si", "air"]),
condition=td.TemperatureBC(temperature=300),
)
bc_top = td.HeatBoundarySpec(
placement=td.MediumMediumInterface(mediums=["SiO2", "air"]),
condition=td.HeatFluxBC(flux=0),
)
Create a uniform heat source inside the heater structure equivalent to electrical current of \(7.3 \times 10^{-3}\) A.
[11]:
current = 7.4e-3 # A
heat_rate = (current / h_heater / w_heater) ** 2 / TiN_sigma # convert into power
heater_source = td.UniformHeatSource(rate=heat_rate, structures=[heater.name])
We will measure temperature distribution in the entire cross section of the simulation setup.
[12]:
temp_mnt = td.TemperatureMonitor(size=(td.inf, 0, td.inf), name="temperature")
For spatial discretization we will use a distance-based meshing specifying that solid-solid material interfaces should be discretized with mesh size equal to the heater height h_heater
divided by 3 and away from interfaces the grid should coarsen to four times of that size. Setting distance_interface
to three of minimal mesh size will create approximately three layers of cells with the minimal size around interfaces. Cells outside of this region will have sizes according to linear
relation dl_interface * (1 - ratio(d)) + dl_interface * ratio(d)
, where ratio(d) = (d - distance_interface) / (distance_bulk - distance_interface)
and d
is the distance to the closest material interface. We choose this transition to happen on the order of 2 * d_heater
. We will also exclude using the higher mesh resolution around the wafer since that region is of less interest.
[13]:
# parameters for meshing
dl_min = h_heater / 3
dl_max = 4 * dl_min
grid_spec = td.DistanceUnstructuredGrid(
dl_interface=dl_min,
dl_bulk=dl_max,
distance_interface=3 * dl_min,
distance_bulk=2 * d_heater,
non_refined_structures=["wafer"], # do not refine near wafer
)
Pack components into a heat simulation specification. Note that from the heat transfer perspective the problem is symmetric around \(x=0\). Thus, we can set symmetry specification to (1, 0, 0)
to reduce simulation size and cost.
Given that the problem is two-dimensional we will use a small simulation size along the invariant \(y\)-direction.
[14]:
heat_sim = td.HeatSimulation.from_scene(
scene=scene,
center=(0, 0, z_sim),
size=(w_sim, dl_min, h_sim),
boundary_spec=[bc_bottom, bc_top],
sources=[heater_source],
monitors=[temp_mnt],
symmetry=(1, 0, 0),
grid_spec=grid_spec,
)
15:43:53 CDT WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
[15]:
heat_sim.plot(y=0.01)
plt.show()

Mesh Inspection#
In case the resulting simulation mesh needs to be inspected one can submit the simulation for solving and download directly either mesh alone (“mesh.cgns”) or simulation results sampled together with the mesh (“volume_proc0.vtu”). These files can be inspected using common third-party software like Paraview. In the upcoming Tidy3D version the mesh inspection step will be simplified and optimized.
[16]:
job = web.Job(simulation=heat_sim, task_name="heat_sim_check_mesh")
heat_sim_data = job.run()
15:43:54 CDT Created task 'heat_sim_check_mesh' with task_id 'he-e853c581-7e41-46de-9161-1cfd506adb01v1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
15:43:56 CDT Heat solver status: queued
15:44:01 CDT Heat solver status: preprocess
15:44:20 CDT Heat solver status: running
15:44:26 CDT Heat solver status: postprocess
15:44:34 CDT Heat solver status: success
15:44:36 CDT loading simulation from simulation_data.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
[17]:
_ = web.core.s3utils.download_file(
resource_id=job.task_id,
remote_filename="volume_proc0.vtu",
to_file="./heat_sim_solution.vtu",
verbose=True,
)
Batch Processing of Heat Simulations#
Having ensured that the simulation mesh is suitable for this simulation setup, let us perform a sweep through several values of electric current in the heating strip. To do this we create a dictionary of simulations with different source definitions.
[18]:
currents = np.linspace(1e-10, 7.4e-3, 10)
heat_sims = {}
for ind, current in enumerate(currents):
heat_rate = (current / h_heater / w_heater) ** 2 / TiN_sigma
heater_source = td.UniformHeatSource(rate=heat_rate, structures=[heater.name])
heat_sim_new = heat_sim.updated_copy(sources=[heater_source])
heat_sims[f"heat_wg_current_{ind}"] = heat_sim_new
15:44:38 CDT WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
And submit this dictionary using Batch functionality.
[19]:
batch = web.Batch(simulations=heat_sims)
Created task 'heat_wg_current_0' with task_id 'he-e5487cc9-6200-439a-a294-6a71298303a0v1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
15:44:39 CDT Created task 'heat_wg_current_1' with task_id 'he-6568fb97-9ebd-4bb0-9899-adfb2dab37c0v1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
15:44:40 CDT Created task 'heat_wg_current_2' with task_id 'he-3e3301d5-5314-4afe-b85b-99041ca2ccc9v1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
15:44:41 CDT Created task 'heat_wg_current_3' with task_id 'he-b11255cf-1f8e-4ba2-8641-9317552ae56bv1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
15:44:42 CDT Created task 'heat_wg_current_4' with task_id 'he-1c8f1e45-e9a7-4e8f-8978-81cba46c0807v1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
15:44:43 CDT Created task 'heat_wg_current_5' with task_id 'he-fa32eb95-1385-4a5a-9390-fc4eae9d2a81v1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
15:44:45 CDT Created task 'heat_wg_current_6' with task_id 'he-3b5d6d2e-761e-4bc7-b080-34d4b22bcfb1v1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
15:44:46 CDT Created task 'heat_wg_current_7' with task_id 'he-6bb99901-4870-4a4d-bd06-275ad43e049bv1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
15:44:47 CDT Created task 'heat_wg_current_8' with task_id 'he-eb15d586-c201-415d-a74a-42c9fd0716fav1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
15:44:48 CDT Created task 'heat_wg_current_9' with task_id 'he-d682c15e-9865-4146-bd2a-43f59bd9f115v1' and task_type 'HEAT'.
Tidy3D's heat solver is currently in the beta stage. All heat simulations are charged a flat fee of 0.025 FlexCredit.
[20]:
batch_data = batch.run()
15:44:53 CDT Started working on Batch.
15:44:58 CDT Maximum FlexCredit cost: 0.250 for the whole batch. Use 'Batch.real_cost()' to get the billed FlexCredit cost after the Batch has completed.
15:46:23 CDT Batch complete.
Visualize some of the simulation results.
[21]:
# max temperature value when plotting to enforce the same coloring
temp_max_plot = 340
fig, ax = plt.subplots(1, 3, figsize=(17, 2))
batch_data["heat_wg_current_1"].plot_field("temperature", ax=ax[0], vmax=temp_max_plot)
ax[0].set_title(f"Current I = {currents[1]:1.3} A")
batch_data["heat_wg_current_5"].plot_field("temperature", ax=ax[1], vmax=temp_max_plot)
ax[1].set_title(f"Current I = {currents[5]:1.3} A")
batch_data["heat_wg_current_9"].plot_field("temperature", ax=ax[2], vmax=temp_max_plot)
ax[2].set_title(f"Current I = {currents[9]:1.3} A")
plt.show()
15:46:26 CDT loading simulation from ./he-6568fb97-9ebd-4bb0-9899-adfb2dab37c0v1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
15:46:27 CDT loading simulation from ./he-fa32eb95-1385-4a5a-9390-fc4eae9d2a81v1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
15:46:29 CDT loading simulation from ./he-d682c15e-9865-4146-bd2a-43f59bd9f115v1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.

Coupling to Optic Simulations#
Now let us create optic simulations where material properties are modified according to obtained temperature distributions. One can conveniently do that using method .perturbed_mediums_copy()
of class Scene. We will use obtained optic simulations only to investigate waveguide modes, thus we are defining neither sources nor monitors, and only provide grid specification.
[22]:
wvl_um = 1.55
freq0 = td.C_0 / wvl_um
grid_spec = td.GridSpec.auto(min_steps_per_wvl=50, wavelength=wvl_um)
perturb_sims = []
for _, hs_data in batch_data.items():
pscene = scene.perturbed_mediums_copy(
temperature=hs_data["temperature"].temperature
)
psim = td.Simulation.from_scene(
scene=pscene,
center=(0, 0, z_sim),
size=(w_sim, dl_min, h_sim),
run_time=1e-15,
grid_spec=grid_spec,
)
perturb_sims.append(psim)
15:46:31 CDT loading simulation from ./he-e5487cc9-6200-439a-a294-6a71298303a0v1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
loading simulation from ./he-6568fb97-9ebd-4bb0-9899-adfb2dab37c0v1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
15:46:33 CDT loading simulation from ./he-3e3301d5-5314-4afe-b85b-99041ca2ccc9v1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
15:46:34 CDT loading simulation from ./he-b11255cf-1f8e-4ba2-8641-9317552ae56bv1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
15:46:36 CDT loading simulation from ./he-1c8f1e45-e9a7-4e8f-8978-81cba46c0807v1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
loading simulation from ./he-fa32eb95-1385-4a5a-9390-fc4eae9d2a81v1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
15:46:38 CDT loading simulation from ./he-3b5d6d2e-761e-4bc7-b080-34d4b22bcfb1v1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
15:46:39 CDT loading simulation from ./he-6bb99901-4870-4a4d-bd06-275ad43e049bv1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
15:46:40 CDT loading simulation from ./he-eb15d586-c201-415d-a74a-42c9fd0716fav1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
15:46:41 CDT loading simulation from ./he-d682c15e-9865-4146-bd2a-43f59bd9f115v1.hdf5
WARNING: More than 2 different solid zones (zone = medium + source) are detected in the heat simulation. Make sure no more than 2 solid zones are adjacent to each other anywhere in the simulation domain. The simulation results may be inaccurate otherwise. This restriction will be removed in the upcoming Tidy3D versions.
Define plane where waveguide modes will be calculated.
[23]:
mode_plane = td.Box(center=(0, 0, z_core), size=(4, 0, 3))
Visual inspection.
[24]:
fig, ax = plt.subplots(1, 1)
perturb_sims[0].plot(y=0, ax=ax)
mode_plane.plot(y=0, ax=ax, alpha=0.5)
plt.show()

We will use Tidy3D’s mode solver plugin.
[25]:
from tidy3d.plugins.mode.web import run as run_mode
from tidy3d.plugins.mode import ModeSolver
Find only the first mode at the frequency corresponding to 1.55 um wavelength.
[26]:
mode_datas = []
for psim in perturb_sims:
ms = ModeSolver(
simulation=psim,
plane=mode_plane,
mode_spec=td.ModeSpec(num_modes=1, precision="double"),
freqs=[freq0],
)
md = run_mode(ms)
mode_datas.append(md)
Mode solver created with task_id='fdve-2d530e9f-ce67-4282-ac0a-468870ba8351v1', solver_id='mo-8fbd2e0d-554b-401d-b245-6315195385a1'.
15:46:44 CDT Mode solver status: queued
15:46:45 CDT Mode solver status: running
15:47:00 CDT Mode solver status: success
15:47:04 CDT Mode solver created with task_id='fdve-bd8d8ef8-bbe5-4d3f-9b8b-aeb302f190d3v1', solver_id='mo-f1339b5e-8e09-4ad5-9e4c-cde67344d7b3'.
15:47:08 CDT Mode solver status: queued
15:47:09 CDT Mode solver status: running
15:47:24 CDT Mode solver status: success
15:47:27 CDT Mode solver created with task_id='fdve-bf6babca-6f38-44f3-8da4-2b6526e11822v1', solver_id='mo-ff0a8a84-55d1-40d3-accc-be0abf6ac7a4'.
15:47:30 CDT Mode solver status: queued
15:48:59 CDT Mode solver status: running
15:49:15 CDT Mode solver status: success
15:49:19 CDT Mode solver created with task_id='fdve-f06dd8ec-a46c-4c65-b852-ffdddc9d0ef9v1', solver_id='mo-7911b5d0-c057-4d18-9f24-a21be30d8275'.
15:49:23 CDT Mode solver status: queued
15:49:24 CDT Mode solver status: running
15:49:39 CDT Mode solver status: success
15:49:41 CDT Mode solver created with task_id='fdve-517b8b59-e0ec-4cfd-b0fa-ee1d037ab0b3v1', solver_id='mo-f97bad26-f0da-489e-b1cf-959481459f76'.
15:49:44 CDT Mode solver status: queued
15:49:45 CDT Mode solver status: running
15:49:57 CDT Mode solver status: success
15:50:00 CDT Mode solver created with task_id='fdve-73e7da85-46ed-4197-89c5-f925f81eb394v1', solver_id='mo-ed3f65f3-dcd6-4396-ba81-d40f8177651e'.
15:50:03 CDT Mode solver status: queued
15:50:10 CDT Mode solver status: running
15:50:25 CDT Mode solver status: success
15:50:28 CDT Mode solver created with task_id='fdve-5ee8c5fc-1ad2-4599-bcc5-9d93417c90e3v1', solver_id='mo-f334dca2-686b-4c77-86d3-3c720ba23622'.
15:50:31 CDT Mode solver status: queued
15:50:33 CDT Mode solver status: running
15:50:47 CDT Mode solver status: success
15:50:51 CDT Mode solver created with task_id='fdve-c69ecbb6-0a33-4480-b9ab-d55319bcb5f9v1', solver_id='mo-71621ac9-f796-4c51-937e-e97cd8396d4b'.
15:50:55 CDT Mode solver status: queued
15:50:56 CDT Mode solver status: running
15:51:16 CDT Mode solver status: success
15:51:19 CDT Mode solver created with task_id='fdve-0f9fe98b-199b-482b-bedc-cba6beaabba1v1', solver_id='mo-d186b861-bd6c-4b25-93ca-bafd947a2980'.
15:51:22 CDT Mode solver status: queued
15:51:23 CDT Mode solver status: running
15:51:35 CDT Mode solver status: success
15:51:38 CDT Mode solver created with task_id='fdve-7c710a16-24d4-4f5f-90f8-cc1f32731ef2v1', solver_id='mo-e6d0f8a0-8b41-47af-a85b-7c85a17d6032'.
15:51:43 CDT Mode solver status: queued
Mode solver status: running
15:51:56 CDT Mode solver status: success
Extract found propagation indices into a single array.
[27]:
n_eff = np.array([md.n_eff.isel(f=0, mode_index=0) for md in mode_datas])
We will compare to results obtained using different thermal and mode solvers.
[28]:
currents_ref = np.linspace(0.0, 7.4e-3, 10)
neff_ref = [
2.4401133396065293,
2.440149458129956,
2.440257814666438,
2.4404384121136413,
2.4406912552977094,
2.441016350968344,
2.441413707791896,
2.4418833363425283,
2.4424252490914293,
2.443039460394046,
]
The absolute values of propagation indices are quite sensitive to the type of solver used and parameters of mode solver solution domain. Thus, we compare changes to the propagation indices rather then their absolute values.
[29]:
print(f"Phase shift over 320um: {2 * np.pi / 1.55 * (n_eff[-1] - n_eff[0]) * 320}")
print(
f"Phase shift over 320um (ref): {2 * np.pi / 1.55 * (neff_ref[-1] - neff_ref[0]) * 320}"
)
plt.plot(currents * 1e3, n_eff[:] - n_eff[0], "o:")
plt.plot(currents_ref * 1e3, np.array(neff_ref) - neff_ref[0])
plt.xlabel("Current / mA")
plt.ylabel("Change in effective refractive index $n_{eff}$")
plt.legend(["tidy3d", "reference"])
plt.show()
Phase shift over 320um: 3.807849105815964
Phase shift over 320um (ref): 3.795687048084378

[ ]: