Example #1
0
import meep as mp
import math

resolution = 20  # pixels/um

nglass = 1.5
glass = mp.Medium(index=nglass)

dsub = 3  # substrate thickness
dair = 3  # air padding between grating and pml
gp = 10.0  # grating period
gh = 0.5  # grating height
gdc = 0.5  # grating duty cycle

lambda_min = 0.4  # vacuum wavelength
lambda_max = 0.8  # vacuum wavelength
fmin = 1 / lambda_max
fmax = 1 / lambda_min
fcen = 0.5 * (fmin + fmax)
df = fmax - fmin

dpml = lambda_max  # PML thickness
sx = dpml + dsub + gh + dair + dpml
sy = gp

cell_size = mp.Vector3(sx, sy, 0)
pml_layers = [mp.PML(thickness=dpml, direction=mp.X)]

geometry = [
    mp.Block(material=glass,
             size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),
Example #2
0
 def test_extra_materials(self):
     sim = self.init_simple_simulation()
     sim.extra_materials = [mp.Medium(epsilon=5), mp.Medium(epsilon=10)]
     sim.run(mp.at_end(lambda sim: None), until=5)
Example #3
0
nr = 0.9999432732358271
ni = 6.7430E-06
real_epsilon = nr**2 - ni**2
imag_epsilon = 2*nr*ni
conductivity=2 * np.pi * f *imag_epsilon / (real_epsilon*8.85e-12)

# real_ind = 1 - 1.1676e-5
# imag_ind = 3.9765e-7
# real_epsilon = real_ind**2 - imag_ind**2
# imag_epsilon = 2*real_ind*imag_ind
# omega = 2*np.pi*f*1e10
# conductivity = omega*imag_epsilon
# factor = (1e-10/3e8)/(real_epsilon*8.85e-12)
# D_conductivity = factor*conductivity

mat = mp.Medium(epsilon=real_epsilon, D_conductivity=conductivity)

# geometry = [mp.Sphere(radius=SphereRadius, material=mat)]
geometry = []

# geometry = [mp.Block(mp.Vector3(SphereRadius,SphereRadius,SphereRadius),
#                      center=mp.Vector3(),
#                      material=mat)]



# sources = [mp.Source(mp.GaussianSource(f, fwidth=df),
#                      component=mp.Ez,
#                      center=mp.Vector3(-sx/2),
#                      size=mp.Vector3(y=sy, z=sz)),
#             mp.Source(mp.GaussianSource(f, fwidth=df),
Example #4
0
sy = 32  # size of cell in Y direction
cell = mp.Vector3(sx, sy, 0)

dpml = 1.0
pml_layers = [mp.PML(dpml)]

pad = 4  # padding distance between waveguide and cell edge
w = 1  # width of waveguide

wvg_xcen = 0.5 * (sx - w - 2 * pad)  # x center of vert. wvg
wvg_ycen = -0.5 * (sy - w - 2 * pad)  # y center of horiz. wvg

geometry = [
    mp.Block(size=mp.Vector3(mp.inf, w, mp.inf),
             center=mp.Vector3(0, wvg_ycen, 0),
             material=mp.Medium(epsilon=12))
]

fcen = 0.15  # pulse center frequency
df = 0.1  # pulse width (in frequency)

sources = [
    mp.Source(mp.GaussianSource(fcen, fwidth=df),
              component=mp.Ez,
              center=mp.Vector3(-0.5 * sx + dpml, wvg_ycen, 0),
              size=mp.Vector3(0, w, 0))
]

sim = mp.Simulation(cell_size=cell,
                    boundary_layers=pml_layers,
                    geometry=geometry,
Example #5
0
def compute_resonant_mode(res, default_mat=False):
    cell_size = mp.Vector3(1, 1, 0)

    rad = 0.301943

    fcen = 0.3
    df = 0.2 * fcen
    sources = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Hz,
                  center=mp.Vector3(-0.1057, 0.2094, 0))
    ]

    k_point = mp.Vector3(0.3892, 0.1597, 0)

    design_shape = mp.Vector3(1, 1, 0)
    design_region_resolution = 50
    Nx = int(design_region_resolution * design_shape.x)
    Ny = int(design_region_resolution * design_shape.y)
    x = np.linspace(-0.5 * design_shape.x, 0.5 * design_shape.x, Nx)
    y = np.linspace(-0.5 * design_shape.y, 0.5 * design_shape.y, Ny)
    xv, yv = np.meshgrid(x, y)
    design_params = np.sqrt(np.square(xv) + np.square(yv)) < rad
    filtered_design_params = gaussian_filter(design_params,
                                             sigma=3.0,
                                             output=np.double)

    matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny),
                              mp.air,
                              mp.Medium(index=3.5),
                              weights=filtered_design_params,
                              do_averaging=True,
                              beta=1000,
                              eta=0.5)

    geometry = [
        mp.Block(center=mp.Vector3(),
                 size=mp.Vector3(design_shape.x, design_shape.y, 0),
                 material=matgrid)
    ]

    sim = mp.Simulation(
        resolution=res,
        cell_size=cell_size,
        default_material=matgrid if default_mat else mp.Medium(),
        geometry=geometry if not default_mat else [],
        sources=sources,
        k_point=k_point)

    h = mp.Harminv(mp.Hz, mp.Vector3(0.3718, -0.2076), fcen, df)
    sim.run(mp.after_sources(h), until_after_sources=200)

    try:
        for m in h.modes:
            print("harminv:, {}, {}, {}".format(res, m.freq, m.Q))
        freq = h.modes[0].freq
    except:
        print("No resonant modes found.")

    sim.reset_meep()
    return freq
Example #6
0
def pol_grating(d,ph,gp,nmode):
    sx = dpml+dsub+d+d+dpad+dpml
    sy = gp

    cell_size = mp.Vector3(sx,sy,0)
    pml_layers = [mp.PML(thickness=dpml,direction=mp.X)]

    # twist angle of nematic director; from equation 1b
    def phi(p):
        xx  = p.x-(-0.5*sx+dpml+dsub)
        if (xx >= 0) and (xx <= d):
            return math.pi*p.y/gp + ph*xx/d
        else:
            return math.pi*p.y/gp - ph*xx/d + 2*ph

    # return the anisotropic permittivity tensor for a uniaxial, twisted nematic liquid crystal
    def lc_mat(p):
        # rotation matrix for rotation around x axis
        Rx = mp.Matrix(mp.Vector3(1,0,0),mp.Vector3(0,math.cos(phi(p)),math.sin(phi(p))),mp.Vector3(0,-math.sin(phi(p)),math.cos(phi(p))))
        lc_epsilon = Rx * epsilon_diag * Rx.transpose()
        lc_epsilon_diag = mp.Vector3(lc_epsilon[0].x,lc_epsilon[1].y,lc_epsilon[2].z)
        lc_epsilon_offdiag = mp.Vector3(lc_epsilon[1].x,lc_epsilon[2].x,lc_epsilon[2].y)
        return mp.Medium(epsilon_diag=lc_epsilon_diag,epsilon_offdiag=lc_epsilon_offdiag)

    geometry = [mp.Block(center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub)),size=mp.Vector3(dpml+dsub,mp.inf,mp.inf),material=mp.Medium(index=n_0)),
                mp.Block(center=mp.Vector3(-0.5*sx+dpml+dsub+d),size=mp.Vector3(2*d,mp.inf,mp.inf),material=lc_mat)]

    # linear-polarized planewave pulse source
    src_pt = mp.Vector3(-0.5*sx+dpml+0.3*dsub,0,0)
    sources = [mp.Source(mp.GaussianSource(fcen,fwidth=0.05*fcen), component=mp.Ez, center=src_pt, size=mp.Vector3(0,sy,0)),
               mp.Source(mp.GaussianSource(fcen,fwidth=0.05*fcen), component=mp.Ey, center=src_pt, size=mp.Vector3(0,sy,0))]

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell_size,
                        boundary_layers=pml_layers,
                        k_point=k_point,
                        sources=sources,
                        default_material=mp.Medium(index=n_0))

    refl_pt = mp.Vector3(-0.5*sx+dpml+0.5*dsub,0,0)
    refl_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=refl_pt, size=mp.Vector3(0,sy,0)))

    sim.run(until_after_sources=100)

    input_flux = mp.get_fluxes(refl_flux)
    input_flux_data = sim.get_flux_data(refl_flux)

    sim.reset_meep()

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell_size,
                        boundary_layers=pml_layers,
                        k_point=k_point,
                        sources=sources,
                        geometry=geometry)

    refl_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=refl_pt, size=mp.Vector3(0,sy,0)))
    sim.load_minus_flux_data(refl_flux,input_flux_data)

    tran_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad,0,0)
    tran_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0,sy,0)))

    sim.run(until_after_sources=300)

    res1 = sim.get_eigenmode_coefficients(tran_flux, range(1,nmode+1), eig_parity=mp.ODD_Z+mp.EVEN_Y)
    res2 = sim.get_eigenmode_coefficients(tran_flux, range(1,nmode+1), eig_parity=mp.EVEN_Z+mp.ODD_Y)
    angles = [math.degrees(math.acos(kdom.x/fcen)) for kdom in res1.kdom]

    return input_flux[0], angles, res1.alpha[:,0,0], res2.alpha[:,0,0];
