Memosa-FVM  0.2
ElecDiagonalTensor.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 _ELECDIAGONALTENSOR_H_
6 #define _ELECDIAGONALTENSOR_H_
7 
8 #include "NumType.h"
9 #include "Vector.h"
10 #include <sstream>
11 #include "ElecOffDiagonalTensor.h"
12 
13 //this structure is used to store the dianogal tensor in dielectric charging model
14 //the full diag tensor looks like
15 /*
16  | Nt0 Nt0c |
17  | nt1 Nt1c |
18  | ... ... |
19  | Nt(n-1) Nt(n-1)c |
20  | Nct0 Nct1 ... Nct(n-1) Nc |
21 */
22 // here Nt is charges in trap and Nc is charges in conduction band
23 // if the level of trap depth is n, then there are 3n+1 non zeros
24 // it is stored in a 1D array data[3n+1]
25 // here is how the indices work
26 // (0, n-1) refers to diagonal elements Nt0, ... Nt(n-1)
27 // (n, 2n-1) refers to upper diag elements Nt0c, .... Nt(n-1)c
28 // (2n, 3n-1) refers to lower diag elements
29 // (3n) refers to Nc
30 
31 // the offdiag would be just a scalar, since the only connection between
32 // neighbors is due to nc drift
33 
34 template <class T, int N>
36 {
37 public:
38  enum { TN = 3*N+1 } ;
42 
44  {}
45 
47  {
48  for(int i=0; i<TN; i++)
49  _data[i] = o._data[i];
50  }
51 
52  ElecDiagonalTensor(const T& o)
53  {
54  for(int i=0; i<N; i++)
55  _data[i] = o;
56  for(int i=N; i<TN; i++)
57  _data[i] = 0;
58  }
59 
60  static string getTypeName()
61  {
62  return "ElecDiagonalTensor<" + NumTypeTraits<T>::getTypeName() +
63  "," + intAsString(N) +
64  ">";
65  }
66 
67  static int getDimension() {return 1;}
68 
69  static void getShape(int *shp) { *shp = TN;}
70 
71  static int getDataSize()
72  {
74  }
75 
76  T& operator[](int n) {return _data[n];}
77 
78  const T& operator[](int n) const {return _data[n];}
79 
80  void printFromC(ostream &os) const
81  {
82  os << "[ " ;
83  for(int i=0;i<TN;i++)
84  os << _data[i] << " " ;
85  os << "]";
86  }
87 
88  static void write(FILE* fp, const ElecDiagonalTensor& x)
89  {
90  for(int i=0; i<TN; i++)
91  {
92  NumTypeTraits<T>::write(fp,x[i]);
93  fprintf(fp, " ");
94  }
95  }
96 
98  {
99  for(int i=0;i<N;i++)
100  _data[i] = o;
101  for(int i=N; i<TN; i++)
102  _data[i] = 0;
103  return *this;
104  }
105 
107  {
108  for(int i=0;i<TN;i++)
109  _data[i] = o[i];
110  return *this;
111  }
112 
114  {
115  for(int i=0;i<TN;i++)
116  _data[i] = 0;
117  _data[3*N] = o[N];
118  return *this;
119  }
120 
122  {
124  for(int i=0;i<TN;i++)
125  r[i]=-_data[i];
126  return r;
127  }
128 
130  {
131  for(int i=0;i<TN;i++)
132  _data[i] += o[i];
133  return *this;
134  }
135 
136 
138  {
139  _data[3*N] += o[N];
140  return *this;
141  }
143  {
144  for(int i=0;i<N;i++)
145  _data[i] += s;
146  _data[3*N] += s;
147  return *this;
148  }
149 
151  {
152  for(int i=0;i<TN;i++)
153  _data[i] -= o[i];
154  return *this;
155  }
156 
158  {
159  for(int i=0;i<N;i++)
160  _data[i] -= s;
161  _data[3*N] -= s;
162  return *this;
163  }
164 
166  {
167  throw CException("operator not defined for diag /= s");
168  for(int i=0;i<TN;i++)
169  _data[i] /= s;
170  return *this;
171  }
172 
173 
175  {
176  throw CException("no operator defined for /= diag");
177  }
178 
179 
181  {
182  throw CException("operator not defined for diag *= s");
183  for(int i=0;i<TN;i++)
184  _data[i] *= s;
185  return *this;
186  }
187 
188 
190  {
191  throw CException("no operator defined for *= diag");
192  }
193 
194  void zero()
195  {
196  for(int i=0;i<TN;i++) _data[i] = NumTypeTraits<T>::getZero();
197  }
198 
199  T mag2() const
200  {
202  for(int i=0; i<N; i++)
203  r+=_data[i]*_data[i];
204  return r;
205  }
206 
207  bool operator<(const double tolerance) const
208  {
209  return mag2() < tolerance*tolerance;
210  }
211 
213  {
215  z.zero();
216  return z;
217  }
218 
219  static double doubleMeasure(const ElecDiagonalTensor& x)
220  {
221  return 0.0;
222  }
223 
225  {
227  for(int i=0; i<N; i++)
229 
230  return n;
231  }
232 
234  {
236  for(int i=0; i<N; i++)
238 
239  return n;
240  }
241 
243  {
244  for(int i=0; i<N; i++)
246  }
247 
249  const ElecDiagonalTensor& v1)
250  {
251  for(int i=0; i<N; i++)
252  NumTypeTraits<T>::accumulateDotProduct(sum[i],v0[i],v1[i]);
253  }
254 
255  static void reduceSum(T_Scalar& sum, const This_T& x)
256  {
257  for(int i=0; i<N; i++)
258  NumTypeTraits<T>::reduceSum(sum,x[i]);
259  }
260 
262  {
263  for(int i=0; i<N; i++)
264  NumTypeTraits<T>::safeDivide(x[i],y[i]);
265  }
266 
268  {
269  for(int i=0; i<N; i++)
270  NumTypeTraits<T>::normalize(x[i],y[i]);
271  }
272 
273  static void setMax(ElecDiagonalTensor& x, const ElecDiagonalTensor& y)
274  {
275  for(int i=0; i<N; i++)
276  NumTypeTraits<T>::setMax(x[i],y[i]);
277  }
278 
279 
280 
281  private:
282  T _data[3*N+1];
283 
284 };
285 
286 
287 
288 template<class T, int N>
289 inline ostream& operator<<(ostream &os,
290  const ElecDiagonalTensor<T,N> &v)
291 {
292  v.printFromC(os);
293  return os;
294 }
295 
296 
297 template<class T, int N>
300 {
301  return ElecDiagonalTensor<T,N>(a) += b;
302 }
303 
304 template<class T, int N>
307 {
308  return ElecDiagonalTensor<T,N>(a) -= b;
309 }
310 
311 template<class T, int N>
314 {
315  return -ElecDiagonalTensor<T,N>(a);
316 }
317 
318 template<class T, int N>
321 {
322  throw CException("no operator defined for diag * diag");
323 }
324 
325 template<class T, int N>
327 operator*(const T s, const ElecDiagonalTensor<T,N>& a)
328 {
329  return ElecDiagonalTensor<T,N>(a) *= s;
330 }
331 
332 template<class T, int N>
334 operator*(const ElecDiagonalTensor<T,N>& a, const T s)
335 {
336  return ElecDiagonalTensor<T,N>(a) *= s;
337 }
338 
339 template<class T, int N>
342 {
343  Vector<T,N+1> r;
344  r = 0;
345  for(int i=0; i<N; i++){
346  r[i] = a[i]*b[i]+a[N+i]*b[N];
347  }
348  for(int i=0; i<=N; i++)
349  r[N] += a[2*N+i]*b[i];
350 
351  return r;
352 }
353 
354 template<class T, int N>
356 operator/(const ElecDiagonalTensor<T,N>& a, const T s)
357 {
358  return ElecDiagonalTensor<T,N>(a) /= s;
359 }
360 
361 template<class T, int N>
364 {
365  //solve bx = a and return x
366  //rename Mx = v where M=b v=a
367  Vector<T,N+1> x;
368  Vector<T,N+1> v;
370  x = 0;
371  M = b;
372  v = a;
373 
374  //first step: eleminate M to upper diagonal
375  for(int i=0; i<N;i++){
376  if(M[2*N+i] !=0.0 && M[i] != 0.0){
377  M[3*N] -= M[N+i] * (M[2*N+i]/M[i]);
378  v[N] -= v[i] * (M[2*N+i]/M[i]);
379  }
380  }
381 
382  //second step: go backward to solve x
383  if (M[3*N] != 0.0)
384  x[N] = v[N] / M[3*N];
385  for(int i=0; i<N; i++){
386  if (M[i] != 0.0)
387  x[i] = (v[i] - M[N+i]*x[N]) / M[i];
388  }
389 
390  return x;
391 }
392 
393 
394 template<class T, int N>
397 {
398  throw CException("operator not defined for diag/diag");
399 }
400 
401 template<class T, int N>
403 operator/(const T s, const ElecDiagonalTensor<T,N>& a)
404 {
405  throw CException("operator not defined for s/diag");
406 }
407 
408 template<class T, int N>
410 {
411  throw CException("diag to offdiag not defined");
412 }
413 
414 
415 #endif
416 
417 
418 
419 
420 
421 
422 
423 
static void setMax(ElecDiagonalTensor &x, const ElecDiagonalTensor &y)
static ElecDiagonalTensor getUnity()
NumTypeTraits< T >::T_BuiltIn T_BuiltIn
ElecDiagonalTensor< T, N > operator/(const ElecDiagonalTensor< T, N > &a, const T s)
static void getShape(int *shp)
Definition: Vector.h:19
static void reduceSum(T_Scalar &sum, const This_T &x)
ElecDiagonalTensor< T, N > This_T
static int getDataSize()
NumTypeTraits< T >::T_Scalar T_Scalar
ElecDiagonalTensor & operator+=(const T s)
ElecDiagonalTensor & operator=(const ElecOffDiagonalTensor< T, N > &o)
ElecDiagonalTensor(const T &o)
ElecDiagonalTensor & operator-=(const ElecDiagonalTensor &o)
static void write(FILE *fp, const ElecDiagonalTensor &x)
ElecDiagonalTensor & operator*=(const T s)
ElecDiagonalTensor & operator/=(const ElecDiagonalTensor &o)
ElecDiagonalTensor & operator/=(const T s)
ElecDiagonalTensor< T, N > operator+(const ElecDiagonalTensor< T, N > &a, const ElecDiagonalTensor< T, N > &b)
ElecDiagonalTensor & operator+=(const ElecOffDiagonalTensor< T, N > &o)
void printFromC(ostream &os) const
ElecDiagonalTensor(const ElecDiagonalTensor &o)
T DiagToOffDiag(const ElecDiagonalTensor< T, N > &x)
static ElecDiagonalTensor getNegativeUnity()
ElecDiagonalTensor & operator=(const T &o)
static void normalize(ElecDiagonalTensor &x, const ElecDiagonalTensor &y)
ElecDiagonalTensor & operator+=(const ElecDiagonalTensor &o)
static void accumulateDotProduct(ElecDiagonalTensor &sum, const ElecDiagonalTensor &v0, const ElecDiagonalTensor &v1)
ElecDiagonalTensor & operator=(const ElecDiagonalTensor &o)
ElecDiagonalTensor & operator*=(const ElecDiagonalTensor &o)
ostream & operator<<(ostream &os, const ElecDiagonalTensor< T, N > &v)
string intAsString(const int i)
Definition: Vector.h:11
ElecDiagonalTensor & operator-=(const T s)
bool operator<(const double tolerance) const
static ElecDiagonalTensor getZero()
static void accumulateOneNorm(ElecDiagonalTensor &sum, const ElecDiagonalTensor &v)
ElecDiagonalTensor< T, N > operator*(const ElecDiagonalTensor< T, N > &a, const ElecDiagonalTensor< T, N > &b)
static double doubleMeasure(const ElecDiagonalTensor &x)
static void safeDivide(ElecDiagonalTensor &x, const ElecDiagonalTensor &y)
static int getDimension()
const T & operator[](int n) const
static string getTypeName()
ElecDiagonalTensor operator-()
ElecDiagonalTensor< T, N > operator-(const ElecDiagonalTensor< T, N > &a, const ElecDiagonalTensor< T, N > &b)