DOCUMENTATION
Get started.
Download a working layout and run your first prediction. Then adapt the example to your own GDS.
01 / YOUR FIRST PREDICTION
Run the Y-branch splitter.
- 1. Install the package Use Python 3.9 or later. Open a terminal and run
python -m pip install --upgrade bamsolve. NumPy is installed with the package. - 2. Get your key Enter your email in the key form. Copy the key shown on the page. The script will ask for it in the terminal.
- 3. Download two files Save ebeam_y_1550.gds and quickstart.py in the same folder. No GDS editor or generator is required.
- 4. Run the script Open that folder in your terminal and run
python quickstart.py. Paste your key at the prompt and press Enter. The key is hidden while you enter it. Wait for the response; the script makes one prediction request. - 5. Read the result The script prints the full S-matrix power ratios and saves
ebeam_y_1550.s3pplusebeam_y_1550_result.npzbeside the GDS. The Y-branch has three ports, sores.S.shapeis(1, 3, 3)at one wavelength. - 6. Check the export (optional) Download read_result.py. Install
scikit-rf, then use--check-touchstoneas shown below. This independent file reader compares the exported S-matrix and frequencies with the saved arrays. It makes no API request.
# Run these commands in your terminal.
python -m pip install --upgrade bamsolve
# Open the folder with both downloaded files.
python quickstart.py
# Paste your key when the hidden prompt appears.
# The script saves:
# ebeam_y_1550.s3p
# ebeam_y_1550_result.npz
The sample is a silicon Y-branch about 15 µm long, with a 0.22 µm thickness. The request uses TE polarization at 1.55 µm.
Port 1 is opt1 at the left end. Ports 2 and 3 are opt2 and opt3 at the upper and lower right ends. abs(res.S[0, 1, 0])**2 and abs(res.S[0, 2, 0])**2 give the power ratios into the two arms.
The default API address is https://api.bamsolve.com. You can also set BAMSOLVE_API_KEY before running the script to use an existing key without a prompt.
Why use a Y-branch for this tutorial?
A 3D FDTD model must include the branch junction, both output arms, the surrounding cladding, and the waveguide thickness. A direct full three-port S-matrix calculation also needs a separate excitation at each port. This adds simulation volume and repeated runs compared with the simple straight-guide check. Runtime depends on mesh resolution, the stopping rule, and hardware. See the Meep introduction for background on FDTD grids and time steps.
02 / DOWNLOADS
Try another layout.
- Main example · Y-branch with three ports Download GDS. Markers:
opt1 (1, 10)at the left end,opt2 (1, 11)at the upper right,opt3 (1, 12)at the lower right. - Optional simple check · straight waveguide Download GDS · Download its gdstk generator. Markers:
opt1 (1, 10)at the left end,opt2 (1, 11)at the right end. - Scripts Run a prediction · Read or plot saved results. Save the reader beside your result file. Reading a saved file makes no API request.
# Inspect the saved Y-branch result (the default).
python read_result.py
# Optional: check the exported S-matrix and frequencies.
python -m pip install scikit-rf
python read_result.py --check-touchstone
# Optional: save a field plot as a PNG.
python -m pip install matplotlib
python read_result.py --plot
# Optional: run the simpler straight-guide check.
python quickstart.py straight_10um.gds
python read_result.py straight_10um_result.npz
# Optional: rebuild the straight GDS locally.
python -m pip install gdstk
python make_straight.py
The optional straight guide is 10 µm × 0.5 µm. It produces an S array with shape (1, 2, 2) and a .s2p file. The plot reader uses |E|² / max(|E|²), so its colors show relative intensity.
03 / GDS LAYOUT
Prepare your own GDS.
The supplied examples use one silicon core layer. Start with this layout convention before you change the material or geometry.
- Waveguide geometry — (1, 0) A pair means
(layer, datatype). Draw the core on(1, 0)and map that pair to aLayerinStack. The examples use micrometres and a 1 nm GDS precision. Use one core material and one vertical layer for this tutorial. - Port markers — one pair per port Put a short GDS path at each waveguide end, centred on the end face. Use
(1, 10),(1, 11), then(1, 12). The generator usessimple_path=Trueso gdstk writes PATH records. - Name and select ports Put a text label such as
opt1at each marker, with the same layer and texttype. The supplied examples useopt1,opt2, andopt3. Pass the exact marker pair topred()to select the input for the returned field. - Mark every external port Markers identify the ports used for the S-matrix and field selection. A marker is not a promise of zero reflection or an absorbing boundary condition.
EXAMPLE / 1×2 Y-BRANCH SPLITTER
Diagram only. Download the GDS above for the actual geometry and markers.
04 / PYTHON API
The code inside the starter.
This basic request uses the downloaded Y-branch. Run it from the folder that contains the GDS.
- 1. Stack Set the cladding index and core refractive index.
z=(0.0, 0.22)gives the bottom and top in µm. The default sidewall angle is zero degrees. - 2. Device Call the stack with the GDS path. This combines the layer mapping and the layout.
- 3. Predict Each input is
(port_layer_pair, polarization, wavelength). The wavelength is in µm. Use"TE"or"TM"; request one polarization at a time for this example.
from getpass import getpass
from bamsolve import Layer, Stack, bamsolve, pred
bamsolve(api_key=getpass("API key: "))
stack = Stack(clad=1.444, layers={
(1, 0): Layer(n=3.48, z=(0.0, 0.22)),
})
dev = stack("ebeam_y_1550.gds")
res = pred(dev, inputs={((1, 10), "TE", 1.55)})
res.export_s("ebeam_y_1550.s3p")
05 / OUTPUTS
Read fields and S-parameters.
- Full S-matrix
res.Sis complex, with shape(wavelength, output_port, input_port). All input columns are calculated. The supplied examples use port orderopt1, opt2oropt1, opt2, opt3. Indices start at zero. - Power ratios
abs(res.S[0, 1, 0])**2gives transmission from port 1 to port 2 at the first wavelength. Diagonal entries give reflection at each port. - Field and coordinates
res.Eis a complex array with shape(len(res.y), len(res.x)). Coordinates are in µm. For the basic request, the field is foropt1at 1.55 µm. - Multiple inputs or wavelengths For a wavelength sweep, pass a tuple such as
(1.53, 1.55, 1.57). The S wavelength axis is in ascending wavelength order. The returned field uses the first input after sorting by port pair, then polarization; for a wavelength tuple it uses the middle entry. Request one input and one wavelength when you need an unambiguous field view. - Effective index and exports
res.n_effis the dimensionless effective index at each wavelength.res.export_s()saves Touchstone. Use.s2pfor two ports or.s3pfor three.
import numpy as np
print(res.S.shape)
print("Port 1 to port 2:", abs(res.S[0, 1, 0])**2)
print("Port 1 to port 3:", abs(res.S[0, 2, 0])**2)
print("Port 1 reflection:", abs(res.S[0, 0, 0])**2)
print("Field shape:", res.E.shape)
print("Effective index:", res.n_eff)
# Optional plot dependency:
# python -m pip install matplotlib
import matplotlib.pyplot as plt
plt.pcolormesh(res.x, res.y, np.abs(res.E)**2,
shading="auto")
plt.xlabel("x (µm)")
plt.ylabel("y (µm)")
plt.axis("equal")
plt.show()
To inspect an earlier run without a new request, use read_result.py with the saved _result.npz file.