Example #7
0
import numpy as np
import gdspy
from matplotlib import pyplot as plt
import importlib
import meep as mp

# core and cladding materials
Si = mp.Medium(index=3.4)
SiO2 = mp.Medium(index=1.4)

# layer numbers for GDS file
RING_LAYER = 0
SOURCE0_LAYER = 1
SOURCE1_LAYER = 2
MONITOR_LAYER = 3
SIMULATION_LAYER = 4

resolution = 50  # pixels/μm
dpml = 1  # thickness of PML
zmin = 0  # minimum z value of simulation domain (0 for 2D)
zmax = 0  # maximum z value of simulation domain (0 for 2D)


def create_ring_gds(radius, width):
    # Reload the library each time to prevent gds library name clashes
    importlib.reload(gdspy)

    ringCell = gdspy.Cell("ring_resonator_r{}_w{}".format(radius, width))

    # Draw the ring
    ringCell.add(
    frq_max = 1 / minwvl
    frq_cen = 0.5 * (frq_min + frq_max)
    dfrq = frq_max - frq_min
    nfrq = 100
    resolution = 110  # this value will change
    dpml = 2
    #wavelength resolution problem
    #transmittance ratio is low
    #silicon dioxide
    #titanium dio
    pml_layers = [
        mp.PML(dpml, direction=mp.Y, side=mp.High),
        mp.Absorber(dpml, direction=mp.Y, side=mp.Low)
    ]
    block_number = 6  # here this number determines how many dielectric material has been used
    Material = mp.Medium(epsilon=12)
    block_thicknessy = 0.1
    block_thicknessx = 0.1  #thickness of each block
    cellx = block_thicknessx
    celly = 2 * dpml + block_number * 2 * (block_thicknessy)
    geometry = []

    sources = [
        mp.Source(mp.GaussianSource(frq_cen, fwidth=dfrq),
                  center=mp.Vector3(0, -0.5 * celly + dpml),
                  size=mp.Vector3(block_thicknessx, 0),
                  component=mp.Ez)
    ]  #polarization?
    sim = mp.Simulation(resolution=resolution,
                        cell_size=mp.Vector3(cellx, celly),
                        boundary_layers=pml_layers,
Example #9
0
import matplotlib.pyplot as plt
from meep.materials import Cu

wid = 1
sq1 = 10
sq2 = 20
cell = mp.Vector3(2 * sq2, 2 * sq2, 0)
gap = 2

cell = cell = mp.Vector3(1.5 * sq2, 1.5 * sq2, 0)
#first square

#vertial
sq1_1 = mp.Block(mp.Vector3(sq1, wid, mp.inf),
                 center=mp.Vector3(0, -sq1 / 2),
                 material=mp.Medium(epsilon=10))
sq1_2 = mp.Block(mp.Vector3(sq1, wid, mp.inf),
                 center=mp.Vector3(0, sq1 / 2),
                 material=mp.Medium(epsilon=10))
#horizontal
sq1_3 = mp.Block(mp.Vector3(wid, sq1 + wid, mp.inf),
                 center=mp.Vector3(sq1 / 2, 0),
                 material=mp.Medium(epsilon=10))
#sides from the split on first square

#length of split side
split_1 = abs(sq1 / 2 - gap / 2)

sq1_4 = mp.Block(mp.Vector3(wid, (sq1 / 2) - (gap / 2), mp.inf),
                 center=mp.Vector3(-sq1 / 2, (sq1 - split_1 + wid) / 2),
                 material=mp.Medium(epsilon=10))
Example #10
0
    eps_Si=12
    eps=4
    T_Si=1
    T_Arc=float(args.v)
    cell = mp.Vector3(sx, sy, 0)
    pml_layers = [mp.PML(1.0)]
    resolution = 10
    nfreq = 100
        fcen = 0.15  # pulse center frequency
        df = 0.1  # pulse width (in frequency)

    print(T_Arc)

    if args.no_ARC:
        geometry = [mp.Block(mp.Vector3(sx, sy, mp.inf), center=mp.Vector3(0, 0),
            material=mp.Medium(epsilon=1))]
    else:
        geometry = [mp.Block(mp.Vector3(T_Si, sy, mp.inf), center=mp.Vector3(0, 0),
            material=mp.Medium(epsilon=eps_Si)),
                mp.Block(mp.Vector3(T_Arc, sy, mp.inf), center=mp.Vector3(-0.5 * (T_Si + T_Arc), 0),
                    material=mp.Medium(epsilon=eps))]

    sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez,
                center=mp.Vector3(2 + (-0.5 * sx), 0), size=mp.Vector3(0, 1))]
    sim = mp.Simulation(cell_size=cell,
            boundary_layers=pml_layers,
            geometry=geometry,
            sources=sources,
            resolution=resolution)

    if args.no_ARC:
Example #11
0
# size of computational cell
#----------------------------------------------------------------------
w_wvg = args.w_wvg
h_wvg = args.h_wvg
w_hole = args.w_hole
L = max(6.0 * dpml + 2.0 * w_hole, 3.0 / fcen)
sx = dpml + L + dpml
sy = dpml + dair + w_wvg + dair + dpml
sz = 0.0 if h_wvg == 0.0 else dpml + dair + h_wvg + dair + dpml
cell_size = v3(sx, sy, sz)

#----------------------------------------------------------------------
# geometric objects (material bodies), not including the design object
#----------------------------------------------------------------------
wvg = mp.Block(center=V3(ORIGIN),
               material=mp.Medium(epsilon=args.eps_wvg),
               size=V3(sx, w_wvg, h_wvg))

#----------------------------------------------------------------------
#- objective regions, objective quantities, objective function
#----------------------------------------------------------------------
w_flux = (0.5 * dair + w_wvg + 0.5 * dair)
h_flux = 0.0 if h_wvg == 0.0 else (0.5 * dair + h_wvg + 0.5 * dair)
flux_size = v3(0, w_flux, h_flux)
d_flux = w_hole + dpml  # distance from origin to centers of flux cells
east = Subregion(name='east',
                 center=v3(+d_flux, 0, 0),
                 size=flux_size,
                 dir=mp.X)
