def get_simulation(
r: float = r_cav, # Cavity radius.
p: float = p_bragg, # Cavity period.
w: float = w_bragg, # Etched width.
h: float = 0.0, # Non-etched thickness with respect to TiO2 thickness.
tsio2: float = t_sio2, # SiO2 layer thickness.
dcf: float = d_cf, # Cavity to fiber distance.
) -> td.Simulation:
"""Create a Simulation of a bullseye cavity with variable geometry and material thickness."""
# Computational domain size.
size_x = 2 * pml_spacing + max(2 * (r + n_bragg * p), 2 * r_core)
size_y = size_x
size_z = pml_spacing + tsio2 + t_tio2 + dcf
center_z = -size_z / 2
qd_pos_z = tsio2 + t_tio2
mon_pos_z = size_z - pml_spacing / 2
# Point dipole source located at the center of TiO2 thin film.
dp_source = td.PointDipole(
center=(0, 0, qd_pos_z),
source_time=td.GaussianPulse(freq0=freq, fwidth=freqw),
polarization="Ey",
)
# Field monitor to visualize the fields in xy plane.
field_monitor_xy = td.FieldMonitor(
center=(0, 0, qd_pos_z - t_tio2 / 2),
size=(size_x, size_y, 0),
freqs=[freq],
name="field_xy",
)
# Field monitor to visualize the fields in xz plane.
field_monitor_xz = td.FieldMonitor(
center=(0, 0.05, size_z / 2),
size=(size_x, 0, size_z),
freqs=[freq],
name="field_xz",
)
# Mode monitor to get the power coupled into the fiber modes.
mode_spec = td.ModeSpec(num_modes=1, target_neff=n_core)
mode_monitor = td.ModeMonitor(
center=(0, 0, mon_pos_z),
size=(size_x, size_y, 0),
freqs=freqs,
mode_spec=mode_spec,
name="mode_fiber",
)
# Flux monitor to get the total dipole power.
flux_dip = td.FluxMonitor(
center=(0, 0, size_z / 2),
size=(0.8 * size_x, 0.8 * size_y, size_z),
freqs=freqs,
exclude_surfaces=("z-",),
name="flux_dip",
)
# Silicon dioxide layer
sio2_layer = td.Structure(
geometry=td.Box.from_bounds(
rmin=(-size_x / 2 - eff_inf, -size_y / 2 - eff_inf, -eff_inf),
rmax=(size_x / 2 + eff_inf, size_y / 2 + eff_inf, tsio2),
),
medium=mat_sio2,
)
# Fiber cladding
fiber_clad = td.Structure(
geometry=td.Box.from_bounds(
rmin=(-size_x / 2 - eff_inf, -size_y / 2 - eff_inf, size_z - pml_spacing),
rmax=(size_x / 2 + eff_inf, size_y / 2 + eff_inf, size_z + eff_inf),
),
medium=mat_clad,
)
# Fiber core
fiber_core = td.Structure(
geometry=td.Cylinder(
radius=r_core,
center=(0, 0, size_z + (((pml_spacing + eff_inf) / 2) - pml_spacing)),
axis=2,
length=pml_spacing + eff_inf,
),
medium=mat_core,
)
# Bullseye cavity
bullseye = []
cyl_rad = n_bragg * p + r
for _ in range(0, n_bragg):
bullseye.append(
td.Structure(
geometry=td.Cylinder(
radius=cyl_rad,
center=(0, 0, qd_pos_z - t_tio2 / 2),
axis=2,
length=t_tio2,
),
medium=mat_tio2,
)
)
bullseye.append(
td.Structure(
geometry=td.Cylinder(
radius=cyl_rad - p + w,
center=(0, 0, qd_pos_z - t_tio2 / 2),
axis=2,
length=t_tio2,
),
medium=mat_etch,
)
)
cyl_rad -= p
bullseye.append(
td.Structure(
geometry=td.Cylinder(
radius=r, center=(0, 0, qd_pos_z - t_tio2 / 2), axis=2, length=t_tio2
),
medium=mat_tio2,
)
)
# Non-etched TiO2 region.
if h > 0:
bullseye.append(
td.Structure(
geometry=td.Box.from_bounds(
rmin=(-size_x / 2 - eff_inf, -size_y / 2 - eff_inf, tsio2),
rmax=(
size_x / 2 + eff_inf,
size_y / 2 + eff_inf,
tsio2 + h * t_tio2,
),
),
medium=mat_tio2,
)
)
# Simulation definition
sim = td.Simulation(
center=(0, 0, -center_z),
size=(size_x, size_y, size_z),
medium=mat_etch,
grid_spec=td.GridSpec.auto(min_steps_per_wvl=15, wavelength=wl),
structures=[sio2_layer, fiber_clad, fiber_core] + bullseye,
sources=[dp_source],
normalize_index=0,
monitors=[field_monitor_xy, field_monitor_xz, mode_monitor, flux_dip],
boundary_spec=td.BoundarySpec(
x=td.Boundary.pml(),
y=td.Boundary.pml(),
z=td.Boundary(minus=td.PECBoundary(), plus=td.PML()),
),
symmetry=(1, -1, 0),
run_time=run_time,
)
return sim