utility.h
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 #ifndef LIBMESH_UTILITY_H 00020 #define LIBMESH_UTILITY_H 00021 00022 // Local includes 00023 #include "libmesh/libmesh_common.h" // for Real 00024 00025 // System includes 00026 #include <string> 00027 #include <vector> 00028 #include <algorithm> // for std::lower_bound 00029 00030 namespace libMesh 00031 { 00032 00033 00034 // ------------------------------------------------------------ 00035 // The Utility namespace is for functions 00036 // which are useful but don't necessarily belong anywhere else. 00037 00038 namespace Utility 00039 { 00040 //------------------------------------------------------------------- 00045 std::string system_info(); 00046 00047 00048 00049 //------------------------------------------------------------------- 00057 template <typename ForwardIter, typename T> 00058 void iota (ForwardIter first, ForwardIter last, T value) 00059 { 00060 while (first != last) 00061 { 00062 *first = value++; 00063 ++first; 00064 } 00065 } 00066 00067 00074 template< class InputIterator > 00075 bool is_sorted(InputIterator first, InputIterator last) 00076 { 00077 if ( first == last ) 00078 return true; 00079 00080 // "prev" always points to the entry just to the left of "first" 00081 // [- - - - - -] 00082 // ^ ^ 00083 // prev first 00084 // 00085 // [- - - - - -] 00086 // ^ ^ 00087 // prev first 00088 // 00089 // [- - - - - -] 00090 // ^ ^ 00091 // prev first 00092 InputIterator prev( first ); 00093 for ( ++first; first != last; ++prev, ++first ) 00094 if ( *first < *prev ) // Note: this is the same as *prev > *first, 00095 return false; // but we only require op< to be defined. 00096 00097 // If we haven't returned yet, it's sorted! 00098 return true; 00099 00100 00101 // A one-liner version using adjacent_find. This doesn't work for 00102 // C-style arrays, since their pointers do not have a value_type. 00103 // 00104 // Works by checking to see if adjacent entries satisfy *i > 00105 // *(i+1) and returns the first one which does. If "last" is 00106 // returned, no such pair was found, and therefore the range must 00107 // be in non-decreasing order. 00108 // 00109 // return (last == 00110 // std::adjacent_find(first, last, 00111 // std::greater< typename InputIterator::value_type >())); 00112 00113 // A second one-linear attempt. This one checks for a **strictly 00114 // increasing** (no duplicate entries) range. Also doesn't work 00115 // with C-style arrays. 00116 // 00117 // return (last == 00118 // std::adjacent_find(first, last, 00119 // std::not2(std::less<typename InputIterator::value_type>()))); 00120 } 00121 00122 00129 template<class ForwardIterator, class T> 00130 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T& value) 00131 { 00132 ForwardIterator it = std::lower_bound(first, last, value); 00133 return (it == last || value < *it) ? last : it; 00134 } 00135 00136 00137 //------------------------------------------------------------------- 00142 template <int N, typename T> 00143 struct do_pow { 00144 static inline T apply (const T& x) 00145 { 00146 libmesh_assert(N>1); 00147 00148 if (N%2) // odd exponent 00149 return x * do_pow<N-1,T>::apply(x); 00150 00151 const T xNover2 = do_pow<N/2,T>::apply(x); 00152 00153 return xNover2*xNover2; 00154 } 00155 }; 00156 00157 // An efficient compiler would distill N=6 down to 3 00158 // multiplications, but an inefficient one (or a complicated 00159 // T::operator*) might do worse, so we'll specialize here. 00160 template <typename T> 00161 struct do_pow<6,T> { 00162 static inline T apply (const T& x) 00163 { 00164 const T x2 = x*x, 00165 x4 = x2*x2; 00166 00167 return x4*x2; 00168 } 00169 }; 00170 00171 template <typename T> 00172 struct do_pow<1,T> { 00173 static inline T apply (const T& x) { return x; } 00174 }; 00175 00176 template <typename T> 00177 struct do_pow<0,T> { 00178 static inline T apply (const T&) { return 1; } 00179 }; 00180 00181 00182 template <int N, typename T> 00183 inline 00184 T pow(const T& x) 00185 { 00186 return do_pow<N,T>::apply(x); 00187 } 00188 00189 //------------------------------------------------------------------- 00193 inline 00194 unsigned int factorial(unsigned int n) 00195 { 00196 00197 unsigned int factorial_n = 1; 00198 00199 if (n==0) 00200 return factorial_n; 00201 00202 for (unsigned int i=1; i<n; i++) 00203 factorial_n *= i+1; 00204 00205 return factorial_n; 00206 } 00207 00208 00209 //------------------------------------------------------------------- 00213 template <typename T> 00214 void deallocate (std::vector<T> &vec) 00215 { 00216 std::vector<T>().swap(vec); 00217 } 00218 00219 00220 //------------------------------------------------------------------- 00221 // Utility functions useful when dealing with complex numbers. 00222 00223 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 00224 00230 std::string complex_filename (const std::string& basename, 00231 unsigned int r_o_c=0); 00232 00236 void prepare_complex_data (const std::vector<Complex>& source, 00237 std::vector<Real>& real_part, 00238 std::vector<Real>& imag_part); 00239 00240 #endif // #ifdef LIBMESH_USE_COMPLEX_NUMBERS 00241 00242 00243 00244 //------------------------------------------------------------------- 00253 class ReverseBytes 00254 { 00255 public: 00256 00261 explicit 00262 ReverseBytes (const bool dr); 00263 00268 template <typename T> 00269 T operator () (T& data) const; 00270 00271 private: 00272 00276 bool reverse () const { return _do_reverse; } 00277 00281 const bool _do_reverse; 00282 }; 00283 00284 00285 00286 //--------------------------------------------------------- 00287 // ReverseBytes inline members 00288 inline 00289 ReverseBytes::ReverseBytes (const bool rb) : 00290 _do_reverse (rb) 00291 {} 00292 00293 00294 template <typename T> 00295 inline 00296 T ReverseBytes::operator() (T& data) const 00297 { 00298 // Possibly reverse the byte ordering 00299 if (this->reverse()) 00300 { 00301 unsigned char* b = (unsigned char*) &data; 00302 00303 register int i=0; 00304 register int j=(sizeof(T) - 1); 00305 00306 while (i < j) 00307 { 00308 std::swap (b[i], b[j]); 00309 i++; j--; 00310 } 00311 } 00312 00313 return data; 00314 } 00315 00316 00317 } 00318 00319 } // namespace libMesh 00320 00321 #endif // LIBMESH_UTILITY_H
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:49 UTC
Hosted By: