Пример #1
0
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
Пример #2
0
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
Пример #3
0
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