v0.13.2
Searching...
No Matches
Tensor3_antisymmetric_value.hpp
Go to the documentation of this file.
1/* A general version, not for pointers. */
2
3#pragma once
4
5namespace 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
12 public:
13 template <class... U> Tensor3_antisymmetric(U... d) : data{d...}
14 {
15 static_assert(sizeof...(d) == sizeof(data) / sizeof(T),
16 "Incorrect number of Arguments. Constructor should "
17 "initialize the entire Tensor");
18 }
19
21
22 /* There are two ways of accessing the values inside,
23 unsafe(int,int,int) and operator(int,int,int).
24 unsafe(int,int,int) will give you a wrong answer if you aren't
25 careful. The problem is that we only store the minimal set of
26 components, but some have different signs. We can't return the
27 negative of a component, and assign something to it, because that
28 would assign something to a temporary. To get the correct answer
29 if you don't want to change the value, just use
30 operator(int,int,int). */
31
32 T &unsafe(const int N1, const int N2, const int N3)
33 {
34#ifdef FTENSOR_DEBUG
35 if(N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim12 || N2 < 0
36 || N3 >= Tensor_Dim12 || N3 < 0 || N2 >= N3)
37 {
38 std::stringstream s;
39 s << "Bad index in Tensor3_antisymmetric<T," << Tensor_Dim0 << ","
40 << Tensor_Dim12 << ">.operator(" << N1 << "," << N2 << "," << N3
41 << ")" << std::endl;
42 throw std::out_of_range(s.str());
43 }
44#endif
45 return data[N1][N3 - 1 + (N2 * (2 * (Tensor_Dim12 - 1) - N2 - 1)) / 2];
46 }
47
48 T operator()(const int N1, const int N2, const int N3) const
49 {
50#ifdef FTENSOR_DEBUG
51 if(N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim12 || N2 < 0
52 || N3 >= Tensor_Dim12 || N3 < 0)
53 {
54 std::stringstream s;
55 s << "Bad index in Tensor3_antisymmetric<T," << Tensor_Dim0 << ","
56 << Tensor_Dim12 << ">.operator(" << N1 << "," << N2 << "," << N3
57 << ") const" << std::endl;
58 throw std::out_of_range(s.str());
59 }
60#endif
61 return N2 < N3
62 ? data[N1][N3 - 1 + (N2 * (2 * (Tensor_Dim12 - 1) - N2 - 1)) / 2]
63 : (N2 > N3
64 ? -data[N1][N2 - 1
65 + (N3 * (2 * (Tensor_Dim12 - 1) - N3 - 1)) / 2]
66 : 0.0);
67 }
68
69 /* These operator()'s are the first part in constructing template
70 expressions. */
71
72 template <char i, char j, char k, int Dim0, int Dim12>
73 typename std::enable_if<
74 (Tensor_Dim0 >= Dim0 && Tensor_Dim12 >= Dim12),
77 j, k>>::type
78 operator()(const Index<i, Dim0>, const Index<j, Dim12>,
79 const Index<k, Dim12>)
80 {
83 j, k>(*this);
84 }
85
86 template <char i, char j, char k, int Dim0, int Dim12>
87 typename std::enable_if<
88 (Tensor_Dim0 >= Dim0 && Tensor_Dim12 >= Dim12),
91 Dim12, i, j, k>>::type
92 operator()(const Index<i, Dim0>, const Index<j, Dim12>,
93 const Index<k, Dim12>) const
94 {
97 Dim12, i, j, k>(*this);
98 }
99 // TODO Add the rest of operations with partial index and numbers
100 };
101}
static Number< 2 > N2
static Number< 1 > N1
T data[Tensor_Dim0][(Tensor_Dim12 *(Tensor_Dim12 - 1))/2]
T operator()(const int N1, const int N2, const int N3) const
T & unsafe(const int N1, const int N2, const int N3)
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
const double T
Tensors class implemented by Walter Landry.
Definition: FTensor.hpp:51
const Tensor1_Expr< const dTensor0< T, Dim, i >, typename promote< T, double >::V, Dim, i > d(const Tensor0< T * > &a, const Index< i, Dim > index, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition: dTensor0.hpp:27