secs2d-0.0.8/ 0000755 0001750 0001750 00000000000 11201031505 010474 5 ustar sh sh secs2d-0.0.8/DESCRIPTION 0000644 0001750 0001750 00000000530 11201030277 012205 0 ustar sh sh Name: SECS2D
Version: 0.0.8
Date: 2009-05-06
Author: Carlo de Falco
Maintainer: Carlo de Falco
Title: SEmi Conductor Simulator in 2D
Description: A Drift-Diffusion simulator for 2d semiconductor devices
Categories: Electrical Engineering
Depends: octave (>= 2.9.17)
Autoload: no
License: GPL version 2 or later
Url: http://www.comson.org/dem
secs2d-0.0.8/inst/ 0000755 0001750 0001750 00000000000 11201031505 011451 5 ustar sh sh secs2d-0.0.8/inst/ThDDGOX/ 0000755 0001750 0001750 00000000000 11201031505 012612 5 ustar sh sh secs2d-0.0.8/inst/ThDDGOX/ThDDGOXupdateelectron_temp.m 0000644 0001750 0001750 00000004177 11201030277 020133 0 ustar sh sh function Tn = ThDDGOXupdateelectron_temp(imesh,Dnodes,Tn,n,p,Tl,Jn,E,mobn0,...
twn0,twn1,tn,tp,n0,p0)
%%
%% Tn = ThDDGOXupdateelectron_temp(mesh,Dnodes,Tn,n,p,Tl,Jn,E,mobn,...
%% twn0,tn,tp,n0,p0)
%%
%% 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 .
Nnodes = columns(imesh.p);
Nelements = columns(imesh.t);
Varnodes = setdiff(1:Nnodes,Dnodes);
alpha = mobn0;
gamma = ones(Nnodes,1);
eta = 1.5 * n .* Tl;
betax = Jn(1,:)./ mobn0';
betay = Jn(2,:)./ mobn0';
beta = -2.5*[betax;betay];
Sn = Uscharfettergummel3(imesh,alpha,gamma,eta,beta);
denom = (tp*(n+sqrt(n0.*p0))+tn*(p+sqrt(n0.*p0)));
R = (p.*n)./denom;
MASS_LHS1 = Ucompmass2(imesh,1.5*R,ones(Nelements,1));
MASS_LHS2 = Ucompmass2(imesh,1.5*n./twn1,1./twn0);
LHS = Sn + MASS_LHS1 + MASS_LHS2;
G = (p0.*n0)./denom;
PJoule = Jn(1,:).*E(1,:) + Jn(2,:).*E(2,:);
PJoule(PJoule<0) = 0;
rhsJoule = Ucompconst (imesh,ones(Nnodes,1),PJoule');
rhsR_G = Ucompconst (imesh,1.5*G.*Tn,ones(Nelements,1));
rhsTh_L = Ucompconst (imesh,1.5*n.*Tl./twn1,1./twn0);
RHS = rhsJoule + rhsR_G + rhsTh_L;
Tn(Varnodes) = LHS(Varnodes,Varnodes) \(RHS(Varnodes) -...
LHS(Varnodes,Dnodes)*Tn(Dnodes));
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXhole_driftdiffusion.m 0000644 0001750 0001750 00000003165 11201030277 020112 0 ustar sh sh function p=ThDDGOXhole_driftdiffusion(mesh,Dnodes,nin,p,V,...
Tp,mobp0,mobp1,tn,tp,n0,p0)
%%
%% p=ThDDGOXhole_driftdiffusion(mesh,Dnodes,nin,p,V,Tp,monp0,mobp1,tn,tp,n0,p0)
%%
%% 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 .
Nnodes = columns(mesh.p);
Nelements = columns(mesh.t);
Varnodes = setdiff(1:Nnodes,Dnodes);
alpha = mobp0;
gamma = mobp1;
eta = Tp;
beta = -V-Tp;
Dp = Uscharfettergummel3(mesh,alpha,gamma,eta,beta);
denom = (tp*(nin+sqrt(n0.*p0))+tn*(p+sqrt(n0.*p0)));
MASS_LHS = Ucompmass2(mesh,nin./denom,ones(Nelements,1));
LHS = Dp+MASS_LHS;
RHS = Ucompconst (mesh,p0.*n0./denom,ones(Nelements,1));
p(Varnodes) = LHS(Varnodes,Varnodes) \(RHS(Varnodes) -...
LHS(Varnodes,Dnodes)*p(Dnodes));
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXTWP0STD.m 0000644 0001750 0001750 00000000316 11201030277 015164 0 ustar sh sh function x = ThDDGOXTWP0STD (imesh,Simesh,Sinodes,Sielements,idata)
Nnodes = columns(Simesh.p);
Nelements = columns(Simesh.t);
x = 1.5 * idata.up * ones(Nelements,1) ./ idata.vsatp^2;
endfunction
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXMOBP0STD.m 0000644 0001750 0001750 00000000270 11201030277 015246 0 ustar sh sh function x = ThDDGOXMOBP0STD (imesh,Simesh,Sinodes,Sielements,idata)
Nnodes = columns(Simesh.p);
Nelements = columns(Simesh.t);
x = idata.up * ones(Nelements,1);
endfunction
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXTWP1STD.m 0000644 0001750 0001750 00000000272 11201030277 015166 0 ustar sh sh function x = ThDDGOXTWP1STD (imesh,Simesh,Sinodes,Sielements,idata)
Nnodes = columns(Simesh.p);
Nelements = columns(Simesh.t);
x = idata.Tl./(1+idata.Tl./idata.Tp);
endfunction
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXnlpoisson.m 0000644 0001750 0001750 00000015040 11201030277 016103 0 ustar sh sh 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 .
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;
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXeletiteration.m 0000644 0001750 0001750 00000007525 11201030277 016740 0 ustar sh sh function [odata,nrm]=ThDDGOXeletiteration(imesh,Dsides,...
Simesh,Sinodes,Sielements,SiDsides,...
idata,toll,maxit,ptoll,pmaxit,verbose)
## function [odata,nrm]=ThDDGOXeletiteration(imesh,Dsides,...
## Simesh,Sinodes,Sielements,SiDsides,areaSi,SiPatch,...
## idata,toll,maxit,ptoll,pmaxit,verbose)
global DDGOXNLPOISSON_LAP DDGOXNLPOISSON_MASS DDGOXNLPOISSON_RHS DDG_RHS DDG_MASS
%%%%%%%%%%%%%%%
%% RRE param %%
RREnnit = [1,2];
RRErank = 7;
RREpattern = URREcyclingpattern(RREnnit,RRErank,maxit);
%%%%%%%%%%%%%%%
odata = idata;
V(:,1) = idata.V;
Fn(:,1) = idata.Fn;
Fp(:,1) = idata.Fp;
n(:,1) = idata.n;
p(:,1) = idata.p;
Tl = idata.Tl;
Tn = idata.Tn;
Tp = idata.Tp;
%% Set list of nodes with Dirichlet BCs
Dnodes = Unodesonside(imesh,Dsides);
SiDnodes = Unodesonside(Simesh,SiDsides);
SiNelements = columns(Simesh.t);
D = idata.D;
nrm = 1;
for ielet=1:maxit
if (verbose>=1)
fprintf(1,"*** start of inner iteration number: %d\n",ielet);
end
if (verbose>=1)
fprintf(1,"\t*** solving non linear poisson equation\n");
end
Fnshift = log(idata.ni) .* (1-Tn);
Fpshift = -log(idata.ni) .* (1-Tp);
[V(:,2),n(:,2),p(:,2)] = ThDDGOXnlpoisson (imesh,Dsides,Sinodes,SiDnodes,Sielements,...
V(:,1),Tn,Tp,...
n(:,1),p(:,1),Fn(:,1)+Fnshift,Fp(:,1)+Fpshift,D,...
idata.l2,idata.l2ox,ptoll,pmaxit,verbose-1);
V(Dnodes,2) = idata.V(Dnodes);
if (verbose>=1)
fprintf (1,"\t***\tupdating electron qfl\n");
end
odata.V = V(:,2);
odata.n = n(:,2);
odata.p = p(:,2);
mobn0 = idata.mobn0(imesh,Simesh,Sinodes,Sielements,odata);
mobp0 = idata.mobp0(imesh,Simesh,Sinodes,Sielements,odata);
mobn1 = idata.mobn1(imesh,Simesh,Sinodes,Sielements,odata);
mobp1 = idata.mobp1(imesh,Simesh,Sinodes,Sielements,odata);
n(:,3) = ThDDGOXelectron_driftdiffusion(Simesh,SiDnodes,n(:,2),p(:,2),...
V(Sinodes,2),Tn,mobn0,mobn1,...
idata.tn,idata.tp,idata.ni,idata.ni);
Fn(:,2)=V(Sinodes,2) - Tn .* log(n(:,3)) - Fnshift;
n(SiDnodes,3) = idata.n(SiDnodes);
Fn(SiDnodes,2) = idata.Fn(SiDnodes);
if (verbose>=1)
fprintf(1,"\t***\tupdating hole qfl\n");
end
p(:,3) = ThDDGOXhole_driftdiffusion(Simesh,SiDnodes,n(:,3),p(:,2),...
V(Sinodes,2),Tp,mobp0,mobp1,...
idata.tn,idata.tp,idata.ni,idata.ni);
Fp(:,2)= V(Sinodes,2) + Tp .* log(p(:,3)) - Fpshift;
p(SiDnodes,3) = idata.p(SiDnodes);
Fp(SiDnodes,2) = idata.Fp(SiDnodes);
## store result for RRE
if RREpattern(ielet)>0
Fermistore(:,RREpattern(ielet)) = [Fn(:,2);Fp(:,2)];
if RREpattern(ielet+1)==0 % Apply RRE extrapolation
if (verbose>=1)
fprintf(1,"\n\t**********\n\tRRE EXTRAPOLATION STEP\n\t**********\n\n");
end
Fermi = Urrextrapolation(Fermistore);
Fn(:,2) = Fermi(1:rows(Fn));
Fp(:,2) = Fermi(rows(Fn)+1:end);
end
end
if (verbose>=1)
fprintf(1,"*** checking for convergence: ");
end
nrfn= norm (Fn(:,2)-Fn(:,1),inf);
nrfp= norm (Fp(:,2)-Fp(:,1),inf);
nrv = norm (V(:,2)-V(:,1),inf);
nrm(ielet) = max([nrfn;nrfp;nrv]);
if (verbose>=1)
subplot(1,3,3);
semilogy(nrm)
%%title("max(|dV|,|dFn|,|dFp|)");
pause(.1)
end
if (verbose>=1)
fprintf (1," max(|dFn|,|dFp|,|dV| )= %g\n\n",...
nrm(ielet));
end
if (nrm(ielet)0)
fprintf(1,"\n*** DD simulation over: # of electrical Gummel iterations = %d\n\n",ielet);
end
odata = idata;
odata.n = n(:,end);
odata.p = p(:,end);
odata.V = V(:,end);
odata.Fn = Fn(:,end);
odata.Fp = Fp(:,end);
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXthermaliteration.m 0000644 0001750 0001750 00000011005 11201030277 017427 0 ustar sh sh function [thermdata,nrm] = ThDDGOXthermaliteration(imesh,Dsides,...
Simesh,Sinodes,Sielements,...
SiDsides,thermdata,toll,...
maxit,verbose)
%% [thermdata,innrm] = ThDDGOXthermaliteration(imesh,Dsides,...
%% Simesh,Sinodes,Sielements,...
%% SiDsides,thermdata,toll,...
%% maxit,verbose)
%%%%%%%%%%%%%%%
%% RRE param %%
RREnnit = [10,2];
RRErank = maxit;
RREpattern = URREcyclingpattern(RREnnit,RRErank,maxit);
%%%%%%%%%%%%%%%
%% Set list of nodes with Dirichlet BCs
Dnodes = Unodesonside(imesh,Dsides);
SiDnodes = Unodesonside(Simesh,SiDsides);
Tl = thermdata.Tl;
Tn = thermdata.Tn;
Tp = thermdata.Tp;
tldampcoef = 1;
tndampcoef = 10;
tpdampcoef = 10;
mobn0 = thermdata.mobn0(imesh,Simesh,Sinodes,Sielements,thermdata);
mobp0 = thermdata.mobp0(imesh,Simesh,Sinodes,Sielements,thermdata);
mobn1 = thermdata.mobn1(imesh,Simesh,Sinodes,Sielements,thermdata);
mobp1 = thermdata.mobp1(imesh,Simesh,Sinodes,Sielements,thermdata);
twn0 = thermdata.twn0 (imesh,Simesh,Sinodes,Sielements,thermdata);
twp0 = thermdata.twp0 (imesh,Simesh,Sinodes,Sielements,thermdata);
twn1 = thermdata.twn1 (imesh,Simesh,Sinodes,Sielements,thermdata);
twp1 = thermdata.twp1 (imesh,Simesh,Sinodes,Sielements,thermdata);
[Ex,Ey] = Updegrad(Simesh,-thermdata.V(Sinodes));
E = [Ex;Ey];
[jnx,jny] = Ufvsgcurrent3(Simesh,thermdata.n,...
mobn0,mobn1,Tn,thermdata.V(Sinodes)-Tn);
[jpx,jpy] = Ufvsgcurrent3(Simesh,thermdata.p,...
-mobp0,mobp1,Tp,-thermdata.V(Sinodes)-Tp);
Jn = [jnx;jny];
Jp = [jpx;jpy];
for ith=1:maxit
if (verbose>=1)
fprintf(1,"*** start of inner iteration number: %d\n",ith);
end
if (verbose>=1)
fprintf(1,'\t***updating electron temperature\n');
end
Tn = ThDDGOXupdateelectron_temp(Simesh,SiDnodes,thermdata.Tn,...
thermdata.n,thermdata.p,...
thermdata.Tl,Jn,E,mobn0,...
twn0,twn1,thermdata.tn,thermdata.tp,...
thermdata.ni,thermdata.ni);
##Tn(Tn0)
tndampfact_n = log(1+tndampcoef*dtn)/(tndampcoef*dtn);
Tn = tndampfact_n * Tn + (1-tndampfact_n) * thermdata.Tn;
end
if (verbose>=1)
fprintf(1,'\t***updating hole temperature\n');
end
Tp = ThDDGOXupdatehole_temp(Simesh,SiDnodes,thermdata.Tp,...
thermdata.n,thermdata.p,...
thermdata.Tl,Jp,E,mobp0,...
twp0,twp1,thermdata.tn,thermdata.tp,...
thermdata.ni,thermdata.ni);
##Tp(Tp0)
tpdampfact_p = log(1+tpdampcoef*dtp)/(tpdampcoef*dtp);
Tp = tpdampfact_p * Tp + (1-tpdampfact_p) * thermdata.Tp;
end
if (verbose>=1)
fprintf(1,'\t***updating lattice temperature\n');
end
## store result for RRE
if RREpattern(ith)>0
TEMPstore(:,RREpattern(ith)) = [Tn;Tp;Tl];
if RREpattern(ith+1)==0 % Apply RRE extrapolation
if (verbose>=1)
fprintf(1,"\n\t**********\n\tRRE EXTRAPOLATION STEP\n\t**********\n\n");
end
TEMP = Urrextrapolation(TEMPstore);
Tn = TEMP(1:rows(Tn));
Tp = TEMP(rows(Tn)+1:rows(Tn)+rows(Tp));
Tl = TEMP(rows(Tn)+rows(Tp)+1:end);
end
end
Tl = ThDDGOXupdatelattice_temp(Simesh,SiDnodes,thermdata.Tl,...
Tn,Tp,thermdata.n,...
thermdata.p,thermdata.kappa,thermdata.Egap,...
thermdata.tn,thermdata.tp,twn0,...
twp0,twn1,twp1,...
thermdata.ni,thermdata.ni);
##Tl(Tl 0)
tldampfact = log(1+tldampcoef*dtl)/(tldampcoef*dtl);
Tl = tldampfact * Tl + (1-tldampfact) * thermdata.Tl;
end
if (verbose>=1)
fprintf(1,"\t*** checking for convergence:\n ");
end
nrm(ith) = max([dtl,dtn,dtp]);
if (verbose>=1)
fprintf (1,"\t\t|dTL|= %g\n",dtl);
fprintf (1,"\t\t|dTn|= %g\n",dtn);
fprintf (1,"\t\t|dTp|= %g\n",dtp);
end
thermdata.Tl = Tl;
thermdata.Tn = Tn;
thermdata.Tp = Tp;
if (verbose>1)
subplot(1,3,2);
title("max(|dTl|,|dTn|,|dTn|)")
semilogy(nrm)
pause(.1)
end
if nrm(ith)< toll
if (verbose>=1)
fprintf(1,"\n***\n***\texit from thermal iteration \n");
end
break
end
end secs2d-0.0.8/inst/ThDDGOX/ThDDGOXMOBN0STD.m 0000644 0001750 0001750 00000000270 11201030277 015244 0 ustar sh sh function x = ThDDGOXMOBN0STD (imesh,Simesh,Sinodes,Sielements,idata)
Nnodes = columns(Simesh.p);
Nelements = columns(Simesh.t);
x = idata.un * ones(Nelements,1);
endfunction
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXddcurrent.m 0000644 0001750 0001750 00000003403 11201030277 016051 0 ustar sh sh function [current,divrg]=ThDDGOXddcurrent(Simesh,Sinodes,data,contacts);
% [current,divrg]=DDGOXddcurrent(Simesh,Sinodes,data,contacts);
% 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 .
load (file_in_path(path,'constants.mat'))
Nelements = size(mesh.t,2);
mobn0 = thermdata.mobn0([],Simesh,Sinodes,[],data);
mobp0 = thermdata.mobp0([],Simesh,Sinodes,[],data);
mobn1 = thermdata.mobn1([],Simesh,Sinodes,[],data);
mobp1 = thermdata.mobp1([],Simesh,Sinodes,[],data);
An = Uscharfettergummel3(Simesh,mobn0,mobn1,data.Tn,data.V(Sinodes)-data.Tn);
Ap = Uscharfettergummel3(Simesh,mobp0,mobp1,data.Tp,-data.V(Sinodes)-data.Tn);
divrg = An * data.n + Ap * data.p;
for con = 1:length(contacts)
cedges = [];
cedges=[cedges,find(mesh.e(5,:)==contacts(con))];
cnodes = mesh.e(1:2,cedges);
cnodes = [cnodes(1,:) cnodes(2,:)];
cnodes = unique(cnodes);
current(con) = sum(divrg(cnodes));
end
Is = q*data.us*data.Vs*data.ns;
current = current * Is;
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXgummelmap.m 0000644 0001750 0001750 00000003456 11201030277 016053 0 ustar sh sh function [odata,ith,res] = ThDDGOXgummelmap (imesh,Dsides,...
Simesh,Sinodes,Sielements,SiDsides,...
idata,tol,maxit,ptol,pmaxit,thtol,thmaxit,...
eltol,elmaxit,verbose)
## [odata,it,res] = ThDDGOXgummelmap (imesh,Dsides,...
## Simesh,Sinodes,Sielements,SiDsides,...
## idata,tol,maxit,ptol,pmaxit,thtol,thmaxit,...
## eltol,elmaxit,verbose)
clear DDGOXNLPOISSON_LAP DDGOXNLPOISSON_MASS DDGOXNLPOISSON_RHS DDG_RHS DDG_MASS
global DDGOXNLPOISSON_LAP DDGOXNLPOISSON_MASS DDGOXNLPOISSON_RHS DDG_RHS DDG_MASS
eletdata = idata;
thermdata = idata;
nrm = 1;
eletnrm = [];
thermnrm = [];
for ith=1:maxit
eletdata.Tl = thermdata.Tl;
eletdata.Tn = thermdata.Tn;
eletdata.Tp = thermdata.Tp;
if (verbose>=1)
fprintf(1,'\n***\n***\tupdating potentials\n***\n');
end
[eletdata,innrm1]=ThDDGOXeletiteration(imesh,Dsides,...
Simesh,Sinodes,Sielements,SiDsides,...
eletdata,eltol,elmaxit,ptol,pmaxit,verbose);
eletnrm = [eletnrm,innrm1];
thermdata.n = eletdata.n;
thermdata.p = eletdata.p;
thermdata.V = eletdata.V;
if (verbose>=1)
fprintf(1,'\n***\n***\tupdating temperatures\n***\n');
end
[thermdata,innrm] = ThDDGOXthermaliteration(imesh,Dsides,...
Simesh,Sinodes,Sielements,SiDsides,...
thermdata,thtol,thmaxit,2);
thermnrm = [eletnrm,innrm];
nrm(ith) = max([innrm,innrm1]);
if (verbose>=1)
subplot(1,3,1);
semilogy(nrm)
pause(.1)
end
if (nrm(ith)0)
fprintf(1,"\n***\n***\tThDD simulation over: # \
of Global iterations = %d\n***\n",ith);
end
break
end
end
res = {nrm,eletnrm,thermnrm};
odata = thermdata;
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXTWN1STD.m 0000644 0001750 0001750 00000000273 11201030277 015165 0 ustar sh sh function x = ThDDGOXTWN1STD (imesh,Simesh,Sinodes,Sielements,idata)
Nnodes = columns(Simesh.p);
Nelements = columns(Simesh.t);
x = idata.Tl./(1+idata.Tl./idata.Tn);
endfunction
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXupdatehole_temp.m 0000644 0001750 0001750 00000004171 11201030277 017241 0 ustar sh sh function Tp = ThDDGOXupdatehole_temp(imesh,Dnodes,Tp,n,p,Tl,Jp,E,mobp0,...
twp0,twp1,tn,tp,n0,p0)
%%
%% Tp = ThDDGOXupdatehole_temp(mesh,Dnodes,Tp,n,p,Tl,Jp,E,mobp0,...
%% twp0,twp1,tn,tp,n0,p0)
%%
%% 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 .
Nnodes = columns(imesh.p);
Nelements = columns(imesh.t);
Varnodes = setdiff(1:Nnodes,Dnodes);
alpha = mobp0;
gamma = ones(Nnodes,1);
eta = 1.5 * p .* Tl;
betax = Jp(1,:)./ mobp0';
betay = Jp(2,:)./ mobp0';
beta = 2.5*[betax;betay];
Sn = Uscharfettergummel3(imesh,alpha,gamma,eta,beta);
denom = (tp*(n+sqrt(n0.*p0))+tn*(p+sqrt(n0.*p0)));
R = (p.*n)./denom;
MASS_LHS1 = Ucompmass2(imesh,1.5*R,ones(Nelements,1));
MASS_LHS2 = Ucompmass2(imesh,1.5*p./twp1,1./twp0);
LHS = Sn + MASS_LHS1 + MASS_LHS2;
G = (p0.*n0)./denom;
PJoule = Jp(1,:).*E(1,:) + Jp(2,:).*E(2,:);
PJoule(PJoule<0) = 0;
rhsJoule = Ucompconst (imesh,ones(Nnodes,1),PJoule');
rhsR_G = Ucompconst (imesh,1.5*G.*Tp,ones(Nelements,1));
rhsTh_L = Ucompconst (imesh,1.5*p.*Tl./twp1,1./twp0);
RHS = rhsJoule + rhsR_G + rhsTh_L;
Tp(Varnodes) = LHS(Varnodes,Varnodes) \(RHS(Varnodes) -...
LHS(Varnodes,Dnodes)*Tp(Dnodes));
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXMOBN1STD.m 0000644 0001750 0001750 00000000255 11201030277 015250 0 ustar sh sh function x = ThDDGOXMOBN1STD (imesh,Simesh,Sinodes,Sielements,idata)
Nnodes = columns(Simesh.p);
Nelements = columns(Simesh.t);
x = idata.Tl./idata.Tn;
endfunction
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXelectron_driftdiffusion.m 0000644 0001750 0001750 00000003157 11201030277 020777 0 ustar sh sh function n=ThDDGOXelectron_driftdiffusion(mesh,Dnodes,n,pin,V,...
Tn,mobn0,mobn1,tn,tp,n0,p0)
%%
%% n=ThDDGOXelectron_driftdiffusion(mesh,Dnodes,n,pin,V,Tn,un0,un1,tn,tp,n0,p0)
%%
%% 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 .
Nnodes = columns(mesh.p);
Nelements = columns(mesh.t);
Varnodes = setdiff(1:Nnodes,Dnodes);
alpha = mobn0;
gamma = mobn1;
eta = Tn;
beta = V-Tn;
Dn = Uscharfettergummel3(mesh,alpha,gamma,eta,beta);
denom = (tp*(n+sqrt(n0.*p0))+tn*(pin+sqrt(n0.*p0)));
MASS_LHS = Ucompmass2(mesh,pin./denom,ones(Nelements,1));
LHS = Dn+MASS_LHS;
RHS = Ucompconst (mesh,p0.*n0./denom,ones(Nelements,1));
n(Varnodes) = LHS(Varnodes,Varnodes) \(RHS(Varnodes) -...
LHS(Varnodes,Dnodes)*n(Dnodes));
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXTWN0STD.m 0000644 0001750 0001750 00000000316 11201030277 015162 0 ustar sh sh function x = ThDDGOXTWN0STD (imesh,Simesh,Sinodes,Sielements,idata)
Nnodes = columns(Simesh.p);
Nelements = columns(Simesh.t);
x = 1.5 * idata.un * ones(Nelements,1) ./ idata.vsatn^2;
endfunction
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXupdatelattice_temp.m 0000644 0001750 0001750 00000003755 11201030277 017746 0 ustar sh sh function Tl = ThDDGOXupdatelattice_temp(mesh,Dnodes,Tl,Tn,Tp,n,p,...
kappa,Egap,tn,tp,...
twn0,twp0,twn1,twp1,n0,p0)
%%
%% Tl = ThDDGOXupdatelattice_temp(mesh,Dnodes,Tl,Tn,Tp,n,p,...
%% kappa,Egap,tn,tp,...
%% twn0,twp0,twn1,twp1,n0,p0)
%% 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 .
Nnodes = columns(mesh.p);
Nelements = columns(mesh.t);
Varnodes = setdiff(1:Nnodes,Dnodes);
alpha = kappa*ones(Nelements,1);
gamma = Tl.^(-4/3);
eta = ones (Nnodes,1);
L = Uscharfettergummel3(mesh,alpha,gamma,eta,0);
MASS_LHSn = Ucompmass2(mesh,1.5*n./twn1,1./twn0);
MASS_LHSp = Ucompmass2(mesh,1.5*p./twp1,1./twp0);
LHS = L+MASS_LHSn+MASS_LHSp;
denom = (tp*(n+sqrt(n0.*p0))+tn*(p+sqrt(n0.*p0)));
U = (p.*n-p0.*n0)./denom;
RHS1 = Ucompconst(mesh,(Egap+1.5*(Tn + Tp)).*U,ones(Nelements,1));
RHS2n = Ucompconst(mesh,1.5*n.*Tn./twn1,1./twn0);
RHS2p = Ucompconst(mesh,1.5*p.*Tp./twp1,1./twp0);
RHS = RHS1 + RHS2n + RHS2p;
Tl(Varnodes) = LHS(Varnodes,Varnodes) \...
(RHS(Varnodes) - LHS(Varnodes,Dnodes)*Tl(Dnodes));
secs2d-0.0.8/inst/ThDDGOX/ThDDGOXMOBP1STD.m 0000644 0001750 0001750 00000000255 11201030277 015252 0 ustar sh sh function x = ThDDGOXMOBP1STD (imesh,Simesh,Sinodes,Sielements,idata)
Nnodes = columns(Simesh.p);
Nelements = columns(Simesh.t);
x = idata.Tl./idata.Tp;
endfunction
secs2d-0.0.8/inst/METLINES/ 0000755 0001750 0001750 00000000000 11201031505 012671 5 ustar sh sh secs2d-0.0.8/inst/METLINES/METLINEScapcomp.m 0000644 0001750 0001750 00000001427 11201030277 015643 0 ustar sh sh function [C,L,Lii,LiI,LII,Dnodes,varnodes]=...
METLINEScapcomp(imesh,epsilon,contacts)
##
##
## [C,L,Lii,LiI,LII,Dnodes,varnodes]=METLINEScapcomp(imesh,epsilon,contacts)
##
##
Ncontacts = length(contacts);
Nnodes = columns(imesh.p);
varnodes = [1:Nnodes];
for ii=1:Ncontacts
Dnodes{ii}=Unodesonside(imesh,contacts{ii});
varnodes = setdiff(varnodes,Dnodes{ii});
end
L = Ucomplap (imesh,epsilon);
for ii=1:Ncontacts
Lii{ii} = L(Dnodes{ii},Dnodes{ii});
LiI{ii} = L(Dnodes{ii},varnodes);
end
LII = L(varnodes,varnodes);
for ii=1:Ncontacts
for jj=ii:Ncontacts
if ii==jj
C(ii,jj)=sum(sum(Lii{ii}-LiI{ii}*(LII\(LiI{ii})')));
else
C(ii,jj)=sum(sum(-LiI{ii}*(LII\(LiI{jj})')));
end
end
end
for ii=1:4
for jj=1:ii-1
C(ii,jj)=C(jj,ii);
end
end
secs2d-0.0.8/inst/METLINES/METLINESdefinepermittivity.m 0000644 0001750 0001750 00000000632 11201030277 020142 0 ustar sh sh function epsilon = METLINESdefinepermittivity(omesh,basevalue,varargin);
##
##
## epsilon = METLINESdefinepermittivity(omesh,basevalue,[regions1, value1,...]);
##
##
load (file_in_path(path,'constants.mat'));
epsilon = e0*basevalue*ones(size(omesh.t(1,:)))';
for ii=1:floor(length(varargin)/2)
[ignore1,ignore2,elements]=Usubmesh(omesh,[],varargin{2*ii-1},1);
epsilon(elements) = varargin{2*ii}*e0;
end
secs2d-0.0.8/inst/DDGOX/ 0000755 0001750 0001750 00000000000 11201031505 012316 5 ustar sh sh secs2d-0.0.8/inst/DDGOX/DDGOXhole_driftdiffusion.m 0000644 0001750 0001750 00000003134 11201030277 017316 0 ustar sh sh function p=DDGOXhole_driftdiffusion(mesh,Dsides,nin,pin,V,up,tn,tp,n0,p0)
%%
% p=DDGhole_driftdiffusion(mesh,Dsides,nin,pin,V,up,tn,tp,n0,p0)
% IN:
% v = electric potential
% mesh = integration domain
% nin = initial guess and BCs for electron density
% pin = hole density (to compute SRH recombination)
% OUT:
% p = updated hole density
%%
% 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 .
if (Ucolumns(nin)>Urows(nin))
nin=nin';
end
if (Ucolumns(V)>Urows(V))
V=V';
end
if (Ucolumns(pin)>Urows(pin))
pin=pin';
end
Nnodes = max(size(mesh.p));
Nelements = max(size(mesh.t));
denom = (tp*(nin+sqrt(n0.*p0))+tn*(pin+sqrt(n0.*p0)));
u = up;
U = n0.*p0./denom;
M = nin./denom;
guess = pin;
V = -V;
p = Udriftdiffusion(mesh,Dsides,guess,M,U,V,u);
secs2d-0.0.8/inst/DDGOX/DDGOXgummelmap.m 0000644 0001750 0001750 00000012313 11201030277 015253 0 ustar sh sh function [odata,it,res] = DDGOXgummelmap (imesh,Dsides,...
Simesh,Sinodes,Sielements,SiDsides,...
idata,toll,maxit,ptoll,pmaxit,verbose)
% [odata,it,res] = DDGOXgummelmap (imesh,Dsides,...
% Simesh,Sinodes,Sielements,SiDsides,...
% idata,toll,maxit,ptoll,pmaxit,verbose)
%
% 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 .
clear DDGOXNLPOISSON_LAP DDGOXNLPOISSON_MASS DDGOXNLPOISSON_RHS DDG_RHS DDG_MASS
global DDGOXNLPOISSON_LAP DDGOXNLPOISSON_MASS DDGOXNLPOISSON_RHS DDG_RHS DDG_MASS
%%%%%%%%%%%%%%%
%% RRE param %%
RREnnit = [1,0];
RRErank = 5;
RREpattern = URREcyclingpattern(RREnnit,RRErank,maxit);
%%%%%%%%%%%%%%%
Nnodes = max(size(imesh.p));
Nelements = max(size(imesh.t));
SiNnodes = max(size(Simesh.p));
SiNelements = max(size(Simesh.t));
V (:,1) = idata.V;
p (:,1) = idata.p;
n (:,1) = idata.n;
Fn(:,1) = idata.Fn;
Fp(:,1) = idata.Fp;
D = idata.D;
% Set list of nodes with Dirichelet BCs
Dnodes = Unodesonside(imesh,Dsides);
% Set list of nodes with Dirichelet BCs
SiDnodes = Unodesonside(Simesh,SiDsides);
nrm = 1;
for i=1:1:maxit
if (verbose>=1)
fprintf(1,'*****************************************************************\n');
fprintf(1,'**** start of gummel iteration number: %d\n',i);
fprintf(1,'*****************************************************************\n');
end
if (verbose>=1)
fprintf(1,'solving non linear poisson equation\n');
if ((i>1)&(verbose>1))
DDGOXplotresults(imesh,Simesh,n(:,1)*idata.ns,p(:,1)*idata.ns,V(:,1)*idata.Vs,...
Fn(:,1)*idata.Vs,Fp(:,1)*idata.Vs,i,nrm(end),'poisson');
end
end
[V(:,2),n(:,2),p(:,2)] =...
DDGOXnlpoisson (imesh,Dsides,Sinodes,SiDnodes,Sielements,...
V(:,1),n(:,1),p(:,1),Fn(:,1),Fp(:,1),D,...
idata.l2,idata.l2ox,ptoll,pmaxit,verbose-1);
V(Dnodes,2) = idata.V(Dnodes);
if (verbose>=1)
fprintf (1,'***\nupdating electron qfl\n');
if ((i>1)&(verbose>1))
DDGOXplotresults(imesh,Simesh,n(:,2)*idata.ns,p(:,2)*idata.ns,...
V(:,2)*idata.Vs,Fn(:,1)*idata.Vs,Fp(:,1)*idata.Vs,i,nrm(end),'e- continuity');
end
end
mob = Ufielddepmob(Simesh,idata.un,Fn(:,1),idata.vsatn,idata.mubn);
n(:,3) =DDGOXelectron_driftdiffusion(Simesh,SiDsides,n(:,2),p(:,2),...
V(Sinodes,2),mob,...
idata.tn,idata.tp,idata.ni,idata.ni);
Fn(:,2)=V(Sinodes,2) - log(n(:,3));
n(SiDnodes,3) = idata.n(SiDnodes);
Fn(SiDnodes,2) = idata.Fn(SiDnodes);
%%%% store result for RRE
if RREpattern(i)>0
Fnstore(:,RREpattern(i)) = Fn(:,2);
if RREpattern(i+1)==0 % Apply RRE extrapolation
if (verbose>=1)
fprintf(1,'\n**********\nRRE EXTRAPOLATION STEP\n**********\n');
end
Fn(:,2) = Urrextrapolation(Fnstore);
end
end
if (verbose>=1)
fprintf(1,'***\nupdating hole qfl\n');
if ((i>1)&(verbose>1))
DDGOXplotresults(imesh,Simesh,n(:,3)*idata.ns,p(:,2)*idata.ns,V(:,2)*idata.Vs,...
Fn(:,2)*idata.Vs,Fp(:,1)*idata.Vs,i,nrm(end),'h+ continuity');
end
end
mob = Ufielddepmob(Simesh,idata.up,Fp(:,1),idata.vsatp,idata.mubp);
p(:,3) =DDGOXhole_driftdiffusion(Simesh,SiDsides,n(:,3),p(:,2),...
V(Sinodes,2),mob,...
idata.tn,idata.tp,idata.ni,idata.ni);
Fp(:,2)= V(Sinodes,2) + log(p(:,3));
p(SiDnodes,3) = idata.p(SiDnodes);
Fp(SiDnodes,2) = idata.Fp(SiDnodes);
if (verbose>=1)
fprintf(1,'checking for convergence\n');
end
nrfn= norm(Fn(:,2)-Fn(:,1),inf);
nrfp= norm (Fp(:,2)-Fp(:,1),inf);
nrv = norm (V(:,2)-V(:,1),inf);
nrm(i) = max([nrfn;nrfp;nrv]);
if (verbose>1)
figure(2);
semilogy(nrm)
pause(.1)
end
if (verbose>=1)
fprintf (1,' max(|phin_(k+1)-phinn_(k)| ,...\n |phip_(k+1)-phip_(k)| ,...\n |v_(k+1)- v_(k)| )= %g\n',nrm(i));
end
if (nrm(i)0)
fprintf(1,'\n***********\nDD simulation over:\n # of Gummel iterations = %d\n\n',it);
end
odata = idata;
odata.n = n(:,end);
odata.p = p(:,end);
odata.V = V(:,end);
odata.Fn = Fn(:,end);
odata.Fp = Fp(:,end);
secs2d-0.0.8/inst/DDGOX/DDGOXplotresults.m 0000644 0001750 0001750 00000003142 11201030277 015667 0 ustar sh sh function DDGOXplotresults(mesh,Simesh,n,p,V,Fn,Fp,gi,nrm,step);
%
% DDGOXplotresults(mesh,Simesh,n,p,V,Fn,Fp,gi,nrm,step);
%
%
% 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 .
f1=figure(1);
subplot(2,3,1)
Updesurf(Simesh,log10(n),'colormap','jet','mesh','off','contour','on');
title('Electron Density (log)'); grid; colorbar; view(2)
subplot(2,3,2)
Updesurf(Simesh,log10(p),'colormap','jet','mesh','off');
title('Hole Density (log)'); grid; colorbar; view(2)
subplot(2,3,4)
Updesurf(Simesh,Fn,'colormap','jet','mesh','off');
title('Electron QFL'); grid; colorbar; view(2)
subplot(2,3,5)
Updesurf(Simesh,Fp,'colormap','jet','mesh','off');
title('Hole QFL'); grid; colorbar; view(2)
subplot(1,3,3)
Updesurf(mesh,V,'colormap','jet','mesh','off');
title('Electric Potential'); grid; colorbar; view(2)
pause(.1)
secs2d-0.0.8/inst/DDGOX/DDGOXnlpoisson.m 0000644 0001750 0001750 00000014353 11201030277 015321 0 ustar sh sh 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 .
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;
secs2d-0.0.8/inst/DDGOX/DDGOXddcurrent.m 0000644 0001750 0001750 00000003165 11201030277 015266 0 ustar sh sh function [current,divrg]=DDGOXddcurrent(mesh,Sinodes,data,contacts);
% [current,divrg]=DDGOXddcurrent(mesh,Sinodes,data,contacts);
% 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 .
load (file_in_path(path,'constants.mat'))
Nelements = size(mesh.t,2);
mob = Ufielddepmob(mesh,data.un,data.Fn,data.vsatn,data.mubn);
An = Uscharfettergummel(mesh,data.V(Sinodes),mob);
mob = Ufielddepmob(mesh,data.up,data.Fp,data.vsatp,data.mubp);
Ap = Uscharfettergummel(mesh,-data.V(Sinodes),mob);
divrg = An * data.n + Ap * data.p;
for con = 1:length(contacts)
cedges = [];
cedges=[cedges,find(mesh.e(5,:)==contacts(con))];
cnodes = mesh.e(1:2,cedges);
cnodes = [cnodes(1,:) cnodes(2,:)];
cnodes = unique(cnodes);
current(con) = sum(divrg(cnodes));
end
Is = q*data.us*data.Vs*data.ns;
current = current * Is;
secs2d-0.0.8/inst/DDGOX/DDGOXelectron_driftdiffusion.m 0000644 0001750 0001750 00000003132 11201030277 020200 0 ustar sh sh function n=DDGOXelectron_driftdiffusion(mesh,Dsides,nin,pin,V,un,tn,tp,n0,p0)
%%
% n=DDGelectron_driftdiffusion(mesh,Dsides,nin,pin,V,un,tn,tp,n0,p0)
% IN:
% v = electric potential
% mesh = integration domain
% ng = initial guess and BCs for electron density
% p = hole density (to compute SRH recombination)
% OUT:
% n = updated electron density
%%
% 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 .
if (Ucolumns(nin)>Urows(nin))
nin=nin';
end
if (Ucolumns(V)>Urows(V))
V=V';
end
if (Ucolumns(pin)>Urows(pin))
pin=pin';
end
Nnodes = max(size(mesh.p));
Nelements = max(size(mesh.t));
denom = (tp*(nin+sqrt(n0.*p0))+tn*(pin+sqrt(n0.*p0)));
u = un;
U = p0.*n0./denom;
M = pin./denom;
guess = nin;
n = Udriftdiffusion(mesh,Dsides,guess,M,U,V,u);
secs2d-0.0.8/inst/DDGOXT/ 0000755 0001750 0001750 00000000000 11201031505 012442 5 ustar sh sh secs2d-0.0.8/inst/DDGOXT/DDGOXTgummelmap.m 0000644 0001750 0001750 00000011170 11201030277 015523 0 ustar sh sh function [odata,it,res] = DDGOXTgummelmap (imesh,Dsides,...
Simesh,Sinodes,Sielements,SiDsides,...
idata,nold,pold,weight,toll,maxit,ptoll,...
pmaxit,verbose)
# function [odata,it,res] = DDGOXTgummelmap (imesh,Dsides,...
# Simesh,Sinodes,Sielements,SiDsides,...
# idata,oldn,oldp,weight,toll,maxit,ptoll,...
# pmaxit,verbose)
% 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 .
clear DDGOXNLPOISSON_LAP DDGOXNLPOISSON_MASS DDGOXNLPOISSON_RHS DDG_RHS DDG_MASS
global DDGOXNLPOISSON_LAP DDGOXNLPOISSON_MASS DDGOXNLPOISSON_RHS DDG_RHS DDG_MASS
%%%%%%%%%%%%%%%
%% RRE param %%
RREnnit = [5,5];
RRErank = 4;
RREpattern = URREcyclingpattern(RREnnit,RRErank,maxit);
%%%%%%%%%%%%%%%
Nnodes = max(size(imesh.p));
Nelements = max(size(imesh.t));
SiNnodes = max(size(Simesh.p));
SiNelements = max(size(Simesh.t));
V (:,1) = idata.V;
p (:,1) = idata.p;
n (:,1) = idata.n;
Fn(:,1) = idata.Fn;
Fp(:,1) = idata.Fp;
D = idata.D;
% Set list of nodes with Dirichelet BCs
Dnodes = Unodesonside(imesh,Dsides);
% Set list of nodes with Dirichelet BCs
SiDnodes = Unodesonside(Simesh,SiDsides);
nrm = 1;
for i=1:1:maxit
if (verbose>=1)
fprintf(1,'*****************************************************************\n');
fprintf(1,'**** start of gummel iteration number: %d\n',i);
fprintf(1,'*****************************************************************\n');
end
if (verbose>=1)
fprintf(1,'solving non linear poisson equation\n');
end
[V(:,2),n(:,2),p(:,2)] =...
DDGOXnlpoisson (imesh,Dsides,Sinodes,SiDnodes,Sielements,...
V(:,1),n(:,1),p(:,1),Fn(:,1),Fp(:,1),D,...
idata.l2,idata.l2ox,ptoll,pmaxit,verbose-1);
V(Dnodes,2) = idata.V(Dnodes);
if (verbose>=1)
fprintf (1,'***\nupdating electron qfl\n');
end
mob = Ufielddepmob(Simesh,idata.un,Fn(:,1),idata.vsatn,idata.mubn);
n(:,3) =DDGOXTelectron_driftdiffusion(Simesh,SiDsides,[n(:,2),nold],[p(:,2),pold],...
V(Sinodes,2),mob,...
idata.tn,idata.tp,idata.ni,idata.ni,weight);
Fn(:,2)=V(Sinodes,2) - log(n(:,3));
n(SiDnodes,3) = idata.n(SiDnodes);
Fn(SiDnodes,2) = idata.Fn(SiDnodes);
%%%% store result for RRE
if RREpattern(i)>0
Fnstore(:,RREpattern(i)) = Fn(:,2);
if RREpattern(i+1)==0 % Apply RRE extrapolation
if (verbose>=1)
fprintf(1,'\n**********\nRRE EXTRAPOLATION STEP\n**********\n');
end
Fn(:,2) = Urrextrapolation(Fnstore);
end
end
if (verbose>=1)
fprintf(1,'***\nupdating hole qfl\n');
end
mob = Ufielddepmob(Simesh,idata.up,Fp(:,1),idata.vsatp,idata.mubp);
p(:,3) =DDGOXThole_driftdiffusion(Simesh,SiDsides,[n(:,3),nold],[p(:,2),pold],...
V(Sinodes,2),mob,...
idata.tn,idata.tp,idata.ni,idata.ni,weight);
Fp(:,2)= V(Sinodes,2) + log(p(:,3));
p(SiDnodes,3) = idata.p(SiDnodes);
Fp(SiDnodes,2) = idata.Fp(SiDnodes);
if (verbose>=1)
fprintf(1,'checking for convergence\n');
end
nrfn= norm(Fn(:,2)-Fn(:,1),inf);
nrfp= norm (Fp(:,2)-Fp(:,1),inf);
nrv = norm (V(:,2)-V(:,1),inf);
nrm(i) = max([nrfn;nrfp;nrv]);
if (verbose>=1)
fprintf (1,' max(|phin_(k+1)-phinn_(k)| ,...\n |phip_(k+1)-phip_(k)| ,...\n |v_(k+1)- v_(k)| )= %g\n',nrm(i));
end
if (nrm(i)0)
fprintf(1,'\n***********\nDD simulation over:\n # of Gummel iterations = %d\n\n',it);
end
odata = idata;
odata.n = n(:,end);
odata.p = p(:,end);
odata.V = V(:,end);
odata.Fn = Fn(:,end);
odata.Fp = Fp(:,end);
secs2d-0.0.8/inst/DDGOXT/DDGOXTelectron_driftdiffusion.m 0000644 0001750 0001750 00000003245 11201030277 020455 0 ustar sh sh function n=DDGOXTelectron_driftdiffusion(mesh,Dsides,nin,pin,V,un,tn,tp,n0,p0,weight)
%%
% n=DDGelectron_driftdiffusion(mesh,Dsides,nin,pin,V,un,tn,tp,n0,p0,weight)
%
% IN:
% V = electric potential
% mesh = integration domain
% nin = electron density in the past + initial guess
% pin = hole density in the past
% n0,p0 = equilibrium densities
% tn,tp = carrier lifetimes
% weight = BDF weights
% un = mobility
%
% OUT:
% n = updated electron density
%
%%
% 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 .
BDForder = length(weight)-1;
denom = (tp*(nin(:,end)+sqrt(n0.*p0))+tn*(pin(:,end)+sqrt(n0.*p0)));
M = weight(1) + pin(:,end)./denom;
u = un;
U = p0.*n0./denom;
for ii=1:BDForder
U += -nin(:,end-ii)*weight(ii+1);
end
guess = nin(:,end);
n = Udriftdiffusion(mesh,Dsides,guess,M,U,V,u);
secs2d-0.0.8/inst/DDGOXT/DDGOXThole_driftdiffusion.m 0000644 0001750 0001750 00000003232 11201030277 017565 0 ustar sh sh function p=DDGOXThole_driftdiffusion(mesh,Dsides,nin,pin,V,up,tn,tp,n0,p0,weight)
%%
% p=DDGhole_driftdiffusion(mesh,Dsides,nin,pin,V,un,tn,tp,n0,p0,weight)
%
% IN:
% V = electric potential
% mesh = integration domain
% nin = electron density in the past
% pin = hole density in the past + initial guess
% n0,p0 = equilibrium densities
% tn,tp = carrier lifetimes
% weight = BDF weights
% up = mobility
%
% OUT:
% p = updated hole density
%
%%
% 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 .
BDForder = length(weight)-1;
denom = (tp*(nin(:,end)+sqrt(n0.*p0))+tn*(pin(:,end)+sqrt(n0.*p0)));
M = weight(1) + nin(:,end)./denom;
u = up;
U = p0.*n0./denom;
for ii=1:BDForder
U += -pin(:,end-ii)*weight(ii+1);
end
guess = pin(:,end);
p = Udriftdiffusion(mesh,Dsides,guess,M,U,-V,u);
secs2d-0.0.8/inst/QDDGOX/ 0000755 0001750 0001750 00000000000 11201031505 012437 5 ustar sh sh secs2d-0.0.8/inst/QDDGOX/QDDGOXgummelmap.m 0000644 0001750 0001750 00000017731 11201030277 015526 0 ustar sh sh function [odata,it,res] = QDDGOXgummelmap (imesh,Dsides,...
Simesh,Sinodes,Sielements,SiDsides,Intsides,...
idata,toll,maxit,ptoll,pmaxit,stoll,smaxit,verbose,options)
% [odata,it,res] = QDDGOXgummelmap (imesh,Dsides,...
% Simesh,Sinodes,Sielements,SiDsides,Intsides,...
% idata,toll,maxit,ptoll,pmaxit,stoll,smaxit,verbose,options);
clear global
global DDGOXNLPOISSON_LAP DDGOXNLPOISSON_MASS DDGOXNLPOISSON_RHS DDG_RHS DDG_MASS
%%%%%%%%%%%%%%%
%% RRE param %%
RREnnit = [1,0];
RRErank = 5;
RREpattern = URREcyclingpattern(RREnnit,RRErank,maxit);
RREnnit2 = [1,0];
RRErank2 = 4;
RREpattern2 = URREcyclingpattern(RREnnit2,RRErank2,smaxit);
%%%%%%%%%%%%%%%
Nnodes = max(size(imesh.p));
Nelements = max(size(imesh.t));
SiNnodes = max(size(Simesh.p));
SiNelements = max(size(Simesh.t));
if (options.SRH==1)
tn= idata.tn;tp=idata.tp;
else
tn=Inf;tp=Inf;
end
V (:,1) = idata.V;
p (:,1) = idata.p;
n (:,1) = idata.n;
Fn(:,1) = idata.Fn;
Fp(:,1) = idata.Fp;
D = idata.D;
Dedges =[];
for ii = 1:length(Dsides)
Dedges=[Dedges,find(imesh.e(5,:)==Dsides(ii))];
end
% Set list of nodes with Dirichelet BCs
Dnodes = imesh.e(1:2,Dedges);
Dnodes = [Dnodes(1,:) Dnodes(2,:)];
Dnodes = unique(Dnodes);
Intedges =[];
for ii = 1:length(Intsides)
Intedges=[Intedges,find(Simesh.e(5,:)==Intsides(ii))];
end
% Set list of Interface nodes
Intnodes = Simesh.e(1:2,Intedges);
Intnodes = [Intnodes(1,:) Intnodes(2,:)];
Intnodes = unique(Intnodes);
SiDedges =[];
for ii = 1:length(SiDsides)
SiDedges=[SiDedges,find(Simesh.e(5,:)==SiDsides(ii))];
end
% Set list of nodes with Dirichelet BCs
SiDnodes = Simesh.e(1:2,SiDedges);
SiDnodes = [SiDnodes(1,:) SiDnodes(2,:)];
SiDnodes = unique(SiDnodes);
if (options.FD==1)
FDn = idata.FDn;
FDp = idata.FDp;
else
FDn = zeros(SiNnodes,1);
FDp = zeros(SiNnodes,1);
end
G (:,1) = Fn(:,1) - V(Sinodes,1) - FDn + log(n(:,1));
if (options.holes==1)
Gp (:,1) = Fp(:,1) - V(Sinodes,1) - FDp - log(p(:,1));
else
Gp (:,1) = G(:,1)*0;
end
nrm=1;
for i=1:1:maxit
if (verbose>=1)
fprintf(1,'*****************************************************************\n');
fprintf(1,'**** start of gummel iteration number: %d\n',i);
fprintf(1,'*****************************************************************\n');
end
V(:,2)= V(:,1);
G(:,2)= G(:,1);
Gp(:,2)= Gp(:,1);
n(:,2)= n(:,1);
bohmdeltav=inf;
for j=1:smaxit
if (verbose>=1)
fprintf(1,'*---------------------------------------------------------------*\n');
fprintf(1,'**** start of Poisson-Bohm iteration number: %d (bohmdeltav=%g)\n',j,bohmdeltav);
fprintf(1,'*---------------------------------------------------------------*\n');
end
if (verbose>1)
fprintf(1,'solving non linear poisson equation\n\n');
end
[V(:,3),n(:,2),p(:,2)] =...
QDDGOXnlpoisson (imesh,Dsides,Sinodes,[SiDnodes,Intnodes] ,Sielements,...
V(:,2),n(:,1),p(:,1),Fn(:,1),Fp(:,1),G(:,2)+FDn,Gp(:,2)+FDp,D,...
idata.l2,idata.l2ox,ptoll,pmaxit,verbose-1);
n([SiDnodes,Intnodes],2) = idata.n([SiDnodes,Intnodes]);
p([SiDnodes,Intnodes],2) = idata.p([SiDnodes,Intnodes]);
V(Dnodes,3) = idata.V(Dnodes);
if (verbose>1)
fprintf(1,'solving non linear Bohm equation for electrons\n\n');
end
n(Intnodes,2) = idata.n(Intnodes);
w = QDDGOXcompdens(Simesh,[SiDsides,Intsides],sqrt(n(:,2)),V(Sinodes,3) + FDn,Fn(:,1),idata.dn2,stoll,smaxit,verbose-1);
n(:,2) = w.^2;
n([SiDnodes,Intnodes],2) = idata.n([SiDnodes,Intnodes]);
G(:,3) = Fn(:,1) - V(Sinodes,3) - FDn + log(n(:,2));
if (verbose>1)
fprintf(1,'solving non linear Bohm equation for holes\n\n');
end
if (options.holes==1)
p(Intnodes,2) = idata.p(Intnodes);
wp = QDDGOXcompdens(Simesh,[SiDsides,Intsides],sqrt(p(:,2)),-V(Sinodes,3) - FDp,...
-Fp(:,1),idata.dp2,ptoll,pmaxit,verbose-1);
p(:,2) = wp.^2;
p([SiDnodes,Intnodes],2) = idata.p([SiDnodes,Intnodes]);
Gp(:,3) = Fp(:,1) - V(Sinodes,3) - FDp - log(p(:,2));
else
Gp(:,3)=G(:,3)*0;
end
if (options.FD==1)
fprintf(1,'\n*** APPLYING FD STATISTICS ***\n')
n(:,2) = idata.Nc*Ufermidirac(V(Sinodes,3)+G(:,3)-Fn(:,1)-log(idata.Nc),1/2);
n(SiDnodes,2) = idata.n(SiDnodes);
nMBtmp = exp(V(Sinodes,3)+G(:,3)-Fn(:,1));
FDn = log(n(:,2)./ nMBtmp);
FDn(SiDnodes) = idata.FDn(SiDnodes);
p(:,2) = idata.Nv*Ufermidirac(-V(Sinodes,3)-Gp(:,3)+Fp(:,1)-log(idata.Nv),1/2);
p([SiDnodes,Intnodes],2) = idata.p([SiDnodes,Intnodes]);
pMBtmp = exp(-V(Sinodes,3)-Gp(:,3)+Fp(:,1));
FDp = -log(p(:,2)./ pMBtmp);
FDp(SiDnodes) = idata.FDp(SiDnodes);
end
bohmdeltav = norm(G(:,3)-G(:,2),inf) +...
norm(Gp(:,3)-Gp(:,2),inf) +...
norm(V(:,3)-V(:,2),inf);
%%%% store result for RRE
if RREpattern2(j)>0
Gstore(:,RREpattern2(j)) = G(:,3);
if RREpattern2(j+1)==0 % Apply RRE extrapolation
G(:,3) = Urrextrapolation(Gstore);
end
end
G(:,2)=G(:,3);
Gp(:,2)=Gp(:,3);
V(:,2)=V(:,3);
if (bohmdeltav<=stoll)
if (verbose>1)
fprintf(1,'Exiting poisson-bohm iteration because bohmdeltav=%g\n\n',bohmdeltav);
end
break;
end
end
if (verbose>1)
fprintf (1,'\n\nupdating electron qfl\n\n');
end
mob = Ufielddepmob(Simesh,idata.un,Fn(:,1), ...
idata.vsatn,idata.mubn);
n(:,3) = DDGOXelectron_driftdiffusion(Simesh,SiDsides,n(:,2),p(:,2),...
V(Sinodes,3)+G(:,3)+FDn,mob,...
tn,tp,idata.n0,idata.p0);
Fn(:,2) = V(Sinodes,3) + G(:,3) + FDn - log(n(:,3));
Fn(SiDnodes,2) = idata.Fn(SiDnodes);
n([SiDnodes,Intnodes],3) = idata.n([SiDnodes,Intnodes]);
%%%% store result for RRE
if RREpattern(i)>0
Fnstore(:,RREpattern(i)) = Fn(:,2);
if RREpattern(i+1)==0 % Apply RRE extrapolation
Fn(:,2) = Urrextrapolation(Fnstore);
end
end
if (verbose>1)
fprintf(1,'updating hole qfl\n\n');
end
mob = Ufielddepmob(Simesh,idata.up,Fp(:,1),idata.vsatp,idata.mubp);
p(:,3) =DDGOXhole_driftdiffusion(Simesh,SiDsides,n(:,3),p(:,2),...
V(Sinodes,3)+Gp(:,3)+FDp,mob,...
tn,tp,idata.n0,idata.p0);
if (options.holes==1)
Fp(:,2)=V(Sinodes,3) + Gp(:,3) + FDp + log(p(:,3));
p([SiDnodes,Intnodes],3) = idata.p([SiDnodes,Intnodes]);
else
Fp(:,2)=Fn(:,2) + 2 * log(idata.ni);
p(:,3) = exp(Fp(:,2)-V(Sinodes,3)-FDp);
p([SiDnodes],3) = idata.p([SiDnodes]);
end
Fp(SiDnodes,2) = idata.Fp(SiDnodes);
if (verbose>1)
fprintf(1,'checking for convergence\n\n');
end
nrfn= norm(Fn(:,2)-Fn(:,1),inf);
nrfp= norm (Fp(:,2)-Fp(:,1),inf);
nrv = norm (V(:,3)-V(:,1),inf);
nrg = norm (G(:,3)-G(:,1),inf);
nrgp = norm (Gp(:,3)-Gp(:,1),inf);
nrm(i) = max([nrfn;nrfp;nrv;nrg;nrgp]);
figure(2)
semilogy(nrm)
pause(.1)
if (verbose>1)
fprintf (1,' max(|phin_(k+1)-phinn_(k)| , |phip_(k+1)-phip_(k)| , |v_(k+1)-v_(k)| |g_(k+1)-g_(k)|)= %d\n',nrm(i));
end
if (nrm(i)0)
fprintf(1,'\n\nDD: # of Gummel iterations = %d\n\n',it);
end
odata = idata;
odata.n = n(:,end);
odata.p = p(:,end);
odata.V = V(:,end);
odata.Fn = Fn(:,end);
odata.Fp = Fp(:,end);
odata.G = G(:,end);
odata.Gp = Gp(:,end);
secs2d-0.0.8/inst/QDDGOX/QDDGOXddcurrent.m 0000644 0001750 0001750 00000001635 11201030277 015530 0 ustar sh sh function [current,divrg]=QDDGOXddcurrent(mesh,Sinodes,data,contacts,options);
% [current,divrg]=QDDGOXddcurrent(mesh,Sinodes,data,contacts);
constants
Nelements = size(mesh.t,2);
mob = Ufielddepmob(mesh,data.un,data.Fn,data.vsatn,data.mubn);
if (~isfield("options","FD")|(options.FD==0))
data.FDn=0;
data.FDp=0;
end
An = Uscharfettergummel(mesh,data.V(Sinodes)+data.G+data.FDn,mob);
if (options.holes==1)
mob = Ufielddepmob(mesh,data.up,data.Fp,data.vsatp,data.mubp);
Ap = Uscharfettergummel(mesh,-data.V(Sinodes)-data.Gp-data.FDp,mob);
divrg = An * data.n + Ap * data.p;
else
divrg = An * data.n;
end
for con = 1:length(contacts)
cedges = [];
cedges=[cedges,find(mesh.e(5,:)==contacts(con))];
cnodes = mesh.e(1:2,cedges);
cnodes = [cnodes(1,:) cnodes(2,:)];
cnodes = unique(cnodes);
current(con) = sum(divrg(cnodes));
end
Is = q*data.us*data.Vs*data.ns;
current = current * Is;
secs2d-0.0.8/inst/QDDGOX/QDDGOXcompdens.m 0000644 0001750 0001750 00000010075 11201030277 015344 0 ustar sh sh function w = QDDGOXcompdens(mesh,Dsides,win,vin,fermiin,d2,toll,maxit,verbose);
% w = QDDGOXcompdens(mesh,Dsides,win,vin,fermiin,d2,toll,maxit,verbose);
global QDDGOXCOMPDENS_LAP QDDGOXCOMPDENS_MASS QDDGOXCOMPDENS_RHS
%% Set some usefull constants
VErank = 4;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% convert input vectors to columns
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if Ucolumns(win)>Urows(win)
win=win';
end
if Ucolumns(vin)>Urows(vin)
vin=vin';
end
if Ucolumns(fermiin)>Urows(fermiin)
fermiin=fermiin';
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% convert grid info to FEM form
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nodes = mesh.p;
Nnodes = size(nodes,2);
elements = mesh.t(1:3,:);
Nelements = size(elements,2);
Dedges =[];
for ii = 1:length(Dsides)
Dedges=[Dedges,find(mesh.e(5,:)==Dsides(ii))];
end
% Set list of nodes with Dirichelet BCs
Dnodes = mesh.e(1:2,Dedges);
Dnodes = [Dnodes(1,:) Dnodes(2,:)];
Dnodes = unique(Dnodes);
Dvals = win(Dnodes);
Varnodes = setdiff([1:Nnodes],Dnodes);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% initialization:
%% we're going to solve
%% $$ -\delta^2 \Lap w_{k+1} + B'(w_k) \delta w_{k+1} = 2 * w_k$$
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% set $$ w_1 = win $$
w = win;
wnew = win;
%% let's compute FEM approximation of $$ L = - \aleph \frac{d^2}{x^2} $$
if (isempty(QDDGOXCOMPDENS_LAP))
QDDGOXCOMPDENS_LAP = Ucomplap (mesh,ones(Nelements,1));
end
L = d2*QDDGOXCOMPDENS_LAP;
%% now compute $$ G_k = F - V + 2 V_{th} log(w) $$
if (isempty(QDDGOXCOMPDENS_MASS))
QDDGOXCOMPDENS_MASS = Ucompmass2 (mesh,ones(Nnodes,1),ones(Nelements,1));
end
G = fermiin - vin + 2*log(w);
Bmat = QDDGOXCOMPDENS_MASS*sparse(diag(G));
nrm = 1;
%%%%%%%%%%%%%%%%%%%%%%%%
%%% NEWTON ITERATION START
%%%%%%%%%%%%%%%%%%%%%%%%
converged = 0;
for jnewt =1:ceil(maxit/VErank)
for k=1:VErank
[w(:,k+1),converged,G,L,Bmat]=onenewtit(w(:,k),G,fermiin,vin,L,Bmat,jnewt,mesh,Dnodes,Varnodes,Dvals,Nnodes,Nelements,toll);
if converged
break
end
end
if converged
break
end
w = Urrextrapolation(w);
end
%%%%%%%%%%%%%%%%%%%%%%%%
%%% NEWTON ITERATION END
%%%%%%%%%%%%%%%%%%%%%%%%
w = w(:,end);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%% ONE NEWTON ITERATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [w,converged,G,L,Bmat]=onenewtit(w,G,fermiin,vin,L,Bmat,jnewt,mesh,Dnodes,Varnodes,Dvals,Nnodes,Nelements,toll);
global QDDGOXCOMPDENS_LAP QDDGOXCOMPDENS_MASS QDDGOXCOMPDENS_RHS
dampit = 5;
dampcoeff = 2;
converged = 0;
wnew = w;
res0 = norm((L + Bmat) * w,inf);
%% chose $ t_k $ to ensure positivity of $w$
mm = -min(G);
pause(1)
if (mm>2)
tk = max( 1/(mm));
else
tk = 1;
end
tmpmat = QDDGOXCOMPDENS_MASS*2;
if (isempty(QDDGOXCOMPDENS_RHS))
QDDGOXCOMPDENS_RHS = Ucompconst (mesh,ones(Nnodes,1),ones(Nelements,1));
end
tmpvect= 2*QDDGOXCOMPDENS_RHS.*w;
%%%%%%%%%%%%%%%%%%%%%%%%
%%% DAMPING ITERATION START
%%%%%%%%%%%%%%%%%%%%%%%%
for idamp = 1:dampit
%% Compute $ B1mat = \frac{2}{t_k} $
%% and the (lumped) mass matrix B1mat(w_k)
B1mat = tmpmat/tk;
%% now we're ready to build LHS matrix and RHS of the linear system for 1st Newton step
A = L + B1mat + Bmat;
b = tmpvect/tk;
%% Apply boundary conditions
A (Dnodes,:) = 0;
b (Dnodes) = 0;
b = b - A (:,Dnodes) * Dvals;
A(Dnodes,:)= [];
A(:,Dnodes)= [];
b(Dnodes) = [];
wnew(Varnodes) = A\b;
%% compute $$ G_{k+1} = F - V + 2 V_{th} log(w) $$
G = fermiin - vin + 2*log(wnew);
Bmat = QDDGOXCOMPDENS_MASS*sparse(diag(G));
res = norm((L + Bmat) * wnew,inf);
if (res