Memosa-FVM  0.2
TunnelingDiscretization.h
Go to the documentation of this file.
1 // This file os part of FVM
2 // Copyright (c) 2012 FVM Authors
3 // See LICENSE file for terms.
4 
5 #ifndef _TUNNELINGDISCRETIZATION_H_
6 #define _TUNNELINGDISCRETIZATION_H_
7 
8 #include "PhysicsConstant.h"
9 #include "ElectricBC.h"
10 #include "Field.h"
11 #include "MultiField.h"
12 #include "MultiFieldMatrix.h"
13 #include "Mesh.h"
14 #include "Discretization.h"
15 #include "StorageSite.h"
16 #include "DiagonalMatrix.h"
17 #include "CRMatrix.h"
19 
20 
21 /**************************************************
22 Diag type: 2x2Tensor
23  | d00, d01 |
24  | d10, d11 |
25 
26 OffDiag type: 2x2Tensor
27  | o00, o01 |
28  | o10, o11 |
29 
30 X type: VectorT2
31  | x0 |
32  | x1 |
33 
34 "0" is trapped charge
35 "1" is band charge
36 
37 Tunneling model only modifies d0 and x0
38 
39 *************************************************/
40 
41 
42 template <class X, class Diag, class OffDiag>
44 {
45 
46  public:
51  typedef typename CCMatrix::DiagArray DiagArray;
53  typedef Array<X> XArray;
55 
57  const GeomFields& geomFields,
58  const Field& varField,
59  const Field& conductionbandField,
60  const ElectricModelConstants<T_Scalar>& constants,
61  T_Scalar& fluxIn,
62  T_Scalar& fluxOut
63  ) :
64  Discretization(meshes),
65  _geomFields(geomFields),
66  _varField(varField),
67  _conductionbandField(conductionbandField),
68  _constants(constants),
69  _fluxIn(fluxIn),
70  _fluxOut(fluxOut)
71  {}
72 
73  void discretize(const Mesh& mesh, MultiFieldMatrix& mfmatrix,
74  MultiField& xField, MultiField& rField)
75  {
76  #define DEBUG 0
77 
78  const StorageSite& cells = mesh.getCells();
79 
80  //const StorageSite& faces = mesh.getFaces();
81 
82  const int nCells = cells.getSelfCount();
83 
84  const TArray& conduction_band = dynamic_cast<const TArray&> (_conductionbandField[cells]);
85 
86  const TArray& cellVolume =
87  dynamic_cast<const TArray&>(_geomFields.volume[cells]);
88 
89  const VectorT3Array& cellCentroid =
90  dynamic_cast<const VectorT3Array& > (_geomFields.coordinate[cells]);
91 
92  const MultiField::ArrayIndex cVarIndex(&_varField,&cells);
93 
94  CCMatrix& matrix = dynamic_cast<CCMatrix&>(mfmatrix.getMatrix(cVarIndex,cVarIndex));
95 
96  const XArray& xCell = dynamic_cast<const XArray&>(_varField[cells]);
97 
98  TArray* ts = new TArray(cells.getCount());
99  *ts = 0;
100  TArray& transmission = *ts;
101 
102  XArray& rCell = dynamic_cast<XArray&>(rField[cVarIndex]);
103 
104  DiagArray& diag = matrix.getDiag();
105 
106  _fluxIn = 0.0;
107  _fluxOut = 0.0;
108 
109  const T_Scalar electron_effmass = _constants["electron_effmass"];
110  const T_Scalar temperature = _constants["OP_temperature"];
111  const T_Scalar electron_capture_cross = _constants["electron_capture_cross"];
112  //const T_Scalar voltage = _constants["voltage"];
113  //const T_Scalar substrate_voltage = _constants["substrate_voltage"];
114  //const T_Scalar membrane_voltage = _constants["membrane_voltage"];
115  const T_Scalar fermilevelsubstrate = -_constants["substrate_workfunction"] - _constants["substrate_voltage"];
116  //const T_Scalar fermilevelmembrane = -_constants["substrate_workfunction"] - _constants["membrane_voltage"];
117  //const T_Scalar& dielectric_ionization = _constants["dielectric_ionization"];
118  const int subID = _constants["substrate_id"];
119  //const int memID = _constants["membrane_id"];
120  const int nLevel = _constants["nLevel"];
121  const int normal = _constants["normal_direction"];
122  const int nTrap = _constants["nTrap"];
123 
124  const vector<double> electron_trapdepth = _constants.electron_trapdepth;
125  const vector<double> electron_trapdensity = _constants.electron_trapdensity;
126 
127  if (int(electron_trapdepth.size()) != nTrap || int(electron_trapdensity.size()) != nTrap)
128  throw CException ("trap depth vector size error!");
129 
130  T_Scalar fluxCoeff(0), fermilevel(0), scatterfactor(0);
131  //T_Scalar sourceTunneling(0);
132 
133  for(int c=0; c < cells.getCount(); c++){
134  transmission[c] = 0.0;
135  }
136 
137 
138 
139  //=======================================//
140  // tunneling from substrate to dielectric
141  //=======================================//
142 
143  //const T_Scalar energystep = 0.1 * fabs(substrate_voltage - membrane_voltage) / nLevel;
144  const T_Scalar energystep = 0.01;
145  const T_Scalar alpha = 4.0 * PI * (electron_effmass*ME) / pow(H_SI, 3.0);
146 
147  fermilevel = fermilevelsubstrate;
148 
149 #if DEBUG
150  shared_ptr<IntArray> mark(new IntArray(cells.getCount()));
151  *mark = 0;
152 #endif
153 
154  for (T_Scalar en = fermilevel-4.0; en <= fermilevel+4.0; en += energystep){
155 
156  const T_Scalar supplyfunction = ElectronSupplyFunction(en, fermilevel, temperature);
157 
158  const T_Scalar fermifunction = FermiFunction(en, fermilevel, temperature);
159 
160  //========= transmission coefficient calculation ==========//
161  // this scheme only works for Cartesian mesh
162 
163  foreach(const FaceGroupPtr fgPtr, mesh.getBoundaryFaceGroups())
164  {
165  const FaceGroup& fg = *fgPtr;
166 
167  if (fg.id == subID){
168 
169  const StorageSite& faces = fg.site;
170  const CRConnectivity& faceCells = mesh.getFaceCells(faces);
171  const CRConnectivity& cellCells = mesh.getCellCells();
172  const int nFaces = faces.getCount();
173 
174  for(int f=0; f<nFaces; f++){
175 
176  int c0 = faceCells(f,0); //the first cell adjacent to boundary
177  int c1 = faceCells(f,1); //boundary cell
178 
179  transmission[c1] = 1.0;
180 
181  int low = c1;
182  int me = c0;
183  int high = c0;
184 
185  for(int l=0; l< nLevel; l++){
186 
187  T_Scalar dX = cellCentroid[me][normal] - cellCentroid[low][normal];
188  T_Scalar factor = -2.0/HBAR_SI * sqrt(2.0*electron_effmass*ME*QE);
189  T_Scalar valueMe = PositiveValueOf( conduction_band[me] - en);
190  //T_Scalar valueLow = PositiveValueOf( conduction_band[low] - en);
191  //T_Scalar avg = (valueMe + valueLow) / 2.0;
192  T_Scalar avg = valueMe;
193  T_Scalar exponent = factor * sqrt(avg) * fabs(dX);
194 
195 #if DEBUG
196  (*mark)[me] = 1;
197 #endif
198  transmission[me] = transmission[low] * exp(exponent);
199 
200  const int nbc = cellCells.getCount(me);
201 
202  T_Scalar drmin = 0.0;
203  int neighborUp = 0;
204 
205  for(int nc = 0; nc < nbc; nc++){
206  const int neighbor = cellCells(me, nc);
207  const T_Scalar dr = cellCentroid[me][normal] - cellCentroid[neighbor][normal];
208  if (dr < drmin){
209  drmin = dr;
210  neighborUp = neighbor;
211  }
212  }
213 
214  if (neighborUp < nCells) {
215  high = neighborUp;
216  low = me;
217  me = high;
218  }
219  }
220  }
221  }
222  }
223 
224  //========= tunneling calculation ==========//
225 
226  for(int c=0; c<nCells; c++){
227 
228  for (int i=0; i<nTrap; i++){
229 
230  const T_Scalar stcap = electron_capture_cross * cellVolume[c];
231 
232  const T_Scalar endiff = en - (conduction_band[c]-electron_trapdepth[i]);
233 
234  // tunneling from substrate to traps
235 
236  if (en-conduction_band[c] < 0){ //this condition determines tunneling only happens close to contact
237 
238  if (endiff < 0)
239  scatterfactor = exp(-QE * fabs(endiff)/(K_SI*temperature));
240  else scatterfactor = 1.0;
241 
242  fluxCoeff = alpha * stcap * transmission[c] * supplyfunction *
243  fermifunction * scatterfactor * energystep * QE;
244 
245  _fluxIn += (fluxCoeff * (electron_trapdensity[i] - xCell[c][i]));
246  rCell[c][i] += (fluxCoeff * (electron_trapdensity[i] - xCell[c][i]));
247  diag[c](i,i) -= fluxCoeff;
248 
249  }
250  // tunneling from traps to substrate
251 
252  if(en - conduction_band[c] < 0){
253  if (endiff > 0)
254  scatterfactor = exp(-QE * fabs(endiff)/(K_SI*temperature));
255  else scatterfactor = 1.0;
256 
257  fluxCoeff = alpha * stcap * transmission[c] * supplyfunction *
258  (1-fermifunction) * scatterfactor * energystep * QE;
259 
260  _fluxOut += (fluxCoeff * (- xCell[c][i]));
261  rCell[c][i] += (fluxCoeff * (- xCell[c][i]));
262  diag[c](i,i) -= fluxCoeff;
263 
264  }
265  }
266  }
267  }
268 #if 0
269  //=======================================//
270  // tunneling from membrane to dielectric
271  //=======================================//
272  for(int c=0; c < cells.getCount(); c++){
273  transmission[c] = 0.0;
274  }
275 
276  fermilevel = fermilevelmembrane;
277 
278  for (T_Scalar en = fermilevel-4.0; en <= fermilevel+4.0; en += energystep){
279 
280  const T_Scalar supplyfunction = ElectronSupplyFunction(en, fermilevel, temperature);
281 
282  const T_Scalar fermifunction = FermiFunction(en, fermilevel, temperature);
283 
284  foreach(const FaceGroupPtr fgPtr, mesh.getBoundaryFaceGroups())
285  {
286  const FaceGroup& fg = *fgPtr;
287 
288  if (fg.id == memID){
289  const StorageSite& faces = fg.site;
290  const CRConnectivity& faceCells = mesh.getFaceCells(faces);
291  const CRConnectivity& cellCells = mesh.getCellCells();
292  const int nFaces = faces.getCount();
293 
294  for(int f=0; f<nFaces; f++){
295 
296  int c0 = faceCells(f,0);
297  int c1 = faceCells(f,1);
298 
299  transmission[c1] = 1.0;
300 
301  int low = c1;
302  int me = c0;
303  int high = c0;
304 
305  for(int l=0; l<nLevel; l++){
306 
307  T_Scalar dX = cellCentroid[me][normal] - cellCentroid[low][normal];
308  T_Scalar factor = -2.0/HBAR_SI * sqrt(2.0*electron_effmass*ME*QE);
309  T_Scalar valueMe = PositiveValueOf( conduction_band[me] - en);
310  T_Scalar valueLow = PositiveValueOf( conduction_band[low] - en);
311  T_Scalar avg = (valueMe + valueLow) / 2.0;
312  T_Scalar exponent = factor * sqrt(avg) * fabs(dX);
313  transmission[me] = transmission[low] * exp(exponent);
314 
315  const int nbc = cellCells.getCount(me);
316 
317  T_Scalar drmin = 0.0;
318  int neighborUp = 0;
319 
320  for(int nc = 0; nc < nbc; nc++){
321  const int neighbor = cellCells(me, nc);
322  const T_Scalar dr = cellCentroid[me][normal] - cellCentroid[neighbor][normal];
323  if (dr > drmin){
324  drmin = dr;
325  neighborUp = neighbor;
326  }
327  }
328  if (neighborUp < nCells) {
329  high = neighborUp;
330  low = me;
331  me = high;
332  }
333  }
334  }
335  }
336  }
337 
338  for(int c=0; c<nCells; c++){
339 
340  for(int i=0; i<nTrap; i++){
341 
342  const T_Scalar stcap = electron_capture_cross * cellVolume[c];
343 
344  const T_Scalar endiff = en - (conduction_band[c]-electron_trapdepth[i]);
345 
346  // tunneling from membrane to traps
347 
348  if (en-conduction_band[c] < 0){
349 
350  if (endiff < 0)
351  scatterfactor = exp(-QE * fabs(endiff)/(K_SI*temperature));
352  else scatterfactor = 1.0;
353 
354  fluxCoeff = alpha * stcap * transmission[c] * supplyfunction *
355  fermifunction * scatterfactor * energystep * QE;
356 
357  rCell[c][i] += (fluxCoeff * (electron_trapdensity[i] - xCell[c][i]));
358  diag[c](i,i) -= fluxCoeff;
359  }
360 
361  // tunneling from traps to membrane
362  if(en - conduction_band[c] < 0 ){
363  if (endiff > 0)
364  scatterfactor = exp(-QE * fabs(endiff)/(K_SI*temperature));
365  else scatterfactor = 1.0;
366 
367  fluxCoeff = alpha * stcap * transmission[c] * supplyfunction *
368  (1-fermifunction) * scatterfactor * energystep * QE;
369 
370  rCell[c][i] += (fluxCoeff * (-xCell[c][i]));
371  diag[c](i,i) -= fluxCoeff;
372  }
373  }
374  }
375  }
376 
377 #endif
378  //cout << _fluxIn << " " << _fluxOut << endl;
379  }
380 
381  private:
383  const Field& _varField;
388 };
389 
390 
391 #endif
const FaceGroupList & getBoundaryFaceGroups() const
Definition: Mesh.h:187
int getCount(const int i) const
Matrix & getMatrix(const Index &rowIndex, const Index &colIndex)
shared_ptr< FaceGroup > FaceGroupPtr
Definition: Mesh.h:46
#define PI
int getSelfCount() const
Definition: StorageSite.h:40
Field coordinate
Definition: GeomFields.h:19
NumTypeTraits< X >::T_Scalar T_Scalar
Definition: Mesh.h:28
CCMatrix::OffDiagArray OffDiagArray
const T FermiFunction(const T &energy, const T &fermilevel, const T &temperature)
Definition: Field.h:14
#define K_SI
Array< Vector< T_Scalar, 3 > > VectorT3Array
Definition: Mesh.h:49
Array< Diag > & getDiag()
Definition: CRMatrix.h:856
TunnelingDiscretization(const MeshList &meshes, const GeomFields &geomFields, const Field &varField, const Field &conductionbandField, const ElectricModelConstants< T_Scalar > &constants, T_Scalar &fluxIn, T_Scalar &fluxOut)
CRMatrix< Diag, OffDiag, X > CCMatrix
#define ME
Tangent sqrt(const Tangent &a)
Definition: Tangent.h:317
#define HBAR_SI
const int id
Definition: Mesh.h:41
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
#define H_SI
#define QE
const CRConnectivity & getCellCells() const
Definition: Mesh.cpp:480
const ElectricModelConstants< T_Scalar > & _constants
const StorageSite & getCells() const
Definition: Mesh.h:109
Field volume
Definition: GeomFields.h:26
const T PositiveValueOf(T input)
const CRConnectivity & getFaceCells(const StorageSite &site) const
Definition: Mesh.cpp:388
Tangent fabs(const Tangent &a)
Definition: Tangent.h:312
Definition: Array.h:14
const T ElectronSupplyFunction(const T &energy, const T &fermilevel, const T &temperature)
int getCount() const
Definition: StorageSite.h:39
vector< T > electron_trapdepth
Definition: ElectricBC.h:77
void discretize(const Mesh &mesh, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField)
vector< Mesh * > MeshList
Definition: Mesh.h:439
StorageSite site
Definition: Mesh.h:40