west = Subregion(name='west',
                 center=v3(-d_flux, 0, 0),
Example #12
0
# ---------------------------------------------------------------------------- #
# Import libraries
# ---------------------------------------------------------------------------- #

import meep as mp
from meep import mpb
import matplotlib.pyplot as plt
import numpy as np

# ---------------------------------------------------------------------------- #
# Materials, constants, and common cimulation params
# ---------------------------------------------------------------------------- #

Si = mp.Medium(index=3.4757)
SiO2 = mp.Medium(index=1.444)

ww      = 0.5   # waveguide width (microns)
wh      = 0.22  # waveguide height (microns)
rradius = 5     # ring radius (microns)
gap     = .1   # gap between ring and bus (microns)
conLen  = 5     # connector length (microns)

resolution = 10

PML = 2.0
pml_layers = [mp.PML(PML)]

cellWidth = 3*rradius + 2*PML
cellHeight = 3*rradius + 2*PML

cell = mp.Vector3(cellWidth,cellHeight,0)
Example #13
0
 def mat_func(p):
     return mp.Medium()
Example #14
0
File: geom.py Project: yaohuic/meep
    def test_check_material_frequencies(self):
        mat = mp.Medium(valid_freq_range=mp.FreqRange(min=10, max=20))
        invalid_sources = [
            [mp.Source(mp.GaussianSource(5, fwidth=1), mp.Ez, mp.Vector3())],
            [
                mp.Source(mp.ContinuousSource(10, fwidth=1), mp.Ez,
                          mp.Vector3())
            ],
            [mp.Source(mp.GaussianSource(10, width=1), mp.Ez, mp.Vector3())],
            [mp.Source(mp.GaussianSource(20, width=1), mp.Ez, mp.Vector3())],
        ]

        cell_size = mp.Vector3(5, 5)
        resolution = 5

        def check_warnings(sim, should_warn=True):
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                sim.run(until=5)

                if should_warn:
                    self.assertEqual(len(w), 1)
                    self.assertIn("material", str(w[-1].message))
                else:
                    self.assertEqual(len(w), 0)

        geom = [mp.Sphere(0.2, material=mat)]

        for s in invalid_sources:
            # Check for invalid extra_materials
            sim = mp.Simulation(cell_size=cell_size,
                                resolution=resolution,
                                sources=s,
                                extra_materials=[mat])
            check_warnings(sim)

            # Check for invalid geometry materials
            sim = mp.Simulation(cell_size=cell_size,
                                resolution=resolution,
                                sources=s,
                                geometry=geom)
            check_warnings(sim)

        valid_sources = [[
            mp.Source(mp.GaussianSource(15, fwidth=1), mp.Ez, mp.Vector3())
        ], [mp.Source(mp.ContinuousSource(15, width=5), mp.Ez, mp.Vector3())]]

        for s in valid_sources:
            sim = mp.Simulation(cell_size=cell_size,
                                resolution=resolution,
                                sources=s,
                                extra_materials=[mat])
            check_warnings(sim, False)

        # Check DFT frequencies

        # Invalid extra_materials
        sim = mp.Simulation(cell_size=cell_size,
                            resolution=resolution,
                            sources=valid_sources[0],
                            extra_materials=[mat])
        fregion = mp.FluxRegion(center=mp.Vector3(0, 1),
                                size=mp.Vector3(2, 2),
                                direction=mp.X)
        sim.add_flux(15, 6, 2, fregion)
        check_warnings(sim)

        # Invalid geometry material
        sim = mp.Simulation(cell_size=cell_size,
                            resolution=resolution,
                            sources=valid_sources[0],
                            geometry=geom)
        sim.add_flux(15, 6, 2, fregion)
        check_warnings(sim)
Example #15
0
# -*- coding: utf-8 -*-

import meep as mp
from meep import mpb
import numpy as np
import matplotlib.pyplot as plt

resolution = 128  # pixels/μm

Si = mp.Medium(index=3.45)

syz = 10
geometry_lattice = mp.Lattice(size=mp.Vector3(0, syz, syz))

k_points = [mp.Vector3(0.5)]

num_bands = 1
tolerance = 1e-9

a = 1.0  # waveguide width


def parallel_waveguide(s, yodd):
    geometry = [
        mp.Block(center=mp.Vector3(0, -0.5 * (s + a), 0),
                 size=mp.Vector3(mp.inf, a, a),
                 material=Si),
        mp.Block(center=mp.Vector3(0, 0.5 * (s + a), 0),
                 size=mp.Vector3(mp.inf, a, a),
                 material=Si)
    ]
Example #16
0
def main(args):

    resolution = 30

    nSiO2 = 1.4
    SiO2 = mp.Medium(index=nSiO2)

    # conversion factor for eV to 1/um
    eV_um_scale = 1 / 1.23984193

    # W, from Rakic et al., Applied Optics, vol. 32, p. 5274 (1998)
    W_eps_inf = 1
    W_plasma_frq = 13.22 * eV_um_scale
    W_f0 = 0.206
    W_frq0 = 1e-10
    W_gam0 = 0.064 * eV_um_scale
    W_sig0 = W_f0 * W_plasma_frq**2 / W_frq0**2
    W_f1 = 0.054
    W_frq1 = 1.004 * eV_um_scale  # 1.235 um
    W_gam1 = 0.530 * eV_um_scale
    W_sig1 = W_f1 * W_plasma_frq**2 / W_frq1**2
    W_f2 = 0.166
    W_frq2 = 1.917 * eV_um_scale  # 0.647
    W_gam2 = 1.281 * eV_um_scale
    W_sig2 = W_f2 * W_plasma_frq**2 / W_frq2**2

    W_susc = [
        mp.DrudeSusceptibility(frequency=W_frq0, gamma=W_gam0, sigma=W_sig0),
        mp.LorentzianSusceptibility(frequency=W_frq1,
                                    gamma=W_gam1,
                                    sigma=W_sig1),
        mp.LorentzianSusceptibility(frequency=W_frq2,
                                    gamma=W_gam2,
                                    sigma=W_sig2)
    ]

    W = mp.Medium(epsilon=W_eps_inf, E_susceptibilities=W_susc)

    # crystalline Si, from M.A. Green, Solar Energy Materials and Solar Cells, vol. 92, pp. 1305-1310 (2008)
    # fitted Lorentzian parameters, only for 600nm-1100nm
    Si_eps_inf = 9.14
    Si_eps_imag = -0.0334
    Si_eps_imag_frq = 1 / 1.55
    Si_frq = 2.2384
    Si_gam = 4.3645e-02
    Si_sig = 14.797 / Si_frq**2

    Si = mp.Medium(epsilon=Si_eps_inf,
                   D_conductivity=2 * math.pi * Si_eps_imag_frq * Si_eps_imag /
                   Si_eps_inf,
                   E_susceptibilities=[
                       mp.LorentzianSusceptibility(frequency=Si_frq,
                                                   gamma=Si_gam,
                                                   sigma=Si_sig)
                   ])

    a = args.a  # lattice periodicity
    cone_r = args.cone_r  # cone radius
    cone_h = args.cone_h  # cone height
    wire_w = args.wire_w  # metal-grid wire width
    wire_h = args.wire_h  # metal-grid wire height
    trench_w = args.trench_w  # trench width
    trench_h = args.trench_h  # trench height
    Np = args.Np  # number of periods in supercell

    dair = 1.0  # air gap thickness
    dmcl = 1.7  # micro lens thickness
    dsub = 3000.0  # substrate thickness
    dpml = 1.0  # PML thickness

    sxy = Np * a
    sz = dpml + dair + dmcl + dsub + dpml
    cell_size = mp.Vector3(sxy, sxy, sz)

    boundary_layers = [
        mp.PML(dpml, direction=mp.Z, side=mp.High),
        mp.Absorber(dpml, direction=mp.Z, side=mp.Low)
    ]

    geometry = []

    if args.substrate:
        geometry = [
            mp.Sphere(material=SiO2,
                      radius=dmcl,
                      center=mp.Vector3(0, 0, 0.5 * sz - dpml - dair - dmcl)),
            mp.Block(material=Si,
                     size=mp.Vector3(mp.inf, mp.inf, dsub + dpml),
                     center=mp.Vector3(0, 0, -0.5 * sz + 0.5 * (dsub + dpml))),
            mp.Block(
                material=W,
                size=mp.Vector3(mp.inf, wire_w, wire_h),
                center=mp.Vector3(0, -0.5 * sxy + 0.5 * wire_w,
                                  -0.5 * sz + dpml + dsub + 0.5 * wire_h)),
            mp.Block(
                material=W,
                size=mp.Vector3(mp.inf, wire_w, wire_h),
                center=mp.Vector3(0, +0.5 * sxy - 0.5 * wire_w,
                                  -0.5 * sz + dpml + dsub + 0.5 * wire_h)),
            mp.Block(
                material=W,
                size=mp.Vector3(wire_w, mp.inf, wire_h),
                center=mp.Vector3(-0.5 * sxy + 0.5 * wire_w, 0,
                                  -0.5 * sz + dpml + dsub + 0.5 * wire_h)),
            mp.Block(material=W,
                     size=mp.Vector3(wire_w, mp.inf, wire_h),
                     center=mp.Vector3(+0.5 * sxy - 0.5 * wire_w, 0,
                                       -0.5 * sz + dpml + dsub + 0.5 * wire_h))
        ]

    if args.substrate and args.texture:
        for nx in range(Np):
            for ny in range(Np):
                cx = -0.5 * sxy + (nx + 0.5) * a
                cy = -0.5 * sxy + (ny + 0.5) * a
                geometry.append(
                    mp.Cone(material=SiO2,
                            radius=0,
                            radius2=cone_r,
                            height=cone_h,
                            center=mp.Vector3(
                                cx, cy,
                                0.5 * sz - dpml - dair - dmcl - 0.5 * cone_h)))

    if args.substrate:
        geometry.append(
            mp.Block(material=SiO2,
                     size=mp.Vector3(mp.inf, trench_w, trench_h),
                     center=mp.Vector3(
                         0, -0.5 * sxy + 0.5 * trench_w,
                         0.5 * sz - dpml - dair - dmcl - 0.5 * trench_h)))
        geometry.append(
            mp.Block(material=SiO2,
                     size=mp.Vector3(mp.inf, trench_w, trench_h),
                     center=mp.Vector3(
                         0, +0.5 * sxy - 0.5 * trench_w,
                         0.5 * sz - dpml - dair - dmcl - 0.5 * trench_h)))
        geometry.append(
            mp.Block(material=SiO2,
                     size=mp.Vector3(trench_w, mp.inf, trench_h),
                     center=mp.Vector3(
                         -0.5 * sxy + 0.5 * trench_w, 0,
                         0.5 * sz - dpml - dair - dmcl - 0.5 * trench_h)))
        geometry.append(
            mp.Block(material=SiO2,
                     size=mp.Vector3(trench_w, mp.inf, trench_h),
                     center=mp.Vector3(
                         +0.5 * sxy - 0.5 * trench_w, 0,
                         0.5 * sz - dpml - dair - dmcl - 0.5 * trench_h)))

    k_point = mp.Vector3(0, 0, 0)

    lambda_min = 0.7  # minimum source wavelength
    lambda_max = 1.0  # maximum source wavelength
    fmin = 1 / lambda_max
    fmax = 1 / lambda_min
    fcen = 0.5 * (fmin + fmax)
    df = fmax - fmin

    sources = [
        mp.Source(mp.GaussianSource(fcen, fwidth=df),
                  component=mp.Ex,
                  center=mp.Vector3(0, 0, 0.5 * sz - dpml - 0.5 * dair),
                  size=mp.Vector3(sxy, sxy, 0))
    ]

    sim = mp.Simulation(resolution=resolution,
                        cell_size=cell_size,
                        boundary_layers=boundary_layers,
                        geometry=geometry,
                        dimensions=3,
                        k_point=k_point,
                        sources=sources)

    nfreq = 50
    refl = sim.add_flux(
        fcen, df, nfreq,
        mp.FluxRegion(center=mp.Vector3(0, 0, 0.5 * sz - dpml),
                      size=mp.Vector3(sxy, sxy, 0)))
    trans_grid = sim.add_flux(
        fcen, df, nfreq,
        mp.FluxRegion(center=mp.Vector3(0, 0,
                                        -0.5 * sz + dpml + dsub + wire_h),
                      size=mp.Vector3(sxy, sxy, 0)))
    trans_sub_top = sim.add_flux(
        fcen, df, nfreq,
        mp.FluxRegion(center=mp.Vector3(0, 0, -0.5 * sz + dpml + dsub),
                      size=mp.Vector3(sxy, sxy, 0)))
    trans_sub_bot = sim.add_flux(
        fcen, df, nfreq,
        mp.FluxRegion(center=mp.Vector3(0, 0, -0.5 * sz + dpml),
                      size=mp.Vector3(sxy, sxy, 0)))

    sim.run(mp.at_beginning(mp.output_epsilon), until=0)

    if args.substrate:
        sim.load_minus_flux('refl-flux', refl)

    sim.run(until_after_sources=mp.stop_when_fields_decayed(
        50, mp.Ex, mp.Vector3(0, 0, -0.5 * sz + dpml + 0.5 * dsub), 1e-9))

    if not args.substrate:
        sim.save_flux('refl-flux', refl)

    sim.display_fluxes(refl, trans_grid, trans_sub_top, trans_sub_bot)
Example #17
0
dpad = 32  # padding between last hole and PML edge
dpml = 0.5 / (fcen - 0.5 * df)  # PML thickness (> half the largest wavelength)
sx = 2 * (dpad + dpml + N) + d - 1  # size of cell in x direction

d1 = 0.2  # y-distance from waveguide edge to near2far surface
d2 = 2.0  # y-distance from near2far surface to far-field line
sy = w + 2 * (d1 + d2 + dpml
              )  # size of cell in y direction (perpendicular to wvg.)

cell = mp.Vector3(sx, sy, 0)

geometry = [
    mp.Block(center=mp.Vector3(),
             size=mp.Vector3(mp.inf, w, mp.inf),
             material=mp.Medium(epsilon=eps))
]

for i in range(N):
    geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i)))
    geometry.append(mp.Cylinder(r, center=mp.Vector3(d / -2 - i)))

