utility.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 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 
33 
34 // ------------------------------------------------------------
35 // The Utility namespace is for functions
36 // which are useful but don't necessarily belong anywhere else.
37 
38 namespace Utility
39 {
40  //-------------------------------------------------------------------
45  std::string system_info();
46 
47 
48 
49  //-------------------------------------------------------------------
57  template <typename ForwardIter, typename T>
58  void iota (ForwardIter first, ForwardIter last, T value)
59  {
60  while (first != last)
61  {
62  *first = value++;
63  ++first;
64  }
65  }
66 
67 
74  template< class InputIterator >
75  bool is_sorted(InputIterator first, InputIterator last)
76  {
77  if ( first == last )
78  return true;
79 
80  // "prev" always points to the entry just to the left of "first"
81  // [- - - - - -]
82  // ^ ^
83  // prev first
84  //
85  // [- - - - - -]
86  // ^ ^
87  // prev first
88  //
89  // [- - - - - -]
90  // ^ ^
91  // prev first
92  InputIterator prev( first );
93  for ( ++first; first != last; ++prev, ++first )
94  if ( *first < *prev ) // Note: this is the same as *prev > *first,
95  return false; // but we only require op< to be defined.
96 
97  // If we haven't returned yet, it's sorted!
98  return true;
99 
100 
101  // A one-liner version using adjacent_find. This doesn't work for
102  // C-style arrays, since their pointers do not have a value_type.
103  //
104  // Works by checking to see if adjacent entries satisfy *i >
105  // *(i+1) and returns the first one which does. If "last" is
106  // returned, no such pair was found, and therefore the range must
107  // be in non-decreasing order.
108  //
109  // return (last ==
110  // std::adjacent_find(first, last,
111  // std::greater< typename InputIterator::value_type >()));
112 
113  // A second one-linear attempt. This one checks for a **strictly
114  // increasing** (no duplicate entries) range. Also doesn't work
115  // with C-style arrays.
116  //
117  // return (last ==
118  // std::adjacent_find(first, last,
119  // std::not2(std::less<typename InputIterator::value_type>())));
120  }
121 
122 
129  template<class ForwardIterator, class T>
130  ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T& value)
131  {
132  ForwardIterator it = std::lower_bound(first, last, value);
133  return (it == last || value < *it) ? last : it;
134  }
135 
139  template<class ForwardIterator, class T, class Compare>
140  ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T& value, Compare comp)
141  {
142  ForwardIterator it = std::lower_bound(first, last, value, comp);
143  return (it == last || comp(value,*it)) ? last : it;
144  }
145 
146 
147  //-------------------------------------------------------------------
152  template <int N, typename T>
153  struct do_pow {
154  static inline T apply (const T& x)
155  {
156  libmesh_assert(N>1);
157 
158  if (N%2) // odd exponent
159  return x * do_pow<N-1,T>::apply(x);
160 
161  const T xNover2 = do_pow<N/2,T>::apply(x);
162 
163  return xNover2*xNover2;
164  }
165  };
166 
167  // An efficient compiler would distill N=6 down to 3
168  // multiplications, but an inefficient one (or a complicated
169  // T::operator*) might do worse, so we'll specialize here.
170  template <typename T>
171  struct do_pow<6,T> {
172  static inline T apply (const T& x)
173  {
174  const T x2 = x*x,
175  x4 = x2*x2;
176 
177  return x4*x2;
178  }
179  };
180 
181  template <typename T>
182  struct do_pow<1,T> {
183  static inline T apply (const T& x) { return x; }
184  };
185 
186  template <typename T>
187  struct do_pow<0,T> {
188  static inline T apply (const T&) { return 1; }
189  };
190 
191 
192  template <int N, typename T>
193  inline
194  T pow(const T& x)
195  {
196  return do_pow<N,T>::apply(x);
197  }
198 
199  //-------------------------------------------------------------------
203  inline
204  unsigned int factorial(unsigned int n)
205  {
206 
207  unsigned int factorial_n = 1;
208 
209  if (n==0)
210  return factorial_n;
211 
212  for (unsigned int i=1; i<n; i++)
213  factorial_n *= i+1;
214 
215  return factorial_n;
216  }
217 
218 
219  //-------------------------------------------------------------------
223  template <typename T>
224  void deallocate (std::vector<T> &vec)
225  {
226  std::vector<T>().swap(vec);
227  }
228 
229 
230  //-------------------------------------------------------------------
231  // Utility functions useful when dealing with complex numbers.
232 
233 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
234 
240  std::string complex_filename (const std::string& basename,
241  unsigned int r_o_c=0);
242 
246  void prepare_complex_data (const std::vector<Complex>& source,
247  std::vector<Real>& real_part,
248  std::vector<Real>& imag_part);
249 
250 #endif // #ifdef LIBMESH_USE_COMPLEX_NUMBERS
251 
252 
253 
254  //-------------------------------------------------------------------
264  {
265  public:
266 
271  explicit
272  ReverseBytes (const bool dr);
273 
278  template <typename T>
279  T operator () (T& data) const;
280 
281  private:
282 
286  bool reverse () const { return _do_reverse; }
287 
291  const bool _do_reverse;
292  };
293 
294 
295 
296  //---------------------------------------------------------
297  // ReverseBytes inline members
298  inline
299  ReverseBytes::ReverseBytes (const bool rb) :
300  _do_reverse (rb)
301  {}
302 
303 
304  template <typename T>
305  inline
307  {
308  // Possibly reverse the byte ordering
309  if (this->reverse())
310  {
311  unsigned char* b = (unsigned char*) &data;
312 
313  register int i=0;
314  register int j=(sizeof(T) - 1);
315 
316  while (i < j)
317  {
318  std::swap (b[i], b[j]);
319  i++; j--;
320  }
321  }
322 
323  return data;
324  }
325 
326 
327 }
328 
329 } // namespace libMesh
330 
331 #endif // LIBMESH_UTILITY_H

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:07 UTC

Hosted By:
SourceForge.net Logo