Adiabatic operation slope-loss algorithm (AO-SLA), how to do it: adiabatic coupling

2 次查看(过去 30 天)
I would like to write a code that can implement the equations of this paper: Adiabatic operation slope-loss algorithm for ultrashort and broadband waveguide taper
I tried it in python but it did not improve my coupling efficiency at all, mayba I am doing something wrong... Here it is my python code:
import sys
sys.path.append(r"C:\Program Files\Lumerical\v241\api\python")
import lumapi
import numpy as np
def create_adiabatic_taper(fdtd, width_input, width_output, alpha, lambda_0, n_eff):
# Define the number of segments to approximate the adiabatic taper
num_segments = 100
L_i_segments = np.zeros(num_segments)
# Widths for each section
widths = np.linspace(width_input, width_output, num_segments + 1)
vertices_x = []
vertices_y = []
for i in range(num_segments):
W1 = widths[i]
W2 = widths[i + 1]
W0 = (W1 + W2) / 2
epsilon = 1e-10 # Small value to prevent division by zero or very small numbers
theta = alpha * lambda_0 / (2 * (W0 + epsilon) * n_eff)
# Prevent theta from becoming too small
if np.abs(theta) < 1e-10:
theta = np.sign(theta) * 1e-10
L_i = (W1 - W2) / (2 * np.tan(theta))
# Ensure L_i is not negative
if L_i < 0:
L_i = 0
L_i_segments[i] = L_i
if i == 0:
vertices_x.append(0)
vertices_y.append(W1 / 2) # For half width
vertices_x.append(sum(L_i_segments[:i+1]))
vertices_y.append(W2 / 2) # For half width
vertices_x = np.array(vertices_x)
vertices_y = np.array(vertices_y)
vertices_x_full = np.concatenate([vertices_x, vertices_x[::-1]])
vertices_y_full = np.concatenate([vertices_y, -vertices_y[::-1]])
vertices = np.vstack((vertices_x_full, vertices_y_full)).T
print("L_i_segments:", L_i_segments)
print("Vertices X:", vertices_x_full)
print("Vertices Y:", vertices_y_full)
# Create the polygon
fdtd.addpoly(
x=0, # Center of the polygon in the x-direction
y=0, # Center of the polygon in the y-direction
z=0, # Center of the polygon in the z-direction
vertices=vertices, # Vertices of the polygon
material="Si (Silicon) - Palik",
name="adiabatic_taper_polygon"
)
fdtd.addtogroup("::model::Taper")
fdtd = lumapi.FDTD()
fdtd.selectall()
fdtd.delete()
# Parameters for the adiabatic taper
wavelength = 1550e-9 # Operating wavelength in meters
width_input = 0.5e-6 # Width of the input waveguide in meters
width_output = 0.075e-6 # Width of the output waveguide in meters
alpha = 1 # Slope angle in degrees
lambda_0 = 1550e-9 # Center wavelength in meters
n_eff = 3.47 # Effective index of the cross-section at the center of the taper
# Create the adiabatic taper
create_adiabatic_taper(fdtd, width_input, width_output, alpha, lambda_0, n_eff)

回答(2 个)

Umar
Umar 2024-6-30
Hi Tay,
The calculation of the variable L_i is incorrect, leading to negative values for some segments. This causes an error when trying to create the polygon.
To fix the issue, you need to modify the calculation of L_i to ensure that it is always positive. You can achieve this by taking the absolute value of the difference between W1 and W2 before dividing by 2 * np.tan(theta).
Replace the following line:
L_i = (W1 - W2) / (2 * np.tan(theta))
with:
L_i = np.abs(W1 - W2) / (2 * np.tan(theta))
This modification ensures that L_i is always positive, preventing any negative values.
Hope this will help resolve your problem.
  2 个评论
Tay
Tay 2024-7-1
Thank you so much for replying :).
Yeah, indeed, so I should delete the lines?
# Ensure L_i is not negative
if L_i < 0:
L_i = 0
Tay
Tay 2024-7-1
I did a quick test by deleting the lines I mentioned and replacing by abs values the line you recommended, and i think still we have some negatives values there, because the shape has a deepth in there.

请先登录,再进行评论。


Umar
Umar 2024-7-1

Hi Tay,

I took the liberty of modifying your code after reviewing it, try this updated version and let me know if it works for you.

import sys sys.path.append(r"C:\Program Files\Lumerical\v241\api\python") import lumapi import numpy as np

def create_adiabatic_taper(fdtd, width_input, width_output, alpha, lambda_0, n_eff): # Define the number of segments to approximate the adiabatic taper num_segments = 100 L_i_segments = np.zeros(num_segments)

    # Widths for each section 
    widths = np.linspace(width_input, width_output, num_segments + 1)
    vertices_x = []
    vertices_y = []
    for i in range(num_segments):
        W1 = widths[i]
        W2 = widths[i + 1]
        W0 = (W1 + W2) / 2
        epsilon = 1e-10  # Small value to prevent division by zero or very small numbers
        theta = alpha * lambda_0 / (2 * (W0 + epsilon) * n_eff)
        # Prevent theta from becoming too small
        if np.abs(theta) < 1e-10:
            theta = np.sign(theta) * 1e-10
        L_i = np.abs(W1 - W2) / (2 * np.tan(theta))
        L_i_segments[i] = L_i
        if i == 0:
            vertices_x.append(0)
            vertices_y.append(W1 / 2)  # For half width
        vertices_x.append(sum(L_i_segments[:i+1]))
        vertices_y.append(W2 / 2)  # For half width
    vertices_x = np.array(vertices_x)
    vertices_y = np.array(vertices_y)
    vertices_x_full = np.concatenate([vertices_x, vertices_x[::-1]])
    vertices_y_full = np.concatenate([vertices_y, -vertices_y[::-1]])
    vertices = np.vstack((vertices_x_full, vertices_y_full)).T
    print("L_i_segments:", L_i_segments)
    print("Vertices X:", vertices_x_full)
    print("Vertices Y:", vertices_y_full)
    # Create the polygon 
    fdtd.addpoly(
        x=0,  # Center of the polygon in the x-direction
        y=0,  # Center of the polygon in the y-direction
        z=0,  # Center of the polygon in the z-direction
        vertices=vertices,  # Vertices of the polygon
        material="Si (Silicon) - Palik",
        name="adiabatic_taper_polygon"
    )
    fdtd.addtogroup("::model::Taper")

fdtd = lumapi.FDTD() fdtd.selectall() fdtd.delete()

  1. Parameters for the adiabatic taper wavelength = 1550e-9 # Operating wavelength in meters width_input = 0.5e-6 # Width of the input waveguide in meters width_output = 0.075e-6 # Width of the output waveguide in meters alpha = 1 # Slope angle in degrees lambda_0 = 1550e-9 # Center wavelength in meters n_eff = 3.47 # Effective index of the cross-section at the center of the taper
  1. Create the adiabatic taper create_adiabatic_taper(fdtd, width_input, width_output, alpha, lambda_0, n_eff)

Hopefully, this code should now correctly calculate the length of each segment of the adiabatic taper without producing negative values.

类别

Help CenterFile Exchange 中查找有关 Call Python from MATLAB 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by