16 return (
N1 ==
N2) ?
T(0) : ((
N1 == 0) ?
T(1) :
T(-1));
19 template <
char i,
char j,
int Dim0,
int Dim1>
21 (Dim0 <= 2 && Dim1 <= 2),
28 template <
char i,
int Dim0>
33 "Index dimension exceeds the maximum for Rank 2 Levi-Civita Tensor");
36 throw std::out_of_range(
37 "Bad index in Levi_Civita<T>::operator()(Index<"
38 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
39 + std::to_string(
N1) +
")\n");
46 template <
char j,
int Dim1>
51 "Index dimension exceeds the maximum for Rank 2 Levi-Civita Tensor");
54 throw std::out_of_range(
"Bad index in Levi_Civita<T>::operator()("
55 + std::to_string(
N0) +
", Index<"
56 + std::basic_string<char>{
j} +
", "
57 + std::to_string(Dim1) +
">)\n");
67 return (
N1 ==
N2 ||
N1 == N3 ||
N2 == N3)
69 : (((
N1 + 1) % 3 ==
N2) ?
T(1) :
T(-1));
72 template <
char i,
char j,
char k,
int Dim0,
int Dim1,
int Dim2>
74 (Dim0 <= 3 && Dim1 <= 3 && Dim2 <= 3),
82 template <
char i,
char j,
int Dim0,
int Dim1>
87 Dim0 <= 3 && Dim1 <= 3,
88 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
91 throw std::out_of_range(
92 "Bad index in Levi_Civita<T>::operator()("
94 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0)
97 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
98 + std::to_string(
N2) +
")\n");
100 auto TensorExpr = [
this,
N2](
const int &
N0,
const int &
N1) {
107 template <
char i,
char k,
int Dim0,
int Dim2>
112 Dim0 <= 3 && Dim2 <= 3,
113 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
115 if(
N1 >= 3 ||
N1 < 0)
116 throw std::out_of_range(
117 "Bad index in Levi_Civita<T>::operator()("
119 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
123 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">)\n");
125 auto TensorExpr = [
this,
N1](
const int &
N0,
const int &
N2) {
132 template <
char j,
char k,
int Dim1,
int Dim2>
137 Dim1 <= 3 && Dim2 <= 3,
138 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
140 if(
N0 >= 3 ||
N0 < 0)
141 throw std::out_of_range(
142 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(
N0)
145 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1)
148 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">)\n");
150 auto TensorExpr = [
this,
N0](
const int &
N1,
const int &
N2) {
157 template <
char i,
int Dim0>
162 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
164 if(
N1 >= 3 || N1 < 0 || N2 >= 3 ||
N2 < 0)
165 throw std::out_of_range(
166 "Bad index in Levi_Civita<T>::operator()("
168 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
169 + std::to_string(
N1) +
", " + std::to_string(
N2) +
")\n");
171 auto TensorExpr = [
this,
N1,
N2](
const int &
N0) {
174 return Tensor1_Expr<
decltype(TensorExpr),
T, Dim0,
i>{TensorExpr};
177 template <
char j,
int Dim1>
182 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
184 if(
N0 >= 3 || N0 < 0 || N2 >= 3 ||
N2 < 0)
185 throw std::out_of_range(
186 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(
N0)
189 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
190 + std::to_string(
N2) +
")\n");
192 auto TensorExpr = [
this,
N0,
N2](
const int &
N1) {
195 return Tensor1_Expr<
decltype(TensorExpr),
T, Dim1,
j>{TensorExpr};
198 template <
char k,
int Dim2>
203 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
205 if(
N0 >= 3 || N0 < 0 || N1 >= 3 ||
N1 < 0)
206 throw std::out_of_range(
207 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(
N0)
208 +
", " + std::to_string(
N1)
211 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">)\n");
213 auto TensorExpr = [
this,
N0,
N1](
const int &
N2) {
216 return Tensor1_Expr<
decltype(TensorExpr),
T, Dim2,
k>{TensorExpr};
223 return (
N1 ==
N2 ||
N1 == N3 ||
N1 == N4 ||
N2 == N3 ||
N2 == N4
227 ? (((
N2 + N3) % 4 == 3) ?
T(1) :
T(-1))
229 ? (((
N2 + N3) % 4 == 1) ?
T(1) :
T(-1))
231 ? (((
N2 + N3) % 4 != 1) ?
T(1) :
T(-1))
235 template <
char i,
char j,
char k,
char l,
int Dim0,
int Dim1,
int Dim2,
238 (Dim0 <= 4 && Dim1 <= 4 && Dim2 <= 4 && Dim3 <= 4),
247 template <
char i,
char j,
char k,
int Dim0,
int Dim1,
int Dim2>
252 Dim0 <= 4 && Dim1 <= 4 && Dim2 <= 4,
253 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
255 if(N3 >= 4 || N3 < 0)
256 throw std::out_of_range(
257 "Bad index in Levi_Civita<T>::operator()("
259 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0)
262 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1)
265 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">, "
266 + std::to_string(N3) +
")\n");
269 = [
this, N3](
const int &
N0,
const int &
N1,
const int &
N2) {
276 template <
char i,
char j,
char l,
int Dim0,
int Dim1,
int Dim3>
281 Dim0 <= 4 && Dim1 <= 4 && Dim3 <= 4,
282 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
284 if(
N2 >= 4 ||
N2 < 0)
285 throw std::out_of_range(
286 "Bad index in Levi_Civita<T>::operator()("
288 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0)
291 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
295 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
298 = [
this,
N2](
const int &
N0,
const int &
N1,
const int &N3) {
305 template <
char i,
char k,
char l,
int Dim0,
int Dim2,
int Dim3>
310 Dim0 <= 4 && Dim2 <= 4 && Dim3 <= 4,
311 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
313 if(
N1 >= 4 ||
N1 < 0)
314 throw std::out_of_range(
315 "Bad index in Levi_Civita<T>::operator()("
317 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
321 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2)
324 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
327 = [
this,
N1](
const int &
N0,
const int &
N2,
const int &N3) {
334 template <
char j,
char k,
char l,
int Dim1,
int Dim2,
int Dim3>
339 Dim1 <= 4 && Dim2 <= 4 && Dim3 <= 4,
340 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
342 if(
N0 >= 4 ||
N0 < 0)
343 throw std::out_of_range(
344 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(
N0)
347 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1)
350 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2)
353 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
356 = [
this,
N0](
const int &
N1,
const int &
N2,
const int &N3) {
363 template <
char i,
char j,
int Dim0,
int Dim1>
365 const int &
N2,
const int &N3)
368 Dim0 <= 4 && Dim1 <= 4,
369 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
371 if(
N2 >= 4 || N2 < 0 || N3 >= 4 || N3 < 0)
372 throw std::out_of_range(
373 "Bad index in Levi_Civita<T>::operator()("
375 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0)
378 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
379 + std::to_string(
N2) +
", " + std::to_string(N3) +
")\n");
381 auto TensorExpr = [
this,
N2, N3](
const int &
N0,
const int &
N1) {
388 template <
char i,
char k,
int Dim0,
int Dim2>
393 Dim0 <= 4 && Dim2 <= 4,
394 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
396 if(
N1 >= 4 || N1 < 0 || N3 >= 4 || N3 < 0)
397 throw std::out_of_range(
398 "Bad index in Levi_Civita<T>::operator()("
400 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
404 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">, "
405 + std::to_string(N3) +
")\n");
407 auto TensorExpr = [
this,
N1, N3](
const int &
N0,
const int &
N2) {
414 template <
char j,
char k,
int Dim1,
int Dim2>
419 Dim1 <= 4 && Dim2 <= 4,
420 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
422 if(
N0 >= 4 || N0 < 0 || N3 >= 4 || N3 < 0)
423 throw std::out_of_range(
424 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(
N0)
427 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1)
430 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">, "
431 + std::to_string(N3) +
")\n");
433 auto TensorExpr = [
this,
N0, N3](
const int &
N1,
const int &
N2) {
440 template <
char i,
char l,
int Dim0,
int Dim3>
445 Dim0 <= 4 && Dim3 <= 4,
446 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
448 if(
N1 >= 4 || N1 < 0 || N2 >= 4 ||
N2 < 0)
449 throw std::out_of_range(
450 "Bad index in Levi_Civita<T>::operator()("
452 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
453 + std::to_string(
N1) +
", " + std::to_string(
N2)
456 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
458 auto TensorExpr = [
this,
N1,
N2](
const int &
N0,
const int &N3) {
465 template <
char j,
char l,
int Dim1,
int Dim3>
470 Dim1 <= 4 && Dim3 <= 4,
471 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
473 if(
N0 >= 4 || N0 < 0 || N2 >= 4 ||
N2 < 0)
474 throw std::out_of_range(
475 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(
N0)
478 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
482 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
484 auto TensorExpr = [
this,
N0,
N2](
const int &
N1,
const int &N3) {
491 template <
char k,
char l,
int Dim2,
int Dim3>
496 Dim2 <= 4 && Dim3 <= 4,
497 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
499 if(
N0 >= 4 || N0 < 0 || N1 >= 4 ||
N1 < 0)
500 throw std::out_of_range(
501 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(
N0)
502 +
", " + std::to_string(
N1)
505 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2)
508 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
510 auto TensorExpr = [
this,
N0,
N1](
const int &
N2,
const int &N3) {
517 template <
char i,
int Dim0>
519 const int &
N2,
const int &N3)
523 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
525 if(
N1 >= 4 || N1 < 0 || N2 >= 4 || N2 < 0 || N3 >= 4 || N3 < 0)
526 throw std::out_of_range(
527 "Bad index in Levi_Civita<T>::operator()("
529 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
530 + std::to_string(
N1) +
", " + std::to_string(
N2) +
", "
531 + std::to_string(N3) +
")\n");
533 auto TensorExpr = [
this,
N1,
N2, N3](
const int &
N0) {
536 return Tensor1_Expr<
decltype(TensorExpr),
T, Dim0,
i>{TensorExpr};
539 template <
char j,
int Dim1>
541 const int &
N2,
const int &N3)
545 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
547 if(
N0 >= 4 || N0 < 0 || N2 >= 4 || N2 < 0 || N3 >= 4 || N3 < 0)
548 throw std::out_of_range(
549 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(
N0)
552 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
553 + std::to_string(
N2) +
", " + std::to_string(N3) +
")\n");
555 auto TensorExpr = [
this,
N0,
N2, N3](
const int &
N1) {
558 return Tensor1_Expr<
decltype(TensorExpr),
T, Dim1,
j>{TensorExpr};
561 template <
char k,
int Dim2>
567 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
569 if(
N0 >= 4 || N0 < 0 || N1 >= 4 || N1 < 0 || N3 >= 4 || N3 < 0)
570 throw std::out_of_range(
571 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(
N0)
572 +
", " + std::to_string(
N1)
575 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">, "
576 + std::to_string(N3) +
")\n");
578 auto TensorExpr = [
this,
N0,
N1, N3](
const int &
N2) {
581 return Tensor1_Expr<
decltype(TensorExpr),
T, Dim2,
k>{TensorExpr};
584 template <
char l,
int Dim3>
590 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
592 if(
N0 >= 4 || N0 < 0 || N1 >= 4 || N1 < 0 || N2 >= 4 ||
N2 < 0)
593 throw std::out_of_range(
594 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(
N0)
595 +
", " + std::to_string(
N1) +
", " + std::to_string(
N2)
598 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
600 auto TensorExpr = [
this,
N0,
N1,
N2](
const int &N3) {
603 return Tensor1_Expr<
decltype(TensorExpr),
T, Dim3,
l>{TensorExpr};
613 template <
class T =
int,
char i,
char j,
int Dim0,
int Dim1>
615 (Dim0 <= 2 && Dim1 <= 2),
616 Tensor2_Expr<Levi_Civita<T>,
T, Dim0, Dim1,
i,
j>>::type
622 template <
class T =
int,
char i,
int Dim0>
628 template <
class T =
int,
char j,
int Dim1>
635 template <
class T =
int,
char i,
char j,
char k,
int Dim0,
int Dim1,
int Dim2>
637 (Dim0 <= 3 && Dim1 <= 3 && Dim2 <= 3),
638 Tensor3_Expr<Levi_Civita<T>,
T, Dim0, Dim1, Dim2,
i,
j,
k>>::type
646 template <
class T =
int,
char i,
char j,
int Dim0,
int Dim1>
653 template <
class T =
int,
char i,
char k,
int Dim0,
int Dim2>
660 template <
class T =
int,
char j,
char k,
int Dim1,
int Dim2>
667 template <
class T =
int,
char i,
int Dim0>
674 template <
class T =
int,
char j,
int Dim1>
681 template <
class T =
int,
char k,
int Dim2>
689 template <
class T = int,
char i,
char j,
char k,
char l,
int Dim0,
int Dim1,
692 (Dim0 <= 4 && Dim1 <= 4 && Dim2 <= 4 && Dim3 <= 4),
693 Tensor4_Expr<Levi_Civita<T>,
T, Dim0, Dim1, Dim2, Dim3,
i,
j,
k,
l>>::type
701 template <
class T =
int,
char i,
char j,
char k,
int Dim0,
int Dim1,
int Dim2>
709 template <
class T =
int,
char i,
char j,
char l,
int Dim0,
int Dim1,
int Dim3>
717 template <
class T =
int,
char i,
char k,
char l,
int Dim0,
int Dim2,
int Dim3>
725 template <
class T =
int,
char j,
char k,
char l,
int Dim1,
int Dim2,
int Dim3>
733 template <
class T =
int,
char i,
char j,
int Dim0,
int Dim1>
735 const int &
N2,
const int &N3)
740 template <
class T =
int,
char i,
char k,
int Dim0,
int Dim2>
747 template <
class T =
int,
char j,
char k,
int Dim1,
int Dim2>
754 template <
class T =
int,
char i,
char l,
int Dim0,
int Dim3>
761 template <
class T =
int,
char j,
char l,
int Dim1,
int Dim3>
768 template <
class T =
int,
char k,
char l,
int Dim2,
int Dim3>
775 template <
class T =
int,
char i,
int Dim0>
777 const int &
N2,
const int &N3)
782 template <
class T =
int,
char j,
int Dim1>
784 const int &
N2,
const int &N3)
789 template <
class T =
int,
char k,
int Dim2>
796 template <
class T =
int,
char l,
int Dim3>
constexpr T operator()(const int N1, const int N2, const int N3) const
Rank 3.
auto operator()(const Index< i, Dim0 > &, const int &N1, const Index< k, Dim2 > &)
constexpr auto operator()(const Index< i, Dim0 > &, const Index< j, Dim1 > &, const Index< k, Dim2 > &, const int &N3)
constexpr T operator()(const int N1, const int N2) const
Rank 2.
constexpr auto operator()(const int &N0, const Index< j, Dim1 > &, const Index< k, Dim2 > &, const Index< l, Dim3 > &)
constexpr auto operator()(const int &N0, const int &N1, const Index< k, Dim2 > &, const Index< l, Dim3 > &)
constexpr auto operator()(const Index< i, Dim0 > &, const int &N1, const int &N2, const Index< l, Dim3 > &)
auto operator()(const int &N0, const int &N1, const Index< k, Dim2 > &)
constexpr auto operator()(const int &N0, const Index< j, Dim1 > &, const Index< k, Dim2 > &, const int &N3)
constexpr auto operator()(const Index< i, Dim0 > &, const Index< j, Dim1 > &, const int &N2, const Index< l, Dim3 > &)
constexpr auto operator()(const Index< i, Dim0 > &, const int &N1, const Index< k, Dim2 > &, const int &N3)
auto operator()(const Index< i, Dim0 > &, const Index< j, Dim1 > &, const int &N2)
constexpr auto operator()(const Index< i, Dim0 > &, const int &N1, const Index< k, Dim2 > &, const Index< l, Dim3 > &)
constexpr auto operator()(const int &N0, const Index< j, Dim1 > &, const int &N2, const Index< l, Dim3 > &)
auto operator()(const int &N0, const Index< j, Dim1 > &, const int &N2)
constexpr auto operator()(const int &N0, const int &N1, const int &N2, const Index< l, Dim3 > &)
constexpr auto operator()(const int &N0, const Index< j, Dim1 > &, const int &N2, const int &N3)
constexpr auto operator()(const Index< i, Dim0 > &, const int &N1, const int &N2, const int &N3)
constexpr auto operator()(const Index< i, Dim0 > &, const Index< j, Dim1 > &, const int &N2, const int &N3)
auto operator()(const Index< i, Dim0 > &, const int &N1, const int &N2)
constexpr auto operator()(const Index< i, Dim0 > &, const int &N1)
constexpr auto operator()(const int &N0, const int &N1, const Index< k, Dim2 > &, const int &N3)
constexpr auto operator()(const int &N0, const Index< j, Dim1 > &)
auto operator()(const int &N0, const Index< j, Dim1 > &, const Index< k, Dim2 > &)
constexpr T operator()(const int N1, const int N2, const int N3, const int N4) const
Rank 4.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
Tensors class implemented by Walter Landry.
constexpr std::enable_if<(Dim0<=2 &&Dim1<=2), Tensor2_Expr< Levi_Civita< T >, T, Dim0, Dim1, i, j > >::type levi_civita(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
levi_civita functions to make for easy adhoc use