Reference documentation for deal.II version Git 082d75bebd 2019-10-16 19:44:02 +0200
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
utilities.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2005 - 2019 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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/config.h>
17 
18 // It's necessary to include winsock2.h before thread_local_storage.h,
19 // because Intel implementation of TBB includes winsock.h,
20 // and we'll get a conflict between winsock.h and winsock2.h otherwise.
21 #ifdef DEAL_II_MSVC
22 # include <winsock2.h>
23 #endif
24 
25 #include <deal.II/base/exceptions.h>
26 #include <deal.II/base/mpi.h>
27 #include <deal.II/base/point.h>
28 #include <deal.II/base/thread_local_storage.h>
29 #include <deal.II/base/utilities.h>
30 
31 #include <boost/lexical_cast.hpp>
32 #include <boost/random.hpp>
33 
34 #include <algorithm>
35 #include <bitset>
36 #include <cctype>
37 #include <cerrno>
38 #include <cmath>
39 #include <cstddef>
40 #include <cstdio>
41 #include <ctime>
42 #include <fstream>
43 #include <iomanip>
44 #include <iostream>
45 #include <limits>
46 #include <sstream>
47 
48 #if defined(DEAL_II_HAVE_UNISTD_H) && defined(DEAL_II_HAVE_GETHOSTNAME)
49 # include <unistd.h>
50 #endif
51 
52 #ifndef DEAL_II_MSVC
53 # include <cstdlib>
54 #endif
55 
56 
57 #ifdef DEAL_II_WITH_TRILINOS
58 # ifdef DEAL_II_WITH_MPI
59 # include <deal.II/lac/trilinos_parallel_block_vector.h>
60 # include <deal.II/lac/trilinos_vector.h>
61 # include <deal.II/lac/vector_memory.h>
62 
63 # include <Epetra_MpiComm.h>
64 # include <Teuchos_DefaultComm.hpp>
65 # endif
66 # include <Epetra_SerialComm.h>
67 # include <Teuchos_RCP.hpp>
68 #endif
69 
70 DEAL_II_NAMESPACE_OPEN
71 
72 
73 namespace Utilities
74 {
76  unsigned int,
77  unsigned int,
78  << "When trying to convert " << arg1 << " to a string with "
79  << arg2 << " digits");
80  DeclException1(ExcInvalidNumber, unsigned int, << "Invalid number " << arg1);
82  std::string,
83  << "Can't convert the string " << arg1
84  << " to the desired type");
85 
86 
87  std::string
89  {
90  return DEAL_II_PACKAGE_NAME " version " DEAL_II_PACKAGE_VERSION;
91  }
92 
93 
94  namespace
95  {
96  template <int dim,
97  typename Number,
98  int effective_dim,
99  typename LongDouble,
100  typename Integer>
101  std::vector<std::array<std::uint64_t, effective_dim>>
102  inverse_Hilbert_space_filling_curve_effective(
103  const std::vector<Point<dim, Number>> &points,
104  const Point<dim, Number> & bl,
105  const std::array<LongDouble, dim> & extents,
106  const std::bitset<dim> & valid_extents,
107  const int min_bits,
108  const Integer max_int)
109  {
110  std::vector<std::array<Integer, effective_dim>> int_points(points.size());
111 
112  for (unsigned int i = 0; i < points.size(); ++i)
113  {
114  // convert into integers:
115  unsigned int eff_d = 0;
116  for (unsigned int d = 0; d < dim; ++d)
117  if (valid_extents[d])
118  {
119  Assert(extents[d] > 0, ExcInternalError());
120  const LongDouble v = (static_cast<LongDouble>(points[i][d]) -
121  static_cast<LongDouble>(bl[d])) /
122  extents[d];
123  Assert(v >= 0. && v <= 1., ExcInternalError());
124  AssertIndexRange(eff_d, effective_dim);
125  int_points[i][eff_d] =
126  static_cast<Integer>(v * static_cast<LongDouble>(max_int));
127  ++eff_d;
128  }
129  }
130 
131  // note that we call this with "min_bits"
132  return inverse_Hilbert_space_filling_curve<effective_dim>(int_points,
133  min_bits);
134  }
135  } // namespace
136 
137  template <int dim, typename Number>
138  std::vector<std::array<std::uint64_t, dim>>
140  const std::vector<Point<dim, Number>> &points,
141  const int bits_per_dim)
142  {
143  using Integer = std::uint64_t;
144  // take floating point number hopefully with mantissa >= 64bit
145  using LongDouble = long double;
146 
147  // return if there is nothing to do
148  if (points.size() == 0)
149  return std::vector<std::array<std::uint64_t, dim>>();
150 
151  // get bounding box:
152  Point<dim, Number> bl = points[0], tr = points[0];
153  for (const auto &p : points)
154  for (unsigned int d = 0; d < dim; ++d)
155  {
156  const double cid = p[d];
157  bl[d] = std::min(cid, bl[d]);
158  tr[d] = std::max(cid, tr[d]);
159  }
160 
161  std::array<LongDouble, dim> extents;
162  std::bitset<dim> valid_extents;
163  for (unsigned int i = 0; i < dim; ++i)
164  {
165  extents[i] =
166  static_cast<LongDouble>(tr[i]) - static_cast<LongDouble>(bl[i]);
167  valid_extents[i] = (extents[i] > 0.);
168  }
169 
170  // make sure our conversion from fractional coordinates to
171  // Integers work as expected, namely our cast (LongDouble)max_int
172  const int min_bits =
173  std::min(bits_per_dim,
174  std::min(std::numeric_limits<Integer>::digits,
175  std::numeric_limits<LongDouble>::digits));
176 
177  // based on that get the maximum integer:
178  const Integer max_int = (min_bits == std::numeric_limits<Integer>::digits ?
179  std::numeric_limits<Integer>::max() :
180  (Integer(1) << min_bits) - 1);
181 
182  const unsigned int effective_dim = valid_extents.count();
183  if (effective_dim == dim)
184  {
185  return inverse_Hilbert_space_filling_curve_effective<dim,
186  Number,
187  dim,
188  LongDouble,
189  Integer>(
190  points, bl, extents, valid_extents, min_bits, max_int);
191  }
192 
193  // various degenerate cases
194  std::array<std::uint64_t, dim> zero_ind;
195  for (unsigned int d = 0; d < dim; ++d)
196  zero_ind[d] = 0;
197 
198  std::vector<std::array<std::uint64_t, dim>> ind(points.size(), zero_ind);
199  // manually check effective_dim == 1 and effective_dim == 2
200  if (dim == 3 && effective_dim == 2)
201  {
202  const auto ind2 =
203  inverse_Hilbert_space_filling_curve_effective<dim,
204  Number,
205  2,
206  LongDouble,
207  Integer>(
208  points, bl, extents, valid_extents, min_bits, max_int);
209 
210  for (unsigned int i = 0; i < ind.size(); ++i)
211  for (unsigned int d = 0; d < 2; ++d)
212  ind[i][d + 1] = ind2[i][d];
213 
214  return ind;
215  }
216  else if (effective_dim == 1)
217  {
218  const auto ind1 =
219  inverse_Hilbert_space_filling_curve_effective<dim,
220  Number,
221  1,
222  LongDouble,
223  Integer>(
224  points, bl, extents, valid_extents, min_bits, max_int);
225 
226  for (unsigned int i = 0; i < ind.size(); ++i)
227  ind[i][dim - 1] = ind1[i][0];
228 
229  return ind;
230  }
231 
232  // we should get here only if effective_dim == 0
233  Assert(effective_dim == 0, ExcInternalError());
234 
235  // if the bounding box is degenerate in all dimensions,
236  // can't do much but exit gracefully by setting index according
237  // to the index of each point so that there is no re-ordering
238  for (unsigned int i = 0; i < points.size(); ++i)
239  ind[i][dim - 1] = i;
240 
241  return ind;
242  }
243 
244 
245 
246  template <int dim>
247  std::vector<std::array<std::uint64_t, dim>>
249  const std::vector<std::array<std::uint64_t, dim>> &points,
250  const int bits_per_dim)
251  {
252  using Integer = std::uint64_t;
253 
254  std::vector<std::array<Integer, dim>> int_points(points);
255 
256  std::vector<std::array<Integer, dim>> res(int_points.size());
257 
258  // follow
259  // J. Skilling, Programming the Hilbert curve, AIP Conf. Proc. 707, 381
260  // (2004); http://dx.doi.org/10.1063/1.1751381 also see
261  // https://stackoverflow.com/questions/499166/mapping-n-dimensional-value-to-a-point-on-hilbert-curve
262  // https://gitlab.com/octopus-code/octopus/blob/develop/src/grid/hilbert.c
263  // https://github.com/trilinos/Trilinos/blob/master/packages/zoltan/src/hsfc/hsfc_hilbert.c
264  // (Zoltan_HSFC_InvHilbertXd)
265  // https://github.com/aditi137/Hilbert/blob/master/Hilbert/hilbert.cpp
266 
267  // now we can map to 1D coordinate stored in Transpose format
268  // adopt AxestoTranspose function from the paper, that
269  // transforms in-place between geometrical axes and Hilbert transpose.
270  // Example: b=5 bits for each of n=3 coordinates.
271  // 15-bit Hilbert integer = A B C D E F G H I J K L M N O is
272  // stored as its Transpose
273  // X[0] = A D G J M X[2]|
274  // X[1] = B E H K N <-------> | /X[1]
275  // X[2] = C F I L O axes |/
276  // high low 0------ X[0]
277 
278  // Depth of the Hilbert curve
279  Assert(bits_per_dim <= std::numeric_limits<Integer>::digits,
280  ExcMessage("This integer type can not hold " +
281  std::to_string(bits_per_dim) + " bits."));
282 
283  const Integer M = Integer(1) << (bits_per_dim - 1); // largest bit
284 
285  for (unsigned int index = 0; index < int_points.size(); ++index)
286  {
287  auto &X = int_points[index];
288  auto &L = res[index];
289 
290  // Inverse undo
291  for (Integer q = M; q > 1; q >>= 1)
292  {
293  const Integer p = q - 1;
294  for (unsigned int i = 0; i < dim; i++)
295  {
296  // invert
297  if (X[i] & q)
298  {
299  X[0] ^= p;
300  }
301  // exchange
302  else
303  {
304  const Integer t = (X[0] ^ X[i]) & p;
305  X[0] ^= t;
306  X[i] ^= t;
307  }
308  }
309  }
310 
311  // Gray encode (inverse of decode)
312  for (unsigned int i = 1; i < dim; i++)
313  X[i] ^= X[i - 1];
314 
315  Integer t = 0;
316  for (Integer q = M; q > 1; q >>= 1)
317  if (X[dim - 1] & q)
318  t ^= q - 1;
319  for (unsigned int i = 0; i < dim; i++)
320  X[i] ^= t;
321 
322  // now we need to go from index stored in transpose format to
323  // consecutive format, which is better suited for comparators.
324  // we could interleave into some big unsigned int...
325  // https://www.forceflow.be/2013/10/07/morton-encodingdecoding-through-bit-interleaving-implementations/
326  // https://stackoverflow.com/questions/4431522/given-2-16-bit-ints-can-i-interleave-those-bits-to-form-a-single-32-bit-int
327  // ...but we would loose spatial resolution!
328 
329  // interleave using brute force, follow TransposetoLine from
330  // https://github.com/aditi137/Hilbert/blob/master/Hilbert/hilbert.cpp
331  {
332  Integer p = M;
333  unsigned int j = 0;
334  for (unsigned int i = 0; i < dim; ++i)
335  {
336  L[i] = 0;
337  // go through bits using a mask q
338  for (Integer q = M; q > 0; q >>= 1)
339  {
340  if (X[j] & p)
341  L[i] |= q;
342  if (++j == dim)
343  {
344  j = 0;
345  p >>= 1;
346  }
347  }
348  }
349  }
350 
351  } // end of the loop over points
352 
353  return res;
354  }
355 
356 
357 
358  template <int dim>
359  std::uint64_t
360  pack_integers(const std::array<std::uint64_t, dim> &index,
361  const int bits_per_dim)
362  {
363  using Integer = std::uint64_t;
364 
365  AssertIndexRange(bits_per_dim * dim, 65);
366  Assert(bits_per_dim > 0, ExcMessage("bits_per_dim should be positive"));
367 
368  const Integer mask = (Integer(1) << bits_per_dim) - 1;
369 
370  Integer res = 0;
371  for (unsigned int i = 0; i < dim; ++i)
372  {
373  // take bits_per_dim from each integer and shift them
374  const Integer v = (mask & index[dim - 1 - i]) << (bits_per_dim * i);
375  res |= v;
376  }
377  return res;
378  }
379 
380 
381 
382  std::string
383  int_to_string(const unsigned int value, const unsigned int digits)
384  {
385  return to_string(value, digits);
386  }
387 
388 
389 
390  template <typename number>
391  std::string
392  to_string(const number value, const unsigned int digits)
393  {
394  std::string lc_string = boost::lexical_cast<std::string>(value);
395 
396  if (digits == numbers::invalid_unsigned_int)
397  return lc_string;
398  else if (lc_string.size() < digits)
399  {
400  // We have to add the padding zeroes in front of the number
401  const unsigned int padding_position = (lc_string[0] == '-') ? 1 : 0;
402 
403  const std::string padding(digits - lc_string.size(), '0');
404  lc_string.insert(padding_position, padding);
405  }
406  return lc_string;
407  }
408 
409 
410  std::string
411  replace_in_string(const std::string &input,
412  const std::string &from,
413  const std::string &to)
414  {
415  if (from.empty())
416  return input;
417 
418  std::string out = input;
419  std::string::size_type pos = out.find(from);
420 
421  while (pos != std::string::npos)
422  {
423  out.replace(pos, from.size(), to);
424  pos = out.find(from, pos + to.size());
425  }
426  return out;
427  }
428 
429  std::string
430  trim(const std::string &input)
431  {
432  std::string::size_type left = 0;
433  std::string::size_type right = input.size() > 0 ? input.size() - 1 : 0;
434 
435  for (; left < input.size(); ++left)
436  {
437  if (!std::isspace(input[left]))
438  {
439  break;
440  }
441  }
442 
443  for (; right >= left; --right)
444  {
445  if (!std::isspace(input[right]))
446  {
447  break;
448  }
449  }
450 
451  return std::string(input, left, right - left + 1);
452  }
453 
454 
455 
456  std::string
457  dim_string(const int dim, const int spacedim)
458  {
459  if (dim == spacedim)
460  return int_to_string(dim);
461  else
462  return int_to_string(dim) + "," + int_to_string(spacedim);
463  }
464 
465 
466  unsigned int
467  needed_digits(const unsigned int max_number)
468  {
469  if (max_number < 10)
470  return 1;
471  if (max_number < 100)
472  return 2;
473  if (max_number < 1000)
474  return 3;
475  if (max_number < 10000)
476  return 4;
477  if (max_number < 100000)
478  return 5;
479  if (max_number < 1000000)
480  return 6;
481  AssertThrow(false, ExcInvalidNumber(max_number));
482  return 0;
483  }
484 
485 
486 
487  int
488  string_to_int(const std::string &s_)
489  {
490  // trim whitespace on either side of the text if necessary
491  std::string s = s_;
492  while ((s.size() > 0) && (s[0] == ' '))
493  s.erase(s.begin());
494  while ((s.size() > 0) && (s[s.size() - 1] == ' '))
495  s.erase(s.end() - 1);
496 
497  // Now convert and see whether we succeed. Note that strtol only
498  // touches errno if an error occurred, so if we want to check
499  // whether an error happened, we need to make sure that errno==0
500  // before calling strtol since otherwise it may be that the
501  // conversion succeeds and that errno remains at the value it
502  // was before, whatever that was.
503  char *p;
504  errno = 0;
505  const int i = std::strtol(s.c_str(), &p, 10);
506 
507  // We have an error if one of the following conditions is true:
508  // - strtol sets errno != 0
509  // - The original string was empty (we could have checked that
510  // earlier already)
511  // - The string has non-zero length and strtol converted the
512  // first part to something useful, but stopped converting short
513  // of the terminating '\0' character. This happens, for example,
514  // if the given string is "1234 abc".
515  AssertThrow(!((errno != 0) || (s.size() == 0) ||
516  ((s.size() > 0) && (*p != '\0'))),
517  ExcMessage("Can't convert <" + s + "> to an integer."));
518 
519  return i;
520  }
521 
522 
523 
524  std::vector<int>
525  string_to_int(const std::vector<std::string> &s)
526  {
527  std::vector<int> tmp(s.size());
528  for (unsigned int i = 0; i < s.size(); ++i)
529  tmp[i] = string_to_int(s[i]);
530  return tmp;
531  }
532 
533 
534 
535  double
536  string_to_double(const std::string &s_)
537  {
538  // trim whitespace on either side of the text if necessary
539  std::string s = s_;
540  while ((s.size() > 0) && (s[0] == ' '))
541  s.erase(s.begin());
542  while ((s.size() > 0) && (s[s.size() - 1] == ' '))
543  s.erase(s.end() - 1);
544 
545  // Now convert and see whether we succeed. Note that strtol only
546  // touches errno if an error occurred, so if we want to check
547  // whether an error happened, we need to make sure that errno==0
548  // before calling strtol since otherwise it may be that the
549  // conversion succeeds and that errno remains at the value it
550  // was before, whatever that was.
551  char *p;
552  errno = 0;
553  const double d = std::strtod(s.c_str(), &p);
554 
555  // We have an error if one of the following conditions is true:
556  // - strtod sets errno != 0
557  // - The original string was empty (we could have checked that
558  // earlier already)
559  // - The string has non-zero length and strtod converted the
560  // first part to something useful, but stopped converting short
561  // of the terminating '\0' character. This happens, for example,
562  // if the given string is "1.234 abc".
563  AssertThrow(!((errno != 0) || (s.size() == 0) ||
564  ((s.size() > 0) && (*p != '\0'))),
565  ExcMessage("Can't convert <" + s + "> to a double."));
566 
567  return d;
568  }
569 
570 
571 
572  std::vector<double>
573  string_to_double(const std::vector<std::string> &s)
574  {
575  std::vector<double> tmp(s.size());
576  for (unsigned int i = 0; i < s.size(); ++i)
577  tmp[i] = string_to_double(s[i]);
578  return tmp;
579  }
580 
581 
582 
583  std::vector<std::string>
584  split_string_list(const std::string &s, const std::string &delimiter)
585  {
586  // keep the currently remaining part of the input string in 'tmp' and
587  // keep chopping elements of the list off the front
588  std::string tmp = s;
589 
590  // as discussed in the documentation, eat whitespace from the end
591  // of the string
592  while (tmp.length() != 0 && tmp[tmp.length() - 1] == ' ')
593  tmp.erase(tmp.length() - 1, 1);
594 
595  // split the input list until it is empty. since in every iteration
596  // 'tmp' is what's left of the string after the next delimiter,
597  // and since we've stripped trailing space already, 'tmp' will
598  // be empty at one point if 's' ended in a delimiter, even if
599  // there was space after the last delimiter. this matches what's
600  // discussed in the documentation
601  std::vector<std::string> split_list;
602  while (tmp.length() != 0)
603  {
604  std::string name;
605  name = tmp;
606 
607  if (name.find(delimiter) != std::string::npos)
608  {
609  name.erase(name.find(delimiter), std::string::npos);
610  tmp.erase(0, tmp.find(delimiter) + delimiter.size());
611  }
612  else
613  tmp = "";
614 
615  // strip spaces from this element's front and end
616  while ((name.length() != 0) && (name[0] == ' '))
617  name.erase(0, 1);
618  while (name.length() != 0 && name[name.length() - 1] == ' ')
619  name.erase(name.length() - 1, 1);
620 
621  split_list.push_back(name);
622  }
623 
624  return split_list;
625  }
626 
627 
628  std::vector<std::string>
629  split_string_list(const std::string &s, const char delimiter)
630  {
631  std::string d = ",";
632  d[0] = delimiter;
633  return split_string_list(s, d);
634  }
635 
636 
637  std::vector<std::string>
638  break_text_into_lines(const std::string &original_text,
639  const unsigned int width,
640  const char delimiter)
641  {
642  std::string text = original_text;
643  std::vector<std::string> lines;
644 
645  // remove trailing spaces
646  while ((text.length() != 0) && (text[text.length() - 1] == delimiter))
647  text.erase(text.length() - 1, 1);
648 
649  // then split the text into lines
650  while (text.length() != 0)
651  {
652  // in each iteration, first remove
653  // leading spaces
654  while ((text.length() != 0) && (text[0] == delimiter))
655  text.erase(0, 1);
656 
657  std::size_t pos_newline = text.find_first_of('\n', 0);
658  if (pos_newline != std::string::npos && pos_newline <= width)
659  {
660  std::string line(text, 0, pos_newline);
661  while ((line.length() != 0) &&
662  (line[line.length() - 1] == delimiter))
663  line.erase(line.length() - 1, 1);
664  lines.push_back(line);
665  text.erase(0, pos_newline + 1);
666  continue;
667  }
668 
669  // if we can fit everything into one
670  // line, then do so. otherwise, we have
671  // to keep breaking
672  if (text.length() < width)
673  {
674  // remove trailing spaces
675  while ((text.length() != 0) &&
676  (text[text.length() - 1] == delimiter))
677  text.erase(text.length() - 1, 1);
678  lines.push_back(text);
679  text = "";
680  }
681  else
682  {
683  // starting at position width, find the
684  // location of the previous space, so
685  // that we can break around there
686  int location = std::min<int>(width, text.length() - 1);
687  for (; location > 0; --location)
688  if (text[location] == delimiter)
689  break;
690 
691  // if there are no spaces, then try if
692  // there are spaces coming up
693  if (location == 0)
694  for (location = std::min<int>(width, text.length() - 1);
695  location < static_cast<int>(text.length());
696  ++location)
697  if (text[location] == delimiter)
698  break;
699 
700  // now take the text up to the found
701  // location and put it into a single
702  // line, and remove it from 'text'
703  std::string line(text, 0, location);
704  while ((line.length() != 0) &&
705  (line[line.length() - 1] == delimiter))
706  line.erase(line.length() - 1, 1);
707  lines.push_back(line);
708  text.erase(0, location);
709  }
710  }
711 
712  return lines;
713  }
714 
715 
716 
717  bool
718  match_at_string_start(const std::string &name, const std::string &pattern)
719  {
720  if (pattern.size() > name.size())
721  return false;
722 
723  for (unsigned int i = 0; i < pattern.size(); ++i)
724  if (pattern[i] != name[i])
725  return false;
726 
727  return true;
728  }
729 
730 
731 
732  std::pair<int, unsigned int>
733  get_integer_at_position(const std::string &name, const unsigned int position)
734  {
735  Assert(position < name.size(), ExcInternalError());
736 
737  const std::string test_string(name.begin() + position, name.end());
738 
739  std::istringstream str(test_string);
740 
741  int i;
742  if (str >> i)
743  {
744  // compute the number of
745  // digits of i. assuming it
746  // is less than 8 is likely
747  // ok
748  if (i < 10)
749  return std::make_pair(i, 1U);
750  else if (i < 100)
751  return std::make_pair(i, 2U);
752  else if (i < 1000)
753  return std::make_pair(i, 3U);
754  else if (i < 10000)
755  return std::make_pair(i, 4U);
756  else if (i < 100000)
757  return std::make_pair(i, 5U);
758  else if (i < 1000000)
759  return std::make_pair(i, 6U);
760  else if (i < 10000000)
761  return std::make_pair(i, 7U);
762  else
763  {
764  Assert(false, ExcNotImplemented());
765  return std::make_pair(-1, numbers::invalid_unsigned_int);
766  }
767  }
768  else
769  return std::make_pair(-1, numbers::invalid_unsigned_int);
770  }
771 
772 
773 
774  double
775  generate_normal_random_number(const double a, const double sigma)
776  {
777  // if no noise: return now
778  if (sigma == 0)
779  return a;
780 
781  // we would want to use rand(), but that function is not reentrant
782  // in a thread context. one could use rand_r, but this does not
783  // produce reproducible results between threads either (though at
784  // least it is reentrant). these two approaches being
785  // non-workable, use a thread-local random number generator here.
786  // we could use std::mt19937 but doing so results in compiler-dependent
787  // output.
788  static Threads::ThreadLocalStorage<boost::mt19937> random_number_generator;
789  return boost::normal_distribution<>(a,
790  sigma)(random_number_generator.get());
791  }
792 
793 
794 
795  std::vector<unsigned int>
796  reverse_permutation(const std::vector<unsigned int> &permutation)
797  {
798  const unsigned int n = permutation.size();
799 
800  std::vector<unsigned int> out(n);
801  for (unsigned int i = 0; i < n; ++i)
802  out[i] = n - 1 - permutation[i];
803 
804  return out;
805  }
806 
807 
808 
809  std::vector<unsigned int>
810  invert_permutation(const std::vector<unsigned int> &permutation)
811  {
812  const unsigned int n = permutation.size();
813 
814  std::vector<unsigned int> out(n, numbers::invalid_unsigned_int);
815 
816  for (unsigned int i = 0; i < n; ++i)
817  {
818  Assert(permutation[i] < n, ExcIndexRange(permutation[i], 0, n));
819  out[permutation[i]] = i;
820  }
821 
822  // check that we have actually reached
823  // all indices
824  for (unsigned int i = 0; i < n; ++i)
826  ExcMessage("The given input permutation had duplicate entries!"));
827 
828  return out;
829  }
830 
831  std::vector<unsigned long long int>
832  reverse_permutation(const std::vector<unsigned long long int> &permutation)
833  {
834  const unsigned long long int n = permutation.size();
835 
836  std::vector<unsigned long long int> out(n);
837  for (unsigned long long int i = 0; i < n; ++i)
838  out[i] = n - 1 - permutation[i];
839 
840  return out;
841  }
842 
843 
844 
845  std::vector<unsigned long long int>
846  invert_permutation(const std::vector<unsigned long long int> &permutation)
847  {
848  const unsigned long long int n = permutation.size();
849 
850  std::vector<unsigned long long int> out(n, numbers::invalid_unsigned_int);
851 
852  for (unsigned long long int i = 0; i < n; ++i)
853  {
854  Assert(permutation[i] < n, ExcIndexRange(permutation[i], 0, n));
855  out[permutation[i]] = i;
856  }
857 
858  // check that we have actually reached
859  // all indices
860  for (unsigned long long int i = 0; i < n; ++i)
862  ExcMessage("The given input permutation had duplicate entries!"));
863 
864  return out;
865  }
866 
867 
868  template <typename Integer>
869  std::vector<Integer>
870  reverse_permutation(const std::vector<Integer> &permutation)
871  {
872  const unsigned int n = permutation.size();
873 
874  std::vector<Integer> out(n);
875  for (unsigned int i = 0; i < n; ++i)
876  out[i] = n - 1 - permutation[i];
877 
878  return out;
879  }
880 
881 
882 
883  template <typename Integer>
884  std::vector<Integer>
885  invert_permutation(const std::vector<Integer> &permutation)
886  {
887  const unsigned int n = permutation.size();
888 
889  std::vector<Integer> out(n, numbers::invalid_unsigned_int);
890 
891  for (unsigned int i = 0; i < n; ++i)
892  {
893  Assert(permutation[i] < n, ExcIndexRange(permutation[i], 0, n));
894  out[permutation[i]] = i;
895  }
896 
897  // check that we have actually reached
898  // all indices
899  for (unsigned int i = 0; i < n; ++i)
901  ExcMessage("The given input permutation had duplicate entries!"));
902 
903  return out;
904  }
905 
906 
907 
908  namespace System
909  {
910 #if defined(__linux__)
911 
912  double
913  get_cpu_load()
914  {
915  std::ifstream cpuinfo;
916  cpuinfo.open("/proc/loadavg");
917 
918  AssertThrow(cpuinfo, ExcIO());
919 
920  double load;
921  cpuinfo >> load;
922 
923  return load;
924  }
925 
926 #else
927 
928  double
930  {
931  return 0.;
932  }
933 
934 #endif
935 
936  const std::string
938  {
939  switch (DEAL_II_COMPILER_VECTORIZATION_LEVEL)
940  {
941  case 0:
942  return "disabled";
943  case 1:
944 #ifdef __ALTIVEC__
945  return "AltiVec";
946 #else
947  return "SSE2";
948 #endif
949  case 2:
950  return "AVX";
951  case 3:
952  return "AVX512";
953  default:
954  AssertThrow(false,
956  "Invalid DEAL_II_COMPILER_VECTORIZATION_LEVEL."));
957  return "ERROR";
958  }
959  }
960 
961 
962  void
964  {
965  stats.VmPeak = stats.VmSize = stats.VmHWM = stats.VmRSS = 0;
966 
967  // parsing /proc/self/stat would be a
968  // lot easier, but it does not contain
969  // VmHWM, so we use /status instead.
970 #if defined(__linux__)
971  std::ifstream file("/proc/self/status");
972  std::string line;
973  std::string name;
974  while (!file.eof())
975  {
976  file >> name;
977  if (name == "VmPeak:")
978  file >> stats.VmPeak;
979  else if (name == "VmSize:")
980  file >> stats.VmSize;
981  else if (name == "VmHWM:")
982  file >> stats.VmHWM;
983  else if (name == "VmRSS:")
984  {
985  file >> stats.VmRSS;
986  break; // this is always the last entry
987  }
988 
989  getline(file, line);
990  }
991 #endif
992  }
993 
994 
995 
996  std::string
998  {
999 #if defined(DEAL_II_HAVE_UNISTD_H) && defined(DEAL_II_HAVE_GETHOSTNAME)
1000  const unsigned int N = 1024;
1001  char hostname[N];
1002  gethostname(&(hostname[0]), N - 1);
1003 #else
1004  std::string hostname("unknown");
1005 #endif
1006  return hostname;
1007  }
1008 
1009 
1010 
1011  std::string
1013  {
1014  std::time_t time1 = std::time(nullptr);
1015  std::tm * time = std::localtime(&time1);
1016 
1017  std::ostringstream o;
1018  o << time->tm_hour << ":" << (time->tm_min < 10 ? "0" : "")
1019  << time->tm_min << ":" << (time->tm_sec < 10 ? "0" : "")
1020  << time->tm_sec;
1021 
1022  return o.str();
1023  }
1024 
1025 
1026 
1027  std::string
1029  {
1030  std::time_t time1 = std::time(nullptr);
1031  std::tm * time = std::localtime(&time1);
1032 
1033  std::ostringstream o;
1034  o << time->tm_year + 1900 << "/" << time->tm_mon + 1 << "/"
1035  << time->tm_mday;
1036 
1037  return o.str();
1038  }
1039 
1040 
1041 
1042  void
1043  posix_memalign(void **memptr, std::size_t alignment, std::size_t size)
1044  {
1045 #ifndef DEAL_II_MSVC
1046  const int ierr = ::posix_memalign(memptr, alignment, size);
1047 
1048  AssertThrow(ierr == 0, ExcOutOfMemory());
1049  AssertThrow(*memptr != nullptr, ExcOutOfMemory());
1050 #else
1051  // Windows does not appear to have posix_memalign. just use the
1052  // regular malloc in that case
1053  *memptr = malloc(size);
1054  (void)alignment;
1055  AssertThrow(*memptr != 0, ExcOutOfMemory());
1056 #endif
1057  }
1058 
1059 
1060 
1061  bool
1062  job_supports_mpi()
1063  {
1065  }
1066  } // namespace System
1067 
1068 
1069 #ifdef DEAL_II_WITH_TRILINOS
1070 
1071  namespace Trilinos
1072  {
1073  const Epetra_Comm &
1075  {
1076 # ifdef DEAL_II_WITH_MPI
1077  static Teuchos::RCP<Epetra_MpiComm> communicator =
1078  Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD), true);
1079 # else
1080  static Teuchos::RCP<Epetra_SerialComm> communicator =
1081  Teuchos::rcp(new Epetra_SerialComm(), true);
1082 # endif
1083 
1084  return *communicator;
1085  }
1086 
1087 
1088 
1089  const Teuchos::RCP<const Teuchos::Comm<int>> &
1091  {
1092 # ifdef DEAL_II_WITH_MPI
1093  static auto communicator = Teuchos::RCP<const Teuchos::Comm<int>>(
1094  new Teuchos::MpiComm<int>(MPI_COMM_SELF));
1095 # else
1096  static auto communicator =
1097  Teuchos::RCP<const Teuchos::Comm<int>>(new Teuchos::Comm<int>());
1098 # endif
1099 
1100  return communicator;
1101  }
1102 
1103 
1104 
1105  const Epetra_Comm &
1107  {
1108 # ifdef DEAL_II_WITH_MPI
1109  static Teuchos::RCP<Epetra_MpiComm> communicator =
1110  Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_SELF), true);
1111 # else
1112  static Teuchos::RCP<Epetra_SerialComm> communicator =
1113  Teuchos::rcp(new Epetra_SerialComm(), true);
1114 # endif
1115 
1116  return *communicator;
1117  }
1118 
1119 
1120 
1121  Epetra_Comm *
1122  duplicate_communicator(const Epetra_Comm &communicator)
1123  {
1124 # ifdef DEAL_II_WITH_MPI
1125 
1126  // see if the communicator is in fact a
1127  // parallel MPI communicator; if so,
1128  // return a duplicate of it
1129  const Epetra_MpiComm *mpi_comm =
1130  dynamic_cast<const Epetra_MpiComm *>(&communicator);
1131  if (mpi_comm != nullptr)
1132  return new Epetra_MpiComm(
1133  Utilities::MPI::duplicate_communicator(mpi_comm->GetMpiComm()));
1134 # endif
1135 
1136  // if we don't support MPI, or if the
1137  // communicator in question was in fact
1138  // not an MPI communicator, return a
1139  // copy of the same object again
1140  Assert(dynamic_cast<const Epetra_SerialComm *>(&communicator) != nullptr,
1141  ExcInternalError());
1142  return new Epetra_SerialComm(
1143  dynamic_cast<const Epetra_SerialComm &>(communicator));
1144  }
1145 
1146 
1147 
1148  void
1149  destroy_communicator(Epetra_Comm &communicator)
1150  {
1151  // save the communicator, reset the map, and delete the communicator if
1152  // this whole thing was created as an MPI communicator
1153 # ifdef DEAL_II_WITH_MPI
1154  Epetra_MpiComm *mpi_comm = dynamic_cast<Epetra_MpiComm *>(&communicator);
1155  if (mpi_comm != nullptr)
1156  {
1157  MPI_Comm comm = mpi_comm->GetMpiComm();
1158  *mpi_comm = Epetra_MpiComm(MPI_COMM_SELF);
1159  const int ierr = MPI_Comm_free(&comm);
1160  AssertThrowMPI(ierr);
1161  }
1162 # endif
1163  }
1164 
1165 
1166 
1167  unsigned int
1168  get_n_mpi_processes(const Epetra_Comm &mpi_communicator)
1169  {
1170  return mpi_communicator.NumProc();
1171  }
1172 
1173 
1174  unsigned int
1175  get_this_mpi_process(const Epetra_Comm &mpi_communicator)
1176  {
1177  return static_cast<unsigned int>(mpi_communicator.MyPID());
1178  }
1179 
1180 
1181 
1182  Epetra_Map
1183  duplicate_map(const Epetra_BlockMap &map, const Epetra_Comm &comm)
1184  {
1185  if (map.LinearMap() == true)
1186  {
1187  // each processor stores a
1188  // contiguous range of
1189  // elements in the
1190  // following constructor
1191  // call
1192  return Epetra_Map(map.NumGlobalElements(),
1193  map.NumMyElements(),
1194  map.IndexBase(),
1195  comm);
1196  }
1197  else
1198  {
1199  // the range is not
1200  // contiguous
1201  return Epetra_Map(map.NumGlobalElements(),
1202  map.NumMyElements(),
1203  map.MyGlobalElements(),
1204  0,
1205  comm);
1206  }
1207  }
1208  } // namespace Trilinos
1209 
1210 #endif
1211 
1212  template std::string
1213  to_string<int>(int, unsigned int);
1214  template std::string
1215  to_string<long int>(long int, unsigned int);
1216  template std::string
1217  to_string<long long int>(long long int, unsigned int);
1218  template std::string
1219  to_string<unsigned int>(unsigned int, unsigned int);
1220  template std::string
1221  to_string<unsigned long int>(unsigned long int, unsigned int);
1222  template std::string
1223  to_string<unsigned long long int>(unsigned long long int, unsigned int);
1224  template std::string
1225  to_string<float>(float, unsigned int);
1226  template std::string
1227  to_string<double>(double, unsigned int);
1228  template std::string
1229  to_string<long double>(long double, unsigned int);
1230 
1231  template std::vector<std::array<std::uint64_t, 1>>
1232  inverse_Hilbert_space_filling_curve<1, double>(
1233  const std::vector<Point<1, double>> &,
1234  const int);
1235  template std::vector<std::array<std::uint64_t, 1>>
1236  inverse_Hilbert_space_filling_curve<1>(
1237  const std::vector<std::array<std::uint64_t, 1>> &,
1238  const int);
1239  template std::vector<std::array<std::uint64_t, 2>>
1240  inverse_Hilbert_space_filling_curve<2, double>(
1241  const std::vector<Point<2, double>> &,
1242  const int);
1243  template std::vector<std::array<std::uint64_t, 2>>
1244  inverse_Hilbert_space_filling_curve<2>(
1245  const std::vector<std::array<std::uint64_t, 2>> &,
1246  const int);
1247  template std::vector<std::array<std::uint64_t, 3>>
1248  inverse_Hilbert_space_filling_curve<3, double>(
1249  const std::vector<Point<3, double>> &,
1250  const int);
1251  template std::vector<std::array<std::uint64_t, 3>>
1252  inverse_Hilbert_space_filling_curve<3>(
1253  const std::vector<std::array<std::uint64_t, 3>> &,
1254  const int);
1255 
1256  template std::uint64_t
1257  pack_integers<1>(const std::array<std::uint64_t, 1> &, const int);
1258  template std::uint64_t
1259  pack_integers<2>(const std::array<std::uint64_t, 2> &, const int);
1260  template std::uint64_t
1261  pack_integers<3>(const std::array<std::uint64_t, 3> &, const int);
1262 } // namespace Utilities
1263 
1264 DEAL_II_NAMESPACE_CLOSE
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition: utilities.cc:584
void posix_memalign(void **memptr, std::size_t alignment, std::size_t size)
Definition: utilities.cc:1043
static const unsigned int invalid_unsigned_int
Definition: types.h:187
std::uint64_t pack_integers(const std::array< std::uint64_t, dim > &index, const int bits_per_dim)
Definition: utilities.cc:360
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:541
A class that provides a separate storage location on each thread that accesses the object...
static ::ExceptionBase & ExcIO()
std::string dealii_version_string()
Definition: utilities.cc:88
unsigned int get_n_mpi_processes(const Epetra_Comm &mpi_communicator)
Definition: utilities.cc:1168
std::string trim(const std::string &input)
Definition: utilities.cc:430
#define AssertIndexRange(index, range)
Definition: exceptions.h:1637
std::pair< int, unsigned int > get_integer_at_position(const std::string &name, const unsigned int position)
Definition: utilities.cc:733
std::vector< std::string > break_text_into_lines(const std::string &original_text, const unsigned int width, const char delimiter=' ')
Definition: utilities.cc:638
#define AssertThrow(cond, exc)
Definition: exceptions.h:1519
static ::ExceptionBase & ExcOutOfMemory()
const Epetra_Comm & comm_self()
Definition: utilities.cc:1106
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
Definition: point.h:110
std::string get_date()
Definition: utilities.cc:1028
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:392
void get_memory_stats(MemoryStats &stats)
Definition: utilities.cc:963
double string_to_double(const std::string &s)
Definition: utilities.cc:536
double get_cpu_load()
Definition: utilities.cc:929
const Teuchos::RCP< const Teuchos::Comm< int > > & tpetra_comm_self()
Definition: utilities.cc:1090
static ::ExceptionBase & ExcMessage(std::string arg1)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:518
double generate_normal_random_number(const double a, const double sigma)
Definition: utilities.cc:775
#define Assert(cond, exc)
Definition: exceptions.h:1407
unsigned long int VmSize
Definition: utilities.h:822
static ::ExceptionBase & ExcCantConvertString(std::string arg1)
static ::ExceptionBase & ExcInvalidNumber(unsigned int arg1)
bool match_at_string_start(const std::string &name, const std::string &pattern)
Definition: utilities.cc:718
std::vector< unsigned int > invert_permutation(const std::vector< unsigned int > &permutation)
Definition: utilities.cc:810
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:383
std::string replace_in_string(const std::string &input, const std::string &from, const std::string &to)
Definition: utilities.cc:411
std::string dim_string(const int dim, const int spacedim)
Definition: utilities.cc:457
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)
Definition: utilities.cc:139
void destroy_communicator(Epetra_Comm &communicator)
Definition: utilities.cc:1149
Definition: cuda.h:31
std::string get_hostname()
Definition: utilities.cc:997
#define AssertThrowMPI(error_code)
Definition: exceptions.h:1695
MPI_Comm duplicate_communicator(const MPI_Comm &mpi_communicator)
Definition: mpi.cc:96
unsigned long int VmHWM
Definition: utilities.h:827
const Epetra_Comm & comm_world()
Definition: utilities.cc:1074
int string_to_int(const std::string &s)
Definition: utilities.cc:488
std::vector< unsigned int > reverse_permutation(const std::vector< unsigned int > &permutation)
Definition: utilities.cc:796
static ::ExceptionBase & ExcNotImplemented()
unsigned long int VmRSS
Definition: utilities.h:833
unsigned int get_this_mpi_process(const Epetra_Comm &mpi_communicator)
Definition: utilities.cc:1175
const std::string get_current_vectorization_level()
Definition: utilities.cc:937
Epetra_Map duplicate_map(const Epetra_BlockMap &map, const Epetra_Comm &comm)
Definition: utilities.cc:1183
std::string get_time()
Definition: utilities.cc:1012
bool job_supports_mpi()
Definition: mpi.cc:810
unsigned long int VmPeak
Definition: utilities.h:817
unsigned int needed_digits(const unsigned int max_number)
Definition: utilities.cc:467
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcInvalidNumber2StringConversersion(unsigned int arg1, unsigned int arg2)