Co-planar Waveguide in RF Photonics 2: Segmented Electrodes

The co-planar waveguide (CPW) is a transmission line commonly used in RF photonics due to its compact planar nature, ease of fabrication, and resistance to external EM interference. In this notebook series, we will examine the CPW in the context of a Mach-Zehnder modulator (MZM).
In part one, we started with a simple CPW on a dielectric substrate. The goal of the notebook is to demonstrate the typical 2D and 3D workflow of modeling transmission lines in Flex RF.
In part two (this notebook), we will simulate the CPW with the MZM optical waveguide. A 2D mode analysis will first be performed on the conventional straight CPW layout, followed by a 3D simulation of a segmented electrode design. In the final section, we compare the Flexcompute RF solver next to experimental results from R&D developments of a Lithium Tantalate–based PDK at Luxtelligence SA.
The segmented electrode design aims to address two key shortcomings of the conventional CPW: velocity mismatch and metallic loss. It is formed by adding T-shaped metal electrodes to the gaps in a conventional CPW. The effective RF index can be tuned by changing the T-electrode geometry, thus allowing for ideal velocity matching between the electrical and optical signals. The T-electrodes also spread the RF surface current outwards away from the gap, effectively increasing conductor area and reducing overall loss. At the same time, the CPW gap remains narrow in order to maintain a strong RF field for optical modulation.
import matplotlib.pyplot as pltimport numpy as npimport flex_rf.tidy3d as rfimport flex_rf.web as webrf.config.logging.level = 'ERROR'Key Parameters and Mediums
Section titled “Key Parameters and Mediums”We define some general model parameters below. The analysis bandwidth is between 1 and 65 GHz.
# Frequency rangef_min, f_max = (1e9, 65e9)f0 = (f_min + f_max) / 2freqs = np.linspace(f_min, f_max, 101)The material properties are defined below. The optical waveguide is made of thin-film lithium niobate (TFLN) with SiO2 cladding. The substrate is made of quartz. The metal CPW electrodes are made of gold.

