1 /*****************************************************************************/
2 /* 8888888 88888888 88888888 */
5 /* 8 88888888 88888888 */
8 /* 888888 888888888 888888888 */
10 /* A Two-Dimensional General Purpose Semiconductor Simulator. */
13 /* Last update: Nov 23, 2005 */
17 /* NINT, No.69 P.O.Box, Xi'an City, China */
19 /*****************************************************************************/
23 //-----------------------------------------------------------------------------
24 // special process of electrode bcs for mix type simulation
25 //-----------------------------------------------------------------------------
27 void ISZone::F1_mix_ddm_gatebc(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
,DABC
&bc
)
30 int size
= pzone
->davcell
.size();
32 const VoronoiCell
* pcell
= &pzone
->davcell
[i
];
33 for(int j
=0;j
<electrode
.size();j
++)
35 if(electrode
[j
]==pcell
->bc_index
-1) {gate_equ
=j
;break;}
37 GateBC
*pbc
= dynamic_cast<GateBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
38 f
[zofs
[zone_index
]+i
] = x
[zofs
[zone_index
]+i
] - pbc
->Vapp
+ pbc
->WorkFunction
;
39 //just for fill the equ entry
40 f
[zofs
[zone_index
]+equ_num
*size
+gate_equ
]=0.0;
44 void ISZone::F1_mix_gate_electrode_current(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
46 int bc_index
= electrode
[i
];
47 GateBC
*pbc
= dynamic_cast <GateBC
* > (bc
.Get_pointer(bc_index
));
48 PetscScalar current
=0;
49 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
51 int node
=bc
[bc_index
].psegment
->node_array
[j
];
52 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
53 PetscScalar Vi
= x
[zofs
[zone_index
]+node
]; //potential of node i
55 for(int k
=0;k
<pcell
->nb_num
;k
++)
57 int nb
= pcell
->nb_array
[k
];
58 PetscScalar Vj
= x
[zofs
[zone_index
]+nb
]; //potential of nb node
59 //displacement current
60 current
+= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
*((Vi
-Vj
)-(fs
[node
].P
-fs
[nb
].P
))/pcell
->ilen
[k
]/ODE_F
.dt
;
64 pbc
->Set_Current_new(current
);
68 void ISZone::J1_mix_ddm_gatebc(int i
,PetscScalar
*x
,Mat
*jac
, ODE_Formula
&ODE_F
, vector
<int> & zofs
,DABC
&bc
)
71 int size
= pzone
->davcell
.size();
73 const VoronoiCell
* pcell
= &pzone
->davcell
[i
];
74 for(int j
=0;j
<electrode
.size();j
++)
76 if(electrode
[j
]==pcell
->bc_index
-1) {gate_equ
=j
;break;}
78 MatSetValue(*jac
,zofs
[zone_index
]+i
,zofs
[zone_index
]+i
,1.0,INSERT_VALUES
);
79 //just for fill the matrix entry
80 MatSetValue(*jac
,zofs
[zone_index
]+equ_num
*size
+gate_equ
,zofs
[zone_index
]+equ_num
*size
+gate_equ
,1.0,INSERT_VALUES
);
84 void ISZone::F1_mix_gate_electrode_Load(int bc_index
, double & current
, PetscScalar
& pdI_pdV
, Vec
& pdI_pdw
, Vec
& pdF_pdV
,
85 PetscScalar
*x
, Mat
*jac
, ODE_Formula
&ODE_F
, vector
<int> &zofs
, DABC
& bc
, PetscScalar DeviceDepth
)
87 GateBC
*pbc
= dynamic_cast <GateBC
* > (bc
.Get_pointer(bc_index
));
89 PetscScalar e
= mt
->e
;
90 VecZeroEntries(pdI_pdw
);
91 VecZeroEntries(pdF_pdV
);
92 PetscScalar
* apdI_pdw
;
93 PetscScalar
* apdF_pdV
;
94 VecGetArray(pdI_pdw
,&apdI_pdw
);
95 VecGetArray(pdF_pdV
,&apdF_pdV
);
96 current
= pbc
->Get_Current_new();
98 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
100 int node
=bc
[bc_index
].psegment
->node_array
[j
];
101 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
102 for(int k
=0;k
<pcell
->nb_num
;k
++)
104 int nb
= pcell
->nb_array
[k
];
105 //for displacement current
106 PetscScalar dJ_dVi
= aux
[node
].eps
/pcell
->ilen
[k
]/ODE_F
.dt
*pcell
->elen
[k
];
107 PetscScalar dJ_dVr
= -aux
[node
].eps
/pcell
->ilen
[k
]/ODE_F
.dt
*pcell
->elen
[k
];
108 apdI_pdw
[zofs
[zone_index
]+node
] += dJ_dVi
*DeviceDepth
;
109 apdI_pdw
[zofs
[zone_index
]+nb
] += dJ_dVr
*DeviceDepth
;
111 apdF_pdV
[zofs
[zone_index
]+node
] = 1.0;
113 VecRestoreArray(pdI_pdw
,&apdI_pdw
);
114 VecRestoreArray(pdF_pdV
,&apdF_pdV
);