]> Creatis software - CreaPhase.git/blobdiff - octave_packages/secs2d-0.0.8/DDGOX/DDGOXnlpoisson.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / secs2d-0.0.8 / DDGOX / DDGOXnlpoisson.m
diff --git a/octave_packages/secs2d-0.0.8/DDGOX/DDGOXnlpoisson.m b/octave_packages/secs2d-0.0.8/DDGOX/DDGOXnlpoisson.m
new file mode 100644 (file)
index 0000000..2ae96a0
--- /dev/null
@@ -0,0 +1,253 @@
+function [V,n,p,res,niter] = DDGOXnlpoisson (mesh,Dsides,Sinodes,SiDnodes,...
+                                             Sielements,Vin,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) - p(V,Fp) -D)$$
+%
+
+
+% 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                 = 10;
+dampcoeff      = 2;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% convert input vectors to columns
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+if Ucolumns(D)>Urows(D)
+       D=D';
+end
+
+
+if Ucolumns(nin)>Urows(nin)
+       nin=nin';
+end
+
+if Ucolumns(pin)>Urows(pin)
+       pin=pin';
+end
+
+if Ucolumns(Vin)>Urows(Vin)
+       Vin=Vin';
+end 
+
+if Ucolumns(Fnin)>Urows(Fnin)
+       Fnin=Fnin';
+end 
+
+if Ucolumns(Fpin)>Urows(Fpin)
+       Fpin=Fpin';
+end 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 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);
+p = exp(-V(Sinodes)+Fp);
+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 + p);
+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>0)
+    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>0)
+                       fprintf(1,'\ndamping iteration: %d, residual norm = %e\n',dit,normrnew);
+               end
+               Vnew   = V + tk * dV;
+               
+               n = exp(Vnew(Sinodes)-Fn);
+               p = exp(-Vnew(Sinodes)+Fp);
+               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 + p);  
+               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>0)
+                               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>0)
+                       fprintf(1,'\nexiting newton cycle because reldVnorm= %e \n',reldVnorm);
+               end
+               break
+       end
+
+end
+
+res = normr;
+niter = newtit;
+