KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
data_type_traits.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main author: Suneth Warnakulasuriya
11 //
12 
13 #pragma once
14 
15 // System includes
16 #include <algorithm>
17 #include <string>
18 #include <type_traits>
19 #include <vector>
20 
21 // Project includes
22 #include "containers/array_1d.h"
24 
25 namespace Kratos {
26 
32 template<class TDataType> class DataTypeTraits
33 {
34 public:
37 
38  using ContainerType = TDataType;
39 
40  using ValueType = TDataType;
41 
42  using PrimitiveType = TDataType;
43 
44  static constexpr bool IsContiguous = true;
45 
46  static constexpr bool IsDynamic = false;
47 
48  static constexpr unsigned int Dimension = 0;
49 
53 
64  template<unsigned int TCheckIndex>
65  static constexpr bool IsDimensionDynamic()
66  {
67  return IsDimensionDynamicImpl<TCheckIndex, 0>();
68  }
69 
75  template<class TIndexType = unsigned int>
76  static inline TIndexType Size(const ContainerType&)
77  {
78  return 1;
79  }
80 
88  template<class TIndexType = unsigned int>
89  static inline std::vector<TIndexType> Shape(const ContainerType&)
90  {
91  return {};
92  }
93 
103  template<class TIndexType = unsigned int>
104  static inline void Shape(
105  const ContainerType&,
106  TIndexType* pShapeBegin,
107  TIndexType* pShapeEnd)
108  {
109  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) == 0)
110  << "Invalid dimensions given to fill for primitive data type [ Expected dimension == 0, provided shape = "
111  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
112  }
113 
125  template<class TIndexType = unsigned int>
126  static inline bool Reshape(
127  ContainerType& rValue,
128  const std::vector<TIndexType>& rShape)
129  {
130  return Reshape(rValue, rShape.data(), rShape.data() + rShape.size());
131  }
132 
144  template<class TIndexType = unsigned int>
145  static inline bool Reshape(
146  ContainerType&,
147  TIndexType const * pShapeBegin,
148  TIndexType const * pShapeEnd)
149  {
150  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) == 0)
151  << "Invalid shape/dimension given for primitive data type [ Expected shape = [], provided shape = "
152  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
153  return false;
154  }
155 
162  inline static PrimitiveType const * GetContiguousData(const ContainerType& rValue)
163  {
164  return &rValue;
165  }
166 
174  {
175  return &rValue;
176  }
177 
190  inline static void CopyToContiguousData(
191  PrimitiveType* pContiguousDataBegin,
192  const ContainerType& rValue)
193  {
194  *pContiguousDataBegin = rValue;
195  }
196 
208  inline static void CopyFromContiguousData(
209  ContainerType& rValue,
210  PrimitiveType const * pContiguousDataBegin)
211  {
212  rValue = *pContiguousDataBegin;
213  }
214 
216 
217 private:
220 
221  template<unsigned int TCheckIndex, unsigned int TCurrentIndex = 0>
222  static constexpr bool IsDimensionDynamicImpl()
223  {
224  if constexpr(TCheckIndex == 0) {
225  return false;
226  } else {
227  static_assert(TCheckIndex != TCheckIndex, "Invalid dimension index.");
228  }
229  }
230 
234 
235  template<class T>
236  friend class DataTypeTraits;
237 
239 };
240 
247 template<class TDataType, std::size_t TSize> class DataTypeTraits<array_1d<TDataType, TSize>>
248 {
249 public:
252 
254 
255  using ValueType = TDataType;
256 
258 
260 
261  static constexpr bool IsDynamic = ValueTraits::IsDynamic;
262 
263  // boost ublas makes the underlying data structure contiguous for
264  // any ValueType which are not dynamic recursively.
265  static constexpr bool IsContiguous = !IsDynamic;
266 
267  static constexpr unsigned int Dimension = ValueTraits::Dimension + 1;
268 
272 
283  template<unsigned int TCheckIndex>
284  static constexpr bool IsDimensionDynamic()
285  {
286  return IsDimensionDynamicImpl<TCheckIndex, 0>();
287  }
288 
298  template<class TIndexType = unsigned int>
299  static inline TIndexType Size(const ContainerType& rContainer)
300  {
301  if constexpr(TSize == 0) {
302  return 0;
303  } else {
304  return TSize * ValueTraits::template Size<TIndexType>(rContainer[0]);
305  }
306  }
307 
317  template<class TIndexType = unsigned int>
318  static inline std::vector<TIndexType> Shape(const ContainerType& rContainer)
319  {
320  std::vector<TIndexType> shape(Dimension);
321  Shape(rContainer, shape.data(), shape.data() + Dimension);
322  return shape;
323  }
324 
334  template<class TIndexType = unsigned int>
335  static inline void Shape(
336  const ContainerType& rContainer,
337  TIndexType* pShapeBegin,
338  TIndexType* pShapeEnd)
339  {
340  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) >= 1)
341  << "Invalid dimensions given to fill for primitive data type [ Expected dimension >= 1, provided shape = "
342  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
343 
344  if constexpr(TSize > 0) {
345  ValueTraits::Shape(rContainer[0], pShapeBegin + 1, pShapeEnd);
346  } else {
347  ValueTraits::Shape(ValueType{}, pShapeBegin + 1, pShapeEnd);
348  }
349  pShapeBegin[0] = TSize;
350  }
351 
368  template<class TIndexType = unsigned int>
369  static inline bool Reshape(
370  ContainerType& rContainer,
371  const std::vector<TIndexType>& rShape)
372  {
373  return Reshape(rContainer, rShape.data(), rShape.data() + rShape.size());
374  }
375 
393  template<class TIndexType = unsigned int>
394  static inline bool Reshape(
395  ContainerType& rContainer,
396  TIndexType const * pShapeBegin,
397  TIndexType const * pShapeEnd)
398  {
399  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) >= 1 && *pShapeBegin == static_cast<TIndexType>(TSize))
400  << "Invalid shape/dimension given for array_1d data type [ Expected shape = " << Shape(rContainer) << ", provided shape = "
401  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
402 
403  bool is_reshaped = false;
404 
405  if constexpr(ValueTraits::IsDynamic) {
406  std::for_each(rContainer.begin(), rContainer.end(), [&is_reshaped, pShapeBegin, pShapeEnd](auto& rValue) {
407  is_reshaped = ValueTraits::Reshape(rValue, pShapeBegin + 1, pShapeEnd) || is_reshaped;
408  });
409  }
410 
411  return is_reshaped;
412  }
413 
424  inline static PrimitiveType const * GetContiguousData(const ContainerType& rValue)
425  {
426  if constexpr(IsContiguous) {
427  if constexpr(std::is_same_v<PrimitiveType, ValueType>) {
428  return rValue.data().data();
429  } else {
430  // since the underlying data structure for recusive static data types
431  // is contiguous in ublas types, we can do the following to get the
432  // contiguous array.
433  if constexpr(TSize > 0) {
434  return reinterpret_cast<PrimitiveType const *>(&rValue[0]);
435  } else {
436  // not returning nullptr so, the return value can be subjected to
437  // arithmetic operations
438  return 0;
439  }
440  }
441  } else {
442  static_assert(!std::is_same_v<TDataType, TDataType>, "This should be only called if the rValue is contiguous only.");
443  }
444  }
445 
457  {
458  if constexpr(IsContiguous) {
459  if constexpr(std::is_same_v<PrimitiveType, ValueType>) {
460  return rValue.data().data();
461  } else {
462  // since the underlying data structure for recusive static data types
463  // is contiguous in ublas types, we can do the following to get the
464  // contiguous array.
465  if constexpr(TSize > 0) {
466  return reinterpret_cast<PrimitiveType*>(&rValue[0]);
467  } else {
468  // not returning nullptr so, the return value can be subjected to
469  // arithmetic operations
470  return 0;
471  }
472  }
473  } else {
474  static_assert(!std::is_same_v<TDataType, TDataType>, "This should be only called if the rValue is contiguous only.");
475  }
476  }
477 
490  inline static void CopyToContiguousData(
491  PrimitiveType* pContiguousDataBegin,
492  const ContainerType& rContainer)
493  {
494  const auto stride = ValueTraits::Size(rContainer[0]);
495  for (unsigned int i = 0; i < TSize; ++i) {
496  ValueTraits::CopyToContiguousData(pContiguousDataBegin + i * stride, rContainer[i]);
497  }
498  }
499 
512  inline static void CopyFromContiguousData(
513  ContainerType& rContainer,
514  PrimitiveType const * pContiguousDataBegin)
515  {
516  const auto stride = ValueTraits::Size(rContainer[0]);
517  for (unsigned int i = 0; i < TSize; ++i) {
518  ValueTraits::CopyFromContiguousData(rContainer[i], pContiguousDataBegin + i * stride);
519  }
520  }
521 
523 
524 private:
527 
528  template<unsigned int TCheckIndex, unsigned int TCurrentIndex>
529  static constexpr bool IsDimensionDynamicImpl()
530  {
531  if constexpr(TCheckIndex == TCurrentIndex) {
532  return false;
533  } else {
534  return ValueTraits::template IsDimensionDynamicImpl<TCheckIndex, TCurrentIndex + 1>();
535  }
536  }
537 
541 
542  template<class T>
543  friend class DataTypeTraits;
544 
546 };
547 
553 template<class TDataType> class DataTypeTraits<DenseVector<TDataType>>
554 {
555 public:
558 
560 
561  using ValueType = TDataType;
562 
564 
566 
567  static constexpr bool IsDynamic = true;
568 
569  // boost ublas makes the underlying data structure contiguous for
570  // any ValueType which are not dynamic recursively.
571  static constexpr bool IsContiguous = !ValueTraits::IsDynamic;
572 
573  static constexpr unsigned int Dimension = ValueTraits::Dimension + 1;
574 
578 
589  template<unsigned int TCheckIndex>
590  static constexpr bool IsDimensionDynamic()
591  {
592  return IsDimensionDynamicImpl<TCheckIndex, 0>();
593  }
594 
604  template<class TIndexType = unsigned int>
605  static inline TIndexType Size(const ContainerType& rValue)
606  {
607  return (rValue.empty() ? 0 : rValue.size() * ValueTraits::template Size<TIndexType>(rValue[0]));
608  }
609 
619  template<class TIndexType = unsigned int>
620  static inline std::vector<TIndexType> Shape(const ContainerType& rContainer)
621  {
622  std::vector<TIndexType> shape(Dimension);
623  Shape(rContainer, shape.data(), shape.data() + Dimension);
624  return shape;
625  }
626 
636  template<class TIndexType = unsigned int>
637  static inline void Shape(
638  const ContainerType& rContainer,
639  TIndexType* pShapeBegin,
640  TIndexType* pShapeEnd)
641  {
642  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) >= 1)
643  << "Invalid dimensions given to fill for primitive data type [ Expected dimension >= 1, provided shape = "
644  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
645 
646  if (rContainer.empty()) {
647  ValueTraits::Shape(ValueType{}, pShapeBegin + 1, pShapeEnd);
648  } else {
649  ValueTraits::Shape(rContainer[0], pShapeBegin + 1, pShapeEnd);
650  }
651  pShapeBegin[0] = rContainer.size();
652  }
653 
670  template<class TIndexType = unsigned int>
671  static inline bool Reshape(
672  ContainerType& rContainer,
673  const std::vector<TIndexType>& rShape)
674  {
675  return Reshape(rContainer, rShape.data(), rShape.data() + rShape.size());
676  }
677 
695  template<class TIndexType = unsigned int>
696  static inline bool Reshape(
697  ContainerType& rContainer,
698  TIndexType const * pShapeBegin,
699  TIndexType const * pShapeEnd)
700  {
701  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) >= 1)
702  << "Invalid shape/dimension given for DenseVector data type [ Expected = " << Shape(rContainer) << ", provided = "
703  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
704 
705  bool is_reshaped = false;
706 
707  if (rContainer.size() != *pShapeBegin) {
708  rContainer.resize(*pShapeBegin, false);
709  is_reshaped = true;
710  }
711 
712  if constexpr(ValueTraits::IsDynamic) {
713  std::for_each(rContainer.begin(), rContainer.end(), [&is_reshaped, pShapeBegin, pShapeEnd](auto& rValue) {
714  is_reshaped = ValueTraits::Reshape(rValue, pShapeBegin + 1, pShapeEnd) || is_reshaped;
715  });
716  }
717 
718  return is_reshaped;
719  }
720 
731  inline static PrimitiveType const * GetContiguousData(const ContainerType& rValue)
732  {
733  if constexpr(IsContiguous) {
734  if constexpr(std::is_same_v<PrimitiveType, ValueType>) {
735  return rValue.data().begin();
736  } else {
737  // since the underlying data structure for recusive static data types
738  // is contiguous in ublas types, we can do the following to get the
739  // contiguous array.
740  if (rValue.size() > 0) {
741  return reinterpret_cast<PrimitiveType const *>(&rValue[0]);
742  } else {
743  // not returning nullptr so, the return value can be subjected to
744  // arithmetic operations
745  return 0;
746  }
747  }
748  } else {
749  static_assert(!std::is_same_v<TDataType, TDataType>, "GetContiguousData should only be called if rValue is contiguous.");
750  }
751  }
752 
764  {
765  if constexpr(IsContiguous) {
766  if constexpr(std::is_same_v<PrimitiveType, ValueType>) {
767  return rValue.data().begin();
768  } else {
769  // since the underlying data structure for recusive static data types
770  // is contiguous in ublas types, we can do the following to get the
771  // contiguous array.
772  if (rValue.size() > 0) {
773  return reinterpret_cast<PrimitiveType*>(&rValue[0]);
774  } else {
775  // not returning nullptr so, the return value can be subjected to
776  // arithmetic operations
777  return 0;
778  }
779  }
780  } else {
781  static_assert(!std::is_same_v<TDataType, TDataType>, "GetContiguousData should only be called if rValue is contiguous.");
782  }
783  }
784 
797  inline static void CopyToContiguousData(
798  PrimitiveType* pContiguousDataBegin,
799  const ContainerType& rContainer)
800  {
801  if (rContainer.size() != 0) {
802  const auto stride = ValueTraits::Size(rContainer[0]);
803  for (unsigned int i = 0; i < rContainer.size(); ++i) {
804  ValueTraits::CopyToContiguousData(pContiguousDataBegin + i * stride, rContainer[i]);
805  }
806  }
807  }
808 
821  inline static void CopyFromContiguousData(
822  ContainerType& rContainer,
823  PrimitiveType const * pContiguousDataBegin)
824  {
825  if (rContainer.size() != 0) {
826  const auto stride = ValueTraits::Size(rContainer[0]);
827  for (unsigned int i = 0; i < rContainer.size(); ++i) {
828  ValueTraits::CopyFromContiguousData(rContainer[i], pContiguousDataBegin + i * stride);
829  }
830  }
831  }
832 
834 
835 private:
838 
839  template<unsigned int TCheckIndex, unsigned int TCurrentIndex>
840  static constexpr bool IsDimensionDynamicImpl()
841  {
842  if constexpr(TCheckIndex == TCurrentIndex) {
843  return true;
844  } else {
845  return ValueTraits::template IsDimensionDynamicImpl<TCheckIndex, TCurrentIndex + 1>();
846  }
847  }
848 
852 
853  template<class T>
854  friend class DataTypeTraits;
855 
857 };
858 
859 template<class TDataType> class DataTypeTraits<DenseMatrix<TDataType>>
860 {
861 public:
864 
866 
867  using ValueType = TDataType;
868 
870 
872 
873  static constexpr bool IsDynamic = true;
874 
875  // boost ublas makes the underlying data structure contiguous for
876  // any ValueType which are not dynamic recursively.
877  static constexpr bool IsContiguous = !ValueTraits::IsDynamic;
878 
879  static constexpr unsigned int Dimension = ValueTraits::Dimension + 2;
880 
884 
895  template<unsigned int TCheckIndex>
896  static constexpr bool IsDimensionDynamic()
897  {
898  return IsDimensionDynamicImpl<TCheckIndex, 0>();
899  }
900 
910  template<class TIndexType = unsigned int>
911  static inline TIndexType Size(const ContainerType& rValue)
912  {
913  return (rValue.size1() == 0 || rValue.size2() == 0 ? 0 : rValue.size1() * rValue.size2() * ValueTraits::template Size<TIndexType>(rValue.data()[0]));
914  }
915 
925  template<class TIndexType = unsigned int>
926  static inline std::vector<TIndexType> Shape(const ContainerType& rContainer)
927  {
928  std::vector<TIndexType> shape(Dimension);
929  Shape(rContainer, shape.data(), shape.data() + Dimension);
930  return shape;
931  }
932 
942  template<class TIndexType = unsigned int>
943  static inline void Shape(
944  const ContainerType& rContainer,
945  TIndexType* pShapeBegin,
946  TIndexType* pShapeEnd)
947  {
948  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) >= 2)
949  << "Invalid dimensions given to fill for primitive data type [ Expected dimension >= 2, provided shape = "
950  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
951 
952  if (rContainer.size1() > 0 && rContainer.size2() > 0) {
953  ValueTraits::Shape(rContainer(0, 0), pShapeBegin + 2, pShapeEnd);
954  } else {
955  ValueTraits::Shape(ValueType{}, pShapeBegin + 2, pShapeEnd);
956  }
957  pShapeBegin[0] = rContainer.size1();
958  pShapeBegin[1] = rContainer.size2();
959  }
960 
977  template<class TIndexType = unsigned int>
978  static inline bool Reshape(
979  ContainerType& rContainer,
980  const std::vector<TIndexType>& rShape)
981  {
982  return Reshape(rContainer, rShape.data(), rShape.data() + rShape.size());
983  }
984 
1002  template<class TIndexType = unsigned int>
1003  static inline bool Reshape(
1004  ContainerType& rContainer,
1005  TIndexType const * pShapeBegin,
1006  TIndexType const * pShapeEnd)
1007  {
1008  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) >= 2)
1009  << "Invalid shape/dimension given for DenseMatrix data type [ Expected = " << Shape(rContainer) << ", provided = "
1010  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
1011 
1012  bool is_reshaped = false;
1013 
1014  if (rContainer.size1() != pShapeBegin[0] || rContainer.size2() != pShapeBegin[1]) {
1015  rContainer.resize(pShapeBegin[0], pShapeBegin[1], false);
1016  is_reshaped = true;
1017  }
1018 
1019  if constexpr(ValueTraits::IsDynamic) {
1020  std::for_each(rContainer.data().begin(), rContainer.data().end(), [&is_reshaped, pShapeBegin, pShapeEnd](auto& rValue) {
1021  is_reshaped = ValueTraits::Reshape(rValue, pShapeBegin + 2, pShapeEnd) || is_reshaped;
1022  });
1023  }
1024 
1025  return is_reshaped;
1026  }
1027 
1038  inline static PrimitiveType const * GetContiguousData(const ContainerType& rValue)
1039  {
1040  if constexpr(IsContiguous) {
1041  if constexpr(std::is_same_v<PrimitiveType, ValueType>) {
1042  return rValue.data().begin();
1043  } else {
1044  // since the underlying data structure for recusive static data types
1045  // is contiguous in ublas types, we can do the following to get the
1046  // contiguous array.
1047  if (rValue.size1() > 0 && rValue.size2() > 0) {
1048  return reinterpret_cast<PrimitiveType const*>(&rValue(0, 0));
1049  } else {
1050  // not returning nullptr so, the return value can be subjected to
1051  // arithmetic operations
1052  return 0;
1053  }
1054  }
1055  } else {
1056  static_assert(!std::is_same_v<TDataType, TDataType>, "GetContiguousData should only be called if rValue is contiguous.");
1057  }
1058  }
1059 
1071  {
1072  if constexpr(IsContiguous) {
1073  if constexpr(std::is_same_v<PrimitiveType, ValueType>) {
1074  return rValue.data().begin();
1075  } else {
1076  // since the underlying data structure for recusive static data types
1077  // is contiguous in ublas types, we can do the following to get the
1078  // contiguous array.
1079  if (rValue.size1() > 0 && rValue.size2() > 0) {
1080  return reinterpret_cast<PrimitiveType*>(&rValue(0, 0));
1081  } else {
1082  // not returning nullptr so, the return value can be subjected to
1083  // arithmetic operations
1084  return 0;
1085  }
1086  }
1087  } else {
1088  static_assert(!std::is_same_v<TDataType, TDataType>, "GetContiguousData should only be called if rValue is contiguous.");
1089  }
1090  }
1091 
1104  inline static void CopyToContiguousData(
1105  PrimitiveType* pContiguousDataBegin,
1106  const ContainerType& rContainer)
1107  {
1108  if (rContainer.size1() != 0 && rContainer.size2() != 0) {
1109  const auto stride = ValueTraits::Size(rContainer(0, 0));
1110  for (unsigned int i = 0; i < rContainer.size1() * rContainer.size2(); ++i) {
1111  ValueTraits::CopyToContiguousData(pContiguousDataBegin + i * stride, rContainer.data()[i]);
1112  }
1113  }
1114  }
1115 
1128  inline static void CopyFromContiguousData(
1129  ContainerType& rContainer,
1130  PrimitiveType const * pContiguousDataBegin)
1131  {
1132  if (rContainer.size1() != 0 && rContainer.size2() != 0) {
1133  const auto stride = ValueTraits::Size(rContainer(0, 0));
1134  for (unsigned int i = 0; i < rContainer.size1() * rContainer.size2(); ++i) {
1135  ValueTraits::CopyFromContiguousData(rContainer.data()[i], pContiguousDataBegin + i * stride);
1136  }
1137  }
1138  }
1139 
1141 
1142 private:
1145 
1146  template<unsigned int TCheckIndex, unsigned int TCurrentIndex>
1147  static constexpr bool IsDimensionDynamicImpl()
1148  {
1149  if constexpr(TCheckIndex == TCurrentIndex || TCheckIndex == TCurrentIndex + 1) {
1150  return true;
1151  } else {
1152  return ValueTraits::template IsDimensionDynamicImpl<TCheckIndex, TCurrentIndex + 2>();
1153  }
1154  }
1155 
1159 
1160  template<class T>
1161  friend class DataTypeTraits;
1162 
1164 };
1165 
1166 template<> class DataTypeTraits<std::string>
1167 {
1168 public:
1171 
1172  using ContainerType = std::string;
1173 
1174  using ValueType = char;
1175 
1176  using PrimitiveType = char;
1177 
1178  static constexpr bool IsContiguous = true;
1179 
1180  static constexpr bool IsDynamic = true;
1181 
1182  static constexpr unsigned int Dimension = 1;
1183 
1187 
1198  template<unsigned int TCheckIndex>
1199  static constexpr bool IsDimensionDynamic()
1200  {
1201  return IsDimensionDynamicImpl<TCheckIndex, 0>();
1202  }
1203 
1213  template<class TIndexType = unsigned int>
1214  static inline TIndexType Size(const ContainerType& rValue)
1215  {
1216  return rValue.size();
1217  }
1218 
1228  template<class TIndexType = unsigned int>
1229  static inline std::vector<TIndexType> Shape(const ContainerType& rContainer)
1230  {
1231  std::vector<TIndexType> shape(Dimension);
1232  Shape(rContainer, shape.data(), shape.data() + Dimension);
1233  return shape;
1234  }
1235 
1245  template<class TIndexType = unsigned int>
1246  static inline void Shape(
1247  const ContainerType& rContainer,
1248  TIndexType* pShapeBegin,
1249  TIndexType* pShapeEnd)
1250  {
1251  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) == 1)
1252  << "Invalid dimensions given to fill for std::string data type [ Expected dimension == 1, provided shape = "
1253  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
1254  pShapeBegin[0] = rContainer.size();
1255  }
1256 
1273  template<class TIndexType = unsigned int>
1274  static inline bool Reshape(
1275  ContainerType& rContainer,
1276  const std::vector<TIndexType>& rShape)
1277  {
1278  return Reshape(rContainer, rShape.data(), rShape.data() + rShape.size());
1279  }
1280 
1298  template<class TIndexType = unsigned int>
1299  static inline bool Reshape(
1300  ContainerType& rContainer,
1301  TIndexType const * pShapeBegin,
1302  TIndexType const * pShapeEnd)
1303  {
1304  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) == 1)
1305  << "Invalid shape/dimension given for std::string data type [ Expected = "
1306  << Shape(rContainer) << ", provided = "
1307  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
1308 
1309  bool is_reshaped = false;
1310 
1311  if (rContainer.size() != pShapeBegin[0]) {
1312  rContainer.resize(pShapeBegin[0], false);
1313  is_reshaped = true;
1314  }
1315 
1316  return is_reshaped;
1317  }
1318 
1329  inline static PrimitiveType const * GetContiguousData(const ContainerType& rValue)
1330  {
1331  return rValue.data();
1332  }
1333 
1345  {
1346  return rValue.data();
1347  }
1348 
1361  inline static void CopyToContiguousData(
1362  PrimitiveType* pContiguousDataBegin,
1363  const ContainerType& rContainer)
1364  {
1365  std::copy(rContainer.begin(), rContainer.end(), pContiguousDataBegin);
1366  }
1367 
1380  inline static void CopyFromContiguousData(
1381  ContainerType& rContainer,
1382  PrimitiveType const * pContiguousDataBegin)
1383  {
1384  std::copy(pContiguousDataBegin, pContiguousDataBegin + rContainer.size(), rContainer.begin());
1385  }
1386 
1388 
1389 private:
1392 
1393  template<unsigned int TCheckIndex, unsigned int TCurrentIndex>
1394  static constexpr bool IsDimensionDynamicImpl()
1395  {
1396  if constexpr(TCheckIndex == TCurrentIndex) {
1397  return true;
1398  } else {
1399  static_assert(TCheckIndex != TCheckIndex, "Invalid dimension index.");
1400  }
1401  }
1402 
1406 
1407  template<class T>
1408  friend class DataTypeTraits;
1409 
1411 };
1412 
1413 template<class TDataType> class DataTypeTraits<std::vector<TDataType>>
1414 {
1415 public:
1418 
1419  using ContainerType = std::vector<TDataType>;
1420 
1421  using ValueType = TDataType;
1422 
1424 
1426 
1427  static constexpr bool IsContiguous = std::is_same_v<PrimitiveType, ValueType>;
1428 
1429  static constexpr bool IsDynamic = true;
1430 
1431  static constexpr unsigned int Dimension = ValueTraits::Dimension + 1;
1432 
1436 
1447  template<unsigned int TCheckIndex>
1448  static constexpr bool IsDimensionDynamic()
1449  {
1450  return IsDimensionDynamicImpl<TCheckIndex, 0>();
1451  }
1452 
1462  template<class TIndexType = unsigned int>
1463  static inline TIndexType Size(const ContainerType& rValue)
1464  {
1465  return (rValue.empty() ? 0 : rValue.size() * ValueTraits::template Size<TIndexType>(rValue[0]));
1466  }
1467 
1477  template<class TIndexType = unsigned int>
1478  static inline std::vector<TIndexType> Shape(const ContainerType& rContainer)
1479  {
1480  std::vector<TIndexType> shape(Dimension);
1481  Shape(rContainer, shape.data(), shape.data() + Dimension);
1482  return shape;
1483  }
1484 
1494  template<class TIndexType = unsigned int>
1495  static inline void Shape(
1496  const ContainerType& rContainer,
1497  TIndexType* pShapeBegin,
1498  TIndexType* pShapeEnd)
1499  {
1500  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) >= 1)
1501  << "Invalid dimensions given to fill for primitive data type [ Expected dimension >= 1, provided shape = "
1502  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
1503 
1504  if (rContainer.empty()) {
1505  ValueTraits::Shape(ValueType{}, pShapeBegin + 1, pShapeEnd);
1506  } else {
1507  ValueTraits::Shape(rContainer[0], pShapeBegin + 1, pShapeEnd);
1508  }
1509  pShapeBegin[0] = rContainer.size();
1510  }
1511 
1528  template<class TIndexType = unsigned int>
1529  static inline bool Reshape(
1530  ContainerType& rContainer,
1531  const std::vector<TIndexType>& rShape)
1532  {
1533  return Reshape(rContainer, rShape.data(), rShape.data() + rShape.size());
1534  }
1535 
1553  template<class TIndexType = unsigned int>
1554  static inline bool Reshape(
1555  ContainerType& rContainer,
1556  TIndexType const * pShapeBegin,
1557  TIndexType const * pShapeEnd)
1558  {
1559  KRATOS_ERROR_IF_NOT(std::distance(pShapeBegin, pShapeEnd) >= 1)
1560  << "Invalid shape/dimension given for std::vector data type [ Expected = " << Shape(rContainer) << ", provided = "
1561  << std::vector<TIndexType>(pShapeBegin, pShapeEnd) << " ].\n";
1562 
1563  bool is_reshaped = false;
1564 
1565  if (rContainer.size() != pShapeBegin[0]) {
1566  rContainer.resize(pShapeBegin[0]);
1567  is_reshaped = true;
1568  }
1569 
1570  if constexpr(ValueTraits::IsDynamic) {
1571  std::for_each(rContainer.begin(), rContainer.end(), [&is_reshaped, pShapeBegin, pShapeEnd](auto& rValue) {
1572  is_reshaped = ValueTraits::Reshape(rValue, pShapeBegin + 1, pShapeEnd) || is_reshaped;
1573  });
1574  }
1575 
1576  return is_reshaped;
1577  }
1578 
1589  inline static PrimitiveType const * GetContiguousData(const ContainerType& rValue)
1590  {
1591  if constexpr(IsContiguous) {
1592  return rValue.data();
1593  } else {
1594  static_assert(!std::is_same_v<TDataType, TDataType>, "GetContiguousData should only be called if rValue is contiguous.");
1595  }
1596  }
1597 
1609  {
1610  if constexpr(IsContiguous) {
1611  return rValue.data();
1612  } else {
1613  static_assert(!std::is_same_v<TDataType, TDataType>, "GetContiguousData should only be called if rValue is contiguous.");
1614  }
1615  }
1616 
1629  inline static void CopyToContiguousData(
1630  PrimitiveType* pContiguousDataBegin,
1631  const ContainerType& rContainer)
1632  {
1633  if (rContainer.size() != 0) {
1634  const auto stride = ValueTraits::Size(rContainer[0]);
1635  for (unsigned int i = 0; i < rContainer.size(); ++i) {
1636  ValueTraits::CopyToContiguousData(pContiguousDataBegin + i * stride, rContainer[i]);
1637  }
1638  }
1639  }
1640 
1653  inline static void CopyFromContiguousData(
1654  ContainerType& rContainer,
1655  PrimitiveType const * pContiguousDataBegin)
1656  {
1657  if (rContainer.size() != 0) {
1658  const auto stride = ValueTraits::Size(rContainer[0]);
1659  for (unsigned int i = 0; i < rContainer.size(); ++i) {
1660  ValueTraits::CopyFromContiguousData(rContainer[i], pContiguousDataBegin + i * stride);
1661  }
1662  }
1663  }
1664 
1666 
1667 private:
1670 
1671  template<unsigned int TCheckIndex, unsigned int TCurrentIndex>
1672  static constexpr bool IsDimensionDynamicImpl()
1673  {
1674  if constexpr(TCheckIndex == TCurrentIndex) {
1675  return true;
1676  } else {
1677  return ValueTraits::template IsDimensionDynamicImpl<TCheckIndex, TCurrentIndex + 1>();
1678  }
1679  }
1680 
1684 
1685  template<class T>
1686  friend class DataTypeTraits;
1687 
1689 };
1690 
1691 }; // namespace Kratos
static std::vector< TIndexType > Shape(const ContainerType &rContainer)
Get the shape of the rContainer.
Definition: data_type_traits.h:926
static PrimitiveType const * GetContiguousData(const ContainerType &rValue)
Get the Contiguous data pointer of the given container.
Definition: data_type_traits.h:1038
typename ValueTraits::PrimitiveType PrimitiveType
Definition: data_type_traits.h:871
static bool Reshape(ContainerType &rContainer, TIndexType const *pShapeBegin, TIndexType const *pShapeEnd)
Reshapes the given value to given shape.
Definition: data_type_traits.h:1003
static void CopyFromContiguousData(ContainerType &rContainer, PrimitiveType const *pContiguousDataBegin)
Copies contiguous values to the container.
Definition: data_type_traits.h:1128
static bool Reshape(ContainerType &rContainer, const std::vector< TIndexType > &rShape)
Reshapes the given value to given shape.
Definition: data_type_traits.h:978
static void Shape(const ContainerType &rContainer, TIndexType *pShapeBegin, TIndexType *pShapeEnd)
Fills the given array with the shape values in each dimension.
Definition: data_type_traits.h:943
static PrimitiveType * GetContiguousData(ContainerType &rValue)
Get the Contiguous data pointer of the given container.
Definition: data_type_traits.h:1070
static void CopyToContiguousData(PrimitiveType *pContiguousDataBegin, const ContainerType &rContainer)
Copies the given container element value to contiguous array.
Definition: data_type_traits.h:1104
static TIndexType Size(const ContainerType &rValue)
Gets the size of underlying rContainer.
Definition: data_type_traits.h:911
TDataType ValueType
Definition: data_type_traits.h:867
static constexpr bool IsDimensionDynamic()
Returns whther the given TCheckIndex is dynamic.
Definition: data_type_traits.h:896
static PrimitiveType * GetContiguousData(ContainerType &rValue)
Get the Contiguous data pointer of the given container.
Definition: data_type_traits.h:763
static PrimitiveType const * GetContiguousData(const ContainerType &rValue)
Get the Contiguous data pointer of the given container.
Definition: data_type_traits.h:731
static void CopyFromContiguousData(ContainerType &rContainer, PrimitiveType const *pContiguousDataBegin)
Copies contiguous values to the container.
Definition: data_type_traits.h:821
static constexpr bool IsDimensionDynamic()
Returns whther the given TCheckIndex is dynamic.
Definition: data_type_traits.h:590
static bool Reshape(ContainerType &rContainer, TIndexType const *pShapeBegin, TIndexType const *pShapeEnd)
Reshapes the given value to given shape.
Definition: data_type_traits.h:696
typename ValueTraits::PrimitiveType PrimitiveType
Definition: data_type_traits.h:565
static void CopyToContiguousData(PrimitiveType *pContiguousDataBegin, const ContainerType &rContainer)
Copies the given container element value to contiguous array.
Definition: data_type_traits.h:797
static void Shape(const ContainerType &rContainer, TIndexType *pShapeBegin, TIndexType *pShapeEnd)
Fills the given array with the shape values in each dimension.
Definition: data_type_traits.h:637
TDataType ValueType
Definition: data_type_traits.h:561
static std::vector< TIndexType > Shape(const ContainerType &rContainer)
Get the shape of the rContainer.
Definition: data_type_traits.h:620
static TIndexType Size(const ContainerType &rValue)
Gets the size of underlying rContainer.
Definition: data_type_traits.h:605
static bool Reshape(ContainerType &rContainer, const std::vector< TIndexType > &rShape)
Reshapes the given value to given shape.
Definition: data_type_traits.h:671
static void CopyToContiguousData(PrimitiveType *pContiguousDataBegin, const ContainerType &rContainer)
Copies the given container element value to contiguous array.
Definition: data_type_traits.h:490
static bool Reshape(ContainerType &rContainer, const std::vector< TIndexType > &rShape)
Reshapes the given value to given shape.
Definition: data_type_traits.h:369
static std::vector< TIndexType > Shape(const ContainerType &rContainer)
Get the shape of the rContainer.
Definition: data_type_traits.h:318
static PrimitiveType * GetContiguousData(ContainerType &rValue)
Get the Contiguous data pointer of the given container.
Definition: data_type_traits.h:456
static PrimitiveType const * GetContiguousData(const ContainerType &rValue)
Get the Contiguous data pointer of the given container.
Definition: data_type_traits.h:424
static bool Reshape(ContainerType &rContainer, TIndexType const *pShapeBegin, TIndexType const *pShapeEnd)
Reshapes the given value to given shape.
Definition: data_type_traits.h:394
typename ValueTraits::PrimitiveType PrimitiveType
Definition: data_type_traits.h:259
static void CopyFromContiguousData(ContainerType &rContainer, PrimitiveType const *pContiguousDataBegin)
Copies contiguous values to the container.
Definition: data_type_traits.h:512
static void Shape(const ContainerType &rContainer, TIndexType *pShapeBegin, TIndexType *pShapeEnd)
Fills the given array with the shape values in each dimension.
Definition: data_type_traits.h:335
static TIndexType Size(const ContainerType &rContainer)
Gets the size of underlying rContainer.
Definition: data_type_traits.h:299
static constexpr bool IsDimensionDynamic()
Returns whther the given TCheckIndex is dynamic.
Definition: data_type_traits.h:284
TDataType ValueType
Definition: data_type_traits.h:255
static void Shape(const ContainerType &rContainer, TIndexType *pShapeBegin, TIndexType *pShapeEnd)
Fills the given array with the shape values in each dimension.
Definition: data_type_traits.h:1246
char PrimitiveType
Definition: data_type_traits.h:1176
char ValueType
Definition: data_type_traits.h:1174
static bool Reshape(ContainerType &rContainer, TIndexType const *pShapeBegin, TIndexType const *pShapeEnd)
Reshapes the given value to given shape.
Definition: data_type_traits.h:1299
static PrimitiveType const * GetContiguousData(const ContainerType &rValue)
Get the Contiguous data pointer of the given container.
Definition: data_type_traits.h:1329
static TIndexType Size(const ContainerType &rValue)
Gets the size of underlying rContainer.
Definition: data_type_traits.h:1214
std::string ContainerType
Definition: data_type_traits.h:1172
static void CopyToContiguousData(PrimitiveType *pContiguousDataBegin, const ContainerType &rContainer)
Copies the given container element value to contiguous array.
Definition: data_type_traits.h:1361
static constexpr bool IsDimensionDynamic()
Returns whther the given TCheckIndex is dynamic.
Definition: data_type_traits.h:1199
static bool Reshape(ContainerType &rContainer, const std::vector< TIndexType > &rShape)
Reshapes the given value to given shape.
Definition: data_type_traits.h:1274
static std::vector< TIndexType > Shape(const ContainerType &rContainer)
Get the shape of the rContainer.
Definition: data_type_traits.h:1229
static PrimitiveType * GetContiguousData(ContainerType &rValue)
Get the Contiguous data pointer of the given container.
Definition: data_type_traits.h:1344
static void CopyFromContiguousData(ContainerType &rContainer, PrimitiveType const *pContiguousDataBegin)
Copies contiguous values to the container.
Definition: data_type_traits.h:1380
static bool Reshape(ContainerType &rContainer, const std::vector< TIndexType > &rShape)
Reshapes the given value to given shape.
Definition: data_type_traits.h:1529
static PrimitiveType const * GetContiguousData(const ContainerType &rValue)
Get the Contiguous data pointer of the given container.
Definition: data_type_traits.h:1589
typename ValueTraits::PrimitiveType PrimitiveType
Definition: data_type_traits.h:1425
static PrimitiveType * GetContiguousData(ContainerType &rValue)
Get the Contiguous data pointer of the given container.
Definition: data_type_traits.h:1608
static void CopyToContiguousData(PrimitiveType *pContiguousDataBegin, const ContainerType &rContainer)
Copies the given container element value to contiguous array.
Definition: data_type_traits.h:1629
static TIndexType Size(const ContainerType &rValue)
Gets the size of underlying rContainer.
Definition: data_type_traits.h:1463
static bool Reshape(ContainerType &rContainer, TIndexType const *pShapeBegin, TIndexType const *pShapeEnd)
Reshapes the given value to given shape.
Definition: data_type_traits.h:1554
TDataType ValueType
Definition: data_type_traits.h:1421
std::vector< TDataType > ContainerType
Definition: data_type_traits.h:1419
static constexpr bool IsDimensionDynamic()
Returns whther the given TCheckIndex is dynamic.
Definition: data_type_traits.h:1448
static std::vector< TIndexType > Shape(const ContainerType &rContainer)
Get the shape of the rContainer.
Definition: data_type_traits.h:1478
static void CopyFromContiguousData(ContainerType &rContainer, PrimitiveType const *pContiguousDataBegin)
Copies contiguous values to the container.
Definition: data_type_traits.h:1653
static void Shape(const ContainerType &rContainer, TIndexType *pShapeBegin, TIndexType *pShapeEnd)
Fills the given array with the shape values in each dimension.
Definition: data_type_traits.h:1495
Generic data type traits class for arithmetic types.
Definition: data_type_traits.h:33
TDataType ContainerType
Definition: data_type_traits.h:38
static constexpr bool IsDynamic
Definition: data_type_traits.h:46
static void Shape(const ContainerType &, TIndexType *pShapeBegin, TIndexType *pShapeEnd)
Fills the given array with the shape values in each dimension.
Definition: data_type_traits.h:104
static std::vector< TIndexType > Shape(const ContainerType &)
Returns a vector with the shape of the value.
Definition: data_type_traits.h:89
static constexpr bool IsDimensionDynamic()
Returns whther the given TCheckIndex is dynamic.
Definition: data_type_traits.h:65
static bool Reshape(ContainerType &, TIndexType const *pShapeBegin, TIndexType const *pShapeEnd)
Reshapes the value.
Definition: data_type_traits.h:145
static PrimitiveType const * GetContiguousData(const ContainerType &rValue)
Get the contiguous data pointer.
Definition: data_type_traits.h:162
static TIndexType Size(const ContainerType &)
Returns the size of the value.
Definition: data_type_traits.h:76
TDataType ValueType
Definition: data_type_traits.h:40
static PrimitiveType * GetContiguousData(ContainerType &rValue)
Get the contiguous data pointer.
Definition: data_type_traits.h:173
static void CopyFromContiguousData(ContainerType &rValue, PrimitiveType const *pContiguousDataBegin)
Copies data from contiguous array to rValue.
Definition: data_type_traits.h:208
static void CopyToContiguousData(PrimitiveType *pContiguousDataBegin, const ContainerType &rValue)
Copies the given Value to contiguous array.
Definition: data_type_traits.h:190
static constexpr bool IsContiguous
Definition: data_type_traits.h:44
static constexpr unsigned int Dimension
Definition: data_type_traits.h:48
TDataType PrimitiveType
Definition: data_type_traits.h:42
static bool Reshape(ContainerType &rValue, const std::vector< TIndexType > &rShape)
Reshapes the value.
Definition: data_type_traits.h:126
Definition: amatrix_interface.h:41
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
iterator end()
Definition: amatrix_interface.h:243
iterator begin()
Definition: amatrix_interface.h:241
Short class definition.
Definition: array_1d.h:61
BOOST_UBLAS_INLINE const array_type & data() const
Definition: array_1d.h:383
BOOST_UBLAS_INLINE const_iterator end() const
Definition: array_1d.h:611
BOOST_UBLAS_INLINE const_iterator begin() const
Definition: array_1d.h:606
#define KRATOS_ERROR_IF_NOT(conditional)
Definition: exception.h:163
TSpaceType::IndexType Size(TSpaceType &dummy, typename TSpaceType::VectorType const &rV)
Definition: add_strategies_to_python.cpp:111
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
tuple const
Definition: ode_solve.py:403
namespace
Definition: array_1d.h:793
integer i
Definition: TensorModule.f:17