OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Tenzor.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  *
7  * Visit http://people.web.psi.ch/adelmann/ for more details
8  *
9  ***************************************************************************/
10 
11 #ifndef TENZOR_H
12 #define TENZOR_H
13 
14 // include files
15 #include "Utility/PAssert.h"
16 #include "Message/Message.h"
17 #include "PETE/IpplExpressions.h"
18 #include "AppTypes/TSVMeta.h"
19 
20 #include <iostream>
21 
22 // forward declarations
23 template <class T, unsigned D> class SymTenzor;
24 template <class T, unsigned D> class AntiSymTenzor;
25 
26 
28 //
29 // Definition of class Tenzor.
30 //
32 
33 template<class T, unsigned D>
34 class Tenzor
35 {
36 public:
37 
38  typedef T Element_t;
39  enum { ElemDim = 2 };
40  enum { Size = D*D };
41 
42  // Default Constructor
43  Tenzor() {
44  TSV_MetaAssignScalar<Tenzor<T,D>,T,OpAssign>::apply(*this,T(0));
45  }
46 
47  // A noninitializing ctor.
48  class DontInitialize {};
49  Tenzor(DontInitialize) {}
50 
51  // Copy Constructor
52  Tenzor(const Tenzor<T,D> &rhs) {
53  TSV_MetaAssign< Tenzor<T,D> , Tenzor<T,D> ,OpAssign >::apply(*this,rhs);
54  }
55 
56  // constructor from a single T
57  Tenzor(const T& x00) {
58  TSV_MetaAssignScalar< Tenzor<T,D> , T ,OpAssign >::apply(*this,x00);
59  }
60 
61  // constructors for fixed dimension
62  Tenzor(const T& x00, const T& x10, const T& x01, const T& x11) {
63  PInsist(D==2, "Number of arguments does not match Tenzor dimension!!");
64  X[0] = x00;
65  X[1] = x10;
66  X[2] = x01;
67  X[3] = x11;
68  }
69  Tenzor(const T& x00, const T& x10, const T& x20, const T& x01, const T& x11,
70  const T& x21, const T& x02, const T& x12, const T& x22) {
71  PInsist(D==3, "Number of arguments does not match Tenzor dimension!!");
72  X[0] = x00;
73  X[1] = x10;
74  X[2] = x20;
75  X[3] = x01;
76  X[4] = x11;
77  X[5] = x21;
78  X[6] = x02;
79  X[7] = x12;
80  X[8] = x22;
81  }
82 
83  // constructor from SymTenzor
84  Tenzor(const SymTenzor<T,D>&);
85 
86  // constructor from AntiSymTenzor
87  Tenzor(const AntiSymTenzor<T,D>&);
88 
89  // destructor
90  ~Tenzor() { };
91 
92  // assignment operators
93  const Tenzor<T,D>& operator= (const Tenzor<T,D> &rhs) {
94  TSV_MetaAssign< Tenzor<T,D> , Tenzor<T,D> ,OpAssign> :: apply(*this,rhs);
95  return *this;
96  }
97  template<class T1>
98  const Tenzor<T,D>& operator= (const Tenzor<T1,D> &rhs) {
99  TSV_MetaAssign< Tenzor<T,D> , Tenzor<T1,D> ,OpAssign> :: apply(*this,rhs);
100  return *this;
101  }
102  const Tenzor<T,D>& operator= (const T& rhs) {
103  TSV_MetaAssignScalar< Tenzor<T,D> , T ,OpAssign> :: apply(*this,rhs);
104  return *this;
105  }
106 
107  // accumulation operators
108  template<class T1>
110  {
112  apply(*this,rhs);
113  return *this;
114  }
115  Tenzor<T,D>& operator+=(const T& rhs)
116  {
118  apply(*this,rhs);
119  return *this;
120  }
121 
122  template<class T1>
124  {
126  apply(*this,rhs);
127  return *this;
128  }
129  Tenzor<T,D>& operator-=(const T& rhs)
130  {
132  apply(*this,rhs);
133  return *this;
134  }
135 
136  template<class T1>
138  {
140  apply(*this,rhs);
141  return *this;
142  }
143  Tenzor<T,D>& operator*=(const T& rhs)
144  {
146  apply(*this,rhs);
147  return *this;
148  }
149 
150  template<class T1>
152  {
154  apply(*this,rhs);
155  return *this;
156  }
157  Tenzor<T,D>& operator/=(const T& rhs)
158  {
160  apply(*this,rhs);
161  return *this;
162  }
163 
164  // Methods
165 
166  void diagonal(const T& rhs) {
167  for (unsigned int i = 0 ; i < D ; i++ )
168  (*this)(i,i) = rhs;
169  }
170 
171  int len(void) const { return Size; }
172  int size(void) const { return sizeof(*this); }
173 
174  // Operators
175 
176  Element_t &operator[]( unsigned int i )
177  {
178  PAssert_LT(i, Size);
179  return X[i];
180  }
181 
182  Element_t operator[]( unsigned int i ) const
183  {
184  PAssert_LT(i, Size);
185  return X[i];
186  }
187 
188  //TJW: add these 12/16/97 to help with NegReflectAndZeroFace BC:
189  // These are the same as operator[] but with () instead:
190 
191  Element_t& operator()(unsigned int i) {
192  PAssert (i < Size);
193  return X[i];
194  }
195 
196  Element_t operator()(unsigned int i) const {
197  PAssert (i < Size);
198  return X[i];
199  }
200  //TJW.
201 
202  Element_t operator()( unsigned int i, unsigned int j ) const {
203  PAssert ( (i<D) && (j<D) );
204  return X[i*D+j];
205  }
206 
207  Element_t& operator()( unsigned int i, unsigned int j ) {
208  PAssert ( (i<D) && (j<D) );
209  return X[i*D+j];
210  }
211 
212  Element_t operator()(const std::pair<int,int> i) const {
213  PAssert ( (i.first>=0) && (i.second>=0) && (i.first<D) && (i.second<D) );
214  return (*this)(i.first,i.second);
215  }
216 
217  Element_t& operator()(const std::pair<int,int> i) {
218  PAssert ( (i.first>=0) && (i.second>=0) && (i.first<D) && (i.second<D) );
219  return (*this)(i.first,i.second);
220  }
221 
222 
223  //----------------------------------------------------------------------
224  // Comparison operators.
225  bool operator==(const Tenzor<T,D>& that) const {
227  }
228  bool operator!=(const Tenzor<T,D>& that) const {
229  return !(*this == that);
230  }
231 
232  //----------------------------------------------------------------------
233  // parallel communication
235  m.setCopy(true);
236  const T *p = X;
237  ::putMessage(m, p, p + D*D);
238  return m;
239  }
240 
242  T *p = X;
243  ::getMessage(m, p, p + D*D);
244  return m;
245  }
246 
247 private:
248 
249  // The elements themselves.
250  T X[Size];
251 
252 };
253 
254 
256 //
257 // Free functions
258 //
260 
261 // trace() - sum of diagonal elements.
262 
263 template <class T, unsigned D>
264 inline T trace(const Tenzor<T,D>& rhs) {
265  T result = 0.0;
266  for (unsigned int i = 0 ; i < D ; i++ )
267  result += rhs(i,i);
268  return result;
269 }
270 
271 // transpose(). transpose(i,j) = input(j,i).
272 
273 template <class T, unsigned D>
274 inline Tenzor<T,D> transpose(const Tenzor<T,D>& rhs) {
275  Tenzor<T,D> result = typename Tenzor<T,D>::DontInitialize();
276 
277  for (unsigned int j = 0 ; j < D ; j++ )
278  for (unsigned int i = 0 ; i < D ; i++ )
279  result(i,j) = rhs(j,i);
280  return result;
281 }
282 
283 // Determinant: only implement for 1D, 2D, 3D:
284 
285 template <class T, unsigned D>
286 inline T det(const Tenzor<T,D>& rhs) {
287  PInsist(D<4, "Tenzor det() function not implemented for D>3!");
288  return T(-999999.999999);
289 }
290 
291 template <class T>
292 inline T det(const Tenzor<T,3>& rhs) {
293  T result;
294  result =
295  rhs(0,0)*(rhs(1,1)*rhs(2,2) - rhs(1,2)*rhs(2,1)) +
296  rhs(0,1)*(rhs(1,2)*rhs(2,0) - rhs(1,0)*rhs(2,2)) +
297  rhs(0,2)*(rhs(1,0)*rhs(2,1) - rhs(1,1)*rhs(2,0));
298  return result;
299 }
300 
301 template <class T>
302 inline T det(const Tenzor<T,2>& rhs) {
303  T result;
304  result = rhs(0,0)*rhs(1,1) - rhs(0,1)*rhs(1,0);
305  return result;
306 }
307 
308 template <class T>
309 inline T det(const Tenzor<T,1>& rhs) {
310  T result = rhs(0,0);
311  return result;
312 }
313 
314 // cofactors() - pow(-1, i+j)*M(i,j), where M(i,j) is a minor of the tensor.
315 // See, for example, Arfken, Mathematical Methods for Physicists, 2nd Edition,
316 // p. 157 (the section where the determinant of a matrix is defined).
317 
318 // Only implement for 1D, 2D, 3D:
319 
320 template <class T, unsigned D>
321 inline Tenzor<T,D> cofactors(const Tenzor<T,D>& rhs) {
322  PInsist(D<4, "Tenzor cofactors() function not implemented for D>3!");
323  return Tenzor<T,D>(-999999.999999);
324 }
325 
326 template <class T>
327 inline Tenzor<T,3> cofactors(const Tenzor<T,3>& rhs) {
328  Tenzor<T,3> result = typename Tenzor<T,3>::DontInitialize();
329 
330  result(0,0) = rhs(1,1)*rhs(2,2) - rhs(1,2)*rhs(2,1);
331  result(1,0) = rhs(0,2)*rhs(2,1) - rhs(0,1)*rhs(2,2);
332  result(2,0) = rhs(0,1)*rhs(1,2) - rhs(1,1)*rhs(0,2);
333  result(0,1) = rhs(2,0)*rhs(1,2) - rhs(1,0)*rhs(2,2);
334  result(1,1) = rhs(0,0)*rhs(2,2) - rhs(0,2)*rhs(2,0);
335  result(2,1) = rhs(1,0)*rhs(0,2) - rhs(0,0)*rhs(1,2);
336  result(0,2) = rhs(1,0)*rhs(2,1) - rhs(2,0)*rhs(1,1);
337  result(1,2) = rhs(0,1)*rhs(2,0) - rhs(0,0)*rhs(2,1);
338  result(2,2) = rhs(0,0)*rhs(1,1) - rhs(1,0)*rhs(0,1);
339  return result;
340 }
341 
342 template <class T>
343 inline Tenzor<T,2> cofactors(const Tenzor<T,2>& rhs) {
344  Tenzor<T,2> result = typename Tenzor<T,2>::DontInitialize();
345 
346  result(0,0) = rhs(1,1);
347  result(1,0) = -rhs(0,1);
348  result(0,1) = -rhs(1,0);
349  result(1,1) = rhs(0,0);
350  return result;
351 }
352 
353 // For D=1, cofactor is the unit tensor, because det = single tensor element
354 // value:
355 template <class T>
356 inline Tenzor<T,1> cofactors(const Tenzor<T,1>& rhs) {
357  Tenzor<T,1> result = Tenzor<T,1>(1);
358  return result;
359 }
360 
361 
363 //
364 // Unary Operators
365 //
367 
368 //----------------------------------------------------------------------
369 // unary operator-
370 template<class T, unsigned D>
372 {
373  return TSV_MetaUnary< Tenzor<T,D> , OpUnaryMinus > :: apply(op);
374 }
375 
376 //----------------------------------------------------------------------
377 // unary operator+
378 template<class T, unsigned D>
379 inline const Tenzor<T,D> &operator+(const Tenzor<T,D> &op)
380 {
381  return op;
382 }
383 
385 //
386 // Binary Operators
387 //
389 
390 //
391 // Elementwise operators.
392 //
393 
396 TSV_ELEMENTWISE_OPERATOR(Tenzor,operator*,OpMultipply)
397 TSV_ELEMENTWISE_OPERATOR(Tenzor,operator/,OpDivide)
400 
401 //----------------------------------------------------------------------
402 // dot products.
403 //----------------------------------------------------------------------
404 
405 template < class T1, class T2, unsigned D >
406 inline Tenzor<typename PETEBinaryReturn<T1,T2,OpMultipply>::type,D>
407 dot(const Tenzor<T1,D> &lhs, const Tenzor<T2,D> &rhs)
408 {
409  return TSV_MetaDot< Tenzor<T1,D> , Tenzor<T2,D> > :: apply(lhs,rhs);
410 }
411 
412 template < class T1, class T2, unsigned D >
414 dot(const Vektor<T1,D> &lhs, const Tenzor<T2,D> &rhs)
415 {
416  return TSV_MetaDot< Vektor<T1,D> , Tenzor<T2,D> > :: apply(lhs,rhs);
417 }
418 
419 template < class T1, class T2, unsigned D >
421 dot(const Tenzor<T1,D> &lhs, const Vektor<T2,D> &rhs)
422 {
423  return TSV_MetaDot< Tenzor<T1,D> , Vektor<T2,D> > :: apply(lhs,rhs);
424 }
425 
426 //----------------------------------------------------------------------
427 // double dot product.
428 //----------------------------------------------------------------------
429 
430 template < class T1, class T2, unsigned D >
432 dotdot(const Tenzor<T1,D> &lhs, const Tenzor<T2,D> &rhs)
433 {
434  return TSV_MetaDotDot< Tenzor<T1,D> , Tenzor<T2,D> > :: apply(lhs,rhs);
435 }
436 
437 //----------------------------------------------------------------------
438 // Outer product.
439 //----------------------------------------------------------------------
440 
441 template<class T1, class T2, unsigned int D>
444 {
445  typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
447 
448  for (unsigned int i=0; i<D; ++i)
449  for (unsigned int j=0; j<D; ++j)
450  ret(i,j) = v1[i]*v2[j];
451  return ret;
452 }
453 
454 //----------------------------------------------------------------------
455 // I/O
456 template<class T, unsigned D>
457 inline std::ostream& operator<<(std::ostream& out, const Tenzor<T,D>& rhs)
458 {
459  if (D >= 1) {
460  for (unsigned int i=0; i<D; i++) {
461  out << "(";
462  for (unsigned int j=0; j<D-1; j++) {
463  out << rhs(i,j) << " , ";
464  }
465  out << rhs(i,D-1) << ")";
466  // I removed this. --TJW: if (i < D - 1) out << endl;
467  }
468  } else {
469  out << "( " << rhs(0,0) << " )";
470  }
471  return out;
472 }
473 
474 // include header files for SymTenzor and AntiSymTenzor in order
475 // to define constructors for Tenzor using these types
476 #include "AppTypes/SymTenzor.h"
477 #include "AppTypes/AntiSymTenzor.h"
478 
479 template <class T, unsigned D>
481  for (unsigned int i=0; i<D; ++i)
482  for (unsigned int j=0; j<D; ++j)
483  (*this)(i,j) = rhs(i,j);
484 }
485 
486 template <class T, unsigned D>
488  for (unsigned int i=0; i<D; ++i)
489  for (unsigned int j=0; j<D; ++j)
490  (*this)(i,j) = rhs(i,j);
491 }
492 
493 
494 #endif // TENZOR_H
495 
496 /***************************************************************************
497  * $RCSfile: Tenzor.h,v $ $Author: adelmann $
498  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:24 $
499  * IPPL_VERSION_ID: $Id: Tenzor.h,v 1.1.1.1 2003/01/23 07:40:24 adelmann Exp $
500  ***************************************************************************/
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:275
int len(void) const
Definition: Tenzor.h:171
int size(void) const
Definition: Tenzor.h:172
Tenzor< T, D > & operator-=(const T &rhs)
Definition: Tenzor.h:129
Definition: TSVMeta.h:24
Definition: rbendmap.h:8
PETEBinaryReturn< T1, T2, OpMultipply >::type dotdot(const AntiSymTenzor< T1, D > &lhs, const AntiSymTenzor< T2, D > &rhs)
T det(const AntiSymTenzor< T, 3 > &t)
Tenzor(DontInitialize)
Definition: Tenzor.h:49
AntiSymTenzor< T, D > transpose(const AntiSymTenzor< T, D > &rhs)
bool operator==(const Tenzor< T, D > &that) const
Definition: Tenzor.h:225
Tenzor< T, D > & operator+=(const T &rhs)
Definition: Tenzor.h:115
Element_t & operator()(unsigned int i, unsigned int j)
Definition: Tenzor.h:207
Tenzor(const T &x00, const T &x10, const T &x20, const T &x01, const T &x11, const T &x21, const T &x02, const T &x12, const T &x22)
Definition: Tenzor.h:69
Tenzor< T, D > & operator-=(const Tenzor< T1, D > &rhs)
Definition: Tenzor.h:123
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
Tenzor< T, D > cofactors(const AntiSymTenzor< T, D > &rhs)
const Tenzor< T, D > & operator=(const Tenzor< T, D > &rhs)
Definition: Tenzor.h:93
#define PAssert_LT(a, b)
Definition: PAssert.h:121
T Element_t
Definition: Tenzor.h:38
Element_t operator[](unsigned int i) const
Definition: Tenzor.h:182
Tenzor(const Tenzor< T, D > &rhs)
Definition: Tenzor.h:52
double Max(double a, double b)
Tenzor< T, D > & operator*=(const T &rhs)
Definition: Tenzor.h:143
Tenzor< T, D > & operator/=(const T &rhs)
Definition: Tenzor.h:157
Element_t & operator()(unsigned int i)
Definition: Tenzor.h:191
static bool apply(const T1 *lhs, const T2 *rhs)
void diagonal(const T &rhs)
Definition: Tenzor.h:166
T X[Size]
Definition: Tenzor.h:250
double Min(double a, double b)
PETE_ComputeBinaryType< PETE_Type2Index< T1 >::val, PETE_Type2Index< T2 >::val, Op::tag >::type type
Tenzor(const T &x00, const T &x10, const T &x01, const T &x11)
Definition: Tenzor.h:62
Element_t operator()(const std::pair< int, int > i) const
Definition: Tenzor.h:212
BOOST_UBLAS_INLINE V trace(ublas::matrix< V > &e)
Computes the trace of a square matrix.
Element_t operator()(unsigned int i) const
Definition: Tenzor.h:196
Element_t & operator()(const std::pair< int, int > i)
Definition: Tenzor.h:217
~Tenzor()
Definition: Tenzor.h:90
Tenzor< typename PETEBinaryReturn< T1, T2, OpMultipply >::type, D > outerProduct(const Vektor< T1, D > &v1, const Vektor< T2, D > &v2)
Definition: Tenzor.h:443
Message & getMessage(Message &m)
Definition: Tenzor.h:241
#define PAssert(c)
Definition: PAssert.h:117
Tenzor()
Definition: Tenzor.h:43
Message & putMessage(Message &m) const
Definition: Tenzor.h:234
#define PInsist(c, m)
Definition: PAssert.h:135
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:282
Tenzor< T, D > & operator*=(const Tenzor< T1, D > &rhs)
Definition: Tenzor.h:137
bool operator!=(const Tenzor< T, D > &that) const
Definition: Tenzor.h:228
#define TSV_ELEMENTWISE_OPERATOR(TSV, OP, APP)
Definition: TSVMeta.h:58
Tenzor< T, D > & operator+=(const Tenzor< T1, D > &rhs)
Definition: Tenzor.h:109
Message & setCopy(const bool c)
Definition: Message.h:327
Element_t operator()(unsigned int i, unsigned int j) const
Definition: Tenzor.h:202
Tenzor< T, D > & operator/=(const Tenzor< T1, D > &rhs)
Definition: Tenzor.h:151
Element_t & operator[](unsigned int i)
Definition: Tenzor.h:176
Tenzor(const T &x00)
Definition: Tenzor.h:57