v0.9.0
Ddg_and_Tensor2_symmetric.hpp
Go to the documentation of this file.
1 /* Multiply a Tensor2_symmetric and a Ddg together but don't
2  contract, yielding a Ddg. */
3 
4 #pragma once
5 
6 namespace FTensor
7 {
8  /* Base Template */
9  template <class A, class B, class T, class U, int Dim01_0, int Dim23_0,
10  int Dim_1, char i0, char j0, char k0, char l0, char i1, char j1>
12  {};
13 
14  /* A(i,j,k,l) & B(i,j) -> Ddg */
15 
16  template <class A, class B, class T, class U, int Dim01, int Dim23, char i,
17  char j, char k, char l>
18  class Ddg_and_Tensor2_symmetric<A, B, T, U, Dim01, Dim23, Dim01, i, j, k, l,
19  i, j>
20  {
23 
24  public:
25  typename promote<T, U>::V
26  operator()(const int N1, const int N2, const int N3, const int N4) const
27  {
28  return iterA(N1, N2, N3, N4) * iterB(N1, N2);
29  }
30 
34  : iterA(a), iterB(b)
35  {}
36  };
37 
38  /* B(i,j) & A(i,j,k,l) -> Ddg */
39 
40  /* A(i,j,k,l) & B(k,l) -> Ddg */
41 
42  template <class A, class B, class T, class U, int Dim01, int Dim23, char i,
43  char j, char k, char l>
44  class Ddg_and_Tensor2_symmetric<A, B, T, U, Dim01, Dim23, Dim23, i, j, k, l,
45  k, l>
46  {
49 
50  public:
51  typename promote<T, U>::V
52  operator()(const int N1, const int N2, const int N3, const int N4) const
53  {
54  return iterA(N1, N2, N3, N4) * iterB(N3, N4);
55  }
56 
60  : iterA(a), iterB(b)
61  {}
62  };
63 
64  template <class A, class B, class T, class U, int Dim01_0, int Dim23_0,
65  int Dim_1, char i0, char j0, char k0, char l0, char i1, char j1>
66  Ddg_Expr<Ddg_and_Tensor2_symmetric<A, B, T, U, Dim01_0, Dim23_0, Dim_1, i0,
67  j0, k0, l0, i1, j1>,
68  typename promote<T, U>::V, Dim01_0, Dim23_0, i0, j0, k0, l0>
71  {
72  using TensorExpr
73  = Ddg_and_Tensor2_symmetric<A, B, T, U, Dim01_0, Dim23_0, Dim_1, i0, j0,
74  k0, l0, i1, j1>;
75  static_assert(
76  !std::is_empty<TensorExpr>::value,
77  "Indexes or Dimensions are not compatible with the & operator");
78  return Ddg_Expr<TensorExpr, typename promote<T, U>::V, Dim01_0, Dim23_0,
79  i0, j0, k0, l0>(TensorExpr(a, b));
80  }
81 
82  /* B(k,l) & A(i,j,k,l) -> Ddg */
83 
84  template <class A, class B, class T, class U, int Dim01_0, int Dim23_0,
85  int Dim_1, char i0, char j0, char k0, char l0, char i1, char j1>
86  Ddg_Expr<Ddg_and_Tensor2_symmetric<A, B, T, U, Dim01_0, Dim23_0, Dim_1, i0,
87  j0, k0, l0, i1, j1>,
88  typename promote<T, U>::V, Dim01_0, Dim23_0, i0, j0, k0, l0>
91  {
92  using TensorExpr
93  = Ddg_and_Tensor2_symmetric<A, B, T, U, Dim01_0, Dim23_0, Dim_1, i0, j0,
94  k0, l0, i1, j1>;
95  static_assert(
96  !std::is_empty<TensorExpr>::value,
97  "Indexes or Dimensions are not compatible with the & operator");
98  return Ddg_Expr<TensorExpr, typename promote<T, U>::V, Dim01_0, Dim23_0,
99  i0, j0, k0, l0>(TensorExpr(a, b));
100  }
101 
102  /* I originally put these declarations for unknown reasons, but they
103  won't work because the result is not a Ddg. The
104  multiplication messes up the symmetries. */
105 
106  // /* A(i,j,k,l) & B(j,l) -> Ddg */
107 
108  // template<class A, class B, class T, class U, int Dim,
109  // char i, char j, char k, char l>
110  // class Ddg_and_Tensor2_symmetric_13
111  // {
112  // const Ddg_Expr<A,T,Dim,Dim,i,j,k,l> iterA;
113  // const Tensor2_symmetric_Expr<B,U,Dim,j,l> iterB;
114  // public:
115  // typename promote<T,U>::V operator()(const int N1, const int N2, const
116  // int N3,
117  // const int N4) const
118  // {
119  // return iterA(N1,N2,N3,N4)*iterB(N2,N4);
120  // }
121 
122  // Ddg_and_Tensor2_symmetric_13
123  // (const Ddg_Expr<A,T,Dim,Dim,i,j,k,l> &a,
124  // const Tensor2_symmetric_Expr<B,U,Dim,j,l> &b): iterA(a), iterB(b) {}
125  // };
126 
127  // template<class A, class B, class T, class U, int Dim,
128  // char i, char j, char k, char l>
129  // const Ddg_Expr
130  // <const Ddg_and_Tensor2_symmetric_13<A,B,T,U,Dim,i,j,k,l>,
131  // typename promote<T,U>::V,Dim,Dim,i,j,k,l>
132  // operator&(const Ddg_Expr<A,T,Dim,Dim,i,j,k,l> &a,
133  // const Tensor2_symmetric_Expr<B,U,Dim,j,l> &b)
134  // {
135  // typedef Ddg_and_Tensor2_symmetric_13<A,B,T,U,Dim,i,j,k,l>
136  // TensorExpr;
137  // return Ddg_Expr<TensorExpr,typename promote<T,U>::V,Dim,Dim,i,j,k,l>
138  // (TensorExpr(a,b));
139  // }
140 
141  // /* B(j,l) & A(i,j,k,l) -> Ddg */
142 
143  // template<class A, class B, class T, class U, int Dim,
144  // char i, char j, char k, char l>
145  // const Ddg_Expr
146  // <const Ddg_and_Tensor2_symmetric_13<A,B,T,U,Dim,i,j,k,l>,
147  // typename promote<T,U>::V,Dim,Dim,i,j,k,l>
148  // operator&(const Tensor2_symmetric_Expr<B,U,Dim,j,l> &b,
149  // const Ddg_Expr<A,T,Dim,Dim,i,j,k,l> &a)
150  // {
151  // typedef Ddg_and_Tensor2_symmetric_13<A,B,T,U,Dim,i,j,k,l>
152  // TensorExpr;
153  // return Ddg_Expr<TensorExpr,typename promote<T,U>::V,Dim,Dim,i,j,k,l>
154  // (TensorExpr(a,b));
155  // }
156 
157  // /* A(i,j,k,l) & B(l,j) -> Ddg */
158 
159  // template<class A, class B, class T, class U, int Dim,
160  // char i, char j, char k, char l>
161  // class Ddg_and_Tensor2_symmetric_31
162  // {
163  // const Ddg_Expr<A,T,Dim,Dim,i,j,k,l> iterA;
164  // const Tensor2_symmetric_Expr<B,U,Dim,l,j> iterB;
165  // public:
166  // typename promote<T,U>::V operator()(const int N1, const int N2, const
167  // int N3,
168  // const int N4) const
169  // {
170  // return iterA(N1,N2,N3,N4)*iterB(N2,N4);
171  // }
172 
173  // Ddg_and_Tensor2_symmetric_31
174  // (const Ddg_Expr<A,T,Dim,Dim,i,j,k,l> &a,
175  // const Tensor2_symmetric_Expr<B,U,Dim,l,j> &b): iterA(a), iterB(b) {}
176  // };
177 
178  // template<class A, class B, class T, class U, int Dim,
179  // char i, char j, char k, char l>
180  // const Ddg_Expr
181  // <const Ddg_and_Tensor2_symmetric_31<A,B,T,U,Dim,i,j,k,l>,
182  // typename promote<T,U>::V,Dim,Dim,i,j,k,l>
183  // operator&(const Ddg_Expr<A,T,Dim,Dim,i,j,k,l> &a,
184  // const Tensor2_symmetric_Expr<B,U,Dim,l,j> &b)
185  // {
186  // typedef Ddg_and_Tensor2_symmetric_31<A,B,T,U,Dim,i,j,k,l>
187  // TensorExpr;
188  // return Ddg_Expr<TensorExpr,typename promote<T,U>::V,Dim,Dim,i,j,k,l>
189  // (TensorExpr(a,b));
190  // }
191 
192  // /* B(l,j) & A(i,j,k,l) -> Ddg */
193 
194  // template<class A, class B, class T, class U, int Dim,
195  // char i, char j, char k, char l>
196  // const Ddg_Expr
197  // <const Ddg_and_Tensor2_symmetric_31<A,B,T,U,Dim,i,j,k,l>,
198  // typename promote<T,U>::V,Dim,Dim,i,j,k,l>
199  // operator&(const Tensor2_symmetric_Expr<B,U,Dim,l,j> &b,
200  // const Ddg_Expr<A,T,Dim,Dim,i,j,k,l> &a)
201  // {
202  // typedef Ddg_and_Tensor2_symmetric_31<A,B,T,U,Dim,i,j,k,l>
203  // TensorExpr;
204  // return Ddg_Expr<TensorExpr,typename promote<T,U>::V,Dim,Dim,i,j,k,l>
205  // (TensorExpr(a,b));
206  // }
207 }
Fully Antisymmetric Levi-Civita Tensor.
Ddg_Expr< Ddg_and_Tensor2_symmetric< A, B, T, U, Dim01_0, Dim23_0, Dim_1, i0, j0, k0, l0, i1, j1 >, typename promote< T, U >::V, Dim01_0, Dim23_0, i0, j0, k0, l0 > operator &(const Ddg_Expr< A, T, Dim01_0, Dim23_0, i0, j0, k0, l0 > &a, const Tensor2_symmetric_Expr< B, U, Dim_1, i1, j1 > &b)
Ddg_and_Tensor2_symmetric(const Ddg_Expr< A, T, Dim01, Dim23, i, j, k, l > &a, const Tensor2_symmetric_Expr< B, U, Dim01, i, j > &b)
Ddg_and_Tensor2_symmetric(const Ddg_Expr< A, T, Dim01, Dim23, i, j, k, l > &a, const Tensor2_symmetric_Expr< B, U, Dim23, k, l > &b)
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const