Example #1
0
def test_dipoleRadiation():
    '''
  Plots the Electric field in the x,y plane from both a z and y oriented dipole.
  Right now, the y-dipole plots |E| -- ultimately this should be a vector plot to highlight
  the loop pattern.
  '''

    wl = 2

    #z-oriented dipole
    P = np.array([0, 0, 1])

    res = 100

    x = np.linspace(-5, 5, res)
    y = np.linspace(-5, 5, res)
    z = 0

    X, Y = np.meshgrid(x, y)
    Z = X * 0

    r = np.array([X, Y, Z])
    r = np.swapaxes(r, 0, 2)

    E = dipoleRadiation(wl, P, r)

    Ez = E[:, :, 2]

    vmax = 10  #np.amax(abs(Ez))
    vmin = -vmax
    plt.imshow(Ez.real,
               extent=putil.getExtent(x, y),
               cmap='RdBu',
               vmax=vmax,
               vmin=vmin)
    plt.colorbar()

    # y-oriented dipole
    P = np.array([0, 1, 0])
    E = dipoleRadiation(wl, P, r)

    Etot = np.array([np.linalg.norm(i)
                     for i in E.reshape(res**2, 3)]).reshape(res, res)

    plt.figure()
    plt.imshow(Etot.T,
               extent=putil.getExtent(x, y),
               cmap='hot',
               vmax=vmax,
               vmin=0)
    # plt.imshow(E[:,:,1].real.T,extent=putil.getExtent(x,y),cmap='RdBu',vmax=vmax,vmin=vmin)
    plt.colorbar()

    plt.show()
Example #2
0
def test_dipoleRadiation():
    '''
  
  '''

    wl = 2
    P = 1

    x = np.linspace(-5, 5, 100)
    y = np.linspace(-5, 5, 100)

    X, Y = np.meshgrid(y, x)

    r = sqrt(X**2 + Y**2)

    Fz = dipoleRadiation(wl, P, r)

    vmax = 1
    vmin = -vmax
    plt.imshow(Fz.real,
               extent=putil.getExtent(x, y),
               cmap='RdBu',
               vmax=vmax,
               vmin=vmin)
    plt.colorbar()
    plt.show()
Example #3
0
def test_addDipoles():

    wl = 1

    d1 = [-wl / 4., 0, 0]
    d2 = [wl / 4., 0, 0]

    ds = np.array([d1, d2])

    p1 = [0, 0, 1]
    p2 = [0, 0, 1]

    ps = np.array([p1, p2])

    res = 100
    xs = np.linspace(-5, 5, res)
    ys = np.linspace(-5, 5, res)

    targets = np.array([[i, j, 0] for i in xs for j in ys])

    E = [addDipoles(wl, ds, ps, t) for t in targets]
    E = np.array(E)
    Ez = E[:, 2].reshape(res, res)

    vmax = 50
    vmin = -vmax
    plt.imshow(Ez.real.T,
               extent=putil.getExtent(xs, ys),
               cmap='RdBu',
               vmax=vmax,
               vmin=vmin)
    plt.show()
Example #4
0
    def plotField(self, xmin, xmax, ymin, ymax, xres=100, yres=100):

        xs = np.linspace(xmin, xmax, xres)
        ys = np.linspace(ymin, ymax, yres)

        X, Y = np.meshgrid(xs, ys)
        Fz = np.zeros((len(xs), len(ys)), dtype=complex)

        # loop over all dipoles and sum contribution to scattered field
        for n in range(self.N):
            print 'plotField: processing dipole %u of %u' % (n, self.N)
            i = self.x[n]
            j = self.y[n]

            r = sqrt((X - i)**2 + (Y - j)**2)

            Fz += dipoleRadiation(self.wl, self.P[n], r)

        Fz_crop = Fz * (
            (abs(X) > self.width) +
            (abs(Y) > self.height) == 1)  # field with resonator removed
        vmax = np.amax(abs(Fz_crop)**2)
        # vmax = None

        plt.figure()
        # plt.imshow(Fz.real,cmap='RdBu',vmax=vmax,vmin=-vmax)
        plt.imshow(abs(Fz)**2,
                   extent=putil.getExtent(xs, ys),
                   cmap='hot',
                   vmax=vmax,
                   vmin=0)
        # plt.imshow(Fz.real,extent=putil.getExtent(xs,ys),cmap='RdBu',vmax=vmax,vmin=-vmax)
        plt.colorbar()
