File: mpb_strip.py

package info (click to toggle)
meep-openmpi 1.7.0-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 25,828 kB
  • sloc: cpp: 27,370; python: 10,574; lisp: 1,213; makefile: 437; sh: 28
file content (83 lines) | stat: -rw-r--r-- 3,141 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
from __future__ import division

import meep as mp
from meep import mpb

# Compute modes of a rectangular Si strip waveguide on top of oxide.
# Note that you should only pay attention, here, to the guided modes,
# which are the modes whose frequency falls under the light line --
# that is, frequency < beta / 1.45, where 1.45 is the SiO2 index.

# Since there's no special lengthscale here, I'll just
# use microns.  In general, if you use units of x, the frequencies
# output are equivalent to x/lambda# so here, the freqeuncies will be
# output as um/lambda, e.g. 1.5um would correspond to the frequency
# 1/1.5 = 0.6667.

w = 0.3  # Si width (um)
h = 0.25  # Si height (um)

Si = mp.Medium(index=3.45)
SiO2 = mp.Medium(index=1.45)

# Define the computational cell.  We'll make x the propagation direction.
# the other cell sizes should be big enough so that the boundaries are
# far away from the mode field.
sc_y = 2  # supercell width (um)
sc_z = 2  # supercell height (um)
geometry_lattice = mp.Lattice(size=mp.Vector3(0, sc_y, sc_z))

# define the 2d blocks for the strip and substrate
geometry = [mp.Block(size=mp.Vector3(mp.inf, mp.inf, 0.5 * (sc_z - h)),
                     center=mp.Vector3(z=0.25 * (sc_z + h)), material=SiO2),
            mp.Block(size=mp.Vector3(mp.inf, w, h), material=Si)]

# The k (i.e. beta, i.e. propagation constant) points to look at, in
# units of 2*pi/um.  We'll look at num_k points from k_min to k_max.
num_k = 9
k_min = 0.1
k_max = 3.0
k_points = mp.interpolate(num_k, [mp.Vector3(k_min), mp.Vector3(k_max)])

resolution = 32  # pixels/um

# Increase this to see more modes.  (The guided ones are the ones below the
# light line, i.e. those with frequencies < kmag / 1.45, where kmag
# is the corresponding column in the output if you grep for "freqs:".)
num_bands = 4

filename_prefix = 'strip-'  # use this prefix for output files

ms = mpb.ModeSolver(
    geometry_lattice=geometry_lattice,
    geometry=geometry,
    k_points=k_points,
    resolution=resolution,
    num_bands=num_bands,
    filename_prefix=filename_prefix
)


def main():
    # compute num_bands lowest frequencies as a function of k. Also display
    # "parities", i.e. whether the mode is symmetric or anti_symmetric
    # through the y=0 and z=0 planes.
    ms.run(mpb.display_yparities, mpb.display_zparities)

    ###########################################################################

    # Above, we outputted the dispersion relation: frequency (omega) as a
    # function of wavevector kx (beta).  Alternatively, you can compute
    # beta for a given omega -- for example, you might want to find the
    # modes and wavevectors at a fixed wavelength of 1.55 microns.  You
    # can do that using the find_k function:

    omega = 1 / 1.55  # frequency corresponding to 1.55um

    # Output the x component of the Poynting vector for num_bands bands at omega
    ms.find_k(mp.NO_PARITY, omega, 1, num_bands, mp.Vector3(1), 1e-3, omega * 3.45,
              omega * 0.1, omega * 4, mpb.output_poynting_x, mpb.display_yparities,
              mpb.display_group_velocities)

if __name__ == '__main__':
    main()