13#ifndef dealii_utilities_h
14#define dealii_utilities_h
21#include <boost/archive/binary_iarchive.hpp>
22#include <boost/archive/binary_oarchive.hpp>
23#include <boost/core/demangle.hpp>
24#include <boost/iostreams/device/array.hpp>
25#include <boost/iostreams/device/back_inserter.hpp>
26#include <boost/iostreams/filtering_streambuf.hpp>
27#include <boost/serialization/array.hpp>
28#include <boost/serialization/complex.hpp>
29#include <boost/serialization/set.hpp>
30#include <boost/serialization/vector.hpp>
41#ifdef DEAL_II_WITH_ZLIB
42# include <boost/iostreams/filter/gzip.hpp>
49template <
int dim,
typename Number>
88 template <
int dim,
typename Number>
89 std::vector<std::array<std::uint64_t, dim>>
92 const int bits_per_dim = 64);
98 std::vector<std::array<std::uint64_t, dim>>
100 const std::vector<std::array<std::uint64_t, dim>> &points,
101 const int bits_per_dim = 64);
121 const int bits_per_dim);
152 decompress(
const std::string &compressed_input);
168 encode_base64(
const std::vector<unsigned char> &binary_input);
178 std::vector<unsigned char>
217 template <
typename number>
237 template <
typename Number>
260 dim_string(
const int dim,
const int spacedim);
327 std::vector<std::string>
335 std::vector<std::string>
348 std::vector<std::string>
350 const unsigned int width,
351 const char delimiter =
' ');
368 std::pair<int, unsigned int>
377 const std::string &from,
378 const std::string &to);
386 trim(
const std::string &input);
455 template <
int N,
typename T>
466 template <
typename T,
typename = std::enable_if_t<std::is_arithmetic_v<T>>>
468 pow(
const T base,
const int iexp);
491 template <
typename Iterator,
typename T>
500 template <
typename Iterator,
typename T,
typename Comp>
509 template <
typename Integer>
518 template <
typename Integer>
576 template <
typename T>
578 pack(
const T &
object,
579 std::vector<char> &dest_buffer,
580 const bool allow_compression =
true);
590 template <
typename T>
592 pack(
const T &
object,
const bool allow_compression =
true);
625 template <
typename T>
627 unpack(
const std::vector<char> &buffer,
const bool allow_compression =
true);
637 template <
typename T>
640 const std::vector<char>::const_iterator &
cend,
641 const bool allow_compression =
true);
675 template <
typename T,
int N>
677 unpack(
const std::vector<char> &buffer,
678 T (&unpacked_object)[N],
679 const bool allow_compression =
true);
689 template <
typename T,
int N>
692 const std::vector<char>::const_iterator &
cend,
693 T (&unpacked_object)[N],
694 const bool allow_compression =
true);
700 get_bit(
const unsigned char number,
const unsigned int n);
707 set_bit(
unsigned char &number,
const unsigned int n,
const bool x);
767 template <
typename To,
typename From>
774 template <
typename T>
781 template <
typename T>
788 template <
typename T>
795 template <
typename T>
802 template <
typename T>
940 template <
int N,
typename T>
944 Assert(((std::is_integral_v<T> ==
true) && (N >= 0)) ||
945 (std::is_integral_v<T> ==
false),
946 ExcMessage(
"If the type of the argument, T, is an integer type, "
947 "then the exponent N must be a non-negative integer "
948 "because the result would otherwise not be an integer."));
958 return ((N % 2 == 1) ? x *
fixed_power<N / 2, T>(x * x) :
964 template <
typename T,
typename>
966 pow(
const T base,
const int iexp)
996 return boost::core::demangle(
typeid(t).name());
1001 template <
typename Iterator,
typename T>
1010 template <
typename Iterator,
typename T,
typename Comp>
1019 "The given iterators do not satisfy the proper ordering."));
1021 unsigned int len =
static_cast<unsigned int>(last -
first);
1038 if (!comp(*
first, val))
1043 if (!comp(*
first, val))
1048 if (!comp(*
first, val))
1053 if (!comp(*
first, val))
1058 if (!comp(*
first, val))
1063 if (!comp(*
first, val))
1068 if (!comp(*
first, val))
1087 const unsigned int half = len >> 1;
1088 const Iterator middle =
first + half;
1095 if (comp(*middle, val))
1115 template <
typename T>
1123 template <
typename T>
1127 std::is_trivially_copyable_v<T> && !std::is_same_v<T, bool>;
1132 template <
typename T>
1136 std::is_trivially_copyable_v<T> && !std::is_same_v<T, bool>;
1149 template <
typename T>
1152 std::vector<char> &)
1160 template <
typename T,
1161 typename = std::enable_if_t<!std::is_same_v<T, bool> &&
1162 std::is_trivially_copyable_v<T>>>
1165 const std::vector<T> &
object,
1166 std::vector<char> &dest_buffer)
1168 const typename std::vector<T>::size_type vector_size =
object.size();
1172 dest_buffer.reserve(dest_buffer.size() +
sizeof(vector_size) +
1173 vector_size *
sizeof(T));
1176 dest_buffer.insert(dest_buffer.end(),
1177 reinterpret_cast<const char *
>(&vector_size),
1178 reinterpret_cast<const char *
>(&vector_size + 1));
1181 if (vector_size > 0)
1182 dest_buffer.insert(dest_buffer.end(),
1183 reinterpret_cast<const char *
>(
object.data()),
1184 reinterpret_cast<const char *
>(
object.data() +
1190 template <
typename T,
1191 typename = std::enable_if_t<!std::is_same_v<T, bool> &&
1192 std::is_trivially_copyable_v<T>>>
1195 const std::vector<std::vector<T>> &
object,
1196 std::vector<char> &dest_buffer)
1198 using size_type =
typename std::vector<T>::size_type;
1199 const size_type vector_size =
object.size();
1201 typename std::vector<T>::size_type aggregated_size = 0;
1202 std::vector<size_type> sizes;
1203 sizes.reserve(vector_size);
1204 for (
const auto &a : object)
1206 aggregated_size += a.size();
1207 sizes.push_back(a.size());
1212 dest_buffer.reserve(dest_buffer.size() +
1213 sizeof(vector_size) * (1 + vector_size) +
1214 aggregated_size *
sizeof(T));
1217 dest_buffer.insert(dest_buffer.end(),
1218 reinterpret_cast<const char *
>(&vector_size),
1219 reinterpret_cast<const char *
>(&vector_size + 1));
1222 if (vector_size > 0)
1223 dest_buffer.insert(dest_buffer.end(),
1224 reinterpret_cast<const char *
>(sizes.data()),
1225 reinterpret_cast<const char *
>(sizes.data() +
1229 for (
const auto &a : object)
1230 dest_buffer.insert(dest_buffer.end(),
1231 reinterpret_cast<const char *
>(a.data()),
1232 reinterpret_cast<const char *
>(a.data() + a.size()));
1237 template <
typename T>
1240 const std::vector<char>::const_iterator &,
1241 const std::vector<char>::const_iterator &,
1250 template <
typename T,
1251 typename = std::enable_if_t<!std::is_same_v<T, bool> &&
1252 std::is_trivially_copyable_v<T>>>
1255 const std::vector<char>::const_iterator &
cbegin,
1256 const std::vector<char>::const_iterator &
cend,
1257 std::vector<T> &
object)
1263 typename std::vector<T>::size_type vector_size;
1264 std::memcpy(&vector_size, &*
cbegin,
sizeof(vector_size));
1267 static_cast<std::ptrdiff_t
>(
sizeof(vector_size) +
1268 vector_size *
sizeof(T)),
1269 ExcMessage(
"The given buffer has the wrong size."));
1290 object.resize(vector_size);
1291 if (vector_size > 0)
1292 std::memcpy(
object.
data(),
1293 &*
cbegin +
sizeof(vector_size),
1294 vector_size *
sizeof(T));
1299 template <
typename T,
1300 typename = std::enable_if_t<!std::is_same_v<T, bool> &&
1301 std::is_trivially_copyable_v<T>>>
1304 const std::vector<char>::const_iterator &
cbegin,
1305 const std::vector<char>::const_iterator &
cend,
1306 std::vector<std::vector<T>> &
object)
1309 using size_type =
typename std::vector<T>::size_type;
1311 size_type vector_size;
1312 std::memcpy(&vector_size, &*
iterator,
sizeof(vector_size));
1314 object.resize(vector_size);
1315 std::vector<size_type> sizes(vector_size);
1316 if (vector_size > 0)
1317 std::memcpy(sizes.data(),
1319 vector_size *
sizeof(size_type));
1321 iterator +=
sizeof(vector_size) * (1 + vector_size);
1322 size_type aggregated_size = 0;
1323 for (
const auto a : sizes)
1324 aggregated_size += a;
1327 static_cast<std::ptrdiff_t
>(aggregated_size *
sizeof(T)),
1328 ExcMessage(
"The given buffer has the wrong size."));
1334 for (
unsigned int i = 0; i < vector_size; ++i)
1337 object[i].resize(sizes[i]);
1338 std::memcpy(
object[i].
data(), &*
iterator, sizes[i] *
sizeof(T));
1343 ExcMessage(
"The given buffer has the wrong size."));
1350 template <
typename T>
1353 std::vector<char> &dest_buffer,
1354 const bool allow_compression)
1356 std::size_t
size = 0;
1362 if constexpr (std::is_trivially_copyable<T>() &&
sizeof(T) < 256)
1370 size = (std::is_same_v<T, std::tuple<>> ? 0 :
sizeof(T));
1372 (void)allow_compression;
1373 const std::size_t previous_size = dest_buffer.size();
1374 dest_buffer.resize(previous_size +
size);
1377 std::memcpy(dest_buffer.data() + previous_size, &
object,
size);
1385 (allow_compression ==
false))
1387 const std::size_t previous_size = dest_buffer.size();
1396 size = dest_buffer.size() - previous_size;
1402 const std::size_t previous_size = dest_buffer.size();
1404 boost::iostreams::filtering_ostreambuf fosb;
1405#ifdef DEAL_II_WITH_ZLIB
1406 if (allow_compression)
1407 fosb.push(boost::iostreams::gzip_compressor());
1409 (void)allow_compression;
1411 fosb.push(boost::iostreams::back_inserter(dest_buffer));
1413 boost::archive::binary_oarchive boa(fosb);
1418 size = dest_buffer.size() - previous_size;
1425 template <
typename T>
1427 pack(
const T &
object,
const bool allow_compression)
1429 std::vector<char> buffer;
1430 pack<T>(
object, buffer, allow_compression);
1436 template <
typename T>
1439 const std::vector<char>::const_iterator &
cend,
1440 const bool allow_compression)
1445 if constexpr (std::is_trivially_copyable<T>() &&
sizeof(T) < 256)
1453 const std::size_t
size =
1454 (std::is_same_v<T, std::tuple<>> ? 0 :
sizeof(T));
1458 (void)allow_compression;
1472 (allow_compression ==
false))
1487 boost::iostreams::filtering_istreambuf fisb;
1488#ifdef DEAL_II_WITH_ZLIB
1489 if (allow_compression)
1490 fisb.push(boost::iostreams::gzip_decompressor());
1492 (void)allow_compression;
1496 boost::archive::binary_iarchive bia(fisb);
1507 template <
typename T>
1509 unpack(
const std::vector<char> &buffer,
const bool allow_compression)
1511 return unpack<T>(buffer.cbegin(), buffer.cend(), allow_compression);
1515 template <
typename T,
int N>
1518 const std::vector<char>::const_iterator &
cend,
1519 T (&unpacked_object)[N],
1520 const bool allow_compression)
1525 if constexpr (std::is_trivially_copyable<T>() &&
sizeof(T) * N < 256)
1529 std::memcpy(unpacked_object, &*
cbegin,
sizeof(T) * N);
1534 boost::iostreams::filtering_istreambuf fisb;
1535#ifdef DEAL_II_WITH_ZLIB
1536 if (allow_compression)
1537 fisb.push(boost::iostreams::gzip_decompressor());
1539 (void)allow_compression;
1543 boost::archive::binary_iarchive bia(fisb);
1544 bia >> unpacked_object;
1549 template <
typename T,
int N>
1552 T (&unpacked_object)[N],
1553 const bool allow_compression)
1555 unpack<T, N>(buffer.cbegin(),
1564 get_bit(
const unsigned char number,
const unsigned int n)
1571 return ((number >> n) & 1U) != 0u;
1577 set_bit(
unsigned char &number,
const unsigned int n,
const bool x)
1584 number ^= (-
static_cast<unsigned char>(x) ^ number) & (1U << n);
1589 template <
typename To,
typename From>
1590 inline std::unique_ptr<To>
1596 if (To *cast =
dynamic_cast<To *
>(p.get()))
1598 std::unique_ptr<To> result(cast);
1603 throw std::bad_cast();
1608 template <
typename T>
1617 template <
typename T>
1626 template <
typename T>
1635 template <
typename T>
1644 template <
typename T>
1653 template <
typename Integer>
1654 std::vector<Integer>
1657 const std::size_t n = permutation.size();
1659 std::vector<Integer> out(n);
1660 for (std::size_t i = 0; i < n; ++i)
1661 out[i] = n - 1 - permutation[i];
1668 template <
typename Integer>
1669 std::vector<Integer>
1672 const std::size_t n = permutation.size();
1676 for (std::size_t i = 0; i < n; ++i)
1679 out[permutation[i]] = i;
1684 for (std::size_t i = 0; i < n; ++i)
1686 ExcMessage(
"The given input permutation had duplicate entries!"));
1698 namespace serialization
1705 template <
class Archive,
typename... Args>
1707 serialize(Archive &ar, std::tuple<Args...> &t,
const unsigned int version)
1709 ar &std::get<
N - 1>(t);
1710 Serialize<N - 1>::serialize(ar, t, version);
1717 template <
class Archive,
typename... Args>
1719 serialize(Archive &ar, std::tuple<Args...> &t,
const unsigned int version)
1727 template <
class Archive,
typename... Args>
1729 serialize(Archive &ar, std::tuple<Args...> &t,
const unsigned int version)
1731 Serialize<
sizeof...(Args)>
::serialize(ar, t, version);
* const_iterator cbegin() const
* const_iterator cend() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CXX20_REQUIRES(condition)
#define DEAL_II_HOST_DEVICE
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ASSERT_UNREACHABLE()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< index_type > data
* * * RotationFunction< dim, Number >::RotationFunction Number(dim)
void get_memory_stats(MemoryStats &stats)
std::string get_hostname()
void posix_memalign(void **memptr, std::size_t alignment, std::size_t size)
std::string get_current_vectorization_level()
void create_vector_of_trivially_copyable_from_buffer(const std::vector< char >::const_iterator &, const std::vector< char >::const_iterator &, T &)
void append_vector_of_trivially_copyable_to_buffer(const T &, std::vector< char > &)
std::size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
T & get_underlying_value(T &p)
Number truncate_to_n_digits(const Number number, const unsigned int n_digits)
std::string type_to_string(const T &t)
std::string dim_string(const int dim, const int spacedim)
std::uint64_t pack_integers(const std::array< std::uint64_t, dim > &index, const int bits_per_dim)
bool get_bit(const unsigned char number, const unsigned int n)
std::pair< int, unsigned int > get_integer_at_position(const std::string &name, const unsigned int position)
std::string encode_base64(const std::vector< unsigned char > &binary_input)
std::unique_ptr< To > dynamic_unique_cast(std::unique_ptr< From > &&p)
constexpr T fixed_power(const T t)
std::string replace_in_string(const std::string &input, const std::string &from, const std::string &to)
std::vector< unsigned char > decode_base64(const std::string &base64_input)
std::vector< std::string > break_text_into_lines(const std::string &original_text, const unsigned int width, const char delimiter=' ')
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
std::vector< std::array< std::uint64_t, dim > > inverse_Hilbert_space_filling_curve(const std::vector< Point< dim, Number > > &points, const int bits_per_dim=64)
std::string compress(const std::string &input)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
bool match_at_string_start(const std::string &name, const std::string &pattern)
T unpack(const std::vector< char > &buffer, const bool allow_compression=true)
std::string decompress(const std::string &compressed_input)
unsigned int needed_digits(const unsigned int max_number)
Iterator lower_bound(Iterator first, Iterator last, const T &val)
double string_to_double(const std::string &s)
std::string dealii_version_string()
void set_bit(unsigned char &number, const unsigned int n, const bool x)
constexpr T pow(const T base, const int iexp)
std::string trim(const std::string &input)
double generate_normal_random_number(const double a, const double sigma)
std::vector< Integer > reverse_permutation(const std::vector< Integer > &permutation)
std::vector< Integer > invert_permutation(const std::vector< Integer > &permutation)
int string_to_int(const std::string &s)
void serialize(Archive &ar, ::std_cxx26::inplace_vector< T, N > &t, const unsigned int file_version)
constexpr unsigned int invalid_unsigned_int
static constexpr bool value