v0.14.0
Tensor2_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 Tensor_Dim0, int Tensor_Dim1>
8 class Tensor2<T *, Tensor_Dim0, Tensor_Dim1> {
9 
10 protected:
11 
12  mutable T *restrict data[Tensor_Dim0][Tensor_Dim1];
13  const int inc;
14 
15 public:
16  /* Initializations for varying numbers of elements. */
17 
18  Tensor2(T *d00, T *d01, T *d10, T *d11, const int i) : inc(i) {
20  data, d00, d01, d10, d11);
21  }
22  Tensor2(T *d00, T *d01, T *d10, T *d11, T *d20, T *d21, const int i)
23  : inc(i) {
25  data, d00, d01, d10, d11, d20, d21);
26  }
27  Tensor2(T *d00, T *d01, T *d02, T *d10, T *d11, T *d12, T *d20, T *d21,
28  T *d22, const int i)
29  : inc(i) {
31  data, d00, d01, d02, d10, d11, d12, d20, d21, d22);
32  }
33  Tensor2(T *d00, T *d01, T *d02, T *d03, T *d10, T *d11, T *d12, T *d13,
34  T *d20, T *d21, T *d22, T *d23, T *d30, T *d31, T *d32, T *d33,
35  const int i)
36  : inc(i) {
38  data, d00, d01, d02, d03, d10, d11, d12, d13, d20, d21, d22, d23, d30,
39  d31, d32, d33);
40  }
41 
42  /* Initializations for varying numbers of elements. */
43  template <class... U> Tensor2(U *...d) : data{d...}, inc(1) {}
44 
45  template <class U>
46  Tensor2(std::array<U *, Tensor_Dim0 * Tensor_Dim1> &a, const int i = 1)
47  : inc(i) {
48  int k = 0;
49  for (int i = 0; i != Tensor_Dim0; ++i) {
50  for (int j = 0; j != Tensor_Dim1; ++j, ++k) {
51  data[i][j] = a[k];
52  }
53  }
54  }
55 
56  Tensor2() {}
57 
58  Tensor2(const int i = 1) : inc(i) {}
59 
60  /* There are two operator(int,int)'s, one for non-consts that lets you
61  change the value, and one for consts that doesn't. */
62 
63  T &operator()(const int N1, const int N2) {
64 #ifdef FTENSOR_DEBUG
65  if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0) {
66  std::stringstream s;
67  s << "Bad index in Tensor2<T*," << Tensor_Dim0 << "," << Tensor_Dim1
68  << ">.operator(" << N1 << "," << N2 << ")" << std::endl;
69  throw std::out_of_range(s.str());
70  }
71 #endif
72  return *data[N1][N2];
73  }
74 
75  T operator()(const int N1, const int N2) const {
76 #ifdef FTENSOR_DEBUG
77  if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0) {
78  std::stringstream s;
79  s << "Bad index in Tensor2<T*," << Tensor_Dim0 << "," << Tensor_Dim1
80  << ">.operator(" << N1 << "," << N2 << ") const" << std::endl;
81  throw std::out_of_range(s.str());
82  }
83 #endif
84  return *data[N1][N2];
85  }
86 
87  T *ptr(const int N1, const int N2) const {
88 #ifdef FTENSOR_DEBUG
89  if (N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim1 || N2 < 0) {
90  std::stringstream s;
91  s << "Bad index in Tensor2<T*," << Tensor_Dim0 << "," << Tensor_Dim1
92  << ">.ptr(" << N1 << "," << N2 << ")" << std::endl;
93  throw std::out_of_range(s.str());
94  }
95 #endif
96  return data[N1][N2];
97  }
98 
99  /* These operator()'s are the first part in constructing template
100  expressions. They can be used to slice off lower dimensional
101  parts. They are not entirely safe, since you can accidentaly use a
102  higher dimension than what is really allowed (like Dim=5). */
103 
104  template <char i, char j, int Dim0, int Dim1>
106  operator()(const Index<i, Dim0>, const Index<j, Dim1> index2) {
108  i, j>(*this);
109  }
110 
111  template <char i, char j, int Dim0, int Dim1>
113  j>
114  operator()(const Index<i, Dim0>, const Index<j, Dim1> index2) const {
116  Dim1, i, j>(*this);
117  }
118 
119  /* This is for expressions where a number is used for one slot, and
120  an index for another, yielding a Tensor1_Expr. The non-const
121  versions don't actually create a Tensor2_number_rhs_[01] object.
122  They create a Tensor1_Expr directly, which provides the
123  appropriate indexing operators. The const versions do create a
124  Tensor2_number_[01]. */
125 
126  template <char i, int Dim, int N>
127  Tensor1_Expr<
129  Dim, i>
131  using TensorExpr =
134  }
135 
136  template <char i, int Dim, int N>
137  Tensor1_Expr<
139  Dim, i>
141  using TensorExpr =
144  }
145 
146  template <char i, int Dim, int N>
149  T, Dim, i>
150  operator()(const Index<i, Dim>, const Number<N>) const {
151  using TensorExpr =
153  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this));
154  }
155 
156  template <char i, int Dim, int N>
159  T, Dim, i>
160  operator()(const Number<N>, const Index<i, Dim>) const {
161  using TensorExpr =
163  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this));
164  }
165 
166  /* The ++ operator increments the pointer, not the number that the
167  pointer points to. This allows iterating over a grid. */
168 
169  const Tensor2 &operator++() const {
170  for (int i = 0; i < Tensor_Dim0; ++i)
171  for (int j = 0; j < Tensor_Dim1; ++j)
172  data[i][j] += inc;
173  return *this;
174  }
175 
176  /* These two operator()'s return the Tensor2 with internal
177  contractions, yielding a T. I have to specify one for both
178  const and non-const because otherwise they compiler will use the
179  operator() which gives a Tensor2_Expr<>. */
180 
181  template <char i, int Dim>
182  T operator()(const Index<i, Dim>, const Index<i, Dim> index2) {
183  return internal_contract(Number<Dim>());
184  }
185 
186  template <char i, int Dim>
187  T operator()(const Index<i, Dim>, const Index<i, Dim> index2) const {
188  return internal_contract(Number<Dim>());
189  }
190 
191 private:
192  template <int N> T internal_contract(Number<N>) const {
193  return *data[N - 1][N - 1] + internal_contract(Number<N - 1>());
194  }
195 
196  T internal_contract(Number<1>) const { return *data[0][0]; }
197 
198 private:
199  /**
200  * @brief Preventing casting on derived class
201  *
202  * That can be source of errors
203  *
204  */
205  template <int I>
206  Tensor2(const Tensor2<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1> &) = delete;
207 };
208 
209 template <class T, int Tensor_Dim0, int Tensor_Dim1, int I>
210 class Tensor2<PackPtr<T *, I>, Tensor_Dim0, Tensor_Dim1>
212 
213 public:
214  /* Initializations for varying numbers of elements. */
215  template <class... U>
216  Tensor2(U *...d) : Tensor2<T *, Tensor_Dim0, Tensor_Dim1>(d...) {}
217 
218  Tensor2() : Tensor2<T, Tensor_Dim0, Tensor_Dim1>() {}
219 
220  template <class U>
221  Tensor2(std::array<U *, Tensor_Dim0 * Tensor_Dim1> &a)
222  : Tensor2<T *, Tensor_Dim0, Tensor_Dim1>(a) {}
223 
224  /* The ++ operator increments the pointer, not the number that the
225  pointer points to. This allows iterating over a grid. */
226 
227  const Tensor2 &operator++() const {
228  for (int i = 0; i < Tensor_Dim0; ++i)
229  for (int j = 0; j < Tensor_Dim1; ++j)
231  return *this;
232  }
233 };
234 
235 } // namespace FTensor
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator()
Tensor2_Expr< Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, Dim0, Dim1, i, j > operator()(const Index< i, Dim0 >, const Index< j, Dim1 > index2)
Definition: Tensor2_pointer.hpp:106
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator()
Tensor2_Expr< const Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, Dim0, Dim1, i, j > operator()(const Index< i, Dim0 >, const Index< j, Dim1 > index2) const
Definition: Tensor2_pointer.hpp:114
FTensor::Tensor2< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2(std::array< U *, Tensor_Dim0 *Tensor_Dim1 > &a)
Definition: Tensor2_pointer.hpp:221
FTensor
JSON compatible output.
Definition: Christof_constructor.hpp:6
FTensor::Tensor2< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1 >::operator++
const Tensor2 & operator++() const
Definition: Tensor2_pointer.hpp:227
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2(T *d00, T *d01, T *d10, T *d11, const int i)
Definition: Tensor2_pointer.hpp:18
FTensor::Tensor2_constructor
Definition: Tensor2_constructor.hpp:10
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2(T *d00, T *d01, T *d02, T *d10, T *d11, T *d12, T *d20, T *d21, T *d22, const int i)
Definition: Tensor2_pointer.hpp:27
FTensor::Tensor2_number_rhs_1
Definition: Tensor2_number.hpp:29
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2(std::array< U *, Tensor_Dim0 *Tensor_Dim1 > &a, const int i=1)
Definition: Tensor2_pointer.hpp:46
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator()
Tensor1_Expr< const Tensor2_number_0< const Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, N >, T, Dim, i > operator()(const Number< N >, const Index< i, Dim >) const
Definition: Tensor2_pointer.hpp:160
FTensor::Tensor2_Expr
Definition: Tensor2_Expr.hpp:26
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::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator()
T operator()(const Index< i, Dim >, const Index< i, Dim > index2) const
Definition: Tensor2_pointer.hpp:187
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2(U *...d)
Definition: Tensor2_pointer.hpp:43
FTensor::Tensor2
Definition: Tensor2_value.hpp:16
I
constexpr IntegrationType I
Definition: operators_tests.cpp:31
FTensor::Tensor2_number_1
Definition: Tensor2_number.hpp:8
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::internal_contract
T internal_contract(Number< N >) const
Definition: Tensor2_pointer.hpp:192
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator()
T operator()(const int N1, const int N2) const
Definition: Tensor2_pointer.hpp:75
FTensor::Number
Definition: Number.hpp:11
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2(T *d00, T *d01, T *d02, T *d03, T *d10, T *d11, T *d12, T *d13, T *d20, T *d21, T *d22, T *d23, T *d30, T *d31, T *d32, T *d33, const int i)
Definition: Tensor2_pointer.hpp:33
FTensor::Tensor1_Expr
Definition: Tensor1_Expr.hpp:27
a
constexpr double a
Definition: approx_sphere.cpp:30
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2()
Definition: Tensor2_pointer.hpp:56
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator()
T operator()(const Index< i, Dim >, const Index< i, Dim > index2)
Definition: Tensor2_pointer.hpp:182
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::ptr
T * ptr(const int N1, const int N2) const
Definition: Tensor2_pointer.hpp:87
FTensor::Tensor2< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2()
Definition: Tensor2_pointer.hpp:218
FTensor::Tensor2< PackPtr< T *, I >, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2(U *...d)
Definition: Tensor2_pointer.hpp:216
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2(T *d00, T *d01, T *d10, T *d11, T *d20, T *d21, const int i)
Definition: Tensor2_pointer.hpp:22
FTensor::PackPtr
Definition: FTensor.hpp:54
FTensor::Tensor2_number_0
Definition: Tensor2_number.hpp:17
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator()
Tensor1_Expr< const Tensor2_number_1< const Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, N >, T, Dim, i > operator()(const Index< i, Dim >, const Number< N >) const
Definition: Tensor2_pointer.hpp:150
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::Tensor2
Tensor2(const int i=1)
Definition: Tensor2_pointer.hpp:58
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::inc
const int inc
Definition: Tensor2_pointer.hpp:13
FTensor::Index
Definition: Index.hpp:23
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >
Definition: Tensor2_pointer.hpp:8
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::internal_contract
T internal_contract(Number< 1 >) const
Definition: Tensor2_pointer.hpp:196
N
const int N
Definition: speed_test.cpp:3
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator()
Tensor1_Expr< Tensor2_number_rhs_1< Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, N >, T, Dim, i > operator()(const Index< i, Dim >, const Number< N >)
Definition: Tensor2_pointer.hpp:130
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator()
Tensor1_Expr< Tensor2_number_rhs_0< Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >, T, N >, T, Dim, i > operator()(const Number< N >, const Index< i, Dim >)
Definition: Tensor2_pointer.hpp:140
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
FTensor::Tensor2_number_rhs_0
Definition: Tensor2_number.hpp:26
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator()
T & operator()(const int N1, const int N2)
Definition: Tensor2_pointer.hpp:63
k
FTensor::Index< 'k', 3 > k
Definition: matrix_function.cpp:20
EshelbianPlasticity::U
@ U
Definition: EshelbianContact.cpp:193
FTensor::Tensor2< T *, Tensor_Dim0, Tensor_Dim1 >::operator++
const Tensor2 & operator++() const
Definition: Tensor2_pointer.hpp:169