5#ifndef __TEMPLATES_HPP__
6#define __TEMPLATES_HPP__
17 static constexpr bool isGaussByCoeffs =
true;
18 static constexpr bool isCoeffsByGauss =
false;
21 static constexpr bool isGaussByCoeffs =
false;
22 static constexpr bool isCoeffsByGauss =
true;
50 typedef typename std::remove_pointer<T1>::type T;
52 ublas::shallow_array_adaptor<T>(
n, ptr));
76 typedef typename std::remove_pointer<T1>::type T;
78 n,
m, ublas::shallow_array_adaptor<T>(
n *
m, ptr));
94template <
class KeyExtractor1,
class KeyExtractor2>
struct KeyFromKey {
99 const KeyExtractor2 &key2_ = KeyExtractor2())
111template <
typename id_type>
struct LtBit {
112 inline bool operator()(
const id_type &valueA,
const id_type &valueB)
const {
113 return valueA.to_ulong() < valueB.to_ulong();
117template <
typename id_type>
struct EqBit {
118 inline bool operator()(
const id_type &valueA,
const id_type &valueB)
const {
119 return valueA.to_ulong() == valueB.to_ulong();
125 return value.to_ulong();
129template <
class X>
inline std::string
toString(X x) {
130 std::ostringstream buffer;
141 static inline auto get(V &data) {
142 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0))>>;
168 static inline auto get(
M &data) {
171 if (data.size1() != 1 && data.size2() != 1)
172 THROW_MESSAGE(
"getFTensor0FromMat: wrong size of data matrix, number of "
173 "rows should be 1 but is " +
174 boost::lexical_cast<std::string>(data.size1()));
176 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
201template <
int S = 1,
class T,
class A>
204 if (data_ptr.expired())
214 THROW_MESSAGE(
"getFTensor0FromMat: data pointer is not available");
231template <
int Tensor_Dim,
int S,
class DL,
class M>
234template <
int Tensor_Dim,
int S,
class M>
237 static inline auto get(
M &data,
int rr,
int cc) {
238 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
239 constexpr int stride = S == -1 ? Tensor_Dim : S;
241 stride % Tensor_Dim == 0,
242 "getFTensor1FromMat: stride should be a multiple of Tensor_Dim");
245 if (data.size2() != Tensor_Dim)
247 "getFTensor1FromMat<" + boost::lexical_cast<std::string>(Tensor_Dim) +
248 ">: wrong size of data matrix, number of columns should be " +
249 boost::lexical_cast<std::string>(Tensor_Dim) +
" but is " +
250 boost::lexical_cast<std::string>(data.size2()));
251 auto *first = &data(rr + 0, cc + 0);
252 auto *last = &data(rr + 0, cc + 0 + Tensor_Dim - 1);
253 if (last - first != Tensor_Dim - 1)
255 boost::lexical_cast<std::string>(Tensor_Dim) +
256 ">: row slice is not contiguous");
260 &data(rr + 0, cc + 0));
264template <
int S,
class M>
267 static inline auto get(
M &data,
int rr,
int cc) {
268 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
269 constexpr int stride = S == -1 ? 1 : S;
272 if (data.size1() % 3 != 0)
274 "getFTensor1FromMat<3>: wrong size of data matrix, number of "
275 "rows modulo of 3 but is " +
276 boost::lexical_cast<std::string>(data.size1()));
279 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0), &data(rr + 2, cc + 0));
283template <
int S,
class M>
286 static inline auto get(
M &data,
int rr,
int cc) {
287 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
288 constexpr int stride = S == -1 ? 1 : S;
290 if (data.size1() % 4 != 0)
292 "getFTensor1FromMat<4>: wrong size of data matrix, number of "
293 "rows should be 4 but is " +
294 boost::lexical_cast<std::string>(data.size1()));
297 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0), &data(rr + 2, cc + 0),
298 &data(rr + 3, cc + 0));
302template <
int S,
class M>
305 static inline auto get(
M &data,
int rr,
int cc) {
306 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
307 constexpr int stride = S == -1 ? 1 : S;
309 if (data.size1() % 6 != 0)
311 "getFTensor1FromMat<6>: wrong size of data matrix, number of "
312 "rows should be 6 but is " +
313 boost::lexical_cast<std::string>(data.size1()));
316 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0), &data(rr + 2, cc + 0),
317 &data(rr + 3, cc + 0), &data(rr + 4, cc + 0), &data(rr + 5, cc + 0));
321template <
int S,
class M>
324 static inline auto get(
M &data,
int rr,
int cc) {
325 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
326 constexpr int stride = S == -1 ? 1 : S;
328 if (data.size1() % 9 != 0)
330 "getFTensor1FromMat<9>: wrong size of data matrix, number of "
331 "rows should be 9 but is " +
332 boost::lexical_cast<std::string>(data.size1()));
335 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0), &data(rr + 2, cc + 0),
336 &data(rr + 3, cc + 0), &data(rr + 4, cc + 0), &data(rr + 5, cc + 0),
337 &data(rr + 6, cc + 0), &data(rr + 7, cc + 0), &data(rr + 8, cc + 0));
341template <
int S,
class M>
344 static inline auto get(
M &data,
int rr,
int cc) {
345 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
346 constexpr int stride = S == -1 ? 1 : S;
348 if (data.size1() % 2 != 0)
350 "getFTensor1FromMat<2>: wrong size of data matrix, number of "
351 "row should be 2 but is " +
352 boost::lexical_cast<std::string>(data.size1()));
355 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0));
359template <
int S,
class M>
362 static inline auto get(
M &data,
int rr,
int cc) {
363 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
364 constexpr int stride = S == -1 ? 1 : S;
366 &data(rr + 0, cc + 0));
373template <
int Tensor_Dim,
int S = -1,
374 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
380template <
int Tensor_Dim,
int S = -1,
381 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
385 std::declval<M &>(), 0, 0));
387template <
int Tensor_Dim,
int S = -1,
394 "Data matrix is not available");
398 *data.lock(), rr, cc);
401template <
int Tensor_Dim,
int S = -1,
402 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>>
408 "Data matrix is not available");
415template <
int Tensor_Dim,
int S = Tensor_Dim,
typename T =
double>
420template <
int Tensor_Dim,
int S = Tensor_Dim>
422 return getFTensor1FromPtr<Tensor_Dim, S, std::complex<double>>(ptr);
426template <
int Tensor_Dim,
int S = Tensor_Dim>
428 return getFTensor1FromPtr<Tensor_Dim, S, adouble>(ptr);
432template <
int Tensor_Dim,
int S = Tensor_Dim,
typename T = VectorDouble>
434 static_assert(S % Tensor_Dim == 0,
435 "getFTensor1FromArray(VectorDouble&) requires S to be a "
436 "multiple of Tensor_Dim");
439 if (data.size() % S != 0) {
441 "getFTensor1FromArray: data size should be divisible by "
442 "pack stride dimension");
445 return getFTensor1FromPtr<Tensor_Dim, S>(data.data().data());
458template <
int DIM,
int S>
472 &data(rr + 0, 0), &data(rr + 1, 1), &data(rr + 2, 2)};
480template <
int Tensor_Dim1,
int Tensor_Dim2,
int S,
class DL,
class M>
482 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
483 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
484 constexpr int stride =
485 S == -1 ? (DL::isGaussByCoeffs ? Tensor_Dim1 * Tensor_Dim2 : 1) : S;
486 if constexpr (DL::isGaussByCoeffs) {
487 static_assert(stride % (Tensor_Dim1 * Tensor_Dim2) == 0,
488 "getFTensor2FromMat: stride should be a multiple of "
489 "Tensor_Dim1 * Tensor_Dim2");
492 if (data.size2() != Tensor_Dim1 * Tensor_Dim2) {
494 "getFTensor2FromMat<" +
495 boost::lexical_cast<std::string>(Tensor_Dim1) +
"," +
496 boost::lexical_cast<std::string>(Tensor_Dim2) +
497 ">: wrong size of columns in data matrix, should be " +
498 boost::lexical_cast<std::string>(Tensor_Dim1 * Tensor_Dim2) +
499 " but is " + boost::lexical_cast<std::string>(data.size2()));
501 auto *first = &data(rr + 0, cc + 0);
502 auto *last = &data(rr + 0, cc + 0 + Tensor_Dim1 * Tensor_Dim2 - 1);
503 if (last - first != Tensor_Dim1 * Tensor_Dim2 - 1) {
505 boost::lexical_cast<std::string>(Tensor_Dim1) +
"," +
506 boost::lexical_cast<std::string>(Tensor_Dim2) +
507 ">: row slice is not contiguous");
511 Tensor_Dim2>(&data(rr + 0, cc + 0));
512 }
else if constexpr (DL::isCoeffsByGauss) {
513 std::array<T *, Tensor_Dim1 * Tensor_Dim2> ptrs;
515 if (data.size1() != Tensor_Dim1 * Tensor_Dim2) {
517 "getFTensor2FromMat<" +
518 boost::lexical_cast<std::string>(Tensor_Dim1) +
"," +
519 boost::lexical_cast<std::string>(Tensor_Dim2) +
520 ">: wrong size of rows in data matrix, should be " +
521 boost::lexical_cast<std::string>(Tensor_Dim1 * Tensor_Dim2) +
522 " but is " + boost::lexical_cast<std::string>(data.size1()));
525 for (
auto i = 0;
i != Tensor_Dim1 * Tensor_Dim2; ++
i)
526 ptrs[
i] = &data(rr +
i, cc + 0);
530 static_assert(!std::is_same<M, M>::value,
531 "Unsupported data layout for getFTensor2FromMatImpl");
539template <
int Tensor_Dim1,
int Tensor_Dim2,
int S = -1,
540 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
546template <
int Tensor_Dim0,
int Tensor_Dim1,
int S = -1,
547 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
551 std::declval<M &>(), 0, 0));
556template <
int Tensor_Dim1,
int Tensor_Dim2,
int S = -1,
560 if (!data_ptr.lock()) {
562 "Data matrix is not available");
572template <
int Tensor_Dim1,
int Tensor_Dim2,
int S = -1,
573 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>>
578 "Data matrix is not available");
585template <
int Tensor_Dim1,
int Tensor_Dim2,
int S = -1>
589 Tensor_Dim1 * Tensor_Dim2);
592 decltype(matrix_data)>::get(matrix_data);
595template <
int Tensor_Dim1,
int Tensor_Dim2,
int S = -1,
596 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>>
598 if constexpr (DL::isGaussByCoeffs) {
601 decltype(matrix_data)>::get(matrix_data);
602 }
else if constexpr (DL::isCoeffsByGauss) {
605 decltype(matrix_data)>::get(matrix_data);
609template <
int Tensor_Dim1,
int Tensor_Dim2,
int S = -1,
610 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>>
612 if constexpr (DL::isGaussByCoeffs) {
615 decltype(matrix_data)>::get(matrix_data);
616 }
else if constexpr (DL::isCoeffsByGauss) {
619 decltype(matrix_data)>::get(matrix_data);
677 inline static auto get(
M &data,
const size_t rr,
const size_t cc) {
678 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
680 &data(rr + 0, cc + 0), &data(rr + 0, cc + 1),
682 &data(rr + 1, cc + 0), &data(rr + 1, cc + 1)};
688 inline static auto get(
M &data,
const size_t rr,
const size_t cc) {
689 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
691 &data(rr + 0, cc + 0), &data(rr + 0, cc + 1), &data(rr + 0, cc + 2),
692 &data(rr + 1, cc + 0), &data(rr + 1, cc + 1), &data(rr + 1, cc + 2),
693 &data(rr + 2, cc + 0), &data(rr + 2, cc + 1), &data(rr + 2, cc + 2)};
699 inline static auto get(
M &data,
const size_t rr,
const size_t cc,
701 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
703 &data(rr + 0, cc + 0), &data(rr + 0, cc + 1),
705 &data(rr + 1, cc + 0), &data(rr + 1, cc + 1), ss);
711 inline static auto get(
M &data,
const size_t rr,
const size_t cc,
713 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
715 &data(rr + 0, cc + 0), &data(rr + 0, cc + 1), &data(rr + 0, cc + 2),
716 &data(rr + 1, cc + 0), &data(rr + 1, cc + 1), &data(rr + 1, cc + 2),
717 &data(rr + 2, cc + 0), &data(rr + 2, cc + 1), &data(rr + 2, cc + 2),
722template <
int DIM1,
int DIM2,
int S>
724 const size_t cc = 0) {
729template <
int DIM1,
int DIM2>
731 const size_t cc,
const int ss) {
737template <
int DIM1,
int DIM2,
int S>
748template <
int Tensor_Dim,
int S,
class DL,
class M>
751template <
int Tensor_Dim,
int S,
class M>
754 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
755 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
756 constexpr int symm_size = (Tensor_Dim * (Tensor_Dim + 1)) / 2;
757 constexpr int stride = S == -1 ? symm_size : S;
758 static_assert(stride % symm_size == 0,
759 "getFTensor2SymmetricFromMat: stride should be a multiple of "
763 if (data.size2() != symm_size)
765 "getFTensor2SymmetricFromMat<" +
766 boost::lexical_cast<std::string>(Tensor_Dim) +
767 ">: wrong size of data matrix, number of columns should be " +
768 boost::lexical_cast<std::string>(symm_size) +
" but is " +
769 boost::lexical_cast<std::string>(data.size2()));
770 auto *first = &data(rr + 0, cc + 0);
771 auto *last = &data(rr + 0, cc + 0 + symm_size - 1);
772 if (last - first != symm_size - 1)
774 boost::lexical_cast<std::string>(Tensor_Dim) +
775 ">: row slice is not contiguous");
778 Tensor_Dim>(&data(rr + 0, cc + 0));
782template <
int S,
class M>
785 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
786 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
787 constexpr int stride = S == -1 ? 1 : S;
789 constexpr int symm_size = 6;
790 if (data.size1() != symm_size)
792 "getFTensor2SymmetricFromMat<3>: wrong size of data matrix, "
793 "number of rows should be 6 but is " +
794 boost::lexical_cast<std::string>(data.size1()));
797 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0), &data(rr + 2, cc + 0),
798 &data(rr + 3, cc + 0), &data(rr + 4, cc + 0), &data(rr + 5, cc + 0));
802template <
int S,
class M>
805 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
806 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
807 constexpr int stride = S == -1 ? 1 : S;
809 constexpr int symm_size = 3;
810 if (data.size1() != symm_size)
812 "getFTensor2SymmetricFromMat<2>: wrong size of data matrix, "
813 "number of rows should be 3 but is " +
814 boost::lexical_cast<std::string>(data.size1()));
817 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0), &data(rr + 2, cc + 0));
824template <
int Tensor_Dim,
int S = -1,
825 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
831template <
int Tensor_Dim,
int S = -1,
832 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
836 std::declval<M &>(), 0, 0));
838template <
int Tensor_Dim,
int S = -1,
843 if (data_ptr.expired()) {
845 "Data matrix is not available");
852template <
int Tensor_Dim,
int S = -1,
853 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>>
859 "Data matrix is not available");
871 decltype(matrix_data)>::get(matrix_data, 0, 0);
875template <
int Tensor_Dim>
881 decltype(matrix_data)>::get(matrix_data, 0, 0);
904 ptr + 0, ptr + 1, ptr + 3);
908template <
int DIM,
class T>
913 full(
i,
j) = symm(
i,
j);
922template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int S,
class DL,
926template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int S,
class M>
929 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
930 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
931 constexpr int tensor_size = Tensor_Dim0 * Tensor_Dim1 * Tensor_Dim2;
932 constexpr int stride = S == -1 ? tensor_size : S;
934 stride % tensor_size == 0,
935 "getFTensor3FromMat: stride should be a multiple of tensor_size");
938 if (data.size2() != tensor_size) {
940 boost::lexical_cast<std::string>(Tensor_Dim0) +
"," +
941 boost::lexical_cast<std::string>(Tensor_Dim1) +
"," +
942 boost::lexical_cast<std::string>(Tensor_Dim2) +
943 ">: wrong size of columns in data matrix, should be " +
944 boost::lexical_cast<std::string>(tensor_size) +
" but is " +
945 boost::lexical_cast<std::string>(data.size2()));
947 auto *first = &data(rr + 0, cc + 0);
948 auto *last = &data(rr + 0, cc + 0 + tensor_size - 1);
949 if (last - first != tensor_size - 1)
951 boost::lexical_cast<std::string>(Tensor_Dim0) +
"," +
952 boost::lexical_cast<std::string>(Tensor_Dim1) +
"," +
953 boost::lexical_cast<std::string>(Tensor_Dim2) +
954 ">: row slice is not contiguous");
957 Tensor_Dim1, Tensor_Dim2>{&data(rr + 0, cc + 0)};
961template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int S,
class M>
964 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
965 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
966 constexpr int tensor_size = Tensor_Dim0 * Tensor_Dim1 * Tensor_Dim2;
967 constexpr int stride = S == -1 ? 1 : S;
968 std::array<T *, tensor_size> ptrs;
970 if (data.size1() != tensor_size) {
972 boost::lexical_cast<std::string>(Tensor_Dim0) +
"," +
973 boost::lexical_cast<std::string>(Tensor_Dim1) +
"," +
974 boost::lexical_cast<std::string>(Tensor_Dim2) +
975 ">: wrong size of rows in data matrix, should be " +
976 boost::lexical_cast<std::string>(tensor_size) +
" but is " +
977 boost::lexical_cast<std::string>(data.size1()));
980 for (
auto i = 0;
i != tensor_size; ++
i)
981 ptrs[
i] = &data(rr +
i, cc + 0);
983 Tensor_Dim1, Tensor_Dim2>(ptrs);
1000template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int S = -1,
1001 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
1005 M>::get(data, rr, cc);
1008template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int S = -1,
1009 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
1013 DL,
M>::get(std::declval<M &>(), 0, 0));
1015template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int S = -1,
1018 int rr = 0,
int cc = 0) {
1020 if (!data_ptr.lock()) {
1022 "Data matrix is not available");
1029template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int S = -1,
1030 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>>
1032 int rr = 0,
int cc = 0) {
1036 "Data matrix is not available");
1050template <
int DIM1,
int DIM2,
int DIM3>
1055 "Such getFTensor3FromPtr is not implemented");
1062 ptr + 0, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5, ptr + 6, ptr + 7,
1063 ptr + 8, ptr + 9, ptr + 10, ptr + 11);
1070 ptr + 0, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5, ptr + 6, ptr + 7,
1071 ptr + 8, ptr + 9, ptr + 10, ptr + 11, ptr + 12, ptr + 13, ptr + 14,
1072 ptr + 15, ptr + 16, ptr + 17, ptr + 18, ptr + 19, ptr + 20, ptr + 21,
1073 ptr + 22, ptr + 23, ptr + 24, ptr + 25, ptr + 26);
1081template <
int Tensor_Dim01,
int Tensor_Dim2,
int S,
class DL,
class M>
1084template <
int Tensor_Dim01,
int Tensor_Dim2,
int S,
class M>
1088 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
1089 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
1090 constexpr int symm_size_01 = (Tensor_Dim01 * (Tensor_Dim01 + 1)) / 2;
1091 constexpr int dg_size = symm_size_01 * Tensor_Dim2;
1092 constexpr int stride = S == -1 ? dg_size : S;
1094 stride % dg_size == 0,
1095 "getFTensor3DgFromMat: stride should be a multiple of dg_size");
1098 if (data.size2() != dg_size) {
1100 "getFTensor3DgFromMat<" +
1101 boost::lexical_cast<std::string>(Tensor_Dim01) +
", " +
1102 boost::lexical_cast<std::string>(Tensor_Dim2) +
1103 ">: wrong size of data matrix, number of columns should be " +
1104 boost::lexical_cast<std::string>(dg_size) +
" but is " +
1105 boost::lexical_cast<std::string>(data.size2()));
1107 auto *first = &data(rr + 0, cc + 0);
1108 auto *last = &data(rr + 0, cc + 0 + dg_size - 1);
1109 if (last - first != dg_size - 1)
1111 boost::lexical_cast<std::string>(Tensor_Dim01) +
", " +
1112 boost::lexical_cast<std::string>(Tensor_Dim2) +
1113 ">: row slice is not contiguous");
1116 Tensor_Dim2>{&data(rr + 0, cc + 0)};
1120template <
int S,
class M>
1123 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
1124 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
1125 constexpr int stride = S == -1 ? 1 : S;
1128 constexpr int dg_size = 1;
1129 if (data.size1() != dg_size)
1131 "getFTensor3DgFromMat<1, 1>: wrong size of data matrix, number "
1132 "of rows should be 1 but is " +
1133 boost::lexical_cast<std::string>(data.size1()));
1136 &data(rr + 0, cc + 0)};
1140template <
int S,
class M>
1143 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
1144 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
1145 constexpr int stride = S == -1 ? 1 : S;
1147 constexpr int dg_size = 6;
1148 if (data.size1() != dg_size) {
1150 "getFTensor3DgFromMat<2, 2>: wrong size of data matrix, number "
1151 "of rows should be 6 but is " +
1152 boost::lexical_cast<std::string>(data.size1()));
1156 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0), &data(rr + 2, cc + 0),
1157 &data(rr + 3, cc + 0), &data(rr + 4, cc + 0), &data(rr + 5, cc + 0)};
1161template <
int S,
class M>
1164 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
1165 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
1166 constexpr int stride = S == -1 ? 1 : S;
1168 constexpr int dg_size = 18;
1169 if (data.size1() != dg_size) {
1171 "getFTensor3DgFromMat<3, 3>: wrong size of data matrix, number "
1172 "of rows should be 18 but is " +
1173 boost::lexical_cast<std::string>(data.size1()));
1177 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0), &data(rr + 2, cc + 0),
1178 &data(rr + 3, cc + 0), &data(rr + 4, cc + 0), &data(rr + 5, cc + 0),
1179 &data(rr + 6, cc + 0), &data(rr + 7, cc + 0), &data(rr + 8, cc + 0),
1180 &data(rr + 9, cc + 0), &data(rr + 10, cc + 0), &data(rr + 11, cc + 0),
1181 &data(rr + 12, cc + 0), &data(rr + 13, cc + 0), &data(rr + 14, cc + 0),
1182 &data(rr + 15, cc + 0), &data(rr + 16, cc + 0), &data(rr + 17, cc + 0)};
1198template <
int Tensor_Dim01,
int Tensor_Dim2,
int S = -1,
1199 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
1206template <
int Tensor_Dim01,
int Tensor_Dim2,
int S = -1,
1207 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
1211 std::declval<M &>(), 0, 0));
1213template <
int Tensor_Dim01,
int Tensor_Dim2,
int S = -1,
1218 if (!data_ptr.lock()) {
1220 "Data matrix is not available");
1227template <
int Tensor_Dim01,
int Tensor_Dim2,
int S = -1,
1228 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>>
1234 "Data matrix is not available");
1241template <
int Tensor_Dim01,
int Tensor_Dim2,
int S,
class T =
double>
1243 constexpr auto dg_size =
1244 ((Tensor_Dim01 * (Tensor_Dim01 + 1)) / 2) * Tensor_Dim2;
1248 decltype(matrix_data)>::get(matrix_data);
1256template <
class T,
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
1257 int Tensor_Dim3,
int S, std::size_t... Is>
1259 const std::array<T *, Tensor_Dim0 * Tensor_Dim1 * Tensor_Dim2 * Tensor_Dim3>
1261 std::index_sequence<Is...>) {
1263 Tensor_Dim2, Tensor_Dim3>(ptrs[Is]...);
1266template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int Tensor_Dim3,
1267 int S,
class DL,
class M>
1269 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
1270 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
1271 constexpr int tensor_size =
1272 Tensor_Dim0 * Tensor_Dim1 * Tensor_Dim2 * Tensor_Dim3;
1273 constexpr int stride =
1274 S == -1 ? (DL::isGaussByCoeffs ? tensor_size : 1) : S;
1275 if constexpr (DL::isGaussByCoeffs) {
1277 stride % tensor_size == 0,
1278 "getFTensor4FromMat: stride should be a multiple of tensor_size");
1281 if (data.size2() != tensor_size) {
1283 boost::lexical_cast<std::string>(Tensor_Dim0) +
"," +
1284 boost::lexical_cast<std::string>(Tensor_Dim1) +
"," +
1285 boost::lexical_cast<std::string>(Tensor_Dim2) +
"," +
1286 boost::lexical_cast<std::string>(Tensor_Dim3) +
1287 ">: wrong size of columns in data matrix, should be " +
1288 boost::lexical_cast<std::string>(tensor_size) +
1290 boost::lexical_cast<std::string>(data.size2()));
1292 auto *first = &data(rr + 0, cc + 0);
1293 auto *last = &data(rr + 0, cc + 0 + tensor_size - 1);
1294 if (last - first != tensor_size - 1) {
1296 boost::lexical_cast<std::string>(Tensor_Dim0) +
"," +
1297 boost::lexical_cast<std::string>(Tensor_Dim1) +
"," +
1298 boost::lexical_cast<std::string>(Tensor_Dim2) +
"," +
1299 boost::lexical_cast<std::string>(Tensor_Dim3) +
1300 ">: row slice is not contiguous");
1304 Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>{
1305 &data(rr + 0, cc + 0)};
1306 }
else if constexpr (DL::isCoeffsByGauss) {
1307 std::array<T *, tensor_size> ptrs;
1309 if (data.size1() != tensor_size) {
1311 boost::lexical_cast<std::string>(Tensor_Dim0) +
"," +
1312 boost::lexical_cast<std::string>(Tensor_Dim1) +
"," +
1313 boost::lexical_cast<std::string>(Tensor_Dim2) +
"," +
1314 boost::lexical_cast<std::string>(Tensor_Dim3) +
1315 ">: wrong size of rows in data matrix, should be " +
1316 boost::lexical_cast<std::string>(tensor_size) +
1318 boost::lexical_cast<std::string>(data.size1()));
1321 for (
auto i = 0;
i != tensor_size; ++
i)
1322 ptrs[
i] = &data(rr +
i, cc + 0);
1324 Tensor_Dim3, stride>(
1325 ptrs, std::make_index_sequence<tensor_size>{});
1327 static_assert(!std::is_same<M, M>::value,
1328 "Unsupported data layout for getFTensor4FromMatImpl");
1346template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int Tensor_Dim3,
1347 int S = -1,
class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
1351 Tensor_Dim3, S, DL,
M>::get(data);
1354template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int Tensor_Dim3,
1355 int S = -1,
class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
1359 Tensor_Dim3, S, DL,
M>::get(
1360 std::declval<M &>(), 0, 0));
1362template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int Tensor_Dim3,
1366 if (!data_ptr.lock()) {
1368 "Data matrix is not available");
1376template <
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
int Tensor_Dim3,
1377 int S = -1,
class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>>
1383 "Data matrix is not available");
1391template <
int DIM1,
int DIM2,
int DIM3,
int DIM4,
int S = -1,
class T =
double>
1396 decltype(matrix_data)>::get(matrix_data);
1404template <
int Tensor_Dim01,
int Tensor_Dim23,
int S,
class DL,
class M>
1407template <
int Tensor_Dim01,
int Tensor_Dim23,
int S,
class M>
1411 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
1412 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
1413 constexpr int symm_size_01 = (Tensor_Dim01 * (Tensor_Dim01 + 1)) / 2;
1414 constexpr int symm_size_23 = (Tensor_Dim23 * (Tensor_Dim23 + 1)) / 2;
1415 constexpr int ddg_size = symm_size_01 * symm_size_23;
1416 constexpr int stride = S == -1 ? ddg_size : S;
1418 stride % ddg_size == 0,
1419 "Stride should be a multiple of the size of the symmetric tensor");
1422 if (data.size2() != ddg_size) {
1424 "getFTensor4DdgFromMat<" +
1425 boost::lexical_cast<std::string>(Tensor_Dim01) +
", " +
1426 boost::lexical_cast<std::string>(Tensor_Dim23) +
1427 ">: wrong size of data matrix, number of columns should be " +
1428 boost::lexical_cast<std::string>(ddg_size) +
" but is " +
1429 boost::lexical_cast<std::string>(data.size2()));
1431 auto *first = &data(rr + 0, cc + 0);
1432 auto *last = &data(rr + 0, cc + 0 + ddg_size - 1);
1433 if (last - first != ddg_size - 1)
1435 boost::lexical_cast<std::string>(Tensor_Dim01) +
", " +
1436 boost::lexical_cast<std::string>(Tensor_Dim23) +
1437 ">: row slice is not contiguous");
1440 Tensor_Dim23>{&data(rr + 0, cc + 0)};
1444template <
int S,
class M>
1447 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
1448 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
1449 constexpr int stride = S == -1 ? 1 : S;
1451 constexpr int ddg_size = 1;
1452 if (data.size1() != ddg_size)
1454 "getFTensor4DdgFromMat<1, 1>: wrong size of data matrix, number "
1455 "of rows should be 1 but is " +
1456 boost::lexical_cast<std::string>(data.size1()));
1459 &data(rr + 0, cc + 0)};
1463template <
int S,
class M>
1466 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
1467 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
1468 constexpr int stride = S == -1 ? 1 : S;
1470 constexpr int ddg_size = 9;
1471 if (data.size1() != ddg_size) {
1473 "getFTensor4DdgFromMat<2, 2>: wrong size of data matrix, number "
1474 "of rows should be 9 but is " +
1475 boost::lexical_cast<std::string>(data.size1()));
1479 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0), &data(rr + 2, cc + 0),
1480 &data(rr + 3, cc + 0), &data(rr + 4, cc + 0), &data(rr + 5, cc + 0),
1481 &data(rr + 6, cc + 0), &data(rr + 7, cc + 0), &data(rr + 8, cc + 0)};
1485template <
int S,
class M>
1488 static inline auto get(
M &data,
int rr = 0,
int cc = 0) {
1489 using T = std::remove_cv_t<std::remove_reference_t<
decltype(data(0, 0))>>;
1490 constexpr int stride = S == -1 ? 1 : S;
1492 constexpr int ddg_size = 36;
1493 if (data.size1() != ddg_size) {
1495 "getFTensor4DdgFromMat<3, 3>: wrong size of data matrix, number "
1496 "of rows should be 36 but is " +
1497 boost::lexical_cast<std::string>(data.size1()));
1501 &data(rr + 0, cc + 0), &data(rr + 1, cc + 0), &data(rr + 2, cc + 0),
1502 &data(rr + 3, cc + 0), &data(rr + 4, cc + 0), &data(rr + 5, cc + 0),
1503 &data(rr + 6, cc + 0), &data(rr + 7, cc + 0), &data(rr + 8, cc + 0),
1504 &data(rr + 9, cc + 0), &data(rr + 10, cc + 0), &data(rr + 11, cc + 0),
1505 &data(rr + 12, cc + 0), &data(rr + 13, cc + 0), &data(rr + 14, cc + 0),
1506 &data(rr + 15, cc + 0), &data(rr + 16, cc + 0), &data(rr + 17, cc + 0),
1507 &data(rr + 18, cc + 0), &data(rr + 19, cc + 0), &data(rr + 20, cc + 0),
1508 &data(rr + 21, cc + 0), &data(rr + 22, cc + 0), &data(rr + 23, cc + 0),
1509 &data(rr + 24, cc + 0), &data(rr + 25, cc + 0), &data(rr + 26, cc + 0),
1510 &data(rr + 27, cc + 0), &data(rr + 28, cc + 0), &data(rr + 29, cc + 0),
1511 &data(rr + 30, cc + 0), &data(rr + 31, cc + 0), &data(rr + 32, cc + 0),
1512 &data(rr + 33, cc + 0), &data(rr + 34, cc + 0), &data(rr + 35, cc + 0)};
1527template <
int Tensor_Dim01,
int Tensor_Dim23,
int S = -1,
1528 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
1535template <
int Tensor_Dim01,
int Tensor_Dim23,
int S = -1,
1536 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>,
1540 M>::get(std::declval<M &>(), 0, 0));
1542template <
int Tensor_Dim01,
int Tensor_Dim23,
int S = -1,
1548 "Data matrix is not available");
1555template <
int Tensor_Dim01,
int Tensor_Dim23,
int S = -1,
1556 class DL = DataLayoutTraits<DataLayout::GaussByCoeffs>>
1562 "Data matrix is not available");
1569template <
int Tensor_Dim01,
int Tensor_Dim23,
int S,
class T =
double>
1571 constexpr auto symm_size01 = (Tensor_Dim01 * (Tensor_Dim01 + 1)) / 2;
1572 constexpr auto symm_size23 = (Tensor_Dim23 * (Tensor_Dim23 + 1)) / 2;
1573 constexpr auto symm_size = symm_size01 * symm_size23;
1577 decltype(matrix_data)>::get(matrix_data);
1588template <
class T,
int S,
int Tensor_Dim>
1593 static inline auto size(
M &
m,
const size_t nb_integration_pts) {
1594 if (
m.size1() != nb_integration_pts ||
m.size2() != Tensor_Dim) {
1595 m.resize(nb_integration_pts, Tensor_Dim,
false);
1604 static inline auto get(
M &
m,
const size_t nb_integration_pts) {
1606 if (S == -1 || S == Tensor_Dim) {
1607 if (
m.size1() != nb_integration_pts) {
1610 "Matrix size is not compatible with the number of "
1611 "integration points: expected " +
1612 boost::lexical_cast<std::string>(nb_integration_pts) +
1613 " but got " + boost::lexical_cast<std::string>(
m.size1()));
1625template <
class T,
int S,
int Tensor_Dim0,
int Tensor_Dim1>
1627 FTensor::Tensor2<FTensor::CursorPtr<T *, S>, Tensor_Dim0, Tensor_Dim1>,
1630 static inline auto size(
M &
m,
const size_t nb_integration_pts) {
1631 if (
m.size1() != nb_integration_pts ||
1632 m.size2() != Tensor_Dim0 * Tensor_Dim1) {
1633 m.resize(nb_integration_pts, Tensor_Dim0 * Tensor_Dim1,
false);
1637 Tensor_Dim0, Tensor_Dim1, S,
1642 static inline auto get(
M &
m,
const size_t nb_integration_pts) {
1644 if (S == -1 || S == Tensor_Dim0 * Tensor_Dim1) {
1645 if (
m.size1() != nb_integration_pts) {
1648 "Matrix size is not compatible with the number of "
1649 "integration points: expected " +
1650 boost::lexical_cast<std::string>(nb_integration_pts) +
1651 " but got " + boost::lexical_cast<std::string>(
m.size1()));
1657 Tensor_Dim0, Tensor_Dim1, S,
1663template <
class T,
int S,
int Tensor_Dim>
1665 FTensor::Tensor2_symmetric<FTensor::CursorPtr<T *, S>, Tensor_Dim>,
1668 static inline auto size(
M &
m,
const size_t nb_integration_pts) {
1669 constexpr int symm_size = (Tensor_Dim * (Tensor_Dim + 1)) / 2;
1670 if (
m.size1() != nb_integration_pts ||
m.size2() != symm_size) {
1671 m.resize(nb_integration_pts, symm_size,
false);
1680 static inline auto get(
M &
m,
const size_t nb_integration_pts) {
1682 constexpr int symm_size = (Tensor_Dim * (Tensor_Dim + 1)) / 2;
1683 if (S == -1 || S == symm_size) {
1684 if (
m.size1() != nb_integration_pts) {
1687 "Matrix size is not compatible with the number of "
1688 "integration points: expected " +
1689 boost::lexical_cast<std::string>(nb_integration_pts) +
1690 " but got " + boost::lexical_cast<std::string>(
m.size1()));
1702template <
class T,
int S,
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2>
1704 FTensor::Tensor3<FTensor::CursorPtr<T *, S>, Tensor_Dim0, Tensor_Dim1,
1708 static inline auto size(
M &
m,
const size_t nb_integration_pts) {
1709 constexpr int tensor_size = Tensor_Dim0 * Tensor_Dim1 * Tensor_Dim2;
1710 if (
m.size1() != nb_integration_pts ||
m.size2() != tensor_size) {
1711 m.resize(nb_integration_pts, tensor_size,
false);
1715 Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, S,
1720 static inline auto get(
M &
m,
const size_t nb_integration_pts) {
1722 constexpr int tensor_size = Tensor_Dim0 * Tensor_Dim1 * Tensor_Dim2;
1723 if (S == -1 || S == tensor_size) {
1724 if (
m.size1() != nb_integration_pts) {
1727 "Matrix size is not compatible with the number of "
1728 "integration points: expected " +
1729 boost::lexical_cast<std::string>(nb_integration_pts) +
1730 " but got " + boost::lexical_cast<std::string>(
m.size1()));
1736 Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, S,
1742template <
class T,
int S,
int Tensor_Dim01,
int Tensor_Dim2>
1744 FTensor::Dg<FTensor::CursorPtr<T *, S>, Tensor_Dim01, Tensor_Dim2>,
1747 static inline auto size(
M &
m,
const size_t nb_integration_pts) {
1748 constexpr int dg_size =
1749 ((Tensor_Dim01 * (Tensor_Dim01 + 1)) / 2) * Tensor_Dim2;
1750 if (
m.size1() != nb_integration_pts ||
m.size2() != dg_size) {
1751 m.resize(nb_integration_pts, dg_size,
false);
1755 Tensor_Dim01, Tensor_Dim2, S,
1760 static inline auto get(
M &
m,
const size_t nb_integration_pts) {
1762 constexpr int dg_size =
1763 ((Tensor_Dim01 * (Tensor_Dim01 + 1)) / 2) * Tensor_Dim2;
1764 if (S == -1 || S == dg_size) {
1765 if (
m.size1() != nb_integration_pts) {
1768 "Matrix size is not compatible with the number of "
1769 "integration points: expected " +
1770 boost::lexical_cast<std::string>(nb_integration_pts) +
1771 " but got " + boost::lexical_cast<std::string>(
m.size1()));
1777 Tensor_Dim01, Tensor_Dim2, S,
1783template <
class T,
int S,
int Tensor_Dim0,
int Tensor_Dim1,
int Tensor_Dim2,
1786 FTensor::Tensor4<FTensor::CursorPtr<T *, S>, Tensor_Dim0, Tensor_Dim1,
1787 Tensor_Dim2, Tensor_Dim3>,
1790 static inline auto size(
M &
m,
const size_t nb_integration_pts) {
1791 constexpr int tensor_size =
1792 Tensor_Dim0 * Tensor_Dim1 * Tensor_Dim2 * Tensor_Dim3;
1793 if (
m.size1() != nb_integration_pts ||
m.size2() != tensor_size) {
1794 m.resize(nb_integration_pts, tensor_size,
false);
1798 Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3, S,
1803 static inline auto get(
M &
m,
const size_t nb_integration_pts) {
1805 if (S == -1 || S == Tensor_Dim0 * Tensor_Dim1 * Tensor_Dim2 * Tensor_Dim3) {
1806 if (
m.size1() != nb_integration_pts) {
1809 "Matrix size is not compatible with the number of "
1810 "integration points: expected " +
1811 boost::lexical_cast<std::string>(nb_integration_pts) +
1812 " but got " + boost::lexical_cast<std::string>(
m.size1()));
1818 Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3, S,
1824template <
class T,
int S,
int Tensor_Dim01,
int Tensor_Dim23>
1826 FTensor::Ddg<FTensor::CursorPtr<T *, S>, Tensor_Dim01, Tensor_Dim23>,
1829 static inline auto size(
M &
m,
const size_t nb_integration_pts) {
1830 constexpr int ddg_size =
1831 ((Tensor_Dim01 * (Tensor_Dim01 + 1)) / 2) *
1832 ((Tensor_Dim23 * (Tensor_Dim23 + 1)) / 2);
1833 if (
m.size1() != nb_integration_pts ||
m.size2() != ddg_size) {
1834 m.resize(nb_integration_pts, ddg_size,
false);
1838 Tensor_Dim01, Tensor_Dim23, S,
1843 static inline auto get(
M &
m,
const size_t nb_integration_pts) {
1845 constexpr int ddg_size =
1846 ((Tensor_Dim01 * (Tensor_Dim01 + 1)) / 2) *
1847 ((Tensor_Dim23 * (Tensor_Dim23 + 1)) / 2);
1848 if (S == -1 || S == ddg_size) {
1850 if (
m.size1() != nb_integration_pts) {
1853 "Matrix size is not compatible with the number of "
1854 "integration points: expected " +
1855 boost::lexical_cast<std::string>(nb_integration_pts) +
1856 " but got " + boost::lexical_cast<std::string>(
m.size1()));
1862 Tensor_Dim01, Tensor_Dim23, S,
1876template <
int DIM,
typename T>
1878 if constexpr (DIM == 3) {
1879 return std::array<double, 9>{t_mat(0, 0), t_mat(1, 1), t_mat(2, 2),
1880 t_mat(0, 1), t_mat(1, 0), t_mat(0, 2),
1881 t_mat(2, 0), t_mat(1, 2), t_mat(2, 1)};
1883 return std::array<double, 5>{t_mat(0, 0), t_mat(1, 1), 1.0, t_mat(0, 1),
1889 constexpr double sqr2 = boost::math::constants::root_two<double>();
1891 if constexpr (DIM == 3) {
1892 return std::array<double, 9>{t_mat(0, 0),
1902 return std::array<double, 4>{t_mat(0, 0), t_mat(1, 1), 0.0,
1903 sqr2 * t_mat(0, 1)};
1907template <
typename T>
1909 array<double, 5> vec{t_mat(0, 0), t_mat(1, 1), 1. + hoop_term, t_mat(0, 1),
1915template <
typename T>
1917 constexpr double sqr2 = boost::math::constants::root_two<double>();
1919 array<double, 4> vec_sym{t_mat(0, 0), t_mat(1, 1), hoop_term,
1920 sqr2 * t_mat(0, 1)};
1939 const size_t M = mat.size1();
1940 const size_t N = mat.size2();
1944 "The input matrix for inverse computation is not square %zu != %zu",
1947 int *ipv =
new int[
N];
1949 double *work =
new double[lwork];
1958 "lapack error info = %d", info);
1975 const size_t M = mat.size1();
1976 const size_t N = mat.size2();
1978 if (
M == 0 ||
M !=
N)
1980 "The input matrix for inverse computation is not square %zu != %zu",
1987 int *ipiv =
new int[
M];
1989 &*f.data().begin(),
M);
1992 "error lapack solve dgesv info = %d", info);
2010 auto mat_copy = mat;
2028 const size_t M = mat.size1();
2029 const size_t N = mat.size2();
2031 if (
M == 0 ||
M !=
N)
2034 "The input matrix for eigen value computation is not square %zu != %zu",
2036 if (eig.size() !=
M)
2037 eig.resize(
M,
false);
2042 const int size = (
M + 2) *
M;
2044 double *work =
new double[size];
2046 if (
lapack_dsyev(
'V',
'U',
n, &*eigen_vec.data().begin(), lda,
2047 &*eig.data().begin(), work, lwork) > 0)
2049 "The algorithm failed to compute eigenvalues.");
2062template <
int DIM,
typename T1,
typename T2>
2069 const int lda = DIM;
2070 const int lwork = (DIM + 2) * DIM;
2071 std::array<
double, (DIM + 2) * DIM> work;
2076 "The algorithm failed to compute eigenvalues.");
2089template <
int DIM,
typename T1,
typename T2,
typename T3>
2095 for (
int ii = 0; ii != DIM; ii++)
2096 for (
int jj = 0; jj != DIM; jj++)
2097 eigen_vec(ii, jj) = mat(ii, jj);
2117 return t(0, 0) *
t(1, 1) *
t(2, 2) +
t(1, 0) *
t(2, 1) *
t(0, 2) +
2118 t(2, 0) *
t(0, 1) *
t(1, 2) -
t(0, 0) *
t(2, 1) *
t(1, 2) -
2119 t(2, 0) *
t(1, 1) *
t(0, 2) -
t(1, 0) *
t(0, 1) *
t(2, 2);
2130 return t(0, 0) *
t(1, 1) -
t(0, 1) *
t(1, 0);
2146template <
typename T,
int DIM>
2154template <
typename T,
int DIM>
2163template <
int Tensor_Dim,
class T,
class L,
class A>
2165 ublas::vector<T, A> &det_data,
2166 ublas::matrix<T, L, A> &inv_jac_data) {
2169 "Specialization for this template not yet implemented");
2182template <
class T1,
class T2>
2193template <
class T1,
class T2>
2204template <
class T1,
class T2,
class T3>
2207 const auto a =
t(0, 0), b =
t(0, 1),
c =
t(0, 2);
2208 const auto d =
t(1, 0), e =
t(1, 1), f =
t(1, 2);
2209 const auto g =
t(2, 0),
h =
t(2, 1),
i =
t(2, 2);
2210 const auto inv_det = 1.0 / det;
2211 inv_t(0, 0) = (e *
i - f *
h) * inv_det;
2212 inv_t(0, 1) = (
c *
h - b *
i) * inv_det;
2213 inv_t(0, 2) = (b * f -
c * e) * inv_det;
2214 inv_t(1, 0) = (f *
g - d *
i) * inv_det;
2215 inv_t(1, 1) = (
a *
i -
c *
g) * inv_det;
2216 inv_t(1, 2) = (
c * d -
a * f) * inv_det;
2217 inv_t(2, 0) = (d *
h - e *
g) * inv_det;
2218 inv_t(2, 1) = (b *
g -
a *
h) * inv_det;
2219 inv_t(2, 2) = (
a * e - b * d) * inv_det;
2227template <
class T1,
class T2,
class T3>
2230 const auto a =
t(0, 0);
2231 const auto b =
t(0, 1);
2232 const auto c =
t(1, 0);
2233 const auto d =
t(1, 1);
2234 inv_t(0, 0) = d / det;
2235 inv_t(0, 1) = -b / det;
2236 inv_t(1, 0) = -
c / det;
2237 inv_t(1, 1) =
a / det;
2245template <
typename T1,
typename T2,
typename T3>
2250 const auto a =
t(0, 0);
2251 const auto b =
t(0, 1);
2252 const auto c =
t(0, 2);
2253 const auto d =
t(1, 1);
2254 const auto e =
t(1, 2);
2255 const auto f =
t(2, 2);
2256 const auto inv_det = 1.0 / det;
2257 inv_t(0, 0) = (d * f - e * e) * inv_det;
2258 inv_t(0, 1) = (
c * e - b * f) * inv_det;
2259 inv_t(0, 2) = (b * e -
c * d) * inv_det;
2260 inv_t(1, 1) = (
a * f -
c *
c) * inv_det;
2261 inv_t(1, 2) = (b *
c -
a * e) * inv_det;
2262 inv_t(2, 2) = (
a * d - b * b) * inv_det;
2270template <
typename T1,
typename T2,
typename T3>
2275 const auto a =
t(0, 0);
2276 const auto b =
t(0, 1);
2277 const auto d =
t(1, 1);
2278 const auto inv_det = 1.0 / det;
2279 inv_t(0, 0) = d * inv_det;
2280 inv_t(0, 1) = -b * inv_det;
2281 inv_t(1, 1) =
a * inv_det;
2285template <
typename T1,
typename T2,
typename T3,
int DIM>
2288template <
typename T1,
typename T2,
typename T3>
2295template <
typename T1,
typename T2,
typename T3>
2302template <
typename T1,
typename T2,
typename T3,
int DIM>
2311template <
typename T1,
typename T2,
typename T3,
int DIM>
2317 DIM>::invert(
t, det, inv_t);
2330 template <
typename Iterator>
2332 return (*it)->getEnt();
2354template <
typename Extractor,
typename Iterator>
2356 Iterator end_iter) {
2357 moab::Range::iterator hint = r.begin();
2358 while (begin_iter != end_iter) {
2360 auto bi = Extractor::extract(begin_iter);
2361 Iterator pj = begin_iter;
2362 while (pj != end_iter && (bi +
j) == Extractor::extract(pj)) {
2366 hint = r.insert(hint, bi, bi + (
j - 1));
2390template <
typename MI,
typename MO = Modify_change_nothing>
2394 for (
auto it = mi.begin(); it != mi.end(); ++it) {
2395 if (!
const_cast<MI &
>(mi).modify(it, mo))
2397 "Houston we have a problem");
2425 return boost::make_shared<TempMeshset>(moab);
2482template <
typename I>
2489 if (tester(first)) {
2491 auto second = first;
2494 while (second != s) {
2501 CHKERR inserter(first, second);
2527template <
typename Dest = void,
typename... Arg>
2529 if constexpr (std::is_same<void, Dest>::value)
2530 return std::array<std::common_type_t<std::decay_t<Arg>...>,
sizeof...(Arg)>{
2531 {std::forward<Arg>(arg)...}};
2533 return std::array<Dest,
sizeof...(Arg)>{{std::forward<Arg>(arg)...}};
2561#define FTENSOR_INDEX(DIM, I) I##_FTIndex<DIM> I;
2563#define FTENSOR_INDEX_DECL(r, DIM, I) FTENSOR_INDEX(DIM, I)
2565#define FTENSOR_INDEXES(DIM, ...) \
2566 BOOST_PP_SEQ_FOR_EACH(FTENSOR_INDEX_DECL, DIM, \
2567 BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
#define MOAB_THROW(err)
Check error code of MoAB function and throw MoFEM exception.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_OPERATION_UNSUCCESSFUL
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double n
refractive index of diffusive medium
static __CLPK_integer lapack_dgesv(__CLPK_integer n, __CLPK_integer nrhs, __CLPK_doublereal *a, __CLPK_integer lda, __CLPK_integer *ipiv, __CLPK_doublereal *b, __CLPK_integer ldb)
static __CLPK_integer lapack_dgetrf(__CLPK_integer m, __CLPK_integer n, __CLPK_doublereal *a, __CLPK_integer lda, __CLPK_integer *ipiv)
static __CLPK_integer lapack_dsyev(char jobz, char uplo, __CLPK_integer n, __CLPK_doublereal *a, __CLPK_integer lda, __CLPK_doublereal *w, __CLPK_doublereal *work, __CLPK_integer lwork)
static __CLPK_integer lapack_dgetri(__CLPK_integer n, __CLPK_doublereal *a, __CLPK_integer lda, __CLPK_integer *ipiv, __CLPK_doublereal *work, __CLPK_integer lwork)
FTensor::Index< 'j', 3 > j
Tensors class implemented by Walter Landry.
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
ublas::vector< T, ublas::shallow_array_adaptor< T > > VectorShallowArrayAdaptor
UBlasMatrix< double > MatrixDouble
UBlasMatrix< adouble > MatrixADouble
ublas::matrix< T, ublas::row_major, ublas::shallow_array_adaptor< T > > MatrixShallowArrayAdaptor
UBlasVector< double > VectorDouble
implementation of Data Operators for Forces and Sources
auto getVectorAdaptor(T1 ptr, const size_t n)
Get Vector adaptor.
auto type_from_handle(const EntityHandle h)
get type from entity handle
static auto getFTensor4FromMat(M &data)
Get tensor rank 4 (non symmetric) form data matrix.
decltype(GetFTensor2SymmetricFromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2SymmetricFromMatType
auto getVoigtVecAxisymm(T &t_mat, const double hoop_term)
auto getFTensor2FromMat(M &data)
Get tensor rank 2 (matrix) form data matrix.
auto to_non_symm(const FTensor::Tensor2_symmetric< T, DIM > &symm)
static auto getFTensor3FromMat(M &data, int rr=0, int cc=0)
Get tensor rank 3 (non symmetries) form data matrix.
auto getFTensor2SymmetricLowerFromPtr< 3 >(double *ptr)
auto getFTensor2SymmetricFromPtr(double *ptr)
decltype(GetFTensor4FromMatImpl< Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor4FromMatType
auto getFTensor2SymmetricLowerFromPtr< 2 >(double *ptr)
FTensor::Tensor3< FTensor::PackPtr< double *, 12 >, 3, 2, 2 > getFTensor3FromPtr< 3, 2, 2 >(double *ptr)
auto getVoigtVec(T &t_mat)
MoFEMErrorCode reconstructMultiIndex(const MI &mi, MO &&mo=Modify_change_nothing())
Template used to reconstruct multi-index.
auto getFTensor2FromVec(VectorDouble &data)
moab::Range::iterator insertOrdered(Range &r, Extractor, Iterator begin_iter, Iterator end_iter)
Insert ordered mofem multi-index into range.
MoFEMErrorCode invertTensor2by2(T1 &t, T2 &det, T3 &inv_t)
Calculate matrix inverse 2 by 2.
static auto getFTensor2SymmetricFromMat(M &data)
Get symmetric tensor rank 2 (matrix) form data matrix.
MoFEMErrorCode computeMatrixInverse(MatrixDouble &mat)
compute matrix inverse with lapack dgetri
auto getFTensor1FromArrayDiag(MatrixDouble &data, const size_t rr)
Get FTensor1 from array.
auto getFTensor2HVecFromPtr< 3, 2 >(double *ptr)
auto id_from_handle(const EntityHandle h)
static auto getFTensor3DgFromPtr(T *ptr)
auto getFTensor1FromArray(T &data)
auto dimension_from_handle(const EntityHandle h)
get entity dimension form handle
auto getFTensor1FromArrayDiag< 2, 2 >(MatrixDouble &data, const size_t rr)
MoFEMErrorCode solveLinearSystem(MatrixDouble &mat, VectorDouble &f)
solve linear system with lapack dgesv
static auto determinantTensor2by2(T &t)
Calculate the determinant of a 2x2 matrix or a tensor of rank 2.
auto getFTensor2HVecFromPtr(double *ptr)
Make Tensor2 for HVec base from pointer.
auto type_name_from_handle(const EntityHandle h)
get entity type name from handle
static auto getFTensor3DgFromMat(M &data)
Get symmetric tensor rank 3 on the first two indices from form data matrix.
auto getFTensor2HVecFromPtr< 3, 3 >(double *ptr)
MoFEMErrorCode invertTensor3by3(ublas::matrix< T, L, A > &jac_data, ublas::vector< T, A > &det_data, ublas::matrix< T, L, A > &inv_jac_data)
Calculate inverse of tensor rank 2 at integration points.
decltype(GetFTensor4DdgFromMatImpl< Tensor_Dim01, Tensor_Dim23, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor4DdgFromMatType
MoFEMErrorCode invertTensor3by3< 3, double, ublas::row_major, DoubleAllocator >(MatrixDouble &jac_data, VectorDouble &det_data, MatrixDouble &inv_jac_data)
auto getFTensor1FromPtr(T *ptr)
static MoFEMErrorCode invertTensor(FTensor::Tensor2< T1, DIM, DIM > &t, T2 &det, FTensor::Tensor2< T3, DIM, DIM > &inv_t)
static auto getFTensor4DdgFromPtr(T *ptr)
constexpr auto make_array(Arg &&...arg)
Create Array.
auto getMatrixAdaptor(T1 ptr, const size_t n, const size_t m)
Get Matrix adaptor.
auto getFTensor1FromMat(M &data, int rr=0, int cc=0)
Get tensor rank 1 (vector) form data matrix.
auto getFTensor4FromPtr(T *ptr)
auto getFTensor2FromArray(MatrixDouble &data, const size_t rr, const size_t cc=0)
static auto determinantTensor(FTensor::Tensor2< T, DIM, DIM > &t)
Calculate the determinant of a tensor of rank DIM.
auto field_bit_from_bit_number(const int bit_number)
get field bit id from bit number
static auto getFTensor0FromPtr(T *ptr)
Get tensor rank 0 (scalar) from pointer.
std::string toString(X x)
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
auto getFTensor2SymmetricLowerFromPtr(double *ptr)
Make symmetric Tensor2 from pointer, taking lower triangle of matrix.
static auto getFTensor4DdgFromMat(M &data)
Get symmetric tensor rank 4 on first two and last indices from form data matrix.
auto getFTensor2FromPtr(double *ptr)
auto getVoigtVecSymm(T &t_mat)
static auto makeFTensor4FromPtrArray(const std::array< T *, Tensor_Dim0 *Tensor_Dim1 *Tensor_Dim2 *Tensor_Dim3 > &ptrs, std::index_sequence< Is... >)
auto getFTensor0FromMat(M &data)
Get tensor rank 0 (scalar) form data vector.
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
decltype(GetFTensor3DgFromMatImpl< Tensor_Dim01, Tensor_Dim2, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor3DgFromMatType
MoFEMErrorCode computeEigenValuesSymmetric(const MatrixDouble &mat, VectorDouble &eig, MatrixDouble &eigen_vec)
compute eigenvalues of a symmetric matrix using lapack dsyev
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
FTensor::Tensor3< FTensor::PackPtr< double *, 27 >, 3, 3, 3 > getFTensor3FromPtr< 3, 3, 3 >(double *ptr)
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
decltype(GetFTensor3FromMatImpl< Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor3FromMatType
auto getVoigtVecSymmAxisymm(T &t_mat, const double hoop_term)
FTensor::Tensor3< FTensor::PackPtr< double *, DIM1 *DIM2 *DIM3 >, DIM1, DIM2, DIM3 > getFTensor3FromPtr(double *ptr)
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
auto rangeInserter(const I f, const I s, boost::function< bool(I it)> tester, boost::function< MoFEMErrorCode(I f, I s)> inserter)
Insert ranges.
auto getFTensor1FromArrayDiag< 3, 3 >(MatrixDouble &data, const size_t rr)
auto ent_form_type_and_id(const EntityType type, const EntityID id)
get entity handle from type and id
constexpr IntegrationType I
constexpr double t
plate stiffness
FTensor::Index< 'm', 3 > m
bool operator()(const id_type &valueA, const id_type &valueB) const
static auto get(M &data, int rr, int cc)
static auto get(M &data, int rr, int cc)
static auto get(M &data, int rr, int cc)
static auto get(M &data, int rr, int cc)
static auto get(M &data, int rr, int cc)
static auto get(M &data, int rr, int cc)
static auto get(M &data, int rr, int cc)
GetFTensor2FromArrayImpl()=delete
static auto get(M &data, const size_t rr, const size_t cc)
static auto get(M &data, const size_t rr, const size_t cc)
GetFTensor2FromArrayImpl()=delete
static auto get(M &data, const size_t rr, const size_t cc, const int ss=0)
GetFTensor2FromArrayRawPtrImpl()=delete
static auto get(M &data, const size_t rr, const size_t cc, const int ss=0)
GetFTensor2FromArrayRawPtrImpl()=delete
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
static auto get(M &data, int rr=0, int cc=0)
unsigned int operator()(const id_type &value) const
static MoFEMErrorCode invert(T1 &t, T2 &det, T3 &inv_t)
static MoFEMErrorCode invert(T1 &t, T2 &det, T3 &inv_t)
result_type operator()(Arg &arg) const
KeyFromKey(const KeyExtractor1 &key1_=KeyExtractor1(), const KeyExtractor2 &key2_=KeyExtractor2())
KeyExtractor1::result_type result_type
bool operator()(const id_type &valueA, const id_type &valueB) const
static auto get(M &m, const size_t nb_integration_pts)
static auto size(M &m, const size_t nb_integration_pts)
static auto size(M &m, const size_t nb_integration_pts)
static auto get(M &m, const size_t nb_integration_pts)
static auto size(M &m, const size_t nb_integration_pts)
static auto get(M &m, const size_t nb_integration_pts)
static auto get(M &m, const size_t nb_integration_pts)
static auto size(M &m, const size_t nb_integration_pts)
static auto get(M &m, const size_t nb_integration_pts)
static auto size(M &m, const size_t nb_integration_pts)
static auto get(M &m, const size_t nb_integration_pts)
static auto size(M &m, const size_t nb_integration_pts)
static auto size(M &m, const size_t nb_integration_pts)
static auto get(M &m, const size_t nb_integration_pts)
Do nothing, used to rebuild database.
Modify_change_nothing()=default
TempMeshset(moab::Interface &moab)