v0.14.0
Tensor3_pointer.hpp
Go to the documentation of this file.
1 /* A version for pointers. */
2 
3 #pragma once
4 
5 namespace FTensor {
6 template <class T, int Dim0, int Dim1, int Dim2, int Current_Dim0,
7  int Current_Dim1, int Current_Dim2>
8 inline void T3_increment(const Tensor3<T, Dim0, Dim1, Dim2> &iter,
9  const Number<Current_Dim0> &,
10  const Number<Current_Dim1> &,
11  const Number<Current_Dim2> &) {
12  iter.increment(Number<Current_Dim0>(), Number<Current_Dim1>(),
16 }
17 
18 template <class T, int Dim0, int Dim1, int Dim2, int Current_Dim1,
19  int Current_Dim2>
21  const Number<1> &, const Number<Current_Dim1> &,
22  const Number<Current_Dim2> &) {
23  iter.increment(Number<1>(), Number<Current_Dim1>(), Number<Current_Dim2>());
26 }
27 
28 template <class T, int Dim0, int Dim1, int Dim2, int Current_Dim2>
30  const Number<1> &, const Number<1> &,
31  const Number<Current_Dim2> &) {
32  iter.increment(Number<1>(), Number<1>(), Number<Current_Dim2>());
35 }
36 
37 template <class T, int Dim0, int Dim1, int Dim2>
39  const Number<1> &, const Number<1> &,
40  const Number<1> &) {
41  iter.increment(Number<1>(), Number<1>(), Number<1>());
42 }
43 
44 template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2>
45 class Tensor3<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2> {
46  const int inc;
47 
48 protected:
49  mutable T *restrict data[Tensor_Dim0][Tensor_Dim1][Tensor_Dim2];
50 
51 public:
52  Tensor3() {}
53 
54  /* Tensor_Dim0=2, Tensor_Dim1=2, Tensor_Dim2=2 */
55  Tensor3(T *d000, T *d001, T *d010, T *d011, T *d100, T *d101, T *d110,
56  T *d111, const int i)
57  : inc(i) {
59  data, d000, d001, d010, d011, d100, d101, d110, d111);
60  }
61 
62  /* Tensor_Dim0=3, Tensor_Dim1=3, Tensor_Dim2=3 */
63  Tensor3(T *d000, T *d001, T *d002, T *d010, T *d011, T *d012, T *d020,
64  T *d021, T *d022, T *d100, T *d101, T *d102, T *d110, T *d111,
65  T *d112, T *d120, T *d121, T *d122, T *d200, T *d201, T *d202,
66  T *d210, T *d211, T *d212, T *d220, T *d221, T *d222, const int i)
67  : inc(i) {
69  data, d000, d001, d002, d010, d011, d012, d020, d021, d022, d100, d101,
70  d102, d110, d111, d112, d120, d121, d122, d200, d201, d202, d210, d211,
71  d212, d220, d221, d222);
72  }
73 
74  /* Tensor_Dim0=4, Tensor_Dim1=4, Tensor_Dim2=4 */
75  Tensor3(T *d000, T *d001, T *d002, T *d003, T *d010, T *d011, T *d012,
76  T *d013, T *d020, T *d021, T *d022, T *d023, T *d030, T *d031,
77  T *d032, T *d033,
78 
79  T *d100, T *d101, T *d102, T *d103, T *d110, T *d111, T *d112,
80  T *d113, T *d120, T *d121, T *d122, T *d123, T *d130, T *d131,
81  T *d132, T *d133,
82 
83  T *d200, T *d201, T *d202, T *d203, T *d210, T *d211, T *d212,
84  T *d213, T *d220, T *d221, T *d222, T *d223, T *d230, T *d231,
85  T *d232, T *d233,
86 
87  T *d300, T *d301, T *d302, T *d303, T *d310, T *d311, T *d312,
88  T *d313, T *d320, T *d321, T *d322, T *d323, T *d330, T *d331,
89  T *d332, T *d333, const int i)
90  : inc(i) {
92  data, d000, d001, d002, d003, d010, d011, d012, d013, d020, d021, d022,
93  d023, d030, d031, d032, d033,
94 
95  d100, d101, d102, d103, d110, d111, d112, d113, d120, d121, d122, d123,
96  d130, d131, d132, d133,
97 
98  d200, d201, d202, d203, d210, d211, d212, d213, d220, d221, d222, d223,
99  d230, d231, d232, d233,
100 
101  d300, d301, d302, d303, d310, d311, d312, d313, d320, d321, d322, d323,
102  d330, d331, d332, d333);
103  }
104 
105  /* Initializations for varying numbers of elements. */
106  template <class... U> Tensor3(U *...d) : data{d...}, inc(1) {}
107 
108  template <class U>
109  Tensor3(std::array<U *, Tensor_Dim0 * Tensor_Dim1 * Tensor_Dim2> &a,
110  const int i = 1)
111  : inc(i) {
112  int l = 0;
113  for (int i = 0; i != Tensor_Dim0; ++i) {
114  for (int j = 0; j != Tensor_Dim1; ++j) {
115  for (int k = 0; k != Tensor_Dim2; ++k, ++l) {
116  data[i][j][k] = a[l];
117  }
118  }
119  }
120  }
121 
122  /* There are two operator(int,int,int)'s, one for non-consts that lets you
123  change the value, and one for consts that doesn't. */
124 
125  T &operator()(const int N1, const int N2, const int N3) {
126 #ifdef FTENSOR_DEBUG
127  if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 ||
128  N3 >= Tensor_Dim2 || N3 < 0) {
129  std::stringstream s;
130  s << "Bad index in Tensor3<T," << Tensor_Dim0 << "," << Tensor_Dim1 << ","
131  << Tensor_Dim2 << ">.operator(" << N1 << "," << N2 << "," << N3 << ")"
132  << std::endl;
133  throw std::runtime_error(s.str());
134  }
135 #endif
136  return *data[N1][N2][N3];
137  }
138 
139  T operator()(const int N1, const int N2, const int N3) const {
140 #ifdef FTENSOR_DEBUG
141  if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0 ||
142  N3 >= Tensor_Dim2 || N3 < 0) {
143  std::stringstream s;
144  s << "Bad index in Tensor3<T," << Tensor_Dim0 << "," << Tensor_Dim1 << ","
145  << Tensor_Dim2 << ">.operator(" << N1 << "," << N2 << "," << N3
146  << ") const" << std::endl;
147  throw std::runtime_error(s.str());
148  }
149 #endif
150  return *data[N1][N2][N3];
151  }
152 
153  /* These operator()'s are the first part in constructing template
154  expressions. */
155 
156  template <char i, char j, char k, int Dim0, int Dim1, int Dim2>
158  Dim1, Dim2, i, j, k>
161  Dim0, Dim1, Dim2, i, j, k>(*this);
162  }
163 
164  template <char i, char j, char k, int Dim0, int Dim1, int Dim2>
166  Dim0, Dim1, Dim2, i, j, k>
168  const Index<k, Dim2>) const {
169  return Tensor3_Expr<
171  Dim1, Dim2, i, j, k>(*this);
172  }
173 
174  /* The ++ operator increments the pointer, not the number that the
175  pointer points to. This allows iterating over a grid. */
176 
177  template <int Current_Dim0, int Current_Dim1, int Current_Dim2>
178  inline void increment(const Number<Current_Dim0> &,
179  const Number<Current_Dim1> &,
180  const Number<Current_Dim2> &) const {
181  data[Current_Dim0 - 1][Current_Dim1 - 1][Current_Dim2 - 1] += inc;
182  }
183 
184  const Tensor3 &operator++() const {
187  return *this;
188  }
189 
190 private:
191  template <int I>
192  Tensor3(const Tensor3<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>
193  &) = delete;
194 };
195 
196 template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2, int I>
197 class Tensor3<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>
199 
200 public:
201  Tensor3() {}
202 
203  /* Initializations for varying numbers of elements. */
204  template <class... U>
205  Tensor3(U *...d)
206  : Tensor3<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>{d...} {}
207 
208  template <class U>
209  Tensor3(std::array<U *, Tensor_Dim0 * Tensor_Dim1 * Tensor_Dim2> &a)
210  : Tensor3<T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>(a) {}
211 
212  /* The ++ operator increments the pointer, not the number that the
213  pointer points to. This allows iterating over a grid. */
214 
215  template <int Current_Dim0, int Current_Dim1, int Current_Dim2>
216  inline void increment(const Number<Current_Dim0> &,
217  const Number<Current_Dim1> &,
218  const Number<Current_Dim2> &) const {
219  Tensor3<T *, Tensor_Dim0, Tensor_Dim1,
220  Tensor_Dim2>::data[Current_Dim0 - 1][Current_Dim1 - 1]
221  [Current_Dim2 - 1] += I;
222  }
223 
224  const Tensor3 &operator++() const {
227  return *this;
228  }
229 };
230 } // namespace FTensor
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::increment
void increment(const Number< Current_Dim0 > &, const Number< Current_Dim1 > &, const Number< Current_Dim2 > &) const
Definition: Tensor3_pointer.hpp:178
FTensor::Tensor3< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::Tensor3
Tensor3(std::array< U *, Tensor_Dim0 *Tensor_Dim1 *Tensor_Dim2 > &a)
Definition: Tensor3_pointer.hpp:209
FTensor
JSON compatible output.
Definition: Christof_constructor.hpp:6
FTensor::Tensor3< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::Tensor3
Tensor3(U *...d)
Definition: Tensor3_pointer.hpp:205
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::Tensor3
Tensor3(std::array< U *, Tensor_Dim0 *Tensor_Dim1 *Tensor_Dim2 > &a, const int i=1)
Definition: Tensor3_pointer.hpp:109
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::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::operator++
const Tensor3 & operator++() const
Definition: Tensor3_pointer.hpp:184
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::operator()
Tensor3_Expr< Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >, T, Dim0, Dim1, Dim2, i, j, k > operator()(const Index< i, Dim0 >, const Index< j, Dim1 >, const Index< k, Dim2 >)
Definition: Tensor3_pointer.hpp:159
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::inc
const int inc
Definition: Tensor3_pointer.hpp:46
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::Tensor3
Tensor3(T *d000, T *d001, T *d002, T *d010, T *d011, T *d012, T *d020, T *d021, T *d022, T *d100, T *d101, T *d102, T *d110, T *d111, T *d112, T *d120, T *d121, T *d122, T *d200, T *d201, T *d202, T *d210, T *d211, T *d212, T *d220, T *d221, T *d222, const int i)
Definition: Tensor3_pointer.hpp:63
I
constexpr IntegrationType I
Definition: operators_tests.cpp:31
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::Tensor3
Tensor3(T *d000, T *d001, T *d002, T *d003, T *d010, T *d011, T *d012, T *d013, T *d020, T *d021, T *d022, T *d023, T *d030, T *d031, T *d032, T *d033, T *d100, T *d101, T *d102, T *d103, T *d110, T *d111, T *d112, T *d113, T *d120, T *d121, T *d122, T *d123, T *d130, T *d131, T *d132, T *d133, T *d200, T *d201, T *d202, T *d203, T *d210, T *d211, T *d212, T *d213, T *d220, T *d221, T *d222, T *d223, T *d230, T *d231, T *d232, T *d233, T *d300, T *d301, T *d302, T *d303, T *d310, T *d311, T *d312, T *d313, T *d320, T *d321, T *d322, T *d323, T *d330, T *d331, T *d332, T *d333, const int i)
Definition: Tensor3_pointer.hpp:75
FTensor::Number
Definition: Number.hpp:11
FTensor::Tensor3
Definition: Tensor3_value.hpp:12
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::Tensor3
Tensor3(U *...d)
Definition: Tensor3_pointer.hpp:106
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >
Definition: Tensor3_pointer.hpp:45
a
constexpr double a
Definition: approx_sphere.cpp:30
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::operator()
Tensor3_Expr< const Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >, T, Dim0, Dim1, Dim2, i, j, k > operator()(const Index< i, Dim0 >, const Index< j, Dim1 >, const Index< k, Dim2 >) const
Definition: Tensor3_pointer.hpp:167
FTensor::PackPtr
Definition: FTensor.hpp:54
FTensor::Tensor3_Expr
Definition: Tensor3_Expr.hpp:24
FTensor::Tensor3< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::operator++
const Tensor3 & operator++() const
Definition: Tensor3_pointer.hpp:224
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::operator()
T & operator()(const int N1, const int N2, const int N3)
Definition: Tensor3_pointer.hpp:125
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::operator()
T operator()(const int N1, const int N2, const int N3) const
Definition: Tensor3_pointer.hpp:139
FTensor::Index
Definition: Index.hpp:23
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::Tensor3
Tensor3()
Definition: Tensor3_pointer.hpp:52
FTensor::T3_increment
void T3_increment(const Tensor3< T, Dim0, Dim1, Dim2 > &iter, const Number< Current_Dim0 > &, const Number< Current_Dim1 > &, const Number< Current_Dim2 > &)
Definition: Tensor3_pointer.hpp:8
FTensor::Tensor3< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::increment
void increment(const Number< Current_Dim0 > &, const Number< Current_Dim1 > &, const Number< Current_Dim2 > &) const
Definition: Tensor3_pointer.hpp:216
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
FTensor::Tensor3_constructor
Definition: Tensor3_constructor.hpp:9
FTensor::Tensor3< T *, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::Tensor3
Tensor3(T *d000, T *d001, T *d010, T *d011, T *d100, T *d101, T *d110, T *d111, const int i)
Definition: Tensor3_pointer.hpp:55
k
FTensor::Index< 'k', 3 > k
Definition: matrix_function.cpp:20
EshelbianPlasticity::U
@ U
Definition: EshelbianContact.cpp:197
l
FTensor::Index< 'l', 3 > l
Definition: matrix_function.cpp:21
FTensor::Tensor3< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 >::Tensor3
Tensor3()
Definition: Tensor3_pointer.hpp:201