def test(): # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam0) # st.add_layer(1e3, si) st.add_layer(1900, sio2) st.add_layer(100, si) st.add_layer(20, sio2) st.add_layer(100, si) # st.add_layer(1900, sio2) st.add_layer(1e3, air) st.info() st.set_polarization('TM') st.set_field('H') st.set_leaky_or_guiding('guiding') alpha = st.calc_guided_modes(normalised=True) st.set_guided_mode(alpha[0]) result = st.calc_field_structure() z = result['z'] z = st.calc_z_to_lambda(z) E = result['field'] # Normalise fields # E /= max(E) plt.figure() plt.plot(z, abs(E) ** 2) for z in st.get_layer_boundaries()[:-1]: z = st.calc_z_to_lambda(z) plt.axvline(x=z, color='k', lw=1, ls='--') plt.show()
def guiding_plot(): """ Find the guiding modes (TE and TM) for a given structure. First plot s_11 as a function of beta. When s_11=0 this corresponds to a wave guiding mode. We then solve the roots (with scipy's brentq algorithm) and plot these as vertical red lines. Check that visually there is a red line at each pole so that none are missed. """ # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam0) st.set_field('E') st.set_leaky_or_guiding('guiding') # st.add_layer(0 * lam0, air) # st.add_layer(1 * lam0, si) # st.add_layer(0 * lam0, air) st.add_layer(300, sio2) st.add_layer(100, si) st.add_layer(20, sio2) st.add_layer(100, si) st.add_layer(300, air) st.info() # Prepare the figure fig, (ax1, ax2) = plt.subplots(2, 1, sharex='col', sharey='none') # TE modes st.set_polarization('TE') [beta, s_11] = st.s11_guided() ax1.plot(beta, s_11, label='TE') roots = st.calc_guided_modes(normalised=True) for root in roots: ax1.axvline(root, color='r') # TM modes st.set_polarization('TM') [beta, s_11] = st.s11_guided() ax2.plot(beta, s_11, label='TM') roots = st.calc_guided_modes(normalised=True) for root in roots: ax2.axvline(root, color='r') # Format plot # fig.tight_layout() ax1.set_ylabel('$S_{11}$') ax1.axhline(color='k') ax2.set_ylabel('$S_{11}$') ax2.set_xlabel('Normalised parallel wave vector (k_11/k)') ax2.axhline(color='k') ax1.legend() ax2.legend() if SAVE: plt.savefig('../Images/guided modes.png', dpi=300) plt.show()
def fig4(): """ n=3 or n=1 (air) to n=1.5 (Erbium deposition) semi-infinite half spaces. Plot the average total spontaneous emission rate of dipoles as a function of distance from the interface. """ # Vacuum wavelength lam_vac = 1550 # Plotting units units = lam_vac / (2 * pi) # Create plot f, ax = plt.subplots(figsize=(15, 7)) for n in [1, 3]: print('Evaluating n={:g}'.format(n)) # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam_vac) st.add_layer(4 * units, n) st.add_layer(4 * units, 1.5) st.info() # Calculate spontaneous emission over whole structure result = st.calc_spe_structure_leaky() z = result['z'] # Shift so centre of structure at z=0 z -= st.get_structure_thickness() / 2 spe = result['spe']['total'] # Plot spontaneous emission rates ax.plot(z/units, spe, label=('n='+str(n)), lw=2) ax.axhline(y=n, xmin=0, xmax=0.4, ls='dotted', color='k', lw=2) # Plot internal layer boundaries for z in st.get_layer_boundaries()[:-1]: # Shift so centre of structure at z=0 z -= st.get_structure_thickness() / 2 ax.axvline(z/units, color='k', lw=2) ax.axhline(1.5, ls='--', color='k', lw=2) ax.set_title('Spontaneous emission rate at boundary for semi-infinite media. RHS n=1.5.') ax.set_ylabel('$\Gamma / \Gamma_0$') ax.set_xlabel('Position z ($\lambda$/2$\pi$)') plt.legend() plt.tight_layout() if SAVE: plt.savefig('../Images/spe_vs_n.png', dpi=300) plt.show()
def fig3(): """ Plot the average decay rate of layer(normalised to bulk n) vs n of semi-infinite half space. Note: * we use the spe_layer function as we only care about the Er-doped layer. * th_num option is specified to give a higher accuracy on the integration. """ # Vacuum emission wavelength lam_vac = 1550 results = [] n_list = np.linspace(1, 2, 10) for n in n_list: print('Evaluating n={:g}'.format(n)) # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam_vac) st.add_layer(1550, 1.5) st.add_layer(0, n) # Calculate average total spontaneous emission of layer 0 (1st) result = st.calc_spe_layer_leaky(layer=0, emission='Lower', th_pow=11) spe = result['spe']['total'] result = st.calc_spe_layer_leaky(layer=0, emission='Upper', th_pow=11) spe += result['spe']['total'] spe /= 2 spe = np.mean(spe) # Normalise to bulk refractive index spe -= 1.5 # Append to list results.append(spe) results = np.array(results) # Plot results f, ax = plt.subplots(figsize=(15, 7)) ax.plot(n_list, results) ax.set_title('Average spontaneous emission rate over doped layer (d=1550nm) ' 'normalised to emission rate in bulk medium.') ax.set_ylabel('$\Gamma / \Gamma_1.5$') ax.set_xlabel('n') plt.tight_layout() if SAVE: plt.savefig('../Images/spe_vs_n.png', dpi=300) np.savez('../Data/spe_vs_n', n=n_list, spe=results) plt.show()
def test2(): # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam0) # st.add_layer(1e3, si) st.add_layer(1900, sio2) st.add_layer(100, si) st.add_layer(20, sio2) st.add_layer(100, si) st.add_layer(1e3, air) st.info() result = st.calc_spe_structure_guided() z = result['z'] spe = result['spe'] # Convert z into z/lam0 and center z = st.calc_z_to_lambda(z) fig, (ax1, ax2) = plt.subplots(2, 1, sharex='col', sharey='none') ax1.plot(z, spe['TE'], label='TE') ax1.plot(z, spe['TM_p'], label='TM') ax1.plot(z, spe['TE'] + spe['TM_p'], label='TE + TM') ax2.plot(z, spe['TM_s'], label='TM') for z in st.get_layer_boundaries()[:-1]: ax1.axvline(st.calc_z_to_lambda(z), color='k', lw=1, ls='--') ax2.axvline(st.calc_z_to_lambda(z), color='k', lw=1, ls='--') # ax1.set_ylim(0, 4) # ax2.set_ylim(0, 6) ax1.set_title('Spontaneous Emission Rate. Core n=3.48, Cladding n=1.') ax1.set_ylabel('$\Gamma / \Gamma_0$') ax2.set_ylabel('$\Gamma /\Gamma_0$') ax2.set_xlabel('z/$\lambda$') size = 12 ax1.legend(title='Horizontal Dipoles', prop={'size': size}) ax2.legend(title='Vertical Dipoles', prop={'size': size}) fig.tight_layout() if SAVE: plt.savefig('../Images/creatore_fig5.png', dpi=300) plt.show()
def example1(): """ Silicon to air semi-infinite half spaces. """ # Vacuum wavelength lam0 = 1550 n_list = np.linspace(1, 2, 3) spe_list = [] for n in n_list: print('Evaluating n={}'.format(n)) # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam0) st.add_layer(1550, 1.5) st.add_layer(1550, n) # Calculate spontaneous emission over whole structure result = st.calc_spe_structure_leaky() z = result['z'] spe = result['spe']['total'] # Only get spe rates in the active layer and then average ind = np.where(z <= 1550) spe = spe[ind] spe = np.mean(spe) - 1.5 spe_list.append(spe) spe_list = np.array(spe_list) # Plot spontaneous emission rates vs n f, ax = plt.subplots(figsize=(15, 7)) ax.plot(n_list, spe_list) ax.set_title('Average spontaneous emission rate over doped layer (d=1550nm) compared to bulk.') ax.set_ylabel('$\Gamma / \Gamma_1.5$') ax.set_xlabel('n') plt.legend() plt.tight_layout() if SAVE: plt.savefig('../Images/spe_vs_n.png', dpi=300) np.savez('../Data/spe_vs_n', n=n_list, spe=spe_list) plt.show()
def t2_spe_vs_n(): n_list = np.append(np.linspace(1, 1.45, num=25), np.linspace(1.45, 1.55, num=50)) n_list = np.append(n_list, np.linspace(1.55, 2, num=25)) # n_list = [1, 1.33, 1.37, 1.47] spe_list = [] leaky_list = [] guided_list = [] for n in n_list: print('Evaluating n={:g}'.format(n)) # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam0) st.add_layer(0, sio2) st.add_layer(d_etds, edts) st.add_layer(0, n) st.info() # Calculate spontaneous emission of layer 0 (1st) result = st.calc_spe_structure() leaky = result['leaky']['avg'] try: guided = result['guided']['avg'] except KeyError: guided = 0 # Average over layer leaky = np.mean(leaky) guided = np.mean(guided) # Append to list leaky_list.append(leaky) guided_list.append(guided) spe_list.append(leaky + guided) # Convert lists to arrays n_list = np.array(n_list) leaky_list = np.array(leaky_list) guided_list = np.array(guided_list) spe_list = np.array(spe_list) fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex='col', sharey='none') ax1.plot(n_list, spe_list, '.-', label='leaky + guided') ax2.plot(n_list, leaky_list, '.-', label='leaky') ax3.plot(n_list, guided_list, '.-', label='guided') ax3.set_xlim(1, 2) ax1.set_title('Average Spontaneous Emission Rate for Random Orientated Dipole in T2.') ax1.set_ylabel('$\Gamma / \Gamma_0$') ax2.set_ylabel('$\Gamma / \Gamma_0$') ax2.set_xlabel('n') ax1.legend() ax2.legend() ax3.legend() plt.tight_layout() if SAVE: plt.savefig('../Images/t2_vs_n.png', dpi=300) np.savez('../Data/t2_vs_n', n=n_list, spe=spe_list, guided=guided_list, leaky=leaky_list) plt.show()
def t2_leaky(): """ T2 EDTS layer next to air. """ # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam0) st.add_layer(2 * lam0, sio2) st.add_layer(d_etds, edts) st.add_layer(2 * lam0, air) st.info() # Calculate spontaneous emission for leaky and guided modes result = st.calc_spe_structure_leaky(th_pow=9) z = result['z'] z = st.calc_z_to_lambda(z) spe = result['spe'] # Plot spontaneous emission rates fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex='col', sharey='row', figsize=(15, 7)) ax1.plot(z, spe['TE'], label='TE') ax1.plot(z, spe['TM_p'], label='TM') ax1.plot(z, spe['TE'] + spe['TM_p'], label='TE + TM') ax2.plot(z, spe['TE_lower_full'] + spe['TM_p_lower_full'], label='Fully radiative lower outgoing') ax2.plot(z, spe['TE_lower_partial'] + spe['TM_p_lower_partial'], label='Partially radiative lower outgoing') ax2.plot(z, spe['TE_upper'] + spe['TM_p_upper'], label='Fully radiative upper outgoing') ax3.plot(z, spe['TM_s'], label='TM') ax4.plot(z, spe['TM_s_lower_full'], label='Fully radiative lower outgoing') ax4.plot(z, spe['TM_s_lower_partial'], label='Partially radiative lower outgoing') ax4.plot(z, spe['TM_s_upper'], label='Fully radiative upper outgoing') # Plot internal layer boundaries for z in st.get_layer_boundaries()[:-1]: ax1.axvline(st.calc_z_to_lambda(z), color='k', lw=1, ls='--') ax2.axvline(st.calc_z_to_lambda(z), color='k', lw=1, ls='--') ax3.axvline(st.calc_z_to_lambda(z), color='k', lw=1, ls='--') ax4.axvline(st.calc_z_to_lambda(z), color='k', lw=1, ls='--') # ax1.set_ylim(0, 4) # ax3.set_ylim(0, 6) # ax1.set_title('Spontaneous Emission Rate. LHS n=3.48, RHS n=1.') ax1.set_ylabel('$\Gamma / \Gamma_0$') ax3.set_ylabel('$\Gamma /\Gamma_0$') ax3.set_xlabel('z/$\lambda$') ax4.set_xlabel('z/$\lambda$') ax1.legend(title='Horizontal Dipoles', fontsize='small') ax2.legend(title='Horizontal Dipoles', fontsize='small') ax3.legend(title='Vertical Dipoles', fontsize='small') ax4.legend(title='Vertical Dipoles', fontsize='small') fig.tight_layout() if SAVE: plt.savefig('../Images/t2_leaky.png', dpi=300) plt.show()
def t2_fig4(): """ Silicon to air semi-infinite half spaces. """ # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam0) st.add_layer(2 * lam0, sio2) st.add_layer(d_etds, edts) st.add_layer(2 * lam0, air) st.info() # Calculate spontaneous emission over whole structure result = st.calc_spe_structure_leaky(th_pow=9) z = result['z'] spe = result['spe'] # Convert z into z/lam0 and center z = st.calc_z_to_lambda(z) # Plot spontaneous emission rates fig, (ax1, ax2) = plt.subplots(1, 2, sharey='row', figsize=(15, 5)) ax1.plot(z, (spe['TM_p_lower'] + spe['TE_lower']) / (spe['TE'] + spe['TM_p']), label='Lower') ax1.plot(z, (spe['TM_p_upper'] + spe['TE_upper']) / (spe['TE'] + spe['TM_p']), label='Upper') ax2.plot(z, (spe['TM_s_lower']) / spe['TM_s'], label='Lower') ax2.plot(z, (spe['TM_s_upper']) / spe['TM_s'], label='Upper') # Plot internal layer boundaries for z in st.get_layer_boundaries()[:-1]: ax1.axvline(st.calc_z_to_lambda(z), color='k', lw=1, ls='--') ax2.axvline(st.calc_z_to_lambda(z), color='k', lw=1, ls='--') # ax1.set_ylim(0, 1.1) # ax1.set_title('Spontaneous Emission Rate. LHS n=3.48, RHS n=1.') ax1.set_ylabel('$\Gamma / \Gamma_0$') ax1.set_xlabel('z/$\lambda$') ax2.set_xlabel('z/$\lambda$') ax1.legend(title='Horizontal Dipoles') ax2.legend(title='Vertical Dipoles') fig.tight_layout() if SAVE: plt.savefig('../Images/t2_fig4.png', dpi=300) plt.show()
def spe(): st = LifetimeTmm() st.set_vacuum_wavelength(lam0) # Add layers # st.add_layer(lam0, 1) st.add_layer(lam0, si) st.add_layer(lam0, air) st.add_layer(lam0, si) # st.add_layer(lam0, 1) # Get results result = st.calc_spe_structure_leaky() z = result['z'] spe = result['spe'] spe_TE = spe['TE_total'] spe_TM_p = spe['TM_p_total'] spe_TM_s = spe['TM_s_total'] # Plot spe rates fig = plt.figure() ax1 = fig.add_subplot(211) ax1.plot(z, spe_TE, label='TE') ax1.plot(z, spe_TM_p, label='TM') ax1.plot(z, spe_TE + spe_TM_p, 'k', label='TE + TM') ax2 = fig.add_subplot(212) ax2.plot(z, spe_TM_s, label='TM') ax1.set_title('Spontaneous Emission Rate. LHS n=3.48, RHS n=1.') ax1.set_ylabel('$\Gamma / \Gamma_0$') ax2.set_ylabel('$\Gamma /\Gamma_0$') ax2.set_xlabel('Position in layer (nm)') ax1.axhline(y=1, linestyle='--', color='k') ax2.axhline(y=1, linestyle='--', color='k') # Plot layer boundaries for z in st.get_layer_boundaries()[:-1]: ax1.axvline(z, color='k', lw=2) ax2.axvline(z, color='k', lw=2) ax1.legend(title='Horizontal Dipoles') ax2.legend(title='Vertical Dipoles') plt.show()
def t2(): """ T2 EDTS layer next to air. """ # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam0) st.add_layer(2 * lam0, sio2) st.add_layer(d_etds, edts) st.add_layer(2 * lam0, air) st.info() # Calculate spontaneous emission for leaky and guided modes result = st.calc_spe_structure(th_pow=9) z = result['z'] z = st.calc_z_to_lambda(z) # Plot results fig, (ax1, ax2) = plt.subplots(2, 1, sharex='col', sharey='none') ax1.plot(z, result['leaky']['avg'], label='leaky') try: ax2.plot(z, result['guided']['avg'], label='guided') except KeyError: pass # Plot internal layer boundaries for z in st.get_layer_boundaries()[:-1]: z = st.calc_z_to_lambda(z) ax1.axvline(z, color='k', lw=1, ls='--') ax2.axvline(z, color='k', lw=1, ls='--') # ax1.set_title('Spontaneous emission rate at boundary for semi-infinite media. LHS n=1.57.') ax1.set_ylabel('$\Gamma / \Gamma_0$') ax2.set_ylabel('$\Gamma / \Gamma_0$') ax2.set_xlabel('Position z ($\lambda$/2$\pi$)') ax1.legend() ax2.legend() plt.tight_layout() if SAVE: plt.savefig('../Images/t2.png', dpi=300) plt.show()
def purcell_factor(): """ T2 next to two mediums. Leaky and guided separate plots. Evaluate purcell factor for randomly orientated dipole averaged over film thickness. """ # Medium 1 # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam0) st.add_layer(2 * lam0, sio2) st.add_layer(d_etds, edts) st.add_layer(2 * lam0, air) st.info() # Calculate spontaneous emission for leaky and guided modes result = st.calc_spe_structure(th_pow=11) z = result['z'] z = st.calc_z_to_lambda(z) # Plot results fig, (ax1, ax2) = plt.subplots(2, 1, sharex='col', sharey='none') ax1.plot(z, result['leaky']['avg'], label='leaky, air') try: ax2.plot(z, result['guided']['avg'], label='guided, air') except KeyError: pass spe_air = result['leaky']['avg'] + result['guided']['avg'] # Medium 2 # Create structure st = LifetimeTmm() st.set_vacuum_wavelength(lam0) st.add_layer(2 * lam0, sio2) st.add_layer(d_etds, edts) st.add_layer(2 * lam0, water) st.info() # Calculate spontaneous emission for leaky and guided modes result = st.calc_spe_structure(th_pow=11) z = result['z'] z = st.calc_z_to_lambda(z) # Plot results ax1.plot(z, result['leaky']['avg'], label='leaky, water') try: ax2.plot(z, result['guided']['avg'], label='guided, water') except KeyError: pass spe_water = result['leaky']['avg'] + result['guided']['avg'] fp = np.mean(spe_water) / np.mean(spe_air) print('Purcell Factor: {:e}'.format(fp)) # Plot internal layer boundaries for z in st.get_layer_boundaries()[:-1]: z = st.calc_z_to_lambda(z) ax1.axvline(z, color='k', lw=1, ls='--') ax2.axvline(z, color='k', lw=1, ls='--') # ax1.set_title('Spontaneous emission rate at boundary for semi-infinite media. LHS n=1.57.') ax1.set_ylabel('$\Gamma / \Gamma_0$') ax2.set_ylabel('$\Gamma / \Gamma_0$') ax2.set_xlabel('Position z ($\lambda$)') ax1.legend() ax2.legend() plt.tight_layout() if SAVE: plt.savefig('../Images/T2_purcell_factor.png', dpi=300) fig, ax1 = plt.subplots() z = result['z'] ax1.plot(z, spe_air, label='Air') ax1.plot(z, spe_water, label='Water') # Plot internal layer boundaries for z in st.get_layer_boundaries()[:-1]: z = st.calc_z_to_lambda(z) ax1.axvline(z, color='k', lw=1, ls='--') ax1.set_ylabel('$\Gamma / \Gamma_0$') ax1.set_xlabel('Position z ($\lambda$)') # ax1.get_xaxis().get_major_formatter().set_useOffset(False) ax1.legend() plt.tight_layout() if SAVE: plt.savefig('../Images/T2_purcell_factor_total.png', dpi=300) plt.show()