v0.14.0
Tensor4_pointer.hpp
Go to the documentation of this file.
1 /* A version for pointers. */
2 
3 #pragma once
4 
5 namespace FTensor
6 {
7 template <class T, int Dim0, int Dim1, int Dim2, int Dim3, int Current_Dim0,
8  int Current_Dim1, int Current_Dim2, int Current_Dim3>
9 inline void
13 {
14  iter.increment(Number<Current_Dim0>(), Number<Current_Dim1>(),
18 }
19 
20 template <class T, int Dim0, int Dim1, int Dim2, int Dim3, int Current_Dim1,
21  int Current_Dim2, int Current_Dim3>
22 inline void
24  const Number<1> &, const Number<Current_Dim1> &,
26 {
31 }
32 
33 template <class T, int Dim0, int Dim1, int Dim2, int Dim3, int Current_Dim2,
34  int Current_Dim3>
35 inline void
37  const Number<1> &, const Number<1> &,
39 {
40  iter.increment(Number<1>(), Number<1>(), Number<Current_Dim2>(),
44 }
45 
46 template <class T, int Dim0, int Dim1, int Dim2, int Dim3, int Current_Dim3>
48  const Number<1> &, const Number<1> &,
49  const Number<1> &, const Number<Current_Dim3> &)
50 {
51  iter.increment(Number<1>(), Number<1>(), Number<1>(),
55 }
56 
57 template <class T, int Dim0, int Dim1, int Dim2, int Dim3>
59  const Number<1> &, const Number<1> &,
60  const Number<1> &, const Number<1> &)
61 {
62  iter.increment(Number<1>(), Number<1>(), Number<1>(), Number<1>());
63 }
64 
65 template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2,
66  int Tensor_Dim3>
67 class Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>
68 {
69  const int inc;
70 
71 protected:
72  mutable T *restrict
73  data[Tensor_Dim0][Tensor_Dim1][Tensor_Dim2][Tensor_Dim3];
74 
75 public:
76  Tensor4(T *d0000, T *d0001, T *d0010, T *d0011, T *d0100, T *d0101,
77  T *d0110, T *d0111, T *d1000, T *d1001, T *d1010, T *d1011,
78  T *d1100, T *d1101, T *d1110, T *d1111, const int i = 1)
79  : inc(i)
80  {
81  Tensor4_constructor<T * restrict, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
82  Tensor_Dim3>(
83  data, d0000, d0001, d0010, d0011, d0100, d0101, d0110, d0111, d1000,
84  d1001, d1010, d1011, d1100, d1101, d1110, d1111);
85  }
86 
87  Tensor4(T *d0000, T *d0001, T *d0002, T *d0010, T *d0011, T *d0012,
88  T *d0020, T *d0021, T *d0022, T *d0100, T *d0101, T *d0102,
89  T *d0110, T *d0111, T *d0112, T *d0120, T *d0121, T *d0122,
90  T *d0200, T *d0201, T *d0202, T *d0210, T *d0211, T *d0212,
91  T *d0220, T *d0221, T *d0222, T *d1000, T *d1001, T *d1002,
92  T *d1010, T *d1011, T *d1012, T *d1020, T *d1021, T *d1022,
93  T *d1100, T *d1101, T *d1102, T *d1110, T *d1111, T *d1112,
94  T *d1120, T *d1121, T *d1122, T *d1200, T *d1201, T *d1202,
95  T *d1210, T *d1211, T *d1212, T *d1220, T *d1221, T *d1222,
96  T *d2000, T *d2001, T *d2002, T *d2010, T *d2011, T *d2012,
97  T *d2020, T *d2021, T *d2022, T *d2100, T *d2101, T *d2102,
98  T *d2110, T *d2111, T *d2112, T *d2120, T *d2121, T *d2122,
99  T *d2200, T *d2201, T *d2202, T *d2210, T *d2211, T *d2212,
100  T *d2220, T *d2221, T *d2222, const int i = 1)
101  : inc(i)
102  {
103  Tensor4_constructor<T * restrict, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
104  Tensor_Dim3>(
105  data, d0000, d0001, d0002, d0010, d0011, d0012, d0020, d0021, d0022,
106  d0100, d0101, d0102, d0110, d0111, d0112, d0120, d0121, d0122, d0200,
107  d0201, d0202, d0210, d0211, d0212, d0220, d0221, d0222, d1000, d1001,
108  d1002, d1010, d1011, d1012, d1020, d1021, d1022, d1100, d1101, d1102,
109  d1110, d1111, d1112, d1120, d1121, d1122, d1200, d1201, d1202, d1210,
110  d1211, d1212, d1220, d1221, d1222, d2000, d2001, d2002, d2010, d2011,
111  d2012, d2020, d2021, d2022, d2100, d2101, d2102, d2110, d2111, d2112,
112  d2120, d2121, d2122, d2200, d2201, d2202, d2210, d2211, d2212, d2220,
113  d2221, d2222);
114  }
115 
116  Tensor4(T *d, const int shift, const int i = 1) : inc(i)
117  {
118  int s = 0;
119  for (int i = 0; i != Tensor_Dim0; ++i)
120  {
121  for (int j = 0; j != Tensor_Dim1; ++j)
122  {
123  for (int k = 0; k != Tensor_Dim2; ++k)
124  {
125  for (int l = 0; l != Tensor_Dim3; ++l)
126  {
127  data[i][j][k][l] = &d[s];
128  s += shift;
129  }
130  }
131  }
132  }
133  }
134 
135  /* Initializations for varying numbers of elements. */
136  template <class... U> Tensor4(U *... d) : inc(1), data{d...} {}
137 
138  /* There are two operator(int,int)'s, one for non-consts that lets you
139  change the value, and one for consts that doesn't. */
140 
141  T &operator()(const int N1, const int N2, const int N3, const int N4)
142  {
143 #ifdef FTENSOR_DEBUG
144  if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 || N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0)
145  {
146  std::stringstream s;
147  s << "Bad index in Tensor4<T," << Tensor_Dim0 << "," << Tensor_Dim1
148  << "," << Tensor_Dim2 << "," << Tensor_Dim3 << ">.operator(" << N1
149  << "," << N2 << "," << N3 << "," << N4 << ") const" << std::endl;
150  throw std::runtime_error(s.str());
151  }
152 #endif
153  return *data[N1][N2][N3][N4];
154  }
155 
156  T operator()(const int N1, const int N2, const int N3, const int N4) const
157  {
158 #ifdef FTENSOR_DEBUG
159  if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 || N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0)
160  {
161  std::stringstream s;
162  s << "Bad index in Tensor4<T," << Tensor_Dim0 << "," << Tensor_Dim1
163  << "," << Tensor_Dim2 << "," << Tensor_Dim3 << ">.operator(" << N1
164  << "," << N2 << "," << N3 << "," << N4 << ") const" << std::endl;
165  throw std::runtime_error(s.str());
166  }
167 #endif
168  return *data[N1][N2][N3][N4];
169  }
170 
171  /* These operator()'s are the first part in constructing template
172  expressions. They can be used to slice off lower dimensional
173  parts. They are not entirely safe, since you can accidently use a
174  higher dimension than what is really allowed (like Dim=5). */
175 
176  template <char i, char j, char k, char l, int Dim0, int Dim1, int Dim2,
177  int Dim3>
178  Tensor4_Expr<
180  Dim0, Dim1, Dim2, Dim3, i, j, k, l>
182  const Index<k, Dim2>, const Index<l, Dim3>)
183  {
184  return Tensor4_Expr<
186  Dim0, Dim1, Dim2, Dim3, i, j, k, l>(*this);
187  }
188 
189  template <char i, char j, char k, char l, int Dim0, int Dim1, int Dim2,
190  int Dim3>
191  Tensor4_Expr<
193  T, Dim0, Dim1, Dim2, Dim3, i, j, k, l>
195  const Index<k, Dim2>, const Index<l, Dim3>) const
196  {
197  return Tensor4_Expr<
199  T, Dim0, Dim1, Dim2, Dim3, i, j, k, l>(*this);
200  }
201 
202  /* The ++ operator increments the pointer, not the number that the
203  pointer points to. This allows iterating over a grid. */
204 
205  template <int Current_Dim0, int Current_Dim1, int Current_Dim2,
206  int Current_Dim3>
207  inline void
209  const Number<Current_Dim2> &, const Number<Current_Dim3> &) const
210  {
211  data[Current_Dim0 - 1][Current_Dim1 - 1][Current_Dim2 - 1]
212  [Current_Dim3 - 1] += inc;
213  }
214 
215  const Tensor4 &operator++() const
216  {
219  return *this;
220  }
221 
222  T *ptr(const int N1, const int N2, const int N3, const int N4) const
223  {
224 #ifdef FTENSOR_DEBUG
225  if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 ||
226  N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0)
227  {
228  std::stringstream s;
229  s << "Bad index in Tensor4<T*," << Tensor_Dim0 << "," << Tensor_Dim1
230  << "," << Tensor_Dim2 << "," << Tensor_Dim3 << ">.ptr(" << N1 << ","
231  << N2 << "," << N3 << "," << N4 << ")" << std::endl;
232  throw std::out_of_range(s.str());
233  }
234 #endif
235  return data[N1][N2][N3][N4];
236  }
237 
238  T *restrict &ptr(const int N1, const int N2, const int N3, const int N4)
239  {
240 #ifdef FTENSOR_DEBUG
241  if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 ||
242  N3 >= Tensor_Dim2 || N3 < 0 || N4 >= Tensor_Dim3 || N4 < 0)
243  {
244  std::stringstream s;
245  s << "Bad index in Tensor4<T*," << Tensor_Dim0 << "," << Tensor_Dim1
246  << "," << Tensor_Dim2 << "," << Tensor_Dim3 << ">.ptr(" << N1 << ","
247  << N2 << "," << N3 << "," << N4 << ")" << std::endl;
248  throw std::out_of_range(s.str());
249  }
250 #endif
251  return data[N1][N2][N3][N4];
252  }
253 
254  private:
255  template <int I>
256  Tensor4(const Tensor4<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1,
257  Tensor_Dim2, Tensor_Dim3> &) = delete;
258 };
259 
260 template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2,
261  int Tensor_Dim3, int I>
262 class Tensor4<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
263  Tensor_Dim3> : public Tensor4<T *, Tensor_Dim0, Tensor_Dim1,
264  Tensor_Dim2, Tensor_Dim3>
265 {
266 
267 public:
268  Tensor4(T *d, const int shift)
269  : Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>(
270  d, shift) {}
271 
272  template <class... U>
273  Tensor4(U *... d)
274  : Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>(
275  d...) {}
276 
277  /* The ++ operator increments the pointer, not the number that the
278  pointer points to. This allows iterating over a grid. */
279 
280  template <int Current_Dim0, int Current_Dim1, int Current_Dim2,
281  int Current_Dim3>
282  inline void increment(const Number<Current_Dim0> &,
283  const Number<Current_Dim1> &,
284  const Number<Current_Dim2> &,
285  const Number<Current_Dim3> &) const
286  {
287  Tensor4<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
288  Tensor_Dim3>::data[Current_Dim0 - 1][Current_Dim1 - 1]
289  [Current_Dim2 - 1][Current_Dim3 - 1] += I;
290  }
291 
292  const Tensor4 &operator++() const
293  {
296  return *this;
297  }
298 };
299 } // namespace FTensor
FTensor
JSON compatible output.
Definition: Christof_constructor.hpp:6
FTensor::Tensor4< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::Tensor4
Tensor4(T *d, const int shift)
Definition: Tensor4_pointer.hpp:268
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::ptr
T *restrict & ptr(const int N1, const int N2, const int N3, const int N4)
Definition: Tensor4_pointer.hpp:238
FTensor::d
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
FTensor::Tensor4_constructor
Definition: Tensor4_constructor.hpp:10
FTensor::Tensor4< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::Tensor4
Tensor4(U *... d)
Definition: Tensor4_pointer.hpp:273
I
constexpr IntegrationType I
Definition: operators_tests.cpp:31
FTensor::Tensor4_Expr
Definition: Tensor4_Expr.hpp:25
FTensor::Number
Definition: Number.hpp:11
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::operator()
T operator()(const int N1, const int N2, const int N3, const int N4) const
Definition: Tensor4_pointer.hpp:156
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >
Definition: Tensor4_pointer.hpp:67
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::Tensor4
Tensor4(T *d, const int shift, const int i=1)
Definition: Tensor4_pointer.hpp:116
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::increment
void increment(const Number< Current_Dim0 > &, const Number< Current_Dim1 > &, const Number< Current_Dim2 > &, const Number< Current_Dim3 > &) const
Definition: Tensor4_pointer.hpp:208
FTensor::PackPtr
Definition: FTensor.hpp:54
FTensor::Tensor4
Definition: Tensor4_value.hpp:18
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::Tensor4
Tensor4(U *... d)
Definition: Tensor4_pointer.hpp:136
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::inc
const int inc
Definition: Tensor4_pointer.hpp:69
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::Tensor4
Tensor4(T *d0000, T *d0001, T *d0002, T *d0010, T *d0011, T *d0012, T *d0020, T *d0021, T *d0022, T *d0100, T *d0101, T *d0102, T *d0110, T *d0111, T *d0112, T *d0120, T *d0121, T *d0122, T *d0200, T *d0201, T *d0202, T *d0210, T *d0211, T *d0212, T *d0220, T *d0221, T *d0222, T *d1000, T *d1001, T *d1002, T *d1010, T *d1011, T *d1012, T *d1020, T *d1021, T *d1022, T *d1100, T *d1101, T *d1102, T *d1110, T *d1111, T *d1112, T *d1120, T *d1121, T *d1122, T *d1200, T *d1201, T *d1202, T *d1210, T *d1211, T *d1212, T *d1220, T *d1221, T *d1222, T *d2000, T *d2001, T *d2002, T *d2010, T *d2011, T *d2012, T *d2020, T *d2021, T *d2022, T *d2100, T *d2101, T *d2102, T *d2110, T *d2111, T *d2112, T *d2120, T *d2121, T *d2122, T *d2200, T *d2201, T *d2202, T *d2210, T *d2211, T *d2212, T *d2220, T *d2221, T *d2222, const int i=1)
Definition: Tensor4_pointer.hpp:87
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
FTensor::Index
Definition: Index.hpp:23
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::Tensor4
Tensor4(T *d0000, T *d0001, T *d0010, T *d0011, T *d0100, T *d0101, T *d0110, T *d0111, T *d1000, T *d1001, T *d1010, T *d1011, T *d1100, T *d1101, T *d1110, T *d1111, const int i=1)
Definition: Tensor4_pointer.hpp:76
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::operator++
const Tensor4 & operator++() const
Definition: Tensor4_pointer.hpp:215
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::operator()
Tensor4_Expr< const Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > operator()(const Index< i, Dim0 >, const Index< j, Dim1 >, const Index< k, Dim2 >, const Index< l, Dim3 >) const
Definition: Tensor4_pointer.hpp:194
FTensor::T4_increment
void T4_increment(const Tensor4< T, Dim0, Dim1, Dim2, Dim3 > &iter, const Number< Current_Dim0 > &, const Number< Current_Dim1 > &, const Number< Current_Dim2 > &, const Number< Current_Dim3 > &)
Definition: Tensor4_pointer.hpp:10
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::operator()
Tensor4_Expr< Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > operator()(const Index< i, Dim0 >, const Index< j, Dim1 >, const Index< k, Dim2 >, const Index< l, Dim3 >)
Definition: Tensor4_pointer.hpp:181
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::ptr
T * ptr(const int N1, const int N2, const int N3, const int N4) const
Definition: Tensor4_pointer.hpp:222
FTensor::Tensor4< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::operator++
const Tensor4 & operator++() const
Definition: Tensor4_pointer.hpp:292
FTensor::Tensor4< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::increment
void increment(const Number< Current_Dim0 > &, const Number< Current_Dim1 > &, const Number< Current_Dim2 > &, const Number< Current_Dim3 > &) const
Definition: Tensor4_pointer.hpp:282
FTensor::Tensor4< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 >::operator()
T & operator()(const int N1, const int N2, const int N3, const int N4)
Definition: Tensor4_pointer.hpp:141
k
FTensor::Index< 'k', 3 > k
Definition: matrix_function.cpp:20
EshelbianPlasticity::U
@ U
Definition: EshelbianContact.cpp:193
l
FTensor::Index< 'l', 3 > l
Definition: matrix_function.cpp:21