pml_layers = [mp.PML(dpml)]

sources = [
    mp.Source(src=mp.GaussianSource(fcen, fwidth=df),
              component=mp.Hz,
              center=mp.Vector3())
]

symmetries = [mp.Mirror(mp.X, phase=-1), mp.Mirror(mp.Y, phase=-1)]
Example #18
0
cSi_sig3 = -0.107

cSi_susc = [
    mp.LorentzianSusceptibility(frequency=cSi_frq1,
                                gamma=cSi_gam1,
                                sigma=cSi_sig1),
    mp.LorentzianSusceptibility(frequency=cSi_frq2,
                                gamma=cSi_gam2,
                                sigma=cSi_sig2),
    mp.LorentzianSusceptibility(frequency=cSi_frq3,
                                gamma=cSi_gam3,
                                sigma=cSi_sig3)
]

cSi = mp.Medium(epsilon=1.0,
                E_susceptibilities=cSi_susc,
                valid_freq_range=cSi_range)

#------------------------------------------------------------------

# amorphous silicon (a-Si) from Horiba Technical Note 08: Lorentz Dispersion Model
# ref: http://www.horiba.com/fileadmin/uploads/Scientific/Downloads/OpticalSchool_CN/TN/ellipsometer/Lorentz_Dispersion_Model.pdf
# wavelength range: 0.21 - 0.83 um

aSi_range = mp.FreqRange(min=1 / 0.83, max=1 / 0.21)

aSi_frq1 = 1 / (0.315481407124682 * um_scale)
aSi_gam1 = 1 / (0.645751005208333 * um_scale)
aSi_sig1 = 14.571

