OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
AntiSymTenzor.h
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * The IPPL Framework
4  *
5  ***************************************************************************/
6 
7 #ifndef ANTI_SYM_TENZOR_H
8 #define ANTI_SYM_TENZOR_H
9 
10 // include files
11 #include "Utility/PAssert.h"
12 #include "Message/Message.h"
13 #include "PETE/IpplExpressions.h"
14 #include "AppTypes/TSVMeta.h"
15 #include "AppTypes/Tenzor.h"
16 
17 #include <iostream>
18 
19 
21 //
22 // Definition of class AntiSymTenzor.
23 //
25 
26 //
27 // | O -x10 -x20 |
28 // | x10 0 -x21 |
29 // | x20 x21 0 |
30 //
31 
32 template<class T, unsigned D>
34 {
35 public:
36 
37  typedef T Element_t;
38  enum { ElemDim = 2 };
39  enum { Size = D*(D-1)/2 };
40 
41  // Default Constructor
44  }
45 
46  // A noninitializing ctor.
47  class DontInitialize {};
49 
50  // Construct an AntiSymTenzor from a single T.
51  // This doubles as the 2D AntiSymTenzor initializer.
52  AntiSymTenzor(const T& x00) {
54  }
55  // construct a 3D AntiSymTenzor
56  AntiSymTenzor(const T& x10, const T& x20, const T& x21) {
57  PInsist(D==3,
58  "Number of arguments does not match AntiSymTenzor dimension!!");
59  X[0]= x10; X[1]= x20; X[2]= x21;
60  }
61 
62  // Copy Constructor
65  apply(*this,rhs);
66  }
67 
68  // Construct from a Tenzor.
69  // Extract the antisymmetric part.
70  AntiSymTenzor( const Tenzor<T,D>& t ) {
71  for (unsigned int i=1; i<D; ++i) {
72  for (unsigned int j=0; j<i; ++j)
73  (*this)[((i-1)*i/2)+j] = (t(i,j)-t(j,i))*0.5;
74  }
75  }
76 
78 
79  // assignment operators
82  apply(*this,rhs);
83  return *this;
84  }
85  template<class T1>
88  apply(*this,rhs);
89  return *this;
90  }
91  const AntiSymTenzor<T,D>& operator= (const T& rhs) {
93  apply(*this,rhs);
94  return *this;
95  }
96 
97  // accumulation operators
98  template<class T1>
100  {
102  :: apply(*this,rhs);
103  return *this;
104  }
105 
106  template<class T1>
108  {
110  OpSubtractAssign > :: apply(*this,rhs);
111  return *this;
112  }
113 
114  template<class T1>
116  {
118  OpMultipplyAssign > :: apply(*this,rhs);
119  return *this;
120  }
122  {
124  apply(*this,rhs);
125  return *this;
126  }
127 
128  template<class T1>
130  {
132  OpDivideAssign > :: apply(*this,rhs);
133  return *this;
134  }
136  {
138  apply(*this,rhs);
139  return *this;
140  }
141 
142  // Methods
143 
144  int len(void) const { return Size; }
145  int size(void) const { return sizeof(*this); }
146  int get_Size(void) const { return Size; }
147 
148  class AssignProxy {
149  public:
151  : elem_m(elem), where_m(where) { }
152  AssignProxy(const AssignProxy &model)
153  : elem_m(model.elem_m), where_m(model.where_m) { }
155  {
156  PAssert_EQ(where_m != 0 || (a.elem_m == -a.elem_m), true);
157  elem_m = where_m < 0 ? -a.elem_m : a.elem_m;
158  return *this;
159  }
161  {
162  PAssert_EQ(where_m != 0 || (e == -e), true);
163  elem_m = where_m < 0 ? -e : e;
164  return *this;
165  }
166 
167  operator Element_t() const
168  {
169  return (where_m < 0 ? -elem_m : elem_m);
170  }
171 
172  private:
173 
175  int where_m;
176  };
177 
178  // Operators
179 
180  Element_t operator()(unsigned int i, unsigned int j) const {
181  if (i == j)
182  return T(0.0);
183  else if (i < j)
184  return -X[((j-1)*j/2) + i];
185  else
186  return X[((i-1)*i/2) + j];
187  }
188 
189  Element_t operator()( std::pair<int,int> a) const {
190  int i = a.first;
191  int j = a.second;
192  return (*this)(i, j);
193  }
194 
195  AssignProxy operator()(unsigned int i, unsigned int j) {
196  if (i == j)
198  else
199  {
200  int lo = i < j ? i : j;
201  int hi = i > j ? i : j;
202  return AssignProxy(X[((hi-1)*hi/2) + lo], i - j);
203  }
204  }
205 
206  AssignProxy operator()(std::pair<int,int> a) {
207  int i = a.first;
208  int j = a.second;
209  return (*this)(i, j);
210  }
211 
212  Element_t& operator[](unsigned int i) {
213  PAssert (i < Size);
214  return X[i];
215  }
216 
217  Element_t operator[](unsigned int i) const {
218  PAssert (i < Size);
219  return X[i];
220  }
221 
222  // These are the same as operator[] but with () instead:
223 
224  Element_t& operator()(unsigned int i) {
225  PAssert (i < Size);
226  return X[i];
227  }
228 
229  Element_t operator()(unsigned int i) const {
230  PAssert (i < Size);
231  return X[i];
232  }
233 
234  //----------------------------------------------------------------------
235  // Comparison operators.
236  bool operator==(const AntiSymTenzor<T,D>& that) const {
237  return TSV_MetaCompareArrays<T,T,D*(D-1)/2>::apply(X,that.X);
238  }
239  bool operator!=(const AntiSymTenzor<T,D>& that) const {
240  return !(*this == that);
241  }
242 
243  //----------------------------------------------------------------------
244  // parallel communication
246  m.setCopy(true);
247  ::putMessage(m, X, X + Size);
248  return m;
249  }
250 
252  ::getMessage(m, X, X + Size);
253  return m;
254  }
255 
256 private:
257 
258  friend class AssignProxy;
259 
260  // The elements themselves.
261  T X[Size];
262 
263  // A place to store a zero element.
264  // We need to return a reference to this
265  // for the diagonal element.
266  static T Zero;
267 };
268 
269 
270 // Assign the static zero element value:
271 template<class T, unsigned int D>
273 
274 
275 
277 // Specialization for 1D -- this is basically just the zero tensor
279 
280 template <class T>
281 class AntiSymTenzor<T,1>
282 {
283 public:
284 
285  typedef T Element_t;
286  enum { ElemDim = 2 };
287 
288  // Default Constructor
290 
291  // Copy Constructor
293 
294  // A noninitializing ctor.
295  class DontInitialize {};
296  AntiSymTenzor(DontInitialize) {}
297 
298  // Construct from a Tenzor: still a no-op here:
299  AntiSymTenzor( const Tenzor<T,1>& /*t*/) { }
300 
302 
303  // assignment operators
305  return *this;
306  }
307  template <class T1>
309  return *this;
310  }
311  const AntiSymTenzor<T,1>& operator=(const T& rhs) {
312  PInsist(rhs==0, "Cannot assign non-zero value to a 1D AntiSymTenzor!");
313  return *this;
314  }
315 
316  // accumulation operators
317  template <class T1>
319  return *this;
320  }
321 
322  template <class T1>
324  return *this;
325  }
326 
327  template <class T1>
329  return *this;
330  }
332  return *this;
333  }
334 
335  template <class T1>
337  return *this;
338  }
340  return *this;
341  }
342 
343  // Methods
344 
345  int len(void) const { return Size; }
346  int size(void) const { return sizeof(*this); }
347  int get_Size(void) const { return Size; }
348 
349  class AssignProxy {
350  public:
352  : elem_m(elem), where_m(where) {}
353  AssignProxy(const AssignProxy& model)
354  : elem_m(model.elem_m), where_m(model.where_m) {}
356  {
357  PAssert_EQ(where_m != 0 || (a.elem_m == -a.elem_m), true);
358  elem_m = where_m < 0 ? -a.elem_m : a.elem_m;
359  return *this;
360  }
362  {
363  PAssert_EQ(where_m != 0 || (e == -e), true);
364  elem_m = where_m < 0 ? -e : e;
365  return *this;
366  }
367 
368  operator Element_t() const
369  {
370  return (where_m < 0 ? -elem_m : elem_m);
371  }
372 
373  private:
374 
376  int where_m;
377  };
378 
379  // Operators
380 
381  Element_t operator()(unsigned int i, unsigned int j) const {
382  // PAssert and PAssert_EQ are macros. They are defined empty, if we
383  // compile for production. i and j are unused in this case. The
384  // following statement suppress the 'unused' warning.
385  (void)i; (void)j;
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  (void)i; (void)j;
398  PAssert_EQ(i, j);
400  }
401 
402  AssignProxy operator()(std::pair<int,int> a) {
403  int i = a.first;
404  int j = a.second;
405  return (*this)(i, j);
406  }
407 
408  Element_t operator[](unsigned int i) const {
409  (void)i;
410  PAssert (i == 0);
412  }
413 
414  // These are the same as operator[] but with () instead:
415 
416  Element_t operator()(unsigned int i) const {
417  (void)i;
418  PAssert (i == 0);
420  }
421 
422  //----------------------------------------------------------------------
423  // Comparison operators.
424  bool operator==(const AntiSymTenzor<T,1>& /*that*/) const {
425  return true;
426  }
427  bool operator!=(const AntiSymTenzor<T,1>& that) const {
428  return !(*this == that);
429  }
430 
431  //----------------------------------------------------------------------
432  // parallel communication
434  m.setCopy(true);
436  return m;
437  }
438 
440  T zero{};
441  m.get(zero);
442  return m;
443  }
444 
445 private:
446 
447  friend class AssignProxy;
448 
449  // The number of elements.
450  enum { Size = 0 };
451 
452  // A place to store a zero element.
453  // We need to return a reference to this
454  // for the diagonal element.
455  static T Zero;
456 };
457 
458 
459 // Assign the static zero element value:
460 template<class T>
462 
463 
464 
466 //
467 // Free functions
468 //
470 
471 template <class T, unsigned D>
472 inline T trace(const AntiSymTenzor<T,D>&) {
473  return T(0.0);
474 }
475 
476 template <class T, unsigned D>
478  return -rhs;
479 }
480 
481 // Determinant: only implement for 1D, 2D, 3D:
482 
483 // For D=3, det is zero, because diagonal elements are zero:
484 template<class T>
485 inline T
486 det(const AntiSymTenzor<T,3>& /*t*/)
487 {
488  return T(0.0);
489 }
490 // For D=2, det is nonzero; use linear indexing of only stored element:
491 template<class T>
492 inline T
494 {
495  T result;
496  result = t(0)*t(0);
497  return result;
498 }
499 // For D=1, det is zero, because diagonal elements are zero:
500 template<class T>
501 inline T
502 det(const AntiSymTenzor<T,1>& /*t*/)
503 {
504  return T(0.0);
505 }
506 
507 // cofactors() - pow(-1, i+j)*M(i,j), where M(i,j) is a minor of the tensor.
508 // See, for example, Arfken, Mathematical Methods for Physicists, 2nd Edition,
509 // p. 157 (the section where the determinant of a matrix is defined).
510 
511 // Only implement for 1D, 2D, 3D:
512 
513 template <class T, unsigned D>
514 inline Tenzor<T,D> cofactors(const AntiSymTenzor<T,D>& /*rhs*/) {
515  PInsist(D<4, "AntiSymTenzor cofactors() function not implemented for D>3!");
516  return Tenzor<T,D>(-999999.999999);
517 }
518 
519 template <class T>
521 
523 
524  result(0,0) = rhs(1,1)*rhs(2,2) - rhs(1,2)*rhs(2,1);
525  result(1,0) = rhs(0,2)*rhs(2,1) - rhs(0,1)*rhs(2,2);
526  result(2,0) = rhs(0,1)*rhs(1,2) - rhs(1,1)*rhs(0,2);
527  result(0,1) = rhs(2,0)*rhs(1,2) - rhs(1,0)*rhs(2,2);
528  result(1,1) = rhs(0,0)*rhs(2,2) - rhs(0,2)*rhs(2,0);
529  result(2,1) = rhs(1,0)*rhs(0,2) - rhs(0,0)*rhs(1,2);
530  result(0,2) = rhs(1,0)*rhs(2,1) - rhs(2,0)*rhs(1,1);
531  result(1,2) = rhs(0,1)*rhs(2,0) - rhs(0,0)*rhs(2,1);
532  result(2,2) = rhs(0,0)*rhs(1,1) - rhs(1,0)*rhs(0,1);
533  return result;
534 }
535 
536 template <class T>
538 
540 
541  result(0,0) = rhs(1,1);
542  result(1,0) = -rhs(0,1);
543  result(0,1) = -rhs(1,0);
544  result(1,1) = rhs(0,0);
545  return result;
546 }
547 
548 // For D=1, cofactor is the unit tensor, because det = single tensor element
549 // value:
550 template <class T>
551 inline Tenzor<T,1> cofactors(const AntiSymTenzor<T,1>& /*rhs*/) {
553  return result;
554 }
555 
556 
558 //
559 // Unary Operators
560 //
562 
563 //----------------------------------------------------------------------
564 // unary operator-
565 template<class T, unsigned D>
567 {
568  return TSV_MetaUnary< AntiSymTenzor<T,D> , OpUnaryMinus > :: apply(op);
569 }
570 
571 //----------------------------------------------------------------------
572 // unary operator+
573 template<class T, unsigned D>
575 {
576  return op;
577 }
578 
580 //
581 // Binary Operators
582 //
584 
585 //
586 // Elementwise operators.
587 //
588 
591 TSV_ELEMENTWISE_OPERATOR(AntiSymTenzor,operator*,OpMultipply)
592 TSV_ELEMENTWISE_OPERATOR(AntiSymTenzor,operator/,OpDivide)
593 TSV_ELEMENTWISE_OPERATOR(AntiSymTenzor,Min,FnMin)
594 TSV_ELEMENTWISE_OPERATOR(AntiSymTenzor,Max,FnMax)
595 
596 //----------------------------------------------------------------------
597 // dot products.
598 //----------------------------------------------------------------------
599 
600 template < class T1, class T2, unsigned D >
601 inline Tenzor<typename PETEBinaryReturn<T1,T2,OpMultipply>::type,D>
602 dot(const AntiSymTenzor<T1,D> &lhs, const AntiSymTenzor<T2,D> &rhs)
603 {
605  apply(lhs,rhs);
606 }
607 
608 template < class T1, class T2, unsigned D >
610 dot(const AntiSymTenzor<T1,D> &lhs, const Tenzor<T2,D> &rhs)
611 {
613  apply(Tenzor<T1,D>(lhs),rhs);
614 }
615 
616 template < class T1, class T2, unsigned D >
618 dot(const Tenzor<T1,D> &lhs, const AntiSymTenzor<T2,D> &rhs)
619 {
621  apply(lhs,Tenzor<T2,D>(rhs));
622 }
623 
624 template < class T1, class T2, unsigned D >
626 dot(const AntiSymTenzor<T1,D> &lhs, const SymTenzor<T2,D> &rhs)
627 {
629  apply(Tenzor<T1,D>(lhs),Tenzor<T2,D>(rhs));
630 }
631 
632 template < class T1, class T2, unsigned D >
634 dot(const SymTenzor<T1,D> &lhs, const AntiSymTenzor<T2,D> &rhs)
635 {
637  apply(Tenzor<T1,D>(lhs),Tenzor<T2,D>(rhs));
638 }
639 
640 template < class T1, class T2, unsigned D >
642 dot(const Vektor<T1,D> &lhs, const AntiSymTenzor<T2,D> &rhs)
643 {
644  return TSV_MetaDot< Vektor<T1,D> , AntiSymTenzor<T2,D> > :: apply(lhs,rhs);
645 }
646 
647 template < class T1, class T2, unsigned D >
649 dot(const AntiSymTenzor<T1,D> &lhs, const Vektor<T2,D> &rhs)
650 {
651  return TSV_MetaDot< AntiSymTenzor<T1,D> , Vektor<T2,D> > :: apply(lhs,rhs);
652 }
653 
654 //----------------------------------------------------------------------
655 // double dot products.
656 //----------------------------------------------------------------------
657 
658 template < class T1, class T2, unsigned D >
661 {
663  apply(lhs,rhs);
664 }
665 
666 template < class T1, class T2, unsigned D >
668 dotdot(const AntiSymTenzor<T1,D> &lhs, const Tenzor<T2,D> &rhs)
669 {
671  apply(Tenzor<T1,D>(lhs),rhs);
672 }
673 
674 template < class T1, class T2, unsigned D >
676 dotdot(const Tenzor<T1,D> &lhs, const AntiSymTenzor<T2,D> &rhs)
677 {
679  apply(lhs,Tenzor<T2,D>(rhs));
680 }
681 
682 template < class T1, class T2, unsigned D >
685 {
687  apply(Tenzor<T1,D>(lhs),Tenzor<T2,D>(rhs));
688 }
689 
690 template < class T1, class T2, unsigned D >
693 {
695  apply(Tenzor<T1,D>(lhs),Tenzor<T2,D>(rhs));
696 }
697 
698 //----------------------------------------------------------------------
699 // I/O
700 template<class T, unsigned D>
701 inline std::ostream& operator<<(std::ostream& out, const AntiSymTenzor<T,D>& rhs) {
702  if (D >= 1) {
703  for (unsigned int i=0; i<D; i++) {
704  out << "(";
705  for (unsigned int j=0; j<D-1; j++) {
706  out << rhs(i,j) << " , ";
707  }
708  out << rhs(i,D-1) << ")";
709  // I removed this. --TJW: if (i < D - 1) out << endl;
710  }
711  } else {
712  out << "( " << rhs(0,0) << " )";
713  }
714  return out;
715 }
716 
718 
719 #endif // ANTI_SYM_TENZOR_H
#define PAssert_EQ(a, b)
Definition: PAssert.h:104
Message & put(const T &val)
Definition: Message.h:406
AntiSymTenzor(const Tenzor< T, D > &t)
Definition: AntiSymTenzor.h:70
AntiSymTenzor(const T &x10, const T &x20, const T &x21)
Definition: AntiSymTenzor.h:56
const AssignProxy & operator=(const Element_t &e)
AntiSymTenzor(DontInitialize)
int len(void) const
T det(const AntiSymTenzor< T, 3 > &)
AssignProxy operator()(std::pair< int, int > a)
AssignProxy operator()(unsigned int i, unsigned int j)
AntiSymTenzor< T, 1 > & operator/=(const T &)
#define TSV_ELEMENTWISE_OPERATOR(TSV, OP, APP)
Definition: TSVMeta.h:58
Message & putMessage(Message &m) const
double Min(double a, double b)
const AssignProxy & operator=(const AssignProxy &a)
Element_t operator()(std::pair< int, int > a) const
Element_t operator[](unsigned int i) const
AntiSymTenzor(const AntiSymTenzor< T, 1 > &)
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:283
int len(void) const
friend class AssignProxy
Definition: TSVMeta.h:24
BOOST_UBLAS_INLINE V trace(ublas::matrix< V > &e)
Computes the trace of a square matrix.
AssignProxy(const AssignProxy &model)
Tenzor< T, D > cofactors(const AntiSymTenzor< T, D > &)
AntiSymTenzor< T, D > transpose(const AntiSymTenzor< T, D > &rhs)
const AssignProxy & operator=(const AssignProxy &a)
int size(void) const
PETE_ComputeBinaryType< T1, T2, Op, Op::tag >::type type
Element_t operator()(std::pair< int, int > a) const
Message & get(const T &cval)
Definition: Message.h:476
AntiSymTenzor< T, 1 > & operator+=(const AntiSymTenzor< T1, 1 > &)
PETEBinaryReturn< T1, T2, OpMultipply >::type dotdot(const AntiSymTenzor< T1, D > &lhs, const AntiSymTenzor< T2, D > &rhs)
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special the source code distributed need not include anything that is normally and so on of the operating system on which the executable unless that component itself accompanies the executable If distribution of executable or object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place counts as distribution of the source even though third parties are not compelled to copy the source along with the object code You may not or distribute the Program except as expressly provided under this License Any attempt otherwise to sublicense or distribute the Program is void
Definition: LICENSE:162
AntiSymTenzor(const Tenzor< T, 1 > &)
const AssignProxy & operator=(const Element_t &e)
AssignProxy(Element_t &elem, int where)
AssignProxy operator()(std::pair< int, int > a)
AntiSymTenzor< T, D > & operator-=(const AntiSymTenzor< T1, D > &rhs)
Element_t operator()(unsigned int i, unsigned int j) const
Element_t operator()(unsigned int i, unsigned int j) const
const AntiSymTenzor< T, 1 > & operator=(const T &rhs)
AntiSymTenzor< T, 1 > & operator/=(const AntiSymTenzor< T1, 1 > &)
Message & setCopy(const bool c)
Definition: Message.h:319
Element_t & operator()(unsigned int i)
double Max(double a, double b)
AntiSymTenzor< T, D > & operator+=(const AntiSymTenzor< T1, D > &rhs)
Definition: AntiSymTenzor.h:99
bool operator==(const AntiSymTenzor< T, D > &that) const
Element_t & operator[](unsigned int i)
const AntiSymTenzor< T, D > & operator=(const AntiSymTenzor< T, D > &rhs)
Definition: AntiSymTenzor.h:80
Message & putMessage(Message &m) const
AntiSymTenzor(const AntiSymTenzor< T, D > &rhs)
Definition: AntiSymTenzor.h:63
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:276
Message & getMessage(Message &m)
const AntiSymTenzor< T, 1 > & operator=(const AntiSymTenzor< T, 1 > &)
const AntiSymTenzor< T, 1 > & operator=(const AntiSymTenzor< T1, 1 > &)
#define PInsist(c, m)
Definition: PAssert.h:120
float result
Definition: test.py:2
AntiSymTenzor< T, D > & operator*=(const AntiSymTenzor< T1, D > &rhs)
bool operator!=(const AntiSymTenzor< T, 1 > &that) const
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)
AssignProxy(Element_t &elem, int where)
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)
int size(void) const
bool operator==(const AntiSymTenzor< T, 1 > &) const
int get_Size(void) const
AntiSymTenzor(DontInitialize)
Definition: AntiSymTenzor.h:48
Definition: Tenzor.h:34
constexpr double e
The value of .
Definition: Physics.h:39
Element_t operator[](unsigned int i) const
AntiSymTenzor< T, 1 > & operator-=(const AntiSymTenzor< T1, 1 > &)
#define PAssert(c)
Definition: PAssert.h:102
AntiSymTenzor< T, 1 > & operator*=(const T &)
AntiSymTenzor< T, D > & operator*=(const T &rhs)
AssignProxy(const AssignProxy &model)
int get_Size(void) const
AntiSymTenzor< T, D > & operator/=(const T &rhs)
Element_t operator()(unsigned int i) const
SDDS1 &description type
Definition: test.stat:4
Message & getMessage(Message &m)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
AntiSymTenzor(const T &x00)
Definition: AntiSymTenzor.h:52
Element_t operator()(unsigned int i) const
bool operator!=(const AntiSymTenzor< T, D > &that) const