--- /dev/null
+function [V,n,p,res,niter] = ThDDGOXnlpoisson (mesh,Dsides,Sinodes,SiDnodes,...
+ Sielements,Vin,Vthn,Vthp,...
+ nin,pin,...
+ Fnin,Fpin,D,l2,l2ox,...
+ toll,maxit,verbose)
+
+ %%
+ %% [V,n,p,res,niter] = DDGOXnlpoisson (mesh,Dsides,Sinodes,Vin,nin,pin,...
+ %% Fnin,Fpin,D,l2,l2ox,toll,maxit,verbose)
+ %%
+ %% solves $$ -\lambda^2 V'' + (n(V,Fn,Tn) - p(V,Fp,Tp) -D) = 0$$
+ %%
+
+
+ %% This file is part of
+ %%
+ %% SECS2D - A 2-D Drift--Diffusion Semiconductor Device Simulator
+ %% -------------------------------------------------------------------
+ %% Copyright (C) 2004-2006 Carlo de Falco
+ %%
+ %%
+ %%
+ %% SECS2D is free software; you can redistribute it and/or modify
+ %% it under the terms of the GNU General Public License as published by
+ %% the Free Software Foundation; either version 2 of the License, or
+ %% (at your option) any later version.
+ %%
+ %% SECS2D is distributed in the hope that it will be useful,
+ %% but WITHOUT ANY WARRANTY; without even the implied warranty of
+ %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ %% GNU General Public License for more details.
+ %%
+ %% You should have received a copy of the GNU General Public License
+ %% along with SECS2D; If not, see <http://www.gnu.org/licenses/>.
+
+ global DDGOXNLPOISSON_LAP DDGOXNLPOISSON_MASS DDGOXNLPOISSON_RHS
+
+ %% Set some useful constants
+ dampit = 3;
+ dampcoeff = 2;
+
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %% setup FEM data structures
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ nodes=mesh.p;
+ elements=mesh.t;
+ Nnodes = length(nodes);
+ Nelements = length(elements);
+
+ % Set list of nodes with Dirichelet BCs
+ Dnodes = Unodesonside(mesh,Dsides);
+
+ % Set values of Dirichelet BCs
+ Bc = zeros(length(Dnodes),1);
+ % Set list of nodes without Dirichelet BCs
+ Varnodes = setdiff([1:Nnodes],Dnodes);
+
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %%
+ %% initialization:
+ %% we're going to solve
+ %% $$ - \lambda^2 (\delta V)''
+ %% + (\frac{\partial n}{\partial V}
+ %% - \frac{\partial p}{\partial V})= -R $$
+ %%
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ %% set $$ n_1 = nin $$ and $$ V = Vin $$
+ V = Vin;
+ Fn = Fnin;
+ Fp = Fpin;
+ n = exp((V(Sinodes)-Fn)./Vthn);
+ p = exp((-V(Sinodes)+Fp)./Vthp);
+ n(SiDnodes) = nin(SiDnodes);
+ p(SiDnodes) = pin(SiDnodes);
+
+
+ %%%
+ %%% Compute LHS matrices
+ %%%
+
+ %% let's compute FEM approximation of $$ L = - \frac{d^2}{x^2} $$
+ if (isempty(DDGOXNLPOISSON_LAP))
+ coeff = l2ox * ones(Nelements,1);
+ coeff(Sielements)=l2;
+ DDGOXNLPOISSON_LAP = Ucomplap (mesh,coeff);
+ end
+
+ %% compute $$ Mv = ( n + p) $$
+ %% and the (lumped) mass matrix M
+ if (isempty(DDGOXNLPOISSON_MASS))
+ coeffe = zeros(Nelements,1);
+ coeffe(Sielements)=1;
+ DDGOXNLPOISSON_MASS = Ucompmass2(mesh,ones(Nnodes,1),coeffe);
+ end
+ freecarr=zeros(Nnodes,1);
+ freecarr(Sinodes)=(n./Vthn + p./Vthp);
+ Mv = freecarr;
+ M = DDGOXNLPOISSON_MASS*spdiag(Mv);
+
+ %%%
+ %%% Compute RHS vector (-residual)
+ %%%
+
+ %% now compute $$ T0 = \frac{q}{\epsilon} (n - p - D) $$
+ if (isempty(DDGOXNLPOISSON_RHS))
+ coeffe = zeros(Nelements,1);
+ coeffe(Sielements)=1;
+ DDGOXNLPOISSON_RHS = Ucompconst (mesh,ones(Nnodes,1),coeffe);
+ end
+ totcharge = zeros(Nnodes,1);
+ totcharge(Sinodes)=(n - p - D);
+ Tv0 = totcharge;
+ T0 = Tv0 .* DDGOXNLPOISSON_RHS;
+
+ %% now we're ready to build LHS matrix and RHS of the linear system for 1st Newton step
+ A = DDGOXNLPOISSON_LAP + M;
+ R = DDGOXNLPOISSON_LAP * V + T0;
+
+ %% Apply boundary conditions
+ A (Dnodes,:) = [];
+ A (:,Dnodes) = [];
+ R(Dnodes) = [];
+
+ %% we need $$ \norm{R_1} $$ and $$ \norm{R_k} $$ for the convergence test
+ normr(1) = norm(R,inf);
+ relresnorm = 1;
+ reldVnorm = 1;
+ normrnew = normr(1);
+ dV = V*0;
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %%
+ %% START OF THE NEWTON CYCLE
+ %%
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ for newtit=1:maxit
+ if (verbose>2)
+ fprintf(1,'\n***\nNewton iteration: %d, reldVnorm = %e\n***\n',newtit,reldVnorm);
+ end
+
+ % A(1,end)=realmin;
+ dV(Varnodes) =(A)\(-R);
+ dV(Dnodes)=0;
+
+
+ %%%%%%%%%%%%%%%%%%
+ %% Start of th damping procedure
+ %%%%%%%%%%%%%%%%%%
+ tk = 1;
+ for dit = 1:dampit
+ if (verbose>2)
+ fprintf(1,'\ndamping iteration: %d, residual norm = %e\n',dit,normrnew);
+ end
+ Vnew = V + tk * dV;
+
+ n = exp((Vnew(Sinodes)-Fn)./Vthn);
+ p = exp((-Vnew(Sinodes)+Fp)./Vthp);
+ n(SiDnodes) = nin(SiDnodes);
+ p(SiDnodes) = pin(SiDnodes);
+
+
+ %%%
+ %%% Compute LHS matrices
+ %%%
+
+ %% let's compute FEM approximation of $$ L = - \frac{d^2}{x^2} $$
+ %L = Ucomplap (mesh,ones(Nelements,1));
+
+ %% compute $$ Mv = ( n + p) $$
+ %% and the (lumped) mass matrix M
+ freecarr=zeros(Nnodes,1);
+ freecarr(Sinodes)=(n./Vthn + p./Vthp);
+ Mv = freecarr;
+ M = DDGOXNLPOISSON_MASS*spdiag(Mv);
+
+ %%%
+ %%% Compute RHS vector (-residual)
+ %%%
+
+ %% now compute $$ T0 = \frac{q}{\epsilon} (n - p - D) $$
+ totcharge( Sinodes)=(n - p - D);
+ Tv0 = totcharge;
+ T0 = Tv0 .* DDGOXNLPOISSON_RHS;%T0 = Ucompconst (mesh,Tv0,ones(Nelements,1));
+
+ %% now we're ready to build LHS matrix and RHS of the linear system for 1st Newton step
+ A = DDGOXNLPOISSON_LAP + M;
+ R = DDGOXNLPOISSON_LAP * Vnew + T0;
+
+ %% Apply boundary conditions
+ A (Dnodes,:) = [];
+ A (:,Dnodes) = [];
+ R(Dnodes) = [];
+
+ %% compute $$ | R_{k+1} | $$ for the convergence test
+ normrnew= norm(R,inf);
+
+ % check if more damping is needed
+ if (normrnew > normr(newtit))
+ tk = tk/dampcoeff;
+ else
+ if (verbose>2)
+ fprintf(1,'\nexiting damping cycle because residual norm = %e \n-----------\n',normrnew);
+ end
+ break
+ end
+ end
+
+ V = Vnew;
+ normr(newtit+1) = normrnew;
+ dVnorm = norm(tk*dV,inf);
+ pause(.1);
+ % check if convergence has been reached
+ reldVnorm = dVnorm / norm(V,inf);
+ if (reldVnorm <= toll)
+ if(verbose>2)
+ fprintf(1,'\nexiting newton cycle because reldVnorm= %e \n',reldVnorm);
+ end
+ break
+ end
+
+ end
+
+ res = normr;
+ niter = newtit;
+