The anisotropic TFLN is implemented with the AnisotropicMedium feature.
We assume gold to be the only lossy medium in this study, as conductor losses typically dominate in the bandwidth of interest. In order to implement constant loss over the frequency range, we use LossyMetalMedium which implements a surface impedance model (SIBC) with constant conductivity.
# Mediumsmed_air = rf.Medium(permittivity=1, name="Air")med_SiO2 = rf.Medium(permittivity=3.8, name="SiO2")med_Qz = rf.Medium(permittivity=4.5, name="Quartz")med_LN_o = rf.Medium(permittivity=44, name="TFLN ord.")med_LN_eo = rf.Medium(permittivity=27.9, name="TFLN extraord.")med_LN = rf.AnisotropicMedium(xx=med_LN_eo, yy=med_LN_o, zz=med_LN_o, name="TFLN")med_Au = rf.LossyMetalMedium(conductivity=41, frequency_range=(f_min, f_max), name="Gold")Conventional MZM-CPW (2D Analysis)
Section titled “Conventional MZM-CPW (2D Analysis)”Geometry
Section titled “Geometry”In this section, we will construct a conventional CPW with a gap size of 5 um. The relevant geometry parameters are defined below. All lengths are in microns.
# Layer thicknesseslen_inf = 1e5 # effective infinitytm = 1 # metaltsio21 = 0.2 # SiO2 cladding layertsio20 = 2 # SiO2 BOX layertln0 = 0.6 # TFLN layer un-etchedtln1 = 0.3 # TFLN layer etchedtqz = len_inf # substrate layer
# CPW dimensionsg = 5 # CPW gapws = 100 # Width of signal tracewg = 300 # Width of ground tracew_cpw = ws + 2 * (g + wg) # Overall span of CPW
# TFLN optical waveguide dimensionsw0 = 1 # Core widththetaln = 30 / 180 * np.pi # Sidewall angle, radiansw1 = 1000 # Overall width of layersWe start by creating Structure instances for each dielectric material layer.
# Define dielectric layersstr_sio2_clad = rf.Structure( medium=med_SiO2, geometry=rf.Box(center=(0, 0, (tln0 - tln1) + tsio21 / 2.0), size=(w1, rf.inf, tsio21)),)str_sio2_box = rf.Structure( medium=med_SiO2, geometry=rf.Box(center=(0, 0, -tsio20 / 2.0), size=(w1, rf.inf, tsio20)))str_qz = rf.Structure( medium=med_Qz, geometry=rf.Box(center=(0, 0, -tqz / 2.0 + tsio20 / 2 - tm / 2), size=(w1, rf.inf, tqz)),)str_ln_layer = rf.Structure( medium=med_LN, geometry=rf.Box(center=(0, 0, tln1 / 2.0), size=(w1, rf.inf, tln1)))structures_layers = [str_qz, str_sio2_clad, str_sio2_box, str_ln_layer]We use a user-defined function to create the CPW structures.
def create_cpw(gap, width, width_gnd, thickness, start, end): """create a centered cpw with specified parameters""" length = end - start midpos = (end + start) / 2 str_c1 = rf.Structure( medium=med_Au, geometry=rf.Box( size=(width_gnd, length, thickness), center=(-width / 2 - gap - width_gnd / 2, midpos, tln0 - tln1 + tsio21 + tm / 2.0), ), ) str_c2 = rf.Structure( medium=med_Au, geometry=rf.Box( size=(width_gnd, length, thickness), center=(width / 2 + gap + width_gnd / 2, midpos, tln0 - tln1 + tsio21 + tm / 2.0), ), ) str_sig = rf.Structure( medium=med_Au, geometry=rf.Box( size=(width, length, thickness), center=(0, midpos, tln0 - tln1 + tsio21 + tm / 2.0) ), ) return [str_c1, str_c2, str_sig]
# Create CPW structurestr_cpw_conventional = create_cpw(g, ws, wg, tm, -len_inf, len_inf)The optical waveguide is also created using a parametrized function.
def create_rib_structure(width, height, sidewall_angle, center, medium): """Create a pair of ribs with given top width, height, sidewall angle and center position (mirrored in x)""" x0, y0 = center geom1 = rf.PolySlab( axis=2, sidewall_angle=sidewall_angle, reference_plane="top", slab_bounds=(y0 - height / 2, y0 + height / 2), vertices=[ (x0 + width / 2, len_inf), (x0 - width / 2, len_inf), (x0 - width / 2, -len_inf), (x0 + width / 2, -len_inf), ], ) geom2 = geom1.translated(-2 * x0, 0, 0) geoms = rf.GeometryGroup(geometries=[geom1, geom2]) return rf.Structure(geometry=geoms, medium=medium)
# Create optical waveguide and cladding structurestr_optical_wg = create_rib_structure( w0, tln0 - tln1, thetaln, ((ws + g) / 2, tln0 - tln1 / 2.0), med_LN)str_optical_wg_clad = create_rib_structure( 1.2 * w0, tln0 - tln1, thetaln, ((ws + g) / 2, tln0 - tln1 / 2.0 + tsio21), med_SiO2)structures_optical = [str_optical_wg_clad, str_optical_wg]All structures are collected in a list.
structures_list_cpw_conventional = structures_layers + structures_optical + str_cpw_conventionalWe can set up a test Scene to visualize the structures.
test_scene = rf.Scene(medium=med_air, structures=structures_list_cpw_conventional)# Plot the test sceneypos = 0fig, ax = plt.subplots(2, 1, figsize=(10, 5), tight_layout=True)test_scene.plot(y=ypos, hlim=(-g - ws, g + ws), vlim=(-10, 5), ax=ax[0])ax[0].set_aspect(1)test_scene.plot(y=ypos, hlim=((g + ws) / 2 - 10, (g + ws) / 2 + 10), vlim=(-3, 2), ax=ax[1])plt.show()
Grid and Boundary Conditions
Section titled “Grid and Boundary Conditions”The simulation domain is surrounded by Perfectly Matched Layers (PMLs) on all side by default. We add a quarter-wavelength padding on all sides to ensure that they do not encroach on the near-field.
# Define simulation sizepadding = rf.C_0 / f_max / 4sim_LX = w_cpw + 2 * paddingsim_LY = sim_LXsim_LZ = sim_LXWe make use of LayerRefinementSpec to refine the grid near the metallic CPW structures.
# Layer refinement around conductorsLR_spec_1 = rf.LayerRefinementSpec.from_structures( structures=str_cpw_conventional, min_steps_along_axis=5, refinement_inside_sim_only=False, corner_refinement=rf.GridRefinement(dl=tm / 5, num_cells=2),)Additionally, we will also define a mesh refinement box around the optical waveguide for more accurate results.
# Mesh override structure around optical waveguide corerefine_box = rf.MeshOverrideStructure( geometry=rf.Box(center=((ws + g) / 2, 0, (tln1) / 2), size=(1.2 * w0, rf.inf, (tln1))), dl=(w0 / 5.0, None, tln1 / 5.0),)The rest of the grid is automatically generated according to the wavelength.
# Define overall grid specificationgrid_spec = rf.GridSpec.auto( wavelength=rf.C_0 / f_max, min_steps_per_wvl=20, override_structures=[refine_box], layer_refinement_specs=[LR_spec_1],)Wave Ports
Section titled “Wave Ports”We define a dummy WavePort in order to facilitate the setup of the 2D mode analysis.
# Wave port dimensionswp_center = (0, 0, 1)wp_size = (w_cpw - 15, 0, w_cpw - 15)
# Define wave portWP_dummy = rf.WavePort( center=wp_center, size=wp_size, mode_spec=rf.MicrowaveModeSpec(target_neff=np.sqrt(8)), direction="+", name="Dummy WP",)Mode Solver
Section titled “Mode Solver”As in the first notebook, we will conduct a 2D mode analysis to obtain key transmission line parameters.
# Define base mode solver simulationms_sim = rf.Simulation( size=(sim_LX, sim_LY, sim_LZ), medium=med_air, grid_spec=grid_spec, structures=structures_list_cpw_conventional, symmetry=(1, 0, 0), run_time=1e-10,)
# Define mode solvermode_solver = WP_dummy.to_mode_solver(simulation=ms_sim, freqs=freqs)Before running, let us preview the transverse grid near the optical waveguide to ensure that it is suitably refined.
# Plot transverse gridfig, ax = plt.subplots(figsize=(12, 4))ms_sim.plot(y=0, ax=ax)ms_sim.plot_grid(y=0, ax=ax, hlim=(ws / 2 - 5, ws / 2 + g + 5), vlim=(-1, 2))plt.show()
We run the mode solver below.
mode_data = web.run(mode_solver, task_name="mode solver", path="data/mode_data.hdf5", verbose=False)2D Results
Section titled “2D Results”Mode Profile
Section titled “Mode Profile”The field magnitude profile in one of the CPW gaps is shown below.
# Plot the mode fieldfig, ax = plt.subplots(figsize=(8, 4), tight_layout=True)mode_solver.plot_field(field_name="E", val="abs", scale="dB", f=40e9, ax=ax, vmax=10, vmin=-20)ax.set_xlim(ws / 2 - 5, ws / 2 + g + 5)ax.set_ylim(-2, 5)plt.show()
Effective Index, Attenuation, and Characteristic Impedance
Section titled “Effective Index, Attenuation, and Characteristic Impedance”The key properties that determine a guided mode are effective index , attenuation , and characteristic impedance . We demonstrate how to obtain those values below. We also extract the complex propagation constant . Note the use of the -np.conjugate() operation to convert from physics phase convention (default in Flex RF) to engineering convention.
# Gather alpha, neff from mode solver resultsneff_mode = mode_data.modes_info["n eff"].squeeze()alphadB_mode = mode_data.modes_info["loss (dB/cm)"].squeeze()
# Get gamma in 1/mmgamma_mode = -np.conjugate(mode_data.gamma).squeeze() * 1e-3The characteristic line impedance is retrieved from the mode solver data as well.
# Retrieve the characteristic impedance from the mode impedance.Z0_mode = np.conjugate(mode_data.transmission_line_data.Z0.isel(mode_index=0)).squeeze()These values are plotted below.
fig, ax = plt.subplots(3, 1, figsize=(8,8), tight_layout=True)ax[0].set_title("Effective index")ax[0].plot(freqs / 1e9, neff_mode)ax[1].set_title("Attenuation (dB/cm)")ax[1].plot(freqs / 1e9, alphadB_mode)ax[2].set_title("Real impedance (Ohm)")ax[2].plot(freqs / 1e9, np.real(Z0_mode))for axis in ax: axis.grid() axis.set_xlabel("f (GHz)")plt.show()
Distributed Transmission Line Parameters (RLCG)
Section titled “Distributed Transmission Line Parameters (RLCG)”Using the complex propagation constant and the line impedance , we can calculate the RLCG parameters using the following relationships:
where . Since the dielectrics are lossless, we can omit .
R_mode = np.real(gamma_mode * Z0_mode) # Ohm/mmL_mode = np.imag(gamma_mode * Z0_mode) / (2 * np.pi * freqs) # H/mmC_mode = np.imag(gamma_mode / Z0_mode) / (2 * np.pi * freqs) # F/mm# Plot RLCGfig, ax = plt.subplots(1,3 , figsize=(10, 4), tight_layout=False)ax[0].plot(freqs / 1e9, R_mode)ax[1].plot(freqs / 1e9, L_mode * 1e9)ax[2].plot(freqs / 1e9, C_mode * 1e12)titles = ["R (Ohm/mm)", "L (nH/mm)", "C (pF/mm)"]for ii, title in enumerate(titles): ax[ii].set_title(title) ax[ii].set_xlabel("f (GHz)") ax[ii].grid()plt.show()
Segmented Electrodes (3D analysis)
Section titled “Segmented Electrodes (3D analysis)”Geometry
Section titled “Geometry”
The T-electrode geometry parameters are defined below. The rest of the dimensions are identical to those defined previously. Because the segmented CPW is longitudinally inhomogeneous, we will be using short sections of conventional CPW on both ends to excite the structure.
# Define T-electrode dimensionss, r = (2, 45) # width and length, top of Th, t = (6, 2) # width and length, neck of Tc = 5 # gap between T unitsP = r + c # T electrode periodgw = g + 2 * (s + h) # CPW gap including electrodes
# Define line lengthsLTL = 20 * P # Length of segmented lineLin = 7 * P # CPW length, input sectionLout = 7 * P # CPW length, output sectionWe make use of parameterized functions to create the T-electrode and segmented CPW.
def create_T_structure(base_position, direction, width_r, width_t, width_s, width_h): """Create a T-shaped electrode""" x0, y0 = base_position sgn = 1 if direction == "+" else -1
geom_T = [ rf.Box( size=(width_s, width_r, tm), center=(x0 + sgn * (width_h + width_s / 2), y0, tln0 - tln1 + tsio21 + tm / 2.0), ), rf.Box( size=(width_h, width_t, tm), center=(x0 + sgn * width_h / 2, y0, tln0 - tln1 + tsio21 + tm / 2.0), ), ]
return geom_Tdef create_segmented_cpw(r, t, s, h, g, ws, P, L): """Creates segmented CPW and optical waveguide core/cladding""" gw = g + 2 * (s + h) # CPW gap including electrodes
# Optical WG Core + Cladding wg_core = create_rib_structure( w0, tln0 - tln1, thetaln, ((ws + gw) / 2, tln0 - tln1 / 2.0), med_LN ) wg_clad = create_rib_structure( 1.2 * w0, tln0 - tln1, thetaln, ((ws + gw) / 2, tln0 - tln1 / 2.0 + tsio21), med_SiO2 )
# Wide CPW in segmented section cpw_list_wide = create_cpw(gw, ws, wg - (s + h), tm, -len_inf, len_inf)
# Narrow CPW for input/output section cpw_list_narrow = create_cpw(g, ws + 2 * (s + h), wg, tm, -len_inf, -L / 2) + create_cpw( g, ws + 2 * (s + h), wg, tm, L / 2, len_inf )
# T-segments num_units = int(L / P) T_geom_list = [] for ii in range(num_units + 1): xx0, xx1, xx2, xx3 = (-ws / 2 - gw, -ws / 2, ws / 2, ws / 2 + gw) yy = -P * num_units / 2 + (ii) * P T_geom_list += create_T_structure((xx0, yy), "+", r, t, s, h) T_geom_list += create_T_structure((xx1, yy), "-", r, t, s, h) T_geom_list += create_T_structure((xx2, yy), "+", r, t, s, h) T_geom_list += create_T_structure((xx3, yy), "-", r, t, s, h) T_structure = rf.Structure(medium=med_Au, geometry=rf.GeometryGroup(geometries=T_geom_list))
return [wg_core, wg_clad, T_structure] + cpw_list_wide + cpw_list_narrow
# Create segmented CPWstructures_cpw_segmented = create_segmented_cpw(r, t, s, h, g, ws, P, LTL)
# Combine list of structuresstructures_list_cpw_segmented = structures_layers + structures_cpw_segmentedGrid and Boundary
Section titled “Grid and Boundary”The simulation size is defined below.
# Simulation dimensionssim_size = (sim_LX, LTL + Lin + Lout, sim_LZ)sim_center = (0, -(Lin - Lout) / 2, 0)We use the same grid refinement strategy as before. For 3D simulation, usually a lower level of refinement is necessary to achieve converged S-parameter results.
# Layer refinement around conductorsLR_spec_2 = rf.LayerRefinementSpec( center=(0, 0, 1), size=(rf.inf, rf.inf, 1), axis=2, corner_refinement=rf.GridRefinement(dl=tm, num_cells=2), refinement_inside_sim_only=False,)
refine_box_2 = rf.MeshOverrideStructure( geometry=rf.Box(center=((ws + gw) / 2, 0, (tln1) / 2), size=(1.2 * w0, rf.inf, (tln1))), dl=(w0 / 5.0, None, tln0 / 2),)# Define grid specgrid_spec_2 = rf.GridSpec.auto( wavelength=rf.C_0 / f_max, min_steps_per_wvl=20, override_structures=[refine_box_2], layer_refinement_specs=[LR_spec_2],)Wave Ports and Monitors
Section titled “Wave Ports and Monitors”The two wave ports are positioned along the input and output sections of the conventional CPW with a 100 micron spacing to the segmented structure.
wp_offset = 100 # wave port offset
# Define wave portsWP1 = rf.WavePort( name="WP1", center=(0, -LTL / 2 - wp_offset, 1), size=wp_size, mode_spec=rf.MicrowaveModeSpec(target_neff=np.sqrt(8)), direction="+",)WP2 = WP1.updated_copy( name="WP2", center=(0, LTL / 2 + wp_offset, 0), direction="-",)We define a field monitor for visualization purposes.
# Define monitorsmon_field1 = rf.FieldMonitor( center=(0, 0, 1), size=(w_cpw, len_inf, 0), freqs=[f_min, f0, f_max], name="field cpw plane",)
monitors_list = [mon_field1]Define Simulation and TerminalComponentModeler
Section titled “Define Simulation and TerminalComponentModeler”# Define base simulationsim = rf.Simulation( center=sim_center, size=sim_size, grid_spec=grid_spec_2, structures=structures_list_cpw_segmented, monitors=monitors_list, run_time=2e-10, symmetry=(1, 0, 0),)# Define TerminalComponentModelertcm = rf.TerminalComponentModeler( simulation=sim, ports=[WP1, WP2], freqs=freqs, run_only=["WP1@0"],)Visualization
Section titled “Visualization”We plot the transverse and longitudinal cross sections to check that the structures and grid are properly set up.
# Plot structure/grid in CPW gapfig, ax = plt.subplots(figsize=(12, 4))sim.plot(y=0, ax=ax)sim.plot_grid(y=0, ax=ax, hlim=(ws / 2, ws / 2 + gw), vlim=(-0.5, 2))plt.show()
# Plot structure/grid in metal planefig, ax = plt.subplots(1, 2, figsize=(10, 10), tight_layout=True)tcm.plot_sim( z=1.1, ax=ax[0], hlim=(-gw - ws, gw + ws), vlim=(-LTL / 2 - Lin, LTL / 2 + Lout),)# sim.plot_grid(z=1.1, hlim=(-gw-ws, gw+ws), vlim=(-LTL/2-Lin,LTL/2+Lout), ax=ax[0])ax[0].set_aspect(0.3)
tcm.plot_sim(z=1.1, ax=ax[1])sim.plot_grid( z=1.1, hlim=((gw + ws) / 2 - 15, (gw + ws) / 2 + 15), vlim=(-LTL / 2, -LTL / 2 + 2 * P), ax=ax[1],)plt.show()
Run Simulation
Section titled “Run Simulation”tcm_data = web.run(tcm, task_name="segmented cpw", path="data/segmented_cpw.hdf5", verbose=False)Results
Section titled “Results”Field Profile
Section titled “Field Profile”First, let us take a look at the field monitor data. The field magnitude in the CPW gap is shown below.
# Load simulation data from TCM datasim_data = tcm_data.data["WP1@0"]
# longitudinal fieldfig, ax = plt.subplots(figsize=(14, 10))f_plot = f_maxsim_data.plot_field("field cpw plane", field_name="E", val="abs", ax=ax, f=f_plot)ax.set_xlim(-100, 100)ax.set_ylim(-1000, 1000)ax.set_aspect(0.1)plt.show()
S-parameters
Section titled “S-parameters”The S-matrix can be calculated using the smatrix() method. We also define several convenience functions to get a specific S_ij in different formats.
# Calculate S-matrix datasetsmat = tcm_data.smatrix()
# Convenience functionsdef sparam(i, j): return np.conjugate(smat.data.isel(port_in=j - 1, port_out=i - 1))
def sparam_abs(i, j): return np.abs(sparam(i, j))
def sparam_dB(i, j): return 20 * np.log10(sparam_abs(i, j))The return and insertion loss (in dB) are plotted below.
fig, ax = plt.subplots(2, 1, figsize=(8, 6), tight_layout=True)ax[0].set_title("Insertion loss")ax[0].plot(freqs / 1e9, sparam_dB(2, 1))
ax[1].set_title("Return loss")ax[1].plot(freqs / 1e9, sparam_dB(1, 1))for axis in ax: axis.grid() axis.set_xlabel("f (GHz)") axis.set_ylabel("dB")plt.show()
Experimental verification of TFLT segmented CPW with Luxtelligence SA
Section titled “Experimental verification of TFLT segmented CPW with Luxtelligence SA”In collaboration with Luxtelligence SA (LXT), we used the RF solver to simulate a range of segmented electrode designs in their thin-film lithium tantalate (TFLT) platform. The results were compared against measurements and simulations on other commercial software performed by LXT.
Compared to lithium niobate, thin-film lithium tantalate offers a five-fold improvement in hour-scale bias stability, supports modulation down to tens of hertz, exhibits approximately twenty-times lower birefringence, provides nearly double the optical power damage threshold, and features a larger bandgap. Together, these properties make thin-film lithium tantalate a very promising platform for advanced telecommunication and datacom components, such as arrayed waveguide gratings (AWGs); enable dispersion engineering for optical-comb generation; and support high-performance frequency-metrology systems, as well as quantum applications operating across the visible-to-telecom wavelength range.
In a separate Flex RF mode solver simulation, the group index of the fundamental TE mode of the TFLT ridge waveguide (based on the ltoi300 PDK of LXT) was calculated. The waveguide has dimensions given by a total height of 300 nm, slab thickness of 120 nm, and ridge width of 2.5 um. The simulations were performed at 1550 nm (C-band) and 1310 nm (O-band), and the group index was calculated to be 2.11 and 2.175 respectively. For more information about the stack, please contact Luxtelligence SA.
The high-frequency RF effective index should match the optical group index to enable high-speed data transmission. We performed a sweep of 12 T-rail designs from LXT (A1-A13; A7 omitted) and sought to match the effective index at the RF frequency of 67 GHz. The results are presented below alongside actual measurement data from LXT. Additionally, results from a similar calculation performed by LXT using a different commercial EM solver are also included.
# Import LXT data_, neff_lxt_tidy3d, neff_lxt_comm, neff_lxt_exp = np.genfromtxt( "misc/cpw_lxt_data.csv", skip_header=1, delimiter=",", unpack=True)device_labels = ["A1", "A2", "A3", "A4", "A5", "A6", "A8", "A9", "A10", "A11", "A12", "A13"]
# Create comparison plotfig, ax = plt.subplots(figsize=(10, 4), tight_layout=True)ax.plot(neff_lxt_tidy3d, "-x", label="Flexcompute RF Solver")ax.plot(neff_lxt_comm, "-o", color="gray", label="LXT simulated")ax.plot(neff_lxt_exp, "-^", color="red", label="LXT measurement average")ax.axhline(2.11, ls="--", color="#bbbbbb", label="C-band Target (n_group = 2.11)")ax.axhline(2.175, ls=":", color="#999999", label="O-band Target (n_group = 2.175)")
ax.set_ylabel("Effective RF index")ax.set_xlabel("Device ID")ax.set_xticks(np.arange(0, 12, 1))ax.set_xticklabels(device_labels, rotation=45, ha="right")ax.grid()ax.legend()plt.show()
Conclusion
Section titled “Conclusion”In this notebook, we studied the CPW in the context of a Mach-Zehnder modulator. We simulated two different configurations, namely the conventional straight CPW and segmented electrodes design, and obtained key transmission line parameters. Additionally, we also performed experimental verification of the RF solver using designs and measurement data from LXT.