v0.15.0
Loading...
Searching...
No Matches
Tensor3_antisymmetric_pointer.hpp
Go to the documentation of this file.
1/* A version for pointers. */
2
3#pragma once
4
5namespace FTensor
6{
7 template <class T, int Tensor_Dim0, int Tensor_Dim12>
8 class Tensor3_antisymmetric<T *, Tensor_Dim0, Tensor_Dim12>
9 {
10 mutable T *restrict
11 data[Tensor_Dim0][(Tensor_Dim12 * (Tensor_Dim12 - 1)) / 2];
12
13 public:
14 template <class... U> Tensor3_antisymmetric(U *... d) : data{d...}
15 {
16 static_assert(sizeof...(d) == sizeof(data) / sizeof(T),
17 "Incorrect number of Arguments. Constructor should "
18 "initialize the entire Tensor");
19 }
20
22
23 /* There are two ways of accessing the values inside,
24 unsafe(int,int,int) and operator(int,int,int).
25 unsafe(int,int,int) will give you a wrong answer if you aren't
26 careful. The problem is that we only store the minimal set of
27 components, but some have different signs. We can't return the
28 negative of a component, and assign something to it, because that
29 would assign something to a temporary. To get the correct answer
30 if you don't want to change the value, just use
31 operator(int,int,int). */
32
33 T &unsafe(const int N1, const int N2, const int N3)
34 {
35#ifdef FTENSOR_DEBUG
36 if(N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim12 || N2 < 0
37 || N3 >= Tensor_Dim12 || N3 < 0 || N2 >= N3)
38 {
39 std::stringstream s;
40 s << "Bad index in Tensor3_antisymmetric<T*," << Tensor_Dim0 << ","
41 << Tensor_Dim12 << ">.unsafe(" << N1 << "," << N2 << "," << N3
42 << ")" << std::endl;
43 throw std::out_of_range(s.str());
44 }
45#endif
46 return *data[N1][N3 - 1 + (N2 * (2 * (Tensor_Dim12 - 1) - N2 - 1)) / 2];
47 }
48
49 T operator()(const int N1, const int N2, const int N3) const
50 {
51#ifdef FTENSOR_DEBUG
52 if(N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim12 || N2 < 0
53 || N3 >= Tensor_Dim12 || N3 < 0)
54 {
55 std::stringstream s;
56 s << "Bad index in Tensor3_antisymmetric<T*," << Tensor_Dim0 << ","
57 << Tensor_Dim12 << ">.operator(" << N1 << "," << N2 << "," << N3
58 << ") const" << std::endl;
59 throw std::out_of_range(s.str());
60 }
61#endif
62 return N2 < N3
63 ? *data[N1]
64 [N3 - 1 + (N2 * (2 * (Tensor_Dim12 - 1) - N2 - 1)) / 2]
65 : (N2 > N3
66 ? -*data[N1][N2 - 1
67 + (N3 * (2 * (Tensor_Dim12 - 1) - N3 - 1)) / 2]
68 : 0.0);
69 }
70
71 T *ptr(const int N1, const int N2, const int N3) const
72 {
73#ifdef FTENSOR_DEBUG
74 if(N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim12 || N2 < 0
75 || N3 >= Tensor_Dim12 || N3 < 0)
76 {
77 std::stringstream s;
78 s << "Bad index in Tensor3_antisymmetric<T*," << Tensor_Dim0 << ","
79 << Tensor_Dim12 << ">.ptr(" << N1 << "," << N2 << "," << N3 << ")"
80 << std::endl;
81 throw std::out_of_range(s.str());
82 }
83#endif
84 return N2 < N3
85 ? data[N1][N3 - 1 + (N2 * (2 * (Tensor_Dim12 - 1) - N2 - 1)) / 2]
86 : (N2 > N3
87 ? -data[N1][N2 - 1
88 + (N3 * (2 * (Tensor_Dim12 - 1) - N3 - 1)) / 2]
89 : 0);
90 }
91
92 /* These operator()'s are the first part in constructing template
93 expressions. */
94
95 template <char i, char j, char k, int Dim0, int Dim12>
98 j, k>
99 operator()(const Index<i, Dim0> index1, const Index<j, Dim12> index2,
100 const Index<k, Dim12> index3)
101 {
104 i, j, k>(*this);
105 }
106
107 template <char i, char j, char k, int Dim0, int Dim12>
110 Dim12, i, j, k>
111 operator()(const Index<i, Dim0> index1, const Index<j, Dim12> index2,
112 const Index<k, Dim12> index3) const
113 {
116 Dim12, i, j, k>(*this);
117 }
118
119 /* The ++ operator increments the pointer, not the number that the
120 pointer points to. This allows iterating over a grid. */
121
124 {
125 for(int i = 0; i < Tensor_Dim0; ++i)
126 for(int j = 0; j < (Tensor_Dim12 * (Tensor_Dim12 - 1)) / 2; ++j)
127 ++data[i][j];
128 return *this;
129 }
130 };
131}
Tensor3_antisymmetric_Expr< const Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >, T, Dim0, Dim12, i, j, k > operator()(const Index< i, Dim0 > index1, const Index< j, Dim12 > index2, const Index< k, Dim12 > index3) const
Tensor3_antisymmetric_Expr< Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >, T, Dim0, Dim12, i, j, k > operator()(const Index< i, Dim0 > index1, const Index< j, Dim12 > index2, const Index< k, Dim12 > index3)
const Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 > & operator++() const
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
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