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