aSi_susc = [
Example #19
0
n = 3.4
w = 1
r = 1
pad = 4
dpml = 2

sxy = 2 * (r + w + pad + dpml)
cell_size = mp.Vector3(sxy, sxy)

pml_layers = [mp.PML(dpml)]

nonpml_vol = mp.Volume(mp.Vector3(),
                       size=mp.Vector3(sxy - 2 * dpml, sxy - 2 * dpml))

geometry = [
    mp.Cylinder(radius=r + w, material=mp.Medium(index=n)),
    mp.Cylinder(radius=r)
]

fcen = 0.118

src = [
    mp.Source(mp.ContinuousSource(fcen),
              component=mp.Ez,
              center=mp.Vector3(r + 0.1)),
    mp.Source(mp.ContinuousSource(fcen),
              component=mp.Ez,
              center=mp.Vector3(-(r + 0.1)),
              amplitude=-1)
]
Example #20
0
    def __init__(self,
                 cell_size,
                 resolution,
                 geometry=[],
                 sources=[],
                 eps_averaging=True,
                 dimensions=2,
                 boundary_layers=[],
                 symmetries=[],
                 verbose=False,
                 force_complex_fields=False,
                 default_material=mp.Medium(),
                 m=0,
                 k_point=False,
                 extra_materials=[],
                 material_function=None,
                 epsilon_func=None,
                 epsilon_input_file='',
                 progress_interval=4,
                 subpixel_tol=1e-4,
                 subpixel_maxeval=100000,
                 ensure_periodicity=False,
                 num_chunks=0,
                 courant=0.5,
                 accurate_fields_near_cylorigin=False,
                 filename_prefix='',
                 output_volume=None,
                 output_single_precision=False):

        self.cell_size = cell_size
        self.geometry = geometry
        self.sources = sources
        self.resolution = resolution
        self.dimensions = dimensions
        self.boundary_layers = boundary_layers
        self.symmetries = symmetries
        self.geometry_center = Vector3()
        self.eps_averaging = eps_averaging
        self.subpixel_tol = subpixel_tol
        self.subpixel_maxeval = subpixel_maxeval
        self.ensure_periodicity = ensure_periodicity
        self.extra_materials = extra_materials
        self.default_material = default_material
        self.epsilon_input_file = epsilon_input_file
        self.num_chunks = num_chunks
        self.courant = courant
        self.global_d_conductivity = 0
        self.global_b_conductivity = 0
        self.special_kz = False
        self.k_point = k_point
        self.fields = None
        self.structure = None
        self.accurate_fields_near_cylorigin = accurate_fields_near_cylorigin
        self.m = m
        self.force_complex_fields = force_complex_fields
        self.verbose = verbose
        self.progress_interval = progress_interval
        self.init_fields_hooks = []
        self.run_index = 0
        self.filename_prefix = ''
        self.output_append_h5 = None
        self.output_single_precision = output_single_precision
        self.output_volume = output_volume
        self.last_eps_filename = ''
        self.output_h5_hook = lambda fname: False
        self.interactive = False
        self.is_cylindrical = False
        self.material_function = material_function
        self.epsilon_func = epsilon_func
fcen = (maxf + minf) / 2
df = maxf - minf
nfreq = 100
resolution = 100
sources = [
    mp.Source(mp.GaussianSource(fcen, fwidth=df, is_integrated=True),
              component=mp.Ey,
              center=mp.Vector3(-0.05, 0, 0),
              size=mp.Vector3(0, 0.12, 0))
]

sim = mp.Simulation(cell_size=cell,
                    boundary_layers=pml_layers,
                    k_point=mp.Vector3(),
                    sources=sources,
                    default_material=mp.Medium(epsilon=1.78),
                    resolution=resolution)

#for i in (np.arange(1,3)):
#    r=i*0.01
r = 0.02
sim = mp.Simulation(cell_size=cell,
                    boundary_layers=pml_layers,
                    sources=sources,
                    resolution=resolution)
left_fr = mp.FluxRegion(center=mp.Vector3(x=-r), size=mp.Vector3(0, 2 * r, 0))
left_monitor = sim.add_flux(fcen, df, nfreq, left_fr)

right_fr = mp.FluxRegion(center=mp.Vector3(x=r), size=mp.Vector3(0, 2 * r, 0))
right_monitor = sim.add_flux(fcen, df, nfreq, right_fr)
Example #22
0
def main():
    # Prefix all output files with the command line argument
    file_prefix = sys.argv[1]
    # Number of pixels per micron
    resolution = 150
    # Simulation volume (um)
    cell_x = 2
    cell_y = 2
    cell_z = 2.5
    # Refractive indicies
    index_si = 3.6  # previously 3.4467
    index_sio2 = 1.444
    # Durations in units of micron/c
    duration = round(1.5 * cell_x + 2)
    num_timesteps = duration * resolution
    # Absorbing layer on boundary
    pml = 0.5
    # Geometry
    src_buffer = pml / 16
    nbn_buffer = src_buffer
    nbn_length = cell_x - 2 * pml - src_buffer - nbn_buffer
    nbn_center_x = (src_buffer + nbn_buffer) / 2
    wavelength = 1.55
    waveguide_width = 0.750  # 750 nm
    waveguide_height = 0.110  # 110 nm
    plane_shift_y = 0

    # nbn is 10/8 times thicker than in reality to have enough simulation pixels
    # so we reduce its absorption by a factor of 5/4 to compensate
    nbn_thickness_comp = 250 / resolution

    nbn_thickness = 0.008 * nbn_thickness_comp  # Actually 8 nm, but simulating this for 2 grid points
    nbn_width = 0.100  # 100 nm
    nbn_spacing = 0.120  # 120 nm

    # Also compensate the difference in index by the same amount
    nbn_base_index = 5.23  # Taken from Hu thesis p86
    nbn_index = (5.23 - index_si) / nbn_thickness_comp + index_si
    nbn_base_k = 5.82  # Taken from Hu thesis p86
    nbn_k = nbn_base_k / nbn_thickness_comp
    conductivity = 2 * math.pi * wavelength * nbn_k / nbn_index

    flux_length = cell_x - 2 * pml - 4 * src_buffer

    # Generate simulation obejcts
    cell = mp.Vector3(cell_x, cell_y, cell_z)
    freq = 1 / wavelength
    src_pt = mp.Vector3(-cell_x / 2 + pml + src_buffer, 0, 0)
    output_slice = mp.Volume(center=mp.Vector3(y=(3 * waveguide_height / 4) +
                                               plane_shift_y),
                             size=(cell_x, 0, cell_z))

    # Log important quantities
    print('ABSORBING RUN')
    print('File prefix: {}'.format(file_prefix))
    print('Duration: {}'.format(duration))
    print('Resolution: {}'.format(resolution))
    print('Dimensions: {} um, {} um, {} um'.format(cell_x, cell_y, cell_z))
    print('Wavelength: {} um'.format(wavelength))
    print('Si thickness: {} um'.format(waveguide_height))
    print('NbN thickness: {} um'.format(nbn_thickness))
    print('Si index: {}; SiO2 index: {}'.format(index_si, index_sio2))
    print('Absorber dimensions: {} um, {} um, {} um'.format(
        nbn_length, nbn_thickness, nbn_width))
    print('Absorber n (base value): {} ({}), k: {} ({})'.format(
        nbn_index, nbn_base_index, nbn_k, nbn_base_k))
    print('Absorber compensation for thickness: {}'.format(nbn_thickness_comp))
    print('Flux length: {} um'.format(flux_length))
    print('\n\n**********\n\n')

    default_material = mp.Medium(epsilon=1)

    # Physical geometry of the simulation
    geometry = [
        mp.Block(mp.Vector3(mp.inf, cell_y, mp.inf),
                 center=mp.Vector3(0, -cell_y / 2 + plane_shift_y, 0),
                 material=mp.Medium(epsilon=index_sio2)),
        mp.Block(mp.Vector3(mp.inf, waveguide_height, waveguide_width),
                 center=mp.Vector3(0, waveguide_height / 2 + plane_shift_y, 0),
                 material=mp.Medium(epsilon=index_si))
    ]

    # Absorber will only be appended to geometry for the second simulation
    absorber = [
        mp.Block(mp.Vector3(nbn_length, nbn_thickness, nbn_width),
                 center=mp.Vector3(
                     nbn_center_x, waveguide_height +
                     nbn_thickness / nbn_thickness_comp / 2 + plane_shift_y,
                     nbn_spacing / 2),
                 material=mp.Medium(epsilon=nbn_index,
                                    D_conductivity=conductivity)),
        mp.Block(mp.Vector3(nbn_length, nbn_thickness, nbn_width),
                 center=mp.Vector3(
                     nbn_center_x, waveguide_height +
                     nbn_thickness / nbn_thickness_comp / 2 + plane_shift_y,
                     -nbn_spacing / 2),
                 material=mp.Medium(epsilon=nbn_index,
                                    D_conductivity=conductivity)),
    ]

    # geometry += absorber

    # Calculate eigenmode source
    src_max_y = cell_y - 2 * pml
    src_max_z = cell_z - 2 * pml
    src_y = src_max_y
    src_z = src_max_z  # min(3 * waveguide_width, src_max_z)

    src_center_y = 0  # plane_shift_y

    sources = [
        mp.EigenModeSource(src=mp.ContinuousSource(frequency=freq),
                           center=mp.Vector3(-cell_x / 2 + pml + src_buffer,
                                             src_center_y, 0),
                           size=mp.Vector3(0, src_y, src_z),
                           eig_match_freq=True,
                           eig_parity=mp.ODD_Z,
                           eig_band=1)
    ]

    pml_layers = [mp.PML(pml)]

    # Pass all simulation parameters to meep
    sim = mp.Simulation(
        cell_size=cell,
        boundary_layers=pml_layers,
        geometry=geometry,
        sources=sources,
        resolution=resolution,
        # eps_averaging=False,
        default_material=default_material,
        symmetries=[mp.Mirror(mp.Z, phase=-1)])

    # Create flux monitors to calculate transmission and absorption
    fr_y = cell_y - 2 * pml
    fr_z = cell_z - 2 * pml

    # Reflected flux
    refl_fr = mp.FluxRegion(center=mp.Vector3(
        -0.5 * cell_x + pml + 2 * src_buffer, 0, 0),
                            size=mp.Vector3(0, fr_y, fr_z))
    refl = sim.add_flux(freq, 0, 1, refl_fr)

    # Transmitted flux
    tran_fr = mp.FluxRegion(center=mp.Vector3(
        0.5 * cell_x - pml - 2 * src_buffer, 0, 0),
                            size=mp.Vector3(0, fr_y, fr_z))
    tran = sim.add_flux(freq, 0, 1, tran_fr)

    # Run simulation, outputting the epsilon distribution and the fields in the
    # x-y plane every 0.25 microns/c
    sim.run(mp.at_beginning(mp.output_epsilon),
            mp.to_appended(
                "ez_z0",
                mp.in_volume(output_slice,
                             mp.at_every(2 / resolution, mp.output_efield_z))),
            until=duration)

    print('\n\n**********\n\n')

    sim.fields.synchronize_magnetic_fields()

    # For normalization run, save flux fields data for reflection plane
    no_absorber_refl_data = sim.get_flux_data(refl)
    # Save incident power for transmission plane
    no_absorber_tran_flux = mp.get_fluxes(tran)

    print("Flux: {}".format(no_absorber_tran_flux[0]))

    eps_data = sim.get_array(center=mp.Vector3(z=(nbn_spacing + nbn_width) /
                                               2),
                             size=mp.Vector3(cell_x, cell_y, 0),
                             component=mp.Dielectric)
    eps_cross_data = sim.get_array(center=mp.Vector3(x=cell_x / 4),
                                   size=mp.Vector3(0, cell_y, cell_z),
                                   component=mp.Dielectric)

    max_field = 1.5

    # Plot epsilon distribution
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_data.transpose(),
                   interpolation='spline36',
                   cmap='binary')
        plt.axis('off')
        plt.savefig(file_prefix + '_Eps_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Eps_A.png')

    # Plot field on x-y plane
    ez_data = sim.get_array(center=mp.Vector3(),
                            size=mp.Vector3(cell_x, cell_y, 0),
                            component=mp.Ez)
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_data.transpose(),
                   interpolation='spline36',
                   cmap='binary')
        plt.imshow(ez_data.transpose(),
                   interpolation='spline36',
                   cmap='RdBu',
                   alpha=0.9)
        plt.axis('off')
        plt.savefig(file_prefix + '_Ez_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Ez_A.png')

    energy_side_data = sim.get_array(center=mp.Vector3(),
                                     size=mp.Vector3(cell_x, cell_y, 0),
                                     component=mp.EnergyDensity)
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_data.transpose(),
                   interpolation='spline36',
                   cmap='binary')
        plt.imshow(energy_side_data.transpose(),
                   interpolation='spline36',
                   cmap='hot',
                   alpha=0.9)
        plt.axis('off')
        plt.savefig(file_prefix + '_Pwr0_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Pwr0_A.png')

    # Plot energy density on y-z plane
    energy_data = sim.get_array(center=mp.Vector3(),
                                size=mp.Vector3(0, cell_y, cell_z),
                                component=mp.EnergyDensity)
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_cross_data, interpolation='spline36', cmap='binary')
        plt.imshow(energy_data,
                   interpolation='spline36',
                   cmap='hot',
                   alpha=0.9)
        plt.axis('off')
        plt.savefig(file_prefix + '_Pwr1_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Pwr1_A.png')

    energy_data = sim.get_array(center=mp.Vector3(x=cell_x / 4),
                                size=mp.Vector3(0, cell_y, cell_z),
                                component=mp.EnergyDensity)
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_cross_data, interpolation='spline36', cmap='binary')
        plt.imshow(energy_data,
                   interpolation='spline36',
                   cmap='hot',
                   alpha=0.9)
        plt.axis('off')
        plt.savefig(file_prefix + '_Pwr2_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Pwr2_A.png')

    # Plot cross-sectional fields at several locations to ensure seeing nonzero fields
    num_x = 4
    num_y = 3
    fig, ax = plt.subplots(num_x, num_y)
    fig.suptitle('Cross Sectional Ez Fields')

    for i in range(num_x * num_y):
        monitor_x = i * (cell_x / 4) / (num_x * num_y)
        ez_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x),
                                      size=mp.Vector3(0, cell_y, cell_z),
                                      component=mp.Ez)
        ax_num = i // num_y, i % num_y
        if mp.am_master():
            ax[ax_num].imshow(eps_cross_data,
                              interpolation='spline36',
                              cmap='binary')
            ax[ax_num].imshow(ez_cross_data,
                              interpolation='spline36',
                              cmap='RdBu',
                              alpha=0.9,
                              norm=ZeroNormalize(vmax=np.max(max_field)))
            ax[ax_num].axis('off')
            ax[ax_num].set_title('x = {}'.format(
                round(cell_x / 4 + i / resolution, 3)))
    if mp.am_master():
        plt.savefig(file_prefix + '_Ez_CS_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Ez_CS_A.png')

    fig_e, ax_e = plt.subplots(num_x, num_y)
    fig_e.suptitle('Cross Sectional Energy Density')

    for i in range(num_x * num_y):
        monitor_x = i * (cell_x / 4) / (num_x * num_y)
        energy_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x),
                                          size=mp.Vector3(0, cell_y, cell_z),
                                          component=mp.EnergyDensity)
        ax_num = i // num_y, i % num_y
        if mp.am_master():
            ax_e[ax_num].imshow(eps_cross_data,
                                interpolation='spline36',
                                cmap='binary')
            ax_e[ax_num].imshow(energy_cross_data,
                                interpolation='spline36',
                                cmap='hot',
                                alpha=0.9)
            ax_e[ax_num].axis('off')
            ax_e[ax_num].set_title('x = {}'.format(
                round(cell_x / 4 + i / resolution, 3)))
    if mp.am_master():
        plt.savefig(file_prefix + '_Pwr_CS_A.png', dpi=300)
        print('Saved ' + file_prefix + '_Pwr_CS_A.png')

    print('\n\n**********\n\n')

    # Reset simulation for absorption run
    """
    sim.reset_meep()

    geometry += absorber

    sim = mp.Simulation(cell_size=cell,
                        boundary_layers=pml_layers,
                        geometry=geometry,
                        sources=sources,
                        resolution=resolution,
                        eps_averaging=False,
                        default_material=default_material,
                        symmetries=[mp.Mirror(mp.Z, phase=-1)])

    refl = sim.add_flux(freq, 0, 1, refl_fr)
    tran = sim.add_flux(freq, 0, 1, tran_fr)

    sim.load_minus_flux_data(refl, no_absorber_refl_data)

    # Run simulation with absorber
    sim.run(mp.at_beginning(mp.output_epsilon),
            mp.to_appended("ez_z0",
                           mp.in_volume(output_slice,
                                        mp.at_every(0.25, mp.output_efield_z))),
            until=duration)

    print('\n\n**********\n\n')

    # Calculate transmission and absorption
    absorber_refl_flux = mp.get_fluxes(refl)
    absorber_tran_flux = mp.get_fluxes(tran)

    transmittance = absorber_tran_flux[0] / no_absorber_tran_flux[0]
    reflectance = absorber_refl_flux[0] / no_absorber_tran_flux[0]
    absorption = 1 - transmittance
    penetration_depth = - nbn_length / math.log(transmittance)

    print('Flux: {}'.format(absorber_tran_flux[0]))
    print("Transmittance: %f" % transmittance)
    print("Reflectance: %f" % reflectance)
    print("Absorption: {} over {} um".format(absorption, nbn_length))
    print("lambda = {} mm".format(penetration_depth / 1000))

    eps_data = sim.get_array(center=mp.Vector3(z=(nbn_spacing + nbn_width) / 2), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Dielectric)

    max_field = 1

    # Plot epsilon distribution with absorber
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary')
        plt.axis('off')
        plt.savefig(file_prefix + '_Eps_B.png', dpi=300)
        print('Saved ' + file_prefix + '_Eps_B.png')

    # Plot fields in x-y plane with absorber
    ez_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Ez)
    if mp.am_master():
        plt.figure()
        plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary')
        plt.imshow(ez_data.transpose(), interpolation='spline36', cmap='RdBu', alpha=0.9)
        plt.axis('off')
        plt.savefig(file_prefix + '_Ez_B.png', dpi=300)
        print('Saved ' + file_prefix + '_Ez_B.png')

    # Plot field cross sections with absorber
    eps_cross_data = sim.get_array(center=mp.Vector3(x=cell_x/4), size=mp.Vector3(0, cell_y, cell_z), component=mp.Dielectric)
    num_x = 4
    num_y = 3
    fig, ax = plt.subplots(num_x, num_y)
    fig.suptitle('Cross Sectional Ez Fields')
    for i in range(num_x * num_y):
        monitor_x = cell_x/4 + i / resolution
        ez_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x), size=mp.Vector3(0, cell_y, cell_z), component=mp.Ez)
        ax_num = i // num_y, i % num_y
        if mp.am_master():
            ax[ax_num].imshow(eps_cross_data, interpolation='spline36', cmap='binary')
            ax[ax_num].imshow(ez_cross_data, interpolation='spline36', cmap='RdBu', alpha=0.9, norm=ZeroNormalize(vmax=np.max(max_field)))
            ax[ax_num].axis('off')
            ax[ax_num].set_title('x = {}'.format(round(cell_x/4 + i / resolution, 3)))
    if mp.am_master():
        plt.savefig(file_prefix + '_Ez_CS_B.png', dpi=300)
        print('Saved ' + file_prefix + '_Ez_CS_B.png')

    print('\n\n**********\n\n')
    """

    print('Program finished.')
