def DDGelectron_driftdiffusion(psi, xaxis, ng, p, ni, TAUN0, TAUP0, mun, fi_e, fi_h, model, Vt, idata): nodes = xaxis n_max = len(nodes) """ n=np.zeros(n_max) p=np.zeros(n_max) """ fi_n = np.zeros(n_max) fi_p = np.zeros(n_max) elements = np.zeros((n_max - 1, 2)) elements[:, 0] = np.arange(0, n_max - 1) elements[:, 1] = np.arange(1, n_max) Nelements = np.size(elements[:, 0]) BCnodes = [0, n_max - 1] nl = ng[0] nr = ng[n_max - 1] h = nodes[1:n_max] - nodes[0:n_max - 1] c = 1 / h """ print("c=",c) print("h=",h) print("nr=",nr) print("nl=",nl) print("BCnodes=",BCnodes) print("Nelements=",Nelements) print("elements=",elements) print("n_max=",n_max) print("nodes=",nodes) check_point_15 """ if model.N_wells_virtual - 2 != 0 and config.quantum_effect: fi_n, fi_p = equi_np_fi222( ni, idata, fi_e, fi_h, psi, Vt, idata.wfh_general, idata.wfe_general, model, idata.E_state_general, idata.E_statec_general, idata.meff_state_general, idata.meff_statec_general, n_max, idata.n, p) Bneg = Ubernoulli( -(psi[1:n_max] - psi[0:n_max - 1]) - (fi_n[1:n_max] - fi_n[0:n_max - 1]), 1) Bpos = Ubernoulli((psi[1:n_max] - psi[0:n_max - 1]) + (fi_p[1:n_max] - fi_p[0:n_max - 1]), 1) """ print("Bneg=",Bneg) print("Bpos=",Bpos) check_point_16 """ d0 = np.zeros(n_max) d0[0] = c[0] * Bneg[0] d0[n_max - 1] = c[len(c) - 1] * Bpos[len(Bpos) - 1] d0[1:n_max - 1] = c[0:len(c) - 1] * Bpos[0:len(Bpos) - 1] + c[1:len(c)] * Bneg[1:len(Bneg)] d1 = np.zeros(n_max) d1[0] = n_max d1[1:n_max] = -c * Bpos dm1 = np.zeros(n_max) dm1[n_max - 1] = n_max dm1[0:n_max - 1] = -c * Bneg """ print("d0=",d0) print("d1=",d1) print("dm1=",dm1) check_point_17 """ A = sp.spdiags([dm1, d0, d1], np.array([-1, 0, 1]), n_max, n_max).todense() b = np.zeros(n_max) #%- A * ng ## SRH Recombination term SRHD = TAUP0 * (ng + ni) + TAUN0 * (p + ni) SRHL = p / SRHD SRHR = ni**2 / SRHD ASRH = Ucompmass(nodes, n_max, elements, Nelements, SRHL, np.ones(Nelements)) bSRH = Ucompconst(nodes, n_max, elements, Nelements, SRHR, np.ones(Nelements)) """ print("ASRH=",ASRH) print("bSRH=",bSRH) check_point_18 """ A = A + ASRH b = b + bSRH """ print("A=",A) print("b=",b) check_point_19 """ ## Boundary conditions b = np.delete(b, BCnodes, 0) b[0] = -A[1, 0] * nl b[len(b) - 1] = -A[n_max - 2, n_max - 1] * nr A = np.delete(A, BCnodes, 0) A = np.delete(A, BCnodes, 1) nn = np.linalg.solve(A, b) n = np.zeros(n_max) n[1:n_max - 1] = nn n[0] = nl n[len(n) - 1] = nr """ print("BCnodes=",BCnodes) print("A=",A) print("b=",b) print("n=",n) check_point_20 """ return n
def DDGnlpoisson_new (idata,xaxis,sinodes,Vin,nin,pin,toll,maxit,verbose,fi_e,fi_h,model,Vt,surface,fi_stat,iteration,ns): ## Set some useful constants dampit = 10 dampcoeff = 5 ## Convert grid info to FEM form #Ndiricheletnodes= 2 nodes = xaxis sielements=np.zeros(len(sinodes)-1) sielements[:] = sinodes[1:len(sinodes)] n_max = len(nodes) #totdofs = n_max - Ndiricheletnodes elements=np.zeros((n_max-1,2)) elements[:,0]= np.arange(0,n_max-1) elements[:,1]=np.arange(1,n_max) Nelements=np.size(elements[:,0]) BCnodes= n_max normr=np.zeros(maxit+1) """ print("nodes=",nodes) print("sielements=",sielements) print("n_max=",n_max) print("elements=",elements) print("Nelements=",Nelements) print("BCnodes=",BCnodes) check_point_8 """ ## Initialization V = Vin EF = 0.0 if iteration == 1: # Determination of the Fermi Level EF = 0.0 V = np.zeros(n_max) n, p, V = equi_np_fi( iteration, idata.dop, idata.Ppz_Psp, n_max, idata.ni, model, Vt, surface ) fi_stat = V else: if model.N_wells_virtual - 2 != 0: n, p, fi_non, EF = equi_np_fi3( V, idata.wfh_general, idata.wfe_general, model, idata.E_state_general, idata.E_statec_general, idata.meff_state_general, idata.meff_statec_general, n_max, idata.ni*ns, ) else: n = np.exp(V) p = np.exp(-V) n=n*idata.ni p=p*idata.ni """ print("sinodes=",sinodes) print("n=",n) print("p=",p) check_point_9 """ if (sinodes[0]==0): n[1]=nin[0] p[1]=pin[0] if (sinodes[n_max-1]==n_max-1): n[n_max-1]=nin[n_max-1] p[n_max-1]=pin[n_max-1] ## Compute LHS matrices l22=idata.l2*np.ones(Nelements) L = Ucomplap (nodes,n_max,elements,Nelements,l22) ## Compute Mv = ( n + p) Mv = np.zeros(n_max) Mv[sinodes] = (n + p) Cv = np.ones(Nelements) M = Ucompmass (nodes,n_max,elements,Nelements,Mv,Cv) ## Compute RHS vector Tv0 = np.zeros(n_max) Tv0[sinodes] = (n - p -idata.dop-idata.Ppz_Psp) Cv= np.ones(Nelements) T0 = Ucompconst (nodes,n_max,elements,Nelements,Tv0,Cv) """ print('L=',L) print('M=',M) print('T0=',T0) check_point_10 """ ## Build LHS matrix and RHS of the linear system for 1st Newton step A=np.zeros((n_max,n_max)) R=np.zeros(n_max) Anew=np.zeros((n_max,n_max)) Rnew=np.zeros(n_max) A = L + M LV=np.dot(np.array(L) , V) R = LV +T0 ## Apply boundary conditions """ print('A=',A) print('R=',R) check_point_11 """ A=np.delete(A, [0,BCnodes-1], 0) A=np.delete(A, [0,BCnodes-1], 1) R=np.delete(R, [0,BCnodes-1], 0) normr[0] = np.linalg.norm(R,np.inf) relresnorm = 1 reldVnorm = 1 normrnew = normr[0] ## Start of the newton cycle for newtit in range(1,maxit): if verbose: print("\n newton iteration: %d, reldVnorm = %f"%(newtit,reldVnorm)) cc= np.linalg.solve(A, -R)#, rcond=None)[0] dV=np.zeros(n_max) dV[1:n_max-1] =cc ## Start of the damping procedure tk = 1 for dit in range(1,dampit): if verbose: print("\n damping iteration: %d, residual norm = %f"%(dit,normrnew)) Vnew = V + tk * dV if iteration == 1: n = np.exp(Vnew)*idata.ni p = np.exp(-Vnew)*idata.ni else: if model.N_wells_virtual - 2 != 0: n, p, fi_non, EF = equi_np_fi3( Vnew, idata.wfh_general, idata.wfe_general, model, idata.E_state_general, idata.E_statec_general, idata.meff_state_general, idata.meff_statec_general, n_max, idata.ni*ns, ) else: n = np.exp(Vnew) p = np.exp(-Vnew) n=n*idata.ni p=p*idata.ni if (sinodes[0]==0): n[0]=nin[0] p[0]=pin[0] if (sinodes[n_max-1]==n_max-1): n[n_max-1]=nin[n_max-1] p[n_max-1]=pin[n_max-1] ## Compute LHS matrices Mv = np.zeros(n_max) Mv[sinodes] = (n + p) Cv = np.ones(Nelements) #Cv[sielements]= 1 M = Ucompmass (nodes,n_max,elements,Nelements,Mv,Cv) ## Compute RHS vector (-residual) Tv0 = np.zeros(n_max) Tv0[sinodes] = (n - p -idata.dop-idata.Ppz_Psp) Cv= np.ones(Nelements) Cv = np.ones(Nelements) #Cv[sielements]= 1 T0 = Ucompconst (nodes,n_max,elements,Nelements,Tv0,Cv) """ print('L=',L) print('M=',M) print('T0=',T0) check_point_12 """ ## Build LHS matrix and RHS of the linear system for 1st Newton step Anew = L + M LVnew=np.dot(np.array(L) , Vnew) Rnew = LVnew +T0 """ print('Anew=',Anew) print('Rnew=',Rnew) check_point_13 """ ## Apply boundary conditions Anew=np.delete(Anew, [0,BCnodes-1], 0) Anew=np.delete(Anew, [0,BCnodes-1], 1) Rnew=np.delete(Rnew, [0,BCnodes-1], 0) if ((dit>1) and (np.linalg.norm(Rnew,np.inf) >= np.linalg.norm(R,np.inf))): if verbose: print("\nexiting damping cycle \n") break else: A = Anew R = Rnew ## Compute | R_{k+1} | for the convergence test normrnew= np.linalg.norm(R,np.inf) ## Check if more damping is needed if (normrnew > normr[newtit]): tk = tk/dampcoeff else: if verbose: print("\nexiting damping cycle because residual norm = %f \n"%normrnew) break V= Vnew normr[newtit+1] = normrnew dVnorm= np.linalg.norm(tk*dV,np.inf) ## Check if convergence has been reached reldVnorm = dVnorm / np.linalg.norm(V,np.inf) if (reldVnorm <= toll): if(verbose): print("\nexiting newton cycle because reldVnorm= %f \n"%reldVnorm) break res = normr niter = newtit return [V,n,p,fi_stat]#,res,niter
def DDGhole_driftdiffusion(psi,xaxis,pg,n,ni,TAUN0,TAUP0,mup,fi_e,fi_h,model,Vt,idata): nodes = xaxis n_max =len(nodes) """ n=np.zeros(n_max) p=np.zeros(n_max) """ fi_n=np.zeros(n_max) fi_p=np.zeros(n_max) elements=np.zeros((n_max-1,2)) elements[:,0]= np.arange(0,n_max-1) elements[:,1]=np.arange(1,n_max) Nelements=np.size(elements[:,0]) BCnodes= [0,n_max-1] pl = pg[0] pr = pg[n_max-1] h=nodes[1:len(nodes)]-nodes[0:len(nodes)-1] c=1/h if model.N_wells_virtual-2!=0 and config.quantum_effect: fi_n,fi_p =equi_np_fi222(ni,idata,fi_e,fi_h,psi,Vt,idata.wfh_general,idata.wfe_general,model,idata.E_state_general,idata.E_statec_general,idata.meff_state_general,idata.meff_statec_general,n_max,n,idata.p) Bneg=Ubernoulli(-(psi[1:n_max]-psi[0:n_max-1])-(fi_n[1:n_max]-fi_n[0:n_max-1]),1) Bpos=Ubernoulli( (psi[1:n_max]-psi[0:n_max-1])+(fi_p[1:n_max]-fi_p[0:n_max-1]),1) d0=np.zeros(n_max) d0[0]=c[0]*Bneg[0] d0[n_max-1]=c[len(c)-1]*Bpos[len(Bpos)-1] d0[1:n_max-1]=c[0:len(c)-1]*Bpos[0:len(Bpos)-1]+c[1:len(c)]*Bneg[1:len(Bneg)] d1 = np.zeros(n_max) d1[0]=n_max d1[1:n_max]=-c* Bneg dm1 = np.zeros(n_max) dm1[n_max-1]=n_max dm1[0:n_max-1]=-c* Bpos A = sp.spdiags([dm1, d0, d1],np.array([-1,0,1]),n_max,n_max).todense() b = np.zeros(n_max)#%- A * ng ## SRH Recombination term SRHD = TAUP0 * (n + ni) + TAUN0 * (pg + ni) SRHL = n / SRHD SRHR = ni**2 / SRHD ASRH = Ucompmass (nodes,n_max,elements,Nelements,SRHL,np.ones(Nelements)) bSRH = Ucompconst (nodes,n_max,elements,Nelements,SRHR,np.ones(Nelements)) A = A + ASRH b = b + bSRH ## Boundary conditions b=np.delete(b, BCnodes, 0) b[0] = - A[1,0] * pl b[len(b)-1] = - A[n_max-2,n_max-1] * pr A=np.delete(A, BCnodes, 0) A=np.delete(A, BCnodes, 1) pp= np.linalg.solve(A,b) p=np.zeros(n_max) p[1:n_max-1]=pp p[0]=pl p[len(p)-1]=pr return p