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