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