v0.14.0
Dg_function_operator.hpp
Go to the documentation of this file.
1 /* This contains the definitions of the almost all of the indexing
2  operators for Dg. */
3 
4 #pragma once
5 
6 namespace FTensor
7 {
8  /* These operator()'s are the first part in constructing template
9  expressions. */
10 
11  template <class T, int Tensor_Dim01, int Tensor_Dim2>
12  template <char i, char j, char k, int Dim01, int Dim2>
13  Dg_Expr<Dg<T, Tensor_Dim01, Tensor_Dim2>, T, Dim01, Dim2, i, j, k>
15  operator()(const Index<i, Dim01> index1, const Index<j, Dim01> index2,
16  const Index<k, Dim2> index3)
17  {
18  return Dg_Expr<Dg<T, Tensor_Dim01, Tensor_Dim2>, T, Dim01, Dim2, i, j, k>(
19  *this);
20  }
21 
22  template <class T, int Tensor_Dim01, int Tensor_Dim2>
23  template <char i, char j, char k, int Dim01, int Dim2>
26  operator()(const Index<i, Dim01> index1, const Index<j, Dim01> index2,
27  const Index<k, Dim2> index3) const
28  {
29  return Dg_Expr<const Dg<T, Tensor_Dim01, Tensor_Dim2>, T, Dim01, Dim2, i,
30  j, k>(*this);
31  }
32 
33  /* These operators are for internal contractions. */
34 
35  template <class T, int Tensor_Dim01, int Tensor_Dim2>
36  template <char i, char j, int Dim, int Dim12>
39  T, Dim, i>
41  operator()(const Index<i, Dim> index1, const Index<j, Dim12> index2,
42  const Index<j, Dim12> index3) const
43  {
44  using TensorExpr
46  i>;
47  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this));
48  }
49 
50  template <class T, int Tensor_Dim01, int Tensor_Dim2>
51  template <char i, char j, int Dim, int Dim02>
54  T, Dim, i>
56  operator()(const Index<j, Dim02> index1, const Index<i, Dim> index2,
57  const Index<j, Dim02> index3) const
58  {
59  using TensorExpr
61  i>;
62  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this));
63  }
64 
65  template <class T, int Tensor_Dim01, int Tensor_Dim2>
66  template <char i, char j, int Dim, int Dim01>
69  T, Dim, i>
71  operator()(const Index<j, Dim01> index1, const Index<j, Dim01> index2,
72  const Index<i, Dim> index3) const
73  {
74  using TensorExpr
76  i>;
77  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this));
78  }
79 
80  /* This is for expressions where a number is used for one slot, and
81  indices for the others, yielding a Tensor2_Expr or
82  Tensor2_symmetric_Expr. The non-const versions don't actually
83  create a Dg_number_rhs_* object, while the const versions
84  do create a Dg_number_*. */
85 
86  /* First slot. */
87 
88  template <class T, int Tensor_Dim01, int Tensor_Dim2>
89  template <char i, char j, int N, int Dim0, int Dim1>
91  Dim0, Dim1, i, j>
93  operator()(const Number<N> n1, const Index<i, Dim0> index1,
94  const Index<j, Dim1> index2)
95  {
98  }
99 
100  template <class T, int Tensor_Dim01, int Tensor_Dim2>
101  template <char i, char j, int N, int Dim0, int Dim1>
103  Dim0, Dim1, i, j>
105  operator()(const Number<N> n1, const Index<i, Dim0> index1,
106  const Index<j, Dim1> index2) const
107  {
108  using TensorExpr
110  return Tensor2_Expr<TensorExpr, T, Dim0, Dim1, i, j>(TensorExpr(*this));
111  }
112 
113  /* Second slot. */
114 
115  template <class T, int Tensor_Dim01, int Tensor_Dim2>
116  template <char i, char j, int N, int Dim0, int Dim1>
118  Dim0, Dim1, i, j>
120  operator()(const Index<i, Dim0> index1, const Number<N> n1,
121  const Index<j, Dim1> index2)
122  {
123  using TensorExpr = Dg_number_rhs_0<Dg<T, Tensor_Dim01, Tensor_Dim2>, T, N>;
125  }
126 
127  template <class T, int Tensor_Dim01, int Tensor_Dim2>
128  template <char i, char j, int N, int Dim0, int Dim1>
130  Dim0, Dim1, i, j>
132  operator()(const Index<i, Dim0> index1, const Number<N> n1,
133  const Index<j, Dim1> index2) const
134  {
135  using TensorExpr
137  return Tensor2_Expr<TensorExpr, T, Dim0, Dim1, i, j>(TensorExpr(*this));
138  }
139 
140  /* Third slot. */
141 
142  template <class T, int Tensor_Dim01, int Tensor_Dim2>
143  template <char i, char j, int N, int Dim>
147  operator()(const Index<i, Dim> index1, const Index<j, Dim> index2,
148  const Number<N> n1)
149  {
150  using TensorExpr = Dg_number_rhs_2<Dg<T, Tensor_Dim01, Tensor_Dim2>, T, N>;
152  }
153 
154  template <class T, int Tensor_Dim01, int Tensor_Dim2>
155  template <char i, char j, int N, int Dim>
159  operator()(const Index<i, Dim> index1, const Index<j, Dim> index2,
160  const Number<N> n1) const
161  {
162  using TensorExpr
164  return Tensor2_symmetric_Expr<TensorExpr, T, Dim, i, j>(TensorExpr(*this));
165  }
166 
167  /* This is for expressions where a number is used for two slots, and
168  an Index for the other, yielding a Tensor1_Expr. The non-const
169  versions don't actually create a Dg_number_rhs_* object,
170  while the const versions do create a Dg_number_*. */
171 
172  /* Index in first slot. */
173 
174  template <class T, int Tensor_Dim01, int Tensor_Dim2>
175  template <char i, int N1, int N2, int Dim>
177  T, Dim, i>
179  operator()(const Index<i, Dim> index, const Number<N1> n1,
180  const Number<N2> n2)
181  {
182  using TensorExpr
185  }
186 
187  template <class T, int Tensor_Dim01, int Tensor_Dim2>
188  template <char i, int N1, int N2, int Dim>
190  T, Dim, i>
192  operator()(const Index<i, Dim> index, const Number<N1> n1,
193  const Number<N2> n2) const
194  {
195  using TensorExpr
197  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this));
198  }
199 
200  /* Index in second slot. I use the same structures as for the Index
201  in the first slot since the tensor is symmetric on the first two
202  indices. */
203 
204  template <class T, int Tensor_Dim01, int Tensor_Dim2>
205  template <char i, int N1, int N2, int Dim>
207  T, Dim, i>
209  operator()(const Number<N1> n1, const Index<i, Dim> index,
210  const Number<N2> n2)
211  {
212  using TensorExpr
215  }
216 
217  template <class T, int Tensor_Dim01, int Tensor_Dim2>
218  template <char i, int N1, int N2, int Dim>
220  T, Dim, i>
222  operator()(const Number<N1> n1, const Index<i, Dim> index,
223  const Number<N2> n2) const
224  {
225  using TensorExpr
227  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this));
228  }
229 
230  /* Index in third slot. */
231 
232  template <class T, int Tensor_Dim01, int Tensor_Dim2>
233  template <char i, int N1, int N2, int Dim>
235  T, Dim, i>
237  operator()(const Number<N1> n1, const Number<N2> n2,
238  const Index<i, Dim> index)
239  {
240  using TensorExpr
243  }
244 
245  template <class T, int Tensor_Dim01, int Tensor_Dim2>
246  template <char i, int N1, int N2, int Dim>
248  T, Dim, i>
250  operator()(const Number<N1> n1, const Number<N2> n2,
251  const Index<i, Dim> index) const
252  {
253  using TensorExpr
255  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this));
256  }
257 
258  /* Specializations for using actual numbers instead of Number<>.
259  This is for expressions where an actual number is used for one
260  slot, and indices for the others, yielding a Tensor2_Expr or
261  Tensor2_symmetric_Expr. I only define the const versions. */
262 
263  /* First slot. */
264 
265  template <class T, int Tensor_Dim01, int Tensor_Dim2>
266  template <char i, char j, int Dim0, int Dim1>
268  Dim0, Dim1, i, j>
270  operator()(const int N, const Index<i, Dim0> index1,
271  const Index<j, Dim1> index2) const
272  {
274  return Tensor2_Expr<TensorExpr, T, Dim0, Dim1, i, j>(TensorExpr(*this, N));
275  }
276 
277  /* Second slot. */
278 
279  template <class T, int Tensor_Dim01, int Tensor_Dim2>
280  template <char i, char j, int Dim0, int Dim1>
282  Dim0, Dim1, i, j>
284  operator()(const Index<i, Dim0> index1, const int N,
285  const Index<j, Dim1> index2) const
286  {
288  return Tensor2_Expr<TensorExpr, T, Dim0, Dim1, i, j>(TensorExpr(*this, N));
289  }
290 
291  /* Third slot. */
292 
293  template <class T, int Tensor_Dim01, int Tensor_Dim2>
294  template <char i, char j, int Dim>
298  operator()(const Index<i, Dim> index1, const Index<j, Dim> index2,
299  const int N) const
300  {
303  TensorExpr(*this, N));
304  }
305 
306  /* This is for expressions where an actual number is used for two
307  slots, and an Index for the other, yielding a Tensor1_Expr. I
308  only define the const versions. */
309 
310  /* Index in first slot. */
311 
312  template <class T, int Tensor_Dim01, int Tensor_Dim2>
313  template <char i, int Dim>
315  Dim, i>
317  operator()(const Index<i, Dim> index, const int N1, const int N2) const
318  {
319  using TensorExpr
321  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this, N1, N2));
322  }
323 
324  /* Index in second slot. I use the same structures as for the Index
325  in the first slot since the tensor is symmetric on the first two
326  indices. */
327 
328  template <class T, int Tensor_Dim01, int Tensor_Dim2>
329  template <char i, int Dim>
331  Dim, i>
333  operator()(const int N1, const Index<i, Dim> index, const int N2) const
334  {
335  using TensorExpr
337  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this, N1, N2));
338  }
339 
340  /* Index in third slot. */
341 
342  template <class T, int Tensor_Dim01, int Tensor_Dim2>
343  template <char i, int Dim>
345  Dim, i>
347  operator()(const int N1, const int N2, const Index<i, Dim> index) const
348  {
349  using TensorExpr
351  return Tensor1_Expr<TensorExpr, T, Dim, i>(TensorExpr(*this, N1, N2));
352  }
353 }
FTensor
JSON compatible output.
Definition: Christof_constructor.hpp:6
FTensor::Dg_number_12
Definition: Dg_number.hpp:39
FTensor::Tensor2_symmetric_Expr
Definition: Tensor2_symmetric_Expr.hpp:36
FTensor::Dg_numeral_01
Definition: Dg_numeral.hpp:49
FTensor::Dg_number_2
Definition: Dg_number.hpp:25
FTensor::Tensor2_Expr
Definition: Tensor2_Expr.hpp:26
FTensor::Dg_numeral_0
Definition: Dg_numeral.hpp:11
FTensor::Tensor3_contracted_12
Definition: Tensor3_contracted.hpp:10
FTensor::Number
Definition: Number.hpp:11
FTensor::Tensor1_Expr
Definition: Tensor1_Expr.hpp:27
FTensor::Dg_number_rhs_2
Definition: Dg_number.hpp:34
FTensor::Dg_number_01
Definition: Dg_number.hpp:53
FTensor::Dg_numeral_12
Definition: Dg_numeral.hpp:35
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
FTensor::Dg::operator()
T & operator()(const int N1, const int N2, const int N3)
Definition: Dg_value.hpp:26
FTensor::Index
Definition: Index.hpp:23
FTensor::Tensor3_contracted_01
Definition: Tensor3_contracted.hpp:48
N
const int N
Definition: speed_test.cpp:3
FTensor::Dg_number_0
Definition: Dg_number.hpp:11
FTensor::Dg_Expr
Definition: Dg_Expr.hpp:25
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
FTensor::Dg_number_rhs_01
Definition: Dg_number.hpp:62
FTensor::Dg_number_rhs_12
Definition: Dg_number.hpp:48
FTensor::Tensor3_contracted_02
Definition: Tensor3_contracted.hpp:29
FTensor::Dg_numeral_2
Definition: Dg_numeral.hpp:23
k
FTensor::Index< 'k', 3 > k
Definition: matrix_function.cpp:20
FTensor::Dg_number_rhs_0
Definition: Dg_number.hpp:20