v0.14.0
Templates.hpp
Go to the documentation of this file.
1 /** \file Templates.hpp
2  * \brief Templates declarations
3  */
4 
5 #ifndef __TEMPLATES_HPP__
6 #define __TEMPLATES_HPP__
7 
8 namespace MoFEM {
9 
10 template <typename T> using ShardVec = boost::shared_ptr<std::vector<T>>;
11 
12 /**
13  * @brief Get Vector adaptor
14  *
15  * \code
16  *
17  * double *a;
18  * CHKERR VecGetArray(v,&a);
19  *
20  * for(int n = 0; n != nodes; ++n) {
21  *
22  * auto a = getVectorAdaptor(&a[3*n], 3);
23  * double dot = inner_prod(a, a);
24  *
25  * }
26  *
27  * CHKERR VecRetsoreArray(v,&a);
28  * \endcode
29  *
30  */
31 template <typename T1> inline auto getVectorAdaptor(T1 ptr, const size_t n) {
32  typedef typename std::remove_pointer<T1>::type T;
34  ublas::shallow_array_adaptor<T>(n, ptr));
35 };
36 
37 /**
38  * @brief Get Matrix adaptor
39  *
40  * \code
41  *
42  * double *a;
43  * CHKERR VecGetArray(v,&a);
44  *
45  * for(int n = 0; n != nodes; ++n) {
46  *
47  * auto F = getMatrixAdaptor(&a[3*3*n], 3, 3);
48  * MatrixDouble C = prod(F, trans(F));
49  *
50  * }
51  *
52  * CHKERR VecRetsoreArray(v,&a);
53  * \endcode
54  *
55  */
56 template <typename T1>
57 inline auto getMatrixAdaptor(T1 ptr, const size_t n, const size_t m) {
58  typedef typename std::remove_pointer<T1>::type T;
60  n, m, ublas::shallow_array_adaptor<T>(n * m, ptr));
61 };
62 
63 /**
64  * This small utility that cascades two key extractors will be
65  * used throughout the boost example
66  * <a
67  * href=http://www.boost.org/doc/libs/1_53_0/libs/multi_index/example/complex_structs.cpp>
68  * http://www.boost.org/doc/libs/1_53_0/libs/multi_index/example/complex_structs.cpp
69  * </a>
70  */
71 template <class KeyExtractor1, class KeyExtractor2> struct KeyFromKey {
72 public:
73  typedef typename KeyExtractor1::result_type result_type;
74 
75  KeyFromKey(const KeyExtractor1 &key1_ = KeyExtractor1(),
76  const KeyExtractor2 &key2_ = KeyExtractor2())
77  : key1(key1_), key2(key2_) {}
78 
79  template <typename Arg> result_type operator()(Arg &arg) const {
80  return key1(key2(arg));
81  }
82 
83 private:
84  KeyExtractor1 key1;
85  KeyExtractor2 key2;
86 };
87 
88 template <typename id_type> struct LtBit {
89  inline bool operator()(const id_type &valueA, const id_type &valueB) const {
90  return valueA.to_ulong() < valueB.to_ulong();
91  }
92 };
93 
94 template <typename id_type> struct EqBit {
95  inline bool operator()(const id_type &valueA, const id_type &valueB) const {
96  return valueA.to_ulong() == valueB.to_ulong();
97  }
98 };
99 
100 template <typename id_type> struct HashBit {
101  inline unsigned int operator()(const id_type &value) const {
102  return value.to_ulong();
103  }
104 };
105 
106 template <class X> inline std::string toString(X x) {
107  std::ostringstream buffer;
108  buffer << x;
109  return buffer.str();
110 }
111 
112 template <int S, class T, class A> struct GetFTensor0FromVecImpl {
113  static inline auto get(ublas::vector<T, A> &data) {
114  return FTensor::Tensor0<FTensor::PackPtr<T *, S>>(&*data.data().begin());
115  }
116 };
117 
118 /**
119 * \brief Get tensor rank 0 (scalar) form data vector
120 
121 Example how to use it.
122 \code
123 VectorDouble vec;
124 vec.resize(nb_gauss_pts,false);
125 vec.clear();
126 auto t0 = getFTensor0FromData(data);
127 for(int gg = 0;gg!=nb_gauss_pts;gg++) {
128 
129  ++t0;
130 }
131 \endcode
132 
133 */
134 template <int S = 1, class T, class A>
135 static inline auto getFTensor0FromVec(ublas::vector<T, A> &data) {
137 }
138 
139 template <int Tensor_Dim, int S, class T, class L, class A>
141 
142 template <int S, class T, class A>
143 struct GetFTensor1FromMatImpl<3, S, T, ublas::row_major, A> {
144  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
145 #ifndef NDDEBUG
146  if (data.size1() != 3)
148  "getFTensor1FromMat<3>: wrong size of data matrix, number of "
149  "rows should be 3 but is " +
150  boost::lexical_cast<std::string>(data.size1()));
151 #endif
153  &data(0, 0), &data(1, 0), &data(2, 0));
154  }
155 };
156 
157 template <int S, class T, class A>
158 struct GetFTensor1FromMatImpl<4, S, T, ublas::row_major, A> {
159  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
160 #ifndef NDDEBUG
161  if (data.size1() != 4)
163  "getFTensor1FromMat<4>: wrong size of data matrix, number of "
164  "rows should be 4 but is " +
165  boost::lexical_cast<std::string>(data.size1()));
166 #endif
168  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0));
169  }
170 };
171 
172 template <int S, class T, class A>
173 struct GetFTensor1FromMatImpl<6, S, T, ublas::row_major, A> {
174  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
175 #ifndef NDDEBUG
176  if (data.size1() != 6)
178  "getFTensor1FromMat<6>: wrong size of data matrix, number of "
179  "rows should be 6 but is " +
180  boost::lexical_cast<std::string>(data.size1()));
181 #endif
183  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0), &data(4, 0),
184  &data(5, 0));
185  }
186 };
187 
188 template <int S, class T, class A>
189 struct GetFTensor1FromMatImpl<9, S, T, ublas::row_major, A> {
190  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
191 #ifndef NDDEBUG
192  if (data.size1() != 9)
194  "getFTensor1FromMat<9>: wrong size of data matrix, number of "
195  "rows should be 9 but is " +
196  boost::lexical_cast<std::string>(data.size1()));
197 #endif
199  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0), &data(4, 0),
200  &data(5, 0), &data(6, 0), &data(7, 0), &data(8, 0));
201  }
202 };
203 
204 template <int S, class T, class A>
205 struct GetFTensor1FromMatImpl<2, S, T, ublas::row_major, A> {
206  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
207 #ifndef NDDEBUG
208  if (data.size1() != 2)
210  "getFTensor1FromMat<2>: wrong size of data matrix, number of "
211  "rows should be 2 but is " +
212  boost::lexical_cast<std::string>(data.size1()));
213 #endif
214  return FTensor::Tensor1<FTensor::PackPtr<double *, S>, 2>(&data(0, 0),
215  &data(1, 0));
216  }
217 };
218 
219 template <int S, class T, class A>
220 struct GetFTensor1FromMatImpl<1, S, T, ublas::row_major, A> {
221  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
222 #ifndef NDEBUG
223  if (data.size1() != 1)
225  "getFTensor1FromMat<1>: wrong size of data matrix, number of "
226  "rows should be 1 but is " +
227  boost::lexical_cast<std::string>(data.size1()));
228 #endif
229  return FTensor::Tensor1<FTensor::PackPtr<double *, S>, 1>(&data(0, 0));
230  }
231 };
232 
233 /**
234  * \brief Get tensor rank 1 (vector) form data matrix
235  */
236 template <int Tensor_Dim, int S = 1, class T, class L, class A>
238 getFTensor1FromMat(ublas::matrix<T, L, A> &data) {
239  static_assert(!std::is_same<T, T>::value, "not implemented");
240 }
241 
242 /**
243  * \brief Get tensor rank 1 (vector) form data matrix (specialization)
244  */
245 template <int Tensor_Dim, int S = 1>
246 inline auto getFTensor1FromMat(MatrixDouble &data) {
247  return GetFTensor1FromMatImpl<Tensor_Dim, S, double, ublas::row_major,
248  DoubleAllocator>::get(data);
249 }
250 
251 template <int Tensor_Dim1, int Tensor_Dim2, int S, class T, class L, class A>
253  static inline auto get(ublas::matrix<T, L, A> &data) {
254 #ifndef NDEBUG
255  if (data.size1() != Tensor_Dim1 * Tensor_Dim2) {
257  "getFTensor2FromMat<" +
258  boost::lexical_cast<std::string>(Tensor_Dim1) + "," +
259  boost::lexical_cast<std::string>(Tensor_Dim2) +
260  ">: wrong size of rows in data matrix, should be " +
261  boost::lexical_cast<std::string>(Tensor_Dim1 * Tensor_Dim2) +
262  " but is " + boost::lexical_cast<std::string>(data.size1()));
263  }
264 #endif
265  std::array<double *, Tensor_Dim1 * Tensor_Dim2> ptrs;
266  for (auto i = 0; i != Tensor_Dim1 * Tensor_Dim2; ++i)
267  ptrs[i] = &data(i, 0);
269  Tensor_Dim2>(ptrs);
270  }
271 };
272 
273 /**
274  * \brief Get tensor rank 2 (matrix) form data matrix
275  */
276 template <int Tensor_Dim1, int Tensor_Dim2>
277 inline FTensor::Tensor2<FTensor::PackPtr<double *, 1>, Tensor_Dim1, Tensor_Dim2>
279  return GetFTensor2FromMatImpl<Tensor_Dim1, Tensor_Dim2, 1, double,
280  ublas::row_major, DoubleAllocator>::get(data);
281 }
282 
283 template <int Tensor_Dim1, int Tensor_Dim2>
284 inline FTensor::Tensor2<FTensor::PackPtr<double *, 1>, Tensor_Dim1, Tensor_Dim2>
286 
287 /**
288  * Template specialization for getFTensor2FromMat
289  */
290 template <>
293  return FTensor::Tensor2<FTensor::PackPtr<double *, 1>, 1, 1>(&*data.begin());
294 }
295 
296 template <int Tensor_Dim, int S, class T, class L, class A>
298 
299 template <int S, class T, class L, class A>
301  static inline auto get(ublas::matrix<T, L, A> &data) {
302 #ifndef NDEBUG
303  if (data.size1() != 6)
305  "getFTensor2SymmetricFromMat<3>: wrong size of data matrix, numer "
306  "of rows should be 6 but is " +
307  boost::lexical_cast<std::string>(data.size1()));
308 #endif
310  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0), &data(4, 0),
311  &data(5, 0));
312  }
313 };
314 
315 template <int S, class T, class L, class A>
317  static inline auto get(ublas::matrix<T, L, A> &data) {
318 #ifndef NDEBUG
319  if (data.size1() != 3)
321  "getFTensor2SymmetricFromMat<2>: wrong size of data matrix, numer "
322  "of rows should be 3 but is " +
323  boost::lexical_cast<std::string>(data.size1()));
324 #endif
326  &data(0, 0), &data(1, 0), &data(2, 0));
327  }
328 };
329 
330 /**
331  * \brief Get symmetric tensor rank 2 (matrix) form data matrix
332  */
333 template <int Tensor_Dim, int S, class T, class L, class A>
334 static inline auto getFTensor2SymmetricFromMat(ublas::matrix<T, L, A> &data) {
336 }
337 
338 template <int Tensor_Dim, int S = 1>
339 static inline auto getFTensor2SymmetricFromMat(MatrixDouble &data) {
340  return getFTensor2SymmetricFromMat<Tensor_Dim, S, double, ublas::row_major,
341  DoubleAllocator>(data);
342 }
343 
344 template <int Tensor_Dim01, int Tensor_Dim23, int S, class T, class L, class A>
346 
347 template <int S, class T, class A>
348 struct GetFTensor4DdgFromMatImpl<1, 1, S, T, ublas::row_major, A> {
349  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
350 #ifndef NDEBUG
351  if (data.size1() != 1)
353  "getFTensor4DdgFromMat<1, 1>: wrong size of data matrix, number "
354  "of rows should be 1 but is " +
355  boost::lexical_cast<std::string>(data.size1()));
356 #endif
357  return FTensor::Ddg<FTensor::PackPtr<double *, S>, 1, 1>{&data(0, 0)};
358  }
359 };
360 
361 template <int S, class T, class A>
362 struct GetFTensor4DdgFromMatImpl<2, 2, S, T, ublas::row_major, A> {
363  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
364 #ifndef NDEBUG
365  if (data.size1() != 9) {
367  "getFTensor4DdgFromMat<2, 2>: wrong size of data matrix, number "
368  "of rows should be 9 but is " +
369  boost::lexical_cast<std::string>(data.size1()));
370  }
371 #endif
373  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0), &data(4, 0),
374  &data(5, 0), &data(6, 0), &data(7, 0), &data(8, 0)};
375  }
376 };
377 
378 template <int S, class T, class A>
379 struct GetFTensor4DdgFromMatImpl<3, 3, S, T, ublas::row_major, A> {
380  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
381 #ifndef NDEBUG
382  if (data.size1() != 36) {
383  cerr << data.size1() << endl;
385  "getFTensor4DdgFromMat<3, 3>: wrong size of data matrix, number "
386  "of rows should be 36 but is " +
387  boost::lexical_cast<std::string>(data.size1()));
388  }
389 #endif
391  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0), &data(4, 0),
392  &data(5, 0), &data(6, 0), &data(7, 0), &data(8, 0), &data(9, 0),
393  &data(10, 0), &data(11, 0), &data(12, 0), &data(13, 0), &data(14, 0),
394  &data(15, 0), &data(16, 0), &data(17, 0), &data(18, 0), &data(19, 0),
395  &data(20, 0), &data(21, 0), &data(22, 0), &data(23, 0), &data(24, 0),
396  &data(25, 0), &data(26, 0), &data(27, 0), &data(28, 0), &data(29, 0),
397  &data(30, 0), &data(31, 0), &data(32, 0), &data(33, 0), &data(34, 0),
398  &data(35, 0)};
399  }
400 };
401 
402 /**
403  * @brief Get symmetric tensor rank 4 on first two and last indices from
404  * form data matrix
405  *
406  * @tparam Tensor_Dim01 dimension of first two indicies
407  * @tparam Tensor_Dim23 dimension of second two indicies
408  * @tparam Memory shift
409  * @tparam T the type of object stored
410  * @tparam L the storage organization
411  * @tparam A the type of Storage array
412  * @param data data container
413  * @return FTensor::Ddg<FTensor::PackPtr<T *, 1>, Tensor_Dim01, TensorDim23>
414  */
415 template <int Tensor_Dim01, int Tensor_Dim23, int S = 1, class T, class L,
416  class A>
417 static inline FTensor::Ddg<FTensor::PackPtr<T *, 1>, Tensor_Dim01, Tensor_Dim23>
418 getFTensor4DdgFromMat(ublas::matrix<T, L, A> &data) {
419  static_assert(!std::is_same<T, T>::value,
420  "Such getFTensor4DdgFromMat specialisation is not implemented");
421 }
422 
423 template <int Tensor_Dim01, int Tensor_Dim23, int S = 1>
424 static inline auto getFTensor4DdgFromMat(MatrixDouble &data) {
425  return GetFTensor4DdgFromMatImpl<Tensor_Dim01, Tensor_Dim23, S, double,
427  DoubleAllocator>::get(data);
428 }
429 
430 template <int Tensor_Dim01, int Tensor_Dim23, int S, class T>
432 
433 template <int S, class T> struct GetFTensor4DdgFromPtrImpl<3, 3, S, T> {
434  static inline auto get(T *ptr) {
436 
437  ptr + 0, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5,
438  ptr + 6, ptr + 7, ptr + 8, ptr + 9, ptr + 10, ptr + 11,
439  ptr + 12, ptr + 13, ptr + 14, ptr + 15, ptr + 16, ptr + 17,
440  ptr + 18, ptr + 19, ptr + 20, ptr + 21, ptr + 22, ptr + 23,
441  ptr + 24, ptr + 25, ptr + 26, ptr + 27, ptr + 28, ptr + 29,
442  ptr + 30, ptr + 31, ptr + 32, ptr + 33, ptr + 34, ptr + 35};
443  }
444 };
445 
446 template <int Tensor_Dim01, int Tensor_Dim23, int S = 1, class T = double>
447 static inline auto getFTensor4DdgFromPtr(T *ptr) {
449 }
450 
451 template <int Tensor_Dim01, int Tensor_Dim2, int S, class T, class L, class A>
453 
454 template <int S, class T, class A>
455 struct GetFTensor3DgFromMatImpl<1, 1, S, T, ublas::row_major, A> {
456  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
457 #ifndef NDEBUG
458  if (data.size1() != 1)
460  "getFTensor3DgFromMat<1, 1>: wrong size of data matrix, number "
461  "of rows should be 1 but is " +
462  boost::lexical_cast<std::string>(data.size1()));
463 #endif
464  return FTensor::Dg<FTensor::PackPtr<double *, S>, 1, 1>{&data(0, 0)};
465  }
466 };
467 
468 template <int S, class T, class A>
469 struct GetFTensor3DgFromMatImpl<2, 2, S, T, ublas::row_major, A> {
470  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
471 #ifndef NDEBUG
472  if (data.size1() != 6) {
474  "getFTensor4DdgFromMat<2, 2>: wrong size of data matrix, number "
475  "of rows should be 6 but is " +
476  boost::lexical_cast<std::string>(data.size1()));
477  }
478 #endif
480  &data(0, 0), &data(1, 0), &data(2, 0),
481  &data(3, 0), &data(4, 0), &data(5, 0)};
482  }
483 };
484 
485 template <int S, class T, class A>
486 struct GetFTensor3DgFromMatImpl<3, 3, S, T, ublas::row_major, A> {
487  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
488 #ifndef NDEBUG
489  if (data.size1() != 18) {
490  cerr << data.size1() << endl;
492  "getFTensor3DgFromMat<3, 3>: wrong size of data matrix, number "
493  "of rows should be 18 but is " +
494  boost::lexical_cast<std::string>(data.size1()));
495  }
496 #endif
498  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0), &data(4, 0),
499  &data(5, 0), &data(6, 0), &data(7, 0), &data(8, 0), &data(9, 0),
500  &data(10, 0), &data(11, 0), &data(12, 0), &data(13, 0), &data(14, 0),
501  &data(15, 0), &data(16, 0), &data(17, 0)};
502  }
503 };
504 
505 /**
506  * @brief Get symmetric tensor rank 3 on the first two indices from
507  * form data matrix
508  *
509  * @tparam Tensor_Dim01 dimension of first two indicies
510  * @tparam Tensor_Dim2 dimension of last index
511  * @tparam T the type of object stored
512  * @tparam L the storage organization
513  * @tparam A the type of Storage array
514  * @param data data container
515  * @return FTensor::Dg<FTensor::PackPtr<T *, 1>, Tensor_Dim01, TensorDim23>
516  */
517 template <int Tensor_Dim01, int Tensor_Dim2, int S = 1, class T, class L,
518  class A>
519 static inline FTensor::Dg<FTensor::PackPtr<T *, 1>, Tensor_Dim01, Tensor_Dim2>
520 getFTensor3DgFromMat(ublas::matrix<T, L, A> &data) {
521  static_assert(!std::is_same<T, T>::value,
522  "Such getFTensor3DgFromMat specialisation is not implemented");
523 }
524 
525 template <int Tensor_Dim01, int Tensor_Dim2, int S = 1>
526 static inline auto getFTensor3DgFromMat(MatrixDouble &data) {
527  return GetFTensor3DgFromMatImpl<Tensor_Dim01, Tensor_Dim2, S, double,
528  ublas::row_major, DoubleAllocator>::get(data);
529 }
530 
531 template <int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2, int Tensor_Dim3,
532  int S, class T, class L, class A>
534 
535 template <int S, class T, class A>
536 struct GetFTensor4FromMatImpl<1, 1, 1, 1, S, T, ublas::row_major, A> {
537  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
538 #ifndef NDEBUG
539  if (data.size1() != 1)
541  "getFTensor4FromMat<1, 1, 1, 1>: wrong size of data matrix, number "
542  "of rows should be 1 but is " +
543  boost::lexical_cast<std::string>(data.size1()));
544 #endif
546  &data(0, 0)};
547  }
548 };
549 
550 template <int S, class T, class A>
551 struct GetFTensor4FromMatImpl<2, 2, 2, 2, S, T, ublas::row_major, A> {
552  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
553 #ifndef NDEBUG
554  if (data.size1() != 16) {
556  "getFTensor4FromMat<2, 2, 2, 2>: wrong size of data matrix, number "
557  "of rows should be 16 but is " +
558  boost::lexical_cast<std::string>(data.size1()));
559  }
560 #endif
562  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0),
563  &data(4, 0), &data(5, 0), &data(6, 0), &data(7, 0),
564  &data(8, 0), &data(9, 0), &data(10, 0), &data(11, 0),
565  &data(12, 0), &data(13, 0), &data(14, 0), &data(15, 0)};
566  }
567 };
568 
569 template <int S, class T, class A>
570 struct GetFTensor4FromMatImpl<3, 3, 3, 3, S, T, ublas::row_major, A> {
571  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
572 #ifndef NDEBUG
573  if (data.size1() != 81) {
574  cerr << data.size1() << endl;
576  "getFTensor4FromMat<3, 3, 3, 3>: wrong size of data matrix, number "
577  "of rows should be 81 but is " +
578  boost::lexical_cast<std::string>(data.size1()));
579  }
580 #endif
582  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0), &data(4, 0),
583  &data(5, 0), &data(6, 0), &data(7, 0), &data(8, 0), &data(9, 0),
584  &data(10, 0), &data(11, 0), &data(12, 0), &data(13, 0), &data(14, 0),
585  &data(15, 0), &data(16, 0), &data(17, 0), &data(18, 0), &data(19, 0),
586  &data(20, 0), &data(21, 0), &data(22, 0), &data(23, 0), &data(24, 0),
587  &data(25, 0), &data(26, 0), &data(27, 0), &data(28, 0), &data(29, 0),
588  &data(30, 0), &data(31, 0), &data(32, 0), &data(33, 0), &data(34, 0),
589  &data(35, 0), &data(36, 0), &data(37, 0), &data(38, 0), &data(39, 0),
590  &data(40, 0), &data(41, 0), &data(42, 0), &data(43, 0), &data(44, 0),
591  &data(45, 0), &data(46, 0), &data(47, 0), &data(48, 0), &data(49, 0),
592  &data(50, 0), &data(51, 0), &data(52, 0), &data(53, 0), &data(54, 0),
593  &data(55, 0), &data(56, 0), &data(57, 0), &data(58, 0), &data(59, 0),
594  &data(60, 0), &data(61, 0), &data(62, 0), &data(63, 0), &data(64, 0),
595  &data(65, 0), &data(66, 0), &data(67, 0), &data(68, 0), &data(69, 0),
596  &data(70, 0), &data(71, 0), &data(72, 0), &data(73, 0), &data(74, 0),
597  &data(75, 0), &data(76, 0), &data(77, 0), &data(78, 0), &data(79, 0),
598  &data(80, 0)};
599  }
600 };
601 
602 /**
603  * @brief Get tensor rank 4 (non symmetric) form data matrix
604  *
605  * @tparam Tensor_Dim0 dimension of frirst index
606  * @tparam Tensor_Dim1 dimension of second index
607  * @tparam Tensor_Dim2 dimension of third index
608  * @tparam Tensor_Dim3 dimension of fourth index
609  * @tparam T the type of object stored
610  * @tparam L the storage organization
611  * @tparam A the type of Storage array
612  * @param data data container
613  * @return FTensor::Tensor4<FTensor::PackPtr<T *, 1>, Tensor_Dim0,
614  Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>
615  */
616 template <int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2, int Tensor_Dim3,
617  int S = 1, class T, class L, class A>
618 static inline FTensor::Tensor4<FTensor::PackPtr<T *, 1>, Tensor_Dim0,
619  Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>
620 getFTensor4FromMat(ublas::matrix<T, L, A> &data) {
621  static_assert(!std::is_same<T, T>::value,
622  "Such getFTensor4FromMat specialisation is not implemented");
623 }
624 
625 template <int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2, int Tensor_Dim3,
626  int S = 1>
627 static inline auto getFTensor4FromMat(MatrixDouble &data) {
628  return GetFTensor4FromMatImpl<Tensor_Dim0, Tensor_Dim1, Tensor_Dim2,
629  Tensor_Dim3, S, double, ublas::row_major,
630  DoubleAllocator>::get(data);
631 }
632 
633 template <int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2, int S, class T,
634  class L, class A>
636 
637 template <int S, class T, class A>
638 struct GetFTensor3FromMatImpl<1, 1, 1, S, T, ublas::row_major, A> {
639  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
640 #ifndef NDEBUG
641  if (data.size1() != 1)
643  "getFTensor3FromMat<1, 1, 1>: wrong size of data matrix, number "
644  "of rows should be 1 but is " +
645  boost::lexical_cast<std::string>(data.size1()));
646 #endif
648  &data(0, 0)};
649  }
650 };
651 
652 template <int S, class T, class A>
653 struct GetFTensor3FromMatImpl<2, 2, 2, S, T, ublas::row_major, A> {
654  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
655 #ifndef NDEBUG
656  if (data.size1() != 8)
658  "getFTensor3FromMat<2, 2, 2>: wrong size of data matrix, number "
659  "of rows should be 8 but is " +
660  boost::lexical_cast<std::string>(data.size1()));
661 #endif
663  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0), &data(4, 0),
664  &data(5, 0), &data(6, 0), &data(7, 0)
665 
666  };
667  }
668 };
669 
670 template <int S, class T, class A>
671 struct GetFTensor3FromMatImpl<3, 2, 2, S, T, ublas::row_major, A> {
672  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
673 #ifndef NDEBUG
674  if (data.size1() != 12)
676  "getFTensor3FromMat<3, 2, 2>: wrong size of data matrix, number "
677  "of rows should be 12 but is " +
678  boost::lexical_cast<std::string>(data.size1()));
679 #endif
681  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0),
682  &data(4, 0), &data(5, 0), &data(6, 0), &data(7, 0),
683  &data(8, 0), &data(9, 0), &data(10, 0), &data(11, 0)};
684  }
685 };
686 
687 template <int S, class T, class A>
688 struct GetFTensor3FromMatImpl<2, 2, 3, S, T, ublas::row_major, A> {
689  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
690 #ifndef NDEBUG
691  if (data.size1() != 12)
693  "getFTensor3FromMat<2, 2, 3>: wrong size of data matrix, number "
694  "of rows should be 12 but is " +
695  boost::lexical_cast<std::string>(data.size1()));
696 #endif
698  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0),
699  &data(4, 0), &data(5, 0), &data(6, 0), &data(7, 0),
700  &data(8, 0), &data(9, 0), &data(10, 0), &data(11, 0)};
701  }
702 };
703 
704 template <int S, class T, class A>
705 struct GetFTensor3FromMatImpl<3, 3, 3, S, T, ublas::row_major, A> {
706  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
707 #ifndef NDEBUG
708  if (data.size1() != 27)
710  "getFTensor3FromMat<3, 3, 3>: wrong size of data matrix, number "
711  "of rows should be 27 but is " +
712  boost::lexical_cast<std::string>(data.size1()));
713 #endif
715  &data(0, 0), &data(1, 0), &data(2, 0), &data(3, 0), &data(4, 0),
716  &data(5, 0), &data(6, 0), &data(7, 0), &data(8, 0), &data(9, 0),
717  &data(10, 0), &data(11, 0), &data(12, 0), &data(13, 0), &data(14, 0),
718  &data(15, 0), &data(16, 0), &data(17, 0), &data(18, 0), &data(19, 0),
719  &data(20, 0), &data(21, 0), &data(22, 0), &data(23, 0), &data(24, 0),
720  &data(25, 0), &data(26, 0)};
721  }
722 };
723 
724 template <int S, class T, class A>
725 struct GetFTensor3FromMatImpl<6, 3, 3, S, T, ublas::row_major, A> {
726  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
727 #ifndef NDEBUG
728  if (data.size1() != 54)
730  "getFTensor3FromMat<6, 3, 3>: wrong size of data matrix, number "
731  "of rows should be 54 but is " +
732  boost::lexical_cast<std::string>(data.size1()));
733 #endif
734  std::array<double *, 54> ptrs;
735  for (auto i = 0; i != 54; ++i)
736  ptrs[i] = &data(i, 0);
737  return FTensor::Tensor3<FTensor::PackPtr<double *, S>, 6, 3, 3>(ptrs);
738  }
739 };
740 
741 template <int S, class T, class A>
742 struct GetFTensor3FromMatImpl<3, 3, 6, S, T, ublas::row_major, A> {
743  static inline auto get(ublas::matrix<T, ublas::row_major, A> &data) {
744 #ifndef NDEBUG
745  if (data.size1() != 54)
747  "getFTensor3FromMat<3, 3, 6>: wrong size of data matrix, number "
748  "of rows should be 54 but is " +
749  boost::lexical_cast<std::string>(data.size1()));
750 #endif
751  std::array<double *, 54> ptrs;
752  for (auto i = 0; i != 54; ++i)
753  ptrs[i] = &data(i, 0);
754  return FTensor::Tensor3<FTensor::PackPtr<double *, S>, 3, 3, 6>(ptrs);
755  }
756 };
757 
758 /**
759  * @brief Get tensor rank 3 (non symmetries) form data matrix
760  *
761  * @tparam Tensor_Dim0 dimension of first index
762  * @tparam Tensor_Dim1 dimension of second index
763  * @tparam Tensor_Dim2 dimension of third index
764  * @tparam S shift size
765  * @tparam T the type of object stored
766  * @tparam L the storage organization
767  * @tparam A the type of Storage array
768  * @param data data container
769  * @return FTensor::Tensor3<FTensor::PackPtr<T *, 1>, Tensor_Dim0,
770  Tensor_Dim1, Tensor_Dim2>
771  */
772 template <int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2, int S = 1, class T,
773  class L, class A>
774 static inline FTensor::Tensor3<FTensor::PackPtr<T *, 1>, Tensor_Dim0,
775  Tensor_Dim1, Tensor_Dim2>
776 getFTensor3FromMat(ublas::matrix<T, L, A> &data) {
777  static_assert(!std::is_same<T, T>::value,
778  "Such getFTensor3FromMat specialisation is not implemented");
779 }
780 
781 template <int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2, int S = 1>
782 static inline auto getFTensor3FromMat(MatrixDouble &data) {
783  return GetFTensor3FromMatImpl<Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, S,
785  DoubleAllocator>::get(data);
786 }
787 
788 template <int DIM, int S, typename T> struct GetFTensor1FromPtrImpl;
789 
790 template <int S, typename T> struct GetFTensor1FromPtrImpl<1, S, T> {
791  GetFTensor1FromPtrImpl() = delete;
792  inline static auto get(T *ptr) {
794  }
795 };
796 
797 template <int S, typename T> struct GetFTensor1FromPtrImpl<2, S, T> {
798  GetFTensor1FromPtrImpl() = delete;
799  inline static auto get(T *ptr) {
801  ptr + HVEC1);
802  }
803 };
804 
805 template <int S, typename T> struct GetFTensor1FromPtrImpl<3, S, T> {
806  GetFTensor1FromPtrImpl() = delete;
807  inline static auto get(T *ptr) {
809  ptr + HVEC0, ptr + HVEC1, ptr + HVEC2);
810  }
811 };
812 
813 template <int S, typename T> struct GetFTensor1FromPtrImpl<4, S, T> {
814  GetFTensor1FromPtrImpl() = delete;
815  inline static auto get(T *ptr) {
816  return FTensor::Tensor1<FTensor::PackPtr<T *, S>, 4>(ptr + 0, ptr + 1,
817  ptr + 2, ptr + 3);
818  }
819 };
820 
821 template <int S, typename T> struct GetFTensor1FromPtrImpl<6, S, T> {
822  GetFTensor1FromPtrImpl() = delete;
823  inline static auto get(T *ptr) {
825  ptr + 0, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5);
826  }
827 };
828 
829 /**
830  * @brief Make Tensor1 from pointer
831  *
832  * @tparam DIM
833  * @param ptr
834  * @return FTensor::Tensor2<FTensor::PackPtr<double *, 3 * DIM>, 3, DIM>
835  */
836 template <int DIM, int S = DIM>
838 getFTensor1FromPtr(double *ptr) {
840 };
841 
842 #ifdef WITH_ADOL_C
843 template <int DIM, int S = DIM>
847 };
848 #endif
849 
850 template <int DIM, int S = DIM>
852 getFTensor1FromPtr(std::complex<double> *ptr) {
854 };
855 
856 template <int DIM1, int DIM2, int S, typename T> struct GetFTensor2FromPtr;
857 
858 template <int S, typename T> struct GetFTensor2FromPtr<3, 2, S, T> {
859  GetFTensor2FromPtr() = delete;
860  inline static auto get(T *ptr) {
862  ptr + 0, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5);
863  }
864 };
865 
866 template <int S, typename T> struct GetFTensor2FromPtr<6, 6, S, T> {
867  GetFTensor2FromPtr() = delete;
868  inline static auto get(T *ptr) {
870  ptr + 0, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5, ptr + 6, ptr + 7,
871  ptr + 8, ptr + 9, ptr + 10, ptr + 11, ptr + 12, ptr + 13, ptr + 14,
872  ptr + 15, ptr + 16, ptr + 17, ptr + 18, ptr + 19, ptr + 20, ptr + 21,
873  ptr + 22, ptr + 23, ptr + 24, ptr + 25, ptr + 26, ptr + 27, ptr + 28,
874  ptr + 29, ptr + 30, ptr + 31, ptr + 32, ptr + 33, ptr + 34, ptr + 35);
875  }
876 };
877 
878 template <int S, typename T> struct GetFTensor2FromPtr<3, 3, S, T> {
879  GetFTensor2FromPtr() = delete;
880  inline static auto get(T *ptr) {
882  ptr + 0, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5, ptr + 6, ptr + 7,
883  ptr + 8);
884  }
885 };
886 
887 template <int S, typename T> struct GetFTensor2FromPtr<2, 2, S, T> {
888  GetFTensor2FromPtr() = delete;
889  inline static auto get(T *ptr) {
890  return FTensor::Tensor2<FTensor::PackPtr<T *, S>, 2, 2>(&ptr[0], &ptr[1],
891  &ptr[2], &ptr[3]);
892  }
893 };
894 
895 template <int S, typename T> struct GetFTensor2FromPtr<1, 3, S, T> {
896  GetFTensor2FromPtr() = delete;
897  inline static auto get(T *ptr) {
898  return FTensor::Tensor2<FTensor::PackPtr<T *, S>, 1, 3>(&ptr[0], &ptr[1],
899  &ptr[2]);
900  }
901 };
902 
903 template <int S, typename T> struct GetFTensor2FromPtr<1, 2, S, T> {
904  GetFTensor2FromPtr() = delete;
905  inline static auto get(T *ptr) {
906  return FTensor::Tensor2<FTensor::PackPtr<T *, S>, 1, 2>(&ptr[0], &ptr[1]);
907  }
908 };
909 
910 template <int S, typename T> struct GetFTensor2FromPtr<1, 1, S, T> {
911  GetFTensor2FromPtr() = delete;
912  inline static auto get(T *ptr) {
913  return FTensor::Tensor2<FTensor::PackPtr<T *, S>, 1, 1>(&ptr[0]);
914  }
915 };
916 
917 /**
918  * @brief Make Tensor2 from pointer
919  *
920  * @tparam DIM
921  * @param ptr
922  * @return FTensor::Tensor2<FTensor::PackPtr<double *, S>, DIM1, DIM2>
923  */
924 template <int DIM1, int DIM2, int S = DIM1 * DIM2>
925 inline auto getFTensor2FromPtr(double *ptr) {
927 };
928 
929 /**
930  * @brief Make Tensor2 from pointer
931  *
932  * @tparam DIM
933  * @param ptr
934  * @return FTensor::Tensor2<FTensor::PackPtr<double *, S>, DIM1, DIM2>
935  */
936 template <int DIM1, int DIM2, int S = DIM1 * DIM2>
937 inline auto getFTensor2FromPtr(std::complex<double> *ptr) {
939 };
940 
941 /**
942  * @brief Make Tensor2 for HVec base from pointer
943  *
944  * @tparam DIM
945  * @param ptr
946  * @return FTensor::Tensor2<FTensor::PackPtr<double *, DIM1 * DIM2>, DIM1, DIM2>
947  */
948 template <int DIM1, int DIM2>
951  static_assert(DIM1 == DIM1 || DIM2 != DIM2,
952  "Such getFTensor2HVecFromPtr is not implemented");
953 };
954 
955 template <>
957  2> inline getFTensor2HVecFromPtr<3, 2>(double *ptr) {
959  ptr + HVEC0_0, ptr + HVEC0_1,
960 
961  ptr + HVEC1_0, ptr + HVEC1_1,
962 
963  ptr + HVEC2_0, ptr + HVEC2_1);
964 };
965 
966 template <>
968  3> inline getFTensor2HVecFromPtr<3, 3>(double *ptr) {
970  ptr + HVEC0_0, ptr + HVEC0_1, ptr + HVEC0_2,
971 
972  ptr + HVEC1_0, ptr + HVEC1_1, ptr + HVEC1_2,
973 
974  ptr + HVEC2_0, ptr + HVEC2_1, ptr + HVEC2_2);
975 };
976 
977 /*
978  * @brief Make Tensor3 from pointer
979  *
980  * @tparam DIM
981  * @param ptr
982  * @return FTensor::Tensor3<FTensor::PackPtr<double *, DIM1 * DIM2* DIM3>, DIM1,
983  * DIM2, DIM3>
984  */
985 template <int DIM1, int DIM2, int DIM3>
987  DIM2, DIM3>
988 getFTensor3FromPtr(double *ptr) {
989  static_assert(DIM1 == DIM1 || DIM2 != DIM2 || DIM3 != DIM3,
990  "Such getFTensor3FromPtr is not implemented");
991 };
992 
993 template <>
997  ptr + 0, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5, ptr + 6, ptr + 7,
998  ptr + 8, ptr + 9, ptr + 10, ptr + 11);
999 };
1000 
1001 template <>
1005  ptr + 0, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5, ptr + 6, ptr + 7,
1006  ptr + 8, ptr + 9, ptr + 10, ptr + 11, ptr + 12, ptr + 13, ptr + 14,
1007  ptr + 15, ptr + 16, ptr + 17, ptr + 18, ptr + 19, ptr + 20, ptr + 21,
1008  ptr + 22, ptr + 23, ptr + 24, ptr + 25, ptr + 26);
1009 };
1010 
1011 /**
1012  * @brief Make symmetric Tensor2 from pointer
1013  *
1014  * @tparam DIM
1015  * @param ptr
1016  * @return FTensor::Tensor2<FTensor::PackPtr<double *, DIM1 * DIM2>, DIM1, DIM2>
1017  */
1018 template <int DIM>
1020  FTensor::PackPtr<double *, (DIM * (DIM + 1)) / 2>, DIM>
1022  static_assert(DIM, "Such getFTensor2SymmetricFromPtr is not implemented");
1023 }
1024 
1025 template <>
1029  ptr + 0, ptr + 1, ptr + 2,
1030 
1031  ptr + 3, ptr + 4,
1032 
1033  ptr + 5);
1034 };
1035 
1036 template <>
1040  &ptr[0], &ptr[1], &ptr[2]);
1041 };
1042 
1043 #ifdef WITH_ADOL_C
1044 
1045 /**
1046  * @brief Make symmetric Tensor2 from pointer
1047  *
1048  * @tparam DIM
1049  * @param ptr
1050  * @return FTensor::Tensor2<FTensor::PackPtr<double *, DIM1 * DIM2>, DIM1, DIM2>
1051  */
1052 template <int DIM>
1054  FTensor::PackPtr<adouble *, (DIM * (DIM + 1)) / 2>, DIM>
1056  static_assert(DIM, "Such getFTensor2SymmetricFromPtr is not implemented");
1057 }
1058 
1059 template <>
1063  ptr + 0, ptr + 1, ptr + 2,
1064 
1065  ptr + 3, ptr + 4,
1066 
1067  ptr + 5);
1068 };
1069 
1070 template <>
1074  ptr + 0, ptr + 1, ptr + 2);
1075 };
1076 
1077 #endif
1078 
1079 /**
1080  * @brief Make symmetric Tensor2 from pointer, taking lower triangle of matrix
1081  *
1082  * @tparam DIM
1083  * @param ptr
1084  * @return FTensor::Tensor2<FTensor::PackPtr<double *, DIM1 * DIM2>, DIM1, DIM2>
1085  */
1086 template <int DIM>
1089  static_assert(DIM,
1090  "Such getFTensor2SymmetricLowerFromPtr is not implemented");
1091 }
1092 
1093 template <>
1097  ptr + HVEC0_0, ptr + HVEC0_1, ptr + HVEC0_2,
1098 
1099  ptr + HVEC1_0, ptr + HVEC1_1,
1100 
1101  ptr + HVEC2_2);
1102 };
1103 
1104 template <>
1108  ptr + 0, ptr + 1, ptr + 3);
1109 };
1110 
1111 template <int DIM, int S> struct GetFTensor1FromArray;
1112 
1113 template <int S> struct GetFTensor1FromArray<1, S> {
1114  GetFTensor1FromArray() = delete;
1115  template <typename V> static inline auto get(V &data) {
1116  using T = typename std::remove_reference<decltype(data[0])>::type;
1117  return FTensor::Tensor1<FTensor::PackPtr<T *, S>, 1>{&data[0]};
1118  }
1119 };
1120 
1121 template <int S> struct GetFTensor1FromArray<2, S> {
1122  GetFTensor1FromArray() = delete;
1123  template <typename V> static inline auto get(V &data) {
1124  using T = typename std::remove_reference<decltype(data[0])>::type;
1125  return FTensor::Tensor1<FTensor::PackPtr<T *, S>, 2>{&data[0], &data[1]};
1126  }
1127 };
1128 
1129 template <int S> struct GetFTensor1FromArray<3, S> {
1130  GetFTensor1FromArray() = delete;
1131  template <typename V> static inline auto get(V &data) {
1132  using T = typename std::remove_reference<decltype(data[0])>::type;
1133  return FTensor::Tensor1<FTensor::PackPtr<T *, S>, 3>{&data[0], &data[1],
1134  &data[2]};
1135  }
1136 };
1137 
1138 template <int S> struct GetFTensor1FromArray<4, S> {
1139  GetFTensor1FromArray() = delete;
1140  template <typename V> static inline auto get(V &data) {
1141  using T = typename std::remove_reference<decltype(data[0])>::type;
1142  return FTensor::Tensor1<FTensor::PackPtr<T *, S>, 4>{&data[0], &data[1],
1143  &data[2], &data[3]};
1144  }
1145 };
1146 
1147 template <int S> struct GetFTensor1FromArray<6, S> {
1148  GetFTensor1FromArray() = delete;
1149  template <typename V> static inline auto get(V &data) {
1150  using T = typename std::remove_reference<decltype(data[0])>::type;
1152  &data[0], &data[1], &data[2], &data[3], &data[4], &data[5]};
1153  }
1154 };
1155 
1156 template <int S> struct GetFTensor1FromArray<9, S> {
1157  GetFTensor1FromArray() = delete;
1158  template <typename V> static inline auto get(V &data) {
1159  using T = typename std::remove_reference<decltype(data[0])>::type;
1161  &data[0], &data[1], &data[2], &data[3], &data[4],
1162  &data[5], &data[6], &data[7], &data[8]};
1163  }
1164 };
1165 
1166 /**
1167  * @brief Get FTensor1 from array
1168  *
1169  * \todo Generalise for different arrays and data types
1170  *
1171  * @tparam DIM
1172  * @param data
1173  * @return FTensor::Tensor1<FTensor::PackPtr<double *, S>, DIM>
1174  */
1175 template <int DIM, int S> inline auto getFTensor1FromArray(VectorDouble &data) {
1176  return GetFTensor1FromArray<DIM, S>::get(data);
1177 }
1178 
1179 /** @copydoc getFTensor1FromArray */
1180 template <int DIM, int S = 0>
1181 inline auto getFTensor1FromArray(VectorDouble3 &data);
1182 
1183 template <> inline auto getFTensor1FromArray<3, 0>(VectorDouble3 &data) {
1184  return GetFTensor1FromArray<3, 0>::get(data);
1185 }
1186 
1187 template <int DIM, int S>
1189 getFTensor1FromMat(MatrixDouble &data, const size_t rr);
1190 
1191 template <>
1193 getFTensor1FromMat(MatrixDouble &data, const size_t rr) {
1194  return FTensor::Tensor1<FTensor::PackPtr<double *, 1>, 2>{&data(rr + 0, 0),
1195  &data(rr + 1, 0)};
1196 }
1197 
1198 template <>
1200 getFTensor1FromMat(MatrixDouble &data, const size_t rr) {
1202  &data(rr + 0, 0), &data(rr + 1, 0), &data(rr + 2, 0)};
1203 }
1204 
1205 template <>
1207 getFTensor1FromMat(MatrixDouble &data, const size_t rr) {
1209  &data(rr + 0, 0), &data(rr + 1, 0), &data(rr + 2, 0), &data(rr + 3, 0)};
1210 }
1211 
1212 template <>
1214 getFTensor1FromMat(MatrixDouble &data, const size_t rr) {
1216  &data(rr + 0, 0), &data(rr + 1, 0), &data(rr + 2, 0),
1217  &data(rr + 3, 0), &data(rr + 4, 0), &data(rr + 5, 0),
1218  &data(rr + 6, 0), &data(rr + 7, 0), &data(rr + 8, 0)};
1219 }
1220 
1221 /**
1222  * @brief Get FTensor1 from array
1223  *
1224  * \todo Generalise for diffrent arrays and data types
1225  *
1226  * @tparam DIM
1227  * @param data
1228  * @param rr
1229  * @return FTensor::Tensor1<FTensor::PackPtr<double *, DIM>, DIM>
1230  */
1231 template <int DIM, int S>
1233 getFTensor1FromArrayDiag(MatrixDouble &data, const size_t rr) {
1234  static_assert(DIM != DIM, "not implemented");
1236 }
1237 
1238 template <>
1240 getFTensor1FromArrayDiag(MatrixDouble &data, const size_t rr) {
1241  return FTensor::Tensor1<FTensor::PackPtr<double *, 2>, 2>{&data(rr + 0, 0),
1242  &data(rr + 1, 1)};
1243 }
1244 
1245 template <>
1247 getFTensor1FromArrayDiag(MatrixDouble &data, const size_t rr) {
1249  &data(rr + 0, 0), &data(rr + 1, 1), &data(rr + 2, 2)};
1250 }
1251 
1252 /**
1253  * @brief Get FTensor2 from array
1254  *
1255  * \note Generalise for other data types
1256  *
1257  * @tparam DIM1
1258  * @tparam DIM2
1259  * @tparam S
1260  * @param data
1261  * @return FTensor::Tensor2<FTensor::PackPtr<double *, S>, DIM1, DIM2>
1262  */
1263 template <int DIM1, int DIM2, int S, class T, class L, class A>
1265 
1266 template <int DIM1, int DIM2, class T, class L, class A>
1268 
1269 template <int S, class T, class L, class A>
1270 struct GetFTensor2FromArrayImpl<2, 2, S, T, L, A> {
1271  GetFTensor2FromArrayImpl() = delete;
1272  inline static auto get(ublas::matrix<T, L, A> &data, const size_t rr,
1273  const size_t cc) {
1275  &data(rr + 0, cc + 0), &data(rr + 0, cc + 1),
1276 
1277  &data(rr + 1, cc + 0), &data(rr + 1, cc + 1)};
1278  }
1279 };
1280 
1281 template <int S, class T, class L, class A>
1282 struct GetFTensor2FromArrayImpl<3, 3, S, T, L, A> {
1283  GetFTensor2FromArrayImpl() = delete;
1284  inline static auto get(ublas::matrix<T, L, A> &data, const size_t rr,
1285  const size_t cc) {
1287  &data(rr + 0, cc + 0), &data(rr + 0, cc + 1), &data(rr + 0, cc + 2),
1288  &data(rr + 1, cc + 0), &data(rr + 1, cc + 1), &data(rr + 1, cc + 2),
1289  &data(rr + 2, cc + 0), &data(rr + 2, cc + 1), &data(rr + 2, cc + 2)};
1290  }
1291 };
1292 
1293 template <class T, class L, class A>
1295  GetFTensor2FromArrayRawPtrImpl() = delete;
1296  inline static auto get(ublas::matrix<T, L, A> &data, const size_t rr,
1297  const size_t cc, const int ss = 0) {
1299  &data(rr + 0, cc + 0), &data(rr + 0, cc + 1),
1300 
1301  &data(rr + 1, cc + 0), &data(rr + 1, cc + 1), ss);
1302  }
1303 };
1304 
1305 template <class T, class L, class A>
1307  GetFTensor2FromArrayRawPtrImpl() = delete;
1308  inline static auto get(ublas::matrix<T, L, A> &data, const size_t rr,
1309  const size_t cc, const int ss = 0) {
1311  &data(rr + 0, cc + 0), &data(rr + 0, cc + 1), &data(rr + 0, cc + 2),
1312  &data(rr + 1, cc + 0), &data(rr + 1, cc + 1), &data(rr + 1, cc + 2),
1313  &data(rr + 2, cc + 0), &data(rr + 2, cc + 1), &data(rr + 2, cc + 2),
1314  ss);
1315  }
1316 };
1317 
1318 template <int DIM1, int DIM2, int S>
1320 getFTensor2FromArray(MatrixDouble &data, const size_t rr, const size_t cc = 0) {
1322  VecAllocator<double>>::get(data, rr, cc);
1323 }
1324 
1325 template <int DIM1, int DIM2>
1327 getFTensor2FromArray(MatrixDouble &data, const size_t rr, const size_t cc,
1328  const int ss) {
1330  VecAllocator<double>>::get(data, rr, cc,
1331  ss);
1332 }
1333 
1334 template <int S, typename T, typename L, typename A>
1335 inline auto getFTensor2FromArray2by2(ublas::matrix<T, L, A> &data,
1336  const FTensor::Number<S> &,
1337  const size_t rr, const size_t cc = 0) {
1339 }
1340 
1341 template <int S, typename T, typename L, typename A>
1342 inline auto getFTensor2FromArray3by3(ublas::matrix<T, L, A> &data,
1343  const FTensor::Number<S> &,
1344  const size_t rr, const size_t cc = 0) {
1346 }
1347 
1348 #ifdef WITH_ADOL_C
1349 
1350 template <int DIM1, int DIM2, int S>
1351 inline auto getFTensor2FromArray(MatrixADouble &data, const size_t rr) {
1353  VecAllocator<adouble>>::get(data, rr);
1354 }
1355 
1356 #endif
1357 
1358 // list of lapack wrappers
1359 /**
1360  * @brief compute matrix inverse with lapack dgetri
1361  *
1362  * @param mat input square matrix / output inverse matrix
1363  * @return MoFEMErrorCode
1364  */
1367 
1368  const size_t M = mat.size1();
1369  const size_t N = mat.size2();
1370 
1371  if (M != N)
1372  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1373  "The input matrix for inverse computation is not square %d != %d",
1374  M, N);
1375 
1376  int *ipv = new int[N];
1377  int lwork = N * N;
1378  double *work = new double[lwork];
1379  int info;
1380  info = lapack_dgetrf(N, N, &*mat.data().begin(), N, ipv);
1381  if (info != 0)
1382  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1383  "lapack error info = %d", info);
1384  info = lapack_dgetri(N, &*mat.data().begin(), N, ipv, work, lwork);
1385  if (info != 0)
1386  SETERRQ1(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1387  "lapack error info = %d", info);
1388 
1389  delete[] ipv;
1390  delete[] work;
1391 
1393 }
1394 /**
1395  * @brief solve linear system with lapack dgesv
1396  *
1397  * @param mat input lhs square matrix / output L and U from the factorization
1398  * @param f input rhs vector / output solution vector
1399  * @return MoFEMErrorCode
1400  */
1403 
1404  const size_t M = mat.size1();
1405  const size_t N = mat.size2();
1406 
1407  if (M == 0 || M != N)
1408  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1409  "The input matrix for inverse computation is not square %d != %d",
1410  M, N);
1411  if (f.size() != M)
1412  f.resize(M, false);
1413 
1414  const int nrhs = 1;
1415  int info;
1416  int *ipiv = new int[M];
1417  info = lapack_dgesv(M, nrhs, &*mat.data().begin(), M, ipiv,
1418  &*f.data().begin(), M);
1419  if (info != 0) {
1420  SETERRQ1(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1421  "error lapack solve dgesv info = %d", info);
1422  }
1423 
1424  delete[] ipiv;
1426 }
1427 
1428 /**
1429  * @brief Solve linear system of equations using Lapack
1430  *
1431  * @param mat
1432  * @param f
1433  * @return MoFEMErrorCode
1434  */
1436  VectorDouble &f) {
1438  // copy matrix since on output lapack returns factorisation
1439  auto mat_copy = mat;
1440  CHKERR solveLinearSystem(mat_copy, f);
1442 }
1443 
1444 /**
1445  * @brief compute eigenvalues of a symmetric matrix using lapack dsyev
1446  *
1447  * @param mat input symmetric matrix
1448  * @param eig output eigen values sorted
1449  * @param eigen_vec output matrix of row eigen vectors
1450  * @return MoFEMErrorCode
1451  */
1453  VectorDouble &eig,
1454  MatrixDouble &eigen_vec) {
1456 
1457  const size_t M = mat.size1();
1458  const size_t N = mat.size2();
1459 
1460  if (M == 0 || M != N)
1461  SETERRQ2(
1462  PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1463  "The input matrix for eigen value computation is not square %d != %d",
1464  M, N);
1465  if (eig.size() != M)
1466  eig.resize(M, false);
1467 
1468  eigen_vec = mat;
1469  const int n = M;
1470  const int lda = M;
1471  const int size = (M + 2) * M;
1472  int lwork = size;
1473  double *work = new double[size];
1474 
1475  if (lapack_dsyev('V', 'U', n, &*eigen_vec.data().begin(), lda,
1476  &*eig.data().begin(), work, lwork) > 0)
1477  SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
1478  "The algorithm failed to compute eigenvalues.");
1479 
1480  delete[] work;
1482 }
1483 /**
1484  * @brief compute eigenvalues of a symmetric matrix using lapack dsyev
1485  *
1486  * @tparam DIM
1487  * @param eigen_vec input / output DIM x DIM matrix of row eigen vectors
1488  * @param eig output eigen values sorted
1489  * @return MoFEMErrorCode
1490  */
1491 template <int DIM, typename T1, typename T2>
1492 inline MoFEMErrorCode
1496 
1497  const int n = DIM;
1498  const int lda = DIM;
1499  const int lwork = (DIM + 2) * DIM;
1500  std::array<double, (DIM + 2) * DIM> work;
1501 
1502  if (lapack_dsyev('V', 'U', n, &eigen_vec(0, 0), lda, &eig(0), work.data(),
1503  lwork) > 0)
1504  SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
1505  "The algorithm failed to compute eigenvalues.");
1507 }
1508 
1509 /**
1510  * @brief compute eigenvalues of a symmetric tensor using lapack dsyev
1511  *
1512  * @tparam DIM
1513  * @param mat input tensor pointer of size DIM x DIM
1514  * @param eig output eigen values sorted
1515  * @param eigen_vec output matrix of row eigen vectors
1516  * @return MoFEMErrorCode
1517  */
1518 template <int DIM, typename T1, typename T2, typename T3>
1519 inline MoFEMErrorCode
1522  FTensor::Tensor2<T3, DIM, DIM> &eigen_vec) {
1524  for (int ii = 0; ii != DIM; ii++)
1525  for (int jj = 0; jj != DIM; jj++)
1526  eigen_vec(ii, jj) = mat(ii, jj);
1527 
1528  CHKERR computeEigenValuesSymmetric(eigen_vec, eig);
1529 
1531 }
1532 
1533 /**
1534  * @brief Calculate the determinant of a 3x3 matrix or a tensor of rank 2
1535  *
1536  * @tparam T
1537  * @param t
1538  * @return double
1539  */
1540 template <typename T> static inline auto determinantTensor3by3(T &t) {
1541  return t(0, 0) * t(1, 1) * t(2, 2) + t(1, 0) * t(2, 1) * t(0, 2) +
1542  t(2, 0) * t(0, 1) * t(1, 2) - t(0, 0) * t(2, 1) * t(1, 2) -
1543  t(2, 0) * t(1, 1) * t(0, 2) - t(1, 0) * t(0, 1) * t(2, 2);
1544 }
1545 
1546 /**
1547  * @brief Calculate the determinant of a 2x2 matrix or a tensor of rank 2
1548  *
1549  * @tparam T
1550  * @param t
1551  * @return double
1552  */
1553 template <typename T> static inline auto determinantTensor2by2(T &t) {
1554  return t(0, 0) * t(1, 1) - t(0, 1) * t(1, 0);
1555 }
1556 
1557 template <typename T, int DIM> struct DeterminantTensorImpl;
1558 
1559 template <typename T> struct DeterminantTensorImpl<T, 3> {
1560  static inline auto get(T &t) { return determinantTensor3by3(t); }
1561 };
1562 
1563 template <typename T> struct DeterminantTensorImpl<T, 2> {
1564  static auto get(T &t) { return determinantTensor2by2(t); }
1565 };
1566 
1567 /**
1568  * @brief Calculate the determinant of a tensor of rank DIM
1569  */
1570 template <typename T, int DIM>
1573 }
1574 
1575 /**
1576  * @brief Calculate the determinant of a tensor of rank DIM
1577  */
1578 template <typename T, int DIM>
1581 }
1582 
1583 /**
1584  * \brief Calculate inverse of tensor rank 2 at integration points
1585 
1586  */
1587 template <int Tensor_Dim, class T, class L, class A>
1588 inline MoFEMErrorCode invertTensor3by3(ublas::matrix<T, L, A> &jac_data,
1589  ublas::vector<T, A> &det_data,
1590  ublas::matrix<T, L, A> &inv_jac_data) {
1592  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1593  "Specialization for this template not yet implemented");
1595 }
1596 
1597 template <>
1598 inline MoFEMErrorCode
1599 invertTensor3by3<3, double, ublas::row_major, DoubleAllocator>(
1600  MatrixDouble &jac_data, VectorDouble &det_data, MatrixDouble &inv_jac_data);
1601 
1602 /**
1603  * \brief Calculate determinant 3 by 3
1604 
1605  */
1606 template <class T1, class T2>
1609  det = determinantTensor3by3(t);
1611 }
1612 
1613 /**
1614  * \brief Calculate determinant 2 by 2
1615 
1616  */
1617 template <class T1, class T2>
1620  det = determinantTensor2by2(t);
1622 }
1623 
1624 /**
1625  * \brief Calculate matrix inverse 3 by 3
1626 
1627  */
1628 template <class T1, class T2, class T3>
1629 inline MoFEMErrorCode invertTensor3by3(T1 &t, T2 &det, T3 &inv_t) {
1631  const auto inv_det = 1. / det;
1632  inv_t(0, 0) = (t(1, 1) * t(2, 2) - t(1, 2) * t(2, 1)) * inv_det;
1633  inv_t(0, 1) = (t(0, 2) * t(2, 1) - t(0, 1) * t(2, 2)) * inv_det;
1634  inv_t(0, 2) = (t(0, 1) * t(1, 2) - t(0, 2) * t(1, 1)) * inv_det;
1635  inv_t(1, 0) = (t(1, 2) * t(2, 0) - t(1, 0) * t(2, 2)) * inv_det;
1636  inv_t(1, 1) = (t(0, 0) * t(2, 2) - t(0, 2) * t(2, 0)) * inv_det;
1637  inv_t(1, 2) = (t(0, 2) * t(1, 0) - t(0, 0) * t(1, 2)) * inv_det;
1638  inv_t(2, 0) = (t(1, 0) * t(2, 1) - t(1, 1) * t(2, 0)) * inv_det;
1639  inv_t(2, 1) = (t(0, 1) * t(2, 0) - t(0, 0) * t(2, 1)) * inv_det;
1640  inv_t(2, 2) = (t(0, 0) * t(1, 1) - t(0, 1) * t(1, 0)) * inv_det;
1642 }
1643 
1644 /**
1645  * \brief Calculate matrix inverse 2 by 2
1646 
1647  */
1648 template <class T1, class T2, class T3>
1649 inline MoFEMErrorCode invertTensor2by2(T1 &t, T2 &det, T3 &inv_t) {
1651  const auto inv_det = 1. / det;
1652  inv_t(0, 0) = t(1, 1) * inv_det;
1653  inv_t(0, 1) = -t(0, 1) * inv_det;
1654  inv_t(1, 0) = -t(1, 0) * inv_det;
1655  inv_t(1, 1) = t(0, 0) * inv_det;
1657 }
1658 
1659 #ifdef WITH_ADOL_C
1660 
1661 /**
1662  * \brief Calculate matrix inverse, specialization for adouble tensor
1663 
1664  */
1665 template <>
1666 inline MoFEMErrorCode invertTensor3by3<FTensor::Tensor2<adouble, 3, 3>, adouble,
1671  inv_t(0, 0) = (t(1, 1) * t(2, 2) - t(1, 2) * t(2, 1)) / det;
1672  inv_t(0, 1) = (t(0, 2) * t(2, 1) - t(0, 1) * t(2, 2)) / det;
1673  inv_t(0, 2) = (t(0, 1) * t(1, 2) - t(0, 2) * t(1, 1)) / det;
1674  inv_t(1, 0) = (t(1, 2) * t(2, 0) - t(1, 0) * t(2, 2)) / det;
1675  inv_t(1, 1) = (t(0, 0) * t(2, 2) - t(0, 2) * t(2, 0)) / det;
1676  inv_t(1, 2) = (t(0, 2) * t(1, 0) - t(0, 0) * t(1, 2)) / det;
1677  inv_t(2, 0) = (t(1, 0) * t(2, 1) - t(1, 1) * t(2, 0)) / det;
1678  inv_t(2, 1) = (t(0, 1) * t(2, 0) - t(0, 0) * t(2, 1)) / det;
1679  inv_t(2, 2) = (t(0, 0) * t(1, 1) - t(0, 1) * t(1, 0)) / det;
1681 }
1682 
1683 #endif
1684 
1685 /**
1686  * \brief Calculate matrix inverse, specialization for symmetric tensor
1687 
1688  */
1689 template <>
1690 inline MoFEMErrorCode
1691 invertTensor3by3<FTensor::Tensor2_symmetric<double, 3>, double,
1696  const auto inv_det = 1. / det;
1697  inv_t(0, 0) = (t(1, 1) * t(2, 2) - t(1, 2) * t(2, 1)) * inv_det;
1698  inv_t(0, 1) = (t(0, 2) * t(2, 1) - t(0, 1) * t(2, 2)) * inv_det;
1699  inv_t(0, 2) = (t(0, 1) * t(1, 2) - t(0, 2) * t(1, 1)) * inv_det;
1700  inv_t(1, 1) = (t(0, 0) * t(2, 2) - t(0, 2) * t(2, 0)) * inv_det;
1701  inv_t(1, 2) = (t(0, 2) * t(1, 0) - t(0, 0) * t(1, 2)) * inv_det;
1702  inv_t(2, 2) = (t(0, 0) * t(1, 1) - t(0, 1) * t(1, 0)) * inv_det;
1704 }
1705 
1706 #ifdef WITH_ADOL_C
1707 
1708 /**
1709  * \brief Calculate matrix inverse, specialization for adouble symmetric tensor
1710 
1711  */
1712 template <>
1713 inline MoFEMErrorCode
1714 invertTensor3by3<FTensor::Tensor2_symmetric<adouble, 3>, adouble,
1719  inv_t(0, 0) = (t(1, 1) * t(2, 2) - t(1, 2) * t(2, 1)) / det;
1720  inv_t(0, 1) = (t(0, 2) * t(2, 1) - t(0, 1) * t(2, 2)) / det;
1721  inv_t(0, 2) = (t(0, 1) * t(1, 2) - t(0, 2) * t(1, 1)) / det;
1722  inv_t(1, 1) = (t(0, 0) * t(2, 2) - t(0, 2) * t(2, 0)) / det;
1723  inv_t(1, 2) = (t(0, 2) * t(1, 0) - t(0, 0) * t(1, 2)) / det;
1724  inv_t(2, 2) = (t(0, 0) * t(1, 1) - t(0, 1) * t(1, 0)) / det;
1726 }
1727 
1728 #endif
1729 
1730 /**
1731  * \brief Calculate matrix inverse, specialization for symmetric (pointer)
1732  tensor
1733 
1734  */
1735 template <>
1736 inline MoFEMErrorCode
1737 invertTensor3by3<FTensor::Tensor2_symmetric<double, 3>, double,
1742  const auto inv_det = 1. / det;
1743  inv_t(0, 0) = (t(1, 1) * t(2, 2) - t(1, 2) * t(2, 1)) * inv_det;
1744  inv_t(0, 1) = (t(0, 2) * t(2, 1) - t(0, 1) * t(2, 2)) * inv_det;
1745  inv_t(0, 2) = (t(0, 1) * t(1, 2) - t(0, 2) * t(1, 1)) * inv_det;
1746  inv_t(1, 1) = (t(0, 0) * t(2, 2) - t(0, 2) * t(2, 0)) * inv_det;
1747  inv_t(1, 2) = (t(0, 2) * t(1, 0) - t(0, 0) * t(1, 2)) * inv_det;
1748  inv_t(2, 2) = (t(0, 0) * t(1, 1) - t(0, 1) * t(1, 0)) * inv_det;
1750 }
1751 
1752 template <typename T1, typename T2, typename T3, int DIM>
1754 
1755 template <typename T1, typename T2, typename T3>
1756 struct InvertTensorImpl<T1, T2, T3, 3> {
1757  inline static MoFEMErrorCode invert(T1 &t, T2 &det, T3 &inv_t) {
1758  return invertTensor3by3(t, det, inv_t);
1759  }
1760 };
1761 
1762 template <typename T1, typename T2, typename T3>
1763 struct InvertTensorImpl<T1, T2, T3, 2> {
1764  inline static MoFEMErrorCode invert(T1 &t, T2 &det, T3 &inv_t) {
1765  return invertTensor2by2(t, det, inv_t);
1766  }
1767 };
1768 
1769 template <typename T1, typename T2, typename T3, int DIM>
1770 static inline MoFEMErrorCode
1774  FTensor::Tensor2<T3, DIM, DIM>, DIM>::invert(t, det,
1775  inv_t);
1776 }
1777 
1778 template <typename T1, typename T2, typename T3, int DIM>
1779 static inline MoFEMErrorCode
1784  DIM>::invert(t, det, inv_t);
1785 }
1786 
1787 /**
1788  * @brief Extract entity handle form multi-index container
1789  *
1790  */
1792  template <typename Iterator>
1793  static inline EntityHandle extract(const Iterator &it) {
1794  return (*it)->getEnt();
1795  }
1796 };
1797 
1798 /**
1799  * @brief Insert ordered mofem multi-index into range
1800  *
1801  * \note Inserted range has to be ordered.
1802  *
1803  * \code
1804  * auto hi_rit = refEntsPtr->upper_bound(start);
1805  * auto hi_rit = refEntsPtr->upper_bound(end);
1806  * Range to_erase;
1807  * insertOrdered(to_erase, RefEntExtractor(), rit, hi_rit);
1808  * \endcode
1809  *
1810  * @tparam Iterator
1811  * @param r
1812  * @param begin_iter
1813  * @param end_iter
1814  * @return moab::Range::iterator
1815  */
1816 template <typename Extractor, typename Iterator>
1817 moab::Range::iterator insertOrdered(Range &r, Extractor, Iterator begin_iter,
1818  Iterator end_iter) {
1819  moab::Range::iterator hint = r.begin();
1820  while (begin_iter != end_iter) {
1821  size_t j = 0;
1822  auto bi = Extractor::extract(begin_iter);
1823  Iterator pj = begin_iter;
1824  while (pj != end_iter && (bi + j) == Extractor::extract(pj)) {
1825  ++pj;
1826  ++j;
1827  }
1828  hint = r.insert(hint, bi, bi + (j - 1));
1829  begin_iter = pj;
1830  }
1831  return hint;
1832 };
1833 
1834 /**
1835  * @brief Do nothing, used to rebuild database
1836  *
1837  */
1839  Modify_change_nothing() = default;
1840  template <typename T> inline void operator()(T &e) {}
1841 };
1842 
1843 /**
1844  * @brief Template used to reconstruct multi-index
1845  *
1846  * @tparam MI multi-index
1847  * @tparam Modifier
1848  * @param mi
1849  * @param mo
1850  * @return MoFEMErrorCode
1851  */
1852 template <typename MI, typename MO = Modify_change_nothing>
1854  MO &&mo = Modify_change_nothing()) {
1856  for (auto it = mi.begin(); it != mi.end(); ++it) {
1857  if (!const_cast<MI &>(mi).modify(it, mo))
1858  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1859  "Houston we have a problem");
1860  }
1862 }
1863 
1864 struct TempMeshset {
1866  rval = moab.create_meshset(MESHSET_SET, meshset);
1867  MOAB_THROW(rval);
1868  }
1869  virtual ~TempMeshset() { delete_meshset(); }
1870  operator EntityHandle() const { return meshset; }
1871  auto get_ptr() { return &meshset; }
1872 
1873 private:
1875  rval = moab.delete_entities(&meshset, 1);
1876  MOAB_THROW(rval);
1877  }
1880 };
1881 
1882 /**
1883  * @brief Create smart pointer to temporary meshset
1884  *
1885  */
1887  return boost::make_shared<TempMeshset>(moab);
1888 };
1889 
1890 inline auto id_from_handle(const EntityHandle h) {
1891  return static_cast<EntityID>(h & MB_ID_MASK);
1892 };
1893 
1894 /**
1895  * @brief get type from entity handle
1896  *
1897  */
1898 inline auto type_from_handle(const EntityHandle h) {
1899  return static_cast<EntityType>(h >> MB_ID_WIDTH);
1900 };
1901 
1902 /**
1903  * @brief get entity handle from type and id
1904  *
1905  */
1906 inline auto ent_form_type_and_id(const EntityType type, const EntityID id) {
1907  return (static_cast<EntityHandle>(type) << MB_ID_WIDTH) | id;
1908 };
1909 
1910 /**
1911  * @brief get entity dimension form handle
1912  *
1913  */
1915  return moab::CN::Dimension(type_from_handle(h));
1916 };
1917 
1918 /**
1919  * @brief get entity type name from handle
1920  *
1921  */
1923  return moab::CN::EntityTypeName(type_from_handle(h));
1924 };
1925 
1926 /**
1927  * @brief get field bit id from bit number
1928  *
1929  */
1930 inline auto field_bit_from_bit_number(const int bit_number) {
1931  return BitFieldId().set(bit_number - 1);
1932 };
1933 
1934 /**
1935  * @brief Insert ranges
1936  *
1937  * @tparam I
1938  * @param f
1939  * @param s
1940  * @param tester
1941  * @param inserter
1942  * @return auto
1943  */
1944 template <typename I>
1945 auto rangeInserter(const I f, const I s, boost::function<bool(I it)> tester,
1946  boost::function<MoFEMErrorCode(I f, I s)> inserter) {
1948 
1949  auto first = f;
1950  while (first != s)
1951  if (tester(first)) {
1952 
1953  auto second = first;
1954  ++second;
1955 
1956  while (second != s) {
1957  if (tester(second))
1958  ++second;
1959  else
1960  break;
1961  }
1962 
1963  CHKERR inserter(first, second);
1964 
1965  first = second;
1966  if (first != s)
1967  ++first;
1968 
1969  } else {
1970  ++first;
1971  }
1972 
1974 }
1975 
1976 /**
1977  * @brief Create Array
1978  *
1979  * See:
1980  * <a
1981  * href="https://stackoverflow.com/questions/50942556/current-status-of-stdmake-array">See
1982  * stack overflow</a>
1983  *
1984  * @tparam Dest
1985  * @tparam Arg
1986  * @param arg
1987  * @return constexpr auto
1988  */
1989 template <typename Dest = void, typename... Arg>
1990 constexpr auto make_array(Arg &&...arg) {
1991  if constexpr (std::is_same<void, Dest>::value)
1992  return std::array<std::common_type_t<std::decay_t<Arg>...>, sizeof...(Arg)>{
1993  {std::forward<Arg>(arg)...}};
1994  else
1995  return std::array<Dest, sizeof...(Arg)>{{std::forward<Arg>(arg)...}};
1996 }
1997 
1998 template <int DIM> using i_FTIndex = FTensor::Index<'i', DIM>;
1999 template <int DIM> using j_FTIndex = FTensor::Index<'j', DIM>;
2000 template <int DIM> using k_FTIndex = FTensor::Index<'k', DIM>;
2001 template <int DIM> using l_FTIndex = FTensor::Index<'l', DIM>;
2002 template <int DIM> using m_FTIndex = FTensor::Index<'m', DIM>;
2003 template <int DIM> using n_FTIndex = FTensor::Index<'n', DIM>;
2004 template <int DIM> using I_FTIndex = FTensor::Index<'I', DIM>;
2005 template <int DIM> using J_FTIndex = FTensor::Index<'J', DIM>;
2006 template <int DIM> using K_FTIndex = FTensor::Index<'K', DIM>;
2007 template <int DIM> using L_FTIndex = FTensor::Index<'L', DIM>;
2008 template <int DIM> using M_FTIndex = FTensor::Index<'M', DIM>;
2009 template <int DIM> using N_FTIndex = FTensor::Index<'N', DIM>;
2010 
2011 #define FTENSOR_INDEX(DIM, I) I##_FTIndex<DIM> I;
2012 
2013 } // namespace MoFEM
2014 
2015 #endif //__TEMPLATES_HPP__
MoFEMFunctionReturnHot
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:460
MoFEM::GetFTensor2FromPtr< 3, 2, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:860
MoFEM::GetFTensor2FromMatImpl
Definition: Templates.hpp:252
MoFEM::id_from_handle
auto id_from_handle(const EntityHandle h)
Definition: Templates.hpp:1890
MoFEM::dimension_from_handle
auto dimension_from_handle(const EntityHandle h)
get entity dimension form handle
Definition: Templates.hpp:1914
MoFEM::KeyFromKey::operator()
result_type operator()(Arg &arg) const
Definition: Templates.hpp:79
MoFEM::getFTensor1FromPtr
FTensor::Tensor1< FTensor::PackPtr< double *, S >, DIM > getFTensor1FromPtr(double *ptr)
Make Tensor1 from pointer.
Definition: Templates.hpp:838
MoFEM::TempMeshset::~TempMeshset
virtual ~TempMeshset()
Definition: Templates.hpp:1869
MoFEM::GetFTensor3FromMatImpl< 2, 2, 2, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:654
MoFEM::GetFTensor1FromArray< 4, S >::get
static auto get(V &data)
Definition: Templates.hpp:1140
MoFEM::GetFTensor2FromPtr< 1, 1, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:912
MoFEM::LtBit::operator()
bool operator()(const id_type &valueA, const id_type &valueB) const
Definition: Templates.hpp:89
MoFEM::GetFTensor1FromArray< 9, S >::get
static auto get(V &data)
Definition: Templates.hpp:1158
MoFEM::GetFTensor2FromArrayRawPtrImpl< 3, 3, T, L, A >::get
static auto get(ublas::matrix< T, L, A > &data, const size_t rr, const size_t cc, const int ss=0)
Definition: Templates.hpp:1308
MoFEM::GetFTensor3DgFromMatImpl< 2, 2, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:470
MoFEM::GetFTensor1FromMatImpl< 9, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:190
MoFEM::field_bit_from_bit_number
auto field_bit_from_bit_number(const int bit_number)
get field bit id from bit number
Definition: Templates.hpp:1930
MoFEM::Types::VectorDouble3
VectorBoundedArray< double, 3 > VectorDouble3
Definition: Types.hpp:92
FTensor::Tensor1
Definition: Tensor1_value.hpp:8
MoFEM::GetFTensor4DdgFromMatImpl
Definition: Templates.hpp:345
EntityHandle
HVEC0_2
@ HVEC0_2
Definition: definitions.h:211
MoFEM::getFTensor2HVecFromPtr
FTensor::Tensor2< FTensor::PackPtr< double *, DIM1 *DIM2 >, DIM1, DIM2 > getFTensor2HVecFromPtr(double *ptr)
Make Tensor2 for HVec base from pointer.
Definition: Templates.hpp:950
lapack_dgetri
static __CLPK_integer lapack_dgetri(__CLPK_integer n, __CLPK_doublereal *a, __CLPK_integer lda, __CLPK_integer *ipiv, __CLPK_doublereal *work, __CLPK_integer lwork)
Definition: lapack_wrap.h:185
MoFEM::Types::MatrixShallowArrayAdaptor
ublas::matrix< double, ublas::row_major, ublas::shallow_array_adaptor< double > > MatrixShallowArrayAdaptor
Definition: Types.hpp:121
FTensor::row_major
@ row_major
Definition: Layout.hpp:13
MoFEM::GetFTensor3FromMatImpl< 3, 3, 3, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:706
MoFEM::getFTensor2SymmetricFromMat
static auto getFTensor2SymmetricFromMat(ublas::matrix< T, L, A > &data)
Get symmetric tensor rank 2 (matrix) form data matrix.
Definition: Templates.hpp:334
MoFEM::GetFTensor3DgFromMatImpl
Definition: Templates.hpp:452
MoFEM::GetFTensor1FromMatImpl< 4, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:159
lapack_dgesv
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)
Definition: lapack_wrap.h:176
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEM::Types::MatrixDouble
UBlasMatrix< double > MatrixDouble
Definition: Types.hpp:77
HVEC0_1
@ HVEC0_1
Definition: definitions.h:208
MoFEM::EqBit::operator()
bool operator()(const id_type &valueA, const id_type &valueB) const
Definition: Templates.hpp:95
MoFEM::Types::BitFieldId
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
Definition: Types.hpp:42
MoFEM::GetFTensor2FromPtr< 6, 6, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:868
MoFEM::getFTensor2FromArray
FTensor::Tensor2< FTensor::PackPtr< double *, S >, DIM1, DIM2 > getFTensor2FromArray(MatrixDouble &data, const size_t rr, const size_t cc=0)
Definition: Templates.hpp:1320
MoFEM::GetFTensor1FromArray< 3, S >::get
static auto get(V &data)
Definition: Templates.hpp:1131
A
constexpr AssemblyType A
Definition: operators_tests.cpp:30
MoFEM::TempMeshset::meshset
EntityHandle meshset
Definition: Templates.hpp:1878
MoFEM::GetFTensor4DdgFromMatImpl< 3, 3, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:380
MOAB_THROW
#define MOAB_THROW(err)
Check error code of MoAB function and throw MoFEM exception.
Definition: definitions.h:554
MoFEM::solveLinearSystem
MoFEMErrorCode solveLinearSystem(MatrixDouble &mat, VectorDouble &f)
solve linear system with lapack dgesv
Definition: Templates.hpp:1401
MoFEM::Modify_change_nothing
Do nothing, used to rebuild database.
Definition: Templates.hpp:1838
MoFEM::GetFTensor2FromPtr< 2, 2, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:889
FTensor::Tensor2_symmetric
Definition: Tensor2_symmetric_value.hpp:13
MoFEM::getFTensor1FromMat
FTensor::Tensor1< FTensor::PackPtr< T *, S >, Tensor_Dim > getFTensor1FromMat(ublas::matrix< T, L, A > &data)
Get tensor rank 1 (vector) form data matrix.
Definition: Templates.hpp:238
MoFEM::Modify_change_nothing::Modify_change_nothing
Modify_change_nothing()=default
HVEC0_0
@ HVEC0_0
Definition: definitions.h:205
MoFEM::getFTensor2SymmetricLowerFromPtr< 3 >
FTensor::Tensor2_symmetric< FTensor::PackPtr< double *, 9 >, 3 > getFTensor2SymmetricLowerFromPtr< 3 >(double *ptr)
Definition: Templates.hpp:1095
HVEC1_1
@ HVEC1_1
Definition: definitions.h:209
MoFEM::getFTensor2SymmetricFromPtr< 3 >
FTensor::Tensor2_symmetric< FTensor::PackPtr< double *, 6 >, 3 > getFTensor2SymmetricFromPtr< 3 >(double *ptr)
Definition: Templates.hpp:1027
THROW_MESSAGE
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
Definition: definitions.h:574
MoFEM::TempMeshset::get_ptr
auto get_ptr()
Definition: Templates.hpp:1871
HVEC1
@ HVEC1
Definition: definitions.h:199
sdf.r
int r
Definition: sdf.py:8
FTensor::Tensor2
Definition: Tensor2_value.hpp:16
MoFEM::GetFTensor2FromPtr< 1, 2, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:905
MoFEM::reconstructMultiIndex
MoFEMErrorCode reconstructMultiIndex(const MI &mi, MO &&mo=Modify_change_nothing())
Template used to reconstruct multi-index.
Definition: Templates.hpp:1853
MoFEM::getFTensor2FromPtr
auto getFTensor2FromPtr(double *ptr)
Make Tensor2 from pointer.
Definition: Templates.hpp:925
MoFEM::GetFTensor1FromPtrImpl< 1, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:792
I
constexpr IntegrationType I
Definition: operators_tests.cpp:31
MoFEM::invertTensor3by3
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.
Definition: Templates.hpp:1588
MoFEM::Interface
DeprecatedCoreInterface Interface
Definition: Interface.hpp:2010
MoFEM::GetFTensor2FromMatImpl::get
static auto get(ublas::matrix< T, L, A > &data)
Definition: Templates.hpp:253
MoFEM::DeterminantTensorImpl< T, 3 >::get
static auto get(T &t)
Definition: Templates.hpp:1560
FTensor::Tensor1::data
T data[Tensor_Dim]
Definition: Tensor1_value.hpp:10
MoFEM::ShardVec
boost::shared_ptr< std::vector< T > > ShardVec
Definition: Templates.hpp:10
MoFEM::determinantTensor2by2
static auto determinantTensor2by2(T &t)
Calculate the determinant of a 2x2 matrix or a tensor of rank 2.
Definition: Templates.hpp:1553
MoFEM::GetFTensor2FromArrayRawPtrImpl< 2, 2, T, L, A >::get
static auto get(ublas::matrix< T, L, A > &data, const size_t rr, const size_t cc, const int ss=0)
Definition: Templates.hpp:1296
HVEC2_1
@ HVEC2_1
Definition: definitions.h:210
MoFEM::Exceptions::rval
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
Definition: Exceptions.hpp:74
PlasticOps::M
FTensor::Index< 'M', 3 > M
Definition: PlasticOps.hpp:117
MoFEM::GetFTensor1FromMatImpl
Definition: Templates.hpp:140
MoFEM::Types::MatrixADouble
UBlasMatrix< adouble > MatrixADouble
Definition: Types.hpp:80
MoFEM::GetFTensor2FromArrayImpl< 3, 3, S, T, L, A >::get
static auto get(ublas::matrix< T, L, A > &data, const size_t rr, const size_t cc)
Definition: Templates.hpp:1284
MoFEM::GetFTensor3FromMatImpl< 3, 3, 6, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:743
MoFEM::GetFTensor2SymmetricFromMatImpl
Definition: Templates.hpp:297
FTensor::Number
Definition: Number.hpp:11
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:548
FTensor::Tensor3
Definition: Tensor3_value.hpp:12
MoFEM::invertTensor2by2
MoFEMErrorCode invertTensor2by2(T1 &t, T2 &det, T3 &inv_t)
Calculate matrix inverse 2 by 2.
Definition: Templates.hpp:1649
HVEC2_2
@ HVEC2_2
Definition: definitions.h:213
HVEC1_2
@ HVEC1_2
Definition: definitions.h:212
MoFEM::GetFTensor1FromArray< 6, S >::get
static auto get(V &data)
Definition: Templates.hpp:1149
MoFEM
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
MoFEM::GetFTensor4DdgFromPtrImpl< 3, 3, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:434
MoFEM::GetFTensor1FromPtrImpl< 3, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:807
MoFEM::Modify_change_nothing::operator()
void operator()(T &e)
Definition: Templates.hpp:1840
MoFEM::GetFTensor0FromVecImpl
Definition: Templates.hpp:112
MoFEM::getFTensor3FromMat
static FTensor::Tensor3< FTensor::PackPtr< T *, 1 >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 > getFTensor3FromMat(ublas::matrix< T, L, A > &data)
Get tensor rank 3 (non symmetries) form data matrix.
Definition: Templates.hpp:776
MoFEM::getVectorAdaptor
auto getVectorAdaptor(T1 ptr, const size_t n)
Get Vector adaptor.
Definition: Templates.hpp:31
MoFEM::getFTensor2HVecFromPtr< 3, 3 >
FTensor::Tensor2< FTensor::PackPtr< double *, 9 >, 3, 3 > getFTensor2HVecFromPtr< 3, 3 >(double *ptr)
Definition: Templates.hpp:968
MoFEM::insertOrdered
moab::Range::iterator insertOrdered(Range &r, Extractor, Iterator begin_iter, Iterator end_iter)
Insert ordered mofem multi-index into range.
Definition: Templates.hpp:1817
MoFEM::getFTensor1FromArray< 3, 0 >
auto getFTensor1FromArray< 3, 0 >(VectorDouble3 &data)
Definition: Templates.hpp:1183
MoFEM::KeyFromKey
Definition: Templates.hpp:71
MoFEM::get_temp_meshset_ptr
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
Definition: Templates.hpp:1886
MoFEM::KeyFromKey::key2
KeyExtractor2 key2
Definition: Templates.hpp:85
DIM1
constexpr int DIM1
Definition: level_set.cpp:21
double
MoFEM::GetFTensor3FromMatImpl
Definition: Templates.hpp:635
MoFEM::GetFTensor3DgFromMatImpl< 3, 3, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:487
convert.type
type
Definition: convert.py:64
MoFEM::GetFTensor4FromMatImpl< 3, 3, 3, 3, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:571
MoFEM::HashBit::operator()
unsigned int operator()(const id_type &value) const
Definition: Templates.hpp:101
MoFEM::KeyFromKey::key1
KeyExtractor1 key1
Definition: Templates.hpp:84
MoFEM::TempMeshset::moab
moab::Interface & moab
Definition: Templates.hpp:1879
MoFEM::DeterminantTensorImpl< T, 2 >::get
static auto get(T &t)
Definition: Templates.hpp:1564
MoFEM::GetFTensor1FromMatImpl< 1, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:221
MoFEM::getFTensor0FromVec
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
Definition: Templates.hpp:135
MoFEM::getFTensor1FromArray
auto getFTensor1FromArray(VectorDouble &data)
Get FTensor1 from array.
Definition: Templates.hpp:1175
MoFEM::getFTensor2SymmetricFromPtr< 2 >
FTensor::Tensor2_symmetric< FTensor::PackPtr< double *, 3 >, 2 > getFTensor2SymmetricFromPtr< 2 >(double *ptr)
Definition: Templates.hpp:1038
MoFEM::getFTensor2FromArray2by2
auto getFTensor2FromArray2by2(ublas::matrix< T, L, A > &data, const FTensor::Number< S > &, const size_t rr, const size_t cc=0)
Definition: Templates.hpp:1335
MoFEM::invertTensor
static MoFEMErrorCode invertTensor(FTensor::Tensor2< T1, DIM, DIM > &t, T2 &det, FTensor::Tensor2< T3, DIM, DIM > &inv_t)
Definition: Templates.hpp:1771
h
double h
Definition: photon_diffusion.cpp:60
MoFEM::GetFTensor3FromMatImpl< 1, 1, 1, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:639
MoFEM::getFTensor2FromVec
FTensor::Tensor2< FTensor::PackPtr< double *, 1 >, Tensor_Dim1, Tensor_Dim2 > getFTensor2FromVec(VectorDouble &data)
Definition: Templates.hpp:292
MoFEM::determinantTensor
static auto determinantTensor(FTensor::Tensor2< T, DIM, DIM > &t)
Calculate the determinant of a tensor of rank DIM.
Definition: Templates.hpp:1571
MoFEM::GetFTensor1FromPtrImpl
Definition: Templates.hpp:788
MoFEM::KeyFromKey::result_type
KeyExtractor1::result_type result_type
Definition: Templates.hpp:73
MoFEM::getMatrixAdaptor
auto getMatrixAdaptor(T1 ptr, const size_t n, const size_t m)
Get Matrix adaptor.
Definition: Templates.hpp:57
MoFEM::getFTensor1FromArrayDiag
FTensor::Tensor1< FTensor::PackPtr< double *, S >, DIM > getFTensor1FromArrayDiag(MatrixDouble &data, const size_t rr)
Get FTensor1 from array.
Definition: Templates.hpp:1233
MoFEM::GetFTensor3FromMatImpl< 3, 2, 2, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:672
MoFEM::getFTensor2SymmetricFromPtr
FTensor::Tensor2_symmetric< FTensor::PackPtr< double *,(DIM *(DIM+1))/2 >, DIM > getFTensor2SymmetricFromPtr(double *ptr)
Make symmetric Tensor2 from pointer.
Definition: Templates.hpp:1021
lapack_dgetrf
static __CLPK_integer lapack_dgetrf(__CLPK_integer m, __CLPK_integer n, __CLPK_doublereal *a, __CLPK_integer lda, __CLPK_integer *ipiv)
Definition: lapack_wrap.h:157
FTensor::PackPtr
Definition: FTensor.hpp:54
MoFEM::type_name_from_handle
auto type_name_from_handle(const EntityHandle h)
get entity type name from handle
Definition: Templates.hpp:1922
MoFEM::RefEntExtractor
Extract entity handle form multi-index container.
Definition: Templates.hpp:1791
MoFEM::L
VectorDouble L
Definition: Projection10NodeCoordsOnField.cpp:124
MoFEM::getFTensor3FromPtr< 3, 2, 2 >
FTensor::Tensor3< FTensor::PackPtr< double *, 12 >, 3, 2, 2 > getFTensor3FromPtr< 3, 2, 2 >(double *ptr)
Definition: Templates.hpp:995
MoFEM::GetFTensor2FromPtr< 1, 3, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:897
MoFEM::GetFTensor4DdgFromMatImpl< 1, 1, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:349
MOFEM_OPERATION_UNSUCCESSFUL
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition: definitions.h:34
MoFEM::type_from_handle
auto type_from_handle(const EntityHandle h)
get type from entity handle
Definition: Templates.hpp:1898
MB_ID_WIDTH
#define MB_ID_WIDTH
Definition: definitions.h:240
MoFEM::GetFTensor4DdgFromPtrImpl
Definition: Templates.hpp:431
FTensor::Tensor4
Definition: Tensor4_value.hpp:18
MoFEM::GetFTensor0FromVecImpl::get
static auto get(ublas::vector< T, A > &data)
Definition: Templates.hpp:113
t
constexpr double t
plate stiffness
Definition: plate.cpp:58
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
MoFEM::DeterminantTensorImpl
Definition: Templates.hpp:1557
MoFEM::Types::DoubleAllocator
VecAllocator< double > DoubleAllocator
Definition: Types.hpp:62
FTensor::Index< 'i', DIM >
MoFEM::Types::VecAllocator
std::vector< T, std::allocator< T > > VecAllocator
Definition: Types.hpp:59
MoFEM::GetFTensor1FromArray< 2, S >::get
static auto get(V &data)
Definition: Templates.hpp:1123
MoFEM::HashBit
Definition: Templates.hpp:100
convert.n
n
Definition: convert.py:82
MoFEM::InvertTensorImpl< T1, T2, T3, 3 >::invert
static MoFEMErrorCode invert(T1 &t, T2 &det, T3 &inv_t)
Definition: Templates.hpp:1757
MoFEM::GetFTensor2SymmetricFromMatImpl< 2, S, T, L, A >::get
static auto get(ublas::matrix< T, L, A > &data)
Definition: Templates.hpp:317
MoFEM::getFTensor3FromPtr
FTensor::Tensor3< FTensor::PackPtr< double *, DIM1 *DIM2 *DIM3 >, DIM1, DIM2, DIM3 > getFTensor3FromPtr(double *ptr)
Definition: Templates.hpp:988
N
const int N
Definition: speed_test.cpp:3
MoFEM::getFTensor2FromArray3by3
auto getFTensor2FromArray3by3(ublas::matrix< T, L, A > &data, const FTensor::Number< S > &, const size_t rr, const size_t cc=0)
Definition: Templates.hpp:1342
MoFEM::InvertTensorImpl< T1, T2, T3, 2 >::invert
static MoFEMErrorCode invert(T1 &t, T2 &det, T3 &inv_t)
Definition: Templates.hpp:1764
MoFEM::determinantTensor3by3
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
Definition: Templates.hpp:1540
Range
MoFEM::GetFTensor3DgFromMatImpl< 1, 1, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:456
adouble
MoFEM::GetFTensor3FromMatImpl< 2, 2, 3, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:689
MoFEM::GetFTensor4FromMatImpl
Definition: Templates.hpp:533
FTensor::Dg
Definition: Dg_value.hpp:9
FTensor::Tensor0
Definition: Tensor0.hpp:16
MoFEM::GetFTensor3FromMatImpl< 6, 3, 3, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:726
MoFEM::InvertTensorImpl
Definition: Templates.hpp:1753
MoFEM::toString
std::string toString(X x)
Definition: Templates.hpp:106
HenckyOps::f
auto f
Definition: HenckyOps.hpp:15
MoFEM::getFTensor2SymmetricLowerFromPtr
FTensor::Tensor2_symmetric< FTensor::PackPtr< double *, DIM *DIM >, DIM > getFTensor2SymmetricLowerFromPtr(double *ptr)
Make symmetric Tensor2 from pointer, taking lower triangle of matrix.
Definition: Templates.hpp:1088
MoFEM::rangeInserter
auto rangeInserter(const I f, const I s, boost::function< bool(I it)> tester, boost::function< MoFEMErrorCode(I f, I s)> inserter)
Insert ranges.
Definition: Templates.hpp:1945
MoFEM::GetFTensor2FromPtr
Definition: Templates.hpp:856
MoFEM::GetFTensor1FromPtrImpl< 2, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:799
MoFEM::getFTensor2HVecFromPtr< 3, 2 >
FTensor::Tensor2< FTensor::PackPtr< double *, 6 >, 3, 2 > getFTensor2HVecFromPtr< 3, 2 >(double *ptr)
Definition: Templates.hpp:957
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
MoFEM::GetFTensor2FromArrayImpl
Get FTensor2 from array.
Definition: Templates.hpp:1264
FTensor::Ddg
Definition: Ddg_value.hpp:7
lapack_dsyev
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)
Definition: lapack_wrap.h:261
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
MoFEM::GetFTensor1FromPtrImpl< 6, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:823
MoFEM::GetFTensor4DdgFromMatImpl< 2, 2, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:363
MoFEM::computeMatrixInverse
MoFEMErrorCode computeMatrixInverse(MatrixDouble &mat)
compute matrix inverse with lapack dgetri
Definition: Templates.hpp:1365
MoFEM::TempMeshset::delete_meshset
void delete_meshset()
Definition: Templates.hpp:1874
MoFEM::GetFTensor2FromArrayRawPtrImpl
Definition: Templates.hpp:1267
DIM2
constexpr int DIM2
Definition: level_set.cpp:22
HVEC2_0
@ HVEC2_0
Definition: definitions.h:207
MoFEM::getFTensor4DdgFromMat
static FTensor::Ddg< FTensor::PackPtr< T *, 1 >, Tensor_Dim01, Tensor_Dim23 > getFTensor4DdgFromMat(ublas::matrix< T, L, A > &data)
Get symmetric tensor rank 4 on first two and last indices from form data matrix.
Definition: Templates.hpp:418
MoFEM::Types::VectorDouble
UBlasVector< double > VectorDouble
Definition: Types.hpp:68
MoFEM::TempMeshset
Definition: Templates.hpp:1864
MoFEM::TempMeshset::TempMeshset
TempMeshset(moab::Interface &moab)
Definition: Templates.hpp:1865
m
FTensor::Index< 'm', 3 > m
Definition: shallow_wave.cpp:80
MoFEM::Types::VectorShallowArrayAdaptor
ublas::vector< T, ublas::shallow_array_adaptor< T > > VectorShallowArrayAdaptor
Definition: Types.hpp:114
MoFEM::GetFTensor1FromMatImpl< 6, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:174
MoFEM::make_array
constexpr auto make_array(Arg &&...arg)
Create Array.
Definition: Templates.hpp:1990
MoFEM::GetFTensor1FromPtrImpl< 4, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:815
MoFEM::getFTensor2FromMat
FTensor::Tensor2< FTensor::PackPtr< double *, 1 >, Tensor_Dim1, Tensor_Dim2 > getFTensor2FromMat(MatrixDouble &data)
Get tensor rank 2 (matrix) form data matrix.
Definition: Templates.hpp:278
MoFEMFunctionBeginHot
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:453
MoFEM::GetFTensor1FromMatImpl< 2, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:206
MoFEM::getFTensor2SymmetricLowerFromPtr< 2 >
FTensor::Tensor2_symmetric< FTensor::PackPtr< double *, 4 >, 2 > getFTensor2SymmetricLowerFromPtr< 2 >(double *ptr)
Definition: Templates.hpp:1106
MoFEM::LtBit
Definition: Templates.hpp:88
HVEC2
@ HVEC2
Definition: definitions.h:199
MoFEM::GetFTensor2FromPtr< 3, 3, S, T >::get
static auto get(T *ptr)
Definition: Templates.hpp:880
MoFEM::getFTensor3DgFromMat
static FTensor::Dg< FTensor::PackPtr< T *, 1 >, Tensor_Dim01, Tensor_Dim2 > getFTensor3DgFromMat(ublas::matrix< T, L, A > &data)
Get symmetric tensor rank 3 on the first two indices from form data matrix.
Definition: Templates.hpp:520
MoFEM::ent_form_type_and_id
auto ent_form_type_and_id(const EntityType type, const EntityID id)
get entity handle from type and id
Definition: Templates.hpp:1906
MB_ID_MASK
#define MB_ID_MASK
Definition: definitions.h:247
MoFEM::RefEntExtractor::extract
static EntityHandle extract(const Iterator &it)
Definition: Templates.hpp:1793
MoFEM::GetFTensor1FromArray
Definition: Templates.hpp:1111
MoFEM::GetFTensor1FromArray< 1, S >::get
static auto get(V &data)
Definition: Templates.hpp:1115
MoFEM::getFTensor4FromMat
static FTensor::Tensor4< FTensor::PackPtr< T *, 1 >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3 > getFTensor4FromMat(ublas::matrix< T, L, A > &data)
Get tensor rank 4 (non symmetric) form data matrix.
Definition: Templates.hpp:620
MoFEM::getFTensor4DdgFromPtr
static auto getFTensor4DdgFromPtr(T *ptr)
Definition: Templates.hpp:447
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:429
MOFEM_NOT_IMPLEMENTED
@ MOFEM_NOT_IMPLEMENTED
Definition: definitions.h:32
MoFEM::GetFTensor1FromMatImpl< 3, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:144
MoFEM::GetFTensor4FromMatImpl< 2, 2, 2, 2, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:552
MoFEM::GetFTensor4FromMatImpl< 1, 1, 1, 1, S, T, ublas::row_major, A >::get
static auto get(ublas::matrix< T, ublas::row_major, A > &data)
Definition: Templates.hpp:537
MoFEM::EqBit
Definition: Templates.hpp:94
MoFEM::getFTensor3FromPtr< 3, 3, 3 >
FTensor::Tensor3< FTensor::PackPtr< double *, 27 >, 3, 3, 3 > getFTensor3FromPtr< 3, 3, 3 >(double *ptr)
Definition: Templates.hpp:1003
MoFEM::KeyFromKey::KeyFromKey
KeyFromKey(const KeyExtractor1 &key1_=KeyExtractor1(), const KeyExtractor2 &key2_=KeyExtractor2())
Definition: Templates.hpp:75
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:359
MOFEM_INVALID_DATA
@ MOFEM_INVALID_DATA
Definition: definitions.h:36
MoFEM::computeEigenValuesSymmetric
MoFEMErrorCode computeEigenValuesSymmetric(const MatrixDouble &mat, VectorDouble &eig, MatrixDouble &eigen_vec)
compute eigenvalues of a symmetric matrix using lapack dsyev
Definition: Templates.hpp:1452
MoFEM::GetFTensor2FromArrayImpl< 2, 2, S, T, L, A >::get
static auto get(ublas::matrix< T, L, A > &data, const size_t rr, const size_t cc)
Definition: Templates.hpp:1272
MoFEM::GetFTensor2SymmetricFromMatImpl< 3, S, T, L, A >::get
static auto get(ublas::matrix< T, L, A > &data)
Definition: Templates.hpp:301
HVEC1_0
@ HVEC1_0
Definition: definitions.h:206
HVEC0
@ HVEC0
Definition: definitions.h:199