QMCPACK
SymTensor.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 //
9 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #ifndef SYM_TENZOR_H
14 #define SYM_TENZOR_H
15 /***************************************************************************
16  *
17  * The POOMA Framework
18  *
19  * This program was prepared by the Regents of the University of
20  * California at Los Alamos National Laboratory (the University) under
21  * Contract No. W-7405-ENG-36 with the U.S. Department of Energy (DOE).
22  * The University has certain rights in the program pursuant to the
23  * contract and the program should not be copied or distributed outside
24  * your organization. All rights in the program are reserved by the DOE
25  * and the University. Neither the U.S. Government nor the University
26  * makes any warranty, express or implied, or assumes any liability or
27  * responsibility for the use of this software
28  *
29  * Visit http://www.acl.lanl.gov/POOMA for more details
30  *
31  ***************************************************************************/
32 
33 
34 // include files
35 //#include "Message/Message.h"
36 #include "PETE/PETE.h"
38 #include "OhmmsPETE/Tensor.h"
39 
40 #include <iostream>
41 
42 namespace qmcplusplus
43 {
44 //////////////////////////////////////////////////////////////////////
45 //
46 // Definition of class SymTensor.
47 //
48 //////////////////////////////////////////////////////////////////////
49 
50 //
51 // | xOO x10 x20 |
52 // | x10 x11 x21 |
53 // | x20 x21 x22 |
54 //
55 
56 template<class T, unsigned D>
57 class SymTensor
58 {
59 public:
60  using Type_t = T;
61  enum
62  {
63  ElemDim = 2
64  };
65  enum
66  {
67  Size = D * (D + 1) / 2
68  };
69 
70  // Default Constructor
71  SymTensor() { OTAssign<SymTensor<T, D>, T, OpAssign>::apply(*this, T(0), OpAssign()); }
72 
73  // A noninitializing ctor.
75  {};
76  SymTensor(DontInitialize) {}
77 
78  // construct a SymTensor from a single T
79  SymTensor(const T& x00) { OTAssign<SymTensor<T, D>, T, OpAssign>::apply(*this, x00, OpAssign()); }
80 
81  // construct a 2D SymTensor
82  SymTensor(const T& x00, const T& x10, const T& x11)
83  {
84  X[0] = x00;
85  X[1] = x10;
86  X[2] = x11;
87  }
88  // construct a 3D SymTensor
89  SymTensor(const T& x00, const T& x10, const T& x11, const T& x20, const T& x21, const T& x22)
90  {
91  X[0] = x00;
92  X[1] = x10;
93  X[2] = x11;
94  X[3] = x20;
95  X[4] = x21;
96  X[5] = x22;
97  }
98 
99  // Copy Constructor
100  template<typename T1>
102  {
104  }
105 
106  // Construct from a Tensor.
107  // Extract the symmetric part.
109  {
110  for (int i = 0; i < D; ++i)
111  {
112  (*this)(i, i) = t(i, i);
113  for (int j = i + 1; j < D; ++j)
114  (*this)(i, j) = (t(i, j) + t(j, i)) * 0.5;
115  }
116  }
117 
118  // Dtor doesn't need to do anything.
120 
121  // assignment operators
123  {
125  return *this;
126  }
127  template<class T1>
129  {
131  return *this;
132  }
133  SymTensor<T, D>& operator=(const T& rhs)
134  {
135  OTAssign<SymTensor<T, D>, T, OpAssign>::apply(*this, rhs, OpAssign());
136  return *this;
137  }
139  {
140  for (int i = 0; i < D; ++i)
141  {
142  (*this)(i, i) = rhs(i, i);
143  for (int j = i + 1; j < D; ++j)
144  (*this)(i, j) = (rhs(i, j) + rhs(j, i)) * 0.5;
145  }
146  return *this;
147  }
148 
149  // accumulation operators
150  template<class T1>
152  {
154  return *this;
155  }
157  {
158  OTAssign<SymTensor<T, D>, T, OpAddAssign>::apply(*this, rhs, OpAddAssign());
159  return *this;
160  }
161 
162  template<class T1>
164  {
166  return *this;
167  }
169  {
171  return *this;
172  }
173 
174  template<class T1>
176  {
178  return *this;
179  }
181  {
183  return *this;
184  }
185 
186  template<class T1>
188  {
190  return *this;
191  }
193  {
194  OTAssign<SymTensor<T, D>, T, OpDivideAssign>::apply(*this, rhs, OpDivideAssign());
195  return *this;
196  }
197 
198  // Methods
199  void diagonal(const T& rhs)
200  {
201  for (int i = 0; i < D; i++)
202  {
203  X[((i + 1) * i / 2) + i] = rhs;
204  }
205  }
206 
207  int len(void) const { return Size; }
208  int size(void) const { return sizeof(*this); }
209  int get_Size(void) const { return Size; }
210 
211  // Operators
212 
213  Type_t operator()(unsigned int i, unsigned int j) const
214  {
215  int lo = i < j ? i : j;
216  int hi = i > j ? i : j;
217  return X[((hi + 1) * hi / 2) + lo];
218  }
219 
220  Type_t& operator()(unsigned int i, unsigned int j)
221  {
222  int lo = i < j ? i : j;
223  int hi = i > j ? i : j;
224  return X[((hi + 1) * hi / 2) + lo];
225  }
226 
227  // Type_t& operator()(std::pair<int,int> a) {
228  // int i = a.first;
229  // int j = a.second;
230  // int lo = i < j ? i : j;
231  // int hi = i > j ? i : j;
232  // return X[((hi+1)*hi/2) + lo];
233  // }
234 
235  // Type_t operator()( std::pair<int,int> a) const {
236  // int i = a.first;
237  // int j = a.second;
238  // int lo = i < j ? i : j;
239  // int hi = i > j ? i : j;
240  // return X[((hi+1)*hi/2) + lo];
241  // }
242 
243  Type_t HL(unsigned int hi, unsigned int lo) const
244  {
245  PAssert(hi >= lo);
246  PAssert(hi < D);
247  PAssert(lo < D);
248  return X[hi * (hi + 1) / 2 + lo];
249  }
250  Type_t& HL(unsigned int hi, unsigned int lo)
251  {
252  PAssert(hi >= lo);
253  PAssert(hi < D);
254  PAssert(lo < D);
255  return X[hi * (hi + 1) / 2 + lo];
256  }
257 
258  Type_t& operator[](unsigned int i)
259  {
260  PAssert(i < Size);
261  return X[i];
262  }
263 
264  Type_t operator[](unsigned int i) const
265  {
266  PAssert(i < Size);
267  return X[i];
268  }
269 
270  //TJW: add these 12/16/97 to help with NegReflectAndZeroFace BC:
271  // These are the same as operator[] but with () instead:
272 
273  Type_t& operator()(unsigned int i)
274  {
275  PAssert(i < Size);
276  return X[i];
277  }
278 
279  Type_t operator()(unsigned int i) const
280  {
281  PAssert(i < Size);
282  return X[i];
283  }
284  //TJW.
285 
286  // //----------------------------------------------------------------------
287  // // Comparison operators.
288  // bool operator==(const SymTensor<T,D>& that) const {
289  // return MetaCompareArrays<T,T,D*(D+1)/2>::apply(X,that.X);
290  // }
291  // bool operator!=(const SymTensor<T,D>& that) const {
292  // return !(*this == that);
293  // }
294 
295  // //----------------------------------------------------------------------
296  // // parallel communication
297  // Message& putMessage(Message& m) const {
298  // m.setCopy(true);
299  // ::putMessage(m, X, X + ((D*(D + 1)/2)));
300  // return m;
301  // }
302 
303  // Message& getMessage(Message& m) {
304  // ::getMessage(m, X, X + ((D*(D + 1)/2)));
305  // return m;
306  // }
307 
308 private:
309  // The elements themselves.
310  T X[Size];
311 };
312 
313 
314 //////////////////////////////////////////////////////////////////////
315 //
316 // Free functions
317 //
318 //////////////////////////////////////////////////////////////////////
319 
320 template<class T, unsigned D>
321 T trace(const SymTensor<T, D>& rhs)
322 {
323  T result = 0.0;
324  for (int i = 0; i < D; i++)
325  result += rhs(i, i);
326  return result;
327 }
328 
329 template<class T, unsigned D>
331 {
332  return rhs;
333 }
334 
335 //////////////////////////////////////////////////////////////////////
336 //
337 // Unary Operators
338 //
339 //////////////////////////////////////////////////////////////////////
340 
341 //----------------------------------------------------------------------
342 // unary operator-
343 //template<class T, unsigned D>
344 //inline SymTensor<T,D> operator-(const SymTensor<T,D> &op)
345 //{
346 // return MetaUnary< SymTensor<T,D> , OpUnaryMinus > :: apply(op,OpUnaryMinus());
347 //}
348 
349 //----------------------------------------------------------------------
350 // unary operator+
351 //template<class T, unsigned D>
352 //inline const SymTensor<T,D> &operator+(const SymTensor<T,D> &op)
353 //{
354 // return op;
355 //}
356 
357 //////////////////////////////////////////////////////////////////////
358 //
359 // Binary Operators
360 //
361 //////////////////////////////////////////////////////////////////////
362 
363 //
364 // Elementwise operators.
365 //
366 
367 OHMMS_META_BINARY_OPERATORS(SymTensor, operator+, OpAdd)
368 OHMMS_META_BINARY_OPERATORS(SymTensor, operator-, OpSubtract)
369 OHMMS_META_BINARY_OPERATORS(SymTensor, operator*, OpMultiply)
370 OHMMS_META_BINARY_OPERATORS(SymTensor, operator/, OpDivide)
371 
372 /*
373 TSV_ELEMENTWISE_OPERATOR2(SymTensor,Tensor,operator+,OpAdd)
374 TSV_ELEMENTWISE_OPERATOR2(Tensor,SymTensor,operator+,OpAdd)
375 TSV_ELEMENTWISE_OPERATOR2(SymTensor,Tensor,operator-,OpSubtract)
376 TSV_ELEMENTWISE_OPERATOR2(Tensor,SymTensor,operator-,OpSubtract)
377 TSV_ELEMENTWISE_OPERATOR2(SymTensor,Tensor,operator*,OpMultiply)
378 TSV_ELEMENTWISE_OPERATOR2(Tensor,SymTensor,operator*,OpMultiply)
379 TSV_ELEMENTWISE_OPERATOR2(SymTensor,Tensor,operator/,OpDivide)
380 TSV_ELEMENTWISE_OPERATOR2(Tensor,SymTensor,operator/,OpDivide)
381 */
382 
383 //----------------------------------------------------------------------
384 // dot products.
385 //----------------------------------------------------------------------
386 
387 template<class T1, class T2, unsigned D>
389  const SymTensor<T2, D>& rhs)
390 {
391  return OTDot<SymTensor<T1, D>, SymTensor<T2, D>>::apply(lhs, rhs);
392 }
393 
394 template<class T1, class T2, unsigned D>
396  const Tensor<T2, D>& rhs)
397 {
398  return OTDot<SymTensor<T1, D>, Tensor<T2, D>>::apply(lhs, rhs);
399 }
400 
401 template<class T1, class T2, unsigned D>
403  const SymTensor<T2, D>& rhs)
404 {
405  return OTDot<Tensor<T1, D>, SymTensor<T2, D>>::apply(lhs, rhs);
406 }
407 
408 template<class T1, class T2, unsigned D>
410  const SymTensor<T2, D>& rhs)
411 {
412  return OTDot<TinyVector<T1, D>, SymTensor<T2, D>>::apply(lhs, rhs);
413 }
414 
415 template<class T1, class T2, unsigned D>
417  const TinyVector<T2, D>& rhs)
418 {
419  return OTDot<SymTensor<T1, D>, TinyVector<T2, D>>::apply(lhs, rhs);
420 }
421 
422 //----------------------------------------------------------------------
423 // double dot products.
424 //----------------------------------------------------------------------
425 
426 //template < class T1, class T2, unsigned D >
427 //inline typename BinaryReturn<T1,T2,OpMultiply>::Type_t
428 //dotdot(const SymTensor<T1,D> &lhs, const SymTensor<T2,D> &rhs)
429 //{
430 // return MetaDotDot< SymTensor<T1,D> , SymTensor<T2,D> > :: apply(lhs,rhs);
431 //}
432 //
433 //template < class T1, class T2, unsigned D >
434 //inline typename BinaryReturn<T1,T2,OpMultiply>::Type_t
435 //dotdot(const SymTensor<T1,D> &lhs, const Tensor<T2,D> &rhs)
436 //{
437 // return MetaDotDot< SymTensor<T1,D> , Tensor<T2,D> > :: apply(lhs,rhs);
438 //}
439 //
440 //template < class T1, class T2, unsigned D >
441 //inline typename BinaryReturn<T1,T2,OpMultiply>::Type_t
442 //dotdot(const Tensor<T1,D> &lhs, const SymTensor<T2,D> &rhs)
443 //{
444 // return MetaDotDot< Tensor<T1,D> , SymTensor<T2,D> > :: apply(lhs,rhs);
445 //}
446 //----------------------------------------------------------------------
447 // I/O
448 template<class T, unsigned D>
449 std::ostream& operator<<(std::ostream& out, const SymTensor<T, D>& rhs)
450 {
451  if (D >= 1)
452  {
453  for (int i = 0; i < D; i++)
454  {
455  for (int j = 0; j < D - 1; j++)
456  {
457  out << rhs(i, j) << " ";
458  }
459  out << rhs(i, D - 1) << " ";
460  if (i < D - 1)
461  out << std::endl;
462  }
463  }
464  else
465  {
466  out << " " << rhs(0, 0) << " ";
467  }
468  return out;
469 }
470 
471 } // namespace qmcplusplus
472 #endif // SYM_TENZOR_H
#define PAssert(condition)
Definition: OhmmsTinyMeta.h:61
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
SymTensor< T, D > & operator*=(const T &rhs)
Definition: SymTensor.h:180
Type_t & HL(unsigned int hi, unsigned int lo)
Definition: SymTensor.h:250
SymTensor< T, D > & operator-=(const T &rhs)
Definition: SymTensor.h:168
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
Type_t operator()(unsigned int i, unsigned int j) const
Definition: SymTensor.h:213
Type_t operator[](unsigned int i) const
Definition: SymTensor.h:264
SymTensor< T, D > & operator-=(const SymTensor< T1, D > &rhs)
Definition: SymTensor.h:163
SymTensor< T, D > & operator/=(const SymTensor< T1, D > &rhs)
Definition: SymTensor.h:187
int size(void) const
Definition: SymTensor.h:208
SymTensor< T, D > & operator=(const T &rhs)
Definition: SymTensor.h:133
SymTensor< T, D > & operator=(const SymTensor< T1, D > &rhs)
Definition: SymTensor.h:128
SymTensor(const Tensor< T, D > &t)
Definition: SymTensor.h:108
SymTensor(const SymTensor< T1, D > &rhs)
Definition: SymTensor.h:101
Type_t & operator()(unsigned int i, unsigned int j)
Definition: SymTensor.h:220
SymTensor(const T &x00, const T &x10, const T &x11)
Definition: SymTensor.h:82
SymTensor< T, D > & operator+=(const SymTensor< T1, D > &rhs)
Definition: SymTensor.h:151
SymTensor< T, D > & operator=(const Tensor< T, D > &rhs)
Definition: SymTensor.h:138
void diagonal(const T &rhs)
Definition: SymTensor.h:199
Tensor<T,D> class for D by D tensor.
Definition: OhmmsTinyMeta.h:32
Type_t & operator()(unsigned int i)
Definition: SymTensor.h:273
SymTensor(DontInitialize)
Definition: SymTensor.h:76
SymTensor< T, D > & operator*=(const SymTensor< T1, D > &rhs)
Definition: SymTensor.h:175
#define OHMMS_META_BINARY_OPERATORS(TENT, FUNC, TAG)
Definition: OhmmsTinyMeta.h:75
SymTensor< T, D > & operator=(const SymTensor< T, D > &rhs)
Definition: SymTensor.h:122
AntiSymTensor< T, D > transpose(const AntiSymTensor< T, D > &rhs)
SymTensor< T, D > & operator/=(const T &rhs)
Definition: SymTensor.h:192
Type_t HL(unsigned int hi, unsigned int lo) const
Definition: SymTensor.h:243
int len(void) const
Definition: SymTensor.h:207
SymTensor(const T &x00)
Definition: SymTensor.h:79
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
Type_t operator()(unsigned int i) const
Definition: SymTensor.h:279
Type_t & operator[](unsigned int i)
Definition: SymTensor.h:258
SymTensor< T, D > & operator+=(const T &rhs)
Definition: SymTensor.h:156
SymTensor(const T &x00, const T &x10, const T &x11, const T &x20, const T &x21, const T &x22)
Definition: SymTensor.h:89
T trace(const AntiSymTensor< T, D > &)
int get_Size(void) const
Definition: SymTensor.h:209