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