def g1(nsigma, c): """ EGDM g1 nsigma=sigma/kT: must be nsigma>=1. c must be 0<=c<=1, recommended c<0.1 """ delta = 2.0 * (ad.log(nsigma**2 - nsigma) - ad.log(ad.log(4))) / (nsigma**2) return ad.exp(0.5 * (nsigma**2 - nsigma) * (2 * c)**delta)
def Ef(self, ctx, eq): c = ctx.varsOf(eq)['c'] c_raw = c c = where(c > self.c_eps, c, self.c_eps) # avoid NaN if self.logger.isEnabledFor(logging.INFO): if np.any(nvalue(c_raw) != nvalue(c)): self.logger.info( 'Ef(%r): clipping c<%r, min(c)=%r' % (eq.prefix, self.c_eps, np.amin( nvalue(c_raw)))) N0 = self.N0(ctx, eq) return ctx.varsOf(eq.thermal)['Vt'] * log(c / N0)
def mobility(self, parent, ctx, eq): mu0 = ctx.param(eq, 'mu0') gamma = ctx.param(eq, 'gamma') v = gamma * sqrt(ctx.varsOf(eq.poisson)['Ecellm'] + 1e-10) v_max = log(1e10) v_min = -v_max v = where(v < v_max, v, v_max) v = where(v > v_min, v, v_min) mu = mu0 * exp(v) mu_face = eq.mesh.faceaverage(mu) ctx.varsOf(eq)['mu_face'] = mu_face ctx.varsOf(eq)['mu_cell'] = mu
def solve_analytical(self, ctx, eq, fixed): hole, = eq.hole electron, = eq.electron C = fixed Nc = electron.dos.N0(ctx, electron) Nv = hole.dos.N0(ctx, hole) Vt = ctx.varsOf(eq.thermal)['Vt'] Ec = ctx.varsOf(electron)['Ebandv'] Ev = ctx.varsOf(hole)['Ebandv'] uc = exp(Ec/Vt) uv = exp(Ev/Vt) # TODO: rewrite to avoid overflow, reference to middle of bandgap Ef = Vt*log((C*uc + sqrt((C*C*uc + 4*Nc*Nv*uv)*uc))/(2*Nc)) n = Nc*exp((Ef-Ec)/Vt) p = Nv*exp((Ev-Ef)/Vt) return Ef, dict({id(hole): p, id(electron): n})
def b(self, a, i, b0=None): return self._b(a, ad.log(i), b0=b0)
def Ef_correction(self, ctx, eq): info = self._load(ctx, eq) return (-info['b'] - log(info['c'])) * info['Vt']