v0.16.0
Loading...
Searching...
No Matches
Tensor1_pointer.hpp
Go to the documentation of this file.
1/* A version for pointers, useful for previously
2 constructed arrays. */
3
4#pragma once
5
6namespace FTensor
7{
8
9template <class T, int Tensor_Dim> class Tensor1<T *, Tensor_Dim> {
10protected:
11
12 const int inc;
13
14 /* Note that the T *'s are mutable, so the pointer can change,
15 allowing iterating over a array. */
16
17 mutable T *restrict data[Tensor_Dim];
18
19public:
20 /* Initializations for varying numbers of elements, with each one
21 defined for a particular Tensor_Dim. To initialize a different
22 dimension, just add the appropriate constructor and call to
23 the Tensor1_constructor constructor. */
24 Tensor1(T *d0, const int i = 1) : inc(i) {
26 }
27 Tensor1(T *d0, T *d1, const int i = 1) : inc(i) {
29 }
30 Tensor1(T *d0, T *d1, T *d2, const int i = 1) : inc(i) {
32 }
33 Tensor1(T *d0, T *d1, T *d2, T *d3, const int i = 1) : inc(i) {
35 }
36 Tensor1(T *d0, T *d1, T *d2, T *d3, T *d4, T *d5, const int i = 1) : inc(i) {
38 }
39 Tensor1(T *d0, T *d1, T *d2, T *d3, T *d4, T *d5, T *d6, T *d7,
40 const int i = 1)
41 : inc(i) {
43 d6, d7);
44 }
45 Tensor1(T *d0, T *d1, T *d2, T *d3, T *d4, T *d5, T *d6, T *d7, T *d8,
46 const int i = 1)
47 : inc(i) {
49 d6, d7, d8);
50 }
51 /* Initializations for varying numbers of elements. */
52 template <class... U> Tensor1(U *... d) : data(d...), inc(1) {}
53
54 /* Initialization from array */
55 template <class U>
56 Tensor1(std::array<U *, Tensor_Dim> &a, const int i = 1) : inc(i) {
57 std::copy(a.begin(), a.end(), data);
58 }
59
60 Tensor1(const int i = 1) : inc(i) {}
61
63 const Index<'a', Tensor_Dim> a;
64 (*this)(a) /= l2();
65 return *this;
66 }
67
68 T l2() const { return sqrt(l2_squared(Number<Tensor_Dim>())); }
69
70 template <int Current_Dim> T l2_squared(const Number<Current_Dim> &) const {
71 return (*data[Current_Dim - 1]) * (*data[Current_Dim - 1]) +
72 l2_squared(Number<Current_Dim - 1>());
73 }
74 T l2_squared(const Number<1> &) const { return (*data[0]) * (*data[0]); }
75
76 /* There are two operator(int)'s, one for non-consts that lets you
77 change the value, and one for consts that doesn't. */
78
79 T &operator()(const int N) {
80#ifdef FTENSOR_DEBUG
81 if(N >= Tensor_Dim || N < 0)
82 {
83 std::stringstream s;
84 s << "Bad index in Tensor1<T*," << Tensor_Dim << ">.operator(" << N
85 << ")" << std::endl;
86 throw std::out_of_range(s.str());
87 }
88#endif
89 return *data[N];
90 }
91 T operator()(const int N) const
92 {
93#ifdef FTENSOR_DEBUG
94 if(N >= Tensor_Dim || N < 0)
95 {
96 std::stringstream s;
97 s << "Bad index in Tensor1<T*," << Tensor_Dim << ">.operator(" << N
98 << ") const" << std::endl;
99 throw std::out_of_range(s.str());
100 }
101#endif
102 return *data[N];
103 }
104 T *ptr(const int N) const
105 {
106#ifdef FTENSOR_DEBUG
107 if(N >= Tensor_Dim || N < 0)
108 {
109 std::stringstream s;
110 s << "Bad index in Tensor1<T*," << Tensor_Dim << ">.ptr(" << N << ")"
111 << std::endl;
112 throw std::out_of_range(s.str());
113 }
114#endif
115 return data[N];
116 }
117
118 T *&ptr(const int N) {
119#ifdef FTENSOR_DEBUG
120 if (N >= Tensor_Dim || N < 0) {
121 std::stringstream s;
122 s << "Bad index in Tensor1<T*," << Tensor_Dim << ">.ptr(" << N << ")"
123 << std::endl;
124 throw std::out_of_range(s.str());
125 }
126#endif
127 return data[N];
128 }
129
130 /* These operator()'s are the first part in constructing template
131 expressions. They can be used to slice off lower dimensional
132 parts. They are not entirely safe, since you can accidentaly use a
133 higher dimension than what is really allowed (like Dim=5). */
134
135 template <char i, int Dim>
138 {
139 return Tensor1_Expr<Tensor1<T *, Tensor_Dim>, T, Dim, i>(*this);
140 }
141
142 template <char i, int Dim>
144 operator()(const Index<i, Dim> &index) const
145 {
146 return Tensor1_Expr<const Tensor1<T *, Tensor_Dim>, T, Dim, i>(*this);
147 }
148
149 /* The ++ operator increments the pointer, not the number that the
150 pointer points to. This allows iterating over a grid. */
151
152 const Tensor1 &operator++() const
153 {
154 for(int i = 0; i < Tensor_Dim; ++i)
155 data[i] += inc;
156 return *this;
157 }
158
159 private:
160
161 /**
162 * @brief Preventing casting on derived class
163 *
164 * That can be source of errors
165 *
166 */
167 template <int I>
168 Tensor1(const Tensor1<PackPtr<T *, I>, Tensor_Dim> &) = delete;
169
170 template <int G>
171 Tensor1(const Tensor1<CursorPtr<T *, G>, Tensor_Dim> &) = delete;
172 };
173
174 template <class T, int Tensor_Dim, int I>
175 class Tensor1<PackPtr<T *, I>, Tensor_Dim> : public Tensor1<T *, Tensor_Dim> {
176
177 public:
178
179 /* Initializations for varying numbers of elements. */
180 template <class... U> Tensor1(U *... d) : Tensor1<T *, Tensor_Dim>(d...) {}
181
182 template <class U>
183 Tensor1(std::array<U *, Tensor_Dim> &a) : Tensor1<T *, Tensor_Dim>(a) {}
184
185 Tensor1(): Tensor1<T *, Tensor_Dim>() {}
186
187 /* The ++ operator increments the pointer, not the number that the
188 pointer points to. This allows iterating over a grid. */
189
190 const Tensor1 &operator++() const
191 {
192 for(int i = 0; i < Tensor_Dim; ++i)
194 return *this;
195 }
196 };
197
198 template <class T, int Tensor_Dim, int G>
199 class Tensor1<CursorPtr<T *, G>, Tensor_Dim> {
200
201 using Self = Tensor1<CursorPtr<T *, G>, Tensor_Dim>;
202
203 mutable T *restrict data;
204
205 public:
206 explicit Tensor1(T *d) : data(d) {}
207
208 Tensor1() = delete;
209
211 const Index<'a', Tensor_Dim> a;
212 (*this)(a) /= l2();
213 return *this;
214 }
215
216 T l2() const { return sqrt(l2_squared(Number<Tensor_Dim>())); }
217
218 template <int Current_Dim> T l2_squared(const Number<Current_Dim> &) const {
219 return (*(data + Current_Dim - 1)) * (*(data + Current_Dim - 1)) +
220 l2_squared(Number<Current_Dim - 1>());
221 }
222 T l2_squared(const Number<1> &) const { return (*data) * (*data); }
223
224 T &operator()(const int N) {
225#ifdef FTENSOR_DEBUG
226 if (N >= Tensor_Dim || N < 0) {
227 std::stringstream s;
228 s << "Bad index in Tensor1<CursorPtr<T*," << G << ">," << Tensor_Dim
229 << ">.operator(" << N << ")" << std::endl;
230 throw std::out_of_range(s.str());
231 }
232#endif
233 return *(data + N);
234 }
235
236 T operator()(const int N) const {
237#ifdef FTENSOR_DEBUG
238 if (N >= Tensor_Dim || N < 0) {
239 std::stringstream s;
240 s << "Bad index in Tensor1<CursorPtr<T*," << G << ">," << Tensor_Dim
241 << ">.operator(" << N << ") const" << std::endl;
242 throw std::out_of_range(s.str());
243 }
244#endif
245 return *(data + N);
246 }
247
248 T *ptr(const int N) const {
249#ifdef FTENSOR_DEBUG
250 if (N >= Tensor_Dim || N < 0) {
251 std::stringstream s;
252 s << "Bad index in Tensor1<CursorPtr<T*," << G << ">," << Tensor_Dim
253 << ">.ptr(" << N << ")" << std::endl;
254 throw std::out_of_range(s.str());
255 }
256#endif
257 return data + N;
258 }
259
260 template <char i, int Dim>
264
265 template <char i, int Dim>
267 operator()(const Index<i, Dim> &index) const {
269 }
270
271 const Tensor1 &operator++() const {
272 data += G;
273 return *this;
274 }
275 };
276
277
278}
constexpr double a
T l2_squared(const Number< Current_Dim > &) const
Tensor1_Expr< Self, T, Dim, i > operator()(const Index< i, Dim > &index)
Tensor1_Expr< const Self, T, Dim, i > operator()(const Index< i, Dim > &index) const
Tensor1(T *d0, T *d1, T *d2, T *d3, T *d4, T *d5, const int i=1)
Tensor1(const Tensor1< CursorPtr< T *, G >, Tensor_Dim > &)=delete
T l2_squared(const Number< 1 > &) const
Tensor1(T *d0, T *d1, const int i=1)
Tensor1< T, Tensor_Dim > normalize()
Tensor1(T *d0, T *d1, T *d2, T *d3, T *d4, T *d5, T *d6, T *d7, const int i=1)
Tensor1(std::array< U *, Tensor_Dim > &a, const int i=1)
Tensor1(T *d0, T *d1, T *d2, T *d3, const int i=1)
Tensor1(T *d0, T *d1, T *d2, const int i=1)
Tensor1_Expr< Tensor1< T *, Tensor_Dim >, T, Dim, i > operator()(const Index< i, Dim > &index)
Tensor1(const Tensor1< PackPtr< T *, I >, Tensor_Dim > &)=delete
Preventing casting on derived class.
Tensor1_Expr< const Tensor1< T *, Tensor_Dim >, T, Dim, i > operator()(const Index< i, Dim > &index) const
T l2_squared(const Number< Current_Dim > &) const
Tensor1(T *d0, T *d1, T *d2, T *d3, T *d4, T *d5, T *d6, T *d7, T *d8, const int i=1)
FTensor::Index< 'i', SPACE_DIM > i
constexpr IntegrationType G
Definition level_set.cpp:33
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
constexpr IntegrationType I
static constexpr std::array< double, 3 > d4
static constexpr std::array< double, 3 > d3
const int N
Definition speed_test.cpp:3