GUI Simulation Guide: Creating Shapes and Running Simulations
Time: 45 minutes
Difficulty: Intermediate
Prerequisites: Basic Python, familiarity with electromagnetic simulations
Learning Objectives
By the end of this tutorial, you will:
✓ Understand the Prismo GUI interface (Lumerical-style)
✓ Create a new simulation using the GUI
✓ Add geometric shapes (Box, Sphere, Cylinder, Polygon)
✓ Assign materials to shapes
✓ Add sources (PlaneWave, GaussianBeam, ModeSource)
✓ Add monitors (FieldMonitor, FluxMonitor)
✓ Use the 3D viewport with slice planes
✓ Run simulations and view results
Overview
This guide will walk you through creating a complete simulation using Prismo’s GUI. We’ll build a waveguide structure with proper materials, sources, and monitors - similar to how you would use Lumerical FDTD Solutions.
The Prismo GUI provides:
3D Viewport: Interactive 3D visualization of your simulation geometry with embedded viewport controls
Slice Planes: Cut through your geometry to inspect interior structures (XY, XZ, YZ planes)
Shape Dialog: Interactive dialog for creating geometric shapes (Box, Sphere, Cylinder) with material assignment
Results Viewer: Built-in viewer for visualizing field data, spectra, S-parameters, and time series
Simulation Control: Run, stop, and reset simulations with progress monitoring
Step 1: Launch the GUI
Start the Prismo GUI from the command line:
prismo gui
Or from Python:
from prismo.gui import MainWindow
window = MainWindow()
window.show()
The main window will open with:
Left Panel: Embedded 3D Viewport with slice plane controls
Right Panel:
Geometry panel with shape list and “Add Shape” button
Property plotter for material visualization
Results Viewer for simulation results
Top Menu: File operations, simulation control, view options
Step 2: Create a New Simulation
When you first launch the GUI, a default simulation is created automatically. To create a new simulation:
Click File → New Simulation, or
Click the New button in the toolbar
This creates a fresh simulation with default parameters:
Size: 10µm × 10µm × 1µm
Resolution: 20 points per micrometer
Boundary conditions: PML (Perfectly Matched Layer)
Step 3: Understanding the 3D Viewport
The 3D viewport displays your simulation geometry. To open the interactive 3D window:
Click “Open 3D View” button in the viewport panel
A separate window will open with the 3D visualization
The viewport supports:
Mouse Interaction:
Left-click drag: Rotate view
Right-click drag: Pan view
Scroll wheel: Zoom in/out
Slice Planes: Cut through geometry to see cross-sections
Reset Camera: Return to default viewing angle
Step 4: Using Slice Planes
Slice planes let you inspect the interior of your geometry, just like in Lumerical.
Enable Slice Planes
In the “Slice Planes” section:
XY Plane (horizontal slice): Check the box to enable
Use the Z Position slider to move the slice up/down
XZ Plane (vertical along y): Enable and adjust Y Position
YZ Plane (vertical along x): Enable and adjust X Position
You can enable multiple slice planes simultaneously to see different cross-sections.
Example: To see the middle of a waveguide:
# In the GUI, enable XY slice plane
# Set Z Position to 0.5e-6 (middle of 1µm thick structure)
Step 5: Creating Geometric Shapes
The GUI provides two ways to add shapes: through the interactive Shape Dialog or programmatically via Python code.
Adding Shapes via GUI (Shape Dialog)
The easiest way to add shapes is using the built-in Shape Dialog:
Click the “Add Shape” button in the Geometry panel (right side)
A dialog window will open with options to create:
Box (Rectangle): Rectangular structures like waveguides
Sphere (Ball): Spherical structures
Cylinder (Tube): Cylindrical waveguides or structures
Configure Shape Parameters:
Position: Set center coordinates (X, Y, Z) in meters
Size/Dimensions:
For Box: Width (X), Height (Y), Depth (Z)
For Sphere: Radius
For Cylinder: Radius, Height, and Axis orientation
Material: Select from library materials (Si, SiO2, Au, etc.) or enter custom permittivity
Click “Create Shape” to add it to your simulation
The shape will immediately appear in the 3D viewport, and you can see it listed in the Geometry panel.
Adding Shapes Programmatically
You can also add shapes via Python code for more control or automation:
Box (Rectangular Structure)
from prismo import Simulation, Box, Material
# Create simulation
sim = Simulation(
size=(10.0e-6, 5.0e-6, 1.0e-6),
resolution=20.0e6,
)
# Define material
silicon = Material(name="Si", epsilon_r=12.0)
# Create a waveguide box
waveguide = Box(
material=silicon,
center=(5.0e-6, 2.5e-6, 0.5e-6), # Center position
size=(8.0e-6, 0.5e-6, 0.22e-6), # Length, width, height
)
# Add to simulation
sim.add_shape(waveguide)
# Update GUI viewport (if using GUI)
# viewport.sync_with_simulation(sim)
Sphere
from prismo import Sphere
# Create a spherical structure
sphere = Sphere(
material=silicon,
center=(5.0e-6, 2.5e-6, 0.5e-6),
radius=0.5e-6,
)
sim.add_shape(sphere)
Cylinder
from prismo import Cylinder
# Create a cylindrical waveguide
cylinder = Cylinder(
material=silicon,
center=(5.0e-6, 2.5e-6, 0.5e-6),
radius=0.25e-6,
height=1.0e-6,
axis="z", # Orientation: "x", "y", or "z"
)
sim.add_shape(cylinder)
Polygon (Custom 2D Shape)
from prismo import Polygon
import numpy as np
# Define polygon vertices (2D, will be extruded)
vertices = np.array([
[1.0e-6, 1.0e-6],
[3.0e-6, 1.0e-6],
[3.0e-6, 2.0e-6],
[2.0e-6, 3.0e-6],
[1.0e-6, 2.0e-6],
])
polygon = Polygon(
material=silicon,
vertices=vertices,
z_min=0.0, # Bottom of extrusion
z_max=0.22e-6, # Top of extrusion
)
sim.add_shape(polygon)
Multiple Materials
You can add multiple shapes with different materials:
from prismo import Material
# Define materials
silicon = Material(name="Si", epsilon_r=12.0)
oxide = Material(name="SiO2", epsilon_r=2.25)
# Substrate
substrate = Box(
material=oxide,
center=(5.0e-6, 2.5e-6, 0.0),
size=(10.0e-6, 5.0e-6, 0.5e-6),
)
# Waveguide on top
waveguide = Box(
material=silicon,
center=(5.0e-6, 2.5e-6, 0.61e-6),
size=(8.0e-6, 0.5e-6, 0.22e-6),
)
sim.add_shape(substrate)
sim.add_shape(waveguide)
Step 6: Adding Sources
Sources excite electromagnetic fields in your simulation.
Plane Wave Source
from prismo import PlaneWaveSource
# Create a plane wave source
source = PlaneWaveSource(
center=(1.0e-6, 2.5e-6, 0.5e-6),
size=(0.0, 5.0e-6, 1.0e-6), # Cross-sectional area
direction="x", # Propagation direction
polarization="y", # E-field polarization
frequency=193.4e12, # 1550 nm (193.4 THz)
amplitude=1.0,
)
sim.add_source(source)
Gaussian Beam Source
from prismo import GaussianBeamSource
# Create a Gaussian beam
source = GaussianBeamSource(
center=(1.0e-6, 2.5e-6, 0.5e-6),
size=(0.0, 1.0e-6, 0.0), # Line source
direction="x",
polarization="y",
frequency=193.4e12,
beam_waist=0.5e-6, # Beam waist radius
pulse=True, # Use Gaussian pulse
pulse_width=10e-15, # Pulse width (10 fs)
amplitude=1.0,
)
sim.add_source(source)
Mode Source (Waveguide Mode Launcher)
from prismo import ModeSource
# Create a mode source that launches a waveguide mode
source = ModeSource(
center=(1.0e-6, 2.5e-6, 0.5e-6),
size=(0.0, 1.0e-6, 0.22e-6), # Cross-section
direction="x",
mode_index=0, # Fundamental mode
frequency=193.4e12,
amplitude=1.0,
)
sim.add_source(source)
Step 7: Adding Monitors
Monitors record field data during the simulation.
Field Monitor
Record electric and magnetic fields:
from prismo import FieldMonitor
# Create a field monitor
monitor = FieldMonitor(
center=(5.0e-6, 2.5e-6, 0.5e-6),
size=(8.0e-6, 3.0e-6, 0.22e-6),
components=["Ey", "Hz"], # Components to record
time_domain=True, # Record time-domain data
frequencies=[193.4e12], # Also do DFT at this frequency
name="field_monitor",
)
sim.add_monitor(monitor)
Monitor Types by Size:
Point Monitor:
size=(0, 0, 0)- Single locationLine Monitor:
size=(Lx, 0, 0)- 1D profilePlane Monitor:
size=(Lx, Ly, 0)- 2D sliceVolume Monitor:
size=(Lx, Ly, Lz)- Full 3D region
Flux Monitor
Record power flow:
from prismo import FluxMonitor
# Monitor power transmission
flux_monitor = FluxMonitor(
center=(9.0e-6, 2.5e-6, 0.5e-6),
size=(0.0, 1.0e-6, 0.22e-6),
direction="x", # Direction of power flow
frequencies=[193.4e12],
name="transmission",
)
sim.add_monitor(flux_monitor)
Multiple Monitors
You can add multiple monitors to track different regions:
# Input monitor
input_monitor = FieldMonitor(
center=(1.0e-6, 2.5e-6, 0.5e-6),
size=(0.0, 1.0e-6, 0.22e-6),
components="all",
frequencies=[193.4e12],
name="input",
)
# Output monitor
output_monitor = FieldMonitor(
center=(9.0e-6, 2.5e-6, 0.5e-6),
size=(0.0, 1.0e-6, 0.22e-6),
components="all",
frequencies=[193.4e12],
name="output",
)
sim.add_monitor(input_monitor)
sim.add_monitor(output_monitor)
Step 8: Setting Simulation Parameters
Before running, configure simulation parameters:
Simulation Size and Resolution
sim = Simulation(
size=(10.0e-6, 5.0e-6, 1.0e-6), # Physical size (m)
resolution=20.0e6, # Points per meter
boundary_conditions="pml", # PML absorbing boundaries
pml_layers=10, # Number of PML layers
courant_factor=0.9, # Time step safety factor
)
Resolution Guidelines:
Higher resolution = more accurate but slower
Typical: 20-50 points per wavelength
For 1550 nm light: ~20-50 points per micrometer
Boundary Conditions
PML: Absorbing boundaries (recommended)
Periodic: Periodic boundary conditions
Reflecting: Perfect electric/magnetic conductors
Step 9: Viewing Geometry in the GUI
After adding shapes, sources, and monitors:
Sync Viewport: The GUI automatically updates when you sync:
# In your code, after adding shapes
viewport.sync_with_simulation(sim)
Open 3D View: Click “Open 3D View” to see:
Shapes: Colored by material (permittivity-based colors)
Sources: Green wireframe boxes or red spheres
Monitors: Yellow wireframe boxes
Use Slice Planes:
Enable XY plane to see horizontal cross-section
Adjust Z position to slice through different heights
Enable multiple planes for different views
Step 10: Running the Simulation
From Code
import time
# Define progress callback
def progress(step, total_steps, sim_time, elapsed_time):
if step % 100 == 0:
print(f"Step {step}/{total_steps} ({step/total_steps*100:.1f}%)")
# Run simulation
sim_time = 100e-15 # 100 femtoseconds
sim.run(sim_time, progress_callback=progress)
print(f"Simulation completed in {sim.current_time*1e15:.1f} fs")
From GUI
Click Simulation → Run or the Run button
Progress will be shown in the status bar
Click Stop to interrupt the simulation
Step 11: Viewing Results
After the simulation completes, you can view results both in the GUI and programmatically.
Viewing Results in GUI (Results Viewer)
The GUI includes a built-in Results Viewer for interactive visualization:
Open Results Viewer: Expand the “Results Viewer” section in the right panel
Load Results: You have two options:
Load from Monitor: Click “Load from Monitor” to load data directly from a monitor in your simulation
Load from File: Click “Load Results…” to load previously saved results from CSV or Parquet files
Visualize Data: The Results Viewer supports:
Field Plots: 2D field distributions with colormaps
Spectra: Frequency-domain power spectra
S-Parameters: Reflection and transmission coefficients
Time Series: Time-domain field evolution
Interactive Controls:
Select different field components (Ex, Ey, Ez, Hx, Hy, Hz)
Adjust colormap and scaling
Zoom and pan in plots
Retrieve Field Data Programmatically
# Get time-domain field data
time_points, field_data = monitor.get_time_data("Ey")
# Get frequency-domain data
field_at_freq = monitor.get_frequency_data("Ey", frequency=193.4e12)
# Plot with matplotlib
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.imshow(field_data[-1], cmap="RdBu_r", origin="lower")
plt.colorbar(label="Ey (V/m)")
plt.xlabel("x (grid points)")
plt.ylabel("y (grid points)")
plt.title("Electric Field Ey at Final Time")
plt.show()
Retrieve Flux Data
# Get power transmission
transmission = flux_monitor.get_frequency_domain_power(frequency=193.4e12)
print(f"Transmission: {transmission:.4f}")
Saving and Loading Results
You can save results to files for later analysis:
# Export to CSV
from prismo.io.exporters import CSVExporter
exporter = CSVExporter()
exporter.export_spectrum(monitor, "results.csv")
# Later, load in GUI using "Load Results..." button
Complete Example
Here’s a complete example combining everything:
from prismo import (
Simulation, Box, Material,
GaussianBeamSource, FieldMonitor, FluxMonitor
)
# Create simulation
sim = Simulation(
size=(10.0e-6, 5.0e-6, 1.0e-6),
resolution=20.0e6,
)
# Materials
silicon = Material(name="Si", epsilon_r=12.0)
oxide = Material(name="SiO2", epsilon_r=2.25)
# Substrate
substrate = Box(
material=oxide,
center=(5.0e-6, 2.5e-6, 0.0),
size=(10.0e-6, 5.0e-6, 0.5e-6),
)
# Waveguide
waveguide = Box(
material=silicon,
center=(5.0e-6, 2.5e-6, 0.61e-6),
size=(8.0e-6, 0.5e-6, 0.22e-6),
)
sim.add_shape(substrate)
sim.add_shape(waveguide)
# Source
freq = 193.4e12 # 1550 nm
source = GaussianBeamSource(
center=(1.0e-6, 2.5e-6, 0.5e-6),
size=(0.0, 1.0e-6, 0.0),
direction="x",
polarization="y",
frequency=freq,
beam_waist=0.5e-6,
pulse=True,
pulse_width=10e-15,
)
sim.add_source(source)
# Monitors
field_monitor = FieldMonitor(
center=(5.0e-6, 2.5e-6, 0.5e-6),
size=(8.0e-6, 3.0e-6, 0.22e-6),
components=["Ey"],
time_domain=True,
frequencies=[freq],
)
flux_monitor = FluxMonitor(
center=(9.0e-6, 2.5e-6, 0.5e-6),
size=(0.0, 1.0e-6, 0.22e-6),
direction="x",
frequencies=[freq],
)
sim.add_monitor(field_monitor)
sim.add_monitor(flux_monitor)
# Run simulation
sim.run(100e-15)
# View results
time_points, field_data = field_monitor.get_time_data("Ey")
print(f"Field monitor recorded {len(time_points)} time steps")
Tips and Best Practices
Start Simple: Begin with a single shape and source to verify setup
Use Appropriate Resolution:
Too low: Inaccurate results
Too high: Slow simulation
Rule of thumb: 20-30 points per wavelength
Monitor Placement:
Place monitors away from sources to avoid artifacts
Use multiple monitors to track field evolution
Slice Planes:
Use slice planes to verify geometry is correct
Check material boundaries before running
Material Properties:
Verify epsilon_r values match your materials
Use library materials when possible:
prismo.get_material("Si")
Simulation Time:
Run long enough for fields to propagate and settle
Typical: 10-100 femtoseconds for photonic structures
Troubleshooting
Problem: Viewport shows nothing
Solution: Ensure you’ve added shapes and synced with simulation
Problem: Slice planes don’t appear
Solution: Make sure “Open 3D View” is clicked and slice plane checkbox is enabled
Problem: Simulation is very slow
Solution: Reduce resolution or simulation size
Problem: Fields look incorrect
Solution: Check material properties, source frequency, and monitor placement
Next Steps
Now that you understand the basics:
Explore advanced features in the Advanced Guide
Learn about Mode Analysis
Check out S-Parameter Extraction