Example #5
0
def test_PW():
    '''
  
  '''

    angle = 25.
    wl = 2.

    x = np.linspace(-10, 10, 1000)
    y = np.linspace(-10, 10, 1000)

    X, Y = np.meshgrid(x, y)

    pw = PW(X, Y, angle, wl)

    plt.imshow(pw.real, extent=putil.getExtent(x, y), cmap='RdBu')
    plt.colorbar()
    plt.show()
Example #6
0
def main():
    '''
  Simulation Parameters
  '''

    wl = 4

    pol = 'Hz'

    # Resonator Properties
    AR = 1  # height / width
    w = 2.2
    h = .36
    # h = w * AR
    l = 100 * wl

    # w *= 1.
    # h *= 1.

    # Mode indices
    m = 4
    n = 1

    # Simulation Grid
    fieldRes = 30
    FFres = 200
    FFR = 20 * wl
    a = wl / 100.  # dipole lattice spacing
    '''
  Get Dipole positions and polarizations
  '''

    x = np.arange(-w / 2., w / 2., a)
    y = np.arange(-h / 2., h / 2., a)
    # z = np.arange(-l/2.,l/2.,a)
    z = np.array([0])

    # center array to ensure symmetry
    shift = lambda x: (x % a) / 2.

    x += shift(w)
    y += shift(h)
    z += shift(l)

    print 'Number of Dipoles = %u' % (len(x) * len(y) * len(z))

    dipoles = [[i, j, k] for i in x for j in y for k in z]
    dipoles = np.array(dipoles)

    amplitude = sin(m * pi / w *
                    (dipoles[:, 0] + w / 2.)) * sin(n * pi / h *
                                                    (dipoles[:, 1] + h / 2.))
    Ps = [np.array([0, 0, a]) for a in amplitude]
    '''
  FF plot
  '''

    theta, pwr = FF(wl, dipoles, Ps, R=FFR, res=FFres)

    plt.figure()
    plt.subplot(111, polar=True)
    plt.gca().grid(True)
    plt.plot(theta, pwr, color='r', lw=2)

    plt.figure()
    plt.plot(theta * 180 / pi - 90, pwr, color='r', lw=2)
    plt.xlim(0, 90)
    '''
  Plot Dipole Arrangement
  '''

    plt.figure()
    plt.imshow(amplitude.reshape(len(x), len(y), len(z))[:, :, 0].T,
               extent=putil.getExtent(x, y))

    plt.show()

    return 0
