def equilibrium_f(self, temperature, semiconductor, fermi_level_from_conduction_band, electron_volts=False, use_mpmath=False, debug=False): """ Calculates trap equilibrium filling for given Fermi level position :param temperature: Temperature, K :param semiconductor: Semiconductor object :param fermi_level_from_conduction_band: distance from Conduction band to Fermi level :param electron_volts: if True assume all energy values to be in eV :param use_mpmath: if True integration is done using mpmath.quad function instead of numpy.trapz (default) :param debug: if True prints out some debug information :return: equilibrium f between 0 and 1 """ if electron_volts: energy_coefficient = to_numeric(q) energy_unit = 'eV' else: energy_coefficient = 1 energy_unit = 'J' energy_scale = to_numeric(k * temperature) / energy_coefficient conduction_band = 0 fermi_level = conduction_band - fermi_level_from_conduction_band trap_energy_level = self.energy_level(temperature, semiconductor, charge_state_idx=0, electron_volts=electron_volts) if debug: print 'Et = %2.2g ' % ((conduction_band - trap_energy_level)) + energy_unit print 'Ef =', fermi_level, energy_unit g_ratio = self.charge_states[0][2] / self.charge_states[1][2] if self.energy_distribution_function in energy_distribution_functions['Single Level']: fermi_level_grid, = np.meshgrid(fermi_level) exp_arg = (np.float(conduction_band - trap_energy_level) - fermi_level_grid) / energy_scale exp_term = np.exp(exp_arg) f = 1 / (1 + g_ratio * exp_term) else: energy = sym.symbols('E') energy_distribution = self.energy_distribution.subs([('Et', trap_energy_level * energy_coefficient), ('Ecb', conduction_band * energy_coefficient)]) energy_distribution = energy_distribution.subs(q, to_numeric(q)) if not use_mpmath: if debug: print 'Numeric integration (numpy.trapz)' energy_range = centered_linspace(conduction_band - trap_energy_level, 10 * to_numeric(self.energy_spread) / energy_coefficient, to_numeric(self.energy_spread) / energy_coefficient / 1000) energy_range_grid, fermi_level_grid = np.meshgrid(energy_range, fermi_level) fermi_function = 1 / (1 + g_ratio * np.exp((energy_range_grid - fermi_level_grid) / energy_scale)) energy_distribution_function = sym.lambdify(energy, energy_distribution, 'numpy') integrand_array = energy_distribution_function(energy_range_grid * energy_coefficient) * fermi_function f = np.trapz(integrand_array, energy_range_grid * energy_coefficient, axis=1) else: if debug: print 'Numeric integration (mpmath.quad)' fermi_level_grid, = np.meshgrid(fermi_level) f = np.zeros_like(fermi_level_grid) for i, fermi_level_i in enumerate(fermi_level_grid): fermi_function = fermi(energy, fermi_level_i * energy_coefficient, temperature, g_ratio) fermi_function = fermi_function.subs(k, to_numeric(k)) integrand = sym.lambdify(energy, energy_distribution * fermi_function) f[i] = mp.quad(integrand, [to_numeric(energy_coefficient * (conduction_band - trap_energy_level) - 10 * self.energy_spread), to_numeric(energy_coefficient * (conduction_band - trap_energy_level) - 0.5 * self.energy_spread), to_numeric(energy_coefficient * (conduction_band - trap_energy_level) + 0.5 * self.energy_spread), to_numeric(energy_coefficient * (conduction_band - trap_energy_level) + 10 * self.energy_spread)]) if debug: print 'F =', f if f.size == 1: f = f[0] return f
def emission_rate(self, temperature, semiconductor, f, poole_frenkel_e=None, poole_frenkel_h=None, barrier_lowering_e=None, barrier_lowering_h=None, use_mpmath=False, debug=False): """ Calculate carriers emission rate for bot electrons and holes :param temperature: Temperature, K :param semiconductor: Semiconductor object :param f: Trap occupation from 0.0 to 1.0 :param poole_frenkel_e: emission rate boost due to Poole-Frenkel effect for electron :param poole_frenkel_h: emission rate boost due to Poole-Frenkel effect for electron :param barrier_lowering_e: lowering of activation energy for electrons :param barrier_lowering_h: lowering of activation energy for holes :param use_mpmath: if True integration is done using mpmath.quad function instead of numpy.trapz (default) :param debug: if True prints out some debug information :return: emission_e, emission_h """ if barrier_lowering_e is None: barrier_lowering_e = np.zeros_like(f, dtype=np.float) if barrier_lowering_h is None: barrier_lowering_h = np.zeros_like(f, dtype=np.float) if poole_frenkel_e is None: poole_frenkel_e = np.ones_like(f, dtype=np.float) if poole_frenkel_h is None: poole_frenkel_h = np.ones_like(f, dtype=np.float) energy_scale = to_numeric(k * temperature) conduction_band = 0 band_gap = semiconductor.band_gap(temperature, symbolic=False, electron_volts=False) valence_band = conduction_band - band_gap trap_energy_level_e = np.float( self.energy_level(temperature, semiconductor, charge_state_idx=1, electron_volts=False)) trap_energy_level_h = np.float( self.energy_level(temperature, semiconductor, charge_state_idx=0, electron_volts=False)) trap_energy_level_e_positive = conduction_band - trap_energy_level_e trap_energy_level_h_positive = conduction_band - trap_energy_level_h g_ratio_e = self.charge_states[0][2] / self.charge_states[1][2] g_ratio_h = self.charge_states[1][2] / self.charge_states[0][2] v_e = np.float(semiconductor.v_T('e', temperature, symbolic=False)) v_h = np.float(semiconductor.v_T('h', temperature, symbolic=False)) if debug: print '<v_e> =', v_e, 'm/s' print '<v_h> =', v_h, 'm/s' sigma_n, sigma_p = self.capture_cross_sections(temperature) fore_factor_n = np.float( sigma_n * v_e * semiconductor.Nc(temperature, symbolic=False) * g_ratio_e) fore_factor_p = np.float( sigma_p * v_h * semiconductor.Nv(temperature, symbolic=False) * g_ratio_h) fore_factor_n *= poole_frenkel_e fore_factor_p *= poole_frenkel_h if debug: print 'factor_n =', fore_factor_n print 'factor_p =', fore_factor_p if self.energy_distribution_function in energy_distribution_functions[ 'Single Level']: activation_energy_e = conduction_band - trap_energy_level_e_positive - barrier_lowering_e activation_energy_h = trap_energy_level_h_positive - valence_band - barrier_lowering_h emission_rate_e = fore_factor_n * np.exp( -activation_energy_e / energy_scale) emission_rate_h = fore_factor_p * np.exp( -activation_energy_h / energy_scale) emission_time_constant_e = 1 / emission_rate_e emission_time_constant_h = 1 / emission_rate_h emission_e = emission_rate_e * f emission_h = emission_rate_h * (1 - f) else: quasi_fermi_level = self.f_to_equilibrium_fermi_level( temperature, semiconductor, f, electron_volts=False, use_mpmath=use_mpmath, debug=False) quasi_fermi_level = conduction_band - quasi_fermi_level if debug: print 'Eqf =', quasi_fermi_level / to_numeric(q), 'eV' energy = sym.symbols('E') energy_distribution_e = self.energy_distribution.subs([ ('Et', trap_energy_level_e), ('Ecb', conduction_band) ]) energy_distribution_e = energy_distribution_e.subs( q, to_numeric(q)) energy_distribution_h = self.energy_distribution.subs([ ('Et', trap_energy_level_h), ('Ecb', conduction_band) ]) energy_distribution_h = energy_distribution_h.subs( q, to_numeric(q)) energy_range_e = centered_linspace( conduction_band - trap_energy_level_e, 10 * to_numeric(self.energy_spread), to_numeric(self.energy_spread) / 1000) energy_range_h = centered_linspace( conduction_band - trap_energy_level_h, 10 * to_numeric(self.energy_spread), to_numeric(self.energy_spread) / 1000) energy_distribution_function_e = sym.lambdify( energy, energy_distribution_e, 'numpy') energy_distribution_function_h = sym.lambdify( energy, energy_distribution_h, 'numpy') energy_range_grid_e, barrier_lowering_grid_e = np.meshgrid( energy_range_e, barrier_lowering_e) energy_range_grid_h, barrier_lowering_grid_h = np.meshgrid( energy_range_h, barrier_lowering_h) exp_term_e = np.exp(-(conduction_band - energy_range_grid_e + barrier_lowering_grid_e) / energy_scale) exp_term_h = np.exp( -(energy_range_grid_h - barrier_lowering_grid_h - valence_band) / energy_scale) emission_rate_e = energy_distribution_function_e( energy_range_e) * exp_term_e * fore_factor_n emission_rate_h = energy_distribution_function_h( energy_range_h) * exp_term_h * fore_factor_p emission_rate_e_max = np.max(emission_rate_e, axis=1) emission_rate_h_max = np.max(emission_rate_h, axis=1) emission_time_constant_e = 1 / emission_rate_e_max emission_time_constant_h = 1 / emission_rate_h_max if not use_mpmath: if debug: print 'Numeric integration (numpy.trapz)' energy_range_grid_e, fermi_level_grid_e = np.meshgrid( energy_range_e, quasi_fermi_level) energy_range_grid_h, fermi_level_grid_h = np.meshgrid( energy_range_h, quasi_fermi_level) fermi_function_e = 1 / (1 + g_ratio_e * np.exp( (energy_range_grid_e - fermi_level_grid_e) / energy_scale)) fermi_function_h = 1 - 1 / (1 + g_ratio_h * np.exp( (energy_range_grid_h - fermi_level_grid_h) / energy_scale)) exp_term_e = np.exp(-(conduction_band - energy_range_grid_e + barrier_lowering_e) / energy_scale) exp_term_h = np.exp( -(energy_range_grid_h - barrier_lowering_h - valence_band) / energy_scale) emission_rate_e = energy_distribution_function_e( energy_range_grid_e) * exp_term_e emission_rate_h = energy_distribution_function_h( energy_range_grid_h) * exp_term_h integrand_array_e = emission_rate_e * fermi_function_e integrand_array_h = emission_rate_h * fermi_function_h emission_e = np.trapz(integrand_array_e, energy_range_grid_e, axis=1) * fore_factor_n emission_h = np.trapz(integrand_array_h, energy_range_grid_h, axis=1) * fore_factor_p else: if debug: print 'Numeric integration (mpmath.quad)' exp_term_e = sym.exp( -(conduction_band - energy + barrier_lowering_e) / energy_scale) exp_term_h = sym.exp( -(energy - barrier_lowering_h - valence_band) / energy_scale) quasi_fermi_level_grid, = np.meshgrid(quasi_fermi_level) emission_e = np.zeros_like(quasi_fermi_level_grid) emission_h = np.zeros_like(quasi_fermi_level_grid) for i, quasi_fermi_level_i in enumerate( quasi_fermi_level_grid): fermi_function_e = fermi(energy, quasi_fermi_level_i, temperature, g_ratio_e) fermi_function_e = fermi_function_e.subs(k, to_numeric(k)) fermi_function_h = fermi(quasi_fermi_level_i, energy, temperature, g_ratio_h) fermi_function_h = fermi_function_h.subs(k, to_numeric(k)) integrand_e = sym.lambdify( energy, energy_distribution_e * fermi_function_e * exp_term_e) integrand_h = sym.lambdify( energy, energy_distribution_h * fermi_function_h * exp_term_h) emission_integral_e = mp.quad(integrand_e, [ to_numeric(trap_energy_level_e_positive - 10 * self.energy_spread), to_numeric(trap_energy_level_e_positive - 0.5 * self.energy_spread), to_numeric(trap_energy_level_e_positive + 0.5 * self.energy_spread), to_numeric(trap_energy_level_e_positive + 10 * self.energy_spread) ]) emission_integral_h = mp.quad(integrand_h, [ to_numeric(trap_energy_level_h_positive - 10 * self.energy_spread), to_numeric(trap_energy_level_h_positive - 0.5 * self.energy_spread), to_numeric(trap_energy_level_h_positive + 0.5 * self.energy_spread), to_numeric(trap_energy_level_h_positive + 10 * self.energy_spread) ]) emission_e[i] = np.float(emission_integral_e * fore_factor_n) emission_h[i] = np.float(emission_integral_h * fore_factor_p) if isinstance(emission_e, np.ndarray): if emission_e.size == 1: emission_e = emission_e[0] emission_h = emission_h[0] emission_time_constant_e = emission_time_constant_e[0] emission_time_constant_h = emission_time_constant_h[0] if debug: print 'emission_e =', emission_e if debug: print 'emission_h =', emission_h if debug: print 'emission_tau_e =', emission_time_constant_e if debug: print 'emission_tau_h =', emission_time_constant_e return emission_e, emission_h, emission_time_constant_e, emission_time_constant_h
def emission_rate(self, temperature, semiconductor, f, poole_frenkel_e=1.0, poole_frenkel_h=1.0, barrier_lowering_e=None, barrier_lowering_h=None, use_mpmath=False, debug=False): """ Calculate carriers emission rate for bot electrons and holes :param temperature: Temperature, K :param semiconductor: Semiconductor object :param f: Trap occupation from 0.0 to 1.0 :param poole_frenkel_e: emission rate boost due to Poole-Frenkel effect for electron :param poole_frenkel_h: emission rate boost due to Poole-Frenkel effect for electron :param barrier_lowering_e: lowering of activation energy for electrons :param barrier_lowering_h: lowering of activation energy for holes :param use_mpmath: if True integration is done using mpmath.quad function instead of numpy.trapz (default) :param debug: if True prints out some debug information :return: emission_e, emission_h """ if barrier_lowering_e is None: barrier_lowering_e = np.zeros_like(f, dtype=np.float) if barrier_lowering_h is None: barrier_lowering_h = np.zeros_like(f, dtype=np.float) energy_scale = to_numeric(k * temperature) conduction_band = 0 band_gap = semiconductor.band_gap(temperature, symbolic=False, electron_volts=False) valence_band = conduction_band - band_gap trap_energy_level_e = np.float(self.energy_level(temperature, semiconductor, charge_state_idx=1, electron_volts=False)) trap_energy_level_h = np.float(self.energy_level(temperature, semiconductor, charge_state_idx=0, electron_volts=False)) trap_energy_level_e_positive = conduction_band - trap_energy_level_e trap_energy_level_h_positive = conduction_band - trap_energy_level_h g_ratio_e = self.charge_states[0][2] / self.charge_states[1][2] g_ratio_h = self.charge_states[1][2] / self.charge_states[0][2] v_e = np.float(semiconductor.v_T('e', temperature, symbolic=False)) v_h = np.float(semiconductor.v_T('h', temperature, symbolic=False)) if debug: print '<v_e> =', v_e, 'm/s' print '<v_h> =', v_h, 'm/s' sigma_n, sigma_p = self.capture_cross_sections(temperature) fore_factor_n = np.float(sigma_n * v_e * semiconductor.Nc(temperature, symbolic=False) * g_ratio_e) fore_factor_p = np.float(sigma_p * v_h * semiconductor.Nv(temperature, symbolic=False) * g_ratio_h) fore_factor_n *= poole_frenkel_e fore_factor_p *= poole_frenkel_h if debug: print 'factor_n =', fore_factor_n print 'factor_p =', fore_factor_p if self.energy_distribution_function in energy_distribution_functions['Single Level']: activation_energy_e = conduction_band - trap_energy_level_e_positive - barrier_lowering_e activation_energy_h = trap_energy_level_h_positive - valence_band - barrier_lowering_h emission_rate_e = fore_factor_n * np.exp(-activation_energy_e / energy_scale) emission_rate_h = fore_factor_p * np.exp(-activation_energy_h / energy_scale) emission_time_constant_e = 1 / emission_rate_e emission_time_constant_h = 1 / emission_rate_h emission_e = emission_rate_e * f emission_h = emission_rate_h * (1 - f) else: quasi_fermi_level = self.f_to_equilibrium_fermi_level(temperature, semiconductor, f, electron_volts=False, use_mpmath=use_mpmath, debug=False) quasi_fermi_level = conduction_band - quasi_fermi_level if debug: print 'Eqf =', quasi_fermi_level / to_numeric(q), 'eV' energy = sym.symbols('E') energy_distribution_e = self.energy_distribution.subs([('Et', trap_energy_level_e), ('Ecb', conduction_band)]) energy_distribution_e = energy_distribution_e.subs(q, to_numeric(q)) energy_distribution_h = self.energy_distribution.subs([('Et', trap_energy_level_h), ('Ecb', conduction_band)]) energy_distribution_h = energy_distribution_h.subs(q, to_numeric(q)) energy_range_e = centered_linspace(conduction_band - trap_energy_level_e, 10 * to_numeric(self.energy_spread), to_numeric(self.energy_spread) / 1000) energy_range_h = centered_linspace(conduction_band - trap_energy_level_h, 10 * to_numeric(self.energy_spread), to_numeric(self.energy_spread) / 1000) energy_distribution_function_e = sym.lambdify(energy, energy_distribution_e, 'numpy') energy_distribution_function_h = sym.lambdify(energy, energy_distribution_h, 'numpy') energy_range_grid_e, barrier_lowering_grid_e = np.meshgrid(energy_range_e, barrier_lowering_e) energy_range_grid_h, barrier_lowering_grid_h = np.meshgrid(energy_range_h, barrier_lowering_h) exp_term_e = np.exp(-(conduction_band - energy_range_grid_e + barrier_lowering_grid_e) / energy_scale) exp_term_h = np.exp(-(energy_range_grid_h - barrier_lowering_grid_h - valence_band) / energy_scale) emission_rate_e = energy_distribution_function_e(energy_range_e) * exp_term_e * fore_factor_n emission_rate_h = energy_distribution_function_h(energy_range_h) * exp_term_h * fore_factor_p emission_rate_e_max = np.max(emission_rate_e, axis=1) emission_rate_h_max = np.max(emission_rate_h, axis=1) emission_time_constant_e = 1 / emission_rate_e_max emission_time_constant_h = 1 / emission_rate_h_max if not use_mpmath: if debug: print 'Numeric integration (numpy.trapz)' energy_range_grid_e, fermi_level_grid_e = np.meshgrid(energy_range_e, quasi_fermi_level) energy_range_grid_h, fermi_level_grid_h = np.meshgrid(energy_range_h, quasi_fermi_level) fermi_function_e = 1 / (1 + g_ratio_e * np.exp((energy_range_grid_e - fermi_level_grid_e) / energy_scale)) fermi_function_h = 1 - 1 / (1 + g_ratio_h * np.exp((energy_range_grid_h - fermi_level_grid_h) / energy_scale)) exp_term_e = np.exp(-(conduction_band - energy_range_grid_e + barrier_lowering_e) / energy_scale) exp_term_h = np.exp(-(energy_range_grid_h - barrier_lowering_h - valence_band) / energy_scale) emission_rate_e = energy_distribution_function_e(energy_range_grid_e) * exp_term_e emission_rate_h = energy_distribution_function_h(energy_range_grid_h) * exp_term_h integrand_array_e = emission_rate_e * fermi_function_e integrand_array_h = emission_rate_h * fermi_function_h emission_e = np.trapz(integrand_array_e, energy_range_grid_e, axis=1) * fore_factor_n emission_h = np.trapz(integrand_array_h, energy_range_grid_h, axis=1) * fore_factor_p else: if debug: print 'Numeric integration (mpmath.quad)' exp_term_e = sym.exp(-(conduction_band - energy + barrier_lowering_e) / energy_scale) exp_term_h = sym.exp(-(energy - barrier_lowering_h - valence_band) / energy_scale) quasi_fermi_level_grid, = np.meshgrid(quasi_fermi_level) emission_e = np.zeros_like(quasi_fermi_level_grid) emission_h = np.zeros_like(quasi_fermi_level_grid) for i, quasi_fermi_level_i in enumerate(quasi_fermi_level_grid): fermi_function_e = fermi(energy, quasi_fermi_level_i, temperature, g_ratio_e) fermi_function_e = fermi_function_e.subs(k, to_numeric(k)) fermi_function_h = fermi(quasi_fermi_level_i, energy, temperature, g_ratio_h) fermi_function_h = fermi_function_h.subs(k, to_numeric(k)) integrand_e = sym.lambdify(energy, energy_distribution_e * fermi_function_e * exp_term_e) integrand_h = sym.lambdify(energy, energy_distribution_h * fermi_function_h * exp_term_h) emission_integral_e = mp.quad(integrand_e, [to_numeric(trap_energy_level_e_positive - 10 * self.energy_spread), to_numeric(trap_energy_level_e_positive - 0.5 * self.energy_spread), to_numeric(trap_energy_level_e_positive + 0.5 * self.energy_spread), to_numeric(trap_energy_level_e_positive + 10 * self.energy_spread)]) emission_integral_h = mp.quad(integrand_h, [to_numeric(trap_energy_level_h_positive - 10 * self.energy_spread), to_numeric(trap_energy_level_h_positive - 0.5 * self.energy_spread), to_numeric(trap_energy_level_h_positive + 0.5 * self.energy_spread), to_numeric(trap_energy_level_h_positive + 10 * self.energy_spread)]) emission_e[i] = np.float(emission_integral_e * fore_factor_n) emission_h[i] = np.float(emission_integral_h * fore_factor_p) if isinstance(emission_e, np.ndarray): if emission_e.size == 1: emission_e = emission_e[0] emission_h = emission_h[0] emission_time_constant_e = emission_time_constant_e[0] emission_time_constant_h = emission_time_constant_h[0] if debug: print 'emission_e =', emission_e if debug: print 'emission_h =', emission_h if debug: print 'emission_tau_e =', emission_time_constant_e if debug: print 'emission_tau_h =', emission_time_constant_e return emission_e, emission_h, emission_time_constant_e, emission_time_constant_h
def d_equilibrium_f_d_fermi_energy(self, temperature, semiconductor, fermi_level_from_conduction_band, electron_volts=False, use_mpmath=False, debug=False): """ Calculates trap equilibrium filling derivative for given Fermi level position on small Fermi level change :param temperature: Temperature, K :param semiconductor: Semiconductor object :param fermi_level_from_conduction_band: distance from Conduction band to Fermi level :param electron_volts: if True assume all energy values to be in eV :param use_mpmath: if True integration is done using mpmath.quad function instead of numpy.trapz (default) :param debug: if True prints out some debug information :return: equilibrium f between 0 and 1 """ if electron_volts: energy_coefficient = to_numeric(q) energy_unit = 'eV' else: energy_coefficient = 1 energy_unit = 'J' energy_scale = to_numeric(k * temperature) / energy_coefficient conduction_band = 0 fermi_level = conduction_band - fermi_level_from_conduction_band trap_energy_level = self.energy_level(temperature, semiconductor, charge_state_idx=0, electron_volts=electron_volts) if debug: print 'Et = %2.2g ' % ( (conduction_band - trap_energy_level)) + energy_unit print 'Ef =,', fermi_level, energy_unit g_ratio = self.charge_states[0][2] / self.charge_states[1][2] if self.energy_distribution_function in energy_distribution_functions[ 'Single Level']: fermi_level_grid, = np.meshgrid(fermi_level) exp_arg = (np.float(conduction_band - trap_energy_level) - fermi_level_grid) / energy_scale exp_term = np.exp(exp_arg) exp_term = np.array(map(mp.exp, exp_arg)) a = g_ratio / (energy_coefficient * energy_scale) #print exp_term #/ (1 + g_ratio * exp_term) b = exp_term / (1 + g_ratio * exp_term)**2 d_f = a * b # d_f = g_ratio / (energy_coefficient * energy_scale) * exp_term / (1 + g_ratio * exp_term) ** 2 d_f[np.where(d_f == np.nan)] = 0 else: energy = sym.symbols('E') energy_distribution = self.energy_distribution.subs([ ('Et', trap_energy_level * energy_coefficient), ('Ecb', conduction_band * energy_coefficient) ]) energy_distribution = energy_distribution.subs(q, to_numeric(q)) if not use_mpmath: if debug: print 'Numeric integration (numpy.trapz)' energy_range = centered_linspace( conduction_band - trap_energy_level, 10 * to_numeric(self.energy_spread) / energy_coefficient, to_numeric(self.energy_spread) / energy_coefficient / 1000) energy_range_grid, fermi_level_grid = np.meshgrid( energy_range, fermi_level) exp_term = np.exp( (energy_range_grid - fermi_level_grid) / energy_scale) fore_factor = g_ratio / (energy_coefficient * energy_scale) d_fermi_function = fore_factor * exp_term / ( 1 + g_ratio * exp_term)**2 d_fermi_function[np.where(d_fermi_function == np.nan)] = 0 energy_distribution_function = sym.lambdify( energy, energy_distribution, 'numpy') integrand_array = energy_distribution_function( energy_range_grid * energy_coefficient) * d_fermi_function d_f = np.trapz(integrand_array, energy_range_grid * energy_coefficient, axis=1) else: if debug: print 'Numeric integration (mpmath.quad)' fermi_level_grid, = np.meshgrid(fermi_level) d_f = np.zeros_like(fermi_level_grid) for i, fermi_level_i in enumerate(fermi_level_grid): d_fermi_function = d_fermi_d_delta_fermi_energy( energy, fermi_level_i * energy_coefficient, temperature, g_ratio) d_fermi_function = d_fermi_function.subs(k, to_numeric(k)) integrand = sym.lambdify( energy, energy_distribution * d_fermi_function) d_f[i] = mp.quad(integrand, [ to_numeric(energy_coefficient * (conduction_band - trap_energy_level) - 10 * self.energy_spread), to_numeric(energy_coefficient * (conduction_band - trap_energy_level) - 0.5 * self.energy_spread), to_numeric(energy_coefficient * (conduction_band - trap_energy_level) + 0.5 * self.energy_spread), to_numeric(energy_coefficient * (conduction_band - trap_energy_level) + 10 * self.energy_spread) ]) if debug: print 'dF =', d_f if d_f.size == 1: d_f = d_f[0] return d_f