secs1d-0.0.9/ 0000755 0000765 0000024 00000000000 11735164216 011673 5 ustar carlo staff secs1d-0.0.9/bak/ 0000755 0000765 0000024 00000000000 11735164216 012430 5 ustar carlo staff secs1d-0.0.9/bak/DDG/ 0000755 0000765 0000024 00000000000 11735164216 013026 5 ustar carlo staff secs1d-0.0.9/bak/DDG/DDGelectron_driftdiffusion.m 0000644 0000765 0000024 00000004616 11733717716 020453 0 ustar carlo staff ## Copyright (C) 2004-2008 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
## -*- texinfo -*-
##
## @deftypefn {Function File}@
## {@var{n}} = DDGelectron_driftdiffusion(@var{psi},@var{x},@var{ng},@var{p},@var{ni},@var{tn},@var{tp},@var{un})
##
## Solve the continuity equation for electrons
##
## Input:
## @itemize @minus
## @item psi: electric potential
## @item x: integration domain
## @item ng: initial guess and BCs for electron density
## @item p: hole density (for SRH recombination)
## @end itemize
##
## Output:
## @itemize @minus
## @item n: updated electron density
## @end itemize
##
## @end deftypefn
function n = DDGelectron_driftdiffusion(psi,x,ng,p,ni,tn,tp,un)
nodes = x;
Nnodes =length(nodes);
elements = [[1:Nnodes-1]' [2:Nnodes]'];
Nelements=size(elements,1);
Bcnodes = [1;Nnodes];
nl = ng(1);
nr = ng(Nnodes);
h=nodes(elements(:,2))-nodes(elements(:,1));
c=1./h;
Bneg=Ubernoulli(-(psi(2:Nnodes)-psi(1:Nnodes-1)),1);
Bpos=Ubernoulli( (psi(2:Nnodes)-psi(1:Nnodes-1)),1);
d0 = [c(1).*Bneg(1); c(1:end-1).*Bpos(1:end-1)+c(2:end).*Bneg(2:end); c(end)*Bpos(end)];
d1 = [1000;-c.* Bpos];
dm1 = [-c.* Bneg;1000];
A = spdiags([dm1 d0 d1],-1:1,Nnodes,Nnodes);
b = zeros(Nnodes,1);%- A * ng;
## SRH Recombination term
SRHD = tp * (ng + ni) + tn * (p + ni);
SRHL = p ./ SRHD;
SRHR = ni.^2 ./ SRHD;
ASRH = Ucompmass (nodes,Nnodes,elements,Nelements,SRHL,ones(Nelements,1));
bSRH = Ucompconst (nodes,Nnodes,elements,Nelements,SRHR,ones(Nelements,1));
A = A + ASRH;
b = b + bSRH;
## Boundary conditions
b(Bcnodes) = [];
b(1) = - A(2,1) * nl;
b(end) = - A(end-1,end) * nr;
A(Bcnodes,:) = [];
A(:,Bcnodes) = [];
n = [nl; A\b ;nr];
endfunction
secs1d-0.0.9/bak/DDG/DDGgummelmap.m 0000644 0000765 0000024 00000011677 11733717716 015532 0 ustar carlo staff ## Copyright (C) 2004-2008 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
## -*- texinfo -*-
##
## @deftypefn {Function File}@
## {@var{odata},@var{it},@var{res}} = DDGgummelmap(@var{x},@var{idata},@var{toll},@var{maxit},@var{ptoll},@var{pmaxit},@var{verbose})
##
## Solve the scaled stationary bipolar DD equation system using Gummel
## algorithm
##
## Input:
## @itemize @minus
## @item x: spatial grid
## @item idata.D: doping profile
## @item idata.p: initial guess for hole concentration
## @item idata.n: initial guess for electron concentration
## @item idata.V: initial guess for electrostatic potential
## @item idata.Fn: initial guess for electron Fermi potential
## @item idata.Fp: initial guess for hole Fermi potential
## @item idata.l2: scaled electric permittivity (diffusion coefficient in Poisson equation)
## @item idata.un: scaled electron mobility
## @item idata.up: scaled electron mobility
## @item idata.nis: scaled intrinsic carrier density
## @item idata.tn: scaled electron lifetime
## @item idata.tp: scaled hole lifetime
## @item toll: tolerance for Gummel iterarion convergence test
## @item maxit: maximum number of Gummel iterarions
## @item ptoll: tolerance for Newton iterarion convergence test for non linear Poisson
## @item pmaxit: maximum number of Newton iterarions
## @item verbose: verbosity level (0,1,2)
## @end itemize
##
## Output:
## @itemize @minus
## @item odata.n: electron concentration
## @item odata.p: hole concentration
## @item odata.V: electrostatic potential
## @item odata.Fn: electron Fermi potential
## @item odata.Fp: hole Fermi potential
## @item it: number of Gummel iterations performed
## @item res: total potential increment at each step
## @end itemize
##
## @end deftypefn
function [odata,it,res] = DDGgummelmap (x,idata,toll,maxit,ptoll,pmaxit,verbose)
odata = idata;
Nnodes=rows(x);
D = idata.D;
vout(:,1) = idata.V;
hole_density (:,1) = idata.p;
electron_density (:,1)= idata.n;
fermin (:,1)=idata.Fn;
fermip (:,1)=idata.Fp;
for i=1:1:maxit
if (verbose>1)
fprintf(1,"*****************************************************************\n");
fprintf(1,"**** start of gummel iteration number: %d\n",i);
fprintf(1,"*****************************************************************\n");
endif
if (verbose>1)
fprintf(1,"solving non linear poisson equation\n\n");
endif
[vout(:,2),electron_density(:,2),hole_density(:,2)] =\
DDGnlpoisson (x,[1:Nnodes],vout(:,1),electron_density(:,1),hole_density(:,1),fermin(:,1),fermip(:,1),D,idata.l2,ptoll,pmaxit,verbose);
if (verbose>1)
fprintf (1,"\n\nupdating electron qfl\n\n");
endif
electron_density(:,3)=\
DDGelectron_driftdiffusion(vout(:,2), x, electron_density(:,2),hole_density(:,2),idata.nis,idata.tn,idata.tp,idata.un);
fermin(:,2) = DDGn2phin(vout(:,2),electron_density(:,3));
fermin(1,2) = idata.Fn(1);
fermin(end:2) = idata.Fn(end);
if (verbose>1)
fprintf(1,"updating hole qfl\n\n");
endif
hole_density(:,3) = \
DDGhole_driftdiffusion(vout(:,2), x, hole_density(:,2),electron_density(:,2),idata.nis,idata.tn,idata.tp,idata.up);
fermip(:,2) = DDGp2phip(vout(:,2),hole_density(:,3));
fermip(1,2) = idata.Fp(1);
fermip(end,2) = idata.Fp(end);
if (verbose>1)
fprintf(1,"checking for convergence\n\n");
endif
nrfn= norm(fermin(:,2)-fermin(:,1),inf);
nrfp= norm (fermip(:,2)-fermip(:,1),inf);
nrv = norm (vout(:,2)-vout(:,1),inf);
nrm(i) = max([nrfn;nrfp;nrv]);
if (verbose>1)
fprintf (1," max(|phin_(k+1)-phinn_(k)| , |phip_(k+1)-phip_(k)| , |v_(k+1)- v_(k)| )= %d\n",nrm(i));
endif
if (nrm(i)0)
fprintf(1,"\n\nInitial guess computed by DD: # of Gummel iterations = %d\n\n",it);
endif
odata.n = electron_density(:,end);
odata.p = hole_density(:,end);
odata.V = vout(:,end);
odata.Fn = fermin(:,end);
odata.Fp = fermip(:,end);
endfunction secs1d-0.0.9/bak/DDG/DDGhole_driftdiffusion.m 0000644 0000765 0000024 00000004576 11733717716 017574 0 ustar carlo staff ## Copyright (C) 2004-2008 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
## -*- texinfo -*-
##
## @deftypefn {Function File}@
## {@var{p}} = DDGhole_driftdiffusio(@var{psi},@var{x},@var{pg},@var{n},@var{ni},@var{tn},@var{tp},@var{up})
##
## Solve the continuity equation for holes
##
## Input:
## @itemize @minus
## @item psi: electric potential
## @item x: spatial grid
## @item ng: initial guess and BCs for electron density
## @item n: electron density (for SRH recombination)
## @end itemize
##
## Output:
## @itemize @minus
## @item p: updated hole density
## @end itemize
##
## @end deftypefn
function p = DDGhole_driftdiffusion(psi,x,pg,n,ni,tn,tp,up)
nodes = x;
Nnodes =length(nodes);
elements = [[1:Nnodes-1]' [2:Nnodes]'];
Nelements=size(elements,1);
Bcnodes = [1;Nnodes];
pl = pg(1);
pr = pg(Nnodes);
h=nodes(elements(:,2))-nodes(elements(:,1));
c=up./h;
Bneg=Ubernoulli(-(psi(2:Nnodes)-psi(1:Nnodes-1)),1);
Bpos=Ubernoulli( (psi(2:Nnodes)-psi(1:Nnodes-1)),1);
d0 = [c(1).*Bpos(1); c(1:end-1).*Bneg(1:end-1)+c(2:end).*Bpos(2:end); c(end)*Bneg(end)];
d1 = [1000;-c.* Bneg];
dm1 = [-c.* Bpos;1000];
A = spdiags([dm1 d0 d1],-1:1,Nnodes,Nnodes);
b = zeros(Nnodes,1);## - A * pg;
## SRH Recombination term
SRHD = tp * (n + ni) + tn * (pg + ni);
SRHL = n ./ SRHD;
SRHR = ni.^2 ./ SRHD;
ASRH = Ucompmass (nodes,Nnodes,elements,Nelements,SRHL,ones(Nelements,1));
bSRH = Ucompconst (nodes,Nnodes,elements,Nelements,SRHR,ones(Nelements,1));
A = A + ASRH;
b = b + bSRH;
## Boundary conditions
b(Bcnodes) = [];
b(1) = - A(2,1) * pl;
b(end) = - A(end-1,end) * pr;
A(Bcnodes,:) = [];
A(:,Bcnodes) = [];
p = [pl; A\b ;pr];
endfunction
secs1d-0.0.9/bak/DDG/DDGn2phin.m 0000644 0000765 0000024 00000002200 11733717716 014722 0 ustar carlo staff ## Copyright (C) 2004-2008 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
## -*- texinfo -*-
##
## @deftypefn {Function File}@
## {@var{phin}} = DDGn2phin(@var{V},@var{n})
##
## Compute the qfl for electrons using Maxwell-Boltzmann statistics.
##
## @end deftypefn
function phin = DDGn2phin (V,n);
## Load constants
nmin = 0;
n = n .* (n>nmin) + nmin * (n<=nmin);
phin = V - log(n) ;
endfunction
secs1d-0.0.9/bak/DDG/DDGnlpoisson.m 0000644 0000765 0000024 00000014127 11733717716 015563 0 ustar carlo staff ## Copyright (C) 2004-2008 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
## -*- texinfo -*-
##
## @deftypefn {Function File}@
## {@var{V},@var{n},@var{p},@var{res},@var{niter}} = @
## DDGnlpoisson(@var{x},@var{sinodes},@var{Vin},@var{nin},@var{pin},@var{Fnin},@var{Fpin},@var{D},@var{l2},@var{toll},@var{maxit},@var{verbose})
##
## Solve the non linear Poisson equation
##
## - lamda^2 *V'' + (n(V,Fn) - p(V,Fp) -D) = 0
##
## Input:
## @itemize @minus
## @item x: spatial grid
## @item sinodes: index of the nodes of the grid which are in the
## semiconductor subdomain (remaining nodes are assumed to be in the oxide subdomain)
## @item Vin: initial guess for the electrostatic potential
## @item nin: initial guess for electron concentration
## @item pin: initial guess for hole concentration
## @item Fnin: initial guess for electron Fermi potential
## @item Fpin: initial guess for hole Fermi potential
## @item D: doping profile
## @item l2: scaled electric permittivity (diffusion coefficient)
## @item toll: tolerance for convergence test
## @item maxit: maximum number of Newton iterations
## @item verbose: verbosity level (0,1,2)
## @end itemize
##
## Output:
## @itemize @minus
## @item V: electrostatic potential
## @item n: electron concentration
## @item p: hole concentration
## @item res: residual norm at each step
## @item niter: number of Newton iterations
## @end itemize
##
## @end deftypefn
function [V,n,p,res,niter] = DDGnlpoisson (x,sinodes,Vin,nin,pin,Fnin,Fpin,D,l2,toll,maxit,verbose)
## Set some useful constants
dampit = 10;
dampcoeff = 2;
## Convert grid info to FEM form
Ndiricheletnodes = 2;
nodes = x;
sielements = sinodes(1:end-1);
Nnodes = length(nodes);
totdofs = Nnodes - Ndiricheletnodes ;
elements = [[1:Nnodes-1]' , [2:Nnodes]'];
Nelements = size(elements,1);
BCnodes = [1;Nnodes];
## Initialization
V = Vin;
Fn = Fnin;
Fp = Fpin;
n = DDGphin2n(V(sinodes),Fn);
p = DDGphip2p(V(sinodes),Fp);
if (sinodes(1)==1)
n(1)=nin(1);
p(1)=pin(1);
endif
if (sinodes(end)==Nnodes)
n(end)=nin(end);
p(end)=pin(end);
endif
## Compute LHS matrices
L = Ucomplap (nodes,Nnodes,elements,Nelements,l2.*ones(Nelements,1));
## Compute Mv = ( n + p)
Mv = zeros(Nnodes,1);
Mv(sinodes) = (n + p);
Cv = zeros(Nelements,1);
Cv(sielements)= 1;
M = Ucompmass (nodes,Nnodes,elements,Nelements,Mv,Cv);
## Compute RHS vector
Tv0 = zeros(Nnodes,1);
Tv0(sinodes) = (n - p - D);
Cv = zeros(Nelements,1);
Cv(sielements)= 1;
T0 = Ucompconst (nodes,Nnodes,elements,Nelements,Tv0,Cv);
## Build LHS matrix and RHS of the linear system for 1st Newton step
A = L + M;
R = L * V + T0;
## Apply boundary conditions
A(BCnodes,:) = [];
A(:,BCnodes) = [];
R(BCnodes) = [];
normr(1) = norm(R,inf);
relresnorm = 1;
reldVnorm = 1;
normrnew = normr(1);
## Start of the newton cycle
for newtit=1:maxit
if verbose
fprintf(1,"\n newton iteration: %d, reldVnorm = %e",newtit,reldVnorm);
endif
dV =[0;(A)\(-R);0];
## Start of the damping procedure
tk = 1;
for dit = 1:dampit
if verbose
fprintf(1,"\n damping iteration: %d, residual norm = %e",dit,normrnew);
endif
Vnew = V + tk * dV;
n = DDGphin2n(Vnew(sinodes),Fn);
p = DDGphip2p(Vnew(sinodes),Fp);
if (sinodes(1)==1)
n(1)=nin(1);
p(1)=pin(1);
endif
if (sinodes(end)==Nnodes)
n(end)=nin(end);
p(end)=pin(end);
endif
## Compute LHS matrices
Mv = zeros(Nnodes,1);
Mv(sinodes) = (n + p);
Cv = zeros(Nelements,1);
Cv(sielements)= 1;
M = Ucompmass (nodes,Nnodes,elements,Nelements,Mv,Cv);
## Compute RHS vector (-residual)
Tv0 = zeros(Nnodes,1);
Tv0(sinodes) = (n - p - D);
Cv = zeros(Nelements,1);
Cv(sielements)= 1;
T0 = Ucompconst (nodes,Nnodes,elements,Nelements,Tv0,Cv);
## Build LHS matrix and RHS of the linear system for 1st Newton step
Anew = L + M;
Rnew = L * Vnew + T0;
## Apply boundary conditions
Anew(BCnodes,:) = [];
Anew(:,BCnodes) = [];
Rnew(BCnodes) = [];
if ((dit>1)&(norm(Rnew,inf)>=norm(R,inf)))
if verbose
fprintf(1,"\nexiting damping cycle \n");
endif
break
else
A = Anew;
R = Rnew;
endif
## 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
fprintf(1,"\nexiting damping cycle because residual norm = %e \n",normrnew);
endif
break
endif
endfor
V = Vnew;
normr(newtit+1) = normrnew;
dVnorm = norm(tk*dV,inf);
## Check if convergence has been reached
reldVnorm = dVnorm / norm(V,inf);
if (reldVnorm <= toll)
if(verbose)
fprintf(1,"\nexiting newton cycle because reldVnorm= %e \n",reldVnorm);
endif
break
endif
endfor
res = normr;
niter = newtit;
endfunction secs1d-0.0.9/bak/DDG/DDGp2phip.m 0000644 0000765 0000024 00000002164 11733717716 014737 0 ustar carlo staff ## Copyright (C) 2004-2008 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
## -*- texinfo -*-
##
## @deftypefn {Function File}@
## {@var{phip}} = DDGn2phin(@var{V},@var{p})
##
## Compute the qfl for holes using Maxwell-Boltzmann statistics
##
## @end deftypefn
function phip = DDGp2phip (V,p);
## Load constants
pmin = 0;
p = p .* (p>pmin) + pmin * (p<=pmin);
phip = V + log(p) ;
endfunction
secs1d-0.0.9/bak/DDG/DDGphin2n.m 0000644 0000765 0000024 00000002153 11733717716 014731 0 ustar carlo staff ## Copyright (C) 2004-2008 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
## -*- texinfo -*-
##
## @deftypefn {Function File}@
## {@var{n}} = DDGphin2n(@var{V},@var{phin})
##
## Compute the electron density using Maxwell-Boltzmann statistics
##
## @end deftypefn
function n = DDGphin2n (V,phin);
nmin = 0;
n = exp ((V-phin));
n = n .* (n>nmin) + nmin * (n<=nmin);
endfunction
secs1d-0.0.9/bak/DDG/DDGphip2p.m 0000644 0000765 0000024 00000002161 11733717716 014734 0 ustar carlo staff ## Copyright (C) 2004-2008 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
## -*- texinfo -*-
##
## @deftypefn {Function File}@
## {@var{p}} = DDGphip2p(@var{V},@var{phip})
##
## Compute the hole density using Maxwell-Boltzmann statistic
##
## @end deftypefn
function p = DDGphip2p (V,phip);
## Load constants
pmin = 0;
p = exp ((phip-V));
p = p .* (p>pmin) + pmin * (p<=pmin);
endfunction
secs1d-0.0.9/bak/DDG/DDGplotresults.m 0000644 0000765 0000024 00000002444 11733717716 016136 0 ustar carlo staff ## Copyright (C) 2004-2008 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
## -*- texinfo -*-
##
## @deftypefn {Function File}@
## DDGplotresults(@var{x},@var{n},@var{p},@var{V},@var{Fn},@var{Fp})
##
## Plot densities and potentials
##
## @end deftypefn
function DDGplotresults(x,n,p,V,Fn,Fp);
subplot(2,3,1)
title('Electron Density')
semilogy(x,n)
subplot(2,3,2)
title('Hole Density')
semilogy(x,p)
subplot(2,3,4)
title('Electron QFL')
plot(x,Fn)
subplot(2,3,5)
title('Hole QFL')
plot(x,Fp)
subplot(2,3,6)
title('Electric Potential')
plot(x,V)
pause(.1)
endfunction
secs1d-0.0.9/bak/DDN/ 0000755 0000765 0000024 00000000000 11735164216 013035 5 ustar carlo staff secs1d-0.0.9/bak/DDN/DDNnewtonmap.m 0000644 0000765 0000024 00000014251 11733717716 015563 0 ustar carlo staff ## Copyright (C) 2004-2008 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
## -*- texinfo -*-
##
## @deftypefn {Function File}@
## {@var{odata},@var{it},@var{res}} = DDNnewtonmap(@var{x},@var{idata},@var{toll},@var{maxit},@var{verbose})
##
## Solve the scaled stationary bipolar DD equation system using a
## coupled Newton algorithm
##
## Input:
## @itemize @minus
## @item x: spatial grid
## @item idata.D: doping profile
## @item idata.p: initial guess for hole concentration
## @item idata.n: initial guess for electron concentration
## @item idata.V: initial guess for electrostatic potential
## @item idata.Fn: initial guess for electron Fermi potential
## @item idata.Fp: initial guess for hole Fermi potential
## @item idata.l2: scaled electric permittivity (diffusion coefficient in Poisson equation)
## @item idata.un: scaled electron mobility
## @item idata.up: scaled electron mobility
## @item idata.nis: scaled intrinsic carrier density
## @item idata.tn: scaled electron lifetime
## @item idata.tp: scaled hole lifetime
## @item toll: tolerance for Newton iterarion convergence test
## @item maxit: maximum number of Newton iterarions
## @item verbose: verbosity level: 0,1,2
## @end itemize
##
## Output:
## @itemize @minus
## @item odata.n: electron concentration
## @item odata.p: hole concentration
## @item odata.V: electrostatic potential
## @item odata.Fn: electron Fermi potential
## @item odata.Fp: hole Fermi potential
## @item it: number of Newton iterations performed
## @item res: residual at each step
## @end itemize
##
## @end deftypefn
function [odata,it,res] = DDNnewtonmap (x,idata,toll,maxit,verbose)
odata = idata;
Nnodes = rows(x);
Nelements=Nnodes-1;
elements=[1:Nnodes-1;2:Nnodes]';
BCnodesp = [1,Nnodes];
BCnodes = [BCnodesp,BCnodesp+Nnodes,BCnodesp+2*Nnodes];
totaldofs= Nnodes-2;
dampcoef = 2;
maxdamp = 2;
V = idata.V;
n = idata.n;
p = idata.p;
D = idata.D;
## Create the complete unknown vector
u = [V; n; p];
## Build fem matrices
L = Ucomplap (x,Nnodes,elements,Nelements,idata.l2*ones(Nelements,1));
M = Ucompmass (x,Nnodes,elements,Nelements,ones(Nnodes,1),ones(Nelements,1));
DDn = Uscharfettergummel(x,Nnodes,elements,Nelements,idata.un,1,V);
DDp = Uscharfettergummel(x,Nnodes,elements,Nelements,idata.up,1,-V);
## Initialise RHS
r1 = L * V + M * (n - p - D);
r2 = DDn * n;
r3 = DDp * p;
RHS = - [ r1; r2; r3 ];
## Apply BCs
RHS(BCnodes,:)= [];
nrm = norm(RHS,inf);
res(1) = nrm;
## Begin Newton Cycle
for count = 1: maxit
if verbose
fprintf (1,"\n\n\nNewton Iteration Number:%d\n",count);
endif
Ln = Ucomplap (x,Nnodes,elements,Nelements,Umediaarmonica(idata.un*n));
Lp = Ucomplap (x,Nnodes,elements,Nelements,Umediaarmonica(idata.up*p));
Z = sparse(zeros(Nnodes));
DDn = Uscharfettergummel(x,Nnodes,elements,Nelements,idata.un,1,V);
DDp = Uscharfettergummel(x,Nnodes,elements,Nelements,idata.up,1,-V);
A = L;
B = M;
C = -M;
DDD = -Ln;
E = DDn;
F = Z;
G = Lp;
H = Z;
I = DDp;
## Build LHS
LHS =sparse([
[A B C];
[DDD E F];
[G H I];
]);
## Apply BCs
LHS(BCnodes,:)=[];
LHS(:,BCnodes)=[];
## Solve the linearised system
dutmp = (LHS) \ (RHS);
dv = dutmp(1:totaldofs);
dn = dutmp(totaldofs+1:2*totaldofs);
dp = dutmp(2*totaldofs+1:3*totaldofs);
du = [0;dv;0;0;dn;0;0;dp;0];
## Check Convergence
nrm_u = norm(u,inf);
nrm_du = norm(du,inf);
ratio = nrm_du/nrm_u;
if verbose
fprintf (1,"ratio = %e\n", ratio);
endif
if (ratio <= toll)
V = u(1:Nnodes);
n = u(Nnodes+1:2*Nnodes);
p = u(2*Nnodes+1:end);
res(count) = nrm;
break;
endif
## Begin damping cycle
tj = 1;
for cc = 1:maxdamp
if verbose
fprintf (1,"\ndamping iteration number:%d\n",cc);
fprintf (1,"reference residual norm:%e\n",nrm);
endif
## Update the unknown vector
utmp = u + tj*du;
Vnew = utmp(1:Nnodes);
nnew = utmp(Nnodes+1:2*Nnodes);
pnew = utmp(2*Nnodes+1:end);
## Try a new RHS
DDn = Uscharfettergummel(x,Nnodes,elements,Nelements,idata.un,1,Vnew);
DDp = Uscharfettergummel(x,Nnodes,elements,Nelements,idata.up,1,-Vnew);
r1 = L * V + M * (nnew - pnew - D);
r2 = DDn * nnew;
r3 = DDp * pnew;
RHS =- [r1;r2;r3];
## Apply BCs
RHS(BCnodes,:) = [];
nrmtmp=norm(RHS,inf);
## Update the damping coefficient
if verbose
fprintf(1,"residual norm:%e\n\n", nrmtmp);
endif
if (nrmtmp>nrm)
tj = tj/(dampcoef*cc);
if verbose
fprintf (1,"\ndamping coefficients = %e",tj);
endif
else
break;
endif
endfor
nrm_du = norm(tj*du,inf);
u = utmp;
if (count>1)
ratio = nrm_du/nrm_du_old;
if (ratio<.005)
V = u(1:Nnodes);
n = u(Nnodes+1:2*Nnodes);
p = u(2*Nnodes+1:end);
res(count) = nrm;
break;
endif
endif
nrm = nrmtmp;
res(count) = nrm;
## Convert result vector into distinct output vectors
V = u(1:Nnodes);
n = u(Nnodes+1:2*Nnodes);
p = u(2*Nnodes+1:end);
nrm_du_old = nrm_du;
endfor
odata.V = V;
odata.n = n;
odata.p = p;
Fn = V - log(n);
Fp = V + log(p);
it = count;
endfunction
secs1d-0.0.9/bak/PKG_ADD 0000644 0000765 0000024 00000001101 11733717716 013444 0 ustar carlo staff dirlist = {"Utilities","DDG","DDN"};
dir = fileparts (mfilename ("fullpath"));
if (! exist (fullfile (dir, "inst"), "dir"))
## Run this if the package is installed
for ii=1:length(dirlist)
addpath ( [ canonicalize_file_name([dir "/.."]) "/" dirlist{ii}])
endfor
else
## Run this if we are testing the package without installation
for ii=1:length(dirlist)
addpath ([ canonicalize_file_name(dir) "/inst/" dirlist{ii}])
endfor
endif
warning ("off", "Octave:fopen-file-in-path");
warning ("off", "Octave:load-file-in-path");
clear dirlist dir
secs1d-0.0.9/bak/secs1d_demo_pndiode.m 0000644 0000765 0000024 00000006022 11733717716 016505 0 ustar carlo staff ## Copyright (C) 2009 Carlo de Falco
##
## SECS1D - A 1-D Drift--Diffusion Semiconductor Device Simulator
##
## SECS1D 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.
##
## SECS1D 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 SECS1D; If not, see .
##
## author: Carlo de Falco
function secs1d_demo_pndiode ()
constants
len = 1e-6;
Nnodes = 1000;
vmin = -2;
vmax = 2;
vstep=.4;
istep = 1;
va = vmin
x = linspace(0,len,Nnodes)';
xm = mean(x);
Nd=1e25;
Na=1e25;
D = Nd * (x>xm) - Na * (x<=xm);
nn = (Nd + sqrt(Nd^2+4*ni^2))/2;
pp = (Na + sqrt(Na^2+4*ni^2))/2;
xn = xm+1e-7;
xp = xm-1e-7;
%% Scaling coefficients
xs = len;
ns = norm(D,inf);
idata.D = D/ns;
Vs = Vth;
us = un;
Js = xs / (us * Vs * q * ns);
while va <= vmax
vvect(istep) = va;
n(:,istep) = nn * (x>=xn) + (ni^2)/pp * (xxp) + pp * (x<=xp);
Fn = va*(x<=xm);
Fp = Fn;
V(:,istep) = (Fn - Vth * log(p(:,istep)/ni));
%% Scaling
xin = x/xs;
idata.n = n(:,istep)/ns;
idata.p = p(:,istep)/ns;
idata.V = V(:,istep)/Vs;
idata.Fn = (Fn - Vs * log(ni/ns))/Vs;
idata.Fp = (Fp + Vs * log(ni/ns))/Vs;
lambda2(istep) = idata.l2 = (Vs*esi)/(q*ns*xs^2);
idata.nis = ni/ns;
idata.un = un/us;
idata.up = up/us;
%% Solution of DD system
%% Algorithm parameters
toll = 1e-3;
maxit = 20;
ptoll = 1e-10;
pmaxit = 100;
verbose = 0;
sinodes = [1:length(x)];
idata.tn = inf;
idata.tp = inf;
[odata,it,res] = DDGgummelmap (xin,idata,toll,maxit,ptoll,pmaxit,verbose);
[odata,it,res] = DDNnewtonmap (xin,odata,toll, maxit,verbose);
n(:,istep) = odata.n;
p(:,istep) = odata.p;
V(:,istep) = odata.V;
DV(istep) = odata.V(end) - odata.V(1);
Emax(istep) = max(abs(diff(odata.V)./diff(xin)))
Bp = Ubernoulli(diff (V(:, istep)),1);
Bm = Ubernoulli(diff (V(:, istep)),0);
Jn(:,istep) = -odata.un * (n(2:end, istep).*Bp-n(1:end-1, istep).*Bm)./diff (xin);
Jp(:,istep) = odata.up * (p(2:end, istep).*Bm-p(1:end-1, istep).*Bp)./diff (xin);
va = va+vstep
istep = istep+1;
endwhile
%% Descaling
n = n*ns;
p = p*ns;
V = V*Vs;
J = abs (Jp+Jn)*Js;
close all
figure();
plot(x, n.')
xlabel("x")
ylabel("n")
figure();
plot(vvect, J)
xlabel("V")
ylabel("J")
figure();
plot(vvect, Emax)
xlabel("V")
ylabel("max(abs(\\phi^\'))")
endfunction secs1d-0.0.9/bak/src/ 0000755 0000765 0000024 00000000000 11735164216 013217 5 ustar carlo staff secs1d-0.0.9/bak/src/Makefile 0000644 0000765 0000024 00000000234 11733717716 014665 0 ustar carlo staff PROGS = $(patsubst %.cc,%.oct,$(wildcard *.cc))
all: $(PROGS)
$(PROGS): Makefile
%.oct: %.cc
mkoctfile $<
clean: ; -$(RM) *.o core octave-core *.oct *~ secs1d-0.0.9/bak/src/Ubern.cc 0000644 0000765 0000024 00000005166 11733717716 014620 0 ustar carlo staff /*
% 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 .
*/
#include
#include
////////////////////////////////////////////
// Ubern function
// this function, though it does make use
// of liboctave, is not an octve command
// the wrapper to make the command is defined
// below
////////////////////////////////////////////
int Ubern(const double x, double &bp, double &bn )
{
double xlim=1e-2;
int ii;
double fp,fn,df,segno;
double ax;
ax=fabs(x);
if (ax == 0.0) {
bp=1.;
bn=1.;
goto theend ;
}
if (ax > 80.0){
if (x >0.0){
bp=0.0;
bn=x;
goto theend ;
}else{
bp=-x;
bn=0.0;
goto theend ;
}
}
if (ax > xlim){
bp=x/(exp(x)-1.0);
bn=x+bp;
goto theend ;
}
ii=1;
fp=1.0;fn=1.0;df=1.0;segno=1.0;
while (fabs(df) > 2.2204e-16){
ii++;
segno= -segno;
df=df*x/ii;
fp=fp+df;
fn=fn+segno*df;
bp=1/fp;
bn=1/fn;
}
theend:
return 0;
}
////////////////////////////////////
// WRAPPER
////////////////////////////////////
// DEFUN_DLD and the macros that it
// depends on are defined in the
// files defun-dld.h, defun.h,
// and defun-int.h.
//
// Note that the third parameter
// (nargout) is not used, so it is
// omitted from the list of arguments
// to DEFUN_DLD in order to avoid
// the warning from gcc about an
// unused function parameter.
////////////////////////////////////
DEFUN_DLD (Ubern, args, ,
" [bp,bn]=Ubern(x)\n \
computes Bernoulli function\n \
B(x)=x/(exp(x)-1) corresponding to \n \
to input values Z and -Z, recalling that\n \
B(-Z)=Z+B(Z)\n")
{
// The list of values to return. See the declaration in oct-obj.h
octave_value_list retval;
NDArray X ( args(0).array_value() );
octave_idx_type lx = X.length();
NDArray BP(X),BN(X);
for (octave_idx_type jj=0; jj