Example #7
0
def main():
    '''
	Complex slab mode solver based on "Exact Solution To Guided Wave Propagation in Lossy Films" by Nagel et al,
	Optics Express 2011

	Currently supports TE even modes only.
	'''

    hlam = 0.5

    nf = 2 + 0.5j
    nc = 1.5

    wl = 1
    h = hlam * wl
    k = 2 * pi / wl
    kf = nf * k
    kc = nc * k

    def f(kx):
        return kx * tan(kx * h) - sqrt(kf**2 - kc**2 - kx**2)

    f_vector = np.vectorize(f)

    def phi(wavevectors):
        b, a = wavevectors
        kx = b + 1j * a
        return np.real(f(kx) * f(kx).conj())

    def phiPlotter(kx):
        return np.real(10 * sp.log10(f(kx) * f(kx).conj()))

    phiPlotter = np.vectorize(phiPlotter)
    '''
	Find zeros in residue, convert to propagation constants
	'''

    # Generate residue for complex plane
    kmax = abs(kf)
    kres = 100
    a = np.linspace(0, kmax / 2, kres)
    b = np.linspace(0, 2 * kmax, kres)

    ## Use to match Fig 2 from paper
    # a = np.linspace(-1.5,1.5,20)
    # b = np.linspace(0,10,20)

    B, A = np.meshgrid(b, a)

    kx = B + 1j * A

    # Look for sign changes in real and imaginary parts of f(kx)
    fkx = f_vector(kx)
    sign_fr = np.sign(fkx.real)
    sign_fi = np.sign(fkx.imag)

    diff_fr = np.diff(sign_fr)
    diff_fi = np.diff(sign_fi)

    # Zeros must occur when both Real and Imag change sign simultaneously
    cross = np.abs(diff_fr) + np.abs(diff_fi)
    pts = np.where((cross == 4))
    guesses = kx[pts]

    # Find minimum residual near initial guess. Returns OptimizeResult object
    for g in guesses:
        res = sp.optimize.minimize(phi, [g.real, g.imag])

        if res.success:
            bx_min, ax_min = res.x
        else:
            print 'Minimize fail.'
            exit()

        kx_min = bx_min + 1j * ax_min

        # Find corresponding Beta (from equation A4)
        B = sqrt(kf**2 - kx_min**2)
        print 'kx:   %.3f + %.3fi' % (kx_min.real, kx_min.imag)
        print 'Beta: %.3f + %.3fi' % (B.real, B.imag)
    '''
	# Pretty pictures
	'''
    ext = np.array(putil.getExtent(b, a))
    asp = 'auto'

    fig, ax = plt.subplots(2, 2, figsize=(7, 7), sharex=True, sharey=True)

    # Residue plot

    ax[0, 0].set_title(r'$10\log_{10}(|f|^{2})$')

    resIm = ax[0, 0].imshow(phiPlotter(kx),
                            extent=ext,
                            vmax=40,
                            vmin=-20,
                            aspect=asp)

    #Colorbar
    # resmag = make_axes_locatable(ax[0])
    # cres = resmag.append_axes("right", size="2%", pad=0.05)
    # cbarres = plt.colorbar(resIm,cax=cres,format='%u')

    ax[0, 1].set_title(r'$\Delta$Sign $Re\{f\}$')
    ax[1, 1].set_title(r'$\Delta$Sign $Im\{f\}$')
    ax[1, 0].set_title(r'Crossings')

    ax[0, 1].imshow(diff_fr, extent=ext, aspect=asp, cmap='coolwarm')
    ax[1, 1].imshow(diff_fi, extent=ext, aspect=asp, cmap='coolwarm')
    ax[1, 0].imshow(cross, extent=ext, aspect=asp, cmap='afmhot')

    ax[1, 0].set_xlabel(r'$\beta_{x} \lambda_{o}$')
    ax[1, 1].set_xlabel(r'$\beta_{x} \lambda_{o}$')
    ax[0, 0].set_ylabel(r'$\alpha_{x}\lambda_{o}$')
    ax[1, 0].set_ylabel(r'$\alpha_{x}\lambda_{o}$')

    # Beta(n,d,wl=wl,pol=pol,polarity='even',Nmodes=None,plot=True)
    # fig.colorbar(ima)
    plt.show()

    return
Example #8
0
def example():
  
  
  #--------------------------------#
  # Parameters
  #--------------------------------#
  
  # Simulation
  wl = 400.
  k = 2*pi/wl
  
  w = 200
  h = 800
  
  m = 1
  n = 2
  
  # Plotting
  res = 500
  xmax = 800
  
  Ro = 1. #distance to measure field (m)
  angle_res = 100

  
  #--------------------------------#
  
  
  
  # Algorithm
  
  dipoles = getDipoles(m,n,w,h)
  
  xs = ys = np.linspace(-xmax,xmax,res)
  
  X,Y = np.meshgrid(xs,ys)
  
  for di,d in enumerate(dipoles):
        
    R = getR(d[0],d[1],X,Y)
    
    phi = pi*(getPhase(m,n,di))
    
    if di==0: Fz  = 1/R*exp(1j*(k*R + phi))
    else:     Fz += 1/R*exp(1j*(k*R + phi))
  
  
  # Plot Real Field
  fig = plt.figure()
  ax  = fig.add_subplot(111)

  Fz *= -1  #flip values so plot color matches dipole color
  Fz /= np.amax(abs(Fz))

  scale = 0.01
  
  im = ax.imshow(Fz.real,extent=putil.getExtent(xs,ys),vmax=scale,vmin=-1*scale,cmap='RdBu')
  fig.colorbar(im)
  
  drawDipoleBox(m,n,w,h,ax)
  
  for di,d in enumerate(dipoles):
    
    p = getPhase(m,n,di)
    ax.add_patch(Circle(d,15,facecolor=colors[p]))

  # Power plot
  fig = plt.figure()
  ax  = fig.add_subplot(111)

  P = abs(Fz)**2
  P /= np.amax(P)
  
  im = ax.imshow(P,extent=putil.getExtent(xs,ys),vmax=sqrt(scale),cmap='hot')
  fig.colorbar(im)
  
    
    
  # Plot Farfield
  ff_fig = plt.figure()
  ff_ax  = ff_fig.add_subplot(111,polar=True)
  ff_ax.grid(True)

  FFplot(ff_ax,wl,w,h,m,n,Ro=Ro,angle_res=angle_res)
  
  print getFF(wl,w,h,m,n,0)
    
  plt.show()
  
  return 0
