libMesh
utility.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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 // Local includes
23 #include "libmesh/libmesh_common.h" // for Real
24 
25 // System includes
26 #include <string>
27 #include <vector>
28 #include <algorithm> // for std::lower_bound
29 
30 namespace libMesh
31 {
32 
38 #define libmesh_map_find(map, key) Utility::map_find((map), (key), __FILE__, __LINE__)
39 
40 // ------------------------------------------------------------
41 // The Utility namespace is for functions
42 // which are useful but don't necessarily belong anywhere else.
43 
44 namespace Utility
45 {
46 
51 std::string system_info();
52 
53 
63 template<typename Map>
64 inline
65 typename Map::mapped_type &
66 map_find(Map & map,
67  const typename Map::key_type & key,
68  const char * filename,
69  int line_number)
70 {
71  auto it = map.find(key);
72  if (it == map.end())
73  libmesh_error_msg("map_find() error: key not found in file " \
74  << filename << " on line " << line_number);
75  return it->second;
76 }
77 
81 template<typename Map>
82 inline
83 const typename Map::mapped_type &
84 map_find(const Map & map,
85  const typename Map::key_type & key,
86  const char * filename,
87  int line_number)
88 {
89  auto it = map.find(key);
90  if (it == map.end())
91  libmesh_error_msg("map_find() error: key not found in file " \
92  << filename << " on line " << line_number);
93  return it->second;
94 }
95 
96 
104 template <typename ForwardIter, typename T>
105 void iota (ForwardIter first, ForwardIter last, T value)
106 {
107  // Use std::iota instead!
108  libmesh_deprecated();
109 
110  while (first != last)
111  {
112  *first = value++;
113  ++first;
114  }
115 }
116 
117 
124 template<class InputIterator >
125 bool is_sorted(InputIterator first, InputIterator last)
126 {
127  if (first == last)
128  return true;
129 
130  // "prev" always points to the entry just to the left of "first"
131  // [- - - - - -]
132  // ^ ^
133  // prev first
134  //
135  // [- - - - - -]
136  // ^ ^
137  // prev first
138  //
139  // [- - - - - -]
140  // ^ ^
141  // prev first
142  InputIterator prev( first );
143  for (++first; first != last; ++prev, ++first)
144  if (*first < *prev) // Note: this is the same as *prev > *first,
145  return false; // but we only require op< to be defined.
146 
147  // If we haven't returned yet, it's sorted!
148  return true;
149 
150 
151  // A one-liner version using adjacent_find. This doesn't work for
152  // C-style arrays, since their pointers do not have a value_type.
153  //
154  // Works by checking to see if adjacent entries satisfy *i >
155  // *(i+1) and returns the first one which does. If "last" is
156  // returned, no such pair was found, and therefore the range must
157  // be in non-decreasing order.
158  //
159  // return (last ==
160  // std::adjacent_find(first, last,
161  // std::greater<typename InputIterator::value_type >()));
162 
163  // A second one-linear attempt. This one checks for a **strictly
164  // increasing** (no duplicate entries) range. Also doesn't work
165  // with C-style arrays.
166  //
167  // return (last ==
168  // std::adjacent_find(first, last,
169  // std::not2(std::less<typename InputIterator::value_type>())));
170 }
171 
172 
182 template<class ForwardIterator, class T>
183 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T & value)
184 {
185  ForwardIterator it = std::lower_bound(first, last, value);
186  return (it == last || value < *it) ? last : it;
187 }
188 
192 template<class ForwardIterator, class T, class Compare>
193 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T & value, Compare comp)
194 {
195  ForwardIterator it = std::lower_bound(first, last, value, comp);
196  return (it == last || comp(value,*it)) ? last : it;
197 }
198 
199 
204 template <int N, typename T>
205 struct do_pow {
206  static inline T apply (const T & x)
207  {
208  libmesh_assert(N>1);
209 
210  if (N%2) // odd exponent
211  return x * do_pow<N-1,T>::apply(x);
212 
213  const T xNover2 = do_pow<N/2,T>::apply(x);
214 
215  return xNover2*xNover2;
216  }
217 };
218 
219 // An efficient compiler would distill N=6 down to 3
220 // multiplications, but an inefficient one (or a complicated
221 // T::operator*) might do worse, so we'll specialize here.
222 template <typename T>
223 struct do_pow<6,T> {
224  static inline T apply (const T & x)
225  {
226  const T x2 = x*x,
227  x4 = x2*x2;
228 
229  return x4*x2;
230  }
231 };
232 
233 template <typename T>
234 struct do_pow<1,T> {
235  static inline T apply (const T & x) { return x; }
236 };
237 
238 template <typename T>
239 struct do_pow<0,T> {
240  static inline T apply (const T &) { return 1; }
241 };
242 
243 
244 template <int N, typename T>
245 inline
246 T pow(const T & x)
247 {
248  return do_pow<N,T>::apply(x);
249 }
250 
254 inline
255 unsigned int factorial(unsigned int n)
256 {
257 
258  unsigned int factorial_n = 1;
259 
260  if (n==0)
261  return factorial_n;
262 
263  for (unsigned int i=1; i<n; i++)
264  factorial_n *= i+1;
265 
266  return factorial_n;
267 }
268 
269 
270 // Simple function to compute "n choose k", aka the binomial coefficient.
271 template <typename T>
272 T binomial(T n, T k)
273 {
274  T ret = 1;
275 
276  // Binomial function is "symmetric" in k, C(n, k) = C(n, n-k).
277  if (k > n - k)
278  k = n - k;
279 
280  // Compute n * (n-1) * ... * (n-k+1) / (k * (k-1) * ... * 1)
281  for (T i = 0; i < k; ++i)
282  {
283  ret *= (n - i);
284  ret /= (i + 1);
285  }
286 
287  return ret;
288 }
289 
290 
294 template <typename T>
295 void deallocate (std::vector<T> & vec)
296 {
297  std::vector<T>().swap(vec);
298 }
299 
300 
301 // Utility functions useful when dealing with complex numbers.
302 
303 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
304 
310 std::string complex_filename (const std::string & basename,
311  unsigned int r_o_c=0);
312 
316 void prepare_complex_data (const std::vector<Complex> & source,
317  std::vector<Real> & real_part,
318  std::vector<Real> & imag_part);
319 
320 #endif // #ifdef LIBMESH_USE_COMPLEX_NUMBERS
321 
322 
326 int mkdir(const char* pathname);
327 
328 
338 {
339 public:
340 
345  explicit
346  ReverseBytes (const bool dr);
347 
352  template <typename T>
353  T operator () (T & data) const;
354 
355 private:
356 
360  bool reverse () const { return _do_reverse; }
361 
365  const bool _do_reverse;
366 };
367 
368 
369 
370 // ReverseBytes inline members
371 inline
372 ReverseBytes::ReverseBytes (const bool rb) :
373  _do_reverse (rb)
374 {}
375 
376 
377 template <typename T>
378 inline
380 {
381  // Possibly reverse the byte ordering
382  if (this->reverse())
383  {
384  unsigned char * b = (unsigned char *) &data;
385 
386  int i=0;
387  int j=(sizeof(T) - 1);
388 
389  while (i < j)
390  {
391  std::swap (b[i], b[j]);
392  i++; j--;
393  }
394  }
395 
396  return data;
397 }
398 
399 
400 }
401 
402 } // namespace libMesh
403 
404 #endif // LIBMESH_UTILITY_H
libMesh::Utility::map_find
Map::mapped_type & map_find(Map &map, const typename Map::key_type &key, const char *filename, int line_number)
This function should not be called directly (although it can be), instead see the libmesh_map_find() ...
Definition: utility.h:66
libMesh::Utility::binomial
T binomial(T n, T k)
Definition: utility.h:272
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::Utility::ReverseBytes::ReverseBytes
ReverseBytes(const bool dr)
Constructor.
Definition: utility.h:372
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::Utility::do_pow::apply
static T apply(const T &x)
Definition: utility.h:206
libMesh::Utility::iota
void iota(ForwardIter first, ForwardIter last, T value)
Utility::iota is a duplication of the SGI STL extension std::iota.
Definition: utility.h:105
libMesh::Utility::prepare_complex_data
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:121
libMesh::Utility::binary_find
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:183
libMesh::Utility::do_pow
An efficient template instantiation for raising to an arbitrary integer power.
Definition: utility.h:205
libMesh::Utility::do_pow< 1, T >::apply
static T apply(const T &x)
Definition: utility.h:235
libMesh::Utility::do_pow< 6, T >::apply
static T apply(const T &x)
Definition: utility.h:224
libMesh::Utility::ReverseBytes
This Functor simply takes an object and reverses its byte representation.
Definition: utility.h:337
libMesh::Utility::mkdir
int mkdir(const char *pathname)
Create a directory.
Definition: utility.C:140
libMesh::Utility::pow
T pow(const T &x)
Definition: utility.h:246
swap
void swap(Iterator &lhs, Iterator &rhs)
swap, used to implement op=
Definition: variant_filter_iterator.h:478
libMesh::Utility::ReverseBytes::_do_reverse
const bool _do_reverse
flag
Definition: utility.h:365
value
static const bool value
Definition: xdr_io.C:56
libMesh::Utility::is_sorted
bool is_sorted(InputIterator first, InputIterator last)
Utility::is_sorted mimics the behavior of the SGI STL extension std::is_sorted.
Definition: utility.h:125
libMesh::Utility::factorial
unsigned int factorial(unsigned int n)
A simple implementation of the factorial.
Definition: utility.h:255
libMesh::Utility::do_pow< 0, T >::apply
static T apply(const T &)
Definition: utility.h:240
data
IterBase * data
Ideally this private member data should have protected access.
Definition: variant_filter_iterator.h:337
libMesh::Utility::deallocate
void deallocate(std::vector< T > &vec)
A convenient method to truly empty a vector using the "swap trick".
Definition: utility.h:295
libMesh::MeshTools::Subdivision::prev
static const unsigned int prev[3]
A lookup table for the decrement modulo 3 operation, for iterating through the three nodes per elemen...
Definition: mesh_subdivision_support.h:108
libMesh::Utility::ReverseBytes::operator()
T operator()(T &data) const
Functor.
Definition: utility.h:379
libMesh::Utility::ReverseBytes::reverse
bool reverse() const
Definition: utility.h:360
libMesh::Utility::complex_filename
std::string complex_filename(const std::string &basename, unsigned int r_o_c=0)
Definition: utility.C:105
libMesh::Utility::system_info
std::string system_info()
Definition: utility.C:57