v0.14.0
Tensor2_times_Tensor2.hpp
Go to the documentation of this file.
1 /* This file has all of the declarations for Tensor2*Tensor2. This
2  includes the double contraction A(i,j)*B(i,j) (yielding a
3  typename promote<T,U>) as well as the more complicated single contraction
4  A(i,j)*B(j,k) (yielding a Tensor2 expression) and no contraction
5  (yielding a Tensor4). */
6 
7 /* Double contraction. */
8 
9 /* A(i,j)*B(i,j) */
10 
11 #pragma once
12 
13 namespace FTensor
14 {
15  template <class A, class B, class T, class U, int Dim0, int Dim1, char i,
16  char j, int Current_Dim0, int Current_Dim1>
17  typename promote<T, U>::V
21  {
22  return a(Current_Dim0 - 1, Current_Dim1 - 1)
23  * b(Current_Dim0 - 1, Current_Dim1 - 1)
26  }
27 
28  template <class A, class B, class T, class U, int Dim0, int Dim1, char i,
29  char j, int Current_Dim1>
30  typename promote<T, U>::V
33  const Number<Current_Dim1> &)
34  {
35  return a(0, Current_Dim1 - 1) * b(0, Current_Dim1 - 1)
37  }
38 
39  template <class A, class B, class T, class U, int Dim0, int Dim1, char i,
40  char j>
41  typename promote<T, U>::V
44  const Number<1> &)
45  {
46  return a(0, 0) * b(0, 0);
47  }
48 
49  template <class A, class B, class T, class U, int Dim0, int Dim1, char i,
50  char j>
51  typename promote<T, U>::V
54  {
55  return T2_times_T2(a, b, Number<Dim0>(), Number<Dim1>());
56  }
57 
58  /* A(i,j)*B(j,i) */
59 
60  template <class A, class B, class T, class U, int Dim0, int Dim1, char i,
61  char j, int Current_Dim0, int Current_Dim1>
62  typename promote<T, U>::V
65  const Number<Current_Dim0> &,
66  const Number<Current_Dim1> &)
67  {
68  return a(Current_Dim0 - 1, Current_Dim1 - 1)
69  * b(Current_Dim1 - 1, Current_Dim0 - 1)
72  }
73 
74  template <class A, class B, class T, class U, int Dim0, int Dim1, char i,
75  char j, int Current_Dim1>
76  typename promote<T, U>::V
79  const Number<1> &, const Number<Current_Dim1> &)
80  {
81  return a(0, Current_Dim1 - 1) * b(Current_Dim1 - 1, 0)
84  }
85 
86  template <class A, class B, class T, class U, int Dim0, int Dim1, char i,
87  char j>
88  typename promote<T, U>::V
91  const Number<1> &, const Number<1> &)
92  {
93  return a(0, 0) * b(0, 0);
94  }
95 
96  template <class A, class B, class T, class U, int Dim0, int Dim1, char i,
97  char j>
98  typename promote<T, U>::V
101  {
103  }
104 
105  /* Single contraction. The wrapper class has a different name for
106  each possible placing of the indices (e.g. A(i,j)*B(j,k) has the
107  number 10 because the contraction indices are on the second and
108  first slots (counting from 0). */
109 
110  /* A(i,j)*B(j,k) */
111 
112  template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
113  char i, char j, char k>
115  {
118 
119  template <int Current_Dim>
120  typename promote<T, U>::V
121  eval(const int N1, const int N2, const Number<Current_Dim> &) const
122  {
123  return iterA(N1, Current_Dim - 1) * iterB(Current_Dim - 1, N2)
124  + eval(N1, N2, Number<Current_Dim - 1>());
125  }
126  typename promote<T, U>::V
127  eval(const int N1, const int N2, const Number<1> &) const
128  {
129  return iterA(N1, 0) * iterB(0, N2);
130  }
131 
132  public:
135  : iterA(a), iterB(b)
136  {}
137  typename promote<T, U>::V operator()(const int N1, const int N2) const
138  {
139  return eval(N1, N2, Number<Dim1>());
140  }
141  };
142 
143  template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
144  char i, char j, char k>
145  Tensor2_Expr<Tensor2_times_Tensor2_10<A, B, T, U, Dim0, Dim1, Dim2, i, j, k>,
146  typename promote<T, U>::V, Dim0, Dim2, i, k>
149  {
150  using TensorExpr
153  k>(TensorExpr(a, b));
154  }
155 
156  /* A(i,j)*B(k,j) */
157 
158  template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
159  char i, char j, char k>
161  {
164 
165  template <int Current_Dim>
166  typename promote<T, U>::V
167  eval(const int N1, const int N2, const Number<Current_Dim> &) const
168  {
169  return iterA(N1, Current_Dim - 1) * iterB(N2, Current_Dim - 1)
170  + eval(N1, N2, Number<Current_Dim - 1>());
171  }
172  typename promote<T, U>::V
173  eval(const int N1, const int N2, const Number<1> &) const
174  {
175  return iterA(N1, 0) * iterB(N2, 0);
176  }
177 
178  public:
181  : iterA(a), iterB(b)
182  {}
183  typename promote<T, U>::V operator()(const int N1, const int N2) const
184  {
185  return eval(N1, N2, Number<Dim1>());
186  }
187  };
188 
189  template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
190  char i, char j, char k>
191  Tensor2_Expr<Tensor2_times_Tensor2_11<A, B, T, U, Dim0, Dim1, Dim2, i, j, k>,
192  typename promote<T, U>::V, Dim0, Dim2, i, k>
195  {
196  using TensorExpr
199  k>(TensorExpr(a, b));
200  }
201 
202  /* A(j,i)*B(j,k) */
203 
204  template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
205  char i, char j, char k>
207  {
210 
211  template <int Current_Dim>
212  typename promote<T, U>::V
213  eval(const int N1, const int N2, const Number<Current_Dim> &) const
214  {
215  return iterA(Current_Dim - 1, N1) * iterB(Current_Dim - 1, N2)
216  + eval(N1, N2, Number<Current_Dim - 1>());
217  }
218  typename promote<T, U>::V
219  eval(const int N1, const int N2, const Number<1> &) const
220  {
221  return iterA(0, N1) * iterB(0, N2);
222  }
223 
224  public:
227  : iterA(a), iterB(b)
228  {}
229  typename promote<T, U>::V operator()(const int N1, const int N2) const
230  {
231  return eval(N1, N2, Number<Dim1>());
232  }
233  };
234 
235  template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
236  char i, char j, char k>
237  Tensor2_Expr<Tensor2_times_Tensor2_00<A, B, T, U, Dim0, Dim1, Dim2, i, j, k>,
238  typename promote<T, U>::V, Dim0, Dim2, i, k>
241  {
242  using TensorExpr
245  k>(TensorExpr(a, b));
246  }
247 
248  /* A(j,i)*B(k,j) */
249 
250  template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
251  char i, char j, char k>
253  {
256 
257  template <int Current_Dim>
258  typename promote<T, U>::V
259  eval(const int N1, const int N2, const Number<Current_Dim> &) const
260  {
261  return iterA(Current_Dim - 1, N1) * iterB(N2, Current_Dim - 1)
262  + eval(N1, N2, Number<Current_Dim - 1>());
263  }
264  typename promote<T, U>::V
265  eval(const int N1, const int N2, const Number<1> &) const
266  {
267  return iterA(0, N1) * iterB(N2, 0);
268  }
269 
270  public:
273  : iterA(a), iterB(b)
274  {}
275  typename promote<T, U>::V operator()(const int N1, const int N2) const
276  {
277  return eval(N1, N2, Number<Dim1>());
278  }
279  };
280 
281  template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
282  char i, char j, char k>
283  Tensor2_Expr<Tensor2_times_Tensor2_01<A, B, T, U, Dim0, Dim1, Dim2, i, j, k>,
284  typename promote<T, U>::V, Dim0, Dim2, i, k>
287  {
288  using TensorExpr
291  k>(TensorExpr(a, b));
292  }
293 
294  /* A(i,j)*B(k,l) -> Tensor4 */
295 
296  template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
297  int Dim3, char i, char j, char k, char l>
299  {
302 
303  public:
306  : iterA(a), iterB(b)
307  {}
308  typename promote<T, U>::V
309  operator()(const int N1, const int N2, const int N3, const int N4) const
310  {
311  return iterA(N1, N2) * iterB(N3, N4);
312  }
313  };
314 
315  template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
316  int Dim3, char i, char j, char k, char l>
317  Tensor4_Expr<
318  Tensor2_times_Tensor2<A, B, T, U, Dim0, Dim1, Dim2, Dim3, i, j, k, l>,
319  typename promote<T, U>::V, Dim0, Dim1, Dim2, Dim3, i, j, k, l>
322  {
323  using TensorExpr
326  Dim2, Dim3, i, j, k, l>(TensorExpr(a, b));
327  }
328 }
FTensor::T2_times_switched_T2
promote< T, U >::V T2_times_switched_T2(const Tensor2_Expr< A, T, Dim0, Dim1, i, j > &a, const Tensor2_Expr< B, U, Dim1, Dim0, j, i > &b, const Number< Current_Dim0 > &, const Number< Current_Dim1 > &)
Definition: Tensor2_times_Tensor2.hpp:63
FTensor::Tensor2_times_Tensor2_00::iterB
Tensor2_Expr< B, U, Dim1, Dim2, j, k > iterB
Definition: Tensor2_times_Tensor2.hpp:209
FTensor::Tensor2_times_Tensor2_10::eval
promote< T, U >::V eval(const int N1, const int N2, const Number< Current_Dim > &) const
Definition: Tensor2_times_Tensor2.hpp:121
FTensor
JSON compatible output.
Definition: Christof_constructor.hpp:6
FTensor::operator*
promote< T, U >::V operator*(const Ddg_Expr< A, T, Dim, Dim, i, j, k, l > &a, const Ddg_Expr< B, U, Dim, Dim, i, k, j, l > &b)
Definition: Ddg_times_Ddg.hpp:79
FTensor::Tensor2_times_Tensor2_01::iterA
Tensor2_Expr< A, T, Dim1, Dim0, j, i > iterA
Definition: Tensor2_times_Tensor2.hpp:254
FTensor::Tensor2_times_Tensor2_11
Definition: Tensor2_times_Tensor2.hpp:160
FTensor::Tensor2_Expr
Definition: Tensor2_Expr.hpp:26
A
constexpr AssemblyType A
Definition: operators_tests.cpp:30
FTensor::Tensor2_times_Tensor2_01::iterB
Tensor2_Expr< B, U, Dim2, Dim1, k, j > iterB
Definition: Tensor2_times_Tensor2.hpp:255
FTensor::Tensor2_times_Tensor2_11::operator()
promote< T, U >::V operator()(const int N1, const int N2) const
Definition: Tensor2_times_Tensor2.hpp:183
FTensor::Tensor2_times_Tensor2::Tensor2_times_Tensor2
Tensor2_times_Tensor2(const Tensor2_Expr< A, T, Dim0, Dim1, i, j > &a, const Tensor2_Expr< B, U, Dim2, Dim3, k, l > &b)
Definition: Tensor2_times_Tensor2.hpp:304
FTensor::Tensor2_times_Tensor2_01::Tensor2_times_Tensor2_01
Tensor2_times_Tensor2_01(const Tensor2_Expr< A, T, Dim1, Dim0, j, i > &a, const Tensor2_Expr< B, U, Dim2, Dim1, k, j > &b)
Definition: Tensor2_times_Tensor2.hpp:271
FTensor::Tensor2_times_Tensor2_01::eval
promote< T, U >::V eval(const int N1, const int N2, const Number< Current_Dim > &) const
Definition: Tensor2_times_Tensor2.hpp:259
FTensor::Tensor2_times_Tensor2_00::operator()
promote< T, U >::V operator()(const int N1, const int N2) const
Definition: Tensor2_times_Tensor2.hpp:229
FTensor::Tensor4_Expr
Definition: Tensor4_Expr.hpp:25
FTensor::Tensor2_times_Tensor2_10::Tensor2_times_Tensor2_10
Tensor2_times_Tensor2_10(const Tensor2_Expr< A, T, Dim0, Dim1, i, j > &a, const Tensor2_Expr< B, U, Dim1, Dim2, j, k > &b)
Definition: Tensor2_times_Tensor2.hpp:133
FTensor::Number
Definition: Number.hpp:11
FTensor::Tensor2_times_Tensor2_10
Definition: Tensor2_times_Tensor2.hpp:114
a
constexpr double a
Definition: approx_sphere.cpp:30
FTensor::Tensor2_times_Tensor2_11::eval
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &) const
Definition: Tensor2_times_Tensor2.hpp:173
FTensor::Tensor2_times_Tensor2
Definition: Tensor2_times_Tensor2.hpp:298
FTensor::promote::V
T1 V
Definition: promote.hpp:17
FTensor::Tensor2_times_Tensor2_00::Tensor2_times_Tensor2_00
Tensor2_times_Tensor2_00(const Tensor2_Expr< A, T, Dim1, Dim0, j, i > &a, const Tensor2_Expr< B, U, Dim1, Dim2, j, k > &b)
Definition: Tensor2_times_Tensor2.hpp:225
FTensor::Tensor2_times_Tensor2_10::iterB
const Tensor2_Expr< B, U, Dim1, Dim2, j, k > iterB
Definition: Tensor2_times_Tensor2.hpp:117
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
FTensor::Tensor2_times_Tensor2_01
Definition: Tensor2_times_Tensor2.hpp:252
FTensor::Tensor2_times_Tensor2_01::operator()
promote< T, U >::V operator()(const int N1, const int N2) const
Definition: Tensor2_times_Tensor2.hpp:275
FTensor::Tensor2_times_Tensor2_10::operator()
promote< T, U >::V operator()(const int N1, const int N2) const
Definition: Tensor2_times_Tensor2.hpp:137
FTensor::Tensor2_times_Tensor2_10::eval
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &) const
Definition: Tensor2_times_Tensor2.hpp:127
FTensor::Tensor2_times_Tensor2::iterB
Tensor2_Expr< B, U, Dim2, Dim3, k, l > iterB
Definition: Tensor2_times_Tensor2.hpp:301
FTensor::Tensor2_times_Tensor2_01::eval
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &) const
Definition: Tensor2_times_Tensor2.hpp:265
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
FTensor::Tensor2_times_Tensor2::operator()
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const
Definition: Tensor2_times_Tensor2.hpp:309
FTensor::Tensor2_times_Tensor2_11::iterB
Tensor2_Expr< B, U, Dim2, Dim1, k, j > iterB
Definition: Tensor2_times_Tensor2.hpp:163
FTensor::Tensor2_times_Tensor2_11::eval
promote< T, U >::V eval(const int N1, const int N2, const Number< Current_Dim > &) const
Definition: Tensor2_times_Tensor2.hpp:167
FTensor::Tensor2_times_Tensor2_10::iterA
const Tensor2_Expr< A, T, Dim0, Dim1, i, j > iterA
Definition: Tensor2_times_Tensor2.hpp:116
FTensor::Tensor2_times_Tensor2_11::iterA
Tensor2_Expr< A, T, Dim0, Dim1, i, j > iterA
Definition: Tensor2_times_Tensor2.hpp:162
FTensor::Tensor2_times_Tensor2_00
Definition: Tensor2_times_Tensor2.hpp:206
FTensor::T2_times_T2
promote< T, U >::V T2_times_T2(const Tensor2_Expr< A, T, Dim0, Dim1, i, j > &a, const Tensor2_Expr< B, U, Dim0, Dim1, i, j > &b, const Number< Current_Dim0 > &, const Number< Current_Dim1 > &)
Definition: Tensor2_times_Tensor2.hpp:18
FTensor::Tensor2_times_Tensor2_11::Tensor2_times_Tensor2_11
Tensor2_times_Tensor2_11(const Tensor2_Expr< A, T, Dim0, Dim1, i, j > &a, const Tensor2_Expr< B, U, Dim2, Dim1, k, j > &b)
Definition: Tensor2_times_Tensor2.hpp:179
FTensor::Tensor2_times_Tensor2_00::eval
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &) const
Definition: Tensor2_times_Tensor2.hpp:219
FTensor::Tensor2_times_Tensor2::iterA
Tensor2_Expr< A, T, Dim0, Dim1, i, j > iterA
Definition: Tensor2_times_Tensor2.hpp:300
FTensor::Tensor2_times_Tensor2_00::iterA
Tensor2_Expr< A, T, Dim1, Dim0, j, i > iterA
Definition: Tensor2_times_Tensor2.hpp:208
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
FTensor::Tensor2_times_Tensor2_00::eval
promote< T, U >::V eval(const int N1, const int N2, const Number< Current_Dim > &) const
Definition: Tensor2_times_Tensor2.hpp:213