def layer_alloy(self, layer, fraction, mat1, mat2, model, plot=False): ### Bruggeman model must be specified if (model == 'Bruggeman'): ### Get RIs of two materials... mat1 can be ### a string that codes a material name or ### it can be a single number if (isinstance(mat1, str)): n_1 = datalib.Material_RI(self.lambda_array, mat1) else: n_1 = mat1 n_2 = datalib.Material_RI(self.lambda_array, mat2) for i in range(0, len(self.lambda_array)): if (isinstance(mat1, str)): eps1 = n_1[i] * n_1[i] else: eps1 = n_1 * n_1 eps2 = n_2[i] * n_2[i] flag = 1 f1 = (1 - fraction) f2 = fraction b = (2 * f1 - f2) * eps1 + (2 * f2 - f1) * eps2 arg = 8 * eps1 * eps2 + b * b srarg = np.sqrt(arg) if (np.imag(arg) < 0): flag = -1 else: flag = 1 epsBG = (b + flag * srarg) / 4. self.n[layer][i] = np.sqrt(epsBG) #### Default is Maxwell-Garnett else: if (isinstance(mat1, str)): n_1 = datalib.Material_RI(self.lambda_array, mat1) else: n_1 = mat1 n_2 = datalib.Material_RI(self.lambda_array, mat2) f = fraction for i in range(0, len(self.lambda_array)): ### eps1 == epsD and eps2 == epsM in MG notation if (isinstance(mat1, str)): epsD = n_1[i] * n_1[i] else: epsD = n_1 * n_1 epsM = n_2[i] * n_2[i] num = epsD * (2 * f * (epsM - epsD) + epsM + 2 * epsD) denom = 2 * epsD + epsM + f * (epsD - epsM) self.n[layer][i] = np.sqrt((num / denom)) if (plot == True): self.plot_index_alloy(n_1, n_2, self.n[layer]) return 1
def insert_layer(self, layer_number, material, thickness): ### just use numpy insert for thickness array new_d = np.insert(self.d, layer_number, thickness) ### because material names can have variable number of characters, ### insert may not reliably work... do "manually" new_m = [] for i in range(0, layer_number): new_m.append(self.matlist[i]) new_m.append(material) for i in range(layer_number + 1, len(self.matlist) + 1): new_m.append(self.matlist[i - 1]) ### de-allocate memory associated with self.d, self.matlist, self.n arrays self.d = None self.matlist = None self.n = None ### assign new values to self.d, self.matlist, self.n self.d = new_d self.matlist = new_m self.n = None self.n = np.zeros((len(self.d), len(self.lambda_array)), dtype=complex) for i in range(0, len(self.matlist)): self.n[:][i] = datalib.Material_RI(self.lambda_array, self.matlist[i]) ### in all cases, updated Fresnel quantities self.fresnel() if (self.explicit_angle): self.fresnel_ea() ### if a thermal application is requested, update Thermal Emission as well #if (self.stpv_emitter_calc or self.stpv_absorber_calc or self.cooling_calc or self.lightbulb_calc or self.color_calc): # self.ThermalEmission() if self.stpv_emitter_calc: self.thermal_emission() self.stpv_se() self.stpv_pd() self.stpv_etatpv() if (self.explicit_angle): self.thermal_emission_ea() self.stpv_se_ea() self.stpv_pd_ea() ### need to implement eta_tpv_ea method. #self.stpv_etatpv_ea() if self.stpv_absorber_calc: self.thermal_emission() if (self.explicit_angle): self.thermal_emission_ea() self.stpv_etaabs() else: self.stpv_etaabs() return 1
def layer_alloy(self, layer, fraction, mat1, mat2, model, plot=False): ### Bruggeman model must be specified if (model == 'Bruggeman'): ### Get RIs of two materials... mat1 can be ### a string that codes a material name or ### it can be a single number if (isinstance(mat1, str)): n_1 = datalib.Material_RI(self.lambda_array, mat1) else: n_1 = mat1 n_2 = datalib.Material_RI(self.lambda_array, mat2) for i in range(0, len(self.lambda_array)): if (isinstance(mat1, str)): eps1 = n_1[i] * n_1[i] else: eps1 = n_1 * n_1 eps2 = n_2[i] * n_2[i] flag = 1 f1 = (1 - fraction) f2 = fraction b = (2 * f1 - f2) * eps1 + (2 * f2 - f1) * eps2 arg = 8 * eps1 * eps2 + b * b srarg = np.sqrt(arg) if (np.imag(arg) < 0): flag = -1 else: flag = 1 epsBG = (b + flag * srarg) / 4. self.n[layer][i] = np.sqrt(epsBG) ## Test Generalized effective medium theory elif (model == 'parker'): v = 3 f = fraction if (isinstance(mat1, str)): n_1 = datalib.Material_RI(self.lambda_array, mat1) else: n_1 = mat1 n_2 = datalib.Material_RI(self.lambda_array, mat2) for i in range(0, len(self.lambda_array)): if (isinstance(mat1, str)): epse = n_1[i] * n_1[i] else: epse = n_1 * n_1 epsi = n_2[i] * n_2[i] # eps1 = inclusion, eps2 = enviroment Y = epsi - epse A = v B = (3 * epse + Y - (1 + v) * f * Y) C = -3 * epse * Y * f arg = (B * B) - 4 * A * C srarg = np.sqrt(arg) if (np.imag(arg) < 0): flag = -1 else: flag = 1 eps = (-B + flag * srarg) / (2 * A) self.n[layer][i] = np.sqrt(epse + eps) #### Default is Maxwell-Garnett else: if (isinstance(mat1, str)): n_1 = datalib.Material_RI(self.lambda_array, mat1) else: n_1 = mat1 n_2 = datalib.Material_RI(self.lambda_array, mat2) f = fraction for i in range(0, len(self.lambda_array)): ### eps1 == epsD and eps2 == epsM in MG notation if (isinstance(mat1, str)): epsD = n_1[i] * n_1[i] else: epsD = n_1 * n_1 epsM = n_2[i] * n_2[i] num = epsD * (2 * f * (epsM - epsD) + epsM + 2 * epsD) denom = 2 * epsD + epsM + f * (epsD - epsM) self.n[layer][i] = np.sqrt((num / denom)) if (plot == True): self.plot_index_alloy(n_1, n_2, self.n[layer]) return 1
def inline_structure(self, args): if 'Lambda_List' in args: lamlist = args['Lambda_List'] # nm = 1e-9 # lda_uv = np.linspace(251,370, num = 120) # 1nm resolution # lda_vis = np.linspace(373,1000,num = 210) # 3nm resolution # lda_ir = np.linspace(1100,30000,num = 290) # 100nm resolution # lda = np.concatenate((lda_uv,lda_vis,lda_ir), axis=0) #lda*nm # self.lambda_array = np.linspace(lamlist[0], lamlist[1], int(lamlist[2])) else: print(" Lambda array not specified! ") print(" Choosing default array of 1000 wl between 400 and 6000 nm") self.lambda_array = np.linspace(400e-9, 6000e-9, 1000) if 'Thickness_List' in args: self.d = args['Thickness_List'] ### default structure else: print(" Thickness array not specified!") print(" Proceeding with default structure - optically thick W! ") self.d = [0, 900e-9, 0] self.matlist = ['Air', 'W', 'Air'] self.n = np.zeros((len(self.d), len(self.lambda_array)), dtype=complex) for i in range(0, len(self.matlist)): self.n[:][i] = datalib.Material_RI(self.lambda_array, self.matlist[i]) if 'Material_List' in args: self.matlist = args['Material_List'] self.n = np.zeros((len(self.d), len(self.lambda_array)), dtype=complex) for i in range(0, len(self.matlist)): self.n[:][i] = datalib.Material_RI(self.lambda_array, self.matlist[i]) else: print(" Material array not specified!") print(" Proceeding with default structure - optically thick W! ") self.d = [0, 900e-9, 0] self.matlist = ['Air', 'W', 'Air'] self.n = np.zeros((len(self.d), len(self.lambda_array)), dtype=complex) for i in range(0, len(self.matlist)): self.n[:][i] = datalib.Material_RI(self.lambda_array, self.matlist[i]) ### Temperature arguments! if 'Temperature' in args: self.T_ml = args['Temperature'] elif 'Structure_Temperature' in args: self.T_ml = args['Structure_Temperature'] else: print(" Temperature not specified!") print(" Proceeding with default T = 300 K") self.T_ml = 300 if 'PV_Temperature' in args: self.T_cell = args['PV_Temperature'] else: self.T_cell = 300 if 'Ambient_Temperature' in args: self.T_amb = args['Ambient_Temperature'] else: self.T_amb = 300 ### Check to see what calculations should be done! if 'STPV_EMIT' in args: self.stpv_emitter_calc = args['STPV_EMIT'] else: self.stpv_emitter_calc = 0 if 'STPV_ABS' in args: self.stpv_absorber_calc = args['STPV_ABS'] else: self.stpv_absorber_calc = 0 if 'COOLING' in args: self.cooling_calc = args['COOLING'] else: self.cooling_calc = 0 if 'LIGHTBULB' in args: self.lightbulb_calc = args['LIGHTBULB'] else: self.lightbulb_calc = 0 if 'COLOR' in args: self.color_calc = args['COLOR'] else: self.color_calc = 0 if 'EXPLICIT_ANGLE' in args: self.explicit_angle = args['EXPLICIT_ANGLE'] else: self.explicit_angle = 0 if 'DEG' in args: self.deg = args['DEG'] else: self.deg = 7 return 1
import scipy.io as sio import multiprocessing as mp print("Number of processors: ", mp.cpu_count()) import time #Statements #%% # GET EFFECTIVE INDEX DATA FROM BRUGGEMAN APPROXIMATION # GET DATA FOR SIO2 AND SIN OVER DENSE WAVELENGTH RANGE nm = 1e-9 lda = linspace(200, 30000, 10000) # list of wavelengths in nm m = datalib.Material_RI(lda * nm, 'SiO2') #convert lda to SI unit fig1 = plt.figure() plt.plot(lda, real(m), 'k') plt.plot(lda, imag(m), 'r') #sio.savemat('P_SiO2_SiN_Ag.mat', {'P_cool_sio2_sin_np': P_cool_sio2_sin_np}) #%% INTERP MATERIALS!! ff = np.array([ 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 ]) / 100 m_sio2 = np.zeros((len(lda), len(ff)), dtype=np.complex64) for idx in range(0, len(ff)):
############################################################################## #%% """ Run the TMM code per wavelength for SiO2 NP on Si using IDEAL MATERIALS """ """ Define materials of interest for layered film simulation Notes: 1) materials are described in SI units 2) materials are stored in datalib 3) materials are output as m = n+j*k 4) materials are iterpolated in datalib based on input lda values """ m = datalib.Material_RI(lda * nm, 'RC0_1B_Si') #convert lda to SI unit msi_fn = interp1d(lda, m, kind='linear') # make mat data a FUNCTION of lda, in nm m = datalib.Material_RI(lda * nm, 'SiO2') #convert lda to SI unit msio2_fn = interp1d(lda, m, kind='linear') # make mat data a FUNCTION of lda, in nm #m = datalib.alloy(lda*nm, 0.238, 'Air','SiO2','Bruggeman') #msio2np_ideal_fn = interp1d(lda, m, kind='linear') # make mat data a FUNCTION of lda, in nm m = datalib.alloy(lda * nm, 0.238, 'Air', 'RC0_1B_SiO2', 'Bruggeman') msio2np_ideal_fn = interp1d( lda, m, kind='linear') # make mat data a FUNCTION of lda, in nm #m = datalib.alloy(lda*nm, 0.0674, 'Air','SiO2','Bruggeman')
#%% """ Run the TMM code per wavelength for SiO2 NP on Si using IDEAL MATERIALS """ """ Define materials of interest for layered film simulation Notes: 1) materials are described in SI units 2) materials are stored in datalib 3) materials are output as m = n+j*k 4) materials are iterpolated in datalib based on input lda values """ m = datalib.Material_RI(lda*nm, 'RC0_1D_Si') #convert lda to SI unit msi_fn = interp1d(lda, m, kind='linear') # make mat data a FUNCTION of lda, in nm m = datalib.Material_RI(lda*nm, 'SiO2') #convert lda to SI unit msio2_fn = interp1d(lda, m, kind='linear') # make mat data a FUNCTION of lda, in nm m1 = datalib.Material_RI(lda*nm, 'RC0_1D_Al2O3') #convert lda to SI unit m2 = datalib.Material_RI(lda*nm, 'Al2O3') plt.figure() plt.plot(lda/1000, real(m1),'k', label = 'n model') plt.plot(lda/1000, real(m2),'k:', label = 'n VASE stock') plt.plot(lda/1000, imag(m1),'r', label = 'k model') plt.plot(lda/1000, imag(m2),'r:', label = 'k VASE stock')
#%% """ Run the TMM code per wavelength for SiO2 NP on Si using IDEAL MATERIALS """ """ Define materials of interest for layered film simulation Notes: 1) materials are described in SI units 2) materials are stored in datalib 3) materials are output as m = n+j*k 4) materials are iterpolated in datalib based on input lda values """ m = datalib.Material_RI(lda*nm, 'AlOxChar3_1C_Au') #convert lda to SI unit mau_fn = interp1d(lda, m, kind='linear') # make mat data a FUNCTION of lda, in nm m = datalib.alloy(lda*nm, 0.416, 'Air','AlOxChar3_1A','Bruggeman') mnp_fn = interp1d(lda, m, kind='linear') # make mat data a FUNCTION of lda, in nm d_list = [inf, 5600, 300, inf] # list of layer thicknesses in nm c_list = ['i','c','c','i'] theta = 0 T_list = []; R_list = []; A_list = []; for lda0 in lda: # msi = msi_fn(lda0) # if (msi.imag < 0):
import matplotlib as mplib from scipy.interpolate import interp1d, InterpolatedUnivariateSpline nm = 1e-9 lda = linspace(8500, 9500, 1000) # list of wavelengths in nm def norm(m): return (real(m) - min(real(m))) / (max(real(m)) - min(real(m))), ( imag(m) - min(imag(m))) / (max(imag(m)) - min(imag(m))) #%% import numpy as np t_atmosphere = datalib.ATData(lda * 1e-9) m_mat = datalib.Material_RI(lda * nm, 'SiO2') #convert lda to SI unit m_MG1 = datalib.alloy(lda * nm, 0.1, 'Air', 'SiO2', 'MG') #m_MG2 = datalib.alloy(lda*nm, 0.8, 'Air','SiO2','MG') m_MG2 = datalib.alloy(lda * nm, 0.1, 'SiO2', 'Air', 'MG') n_mat, k_mat = norm(m_mat) idx_max_k_mat = np.argmax(k_mat) n_MG1, k_MG1 = norm(m_MG1) idx_max_k_MG1 = np.argmax(k_MG1) n_MG2, k_MG2 = norm(m_MG2) idx_max_k_MG2 = np.argmax(k_MG2) #plt.figure() #