v0.7.2
Tensor3_antisymmetric_value.hpp
Go to the documentation of this file.
1 /* A general version, not for pointers. */
2 
3 #pragma once
4 
5 namespace FTensor
6 {
7  template <class T, int Tensor_Dim0, int Tensor_Dim12>
9  {
10  T data[Tensor_Dim0][(Tensor_Dim12*(Tensor_Dim12-1))/2];
11  public:
13 
14  /* Tensor_Dim0=2, Tensor_Dim12=2 */
15  Tensor3_antisymmetric(T d001, T d101)
16  {
18  }
19 
20  /* Tensor_Dim0=3, Tensor_Dim12=3 */
21  Tensor3_antisymmetric(T d001, T d002, T d012, T d101, T d102, T d112,
22  T d201, T d202, T d212)
23  {
25  (data,d001,d002,d012,d101,d102,d112,d201,d202,d212);
26  }
27 
28  /* Tensor_Dim0=4, Tensor_Dim12=4 */
29  Tensor3_antisymmetric(T d001, T d002, T d003, T d012, T d013, T d023,
30  T d101, T d102, T d103, T d112, T d113, T d123,
31  T d201, T d202, T d203, T d212, T d213, T d223)
32  {
34  (data,d001,d002,d003,d012,d013,d023,d101,d102,d103,d112,d113,d123,
35  d201,d202,d203,d212,d213,d223);
36  }
37 
38  /* There are two ways of accessing the values inside,
39  unsafe(int,int,int) and operator(int,int,int).
40  unsafe(int,int,int) will give you a wrong answer if you aren't
41  careful. The problem is that we only store the minimal set of
42  components, but some have different signs. We can't return the
43  negative of a component, and assign something to it, because that
44  would assign something to a temporary. To get the correct answer
45  if you don't want to change the value, just use
46  operator(int,int,int). */
47 
48  T & unsafe(const int N1, const int N2, const int N3)
49  {
50 #ifdef FTENSOR_DEBUG
51  if(N1>=Tensor_Dim0 || N1<0
52  || N2>=Tensor_Dim12 || N2<0 || N3>=Tensor_Dim12 || N3<0
53  || N2>=N3)
54  {
55  std::stringstream s;
56  s << "Bad index in Tensor3_antisymmetric<T,"
57  << Tensor_Dim0 << "," << Tensor_Dim12
58  << ">.operator("
59  << N1 << "," << N2 << "," << N3 << ")" << std::endl;
60  throw std::runtime_error(s.str());
61  }
62 #endif
63  return data[N1][N3-1+(N2*(2*(Tensor_Dim12-1)-N2-1))/2];
64  }
65 
66  T operator()(const int N1, const int N2, const int N3) const
67  {
68 #ifdef FTENSOR_DEBUG
69  if(N1>=Tensor_Dim0 || N1<0
70  || N2>=Tensor_Dim12 || N2<0 || N3>=Tensor_Dim12 || N3<0)
71  {
72  std::stringstream s;
73  s << "Bad index in Tensor3_antisymmetric<T,"
74  << Tensor_Dim0 << "," << Tensor_Dim12
75  << ">.operator("
76  << N1 << "," << N2 << "," << N3 << ") const"
77  << std::endl;
78  throw std::runtime_error(s.str());
79  }
80 #endif
81  return N2<N3 ? data[N1][N3-1+(N2*(2*(Tensor_Dim12-1)-N2-1))/2]
82  : (N2>N3 ? -data[N1][N2-1+(N3*(2*(Tensor_Dim12-1)-N3-1))/2] : 0.0);
83  }
84 
85  /* These operator()'s are the first part in constructing template
86  expressions. */
87 
88  template<char i, char j, char k, int Dim0, int Dim12>
89  typename std::enable_if<(Tensor_Dim0 >= Dim0 && Tensor_Dim12 >= Dim12),
91  T,Dim0,Dim12,i,j,k> >::type
92  operator()(const Index<i,Dim0> , const Index<j,Dim12> ,
93  const Index<k,Dim12> )
94  {
96  <T,Tensor_Dim0,Tensor_Dim12>,T,Dim0,Dim12,i,j,k>(*this);
97  }
98 
99  template<char i, char j, char k, int Dim0, int Dim12>
100  typename std::enable_if<(Tensor_Dim0 >= Dim0 && Tensor_Dim12 >= Dim12),
102  T,Dim0,Dim12,i,j,k> >::type
103  operator()(const Index<i,Dim0> , const Index<j,Dim12> ,
104  const Index<k,Dim12> ) const
105  {
107  <T,Tensor_Dim0,Tensor_Dim12>,T,Dim0,Dim12,i,j,k>(*this);
108  }
109  //TODO Add the rest of operations with partial index and numbers
110  };
111 }
T data[Tensor_Dim0][(Tensor_Dim12 *(Tensor_Dim12-1))/2]
Tensor3_antisymmetric(T d001, T d002, T d003, T d012, T d013, T d023, T d101, T d102, T d103, T d112, T d113, T d123, T d201, T d202, T d203, T d212, T d213, T d223)
Tensor3_antisymmetric(T d001, T d002, T d012, T d101, T d102, T d112, T d201, T d202, T d212)
JSON compatible output.
T operator()(const int N1, const int N2, const int N3) const
T & unsafe(const int N1, const int N2, const int N3)