from scipy import constants
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib as mpl
import meep
import meep_ext
import pinboard

job = pinboard.pinboard()
nm = 1e-9
um = 1e-6

### geometry
radius = 75 * nm
gold = meep_ext.material.Au()
gold = meep.Medium(index=3.5)

sep = 400 * nm
p1 = meep.Vector3(-sep / 2, 0, 0)
p2 = meep.Vector3(sep / 2, 0, 0)
geometry = [
    meep.Sphere(center=p1, radius=radius, material=gold),
    meep.Sphere(center=p2, radius=radius, material=gold)
]

### source
fcen, df = meep_ext.freq_data(1 / (400 * nm), 1 / (1000 * nm))
nfreq = 40
src_time = meep.GaussianSource(frequency=1.3 / um, fwidth=4.0 / um)
polarization = meep.Ex  # used in convergence check 'decay_by'
source = lambda sim: meep_ext.x_polarized_plane_wave(sim, src_time)
freqs = mp.get_flux_freqs(box_x1)
box_x1_data = sim.get_flux_data(box_x1)
box_x2_data = sim.get_flux_data(box_x2)
box_y1_data = sim.get_flux_data(box_y1)
box_y2_data = sim.get_flux_data(box_y2)
box_z1_data = sim.get_flux_data(box_z1)
box_z2_data = sim.get_flux_data(box_z2)

