def _conductivity(self, Na, Nd, nxc, **kwargs): Nid, Nia = get_carriers(Na, Nd, 0, temp=self.cal_dts['temp'], ni_author=self.cal_dts['nieff_author'] ) if np.all(Nid > Nia): Nid = self.ion.update_dopant_ionisation( Nid, nxc, self.cal_dts['dopant']) elif np.all(Nia > Nid): Nia = self.ion.update_dopant_ionisation( Nia, nxc, self.cal_dts['dopant']) ne, nh = get_carriers(Nid, Nia, nxc, temp=self.cal_dts['temp'], ni_author=self.cal_dts['nieff_author'] ) mob_e = self.Mob.electron_mobility(nxc, Na, Nd, temp=self.cal_dts['temp']) mob_h = self.Mob.hole_mobility(nxc, Na, Nd, temp=self.cal_dts['temp']) # print mob_h, mob_e, Na return const.e * (mob_e * ne + mob_h * nh)
def _conductivity(self, **kwargs): Nid, Nia = get_carriers(nxc=0, Na=self.cal_dts['Na'], Nd=self.cal_dts['Nd'], temp=self.cal_dts['temp'], ni_author=self.cal_dts['nieff_author'] ) if np.all(Nid > Nia): Nid = self.ion.update_dopant_ionisation( Nid, nxc, impurity=self.cal_dts['dopant']) elif np.all(Nia > Nid): Nia = self.ion.update_dopant_ionisation( Nia, nxc=self.cal_dts['nxc'], impurity=self.cal_dts['dopant']) ne, nh = get_carriers(Nid, Nia, nxc=self.cal_dts['nxc'], temp=self.cal_dts['temp'], ni_author=self.cal_dts['nieff_author'] ) mob_e = self.Mob.electron_mobility(nxc=self.cal_dts['nxc'], Na=self.cal_dts['Na'], Nd=self.cal_dts['Nd'], temp=self.cal_dts['temp'] ) mob_h = self.Mob.hole_mobility(nxc=self.cal_dts['nxc'], Na=self.cal_dts['Na'], Nd=self.cal_dts['Nd'], temp=self.cal_dts['temp']) return const.e * (mob_e * ne + mob_h * nh)
def generteCaldts(T, Ndop, doptypelist, ionauthor='Altermatt_2006_table1', vthauthor='Green_1990', ni_author='Couderc_2014', **kwarg): vth_e300, vth_h300 = Vel_th().update(temp=300, author=vthauthor) Caldts = [] for i in range(len(T)): vth_e, vth_h = Vel_th().update(temp=T[i], author=vthauthor) Ni = ni().update(temp=T[i], author=ni_author) doptype = doptypelist[i] if doptype == 'n': Nidop = Ion(temp=T[i], ni_author=ni_author).update_dopant_ionisation( N_dop=Ndop[i], nxc=0, impurity='phosphorous', author=ionauthor) n0, p0 = CF.get_carriers(1, Nidop, 0, temp=T[i], ni_author=ni_author) elif doptype == 'p': Nidop = Ion(temp=T[i], ni_author=ni_author).update_dopant_ionisation( N_dop=Ndop[i], nxc=0, impurity='boron', author=ionauthor) n0, p0 = CF.get_carriers(Nidop, 0, 0, temp=T[i], ni_author=ni_author) dts = { 'ni': Ni, 'vth_e': vth_e, 'vth_h': vth_h, 'n0': n0, 'p0': p0, 'T': T[i], 'doptype': doptype, 'vth_e300': vth_e300, 'vth_h300': vth_h300 } Caldts.append(dts.copy()) return Caldts
def _tau(self, nxc, tau_e, tau_h, Et): """ The Shockley Read Hall lifetime for a defect level in the band gap. This is calculated from the kinetics of repairing. """ # the escape from defects nh1 = self.ni.ni * \ np.exp(-Et * const.e / (const.k * self._cal_dts['temp'])) ne1 = self.ni.ni * \ np.exp(Et * const.e / (const.k * self._cal_dts['temp'])) # get the number of carriers ne, nh = get_carriers(Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'], nxc=self._cal_dts['nxc'], temp=self._cal_dts['temp'], material=self._cal_dts['material'], ni=self.ni.ni) # calculate the recombination rate U = (ne * nh - self.ni.ni**2) / \ (tau_h * (ne + ne1) + tau_e * (nh + nh1)) return self._cal_dts['nxc'] / U
def update(self, **kwargs): ''' Calculates the band gap narrowing Inputs: Na, Nd, delta n, temp, ni output: band gap narrowing in eV ''' self.calculationdetails = kwargs # a check to make sure the model hasn't changed if 'author' in kwargs.keys(): self.change_model(self._cal_dts['author']) # this should be change an outside function alter ne, nh = GF.get_carriers(Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'], nxc=self._cal_dts['nxc'], temp=self._cal_dts['temp']) doping = np.array(np.abs(self._cal_dts['Na'] - self._cal_dts['Nd'])) return getattr(Bgn, self.model)( self.vals, Na=np.copy(self._cal_dts['Na']), Nd=np.copy(self._cal_dts['Nd']), ne=ne, nh=nh, temp=self._cal_dts['temp'], doping=doping)
def ambipolar(self, ni_author=None, **kwargs): ''' returns the ambipolar mobility inputs: ni_author: (optional, str) an author for the intrinsic carrier density kwargs: (optinal) any value with _cal_dts, for which the mobility depends on output: ambipolar mobility in cm^2 V^-1 s^-1 ''' if bool(kwargs): self.calculationdetails = kwargs # get the number of carriers ne, nh = get_carriers( Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'], nxc=self._cal_dts['nxc'], temp=self._cal_dts['temp'], material=self._cal_dts['material'], ni_author=ni_author, ni=9e9) mob_h = self.hole_mobility() mob_e = self.electron_mobility() # caculate the ambipolar mobility according to mob_ambi = (ne + nh) / (nh / mob_e + ne / mob_h) return mob_ambi
def ambipolar(self, ni_author=None, **kwargs): ''' returns the ambipolar mobility inputs: ni_author: (optional, str) an author for the intrinsic carrier density kwargs: (optinal) any value with _cal_dts, for which the mobility depends on output: ambipolar mobility in cm^2 V^-1 s^-1 ''' if bool(kwargs): self.calculationdetails = kwargs # get the number of carriers ne, nh = get_carriers(Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'], nxc=self._cal_dts['nxc'], temp=self._cal_dts['temp'], material=self._cal_dts['material'], ni_author=ni_author, ni=9e9) mob_h = self.hole_mobility() mob_e = self.electron_mobility() # caculate the ambipolar mobility according to mob_ambi = (ne + nh) / (nh / mob_e + ne / mob_h) return mob_ambi
def _tau(self, nxc, tau_e, tau_h, Et): """ The Shockley Read Hall lifetime for a defect level in the band gap. This is calculated from the kinetics of repairing. """ # the escape from defects nh1 = self.ni.ni * \ np.exp(-Et * const.e / (const.k * self._cal_dts['temp'])) ne1 = self.ni.ni * \ np.exp(Et * const.e / (const.k * self._cal_dts['temp'])) # get the number of carriers ne, nh = get_carriers(Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'], nxc=self._cal_dts['nxc'], temp=self._cal_dts['temp'], material=self._cal_dts['material'], ni=self.ni.ni ) # calculate the recombination rate U = (ne * nh - self.ni.ni**2) / \ (tau_h * (ne + ne1) + tau_e * (nh + nh1)) return self._cal_dts['nxc'] / U
def update(self, **kwargs): ''' Calculates the band gap narrowing Inputs: Na, Nd, delta n, temp, ni output: band gap narrowing in eV ''' self.calculationdetails = kwargs # a check to make sure the model hasn't changed if 'author' in kwargs.keys(): self.change_model(self._cal_dts['author']) # this should be change an outside function alter ne, nh = GF.get_carriers(Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'], nxc=self._cal_dts['nxc'], temp=self._cal_dts['temp']) doping = np.array(np.abs(self._cal_dts['Na'] - self._cal_dts['Nd'])) return getattr(Bgn, self.model)( self.vals, Na=np.copy(self._cal_dts['Na']), Nd=np.copy(self._cal_dts['Nd']), ne=ne, nh=nh, temp=self._cal_dts['temp'], doping=doping)
def update_dopant_ionisation(self, N_dop, nxc, impurity, **kwargs): ''' This is a special function used to determine the number of ionised dopants given a number of excess carriers, and a single dopant type. inputs: N_dop: (float; cm^-3) The dopant density nxc: (float; cm^-3) The excess carrier density impurity: (str) The name of the dopant used e.g. boron, phosphorous. The dopants available depend on the model used output: N_idop: (float cm^-2) The number of ionised dopants ''' self.calculationdetails = kwargs # a check to make sure the model hasn't changed if 'author' in kwargs.keys(): self.change_model(self._cal_dts['author']) N_idop = N_dop if not isinstance(N_idop, np.ndarray): N_idop = np.asarray([N_idop]) if not isinstance(N_dop, np.ndarray): N_dop = np.asarray([N_dop]) if impurity in self.vals.keys(): # TO DO, change this from just running 10 times to a proper check for i in range(10): if self.vals['tpe_' + self.vals[impurity]] == 'donor': Nd = np.copy(N_idop) Na = np.zeros(Nd.shape) elif self.vals['tpe_' + self.vals[impurity]] == 'acceptor': Na = np.copy(N_idop) Nd = np.zeros(Na.shape) else: print('something went wrong in ionisation model') ne, nh = CF.get_carriers(Na, Nd, nxc, temp=self._cal_dts['temp'], material=self._cal_dts['material'], ni=self._cal_dts['ni_author']) N_idop = self.update(N_dop, ne, nh, impurity) else: print(r'Not a valid impurity, returning 100% ionisation') return N_idop
def update_dopant_ionisation(self, N_dop, nxc, impurity, **kwargs): ''' This is a special function used to determine the number of ionised dopants given a number of excess carriers, and a single dopant type. inputs: N_dop: (float; cm^-3) The dopant density nxc: (float; cm^-3) The excess carrier density impurity: (str) The name of the dopant used e.g. boron, phosphorous. The dopants available depend on the model used output: N_idop: (float cm^-2) The number of ionised dopants ''' self.calculationdetails = kwargs # a check to make sure the model hasn't changed if 'author' in kwargs.keys(): self.change_model(self._cal_dts['author']) if not isinstance(N_dop, np.ndarray): N_dop = np.asarray([N_dop]) N_idop = np.copy(N_dop) if impurity in self.vals.keys(): # TO DO, change this from just running 10 times to a proper check for i in range(10): if self.vals['tpe_' + self.vals[impurity]] == 'donor': Nd = np.copy(N_idop) Na = np.zeros(Nd.shape) elif self.vals['tpe_' + self.vals[impurity]] == 'acceptor': Na = np.copy(N_idop) Nd = np.zeros(Na.shape) else: print('something went wrong in ionisation model') ne, nh = CF.get_carriers( Na, Nd, nxc, temp=self._cal_dts['temp'], material=self._cal_dts['material'], ni=self._cal_dts['ni_author']) N_idop = self.update( N_imp=N_dop, ne=ne, nh=nh, impurity=impurity) else: print(r'Not a valid impurity, returning 100% ionisation') return N_idop
def uDCS_compensated(carrier, vals, nh, ne, Na, Nd, temp): ''' A modifcation by Schindler that provides the mobility for compensated doped material. ''' carrier_sum = nh + ne ne0, nh0 = GF.get_carriers(Na=Na, Nd=Nd, nxc=0, temp=300.) C_l = (Na + Nd) / (nh0 + ne0) if C_l < 1: C_l = 1 nsc = Nsc(carrier, vals, nh, ne, Na, Nd) nsceff = Nsceff(carrier, vals, nh, ne, Na, Nd, temp) # determine e and h from which i majority def cal_maj(): def beta2(): tref = 37.9 * np.log(vals['cl_ref']**2 * (Na + Nd) / 1e19 + 3.6) return 1 + 60. / np.sqrt(vals['cl_ref']) * \ np.exp(-(temp / tref + 1.18)**2) return un(carrier, vals, 300) * nsc / nsceff * ( (nsc / vals['nref_' + carrier])**(vals['alpha_' + carrier]) / (temp / vals['temp_refc'])**(3 * vals['alpha_' + carrier] - 1.5) + ( (C_l**beta2() - 1.) / vals['cl_ref'])**vals['beta1'] )**(-1.) + \ (uc(carrier, vals, 300) * carrier_sum / nsceff) *\ (vals['temp_refc'] / temp)**(0.5) def cal_min(): return un(carrier, vals, 300) * nsc / nsceff * ( (nsc / vals['nref_' + carrier])**(vals['alpha_' + carrier]) / (temp / vals['temp_refc'])**(3. * vals['alpha_' + carrier] - 1.5) + ( ((Na + Nd) / vals['n_ref3']) * (C_l - 1.) / vals['cl_ref'])**vals['beta1'] )**(-1.) + \ (uc(carrier, vals, 300) * carrier_sum / nsceff) * \ (vals['temp_refc'] / temp)**(0.5) mob = 1 # if the carriers are electrons change the following if statement if carrier == 'e': mob = -1 # if the holes are larger at any point, assume # they are the majority carriers if np.any(nh * mob > ne * mob): mob = cal_min() else: mob = cal_maj() return mob
def unified_mobility_compensated(vals, Na, Nd, nxc, temp, carrier, **kwargs): """ Thaken from: [1] D. B. M. Klaassen, "A unified mobility model for device simulation-I. Model equations and concentration dependence" Solid. State. Electron., vol. 35, no. 7, pp. 953-959, Jul. 1992. [2] D. B. M. Klaassen, "A unified mobility model for device simulation-II. Temperature dependence of carrier mobility and lifetime," Solid. State. Electron., vol. 35, no. 7, pp. 961-967, Jul. 1992. The model takes the sample inputs of ionised impurities and carrier concentrations This is the Klaassen's mobility model, for which the calculations with two exceptions: (i) r5 is set to -0.8552 rather than -0.01552 (see Table 2 of [1]), (ii) Eq. A3 of [1] is adjusted such that PCWe is determined with Ne,sc rather than (Z^3 Ni) and PCWh is determined with Nh,sc rather than (Z^3 Ni); these changes give a better fit to the solid calculated lines in Figures 6 and 7 of [1], which better fits the experimental data. These modifications are also contained in Sentaurus's version of Klaassen's model [5]. Klaassen's mobility model fits reasonably with experimental data over an estimated temperature range of 100 - 450 K. Its accuracy is greatest at 300 K (see [1,2]). """ # these are the values for phosphorous and boron respectively. # Original value # r5 = -0.01552, changing this means changing 2 equations as well # a switch used for different types # change to hle and electron for clarity type_dic = {'hole': 'h', 'electron': 'e'} if carrier in type_dic: carrier = type_dic[carrier] else: print('incorrect input for carrier input') # Things to fix up # ni = ni # the only thing ni is used for, this can be factored out so these values # are passed to this function ne, nh = GF.get_carriers(Na=Na, Nd=Nd, nxc=nxc, temp=temp) return 1. / (1. / uDCS(carrier, vals, nh, ne, Na, Nd, temp) + 1. / uLS(carrier, vals, temp))
def unified_mobility_compensated(vals, Na, Nd, nxc, temp, carrier, **kwargs): """ Thaken from: [1] D. B. M. Klaassen, "A unified mobility model for device simulation-I. Model equations and concentration dependence" Solid. State. Electron., vol. 35, no. 7, pp. 953-959, Jul. 1992. [2] D. B. M. Klaassen, "A unified mobility model for device simulation-II. Temperature dependence of carrier mobility and lifetime," Solid. State. Electron., vol. 35, no. 7, pp. 961-967, Jul. 1992. The model takes the sample inputs of ionised impurities and carrier concentrations This is the Klaassen's mobility model, for which the calculations with two exceptions: (i) r5 is set to -0.8552 rather than -0.01552 (see Table 2 of [1]), (ii) Eq. A3 of [1] is adjusted such that PCWe is determined with Ne,sc rather than (Z^3 Ni) and PCWh is determined with Nh,sc rather than (Z^3 Ni); these changes give a better fit to the solid calculated lines in Figures 6 and 7 of [1], which better fits the experimental data. These modifications are also contained in Sentaurus's version of Klaassen's model [5]. Klaassen's mobility model fits reasonably with experimental data over an estimated temperature range of 100 - 450 K. Its accuracy is greatest at 300 K (see [1,2]). """ # these are the values for phosphorous and boron respectively. # Original value # r5 = -0.01552, changing this means changing 2 equations as well # a switch used for different types # change to hle and electron for clarity type_dic = {"hole": "h", "electron": "e"} if carrier in type_dic: carrier = type_dic[carrier] else: print("incorrect input for carrier input") # Things to fix up # ni = ni # the only thing ni is used for, this can be factored out so these values # are passed to this function ne, nh = GF.get_carriers(Na=Na, Nd=Nd, nxc=nxc, temp=temp) return 1.0 / (1.0 / uDCS(carrier, vals, nh, ne, Na, Nd, temp) + 1.0 / uLS(carrier, vals, temp))
def _conductivity(self, **kwargs): self.calculationdetails = kwargs self._update_links() Nid, Nia = get_carriers(nxc=0, Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'], temp=self._cal_dts['temp'], ni_author=self._cal_dts['nieff_author'] ) if np.all(Nid > Nia): Nid = self.ion.update_dopant_ionisation( N_dop=Nid, nxc=self._cal_dts['nxc'], impurity=self._cal_dts['dopant']) elif np.all(Nia > Nid): Nia = self.ion.update_dopant_ionisation( N_dop=Nia, nxc=self._cal_dts['nxc'], impurity=self._cal_dts['dopant']) ne, nh = get_carriers( Na=Nia, Nd=Nid, nxc=self._cal_dts['nxc'], temp=self._cal_dts['temp'], ni_author=self._cal_dts['nieff_author'] ) mob_e = self.Mob.electron_mobility(nxc=self._cal_dts['nxc'], Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'] ) mob_h = self.Mob.hole_mobility(nxc=self._cal_dts['nxc'], Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd']) return const.e * (mob_e * ne + mob_h * nh)
def dorkel(vals, Na, Nd, nxc, temp, carrier, **kwargs): ''' inputs: impurty: the number of impurities (cm^-3) min_carr_den: the number of minoirty carrier densities (cm^-3) maj_car_den: the number of majority carrier densities (cm^-3) temp: temperature (K) output: electron mobility (cm^2 V^-1 s^-1) hole mobility (cm^2 V^-1 s^-1) ''' impurity = Na + Nd ne, nh = GF.get_carriers(Na, Nd, nxc, temp=temp) # print Na, Nd, nxc, temp if np.all(nh < ne): nxc = nh maj_car_den = ne elif np.all(nh >= ne): maj_car_den = nh nxc = ne else: sys.exit("Mixed doping types not permitted") # this relates the carrier to the extension in the variable name if carrier == 'electron': carrier = 'e' elif carrier == 'hole': carrier = 'h' else: sys.exit("inappropriate values for carrier passed") # determine hole dependent carrier partial mobilities mu_L = lattice_mobility(vals, temp, carrier) mu_i = impurity_mobility(vals, impurity, temp, carrier) # determine both carrier scattering mobilities mu_css = carrier_scattering_mobility( vals, nxc, maj_car_den, temp) # determine sudo function X = np.sqrt(6. * mu_L * (mu_i + mu_css) / (mu_i * mu_css)) # combine partial moblities into total mu = mu_L * (1.025 / (1. + (X / 1.68)**(1.43)) - 0.025) return mu
def uDCS_compensated(carrier, vals, nh, ne, Na, Nd, temp): """ A modifcation by Schindler that provides the mobility for compensated doped material. """ carrier_sum = nh + ne ne0, nh0 = GF.get_carriers(Na=Na, Nd=Nd, nxc=0, temp=300.0) C_l = (Na + Nd) / (nh0 + ne0) if C_l < 1: C_l = 1 nsc = Nsc(carrier, vals, nh, ne, Na, Nd) nsceff = Nsceff(carrier, vals, nh, ne, Na, Nd, temp) # determine e and h from which i majority def cal_maj(): def beta2(): tref = 37.9 * np.log(vals["cl_ref"] ** 2 * (Na + Nd) / 1e19 + 3.6) return 1 + 60.0 / np.sqrt(vals["cl_ref"]) * np.exp(-(temp / tref + 1.18) ** 2) return un(carrier, vals, 300) * nsc / nsceff * ( (nsc / vals["nref_" + carrier]) ** (vals["alpha_" + carrier]) / (temp / vals["temp_refc"]) ** (3 * vals["alpha_" + carrier] - 1.5) + ((C_l ** beta2() - 1.0) / vals["cl_ref"]) ** vals["beta1"] ) ** (-1.0) + (uc(carrier, vals, 300) * carrier_sum / nsceff) * (vals["temp_refc"] / temp) ** (0.5) def cal_min(): return un(carrier, vals, 300) * nsc / nsceff * ( (nsc / vals["nref_" + carrier]) ** (vals["alpha_" + carrier]) / (temp / vals["temp_refc"]) ** (3.0 * vals["alpha_" + carrier] - 1.5) + (((Na + Nd) / vals["n_ref3"]) * (C_l - 1.0) / vals["cl_ref"]) ** vals["beta1"] ) ** (-1.0) + (uc(carrier, vals, 300) * carrier_sum / nsceff) * (vals["temp_refc"] / temp) ** (0.5) mob = 1 # if the carriers are electrons change the following if statement if carrier == "e": mob = -1 # if the holes are larger at any point, assume # they are the majority carriers if np.any(nh * mob > ne * mob): mob = cal_min() else: mob = cal_maj() return mob
def dorkel(vals, Na, Nd, nxc, temp, carrier, **kwargs): ''' inputs: impurty: the number of impurities (cm^-3) min_carr_den: the number of minoirty carrier densities (cm^-3) maj_car_den: the number of majority carrier densities (cm^-3) temp: temperature (K) output: electron mobility (cm^2 V^-1 s^-1) hole mobility (cm^2 V^-1 s^-1) ''' impurity = Na + Nd ne, nh = GF.get_carriers(Na, Nd, nxc, temp=temp) print Na, Nd, nxc, temp if np.all(nh < ne): nxc = nh maj_car_den = ne elif np.all(nh >= ne): maj_car_den = nh nxc = ne else: sys.exit("Mixed doping types not permitted") # this relates the carrier to the extension in the variable name if carrier == 'electron': carrier = 'e' elif carrier == 'hole': carrier = 'h' else: sys.exit("inappropriate values for carrier passed") # determine hole dependent carrier partial mobilities mu_L = lattice_mobility(vals, temp, carrier) mu_i = impurity_mobility(vals, impurity, temp, carrier) # determine both carrier scattering mobilities mu_css = carrier_scattering_mobility(vals, nxc, maj_car_den, temp) # determine sudo function X = np.sqrt(6. * mu_L * (mu_i + mu_css) / (mu_i * mu_css)) # combine partial moblities into total mu = mu_L * (1.025 / (1. + (X / 1.68)**(1.43)) - 0.025) return mu
def update_dopant_ionisation(self, N_dop, nxc, impurity, temp=None, author=None): ''' This is a special function used to determine the number of ionised dopants given a number of excess carriers, and a single dopant type. inputs: N_dop: (float; cm^-3) The dopant density nxc: (float; cm^-3) The excess carrier density impurity: (str) The name of the dopant used e.g. boron, phosphorous. The dopants available depend on the model used output: N_idop: (float cm^-2) The number of ionised dopants ''' if temp is None: temp = self.temp if author is not None: self.change_model(author) N_idop = N_dop if impurity in self.vals.keys(): # TO DO, change this from just running 10 times to a proper check for i in range(10): if self.vals['tpe_' + self.vals[impurity]] == 'donor': Nd = N_idop Na = 0 elif self.vals['tpe_' + self.vals[impurity]] == 'acceptor': Na = N_idop Nd = 0 ne, nh = CF.get_carriers( Na, Nd, nxc, temp=temp, matterial='Si') N_idop = self.update( N_dop, ne, nh, impurity, temp=temp, author=None) else: print r'Not a valid impurity, returning 100% ionisation' return N_idop
def update_dopant_ionisation(self, N_dop, nxc, impurity, **kwargs): ''' This is a special function used to determine the number of ionised dopants given a number of excess carriers, and a single dopant type. inputs: N_dop: (float; cm^-3) The dopant density nxc: (float; cm^-3) The excess carrier density impurity: (str) The name of the dopant used e.g. boron, phosphorous. The dopants available depend on the model used output: N_idop: (float cm^-2) The number of ionised dopants ''' self._update_dts(**kwargs) # a check to make sure the model hasn't changed if 'author' in kwargs.keys(): self.change_model(self.cal_dts['author']) N_idop = N_dop if impurity in self.vals.keys(): # TO DO, change this from just running 10 times to a proper check for i in range(10): if self.vals['tpe_' + self.vals[impurity]] == 'donor': Nd = N_idop Na = 0 elif self.vals['tpe_' + self.vals[impurity]] == 'acceptor': Na = N_idop Nd = 0 ne, nh = CF.get_carriers( Na, Nd, nxc, temp=self.cal_dts['temp'], material=self.cal_dts['material']) N_idop = self.update( N_dop, ne, nh, impurity) else: print r'Not a valid impurity, returning 100% ionisation' return N_idop
def tau(self, nxc, **kwargs): self.calculationdetails = kwargs if 'author' in kwargs.keys(): self.change_model(self._cal_dts['author']) ne0, nh0 = get_carriers( Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'], nxc=0, ni_author=self._cal_dts['ni_author'], temp=self._cal_dts['temp'] ) return getattr(augmdls, self.model)( self.vals, nxc, ne0, nh0, temp=self._cal_dts['temp'])
def tau(self, nxc, **kwargs): self.calculationdetails = kwargs self.change_model(self._cal_dts['author']) ne0, nh0 = get_carriers( Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'], nxc=self._cal_dts['nxc'], ni_author=self._cal_dts['ni_author'], temp=self._cal_dts['temp'] ) B = self._get_B() return getattr(radmdls, self.model)( self.vals, nxc, nh0, ne0, B, temp=self._cal_dts['temp'] )
def tau(self, nxc, **kwargs): ''' Returns the intrinsic carrier lifetime in seconds ''' self.calculationdetails = kwargs self.change_model(self._cal_dts['author']) ne0, nh0 = get_carriers(Na=self._cal_dts['Na'], Nd=self._cal_dts['Nd'], nxc=0, ni_author=self._cal_dts['ni_author'], temp=self._cal_dts['temp']) Blow = self._get_Blow() return getattr(radmdls, self.model)(vals=self.vals, nxc=nxc, nh0=nh0, ne0=ne0, Blow=Blow, temp=self._cal_dts['temp'])
def tau(self, nxc, Na, Nd, temp=300): ne0, nh0 = get_carriers( Na, Nd, nxc=0, ni_author=None, temp=temp) return getattr(augmdls, self.model)(self.vals, nxc, ne0, nh0, temp)
def tau(self, nxc, Na, Nd, temp=300): ne0, nh0 = get_carriers(Na, Nd, nxc=0, ni_author=None, temp=temp) return getattr(augmdls, self.model)(self.vals, nxc, ne0, nh0, temp)