The source files for all examples can be found in /examples.
Mode converter design setup
We show how to setup the problem data to design a mode converter, as we do in Bounds on Efficiency Metrics in Photonics.
# Import the packages
using WaveOperators
using PlotsConstructing the design region
First we set basic parameters of our design region and the simulation grid.
n = 50 # Number of gridpoints per unit length
width, height = 2, 1 # Width and height of the domain
k = 2π # Wavenumber of the domain
# Construct grid
g = Grid(height, width, 1/n, k);Next, we add the waveguide slab, centered, of length height/2 and width height/3. We set the material contrast to be 5.
contrast = 5
waveguide = Slab(height/2, height/3)
set_contrast!(g, waveguide, contrast)Finally we define the design region itself, centered on the domain, of size 2/3*height by height.
d_height = 2*height/3
d_width = width/2
x_pos = height/2 - d_height/2
y_pos = width/2 - d_width/2
design_region = Rectangle((x_pos, y_pos), (d_height, d_width))
# Set the maximum allowable contrast for the design region
set_contrast!(g, design_region, contrast)
heatmap(g.contrast, title="Design Region")
Adding an input field
With our design region defined, we now add the input mode to the design region.
mode_input_position = 0
input_mode = 1
input_line = VerticalLine(mode_input_position)
mode = add_mode!(g, input_line, input_mode);We can visualize the amplitude of this mode.
modes = compute_modes(g, input_line)
mode_in = modes.vectors[:, input_mode]
plot(abs.(mode_in), grid=false, legend=false,lw=3, color=:black)
And the resulting field. (Note, we haven't designed anything yet!)
solution = solve(g)
heatmap(abs.(solution))
For a nicer looking plot (like the ones we used in the paper), we can interpolate:
using Interpolations: LinearInterpolation
function interpolate(img; factor=8, ylims=(0,2), xlims=(0,2))
xx = range(xlims..., size(img, 1))
yy = range(ylims..., size(img, 2))
itp = LinearInterpolation((xx,yy), img)
x2 = range(xlims..., size(img, 1)*factor)
y2 = range(ylims..., size(img, 2)*factor)
return [itp(x, y) for x in x2, y in y2]
end
heatmap(interpolate(abs.(solution)))
Defining the objective
For a mode converter, we want to measure correlation with some predefined output mode at a target (in this case, the RHS of the domain.) See section 1.1 of our paper.
# Make a target line at the right hand side of the domain
target_line = VerticalLine(width)
# Generate the Green's function for the problem
g_functions = generate_G(g, design_region, target_line)
# Compute the desired output mode vector
modes = compute_modes(g, target_line)
output_mode = 2
c = modes.vectors[:, output_mode];The desired output mode is plotted below:
out_fig = plot(abs.(c), grid=false, legend=false, lw=3, color=:black)
Making a design
We can use the tools in PhysicalBounds.jl to create a design. Below, we show how to use the optimal value of the optimization problem to set the design from our variable vector $\theta$.
# Usually θ would be replaced by a real design. Here we use a 'random' design.
# See PhysicalBounds.jl for a complete example.
designidx = getindices(g, design_region)
θ = rand(length(designidx))
# Set the contrast to be the design's
g.contrast[designidx] .*= θ
heatmap(g.contrast, title="Design Region")
Solve for the new design's fields
solution_new = solve(g)
heatmap(abs.(solution_new))
This page was generated using Literate.jl.