Reference documentation for deal.II version 9.0.0
utilities.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2005 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_utilities_h
17 #define dealii_utilities_h
18 
19 #include <deal.II/base/config.h>
20 #include <deal.II/base/exceptions.h>
21 
22 #include <vector>
23 #include <utility>
24 #include <functional>
25 #include <string>
26 #include <tuple>
27 #include <type_traits>
28 
29 #ifdef DEAL_II_WITH_TRILINOS
30 # include <Epetra_Comm.h>
31 # include <Epetra_Map.h>
32 # ifdef DEAL_II_WITH_MPI
33 # include <Epetra_MpiComm.h>
34 # else
35 # include <Epetra_SerialComm.h>
36 # endif
37 #endif
38 
39 #include <boost/archive/binary_oarchive.hpp>
40 #include <boost/archive/binary_iarchive.hpp>
41 #include <boost/serialization/vector.hpp>
42 #include <boost/serialization/array.hpp>
43 
44 #ifdef DEAL_II_WITH_ZLIB
45 # include <boost/iostreams/stream.hpp>
46 # include <boost/iostreams/filtering_stream.hpp>
47 # include <boost/iostreams/device/back_inserter.hpp>
48 # include <boost/iostreams/filter/gzip.hpp>
49 #endif
50 
51 DEAL_II_NAMESPACE_OPEN
52 
53 
62 namespace Utilities
63 {
70  std::string dealii_version_string ();
71 
88  std::string
89  int_to_string (const unsigned int value,
90  const unsigned int digits = numbers::invalid_unsigned_int);
91 
102  template <typename number>
103  std::string
104  to_string (const number value,
105  const unsigned int digits = numbers::invalid_unsigned_int);
106 
111  unsigned int
112  needed_digits (const unsigned int max_number);
113 
118  int
119  string_to_int (const std::string &s);
120 
132  std::string dim_string(const int dim, const int spacedim);
133 
138  std::vector<int>
139  string_to_int (const std::vector<std::string> &s);
140 
145  double
146  string_to_double (const std::string &s);
147 
148 
153  std::vector<double>
154  string_to_double (const std::vector<std::string> &s);
155 
156 
199  std::vector<std::string>
200  split_string_list (const std::string &s,
201  const std::string &delimiter = ",");
202 
203 
208  std::vector<std::string>
209  split_string_list (const std::string &s,
210  const char delimiter);
211 
212 
222  std::vector<std::string>
223  break_text_into_lines (const std::string &original_text,
224  const unsigned int width,
225  const char delimiter = ' ');
226 
231  bool
232  match_at_string_start (const std::string &name,
233  const std::string &pattern);
234 
243  std::pair<int, unsigned int>
244  get_integer_at_position (const std::string &name,
245  const unsigned int position);
246 
251  std::string replace_in_string(const std::string &input,
252  const std::string &from,
253  const std::string &to);
254 
260  std::string
261  trim(const std::string &input);
262 
288  double
289  generate_normal_random_number (const double a,
290  const double sigma);
291 
292 
301  template <int N, typename T>
302  T
303  fixed_power (const T t);
304 
329  template <int a, int N>
330  struct DEAL_II_DEPRECATED fixed_int_power
331  {
332  static const int value = a *fixed_int_power<a,N-1>::value;
333  };
334 
342  template <int a>
343  struct DEAL_II_DEPRECATED fixed_int_power<a,0>
344  {
345  static const int value = 1;
346  };
347 
352  constexpr
353  unsigned int
354  pow(const unsigned int base, const unsigned int iexp)
355  {
356  return iexp == 0 ? 1 : base*::Utilities::pow(base, iexp - 1);
357  }
358 
380  template <typename Iterator, typename T>
381  Iterator
382  lower_bound (Iterator first,
383  Iterator last,
384  const T &val);
385 
386 
392  template <typename Iterator, typename T, typename Comp>
393  Iterator
394  lower_bound (Iterator first,
395  Iterator last,
396  const T &val,
397  const Comp comp);
398 
404  std::vector<unsigned int>
405  reverse_permutation (const std::vector<unsigned int> &permutation);
406 
412  std::vector<unsigned int>
413  invert_permutation (const std::vector<unsigned int> &permutation);
414 
420  std::vector<unsigned long long int>
421  reverse_permutation (const std::vector<unsigned long long int> &permutation);
422 
428  std::vector<unsigned long long int>
429  invert_permutation (const std::vector<unsigned long long int> &permutation);
430 
447  template <typename T>
448  size_t pack (const T &object, std::vector<char> &dest_buffer);
449 
456  template <typename T>
457  std::vector<char> pack (const T &object);
458 
487  template <typename T>
488  T unpack (const std::vector<char> &buffer);
489 
496  template <typename T>
497  T unpack (const std::vector<char>::iterator &begin,
498  const std::vector<char>::iterator &end);
499 
530  template <typename T, int N>
531  void unpack (const std::vector<char> &buffer,
532  T (&unpacked_object)[N]);
533 
540  template <typename T, int N>
541  void unpack (const std::vector<char>::iterator &begin,
542  const std::vector<char>::iterator &end,
543  T (&unpacked_object)[N]);
544 
590  template <typename To, typename From>
591  std::unique_ptr<To>
592  dynamic_unique_cast (std::unique_ptr<From> &&p)
593  {
594  // Let's see if we can cast from 'From' to 'To'. If so, do the cast,
595  // and then release the pointer from the old
596  // owner
597  if (To *cast = dynamic_cast<To *>(p.get()))
598  {
599  std::unique_ptr<To> result(cast);
600  p.release();
601  return result;
602  }
603  else
604  throw std::bad_cast();
605  }
606 
612  namespace System
613  {
614 
622  double get_cpu_load ();
623 
656  const std::string get_current_vectorization_level();
657 
662  struct MemoryStats
663  {
667  unsigned long int VmPeak;
668 
672  unsigned long int VmSize;
673 
677  unsigned long int VmHWM;
678 
682  unsigned long int VmRSS;
683  };
684 
685 
690  void get_memory_stats (MemoryStats &stats);
691 
692 
696  std::string get_hostname ();
697 
698 
702  std::string get_time ();
703 
708  std::string get_date ();
709 
724  void posix_memalign (void **memptr, size_t alignment, size_t size);
725  }
726 
727 
728 #ifdef DEAL_II_WITH_TRILINOS
729 
734  namespace Trilinos
735  {
745  const Epetra_Comm &comm_world();
746 
756  const Epetra_Comm &comm_self();
757 
790  Epetra_Comm *
791  duplicate_communicator (const Epetra_Comm &communicator);
792 
815  void
816  destroy_communicator (Epetra_Comm &communicator);
817 
826  unsigned int get_n_mpi_processes (const Epetra_Comm &mpi_communicator);
827 
834  unsigned int get_this_mpi_process (const Epetra_Comm &mpi_communicator);
835 
846  Epetra_Map
847  duplicate_map (const Epetra_BlockMap &map,
848  const Epetra_Comm &comm);
849  }
850 
851 #endif
852 
853 
854 }
855 
856 
857 // --------------------- inline functions
858 
859 namespace Utilities
860 {
861  template <int N, typename T>
862  inline
863  T fixed_power (const T n)
864  {
865  Assert (N>=0, ExcNotImplemented());
866  switch (N)
867  {
868  case 0:
869  return ::internal::NumberType<T>::value(1);
870  case 1:
871  return n;
872  case 2:
873  return n*n;
874  case 3:
875  return n*n*n;
876  case 4:
877  return n*n*n*n;
878  default:
879  T result = n;
880  for (int d=1; d<N; ++d)
881  result *= n;
882  return result;
883  }
884  }
885 
886 
887 
888  template <typename Iterator, typename T>
889  inline
890  Iterator
891  lower_bound (Iterator first,
892  Iterator last,
893  const T &val)
894  {
895  return Utilities::lower_bound (first, last, val,
896  std::less<T>());
897  }
898 
899 
900 
901  template <typename Iterator, typename T, typename Comp>
902  inline
903  Iterator
904  lower_bound (Iterator first,
905  Iterator last,
906  const T &val,
907  const Comp comp)
908  {
909  // verify that the two iterators are properly ordered. since
910  // we need operator- for the iterator type anyway, do the
911  // test as follows, rather than via 'last >= first'
912  Assert (last - first >= 0,
913  ExcMessage ("The given iterators do not satisfy the proper ordering."));
914 
915  unsigned int len = static_cast<unsigned int>(last-first);
916 
917  if (len==0)
918  return first;
919 
920  while (true)
921  {
922  // if length equals 8 or less,
923  // then do a rolled out
924  // search. use a switch without
925  // breaks for that and roll-out
926  // the loop somehow
927  if (len < 8)
928  {
929  switch (len)
930  {
931  case 7:
932  if (!comp(*first, val))
933  return first;
934  ++first;
935  DEAL_II_FALLTHROUGH;
936  case 6:
937  if (!comp(*first, val))
938  return first;
939  ++first;
940  DEAL_II_FALLTHROUGH;
941  case 5:
942  if (!comp(*first, val))
943  return first;
944  ++first;
945  DEAL_II_FALLTHROUGH;
946  case 4:
947  if (!comp(*first, val))
948  return first;
949  ++first;
950  DEAL_II_FALLTHROUGH;
951  case 3:
952  if (!comp(*first, val))
953  return first;
954  ++first;
955  DEAL_II_FALLTHROUGH;
956  case 2:
957  if (!comp(*first, val))
958  return first;
959  ++first;
960  DEAL_II_FALLTHROUGH;
961  case 1:
962  if (!comp(*first, val))
963  return first;
964  return first+1;
965  default:
966  // indices seem
967  // to not be
968  // sorted
969  // correctly!? or
970  // did len
971  // become==0
972  // somehow? that
973  // shouldn't have
974  // happened
975  Assert (false, ExcInternalError());
976  }
977  }
978 
979 
980 
981  const unsigned int half = len >> 1;
982  const Iterator middle = first + half;
983 
984  // if the value is larger than
985  // that pointed to by the
986  // middle pointer, then the
987  // insertion point must be
988  // right of it
989  if (comp(*middle, val))
990  {
991  first = middle + 1;
992  len -= half + 1;
993  }
994  else
995  len = half;
996  }
997  }
998 
999 
1000 // --------------------- non-inline functions
1001 
1002  template <typename T>
1003  size_t pack (const T &object, std::vector<char> &dest_buffer)
1004  {
1005  // see if the object is small and copyable via memcpy. if so, use
1006  // this fast path. otherwise, we have to go through the BOOST
1007  // serialization machinery
1008  //
1009  // we have to work around the fact that GCC 4.8.x claims to be C++
1010  // conforming, but is not actually as it does not implement
1011  // std::is_trivially_copyable.
1012 #if __GNUG__ && __GNUC__ < 5
1013  if ( __has_trivial_copy(T) && sizeof(T)<256)
1014 #else
1015 # ifdef DEAL_II_WITH_CXX17
1016  if constexpr (std::is_trivially_copyable<T>() && sizeof(T)<256)
1017 # else
1018  if (std::is_trivially_copyable<T>() && sizeof(T)<256)
1019 # endif
1020 #endif
1021  {
1022  const size_t previous_size = dest_buffer.size();
1023  dest_buffer.resize (previous_size + sizeof(T));
1024 
1025  std::memcpy (dest_buffer.data() + previous_size, &object, sizeof(T));
1026 
1027  return sizeof(T);
1028  }
1029  else
1030  {
1031  // use buffer as the target of a compressing
1032  // stream into which we serialize the current object
1033  const size_t previous_size = dest_buffer.size();
1034  {
1035 #ifdef DEAL_II_WITH_ZLIB
1036  boost::iostreams::filtering_ostream out;
1037  out.push(boost::iostreams::gzip_compressor
1038  (boost::iostreams::gzip_params
1039  (boost::iostreams::gzip::best_compression)));
1040  out.push(boost::iostreams::back_inserter(dest_buffer));
1041 
1042  boost::archive::binary_oarchive archive(out);
1043  archive << object;
1044  out.flush();
1045 #else
1046  std::ostringstream out;
1047  boost::archive::binary_oarchive archive(out);
1048  archive << object;
1049 
1050  const std::string &s = out.str();
1051  dest_buffer.reserve (dest_buffer.size() + s.size());
1052  std::move (s.begin(), s.end(), std::back_inserter(dest_buffer));
1053 #endif
1054  }
1055  return (dest_buffer.size() - previous_size);
1056  }
1057  }
1058 
1059 
1060  template <typename T>
1061  std::vector<char> pack (const T &object)
1062  {
1063  std::vector<char> buffer;
1064  pack<T> (object, buffer);
1065  return buffer;
1066  }
1067 
1068 
1069  template <typename T>
1070  T unpack (const std::vector<char>::const_iterator &cbegin,
1071  const std::vector<char>::const_iterator &cend)
1072  {
1073  // see if the object is small and copyable via memcpy. if so, use
1074  // this fast path. otherwise, we have to go through the BOOST
1075  // serialization machinery
1076  //
1077  // we have to work around the fact that GCC 4.8.x claims to be C++
1078  // conforming, but is not actually as it does not implement
1079  // std::is_trivially_copyable.
1080 #if __GNUG__ && __GNUC__ < 5
1081  if ( __has_trivial_copy(T) && sizeof(T)<256)
1082 #else
1083 # ifdef DEAL_II_WITH_CXX17
1084  if constexpr (std::is_trivially_copyable<T>() && sizeof(T)<256)
1085 # else
1086  if (std::is_trivially_copyable<T>() && sizeof(T)<256)
1087 # endif
1088 #endif
1089  {
1090  Assert (std::distance(cbegin, cend) == sizeof(T), ExcInternalError());
1091  T object;
1092  std::memcpy (&object, &*cbegin, sizeof(T));
1093  return object;
1094  }
1095  else
1096  {
1097  std::string decompressed_buffer;
1098  T object;
1099 
1100  // first decompress the buffer
1101  {
1102 #ifdef DEAL_II_WITH_ZLIB
1103  boost::iostreams::filtering_ostream decompressing_stream;
1104  decompressing_stream.push(boost::iostreams::gzip_decompressor());
1105  decompressing_stream.push(boost::iostreams::back_inserter(decompressed_buffer));
1106  decompressing_stream.write (&*cbegin, std::distance(cbegin, cend));
1107 #else
1108  decompressed_buffer.assign (cbegin, cend);
1109 #endif
1110  }
1111 
1112  // then restore the object from the buffer
1113  std::istringstream in(decompressed_buffer);
1114  boost::archive::binary_iarchive archive(in);
1115 
1116  archive >> object;
1117  return object;
1118  }
1119  }
1120 
1121 
1122  template <typename T>
1123  T unpack(const std::vector<char> &buffer)
1124  {
1125  return unpack<T> (buffer.cbegin(), buffer.cend());
1126  }
1127 
1128 
1129  template <typename T, int N>
1130  void unpack (const std::vector<char>::const_iterator &cbegin,
1131  const std::vector<char>::const_iterator &cend,
1132  T (&unpacked_object)[N])
1133  {
1134  // see if the object is small and copyable via memcpy. if so, use
1135  // this fast path. otherwise, we have to go through the BOOST
1136  // serialization machinery
1137  //
1138  // we have to work around the fact that GCC 4.8.x claims to be C++
1139  // conforming, but is not actually as it does not implement
1140  // std::is_trivially_copyable.
1141  if (
1142 #if __GNUG__ && __GNUC__ < 5
1143  __has_trivial_copy(T)
1144 #else
1145  std::is_trivially_copyable<T>()
1146 #endif
1147  &&
1148  sizeof(T)*N<256)
1149  {
1150  Assert (std::distance(cbegin, cend) == sizeof(T)*N, ExcInternalError());
1151  std::memcpy (unpacked_object, &*cbegin, sizeof(T)*N);
1152  }
1153  else
1154  {
1155  std::string decompressed_buffer;
1156 
1157  // first decompress the buffer
1158  {
1159 #ifdef DEAL_II_WITH_ZLIB
1160  boost::iostreams::filtering_ostream decompressing_stream;
1161  decompressing_stream.push(boost::iostreams::gzip_decompressor());
1162  decompressing_stream.push(boost::iostreams::back_inserter(decompressed_buffer));
1163  decompressing_stream.write (&*cbegin, std::distance(cbegin, cend));
1164 #else
1165  decompressed_buffer.assign (cbegin, cend);
1166 #endif
1167  }
1168 
1169  // then restore the object from the buffer
1170  std::istringstream in(decompressed_buffer);
1171  boost::archive::binary_iarchive archive(in);
1172 
1173  archive >> unpacked_object;
1174  }
1175  }
1176 
1177 
1178  template <typename T, int N>
1179  void unpack (const std::vector<char> &buffer,
1180  T (&unpacked_object)[N])
1181  {
1182  unpack<T,N> (buffer.cbegin(), buffer.cend(), unpacked_object);
1183  }
1184 
1185 }
1186 
1187 
1188 DEAL_II_NAMESPACE_CLOSE
1189 
1190 #ifndef DOXYGEN
1191 namespace boost
1192 {
1193  namespace serialization
1194  {
1195 
1196  // Provides boost and c++11 with a way to serialize tuples and pairs automatically
1197  template<int N>
1198  struct Serialize
1199  {
1200  template<class Archive, typename... Args>
1201  static void serialize(Archive &ar, std::tuple<Args...> &t, const unsigned int version)
1202  {
1203  ar &std::get<N-1>(t);
1204  Serialize<N-1>::serialize(ar, t, version);
1205  }
1206  };
1207 
1208  template<>
1209  struct Serialize<0>
1210  {
1211  template<class Archive, typename... Args>
1212  static void serialize(Archive &ar, std::tuple<Args...> &t, const unsigned int version)
1213  {
1214  (void) ar;
1215  (void) t;
1216  (void) version;
1217  }
1218  };
1219 
1220  template<class Archive, typename... Args>
1221  void serialize(Archive &ar, std::tuple<Args...> &t, const unsigned int version)
1222  {
1223  Serialize<sizeof...(Args)>::serialize(ar, t, version);
1224  }
1225  }
1226 }
1227 #endif
1228 
1229 #endif
Iterator lower_bound(Iterator first, Iterator last, const T &val)
Definition: utilities.h:891
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition: utilities.cc:283
static const unsigned int invalid_unsigned_int
Definition: types.h:173
constexpr unsigned int pow(const unsigned int base, const unsigned int iexp)
Definition: utilities.h:354
std::string dealii_version_string()
Definition: utilities.cc:90
unsigned int get_n_mpi_processes(const Epetra_Comm &mpi_communicator)
Definition: utilities.cc:838
std::string trim(const std::string &input)
Definition: utilities.cc:149
std::pair< int, unsigned int > get_integer_at_position(const std::string &name, const unsigned int position)
Definition: utilities.cc:432
std::vector< std::string > break_text_into_lines(const std::string &original_text, const unsigned int width, const char delimiter=' ')
Definition: utilities.cc:339
T unpack(const std::vector< char > &buffer)
Definition: utilities.h:1123
const Epetra_Comm & comm_self()
Definition: utilities.cc:777
std::string get_date()
Definition: utilities.cc:716
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:107
void get_memory_stats(MemoryStats &stats)
Definition: utilities.cc:654
std::unique_ptr< To > dynamic_unique_cast(std::unique_ptr< From > &&p)
Definition: utilities.h:592
double string_to_double(const std::string &s)
Definition: utilities.cc:245
double get_cpu_load()
Definition: utilities.cc:627
T fixed_power(const T t)
Definition: utilities.h:863
static ::ExceptionBase & ExcMessage(std::string arg1)
Epetra_Comm * duplicate_communicator(const Epetra_Comm &communicator)
Definition: utilities.cc:793
double generate_normal_random_number(const double a, const double sigma)
Definition: utilities.cc:476
#define Assert(cond, exc)
Definition: exceptions.h:1142
unsigned long int VmSize
Definition: utilities.h:672
bool match_at_string_start(const std::string &name, const std::string &pattern)
Definition: utilities.cc:416
void posix_memalign(void **memptr, size_t alignment, size_t size)
Definition: utilities.cc:731
std::vector< unsigned int > invert_permutation(const std::vector< unsigned int > &permutation)
Definition: utilities.cc:509
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:98
std::string replace_in_string(const std::string &input, const std::string &from, const std::string &to)
Definition: utilities.cc:130
std::string dim_string(const int dim, const int spacedim)
Definition: utilities.cc:176
void destroy_communicator(Epetra_Comm &communicator)
Definition: utilities.cc:819
Definition: cuda.h:31
std::string get_hostname()
Definition: utilities.cc:687
unsigned long int VmHWM
Definition: utilities.h:677
size_t pack(const T &object, std::vector< char > &dest_buffer)
Definition: utilities.h:1003
const Epetra_Comm & comm_world()
Definition: utilities.cc:761
int string_to_int(const std::string &s)
Definition: utilities.cc:207
std::vector< unsigned int > reverse_permutation(const std::vector< unsigned int > &permutation)
Definition: utilities.cc:495
static ::ExceptionBase & ExcNotImplemented()
unsigned long int VmRSS
Definition: utilities.h:682
unsigned int get_this_mpi_process(const Epetra_Comm &mpi_communicator)
Definition: utilities.cc:844
const std::string get_current_vectorization_level()
Definition: utilities.cc:635
Epetra_Map duplicate_map(const Epetra_BlockMap &map, const Epetra_Comm &comm)
Definition: utilities.cc:852
std::string get_time()
Definition: utilities.cc:701
unsigned long int VmPeak
Definition: utilities.h:667
unsigned int needed_digits(const unsigned int max_number)
Definition: utilities.cc:186
static ::ExceptionBase & ExcInternalError()