OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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"
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
36template<class T, unsigned D>
38{
39public:
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.
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
75 apply(*this,rhs);
76 }
77
78 // Construct from a Tenzor.
79 // Extract the symmetric part.
81 for (unsigned int i=0; i<D; ++i) {
82 (*this)(i,i) = t(i,i);
83 for (unsigned 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.
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 }
108 for (unsigned int i=0; i<D; ++i) {
109 (*this)(i,i) = rhs(i,i);
110 for (unsigned 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 (unsigned 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
272private:
273
274 // The elements themselves.
276
277};
278
279
281//
282// Free functions
283//
285
286template <class T, unsigned D>
287inline T trace(const SymTenzor<T,D> &rhs) {
288 T result = 0.0;
289 for (unsigned int i = 0 ; i < D ; i++ )
290 result += rhs(i,i);
291 return result;
292}
293
294template <class T, unsigned D>
296 return rhs;
297}
298
299// Determinant: only implement for 1D, 2D, 3D:
300template <class T, unsigned D>
301inline 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
306template <class T>
307inline 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
316template <class T>
317inline 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
323template <class T>
324inline 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
335template <class T, unsigned D>
336inline Tenzor<T,D> cofactors(const SymTenzor<T,D>& /*rhs*/) {
337 PInsist(D<4, "SymTenzor cofactors() function not implemented for D>3!");
338 return Tenzor<T,D>(-999999.999999);
339}
340
341template <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
357template <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:
370template <class T>
371inline Tenzor<T,1> cofactors(const SymTenzor<T,1>& /*rhs*/) {
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-
385template<class T, unsigned D>
387{
388 return TSV_MetaUnary< SymTenzor<T,D> , OpUnaryMinus > :: apply(op);
389}
390
391//----------------------------------------------------------------------
392// unary operator+
393template<class T, unsigned D>
395{
396 return op;
397}
398
400//
401// Binary Operators
402//
404
405//
406// Elementwise operators.
407//
408
415
424
425//----------------------------------------------------------------------
426// dot products.
427//----------------------------------------------------------------------
428
429template < class T1, class T2, unsigned D >
431dot(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
436template < class T1, class T2, unsigned D >
438dot(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
443template < class T1, class T2, unsigned D >
445dot(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
450template < class T1, class T2, unsigned D >
452dot(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
457template < class T1, class T2, unsigned D >
459dot(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
468template < class T1, class T2, unsigned D >
470dotdot(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
475template < class T1, class T2, unsigned D >
477dotdot(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
482template < class T1, class T2, unsigned D >
484dotdot(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
491template<class T, unsigned D>
492inline std::ostream& operator<<(std::ostream& out, const SymTenzor<T,D>& rhs) {
493 if (D >= 1) {
494 for (unsigned int i=0; i<D; i++) {
495 out << "(";
496 for (unsigned 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
std::complex< double > a
T trace(const SymTenzor< T, D > &rhs)
Definition: SymTenzor.h:287
SymTenzor< T, D > operator-(const SymTenzor< T, D > &op)
Definition: SymTenzor.h:386
Tenzor< T, D > cofactors(const SymTenzor< T, D > &)
Definition: SymTenzor.h:336
std::ostream & operator<<(std::ostream &out, const SymTenzor< T, D > &rhs)
Definition: SymTenzor.h:492
Tenzor< typename PETEBinaryReturn< T1, T2, OpMultipply >::type, D > dot(const SymTenzor< T1, D > &lhs, const SymTenzor< T2, D > &rhs)
Definition: SymTenzor.h:431
const SymTenzor< T, D > & operator+(const SymTenzor< T, D > &op)
Definition: SymTenzor.h:394
T det(const SymTenzor< T, D > &)
Definition: SymTenzor.h:301
SymTenzor< T, D > transpose(const SymTenzor< T, D > &rhs)
Definition: SymTenzor.h:295
PETEBinaryReturn< T1, T2, OpMultipply >::type dotdot(const SymTenzor< T1, D > &lhs, const SymTenzor< T2, D > &rhs)
Definition: SymTenzor.h:470
#define TSV_ELEMENTWISE_OPERATOR2(TSV1, TSV2, OP, APP)
Definition: TSVMeta.h:75
#define TSV_ELEMENTWISE_OPERATOR(TSV, OP, APP)
Definition: TSVMeta.h:58
#define PAssert_LT(a, b)
Definition: PAssert.h:106
#define PInsist(c, m)
Definition: PAssert.h:120
#define PAssert(c)
Definition: PAssert.h:102
#define PAssert_GE(a, b)
Definition: PAssert.h:109
double Min(double a, double b)
double Max(double a, double b)
Definition: Tenzor.h:35
SymTenzor(DontInitialize)
Definition: SymTenzor.h:52
bool operator!=(const SymTenzor< T, D > &that) const
Definition: SymTenzor.h:255
int len(void) const
Definition: SymTenzor.h:181
Element_t operator[](unsigned int i) const
Definition: SymTenzor.h:231
const SymTenzor< T, D > & operator=(const SymTenzor< T, D > &rhs)
Definition: SymTenzor.h:92
SymTenzor< T, D > & operator+=(const T &rhs)
Definition: SymTenzor.h:124
Message & getMessage(Message &m)
Definition: SymTenzor.h:267
SymTenzor(const T &x00)
Definition: SymTenzor.h:55
SymTenzor< T, D > & operator-=(const SymTenzor< T1, D > &rhs)
Definition: SymTenzor.h:132
void diagonal(const T &rhs)
Definition: SymTenzor.h:175
T X[Size]
Definition: SymTenzor.h:275
bool operator==(const SymTenzor< T, D > &that) const
Definition: SymTenzor.h:252
SymTenzor< T, D > & operator-=(const T &rhs)
Definition: SymTenzor.h:138
Element_t & operator()(unsigned int i)
Definition: SymTenzor.h:239
SymTenzor(const T &x00, const T &x10, const T &x11)
Definition: SymTenzor.h:60
int size(void) const
Definition: SymTenzor.h:182
T Element_t
Definition: SymTenzor.h:41
SymTenzor(const T &x00, const T &x10, const T &x11, const T &x20, const T &x21, const T &x22)
Definition: SymTenzor.h:65
int get_Size(void) const
Definition: SymTenzor.h:183
SymTenzor(const Tenzor< T, D > &t)
Definition: SymTenzor.h:80
SymTenzor(const SymTenzor< T, D > &rhs)
Definition: SymTenzor.h:73
SymTenzor< T, D > & operator+=(const SymTenzor< T1, D > &rhs)
Definition: SymTenzor.h:118
SymTenzor< T, D > & operator*=(const T &rhs)
Definition: SymTenzor.h:152
Message & putMessage(Message &m) const
Definition: SymTenzor.h:261
Element_t & operator()(unsigned int i, unsigned int j)
Definition: SymTenzor.h:193
Element_t HL(unsigned int hi, unsigned int lo) const
Definition: SymTenzor.h:215
Element_t & operator()(std::pair< int, int > a)
Definition: SymTenzor.h:199
Element_t operator()(unsigned int i, unsigned int j) const
Definition: SymTenzor.h:187
Element_t & HL(unsigned int hi, unsigned int lo)
Definition: SymTenzor.h:220
Element_t operator()(unsigned int i) const
Definition: SymTenzor.h:244
SymTenzor< T, D > & operator/=(const SymTenzor< T1, D > &rhs)
Definition: SymTenzor.h:160
Element_t & operator[](unsigned int i)
Definition: SymTenzor.h:226
SymTenzor< T, D > & operator/=(const T &rhs)
Definition: SymTenzor.h:166
SymTenzor< T, D > & operator*=(const SymTenzor< T1, D > &rhs)
Definition: SymTenzor.h:146
~SymTenzor()
Definition: SymTenzor.h:89
SymTenzor()
Definition: SymTenzor.h:46
Element_t operator()(std::pair< int, int > a) const
Definition: SymTenzor.h:207
Definition: Vektor.h:32
Message & setCopy(const bool c)
Definition: Message.h:319
PETE_ComputeBinaryType< T1, T2, Op, Op::tag >::type type