OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
AntiSymTenzor.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 ANTI_SYM_TENZOR_H
12 #define ANTI_SYM_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 #include "AppTypes/Tenzor.h"
20 
21 #include <iostream>
22 
23 
25 //
26 // Definition of class AntiSymTenzor.
27 //
29 
30 //
31 // | O -x10 -x20 |
32 // | x10 0 -x21 |
33 // | x20 x21 0 |
34 //
35 
36 template<class T, unsigned D>
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 {};
53 
54  // Construct an AntiSymTenzor from a single T.
55  // This doubles as the 2D AntiSymTenzor initializer.
56  AntiSymTenzor(const T& x00) {
58  }
59  // construct a 3D AntiSymTenzor
60  AntiSymTenzor(const T& x10, const T& x20, const T& x21) {
61  PInsist(D==3,
62  "Number of arguments does not match AntiSymTenzor dimension!!");
63  X[0]= x10; X[1]= x20; X[2]= x21;
64  }
65 
66  // Copy Constructor
69  apply(*this,rhs);
70  }
71 
72  // Construct from a Tenzor.
73  // Extract the antisymmetric part.
74  AntiSymTenzor( const Tenzor<T,D>& t ) {
75  for (int i=1; i<D; ++i) {
76  for (int j=0; j<i; ++j)
77  (*this)[((i-1)*i/2)+j] = (t(i,j)-t(j,i))*0.5;
78  }
79  }
80 
82 
83  // assignment operators
86  apply(*this,rhs);
87  return *this;
88  }
89  template<class T1>
92  apply(*this,rhs);
93  return *this;
94  }
95  const AntiSymTenzor<T,D>& operator= (const T& rhs) {
97  apply(*this,rhs);
98  return *this;
99  }
100 
101  // accumulation operators
102  template<class T1>
104  {
106  :: apply(*this,rhs);
107  return *this;
108  }
109 
110  template<class T1>
112  {
114  OpSubtractAssign > :: apply(*this,rhs);
115  return *this;
116  }
117 
118  template<class T1>
120  {
122  OpMultipplyAssign > :: apply(*this,rhs);
123  return *this;
124  }
126  {
128  apply(*this,rhs);
129  return *this;
130  }
131 
132  template<class T1>
134  {
136  OpDivideAssign > :: apply(*this,rhs);
137  return *this;
138  }
140  {
142  apply(*this,rhs);
143  return *this;
144  }
145 
146  // Methods
147 
148  int len(void) const { return Size; }
149  int size(void) const { return sizeof(*this); }
150  int get_Size(void) const { return Size; }
151 
152  class AssignProxy {
153  public:
155  : elem_m(elem), where_m(where) { }
156  AssignProxy(const AssignProxy &model)
157  : elem_m(model.elem_m), where_m(model.where_m) { }
159  {
160  PAssert_EQ(where_m != 0 || a.elem_m == -a.elem_m, true);
161  elem_m = where_m < 0 ? -a.elem_m : a.elem_m;
162  return *this;
163  }
165  {
166  PAssert_EQ(where_m != 0 || e == -e, true);
167  elem_m = where_m < 0 ? -e : e;
168  return *this;
169  }
170 
171  operator Element_t() const
172  {
173  return (where_m < 0 ? -elem_m : elem_m);
174  }
175 
176  private:
177 
179  int where_m;
180  };
181 
182  // Operators
183 
184  Element_t operator()(unsigned int i, unsigned int j) const {
185  if (i == j)
186  return T(0.0);
187  else if (i < j)
188  return -X[((j-1)*j/2) + i];
189  else
190  return X[((i-1)*i/2) + j];
191  }
192 
193  Element_t operator()( std::pair<int,int> a) const {
194  int i = a.first;
195  int j = a.second;
196  return (*this)(i, j);
197  }
198 
199  AssignProxy operator()(unsigned int i, unsigned int j) {
200  if (i == j)
202  else
203  {
204  int lo = i < j ? i : j;
205  int hi = i > j ? i : j;
206  return AssignProxy(X[((hi-1)*hi/2) + lo], i - j);
207  }
208  }
209 
210  AssignProxy operator()(std::pair<int,int> a) {
211  int i = a.first;
212  int j = a.second;
213  return (*this)(i, j);
214  }
215 
216  Element_t& operator[](unsigned int i) {
217  PAssert (i < Size);
218  return X[i];
219  }
220 
221  Element_t operator[](unsigned int i) const {
222  PAssert (i < Size);
223  return X[i];
224  }
225 
226  // These are the same as operator[] but with () instead:
227 
228  Element_t& operator()(unsigned int i) {
229  PAssert (i < Size);
230  return X[i];
231  }
232 
233  Element_t operator()(unsigned int i) const {
234  PAssert (i < Size);
235  return X[i];
236  }
237 
238  //----------------------------------------------------------------------
239  // Comparison operators.
240  bool operator==(const AntiSymTenzor<T,D>& that) const {
241  return TSV_MetaCompareArrays<T,T,D*(D-1)/2>::apply(X,that.X);
242  }
243  bool operator!=(const AntiSymTenzor<T,D>& that) const {
244  return !(*this == that);
245  }
246 
247  //----------------------------------------------------------------------
248  // parallel communication
250  m.setCopy(true);
251  ::putMessage(m, X, X + Size);
252  return m;
253  }
254 
256  ::getMessage(m, X, X + Size);
257  return m;
258  }
259 
260 private:
261 
262  friend class AssignProxy;
263 
264  // The elements themselves.
265  T X[Size];
266 
267  // A place to store a zero element.
268  // We need to return a reference to this
269  // for the diagonal element.
270  static T Zero;
271 };
272 
273 
274 // Assign the static zero element value:
275 template<class T, unsigned int D>
277 
278 
279 
281 // Specialization for 1D -- this is basically just the zero tensor
283 
284 template <class T>
285 class AntiSymTenzor<T,1>
286 {
287 public:
288 
289  typedef T Element_t;
290  enum { ElemDim = 2 };
291 
292  // Default Constructor
294 
295  // Copy Constructor
297 
298  // A noninitializing ctor.
299  class DontInitialize {};
300  AntiSymTenzor(DontInitialize) {}
301 
302  // Construct from a Tenzor: still a no-op here:
303  AntiSymTenzor( const Tenzor<T,1>& t ) { }
304 
306 
307  // assignment operators
309  return *this;
310  }
311  template <class T1>
313  return *this;
314  }
315  const AntiSymTenzor<T,1>& operator=(const T& rhs) {
316  PInsist(rhs==0, "Cannot assign non-zero value to a 1D AntiSymTenzor!");
317  return *this;
318  }
319 
320  // accumulation operators
321  template <class T1>
323  return *this;
324  }
325 
326  template <class T1>
328  return *this;
329  }
330 
331  template <class T1>
333  return *this;
334  }
336  return *this;
337  }
338 
339  template <class T1>
341  return *this;
342  }
344  return *this;
345  }
346 
347  // Methods
348 
349  int len(void) const { return Size; }
350  int size(void) const { return sizeof(*this); }
351  int get_Size(void) const { return Size; }
352 
353  class AssignProxy {
354  public:
356  : elem_m(elem), where_m(where) {}
357  AssignProxy(const AssignProxy& model)
358  : elem_m(model.elem_m), where_m(model.where_m) {}
360  {
361  PAssert_EQ(where_m != 0 || a.elem_m == -a.elem_m, true);
362  elem_m = where_m < 0 ? -a.elem_m : a.elem_m;
363  return *this;
364  }
366  {
367  PAssert_EQ(where_m != 0 || e == -e, true);
368  elem_m = where_m < 0 ? -e : e;
369  return *this;
370  }
371 
372  operator Element_t() const
373  {
374  return (where_m < 0 ? -elem_m : elem_m);
375  }
376 
377  private:
378 
380  int where_m;
381  };
382 
383  // Operators
384 
385  Element_t operator()(unsigned int i, unsigned int j) const {
386  PAssert_EQ(i, j);
387  return T(0.0);
388  }
389 
390  Element_t operator()( std::pair<int,int> a) const {
391  int i = a.first;
392  int j = a.second;
393  return (*this)(i, j);
394  }
395 
396  AssignProxy operator()(unsigned int i, unsigned int j) {
397  PAssert_EQ(i, j);
399  }
400 
401  AssignProxy operator()(std::pair<int,int> a) {
402  int i = a.first;
403  int j = a.second;
404  return (*this)(i, j);
405  }
406 
407  Element_t operator[](unsigned int i) const {
408  PAssert (i == 0);
410  }
411 
412  // These are the same as operator[] but with () instead:
413 
414  Element_t operator()(unsigned int i) const {
415  PAssert (i == 0);
417  }
418 
419  //----------------------------------------------------------------------
420  // Comparison operators.
421  bool operator==(const AntiSymTenzor<T,1>& that) const {
422  return true;
423  }
424  bool operator!=(const AntiSymTenzor<T,1>& that) const {
425  return !(*this == that);
426  }
427 
428  //----------------------------------------------------------------------
429  // parallel communication
431  m.setCopy(true);
433  return m;
434  }
435 
437  T zero;
438  m.get(zero);
439  return m;
440  }
441 
442 private:
443 
444  friend class AssignProxy;
445 
446  // The number of elements.
447  enum { Size = 0 };
448 
449  // A place to store a zero element.
450  // We need to return a reference to this
451  // for the diagonal element.
452  static T Zero;
453 };
454 
455 
456 // Assign the static zero element value:
457 template<class T>
459 
460 
461 
463 //
464 // Free functions
465 //
467 
468 template <class T, unsigned D>
469 inline T trace(const AntiSymTenzor<T,D>&) {
470  return T(0.0);
471 }
472 
473 template <class T, unsigned D>
475  return -rhs;
476 }
477 
478 // Determinant: only implement for 1D, 2D, 3D:
479 
480 // For D=3, det is zero, because diagonal elements are zero:
481 template<class T>
482 inline T
484 {
485  return T(0.0);
486 }
487 // For D=2, det is nonzero; use linear indexing of only stored element:
488 template<class T>
489 inline T
491 {
492  T result;
493  result = t(0)*t(0);
494  return result;
495 }
496 // For D=1, det is zero, because diagonal elements are zero:
497 template<class T>
498 inline T
500 {
501  return T(0.0);
502 }
503 
504 // cofactors() - pow(-1, i+j)*M(i,j), where M(i,j) is a minor of the tensor.
505 // See, for example, Arfken, Mathematical Methods for Physicists, 2nd Edition,
506 // p. 157 (the section where the determinant of a matrix is defined).
507 
508 // Only implement for 1D, 2D, 3D:
509 
510 template <class T, unsigned D>
512  PInsist(D<4, "AntiSymTenzor cofactors() function not implemented for D>3!");
513  return Tenzor<T,D>(-999999.999999);
514 }
515 
516 template <class T>
518 
519  Tenzor<T,3> result = typename Tenzor<T,3>::DontInitialize();
520 
521  result(0,0) = rhs(1,1)*rhs(2,2) - rhs(1,2)*rhs(2,1);
522  result(1,0) = rhs(0,2)*rhs(2,1) - rhs(0,1)*rhs(2,2);
523  result(2,0) = rhs(0,1)*rhs(1,2) - rhs(1,1)*rhs(0,2);
524  result(0,1) = rhs(2,0)*rhs(1,2) - rhs(1,0)*rhs(2,2);
525  result(1,1) = rhs(0,0)*rhs(2,2) - rhs(0,2)*rhs(2,0);
526  result(2,1) = rhs(1,0)*rhs(0,2) - rhs(0,0)*rhs(1,2);
527  result(0,2) = rhs(1,0)*rhs(2,1) - rhs(2,0)*rhs(1,1);
528  result(1,2) = rhs(0,1)*rhs(2,0) - rhs(0,0)*rhs(2,1);
529  result(2,2) = rhs(0,0)*rhs(1,1) - rhs(1,0)*rhs(0,1);
530  return result;
531 }
532 
533 template <class T>
535 
536  Tenzor<T,2> result = typename Tenzor<T,2>::DontInitialize();
537 
538  result(0,0) = rhs(1,1);
539  result(1,0) = -rhs(0,1);
540  result(0,1) = -rhs(1,0);
541  result(1,1) = rhs(0,0);
542  return result;
543 }
544 
545 // For D=1, cofactor is the unit tensor, because det = single tensor element
546 // value:
547 template <class T>
549  Tenzor<T,1> result = Tenzor<T,1>(1);
550  return result;
551 }
552 
553 
555 //
556 // Unary Operators
557 //
559 
560 //----------------------------------------------------------------------
561 // unary operator-
562 template<class T, unsigned D>
564 {
565  return TSV_MetaUnary< AntiSymTenzor<T,D> , OpUnaryMinus > :: apply(op);
566 }
567 
568 //----------------------------------------------------------------------
569 // unary operator+
570 template<class T, unsigned D>
572 {
573  return op;
574 }
575 
577 //
578 // Binary Operators
579 //
581 
582 //
583 // Elementwise operators.
584 //
585 
588 TSV_ELEMENTWISE_OPERATOR(AntiSymTenzor,operator*,OpMultipply)
589 TSV_ELEMENTWISE_OPERATOR(AntiSymTenzor,operator/,OpDivide)
590 TSV_ELEMENTWISE_OPERATOR(AntiSymTenzor,Min,FnMin)
591 TSV_ELEMENTWISE_OPERATOR(AntiSymTenzor,Max,FnMax)
592 
593 //----------------------------------------------------------------------
594 // dot products.
595 //----------------------------------------------------------------------
596 
597 template < class T1, class T2, unsigned D >
598 inline Tenzor<typename PETEBinaryReturn<T1,T2,OpMultipply>::type,D>
599 dot(const AntiSymTenzor<T1,D> &lhs, const AntiSymTenzor<T2,D> &rhs)
600 {
602  apply(lhs,rhs);
603 }
604 
605 template < class T1, class T2, unsigned D >
607 dot(const AntiSymTenzor<T1,D> &lhs, const Tenzor<T2,D> &rhs)
608 {
610  apply(Tenzor<T1,D>(lhs),rhs);
611 }
612 
613 template < class T1, class T2, unsigned D >
615 dot(const Tenzor<T1,D> &lhs, const AntiSymTenzor<T2,D> &rhs)
616 {
618  apply(lhs,Tenzor<T2,D>(rhs));
619 }
620 
621 template < class T1, class T2, unsigned D >
623 dot(const AntiSymTenzor<T1,D> &lhs, const SymTenzor<T2,D> &rhs)
624 {
626  apply(Tenzor<T1,D>(lhs),Tenzor<T2,D>(rhs));
627 }
628 
629 template < class T1, class T2, unsigned D >
631 dot(const SymTenzor<T1,D> &lhs, const AntiSymTenzor<T2,D> &rhs)
632 {
634  apply(Tenzor<T1,D>(lhs),Tenzor<T2,D>(rhs));
635 }
636 
637 template < class T1, class T2, unsigned D >
639 dot(const Vektor<T1,D> &lhs, const AntiSymTenzor<T2,D> &rhs)
640 {
641  return TSV_MetaDot< Vektor<T1,D> , AntiSymTenzor<T2,D> > :: apply(lhs,rhs);
642 }
643 
644 template < class T1, class T2, unsigned D >
646 dot(const AntiSymTenzor<T1,D> &lhs, const Vektor<T2,D> &rhs)
647 {
648  return TSV_MetaDot< AntiSymTenzor<T1,D> , Vektor<T2,D> > :: apply(lhs,rhs);
649 }
650 
651 //----------------------------------------------------------------------
652 // double dot products.
653 //----------------------------------------------------------------------
654 
655 template < class T1, class T2, unsigned D >
658 {
660  apply(lhs,rhs);
661 }
662 
663 template < class T1, class T2, unsigned D >
665 dotdot(const AntiSymTenzor<T1,D> &lhs, const Tenzor<T2,D> &rhs)
666 {
668  apply(Tenzor<T1,D>(lhs),rhs);
669 }
670 
671 template < class T1, class T2, unsigned D >
673 dotdot(const Tenzor<T1,D> &lhs, const AntiSymTenzor<T2,D> &rhs)
674 {
676  apply(lhs,Tenzor<T2,D>(rhs));
677 }
678 
679 template < class T1, class T2, unsigned D >
682 {
684  apply(Tenzor<T1,D>(lhs),Tenzor<T2,D>(rhs));
685 }
686 
687 template < class T1, class T2, unsigned D >
690 {
692  apply(Tenzor<T1,D>(lhs),Tenzor<T2,D>(rhs));
693 }
694 
695 //----------------------------------------------------------------------
696 // I/O
697 template<class T, unsigned D>
698 inline std::ostream& operator<<(std::ostream& out, const AntiSymTenzor<T,D>& rhs) {
699  if (D >= 1) {
700  for (int i=0; i<D; i++) {
701  out << "(";
702  for (int j=0; j<D-1; j++) {
703  out << rhs(i,j) << " , ";
704  }
705  out << rhs(i,D-1) << ")";
706  // I removed this. --TJW: if (i < D - 1) out << endl;
707  }
708  } else {
709  out << "( " << rhs(0,0) << " )";
710  }
711  return out;
712 }
713 
715 
716 #endif // ANTI_SYM_TENZOR_H
717 
718 /***************************************************************************
719  * $RCSfile: AntiSymTenzor.h,v $
720  * $Revision: 1.1.1.1 $
721  * IPPL_VERSION_ID: $Id: AntiSymTenzor.h,v 1.1.1.1 2003/01/23 07:40:24 adelmann Exp $
722  ***************************************************************************/
723 
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:275
int get_Size(void) const
Element_t operator()(unsigned int i) const
AssignProxy(Element_t &elem, int where)
AntiSymTenzor(const T &x00)
Definition: AntiSymTenzor.h:56
Element_t operator()(unsigned int i) const
constexpr double e
The value of .
Definition: Physics.h:40
Element_t operator()(std::pair< int, int > a) const
Element_t operator[](unsigned int i) const
AntiSymTenzor(const AntiSymTenzor< T, 1 > &)
Definition: TSVMeta.h:24
Definition: rbendmap.h:8
PETEBinaryReturn< T1, T2, OpMultipply >::type dotdot(const AntiSymTenzor< T1, D > &lhs, const AntiSymTenzor< T2, D > &rhs)
friend class AssignProxy
bool operator==(const AntiSymTenzor< T, 1 > &that) const
T det(const AntiSymTenzor< T, 3 > &t)
AntiSymTenzor(const T &x10, const T &x20, const T &x21)
Definition: AntiSymTenzor.h:60
const AssignProxy & operator=(const AssignProxy &a)
int len(void) const
AntiSymTenzor< T, D > transpose(const AntiSymTenzor< T, D > &rhs)
AssignProxy operator()(std::pair< int, int > a)
AssignProxy operator()(unsigned int i, unsigned int j)
AntiSymTenzor< T, 1 > & operator/=(const T &)
AntiSymTenzor< T, 1 > & operator+=(const AntiSymTenzor< T1, 1 > &)
Message & putMessage(Message &m) const
AssignProxy operator()(std::pair< int, int > a)
AntiSymTenzor< T, D > & operator-=(const AntiSymTenzor< T1, D > &rhs)
AssignProxy(Element_t &elem, int where)
Element_t operator()(unsigned int i, unsigned int j) const
const AssignProxy & operator=(const AssignProxy &a)
int len(void) const
Element_t operator()(unsigned int i, unsigned int j) const
AntiSymTenzor< T, 1 > & operator/=(const AntiSymTenzor< T1, 1 > &)
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 AssignProxy & operator=(const Element_t &e)
int size(void) const
Element_t operator()(std::pair< int, int > a) const
AntiSymTenzor< T, D > & operator+=(const AntiSymTenzor< T1, D > &rhs)
Element_t & operator[](unsigned int i)
#define PAssert_EQ(a, b)
Definition: PAssert.h:119
const AntiSymTenzor< T, D > & operator=(const AntiSymTenzor< T, D > &rhs)
Definition: AntiSymTenzor.h:84
AntiSymTenzor(const AntiSymTenzor< T, D > &rhs)
Definition: AntiSymTenzor.h:67
double Max(double a, double b)
const AntiSymTenzor< T, 1 > & operator=(const AntiSymTenzor< T, 1 > &)
const AntiSymTenzor< T, 1 > & operator=(const T &rhs)
const AntiSymTenzor< T, 1 > & operator=(const AntiSymTenzor< T1, 1 > &)
AssignProxy(const AssignProxy &model)
PETE_TTTree< OpWhere, typename Cond_t::PETE_Expr_t, typename True_t::PETE_Expr_t, PETE_Scalar< Vektor< T, Dim > > > where(const PETE_Expr< Cond_t > &c, const PETE_Expr< True_t > &t, const Vektor< T, Dim > &f)
Element_t & operator()(unsigned int i)
bool operator!=(const AntiSymTenzor< T, 1 > &that) const
AntiSymTenzor< T, D > & operator/=(const AntiSymTenzor< T1, D > &rhs)
bool operator==(const AntiSymTenzor< T, D > &that) const
Message & putMessage(Message &m) const
Message & get(const T &cval)
Definition: Message.h:484
int get_Size(void) const
Message & put(const T &val)
Definition: Message.h:414
AntiSymTenzor(DontInitialize)
Definition: AntiSymTenzor.h:52
double Min(double a, double b)
PETE_ComputeBinaryType< PETE_Type2Index< T1 >::val, PETE_Type2Index< T2 >::val, Op::tag >::type type
Message & getMessage(Message &m)
AntiSymTenzor< T, 1 > & operator*=(const T &)
BOOST_UBLAS_INLINE V trace(ublas::matrix< V > &e)
Computes the trace of a square matrix.
const AssignProxy & operator=(const Element_t &e)
AntiSymTenzor(const Tenzor< T, 1 > &t)
AntiSymTenzor< T, D > & operator*=(const T &rhs)
AntiSymTenzor< T, D > & operator*=(const AntiSymTenzor< T1, D > &rhs)
AntiSymTenzor< T, 1 > & operator*=(const AntiSymTenzor< T1, 1 > &)
AssignProxy operator()(unsigned int i, unsigned int j)
#define PAssert(c)
Definition: PAssert.h:117
int size(void) const
AntiSymTenzor< T, D > & operator/=(const T &rhs)
AssignProxy(const AssignProxy &model)
Message & getMessage(Message &m)
#define PInsist(c, m)
Definition: PAssert.h:135
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:282
#define TSV_ELEMENTWISE_OPERATOR(TSV, OP, APP)
Definition: TSVMeta.h:58
bool operator!=(const AntiSymTenzor< T, D > &that) const
Element_t operator[](unsigned int i) const
AntiSymTenzor< T, 1 > & operator-=(const AntiSymTenzor< T1, 1 > &)
Message & setCopy(const bool c)
Definition: Message.h:327
AntiSymTenzor(const Tenzor< T, D > &t)
Definition: AntiSymTenzor.h:74
AntiSymTenzor(DontInitialize)