v0.15.4
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 || N2 > N3 || N2 == N3)
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 data[N1][N3 - 1 + (N2 * (2 * (Tensor_Dim12 - 1) - N2 - 1)) / 2];
85 }
86
87 /* These operator()'s are the first part in constructing template
88 expressions. */
89
90 template <char i, char j, char k, int Dim0, int Dim12>
93 j, k>
94 operator()(const Index<i, Dim0> index1, const Index<j, Dim12> index2,
95 const Index<k, Dim12> index3)
96 {
99 i, j, k>(*this);
100 }
101
102 template <char i, char j, char k, int Dim0, int Dim12>
105 Dim12, i, j, k>
106 operator()(const Index<i, Dim0> index1, const Index<j, Dim12> index2,
107 const Index<k, Dim12> index3) const
108 {
111 Dim12, i, j, k>(*this);
112 }
113
114 /* The ++ operator increments the pointer, not the number that the
115 pointer points to. This allows iterating over a grid. */
116
119 {
120 for(int i = 0; i < Tensor_Dim0; ++i)
121 for(int j = 0; j < (Tensor_Dim12 * (Tensor_Dim12 - 1)) / 2; ++j)
122 ++data[i][j];
123 return *this;
124 }
125 };
126}
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