*********************************************
   Enjoy C-Programming

********************************************

hagiwara-yoshiaki@aiplab.com ( http://www.aiplab.com/ )

hagiwara@ssis.or.jp ( http://www.ssis.or.jp/en/index.html )

***********************************************



*********************************************
Computer Simulation of P+PNPP+ junction Solar Cell
        updated on April 25, 2020

*********************************************




***************************************************
Case Study (1) of Uniform Doping Profile of P+PN junction
***************************************************

(i) C-source program code list ..... C_2020_04_20.txt

(ii) Change txt file name to c code name
a.c and

(iii) Compile c source file
a.c by your c compiler and create a.exe file.

(iv) Then excute a.exe to obtain the output file
AA.txt . .

Output File Example........AA_2020_04_20.txt

(v) This program also creates four output graph plots in html format.

They are A1.html, A2.html, A3.html and A4.html.

(vi) From these information created, the following output image

was constructed for the P+PN junction photodiode analysis..




The value of the empty potential
Vm was computed as 0.8803 volt

for the uniform impurity doping levels of Ns, Na and Nd as defined

above and with the total width of
6 μm width for the Buried

Charge Collecting N region for the Pinned Photodiode structure.

***************************************************
Case Study (2) of Uniform Doping Profile of P+PN junction
***************************************************

(i) C-source program code list ..... C_2020_04_25.txt

(ii) Change txt file name to c code name a.c and

(iii) Compile c source file a.c by your c compiler and create a.exe file.

(iv) Then excute a.exe to obtain the output file AA.txt . .

Output File Example........AA_2020_04_25.txt

(v) This program also creates four output graph plots in html format.

They are A1.html, A2.html, A3.html and A4.html.

(vi) From these information created, the following output image

was constructed for the P+PN junction photodiode analysis..












Note that the acutual barrier potential profile was found to be smoothly varying
in the range (XP +XPP) of about more than 0.2 μm width which is more than
three times wider than the value expected by the Debye Lengh Estimation.

For a gradually varing doping profile D(X), we may approximate
the barrier potential drop for 0 < X < X5 as

   V(X) = V(0) + kT ln ( D(0) /D(X))



************************
C-source program code list ..... C_2020_04_25.txt
************************


/***********************************************

  P+PNPP+ double junction type Photodiode

for Solar Cell Application

************************************************

coded on April 25 2020

by Yoshiaki Hagiwara

*************************************************


************************************************





***********************************************************

Main Program の名称は void main( void ) です。

**********************************************************

 NP 個の graph を描いて a.html に出力します。

**********************************************************

 関数 PXPY( ) で Graphの各点の座標値を決定します。     

       for k=1 to NP and for i = 0 to N,

  各点の座標値は XP[k][i]、YP[k][i]  に入ります。

**********************************************************

  電位 V[j] for j = 0 to N の値を数値計算します。

    変数 X の 区間 は [ 0, Xm ] です。
   
  関数 dope ( ) 関数は  不純物濃度 D を 計算します。 

***********************************************************/

#include <stdio.h>
#include <math.h>

/***************************************************

     出力 File の 定義

  fpAA に 計算結果 data が aa.txt に出力されます。

   他のFile はグラフ描画の為の補助 file です。
 
  この program を実行する為には必要なものです。

 そのまま変更しないで一緒に加えて実行してください。

****************************************************/

FILE *fpAA;

FILE *fpC;


/**************************************************************/


/**************************************

Graph を NP 個 描きます。

**************************************/

int NP=1;

/**************************************

各Graphの点の数は N個です。 

**************************************/

int N = 10000,N2 =5000,NN=100 ;

double XP[10][10001],YP[10][10001],V[10001],VV[10002];

double DX,DXX,XX,YY;



/**************************************************

Graphの描画範囲(わく)の値を決定します 

すなわち Graphの描画範囲を決定します。

***************************************************/

double xx,yy ;

double xmin=0,xmax=20,ymin=0,ymax=10;

double xxmin[10],xxmax[10],yymax[10],yymin[10];

int nxx,nx1=100,nx2=600,nyy,ny1=50,ny2=1050 ;

int i,j,k,m;




/****************************************************/



/*******************************************

     関数 PXPY( ) を定義して

   Graphの各点の座標値を決定します。     

    for i_plot =1 to nfn and for i = 0 to N,    

 各点の座標 XP[k][i]、YP[k][i] を決定します。  

Graph を描いて A(k).html に出力します。

i_plot = 1 の時は A1.html に
      i_plot = 2 の時は A2.html に  
      ..............................................

i_plot = 9 の時は A9.html に出力されます。

***************************************************/




/********************************************

反復計算の回数 hhhhhh の値を決めます

*********************************************/

int hhhhhh=10000;

/*********************************************/




/************************************************************/


/************************************************

Case 001

************************************************/

double Ns=20000,Na=10000,Nd=100;

/************************************************/


/************** Uniform Doping Case ************/

double Rs = 0 , Ra = 0, XX1=3, XX5=7 ;

double X1,X5;

/*********************************************/


double NDD,QD,QDD,NAA,QA,QAA;

double Xm=10;

double X1,D1,V1;

double X2,D2,V2;

double X3,D3,V3;

double X4,D4,V4;

double X5,D5,V5;

double kT = 0.0259, Esi = 648;

double VMM,VB;

double X, D, Hole;

double XX2,XX3,XX4,XX6,XX7,XX8,XX9,XX10,XX11,XX12;

double WW1,WW2,WW3,WW4,WW5;

double Doo;

double W,A;

double ErrMax,X_ErrMax,Err,Drr;

int i_ErrMax ;

/***************************************************/




/************ GetXPYP ( ) の 初期変数設定です ****************/



/*********************************************************

いろいろな値で掲載した事例の結果を記録しています。

***********************************************************

(1) Ns=10000000,Xs = 0.57,Na=3000,Xa=5,Nd=100,Xm=10,SCP=20;

VB = 0.195 V, Vm = 0.310 V, Xj = 9.20 , Vo = 0.298 V, ;

(2) Ns=10000000,Xs = 0.57,Na=3000,Xa=4,Nd=100,Xm=10,SCP=20;

VB = 0.195 V , Vm = 0.801 V, Xj = 7.35 , Vo = 0.451 V, ;

(3) Ns=10000000,Xs = 0.57,Na=100000,Xa=3,Nd=100,Xm=10,SCP=20;

VB = 0.111 V , Vm = 0.624 V, Xj = 7.85 , Vo = 0.356 V, ;

(4) Ns=10000000,Xs = 0.57,Na=500000,Xa=2.5,Nd=100,Xm=10,SCP=20;

VB = 0.072 V , Vm = 0.878 V, Xj = 7.25 , Vo = 0.383 V, ;

***************************************************************/








/***********************************************

  P+PNPP+ double junction type Photodiode

for Solar Cell Application


( Line 246~ )

************************************************/










/***********************************************************

Main Program の名称は void main( void ) です。

 NP 個の graph を描いて a.html に出力します。

関数 PXPY( ) を定義し、Graphの各点の座標値を決定します。     

       for k=1 to NP and for i = 0 to N,

  各点の座標値は XP[k][i]、YP[k][i]  に入ります。  

***********************************************************/









/***********************************************

  P+PNPP+ double junction type Photodiode

for Solar Cell Application


( Line 855~ )

************************************************/



/*******************************************

     関数 PXPY( ) を定義して

   Graphの各点の座標値を決定します。     

    for k =1 to NP and for i = 0 to N,    

 各点の座標 XP[k][i]、YP[k][i] を決定します。  

Graph を描いて A(k).html に出力します。

k = 1 の時は A1.html に
      k = 2 の時は A2.html に  
      ..............................................

k = 9 の時は A9.html に出力されます。


***************************************************/










/**********************************************************

ここからは PXPY ( ) の Program の Coding です。

**********************************************************/



/****************************************************

   ここで、不純物濃度 D(X) の値を決めます。


 Xss < 0.01 (μm) は、表面均一イオン打ち込みの深さです。 

   表面にさらにHole Accumultaion 領域を形成できます。

       表面電界が生じないようにするには

      さらに 表面が絶対空乏化しない濃度の
     
        P++の 薄い 均一な 層を

         形成する事も可能です。

       ここでは Xss = 0 としていますが、

          いろいろ変更可能です。

    また、これは double ion 打ち込みの場合ですが、

        single ion 打ち込みの場合も可能です。

    また、 N type 基板でなく、P type 基板にして、

       埋め込み N 層を deep ion 打ち込みで

    Ndd exp ( - ( X - Xdd)/Xd ) とする事も可能です。

         自由に変更してください。

*****************************************

また、均一不純物濃度の場合もあります。

この場合は空乏層近位の2次式で

かなり精度良く近似できます。

*****************************************


*****************************************************/



/*****************************************************


     Case (1) 均一不純物濃度の場合です。

     この場合は空乏層近位の2次式で

  かなり精度良く近似できます。


*****************************************************/




/*************************************************

void Dope(void)の定義

*************************************************/




/**************************************************

Case (1)

**************************************************/

void Dope(void) {

if ( X < XX1) { D = Ns ; return ; }

if ( X < XX5 ) { D = Na ; return ; }

D = - Nd ; }

/**************************************************/










/***********************************************************/



void Find_X5(void) { double dx = 0.000001;

X = 0;

NEXTX:

Dope( ); if( D < 0 ) goto FINISH;

X=X+dx; goto NEXTX;

FINISH: X5 = X ; D5 = D;

printf("\n\n Find_X5( ) : X5 = % f D(X5) = %f", X5,D5 );

X=X5-dx; Dope( );

printf("\n\n Find_X5( ) : X5 - dx = % f D(X5-dx) = %f", X5 - dx , D); }




/**********************************************************/











/*****************************************************

   空乏層近似と 表面近傍ではバリア電界近似で

    反復計算の初期値 WW( ) 関数を使って求めます

******************************************************/

/**********************************************************/

void WW(void) {


/**************************************

VB = kT*log(Ns/Na) ;

***************************************/


if ( X< XX1 ) { W = 0 ; return ; }

if ( X< XX4 ) { W = VB; return ; }

/**************************************************

( XX1<=X < XX4 ) では、V(XX4) = VB を起点として、

      空乏層近似で求めます

**************************************************/

if ( X < XX5 ) { W = VB + (X-XX4)*(X-XX4)*Na/2/Esi ; return ; }

/**************************************************

( XX1 <= X<= Xm ) では、 (Xm -X) に注目し、

V(Xm) = VMM を起点として、空乏層近似で求めます


V5 = VB + (XX5-XX4)*(XX5-XX4)*Na/2/Esi ;

VMM = V5 + (Xm-XX5)*(Xm-XX5)*Nd/2/Esi ;

**************************************************/

W = VMM - ( Xm - X )*( Xm - X )*Nd/2/Esi ; }

/**************************************************/












/***************************************************/


void ErrorV(void) { int i;


ErrMax=0; V[N+1]=V[N-1];

for (i=1;i<N+1;i++) { i=i*DX; Dope( );


Err = V[i+1]+V[i-1]-2*V[i] - ( D - Doo*exp( - V[i]/kT) )*DX*DX/Esi ;

if(Err<0) Err= -Err ;

if(ErrMax<Err) { i_ErrMax = i ; X_ErrMax = i*DX; ErrMax = Err ; } }

printf ( "\n\n i_ErrMax = %d , X_ErrMax = %f ErrMax = %f ",

i_ErrMax, X_ErrMax, ErrMax) ; }


/**********************************************************/



















/***********************************************

  P+PNPP+ double junction type Photodiode

for Solar Cell Application


( Line 574~ )


************************************************/












/**********************************************************

Function void PXPY ( void ) を定義します。

***********************************************************/



void PXPY ( void ) {


char c; int i , j , k , h ;


fpAA=fopen("AA.txt","w");


/********** AA.txt に各物理定数を記録します****************/





fprintf(fpAA,"\n\n (001) kT = %f ", kT );

fprintf(fpAA,"\n\n (002) Esi = %f ", Esi );

fprintf(fpAA,"\n\n (003) Nd= %f ", Nd );

fprintf(fpAA,"\n\n Debye Length = sqrt ( Esi*kT/Nd) =%f", sqrt ( Esi*kT/Nd) );

fprintf(fpAA,"\n\n (004) Ns= %f ", Ns );

fprintf(fpAA,"\n\n Debye Length = sqrt ( Esi*kT/Ns) = %f", sqrt ( Esi*kT/Ns) );

fprintf(fpAA,"\n\n (005) Rs= %f ", Rs );

fprintf(fpAA,"\n\n (006) Na= %f ", Na );

fprintf(fpAA,"\n\n Debye Length = sqrt ( Esi*kT/Na) = %f ", sqrt ( Esi*kT/Na) );

fprintf(fpAA,"\n\n (007) Ra= %f ", Ra );



printf("\n\n (001) kT = %f ", kT );

printf("\n\n (002) Esi = %f ", Esi );


printf("\n\n (003) Nd= %f ", Nd );

printf("\n\n Debye Length = sqrt ( Esi*kT/Nd) = %f", sqrt ( Esi*kT/Nd) );


printf("\n\n (004) Ns= %f ", Ns );

printf("\n\n Debye Length = sqrt ( Esi*kT/Ns) = %f", sqrt ( Esi*kT/Ns) );

printf("\n\n (005) Rs= %f ", Rs );

printf("\n\n (006) Na= %f ", Na );

printf("\n\n Debye Length = sqrt ( Esi*kT/Na) = %f ", sqrt ( Esi*kT/Na) );

printf("\n\n (007) Ra= %f ", Ra );







/****** 濃度差によるバリア電位を概算します************/


VB = kT*log(Ns/Na);

fprintf(fpAA,"\n\n (008) 濃度差によるバリア電位 VB= %f ", VB );

printf( "\n\n (008) 濃度差によるバリア電位 VB= %f ", VB );






/****** 数値計算のXの範囲 [ 0, Xm ] を決めます ******/

fprintf(fpAA,"\n\n (009) 数値計算のXの範囲 Xm= %f ", Xm );

printf("\n\n (009) 数値計算のXの範囲 Xm= %f ", Xm );

XX6=Xm, XX12=2*Xm;


fprintf(fpAA,"\n\n (010) XX6=Xm= %f ", XX6 );

fprintf(fpAA,"\n\n (011) 実際の P+PNPP+接合の幅 XX12= 2* Xm = %f ", XX12 );

printf("\n\n (010) XX6=Xm= %f ", XX6 );

printf("\n\n (011) 実際の P+PNPP+接合の幅 XX12= 2* Xm = %f ", XX12 );




/********************************************************

●数値計算用のXの差分の数 N1 の値を決めます。

       DX = Xm/N1 を計算します。

    ●偶数奇数反復の為に 2分割します。

          N2 = N1/2;
 
    ● AA.txt に出力する間引き数 

          N = 100;        

********************************************************/


fprintf(fpAA,"\n\n (012) N= %d \n\n", N );

printf("\n\n (012) N= %d \n\n", N );


DX = Xm/N;

fprintf(fpAA,"\n\n (013) DX = Xm/N1 = %f ", DX );

printf("\n\n (013) DX = Xm/N = %f ", DX );




fprintf(fpAA,"\n\n (014) N2 = N/2= %d \n\n", N2 );

printf("\n\n (014) N2 = N/2= %d \n\n", N2 );



fprintf(fpAA,"\n\n (015) NN= %d \n\n", NN );

printf("\n\n (015) NN= %d \n\n", NN );

/********************************************************/








/********************************************************

      不純物濃度 profile D(X) を計算します。

*********************************************************/

fprintf (fpAA, "\n\n 不純物濃度 profile D(X) と 初期値 V(X)を計算します。\n\n");

printf ( "\n\n 不純物濃度 profile D(X) と 初期値 V(X)を計算します。\n\n");


VB= kT*log(Ns/Na) ;

XX4 = XX5 - ( Xm - XX5)*Nd/Na ;

V5 = VB + Na*( XX5 - XX4 )*( XX5- XX4 )/2/Esi;

VMM = V5 + Nd*(Xm -XX5)*(Xm-XX5)/2/Esi ;

printf( "\n\n VB= kT*log(Ns/Na) = %f",VB);

fprintf(fpAA,"\n\n VB= kT*log(Ns/Na) = %f",VB);

printf( "\n\n XX4 = XX5 - ( Xm - XX5)*Nd/Na = %f",XX4);

fprintf(fpAA,"\n\n XX4 = XX5 - ( Xm - XX5)*Nd/Na = %f",XX4);

printf( "\n\n V5 = VB + Na*( XX5 - XX4 )*( XX5- XX4 )/2/Esi = %f",V5);

fprintf(fpAA,"\n\n V5 = VB + Na*( XX5 - XX4 )*( XX5- XX4 )/2/Esi = %f",V5);

printf( "\n\n VMM = V5 + Nd*(Xm -XX5)*(Xm-XX5)/2/Esi = %f \n\n",VMM);

fprintf(fpAA,"\n\n VMM = V5 + Nd*(Xm -XX5)*(Xm-XX5)/2/Esi = %f \n\n",VMM);


/*********************************************************

初期の 電圧 V(X)を求めます・

**********************************************************/

for ( i=0; i<N+1; i++) {


X = i*DX;

Dope( );

WW( );

j = i - (i/NN)*NN;

if(j == 0 ) { fprintf (fpAA, "\n i = %d , X = %f D =%f V =%f", i,X,D,W);

printf ( "\n i = %d , X = %f D =%f ,V=%f ", i,X,D,W); } }


/*********************************************************/










/********************************************************

    PN 接合の接合位置 X5 の値を求めます。

     We have D(X) = Ns > 0 at X = 0 ,

and D(X) = - Ndd < 0 at X = Xm.

D(X) = 0  となる X=X5 の値を求めます。

0 < X5 < Xm

*********************************************************/

Find_X5( );

X=X5; Dope( );

fprintf(fpAA,"\n\n (016) X5 = %f D(X5) = %f ", X, D );

printf( "\n\n (016) X5 = %f D(X5) = %f ", X, D );

X=X5-DX; Dope( );

fprintf(fpAA,"\n\n (017) X5 - DX = %f D(X5-DX) = %f ", X, D );

printf( "\n\n (017) X5 - DX = %f D(X5-DX) = %f ", X, D );


/*********************************************************/

XX7=2*Xm -XX5;

fprintf(fpAA,"\n\n (018) The PN junction edge XX5 = %f ", XX5 );

fprintf(fpAA,"\n\n (019) The PN junction edge XX7 = 2*Xm - XX5 = %f ", XX7 );

printf("\n\n (018) The PN junction edge XX5 = %f ", XX5 );

printf("\n\n (019) The PN junction edge XX7 = 2*Xm - XX5 = %f ", XX7 );

/*******************************************************

P+PNPP+接合 幅 XX12 = 2*Xm の中で

      埋め込み N 層の 幅 WW1の値を求めます。

********************************************************/

WW1 = 2* ( Xm - XX5) ;

fprintf(fpAA,"\n\n (020) The width of the N region ") ;

printf( "\n\n (020) The width of the N region ") ;

fprintf(fpAA," WW1 = XX7 - XX5 = 2* ( Xm - XX5) = %f ", WW1 );

printf( " WW1 = XX7 - XX5 = 2* ( Xm - XX5) = %f ", WW1 );

/******************************************************/







/*******************************************************

   P+PNPP+接合 幅 XX12 = 2*Xm の中で

 埋め込み N 層の 不純物DOSE量 QDDの値を求めます。

********************************************************/

DXX = ( Xm - XX5)/1000000;


QD=0;

for (i=1;i<1000001;i++) {

X = XX5 + ( i - 0.5 )*DXX;

Dope( );

QD= QD+ D*DXX; }


QD = - QD;


printf( "\n\n (021) In N region [ XX5 , Xm ] = [ %f , %f ]", XX5,Xm ) ;

fprintf(fpAA,"\n\n (021) In N region [ XX5 , Xm ] = [ %f , %f ]", XX5,Xm ) ;

QDD = Nd*(Xm -XX5) ;

printf( "\n\n the tolal charge QDD = Nd*(Xm -XX5) = %f ", QDD) ;

fprintf(fpAA,"\n\n the tolal charge QDD = Nd*(Xm -XX5) = %f ", QDD) ;


printf( "\n\n the tolal charge QD = %f ", QD) ;

fprintf(fpAA,"\n\n the tolal charge QD = %f ", QD) ;

NDD= QD/(Xm-XX5) ;

printf( "\n\n NDD = QD/(Xm-XX5) = %f with Nd = %f ",NDD,Nd) ;

fprintf(fpAA,"\n\n NDD = QD/(Xm-XX5) = %f with Nd = %f ",NDD, Nd) ;









/************************************************************

  表面のP+P 層側の空乏層の右側の境界位置 XX4 を求めます。

Left方向 <--- Xm < XX5 < XX4 < XX1 < 0 ---> Right方向

     QDD = 区間 [ XX5, Xm ] の 不純物DOSE量


平均不純物濃度 NDD = QDD/ ( Xm - XX5 ) の値を求めます。

*************************************************************/

NDD=QDD/( Xm - XX5 );

printf( "\n\n (022) In N region [ XX5 , Xm ] = [ %f , %f ]", XX5,Xm);

fprintf(fpAA,"\n\n (022) In N region [ XX5 , Xm ] = [ %f , %f ]", XX5,Xm );

printf( "\n\n NDD = QDD/( Xm - XX5 )= %f with Nd = %f ", NDD,Nd);

fprintf(fpAA,"\n\n NDD = QDD/( Xm - XX5 )= %f with Nd = %f ", NDD,Nd);


/************************************************************

  表面のP+P 層側の空乏層の右側の境界位置 XX4 を求めます。

Left方向 <--- Xm < XX5 < XX4 < XX1 < 0 ---> Right方向

     QDD = 区間 [ XX5, Xm ] の 不純物DOSE量

     QAA = 区間 [ XX4, XX5] の 不純物DOSE量

不純物DOSE量 QAA = QDD となる点が XX4の値です。


*************************************************************/


XX4 = XX5 - (Xm-XX5)*Nd/Na;

printf( "\n\n (023) XX4 = XX5 - (Xm-XX5)*Nd/Na) = %f ", XX4 );

fprintf(fpAA, "\n\n (023) XX4 = XX5 - (Xm-XX5)*Nd/Na) = %f ", XX4 );


X=XX4-DX; Dope( );

printf( "\n\n at X = XX4-DX = %f Dope(X) = %f ", XX4-DX, D);

fprintf(fpAA,"\n\n at X = XX4-DX = %f Dope(X) = %f ", XX4-DX, D);


X = XX4 ; Dope( ); D4= D;

printf( "\n\n at X = XX4 = %f Dope(XX4) = D4= %f ", XX4, D4);

fprintf(fpAA,"\n\n at X = XX4 = %f Dope(XX4) = D4= %f ", XX4, D4);


XX8=2*Xm-XX4;

printf( "\n\n The left PN junction depletion edge is at X = XX8 ; ");

printf( "\n\n XX8 = 2*Xm-XX4 = %f ", XX8);

fprintf(fpAA,"\n\n The left PN junction depletion edge is at X = XX8 ; ");

fprintf(fpAA,"\n\n XX8 = 2*Xm-X4 = %f ", XX8 );

/*************************************************************/


QAA=0; i=1; X=0; DXX = 0.00001;

NEXT_i :

X=XX5 - ( i - 0.5 )*DXX;

Dope( );

QAA = QAA + D*DXX;

i=i+1;

if(QAA<QDD) goto NEXT_i;


X4 = X - 0.5*DXX ;

NAA = QAA/(XX5-X4);


printf( "\n\n (024) The right PN junction depletion edge is at X = X4 : ");

printf( "\n\n X4 = %f ( XX5 - X4 ) = %f with XX4 = %f ", X4, XX5 -X4, XX4 );

printf( "\n\n NAA = QAA/(XX5-X4)= %f with Na = %f ", NAA,Na );



fprintf( fpAA,"\n\n (024) The right PN junction depletion edge is at X = X4 : ");

fprintf( fpAA,"\n\n X4 = %f ( XX5 - X4 ) = %f with XX4 = %f ", X4, XX5 -X4, XX4 );

fprintf( fpAA,"\n\n NAA = QAA/(XX5-X4)= %f with Na = %f ", NAA,Na );




X = X4; Dope( ); D4 = D;


printf( "\n\n (025) at X = X4 = %f D(X4) = D4 = %f with XX4 = %f ", XX4, D4, XX4);

fprintf(fpAA,"\n\n (025) at X = X4 = %f D(X4) = D4 = %f with XX4 = %f ", XX4, D4, XX4);



/**********************************************************


  不純物DOSE量 QAA = QDD となる点が XX4の値でした。

     その点 X=XX4 での濃度 D4 = Dope(XX4)。


***********************************************************/


X=XX4-DX; Dope( );

printf( "\n\n (026) at X = XX4-DX = %f Dope(X) = %f ", XX4-DX, D);

fprintf(fpAA,"\n\n (026) at X = XX4-DX = %f Dope(X) = %f ", XX4-DX, D);


X = XX4 ; Dope( ); D4= D;

printf( "\n\n (026) at X = XX4 = %f Dope(XX4) = D4= %f ", XX4, D4);

fprintf(fpAA,"\n\n (026) at X = XX4 = %f Dope(XX4) = D4= %f ", XX4, D4);


X=X4-DX; Dope( );

printf( "\n\n (027) at X = X4-DX = %f Dope(X) = %f ", X4-DX, D);

fprintf(fpAA,"\n\n (027) at X = X4-DX = %f Dope(X) = %f ", X4-DX, D);


X = XX4 ; Dope( ); D4= D;

printf( "\n\n (027) at X = X4 = %f Dope(XX4) = D4= %f ", X4, D4);

fprintf(fpAA,"\n\n (027) at X = X4 = %f Dope(XX4) = D4= %f ", X4, D4);



/*******************************************************/













/*****************************************************

表面の P+P 濃度差によるバリア電位の概算

******************************************************/



X=0 ; Dope( ); Doo=D;

printf( "\n\n (028) Surface Impurity Density Doo =%f" , Doo ) ;

fprintf(fpAA, "\n\n (028) Surface Impurity Density Doo =%f" , Doo ) ;



X=XX4 ; Dope( ); D4=D;

printf( "\n\n at X = XX4 =%f Dope(XX4) = D4 = %f with Na = %f ", XX4,D4,Na);

fprintf(fpAA,"\n\n at X = XX4 =%f Dope(XX4) = D4 = %f with Na = %f ", XX4,D4,Na);


V4 = kT*log( Ns/D4 );

printf( "\n\n (029) V4 = kT*log( Doo/D4 ) = %f with VB = %f", V4,VB );


fprintf(fpAA,"\n\n (029) V4 = kT*log( Doo/D4 ) = %f with VB = %f", V4,VB );


V5 = VB + Na*(XX5-XX4)*(XX5-XX4)/2/Esi;


printf( "\n\n V5 = VB + Na*(XX5-XX4)*(XX5-XX4)/2/Esi = %f", V5 );

fprintf(fpAA,"\n\n V5 = VB + Na*(XX5-XX4)*(XX5-XX4)/2/Esi = %f", V5 );



/**************************************************************************/











/************************************************************

  表面のP+P 層側の空乏層の右側の境界位置 XX4 を求めます。

Left方向 <--- Xm < XX5 < XX4 < XX1 < 0 ---> Right方向

     QDD = 区間 [ XX5, Xm ] の 不純物DOSE量

     QAA = 区間 [ XX4, XX5] の 不純物DOSE量

不純物DOSE量 QAA = QDD となる点が XX4の値です。


平均不純物濃度 NAA = QAA / ( XX5 - XX4 ) を求めます。


**************************************************************/


NAA = QDD/ ( XX5 - XX4 ) ;

printf( "\n\n (030)  P 領域側の空乏層の平均不純物濃度");

printf( "\n\n NAA= QDD/ ( XX5 - XX4 ) = %f with Na = %f ", NAA,Na) ;

fprintf( fpAA,"\n\n (030) P 領域側の空乏層の平均不純物濃度");

fprintf( fpAA,"\n\n NAA= QDD/ ( XX5 - XX4 ) = %f with Na =%f ", NAA,Na) ;


/************************************************************************/

















/*****************************************************

      空乏層近似での N層の中の

      Empty Potential Well の minimum 電位 

  最低電圧 VMMの値を求めます.

******************************************************

      同じ空乏層近似での式が 

    関数 WW( )の定義でも使用しています。

Empty Well Potentialの概算値の計算

******************************************************/


VMM = V5 + NDD* ( Xm - XX5 )* ( Xm - XX5 )/2/Esi ;


printf( "\n\n (032) VMM = V5 + NDD* ( Xm - XX5 )* ( Xm - XX5 )/2/Esi ; " );

printf( "\n\n Empty Well Potential = VMM = %f ", VMM );


fprintf(fpAA, "\n\n (032) VMM = V5 + NDD* ( Xm - XX5 )* ( Xm - XX5 )/2/Esi ; " );

fprintf(fpAA,"\n\n Empty Well Potential = VMM = %f \n\n", VMM);






/*****************************************************

   空乏層近似と 表面近傍ではバリア電界近似で

     V(X)に関する反復計算の初期を求めます。

    WW( ) 関数を使って V(X) の初期値を求めます。

******************************************************/


DX=Xm/N ;

ErrMax=0;

/*********************************************/

for (i=1;i<N+1;i++) { X=i*DX; WW( ); V[i] = W ; }

/*********************************************/


V[0] =0 ;

V[N+1]=V[N-1];




/*********************************************/

for ( i=1;i<N+1;i++) { X=i*DX; Dope( );

Err = V[i+1]+V[i-1]-2*V[i] - ( D - Doo*exp( - V[i]/kT) ) *DX*DX/Esi ;

if(Err<0) Err=-Err;

if(ErrMax<Err) { i_ErrMax = i; ErrMax = Err; }

j = i - (i/NN)*NN;

if(j == 0 ) {

printf ( "\n i = %d , X = %f D = %f V =%f Err=%f ", i,X,D,V[i],Err);

fprintf (fpAA, "\n i = %d , X = %f D = %f V =%f Err=%f ", i,X,D,V[i],Err); } }



fprintf(fpAA, "\n\n");

printf("\n\n type Enter >");

c=getchar( );

if(c =='c') printf("\n\n Good Bye ! \n\n") ;


fprintf( fpAA,"\n\n");



















/***********************************************

  P+PNPP+ double junction type Photodiode

for Solar Cell Application


( Line 1210~ )


************************************************/





/************************************************

ここから 反復計算を hhhhh 回 実行します。

************************************************/

/******************* Loop 001 **********************/

for (h=0;h<hhhhhh ;h++) { V[0] = 0 ;


/******************* Loop 002<001 **********************/

for (j=0;j<N2;j++) {





/**************************************

    i = ( 2*j + 1 )= 奇数値 です。

    V[i-1]とV[i+1]の値から新しく、

   奇数値のV[i]の値を計算します。

***************************************/

i=2*j+1;

X=i*DX; Dope( );

W= (V[i-1]+V[i+1])/2;

/******************* Loop 003<002<001 **********************/

for (m=1;m<10;m++) {

Err= V[i+1]+V[i-1]-2*W - ( D - Doo*exp( -W/kT) )*DX*DX/Esi ;

Drr= -2 - Doo*exp( -W/kT)*DX*DX/Esi/kT ;

W = W - Err/Drr ; if(W<0) W=0;

}/*************** End Loop 003<002<001 **********************/


V[i] = W;

}/*************** End Loop 002<001 **********************/


V[N+1]=V[N-1]; V[0] = 0;


/*************** Loop 004<001 **********************/


for (j=1;j<N2+1;j++) {


/**************************************

      i = 2*j = 偶数値 です。

    V[i-1]とV[i+1]の値から新しく、

   奇数値のV[i]の値を計算します。


***************************************/

i=2*j;

X=i*DX; Dope( );

W= (V[i-1]+V[i+1])/2;

/*************** Loop 005<004<001 **********************/

for (m=1;m<10;m++) {

Err= V[i+1]+V[i-1]-2*W - ( D - Doo*exp( -W/kT) ) *DX*DX/Esi ;

Drr= -2 - Doo*exp( -W/kT)*DX*DX/Esi/kT ;

W = W - Err/Drr ; if(W<0) W=0;

}/************* End Loop 005<004<001 **********************/

V[i] = W;

}/************* End Loop 004<001 **********************/



ErrMax = 0;


/************* Loop 006<001 **********************/


for (i=1;i<N+1;i++) {


/**************************

誤差を計算します。

****************************/

X = i*DX; Dope( ); Hole = Doo*exp( - V[i]/kT);

Err = V[i+1]+V[i-1]-2*V[i] - ( D - Hole)*DX*DX/Esi ;

if(Err<0) Err=-Err;

if(ErrMax<Err) { i_ErrMax = i; ErrMax = Err; }


}/********** End Loop 006<001 **********************/


Err = log(ErrMax) /log(10);

printf( "\n h=%d X_ErrMax = %f log(ErrMax)/log(10) = %f", h,i_ErrMax*DX, Err);

fprintf( fpAA,"\n h=%d X_ErrMax = %f log(ErrMax)/log(10) = %f", h,i_ErrMax*DX, Err );


}/********** End Loop 001 **********************/



/************************************************

End of 反復計算 ( hhhhh 回 )  

************************************************/


printf( "\n\n" );

fprintf(fpAA, "\n\n" );

/***********************************************/





/***********************************************

  P+PNPP+ double junction type Photodiode

for Solar Cell Application


( Line 1378~ )


************************************************/














/**************************************

表面近傍のV[i]の値を詳細に出力します。

***************************************/


/************* Loop 007 *********************

for (i=1;i<21;i++) {


X = i*DX; Dope( ); Hole = Doo*exp( - V[i]/kT);

Err = V[i+1]+V[i-1]-2*V[i] - ( D - Hole)*DX*DX/Esi ;

fprintf (fpAA, "\n i = %d X = %f D = %f Hole = %f ( H - D ) = %f V= %f Err =%f ",

i,X,D,Hole,Hole-D,V[i], Err ) ;

printf ("\n i = %d X = %f D = %f Hole = %f ( H - D ) = %f V= %f Err =%f ",

i,X,D,Hole,Hole-D,V[i], Err ) ; }

}/********************** End of Loop 7 ****************************/




printf( "\n\n ***************************************** \n\n");
fprintf(fpAA,"\n\n ***************************************** \n\n");


/************* Loop 008 **********************/


for (i=1;i<N+1;i++) {



/******************************************

X の 全域で V[i]の値を間引きして出力します。

*******************************************/





j = i - (i/NN)*NN;

if(j == 0 ) { X = i*DX; Dope( ); Hole = Doo*exp( - V[i]/kT);

Err = V[i+1]+V[i-1]-2*V[i] - ( D - Hole)*DX*DX/Esi ;


fprintf (fpAA, "\n\n i = %d X = %f D = %f ", i,X,D);
printf ( "\n\n i = %d X = %f D = %f ", i,X,D);

fprintf (fpAA, "\n\n Hole = %f ( H - D ) = %f", Hole,Hole-D);
printf ( "\n\n Hole = %f ( H - D ) = %f", Hole,Hole-D);

fprintf (fpAA, "\n\n V = %f Err =%f ", V[i], Err );
printf ( "\n\n V = %f Err =%f ", V[i], Err ); }


} /******************* End of Loop 8 **************/










/***********************************************

  P+PNPP+ double junction type Photodiode

for Solar Cell Application


( Line 1482~ )

************************************************/







/*************************************************

Graph 描画の入力関数の値を決めます。

N = 10000 個の V[i] の data から

 N =10000 個の Graph 描画用の data を生成します。

***************************************************/


printf("\n\n****************Final Output ******************\n\n");

fprintf(fpAA,"\n\n****************Final Output ******************\n\n");



h=1; k=0;

/************* Loop 009 **********************/



for ( i=0;i<N+1;i++) {

/***********************************************

Space Charge Polarization Zero Piont を検出します。

***********************************************/

X = i*DX; Dope( ); Hole = Doo*exp( - V[i]/kT);

D = Hole - D ;

if( h == 1 ) if ( D > 0 ) { h = 0 ; k=k+1;

fprintf(fpAA, "\n\n i= %d XX%d = %f \n\n" , i, k, X) ;

goto HHH; }







if( h == 0 ) if ( D < 0 ) { h = 1 ; k=k+1;

fprintf(fpAA, "\n\n i= %d XX%d = %f \n\n" , i, k, X) ;

}


HHH:




/***********************************************/















X=i*DX; Dope( ) ; Hole = Doo*exp( - V[i]/kT) ;


/***********************************************************

          Graphの座標DATAを計算します。


Graph を NP 個 描きます。

************************************************************/


NP = 4 ;



/***************** Graph (1) **********************************

k = 1

電位  - 0.1 < V(X) < 0.9 の グラフを 描画します。

for 0 < X < 10 の範囲で。。。

************************************************************/

k=1;

xxmin[k] = 0 ; xxmax[k] = 10 ; yymin[k]= 0.9 ; yymax[k] = - 0.1 ;


/************************************************************/

XX = X ;

if ( XX < xxmin[k] ) XX = xxmin[k];

if ( XX > xxmax[k] ) XX = xxmax[k];

XP[k][i] = xmin+ xmax*( XX - xxmin[k] ) /( xxmax[k] -xxmin[k] ) ;

YY = V[i];

if ( YY > yymin[k] ) YY = yymin[k] ;

if ( YY < yymax[k] ) YY = yymax[k];

YP[k][i] = ymin + ymax* ( YY - yymin[k] ) /( yymax[k] -yymin[k] ) ;

/*************************************************************/




/***************** Graph (2) ****************************

k = 2

Barrier 電位  -0.01 < V(X) < 0.02  の グラフを 描画します。

      for 2.5 < X < 4.0 の範囲で。。。

********************************************************/

k=2;


xxmin[k] = 2.5 ; xxmax[k] = 3.5 ; yymin[k] = 0.020 ; yymax[k] = -0.005 ;


/************************************************************/

XX = X ;

if ( XX < xxmin[k] ) XX = xxmin[k];

if ( XX > xxmax[k] ) XX = xxmax[k];

XP[k][i] = xmin+ xmax*( XX - xxmin[k] ) /( xxmax[k] -xxmin[k] ) ;

YY = V[i];

if ( YY > yymin[k] ) YY = yymin[k] ;

if ( YY < yymax[k] ) YY = yymax[k];

YP[k][i] = ymin + ymax* ( YY - yymin[k] ) /( yymax[k] -yymin[k] ) ;

/*************************************************************/




/***************** Graph (3) ****************************

k = 3

電位 ρ(x) = D(x) - P(V(x))  の グラフを 描画します。

-6000 < ρ(x) < + 6000

for 0 < X < 10 の範囲で。。。

********************************************************/

k=3;


xxmin[k] = 0 ; xxmax[k] = 10 ; yymin[k] = -7000 ; yymax[k] = 7000 ;


/************************************************************/

XX = X ;

if ( XX < xxmin[k] ) XX = xxmin[k];

if ( XX > xxmax[k] ) XX = xxmax[k];

XP[k][i] = xmin+ xmax*( XX - xxmin[k] ) /( xxmax[k] -xxmin[k] ) ;

Dope( ) ; YY = D - Ns*exp ( - V[i] / kT ) ;

if ( YY < yymin[k] ) YY = yymin[k] ;

if ( YY > yymax[k] ) YY = yymax[k];

YP[k][i] = ymin + ymax* ( YY - yymin[k] ) /( yymax[k] -yymin[k] ) ;

/*************************************************************/




/***************** Graph (4) ****************************

k = 4

電位  D(x)   の グラフを 描画します。

-Nd -20 < D(x) < Ns +20

for 0 < X < 10 の範囲で。。。

********************************************************/

k=4;


xxmin[k] = 0 ; xxmax[k] = 10 ; yymin[k] = - 0.1*Ns ; yymax[k] = Ns*1.1 ;


/************************************************************/

XX = X ;

if ( XX < xxmin[k] ) XX = xxmin[k];

if ( XX > xxmax[k] ) XX = xxmax[k];

XP[k][i] = xmin+ xmax*( XX - xxmin[k] ) /( xxmax[k] -xxmin[k] ) ;

Dope( ) ; YY = D ;

if ( YY < yymin[k] ) YY = yymin[k] ;

if ( YY > yymax[k] ) YY = yymax[k];

YP[k][i] = ymin + ymax* ( YY - yymin[k] ) /( yymax[k] -yymin[k] ) ;

/*************************************************************/



Dope( ); Hole = Ns*exp(-V[i]/kT); Err = ( V[i] - V[i-1] )/DX ;

fprintf(fpAA,"\n i=%d X=%f D =%f V= %f dV/dX = %f Hole = %f ( Hole - D ) = %f " ,

i, X, D, V[i], Err, Hole, Hole - D ) ;











} /************* End Loop 009 **********************/


/*******************************************

この後は Graph を描いて a.html に出力します 

********************************************/



fclose(fpAA);






} /******************************************

End of Function void PXPY ( void )

*********************************************/




/******************************************


void Graph_Plot(void)

  グラフ描画出力用の定義です。

*********************************************/



void Graph_Plot(void) {


printf("\n\n Graph_PLot(%d) ......... Output = A&d.html ..... ",k,k);



if ( k == 1 ) fpC=fopen("A1.html","w");

if ( k == 2 ) fpC=fopen("A2.html","w");

if ( k == 3 ) fpC=fopen("A3.html","w");

if ( k == 4 ) fpC=fopen("A4.html","w");

if ( k == 5 ) fpC=fopen("A5.html","w");

if ( k == 6 ) fpC=fopen("A6.html","w");

if ( k == 7 ) fpC=fopen("A7.html","w");

if ( k == 8 ) fpC=fopen("A8.html","w");

if ( k == 9 ) fpC=fopen("A9.html","w");

fprintf(fpC,"<!DOCTYPE HTML PUBLIC \"");

fprintf(fpC,"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");

fprintf(fpC,"<HTML>\n<HEAD>\n<META http-equiv=\"Content-Type\"");

fprintf(fpC," content=\"text/html; charset=Shift_JIS\">\n");

fprintf(fpC,"<META http-equiv=\"Content-Style-Type\" content=\"text/css\">\n");

fprintf(fpC,"<TITLE></TITLE>\n</HEAD>\n<BODY>\n<BR>\n");


fprintf(fpC,"<BR>\n<FONT size=\"+2\"></FONT><I><B><FONT color=\"#ff0000\">\n\n");


fprintf(fpC,"Frame < xmin = 0 , xmax = 20 , ymin = 0 , ymax = 10 > <BR> \n") ;

fprintf(fpC," Graph %d < xxmin = %f , xxmax =%f , yymin =%f , yymax = %f > \n",

k, xxmin[k],xxmax[k],yymin[k],yymax[k]) ;




fprintf(fpC,"</FONT><BR><FONT color=\"#ff0000\">\n");




fprintf(fpC," Graph (%d) ........ V(x),D(x) and ρ(x) = D(x) - P(V) .......\n", k ) ;



fprintf(fpC,"</FONT> <BR>\n</B><BR>\n</I><BR>\n");



/*******************************************************

グラフの枠 ( k = 0 ) を描きます 

*******************************************************/

for (i =0 ; i< 2500 ; i++) { XP[0][i] = xmin ;

YP[0][i] = ymin + ( 2500 - i )*( ymax -ymin)/2500; }


for (i =2500; i< 5000 ; i++) { XP[0][i] = xmax ;

YP[0][i] = ymin + ( 5000 - i )*( ymax -ymin)/2500; }


for (i =5000; i< 7500 ; i++) { YP[0][i] = ymin ;

XP[0][i] = xmin + ( 7500 - i )*( xmax- xmin)/2500; }


for (i =7500; i<=10000 ; i++) { YP[0][i] = ymax ;

XP[0][i] = xmin + (10000 - i )*( xmax-xmin)/2500; }

/********************************************************/


for ( i =0; i<=N ; i++) {

xx= XP[0][i] ;

yy= YP[0][i] ;


/**************************************************************

 描画したい点 (xx,yy) のGraph 上での絶対座標 (nxx,nyy) の計算

**************************************************************/

nyy = ny1 + (xx-xmin)*(ny2-ny1)/(xmax-xmin) ;

nxx = nx2 + (yy-ymin)*(nx1-nx2)/(ymax-ymin) ;


/**************************************************************/


fprintf(fpC,"<DIV style=\"top :");

fprintf(fpC,"%d",nxx) ;

fprintf(fpC,"px;left :") ;

fprintf(fpC,"%d",nyy);

fprintf(fpC,"px; position : absolute; z-index : 1;\" id=\"Layer1\"><P>");

fprintf(fpC,".");

fprintf(fpC,"</P></DIV>\n" ); }


/**************************************************************/




/*******************************************************

k 番目の グラフ ( k > 0 ) を描きます 

*******************************************************/

for ( i =0; i<=N ;i++) {

xx= XP[k][i];

yy= YP[k][i];


/**************************************************************

 描画したい点 (xx,yy) のGraph 上での絶対座標 (nxx,nyy) の計算

**************************************************************/

nyy = ny1 + (xx-xmin)*(ny2-ny1)/(xmax-xmin) ;

nxx = nx2 + (yy-ymin)*(nx1-nx2)/(ymax-ymin) ;


/**************************************************************/


fprintf(fpC,"<DIV style=\"top :");

fprintf(fpC,"%d",nxx) ;

fprintf(fpC,"px;left :") ;

fprintf(fpC,"%d",nyy);

fprintf(fpC,"px; position : absolute; z-index : 1;\" id=\"Layer1\"><P>");

fprintf(fpC,".");

fprintf(fpC,"</P></DIV>\n" ); }

/**************************************************************/



fprintf(fpC,"</B></I></FONT>\n</BODY></HTML>\n");



fclose(fpC);


printf("\n\n ******* See a%d.html *******\n\n",k);



}/********* End of PXPY ( ) *****************/







/***********************************************

  P+PNPP+ double junction type Photodiode

for Solar Cell Application


( Line 1839~ )


************************************************/





/***********************************************

  P+PNPP+ double junction type Photodiode

for Solar Cell Application

************************************************/



/***********************************************************

Main Program の名称は void main( void ) です。

 NP 個の graph を描いて a.html に出力します。

関数 PXPY( ) を定義し、Graphの各点の座標値を決定します。     

       for k=1 to NP and for i = 0 to N,

  各点の座標値は XP[k][i]、YP[k][i]  に入ります。  

***********************************************************/


void main( void ) { char c ;



/************* 物理定数の値を決めます*******/


/************V(X)の初期値を決定します*******/


/************* 反復計算をします*************/


PXPY( );


/************* Graphを描きます*************/


for ( k=1; k<NP+1;k++) Graph_Plot( );



/*******************************************

Program のすべての計算が完了しますと、

  Standby 状態のなります。

  最後に Enter Key を押すと 

  Programが終了します。

********************************************/



printf( "\n Also see aa.txt \n\n Push Enter Key to end >" );



c=getchar( ); if(c =='c') printf("\n\n Good Bye ! \n\n");

c=getchar( ); if(c =='c') printf("\n\n Good Bye ! \n\n"); }




/**END of Source Program Code ****************/



/******** End of C-source program code ******************/



More to come soon ..........Now under consruction .......

*****************************************************




*************************************************



***********************************************

What is Pinned Photodiode ?

Hagiwara Publication List

Study Special Relativity Theory

What is Abura Wake Zan ?

Study Korean for Your Enjoyment

Enjoy C-programming.

****************************************************

hagiwara-yoshiaki@aiplab.com ( http://www.aiplab.com/ )

hagiwara@ssis.or.jp ( http://www.ssis.or.jp/en/index.html )

********************************************************
         Return to Top Page
*********************************************************