libMesh
utility.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 #ifndef LIBMESH_UTILITY_H
20 #define LIBMESH_UTILITY_H
21 
22 // LibMesh includes
23 #include "libmesh/libmesh_common.h" // for Real
24 
25 // C++ includes
26 #include <string>
27 #include <vector>
28 #include <algorithm> // is_sorted, lower_bound
29 #include <memory> // unique_ptr
30 
31 namespace libMesh
32 {
33 
39 #define libmesh_map_find(map, key) libMesh::Utility::map_find((map), (key), __FILE__, __LINE__)
40 
46 #define libmesh_vector_at(vec, idx) libMesh::Utility::vector_at((vec), (idx), __FILE__, __LINE__)
47 
48 // ------------------------------------------------------------
49 // The Utility namespace is for functions
50 // which are useful but don't necessarily belong anywhere else.
51 
52 namespace Utility
53 {
54 
59 std::string system_info();
60 
64 template <typename T>
66 {
67  template <typename U> // must be template to get SFINAE fall-through...
68  static auto test(const U* u) -> decltype(std::cout << *u);
69 
70  static auto test(...) -> std::false_type;
71 
72 public:
74 };
75 
85 #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
86 #if (__GNUC__ > 12)
87 #pragma GCC diagnostic push
88 #pragma GCC diagnostic ignored "-Wdangling-reference"
89 #endif
90 #endif
91 
101 template<typename Map, typename Key,
102  typename std::enable_if<!is_streamable<Key>::value, Key>::type* = nullptr>
103 inline
104 typename Map::mapped_type &
105 map_find(Map & map,
106  const Key & key,
107  const char * filename,
108  int line_number)
109 {
110  auto it = map.find(key);
111  libmesh_error_msg_if(it == map.end(),
112  "map_find() error: key not found in file "
113  << filename << " on line " << line_number);
114  return it->second;
115 }
116 
120 template<typename Map, typename Key,
121  typename std::enable_if<!is_streamable<Key>::value, Key>::type* = nullptr>
122 inline
123 const typename Map::mapped_type &
124 map_find(const Map & map,
125  const Key & key,
126  const char * filename,
127  int line_number)
128 {
129  auto it = map.find(key);
130  libmesh_error_msg_if(it == map.end(),
131  "map_find() error: key not found in file "
132  << filename << " on line " << line_number);
133  return it->second;
134 }
135 
140 template<typename Map, typename Key,
141  typename std::enable_if<is_streamable<Key>::value, Key>::type* = nullptr>
142 inline
143 typename Map::mapped_type &
144 map_find(Map & map,
145  const Key & key,
146  const char * filename,
147  int line_number)
148 {
149  auto it = map.find(key);
150  libmesh_error_msg_if(it == map.end(),
151  "map_find() error: key \"" << key << "\" not found in file "
152  << filename << " on line " << line_number);
153  return it->second;
154 }
155 
159 template<typename Map, typename Key,
160  typename std::enable_if<is_streamable<Key>::value, Key>::type* = nullptr>
161 inline
162 const typename Map::mapped_type &
163 map_find(const Map & map,
164  const Key & key,
165  const char * filename,
166  int line_number)
167 {
168  auto it = map.find(key);
169  libmesh_error_msg_if(it == map.end(),
170  "map_find() error: key \"" << key << "\" not found in file "
171  << filename << " on line " << line_number);
172  return it->second;
173 }
174 
175 // The map_find functions are our only dangling-reference false positives
176 
177 #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
178 #if (__GNUC__ > 12)
179 #pragma GCC diagnostic pop
180 #endif
181 #endif
182 
183 
189 template<typename Vector>
190 inline
191 typename Vector::reference &
192 vector_at(Vector & vec,
193  typename Vector::size_type i,
194  const char * filename,
195  int line_number)
196 {
197  libmesh_error_msg_if(i >= vec.size(),
198  "vec_at() error: Index " << i <<
199  " past end of vector in file " << filename <<
200  " on line " << line_number);
201  return vec[i];
202 }
203 
207 template<typename Vector>
208 inline
209 typename Vector::const_reference &
210 vector_at(const Vector & vec,
211  typename Vector::size_type i,
212  const char * filename,
213  int line_number)
214 {
215  libmesh_error_msg_if(i >= vec.size(),
216  "vec_at() error: Index " << i <<
217  " past end of vector in file " << filename <<
218  " on line " << line_number);
219  return vec[i];
220 }
221 
222 
232 template<class ForwardIterator, class T>
233 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T & value)
234 {
235  ForwardIterator it = std::lower_bound(first, last, value);
236  return (it == last || value < *it) ? last : it;
237 }
238 
242 template<class ForwardIterator, class T, class Compare>
243 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T & value, Compare comp)
244 {
245  ForwardIterator it = std::lower_bound(first, last, value, comp);
246  return (it == last || comp(value,*it)) ? last : it;
247 }
248 
249 
254 template <int N, typename T>
255 struct do_pow {
256  static inline T apply (const T & x)
257  {
258  libmesh_assert(N>1);
259 
260  if (N%2) // odd exponent
261  return x * do_pow<N-1,T>::apply(x);
262 
263  const T xNover2 = do_pow<N/2,T>::apply(x);
264 
265  return xNover2*xNover2;
266  }
267 };
268 
269 // An efficient compiler would distill N=6 down to 3
270 // multiplications, but an inefficient one (or a complicated
271 // T::operator*) might do worse, so we'll specialize here.
272 template <typename T>
273 struct do_pow<6,T> {
274  static inline T apply (const T & x)
275  {
276  const T x2 = x*x,
277  x4 = x2*x2;
278 
279  return x4*x2;
280  }
281 };
282 
283 template <typename T>
284 struct do_pow<1,T> {
285  static inline T apply (const T & x) { return x; }
286 };
287 
288 template <typename T>
289 struct do_pow<0,T> {
290  static inline T apply (const T &) { return 1; }
291 };
292 
293 
294 template <int N, typename T>
295 inline
296 T pow(const T & x)
297 {
298  return do_pow<N,T>::apply(x);
299 }
300 
304 inline
305 unsigned int factorial(unsigned int n)
306 {
307 
308  unsigned int factorial_n = 1;
309 
310  if (n==0)
311  return factorial_n;
312 
313  for (unsigned int i=1; i<n; i++)
314  factorial_n *= i+1;
315 
316  return factorial_n;
317 }
318 
319 
320 // Simple function to compute "n choose k", aka the binomial coefficient.
321 template <typename T>
322 T binomial(T n, T k)
323 {
324  T ret = 1;
325 
326  // Binomial function is "symmetric" in k, C(n, k) = C(n, n-k).
327  if (k > n - k)
328  k = n - k;
329 
330  // Compute n * (n-1) * ... * (n-k+1) / (k * (k-1) * ... * 1)
331  for (T i = 0; i < k; ++i)
332  {
333  ret *= (n - i);
334  ret /= (i + 1);
335  }
336 
337  return ret;
338 }
339 
340 
344 template <typename T>
345 void deallocate (std::vector<T> & vec)
346 {
347  std::vector<T>().swap(vec);
348 }
349 
350 
351 // When looking for a complicated suffix to a filename, we only want
352 // to consider the base name, without any preceding path name.
353 // "/tmp/foo.e25ad0/mesh.msh" is not ExodusII.
354 std::string_view basename_of(const std::string & fullname);
355 
356 
360 bool contains(std::string_view superstring,
361  std::string_view substring);
362 
363 
367 bool ends_with(std::string_view superstring,
368  std::string_view suffix);
369 
370 
371 // Utility functions useful when dealing with complex numbers.
372 
373 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
374 
380 std::string complex_filename (std::string basename,
381  unsigned int r_o_c=0);
382 
386 void prepare_complex_data (const std::vector<Complex> & source,
387  std::vector<Real> & real_part,
388  std::vector<Real> & imag_part);
389 
390 #endif // #ifdef LIBMESH_USE_COMPLEX_NUMBERS
391 
392 
396 int mkdir(const char* pathname);
397 
398 
406 std::string unzip_file (std::string_view name);
407 
408 
418 {
419 public:
420 
425  explicit
426  ReverseBytes (const bool dr);
427 
432  template <typename T>
433  T operator () (T & data) const;
434 
435 private:
436 
440  bool reverse () const { return _do_reverse; }
441 
445  const bool _do_reverse;
446 };
447 
448 
449 
450 // ReverseBytes inline members
451 inline
452 ReverseBytes::ReverseBytes (const bool rb) :
453  _do_reverse (rb)
454 {}
455 
456 
457 template <typename T>
458 inline
459 T ReverseBytes::operator() (T & data) const
460 {
461  // Possibly reverse the byte ordering
462  if (this->reverse())
463  {
464  unsigned char * b = (unsigned char *) &data;
465 
466  int i=0;
467  int j=(sizeof(T) - 1);
468 
469  while (i < j)
470  {
471  std::swap (b[i], b[j]);
472  i++; j--;
473  }
474  }
475 
476  return data;
477 }
478 
479 
480 
486 {
492  using is_transparent = void;
493 
498  template <class T>
499  bool operator()(const std::unique_ptr<T> & a, const std::unique_ptr<T> & b) const
500  {
501  return a.get() < b.get();
502  }
503 
507  template <class T>
508  bool operator()(const std::unique_ptr<T> & a, const T * const & b) const
509  {
510  return a.get() < b;
511  }
512 
516  template <class T>
517  bool operator()(const T * const & a, const std::unique_ptr<T> & b) const
518  {
519  return a < b.get();
520  }
521 };
522 
523 } // namespace Utility
524 
525 } // namespace libMesh
526 
527 #endif // LIBMESH_UTILITY_H
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
This Functor simply takes an object and reverses its byte representation.
Definition: utility.h:417
const bool _do_reverse
flag
Definition: utility.h:445
Map::mapped_type & map_find(Map &map, const Key &key, const char *filename, int line_number)
-Wdangling-reference was nowhere near ready to add to -Wall in gcc 13.
Definition: utility.h:105
bool ends_with(std::string_view superstring, std::string_view suffix)
Look for a substring at the very end of a string.
Definition: utility.C:213
void deallocate(std::vector< T > &vec)
A convenient method to truly empty a vector using the "swap trick".
Definition: utility.h:345
Vector::reference & vector_at(Vector &vec, typename Vector::size_type i, const char *filename, int line_number)
A replacement for std::vector::at(i) which is meant to be used with a macro, and, unlike at()...
Definition: utility.h:192
void is_transparent
As of C++14, std::set::find() can be a templated overload.
Definition: utility.h:492
int mkdir(const char *pathname)
Create a directory.
Definition: utility.C:152
The libMesh namespace provides an interface to certain functionality in the library.
std::string system_info()
Definition: utility.C:63
static T apply(const T &)
Definition: utility.h:290
static T apply(const T &x)
Definition: utility.h:285
T pow(const T &x)
Definition: utility.h:296
T operator()(T &data) const
Functor.
Definition: utility.h:459
std::string unzip_file(std::string_view name)
Create an unzipped copy of a bz2 or xz file, returning the name of the now-unzipped file that can be ...
Definition: utility.C:164
libmesh_assert(ctx)
bool operator()(const std::unique_ptr< T > &a, const std::unique_ptr< T > &b) const
This is already what the default operator< comparison for std::unique_ptrs does, we are not adding an...
Definition: utility.h:499
void prepare_complex_data(const std::vector< Complex > &source, std::vector< Real > &real_part, std::vector< Real > &imag_part)
Prepare complex data for writing.
Definition: utility.C:133
std::string complex_filename(std::string basename, unsigned int r_o_c=0)
Definition: utility.C:119
bool contains(std::string_view superstring, std::string_view substring)
Look for a substring within a string.
Definition: utility.C:205
An efficient template instantiation for raising to an arbitrary integer power.
Definition: utility.h:255
static T apply(const T &x)
Definition: utility.h:256
bool operator()(const T *const &a, const std::unique_ptr< T > &b) const
operator< comparison when lhs is a dumb pointer
Definition: utility.h:517
static T apply(const T &x)
Definition: utility.h:274
bool operator()(const std::unique_ptr< T > &a, const T *const &b) const
operator< comparison when rhs is a dumb pointer
Definition: utility.h:508
std::string_view basename_of(const std::string &fullname)
Definition: utility.C:108
Struct which defines a custom comparison object that can be used with std::sets of std::unique_ptrs...
Definition: utility.h:485
static const Real b
unsigned int factorial(unsigned int n)
A simple implementation of the factorial.
Definition: utility.h:305
static const bool value
Definition: xdr_io.C:55
ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T &value)
The STL provides std::binary_search() which returns true or false depending on whether the searched-f...
Definition: utility.h:233
static auto test(const U *u) -> decltype(std::cout<< *u)
Helper struct for enabling template metaprogramming/SFINAE.
Definition: utility.h:65
ReverseBytes(const bool dr)
Constructor.
Definition: utility.h:452
T binomial(T n, T k)
Definition: utility.h:322