v0.14.0
src
ftensor
src
FTensor
Dg
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
>
14
Dg<T, Tensor_Dim01, Tensor_Dim2>::
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>
24
Dg_Expr<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, Dim01, Dim2,
i
,
j
,
k
>
25
Dg<T, Tensor_Dim01, Tensor_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>
37
Tensor1_Expr
<
38
Tensor3_contracted_12<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, Dim12,
i
>,
39
T, Dim,
i
>
40
Dg<T, Tensor_Dim01, Tensor_Dim2>::
41
operator()
(
const
Index<i, Dim>
index1,
const
Index<j, Dim12>
index2,
42
const
Index<j, Dim12>
index3)
const
43
{
44
using
TensorExpr
45
=
Tensor3_contracted_12<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, Dim12,
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>
52
Tensor1_Expr
<
53
Tensor3_contracted_02<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, Dim02,
i
>,
54
T, Dim,
i
>
55
Dg<T, Tensor_Dim01, Tensor_Dim2>::
56
operator()
(
const
Index<j, Dim02>
index1,
const
Index<i, Dim>
index2,
57
const
Index<j, Dim02>
index3)
const
58
{
59
using
TensorExpr
60
=
Tensor3_contracted_02<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, Dim02,
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>
67
Tensor1_Expr
<
68
Tensor3_contracted_01<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, Dim01,
i
>,
69
T, Dim,
i
>
70
Dg<T, Tensor_Dim01, Tensor_Dim2>::
71
operator()
(
const
Index<j, Dim01>
index1,
const
Index<j, Dim01>
index2,
72
const
Index<i, Dim>
index3)
const
73
{
74
using
TensorExpr
75
=
Tensor3_contracted_01<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, Dim01,
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>
90
Tensor2_Expr<Dg_number_rhs_0<Dg<T, Tensor_Dim01, Tensor_Dim2>
, T,
N
>, T,
91
Dim0, Dim1,
i
,
j
>
92
Dg<T, Tensor_Dim01, Tensor_Dim2>::
93
operator()
(
const
Number<N>
n1,
const
Index<i, Dim0>
index1,
94
const
Index<j, Dim1>
index2)
95
{
96
using
TensorExpr =
Dg_number_rhs_0<Dg<T, Tensor_Dim01, Tensor_Dim2>
, T,
N
>;
97
return
Tensor2_Expr<TensorExpr, T, Dim0, Dim1, i, j>
(*
this
);
98
}
99
100
template
<
class
T,
int
Tensor_Dim01,
int
Tensor_Dim2>
101
template
<
char
i,
char
j,
int
N,
int
Dim0,
int
Dim1>
102
Tensor2_Expr<Dg_number_0<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T,
N
>, T,
103
Dim0, Dim1,
i
,
j
>
104
Dg<T, Tensor_Dim01, Tensor_Dim2>::
105
operator()
(
const
Number<N>
n1,
const
Index<i, Dim0>
index1,
106
const
Index<j, Dim1>
index2)
const
107
{
108
using
TensorExpr
109
=
Dg_number_0<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T,
N
>;
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>
117
Tensor2_Expr<Dg_number_rhs_0<Dg<T, Tensor_Dim01, Tensor_Dim2>
, T,
N
>, T,
118
Dim0, Dim1,
i
,
j
>
119
Dg<T, Tensor_Dim01, Tensor_Dim2>::
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
>;
124
return
Tensor2_Expr<TensorExpr, T, Dim0, Dim1, i, j>
(*
this
);
125
}
126
127
template
<
class
T,
int
Tensor_Dim01,
int
Tensor_Dim2>
128
template
<
char
i,
char
j,
int
N,
int
Dim0,
int
Dim1>
129
Tensor2_Expr<Dg_number_0<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T,
N
>, T,
130
Dim0, Dim1,
i
,
j
>
131
Dg<T, Tensor_Dim01, Tensor_Dim2>::
132
operator()
(
const
Index<i, Dim0>
index1,
const
Number<N>
n1,
133
const
Index<j, Dim1>
index2)
const
134
{
135
using
TensorExpr
136
=
Dg_number_0<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T,
N
>;
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>
144
Tensor2_symmetric_Expr
<
145
Dg_number_rhs_2<Dg<T, Tensor_Dim01, Tensor_Dim2>
, T,
N
>, T, Dim,
i
,
j
>
146
Dg<T, Tensor_Dim01, Tensor_Dim2>::
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
>;
151
return
Tensor2_symmetric_Expr<TensorExpr, T, Dim, i, j>
(*
this
);
152
}
153
154
template
<
class
T,
int
Tensor_Dim01,
int
Tensor_Dim2>
155
template
<
char
i,
char
j,
int
N,
int
Dim>
156
Tensor2_symmetric_Expr
<
157
Dg_number_2<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T,
N
>, T, Dim,
i
,
j
>
158
Dg<T, Tensor_Dim01, Tensor_Dim2>::
159
operator()
(
const
Index<i, Dim>
index1,
const
Index<j, Dim>
index2,
160
const
Number<N>
n1)
const
161
{
162
using
TensorExpr
163
=
Dg_number_2<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T,
N
>;
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>
176
Tensor1_Expr<Dg_number_rhs_12<Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>,
177
T, Dim,
i
>
178
Dg<T, Tensor_Dim01, Tensor_Dim2>::
179
operator()
(
const
Index<i, Dim>
index,
const
Number<N1>
n1,
180
const
Number<N2>
n2)
181
{
182
using
TensorExpr
183
=
Dg_number_rhs_12<Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>;
184
return
Tensor1_Expr<TensorExpr, T, Dim, i>
(*
this
);
185
}
186
187
template
<
class
T,
int
Tensor_Dim01,
int
Tensor_Dim2>
188
template
<
char
i,
int
N1,
int
N2,
int
Dim>
189
Tensor1_Expr<Dg_number_12<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>,
190
T, Dim,
i
>
191
Dg<T, Tensor_Dim01, Tensor_Dim2>::
192
operator()
(
const
Index<i, Dim>
index,
const
Number<N1>
n1,
193
const
Number<N2>
n2)
const
194
{
195
using
TensorExpr
196
=
Dg_number_12<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>;
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>
206
Tensor1_Expr<Dg_number_rhs_12<Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>,
207
T, Dim,
i
>
208
Dg<T, Tensor_Dim01, Tensor_Dim2>::
209
operator()
(
const
Number<N1>
n1,
const
Index<i, Dim>
index,
210
const
Number<N2>
n2)
211
{
212
using
TensorExpr
213
=
Dg_number_rhs_12<Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>;
214
return
Tensor1_Expr<TensorExpr, T, Dim, i>
(*
this
);
215
}
216
217
template
<
class
T,
int
Tensor_Dim01,
int
Tensor_Dim2>
218
template
<
char
i,
int
N1,
int
N2,
int
Dim>
219
Tensor1_Expr<Dg_number_12<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>,
220
T, Dim,
i
>
221
Dg<T, Tensor_Dim01, Tensor_Dim2>::
222
operator()
(
const
Number<N1>
n1,
const
Index<i, Dim>
index,
223
const
Number<N2>
n2)
const
224
{
225
using
TensorExpr
226
=
Dg_number_12<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>;
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>
234
Tensor1_Expr<Dg_number_rhs_01<Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>,
235
T, Dim,
i
>
236
Dg<T, Tensor_Dim01, Tensor_Dim2>::
237
operator()
(
const
Number<N1>
n1,
const
Number<N2>
n2,
238
const
Index<i, Dim>
index)
239
{
240
using
TensorExpr
241
=
Dg_number_rhs_01<Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>;
242
return
Tensor1_Expr<TensorExpr, T, Dim, i>
(*
this
);
243
}
244
245
template
<
class
T,
int
Tensor_Dim01,
int
Tensor_Dim2>
246
template
<
char
i,
int
N1,
int
N2,
int
Dim>
247
Tensor1_Expr<Dg_number_01<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>,
248
T, Dim,
i
>
249
Dg<T, Tensor_Dim01, Tensor_Dim2>::
250
operator()
(
const
Number<N1>
n1,
const
Number<N2>
n2,
251
const
Index<i, Dim>
index)
const
252
{
253
using
TensorExpr
254
=
Dg_number_01<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T, N1, N2>;
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>
267
Tensor2_Expr<Dg_numeral_0<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>, T,
268
Dim0, Dim1,
i
,
j
>
269
Dg<T, Tensor_Dim01, Tensor_Dim2>::
270
operator()
(
const
int
N
,
const
Index<i, Dim0>
index1,
271
const
Index<j, Dim1>
index2)
const
272
{
273
using
TensorExpr =
Dg_numeral_0<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>;
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>
281
Tensor2_Expr<Dg_numeral_0<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>, T,
282
Dim0, Dim1,
i
,
j
>
283
Dg<T, Tensor_Dim01, Tensor_Dim2>::
284
operator()
(
const
Index<i, Dim0>
index1,
const
int
N
,
285
const
Index<j, Dim1>
index2)
const
286
{
287
using
TensorExpr =
Dg_numeral_0<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>;
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>
295
Tensor2_symmetric_Expr
<
296
Dg_numeral_2<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>, T, Dim,
i
,
j
>
297
Dg<T, Tensor_Dim01, Tensor_Dim2>::
298
operator()
(
const
Index<i, Dim>
index1,
const
Index<j, Dim>
index2,
299
const
int
N
)
const
300
{
301
using
TensorExpr =
Dg_numeral_2<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>;
302
return
Tensor2_symmetric_Expr<TensorExpr, T, Dim, i, j>
(
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>
314
Tensor1_Expr<Dg_numeral_12<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>, T,
315
Dim,
i
>
316
Dg<T, Tensor_Dim01, Tensor_Dim2>::
317
operator()
(
const
Index<i, Dim>
index,
const
int
N1,
const
int
N2)
const
318
{
319
using
TensorExpr
320
=
Dg_numeral_12<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>;
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>
330
Tensor1_Expr<Dg_numeral_12<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>, T,
331
Dim,
i
>
332
Dg<T, Tensor_Dim01, Tensor_Dim2>::
333
operator()
(
const
int
N1,
const
Index<i, Dim>
index,
const
int
N2)
const
334
{
335
using
TensorExpr
336
=
Dg_numeral_12<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>;
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>
344
Tensor1_Expr<Dg_numeral_01<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>, T,
345
Dim,
i
>
346
Dg<T, Tensor_Dim01, Tensor_Dim2>::
347
operator()
(
const
int
N1,
const
int
N2,
const
Index<i, Dim>
index)
const
348
{
349
using
TensorExpr
350
=
Dg_numeral_01<const Dg<T, Tensor_Dim01, Tensor_Dim2>
, T>;
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
Generated by
Doxygen
1.8.17 and hosted at