box_x1_flux0 = mp.get_fluxes(box_x1)

sim.reset_meep()

n_sphere = 2.0
geometry = [
    mp.Sphere(material=mp.Medium(index=n_sphere),
              center=mp.Vector3(),
              radius=r)
]

sim = mp.Simulation(resolution=resolution,
                    cell_size=cell_size,
                    boundary_layers=pml_layers,
                    sources=sources,
                    k_point=mp.Vector3(),
                    symmetries=symmetries,
                    geometry=geometry)

box_x1 = sim.add_flux(
    frq_cen, dfrq, nfrq,
    mp.FluxRegion(center=mp.Vector3(x=-r), size=mp.Vector3(0, 2 * r, 2 * r)))
Example #25
0
epsn, f0, gamma, sn, b0 = 1.5, 4.0, 4e-6, 0.4, 1.8
fcen, df, alpha = 0.2, 0.5, 1e-5
df1 = f0 - 1j * fcen * alpha
df2 = fcen + 1j * gamma
muperp = epsn + sn * df1 / (df1**2 - df2**2)
xi = sn * df2 / (df1**2 - df2**2)

susc = [
    mp.GyrotropicSaturatedSusceptibility(frequency=f0,
                                         gamma=gamma,
                                         sigma=sn,
                                         bias=mp.Vector3(0, 0, b0))
]

mat = mp.Medium(
    epsilon=1, mu=epsn,
    H_susceptibilities=susc)  #gyroelectric medium; this is just a dot cell

#-------------------------------------------------------#
# Set up simulation cell:
#-------------------------------------------------------#

tmax, L = 100, 20
#tmax: number of time steps over which sim will run

cell, src_z, pml_layers = mp.Vector3(1, 1,
                                     1), mp.Vector3(0, 0,
                                                    -10), [mp.PML(1.0, mp.Z)]