Example #9
0
def overlay(modes='horizontal', asym=False, noLines=True):
    '''
	Display cavity mode map over FDFD results
	
	NOTES:
	
	- There is a reversal in polarization convention between FDFD and waveguides
	'''

    Q_TE_n4 = 'parameter sweeps/Q_TE_n4_45deg.pickle'
    Q_TM_n4 = 'parameter sweeps/Q_TM_n4_45deg.pickle'
    Q_TE_n4_0_deg = 'parameter sweeps/Q_TE_n4_0deg.pickle'
    Q_TE_n4_lossy = 'parameter sweeps/lossy/Q_TE_n4_k0_1_45deg.pickle'
    Qabs_TE_n4_lossy = 'parameter sweeps/lossy/Qabs_TE_n4_k0_1_45deg.pickle'
    Q_TE_n4_nsub2 = 'parameter sweeps/w_substrate/Q_TE_n4_nsub2_45deg.pickle'
    Q_TE_n4_metalsub = 'parameter sweeps/w_substrate/Q_TE_n4_esub-100_45deg.pickle'
    Q_TE_n4_metalsides = 'parameter sweeps/sidewalls/Q_TE_n4_nsides10j_wref_100.pickle'
    Q_TM_n4_metalsides = 'parameter sweeps/sidewalls/Q_TM_n4_nsides10j_wref_100.pickle'

    # Load FDFD data
    with open(PATH + Q_TM_n4, 'rb') as f:
        fdfd = pickle.load(f)

    ds = np.linspace(0.02, 3., 100)

    if not noLines:
        # Generate resonance map
        ds, ws = rect_cavity_modes(
            ncore=4,
            nclad=1,
            nsub=1,
            ms=np.array([3]),
            wmodes=7,
            pol='TM',
            linemap=False,
            colormap=False,
            usePhase=True  #0.5*(pi+phase(ds,pol='TM',mode=0,nsub=1))*pi/180. 
        )
        if asym and not (modes == 'horizontal'
                         or modes == 'vertical'):  #do vertical modes
            ds, wsv = rect_cavity_modes(ncore=4,
                                        nclad=1,
                                        nsub=1,
                                        ms=np.array([1]),
                                        wmodes=7,
                                        pol='TM',
                                        linemap=False,
                                        colormap=False,
                                        usePhase=True)
        else:
            wsv = ws

    fig = plt.figure(figsize=(6.5, 5))
    ax = fig.add_subplot(111)

    ext = putil.getExtent(ds, ds)

    vmax = 50
    vmin = 0
    im = ax.imshow(fdfd, extent=ext, vmin=vmin, vmax=vmax)
    fig.colorbar(im)

    if noLines:

        ax.set_xlabel(r'Width / $\lambda$')
        ax.set_ylabel(r'Height / $\lambda$')
        ax.set_title('Truncated Dielectric Slab Resonances')
        plt.show()
        exit()

    for i in range(len(ws[0, :, 0, 0])):
        for j in range(len(ws[0, 0, :, 0])):
            for k in range(5):
                if modes == 'horizontal':
                    if i % 2 == 0:
                        ax.plot(ws[:, i, j, k], ds, color='w', lw=3, ls='-')
                    if i % 2 == 1:
                        ax.plot(ws[:, i, j, k], ds, color='w', lw=3, ls=':')
                if modes == 'vertical':
                    ax.plot(ds, ws[:, i, j, k], color='w', lw=3, ls='-')
                if modes == 'both':
                    ax.plot(ds, wsv[:, i, j, k], color='w', lw=2,
                            ls='-')  #vert
                    ax.plot(ws[:, i, j, k], ds, color='w', lw=2,
                            ls='-')  #horiz

    ax.set_xlim(0.02, 3)
    ax.set_ylim(0.02, 3)
    ax.set_xlabel(r'Width / $\lambda$')
    ax.set_ylabel(r'Height / $\lambda$')
    ax.set_title('Truncated Dielectric Slab Resonances')
    #ax.set_title(r'$Q_{abs}$',fontsize=18)

    plt.show()