#df: frequency width of source
#-------------------------------------------------------#
Example #26
0
    def __init__(self,
                 resolution=10,
                 is_negative_epsilon_ok=False,
                 eigensolver_flops=0,
                 eigensolver_flags=68,
                 use_simple_preconditioner=False,
                 force_mu=False,
                 mu_input_file='',
                 epsilon_input_file='',
                 mesh_size=3,
                 target_freq=0.0,
                 tolerance=1.0e-7,
                 num_bands=1,
                 k_points=[],
                 ensure_periodicity=True,
                 geometry=[],
                 geometry_lattice=mp.Lattice(),
                 geometry_center=mp.Vector3(0, 0, 0),
                 default_material=mp.Medium(epsilon=1),
                 dimensions=3,
                 random_fields=False,
                 filename_prefix='',
                 deterministic=False,
                 verbose=False,
                 optimize_grid_size=True,
                 eigensolver_nwork=3,
                 eigensolver_block_size=-11):

        self.mode_solver = None
        self.resolution = resolution
        self.eigensolver_flags = eigensolver_flags
        self.k_points = k_points
        self.geometry = geometry
        self.geometry_lattice = geometry_lattice
        self.geometry_center = mp.Vector3(*geometry_center)
        self.default_material = default_material
        self.random_fields = random_fields
        self.filename_prefix = filename_prefix
        self.optimize_grid_size = optimize_grid_size
        self.parity = ''
        self.iterations = 0
        self.all_freqs = None
        self.freqs = []
        self.band_range_data = []
        self.total_run_time = 0
        self.current_k = mp.Vector3()
        self.k_split_num = 1
        self.k_split_index = 0
        self.eigensolver_iters = []

        grid_size = self._adjust_grid_size()

        if type(self.default_material) is not mp.Medium and callable(
                self.default_material):
            init_do_averaging(self.default_material)
            self.default_material.eps = False

        self.mode_solver = mode_solver(
            num_bands,
            self.resolution,
            self.geometry_lattice,
            tolerance,
            mesh_size,
            self.default_material,
            deterministic,
            target_freq,
            dimensions,
            verbose,
            ensure_periodicity,
            eigensolver_flops,
            is_negative_epsilon_ok,
            epsilon_input_file,
            mu_input_file,
            force_mu,
            use_simple_preconditioner,
            grid_size,
            eigensolver_nwork,
            eigensolver_block_size,
        )
                                                   weight=+1),
                                 mp.Near2FarRegion(center=mp.Vector3(z=+2*r),
                                                   size=mp.Vector3(4*r,4*r,0),
                                                   weight=-1))

sim.run(until_after_sources=10)

input_flux = mp.get_fluxes(box_flux)[0]
nearfield_box_data = sim.get_near2far_data(nearfield_box)
# Watch it! Now we're also using 'get_near2far_data'

sim.reset_meep()

#%% SECOND RUN: FULL CONFIGURATION :)

geometry = [mp.Sphere(material=mp.Medium(index=n_sphere),
                      center=mp.Vector3(),
                      radius=r)]

sim = mp.Simulation(resolution=resolution,
                    cell_size=cell_size,
                    boundary_layers=pml_layers,
                    sources=sources,
                    k_point=mp.Vector3(),
                    geometry=geometry)

#%% SECOND RUN: FULL SIMULATION :D

nearfield_box = sim.add_near2far(frq_cen, 0, 1,
                                 mp.Near2FarRegion(center=mp.Vector3(x=-2*r),
                                                   size=mp.Vector3(0,4*r,4*r),
Example #28
0
try:
    import meep.adjoint as mpa
except:
    import adjoint as mpa
import numpy as np
from autograd import numpy as npa
from autograd import tensor_jacobian_product
import unittest
from enum import Enum
mp.quiet(True)

MonitorObject = Enum('MonitorObject', 'EIGENMODE DFT')

resolution = 25

silicon = mp.Medium(epsilon=12)

sxy = 5.0
cell_size = mp.Vector3(sxy, sxy, 0)

dpml = 1.0
boundary_layers = [mp.PML(thickness=dpml)]

eig_parity = mp.EVEN_Y + mp.ODD_Z

design_shape = mp.Vector3(1.5, 1.5)
design_region_resolution = int(2 * resolution)
Nx = int(design_region_resolution * design_shape.x)
Ny = int(design_region_resolution * design_shape.y)

## ensure reproducible results
Example #29
0
import matplotlib as mpl
import meep
import meep_ext
from numpipe import scheduler, pbar
import miepy

job = scheduler()
nm = 1e-9
um = 1e-6

### Parameters
W = 160 * nm
H = 120 * nm

material = meep_ext.material.Au()
material = meep.Medium(index=3.5)

geometry = []
q = miepy.quaternion.from_spherical_coords(0, 0)
R = miepy.quaternion.as_rotation_matrix(q)

X = W / np.sqrt(2 * (1 - np.cos(2 * np.pi / 3)))
vertices = [
    meep.Vector3(X, 0, 0),
    meep.Vector3(-X / 2,
                 np.sqrt(3) / 2 * X, 0),
    meep.Vector3(-X / 2, -np.sqrt(3) / 2 * X, 0)
]
geometry.append(
    meep.Prism(center=meep.Vector3(0, 0, 0),
               height=H,
Example #30
0
    def __init__(self, dir_name, wavelength, thy_absorb, cyt_absorb):
        self.base_directory = base_directory + str(dir_name)

        self.wavelength = wavelength
        self.thy_absorb = thy_absorb
        self.cyt_absorb = cyt_absorb
        self.frequency = 1 / wavelength
        # Calculate wavelengths dependent on RI
        self.wavelength_in_media = wavelength / ri_media
        self.wavelength_in_cytoplasm = wavelength / ri_cytoplasm
        self.wavelength_in_thylakoid = wavelength / ri_thylakoid
        max_freq = self.frequency - 0.01
        min_freq = self.frequency + 0.01
        self.pulse_width = abs(max_freq - min_freq)

        cell = mp.Vector3(sxx, sxy, sxz)
        pml_layers = [mp.PML(dpml)]

        thylakoid_material = mp.Medium(index=ri_thylakoid,
                                       D_conductivity=2 * math.pi * self.frequency * (thy_absorb / (ri_thylakoid ** 2)))
        cytoplasm_material = mp.Medium(index=ri_cytoplasm,
                                       D_conductivity=2 * math.pi * self.frequency * (cyt_absorb / (ri_cytoplasm ** 2)))

        thylakoid_region = mp.Sphere(radius=cell_radius,
                                     center=mp.Vector3(0, 0, 0),
                                     material=thylakoid_material)
        cytoplasm_region = mp.Sphere(radius=cell_radius - thylakoid_thickness,
                                     center=mp.Vector3(0, 0, 0),
                                     material=cytoplasm_material)
        geometry = [thylakoid_region, cytoplasm_region]

        # Sources
        kdir = mp.Vector3(1, 0, 0)  # direction of k (length is irrelevant)
        n = ri_media  # refractive index of material containing the source
        k = kdir.unit().scale(2 * math.pi * self.frequency * n)  # k with correct length

        def pw_amp(k, x0):
            def _pw_amp(x):
                return cmath.exp(1j * k.dot(x + x0))
            return _pw_amp
        source = [
            mp.Source(
                mp.ContinuousSource(frequency=self.frequency, fwidth=self.pulse_width),  # along x axis
                component=mp.Ez,
                center=mp.Vector3(-0.5 * simulation_size, 0, 0),  # x, ,y ,z
                size=mp.Vector3(0, sxy, sxz),
                amp_func=pw_amp(k, mp.Vector3(x=-0.5 * simulation_size))
            )
        ]

        sim = mp.Simulation(
            cell_size=cell,
            sources=source,
            boundary_layers=pml_layers,
            resolution=resolution,
            geometry=geometry,
            default_material=mp.Medium(index=ri_media),
            force_complex_fields=complex_f,
            eps_averaging=eps_av,
        )

        def output_fields(sim):
            ez_output = open(base_directory + "Ez Field 430 HiAbs" + ".npy", 'wb')
            ez_array = sim.get_array(component=mp.Ez, cmplx=complex_f)
            ez_field_output = np.asarray(ez_array)
            np.save(ez_output, ez_field_output)
            ez_output.close()

            # ey_output = open(base_directory + "Ey Field 300 Std" + ".npy", 'wb')
            # ey_array = sim.get_array(component=mp.Ey, cmplx=complex_f)
            # ey_field_output = np.asarray(ey_array)
            # np.save(ey_output, ey_field_output)
            # ey_output.close()
            #
            # ex_output = open(base_directory + "Ex Field 300 std abs" + ".npy", 'wb')
            # ex_array = sim.get_array(component=mp.Ex, cmplx=complex_f)
            # ex_field_output = np.asarray(ex_array)
            # np.save(ex_output, ex_field_output)
            # ex_output.close()

            # eps_output = open(base_directory + "Refractive Index" + ".npy", 'wb')
            # eps_array = sim.get_array(component=mp.Dielectric, cmplx=complex_f)
            # np.save(eps_output, eps_array)
            # eps_output.close()

        sim.use_output_directory(self.base_directory)
        sim.run(mp.at_every(1, output_fields), until=t)