$extrastylesheet
00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2014 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 00139 template<class ForwardIterator, class T, class Compare> 00140 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T& value, Compare comp) 00141 { 00142 ForwardIterator it = std::lower_bound(first, last, value, comp); 00143 return (it == last || comp(value,*it)) ? last : it; 00144 } 00145 00146 00147 //------------------------------------------------------------------- 00152 template <int N, typename T> 00153 struct do_pow { 00154 static inline T apply (const T& x) 00155 { 00156 libmesh_assert(N>1); 00157 00158 if (N%2) // odd exponent 00159 return x * do_pow<N-1,T>::apply(x); 00160 00161 const T xNover2 = do_pow<N/2,T>::apply(x); 00162 00163 return xNover2*xNover2; 00164 } 00165 }; 00166 00167 // An efficient compiler would distill N=6 down to 3 00168 // multiplications, but an inefficient one (or a complicated 00169 // T::operator*) might do worse, so we'll specialize here. 00170 template <typename T> 00171 struct do_pow<6,T> { 00172 static inline T apply (const T& x) 00173 { 00174 const T x2 = x*x, 00175 x4 = x2*x2; 00176 00177 return x4*x2; 00178 } 00179 }; 00180 00181 template <typename T> 00182 struct do_pow<1,T> { 00183 static inline T apply (const T& x) { return x; } 00184 }; 00185 00186 template <typename T> 00187 struct do_pow<0,T> { 00188 static inline T apply (const T&) { return 1; } 00189 }; 00190 00191 00192 template <int N, typename T> 00193 inline 00194 T pow(const T& x) 00195 { 00196 return do_pow<N,T>::apply(x); 00197 } 00198 00199 //------------------------------------------------------------------- 00203 inline 00204 unsigned int factorial(unsigned int n) 00205 { 00206 00207 unsigned int factorial_n = 1; 00208 00209 if (n==0) 00210 return factorial_n; 00211 00212 for (unsigned int i=1; i<n; i++) 00213 factorial_n *= i+1; 00214 00215 return factorial_n; 00216 } 00217 00218 00219 //------------------------------------------------------------------- 00223 template <typename T> 00224 void deallocate (std::vector<T> &vec) 00225 { 00226 std::vector<T>().swap(vec); 00227 } 00228 00229 00230 //------------------------------------------------------------------- 00231 // Utility functions useful when dealing with complex numbers. 00232 00233 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 00234 00240 std::string complex_filename (const std::string& basename, 00241 unsigned int r_o_c=0); 00242 00246 void prepare_complex_data (const std::vector<Complex>& source, 00247 std::vector<Real>& real_part, 00248 std::vector<Real>& imag_part); 00249 00250 #endif // #ifdef LIBMESH_USE_COMPLEX_NUMBERS 00251 00252 00253 00254 //------------------------------------------------------------------- 00263 class ReverseBytes 00264 { 00265 public: 00266 00271 explicit 00272 ReverseBytes (const bool dr); 00273 00278 template <typename T> 00279 T operator () (T& data) const; 00280 00281 private: 00282 00286 bool reverse () const { return _do_reverse; } 00287 00291 const bool _do_reverse; 00292 }; 00293 00294 00295 00296 //--------------------------------------------------------- 00297 // ReverseBytes inline members 00298 inline 00299 ReverseBytes::ReverseBytes (const bool rb) : 00300 _do_reverse (rb) 00301 {} 00302 00303 00304 template <typename T> 00305 inline 00306 T ReverseBytes::operator() (T& data) const 00307 { 00308 // Possibly reverse the byte ordering 00309 if (this->reverse()) 00310 { 00311 unsigned char* b = (unsigned char*) &data; 00312 00313 int i=0; 00314 int j=(sizeof(T) - 1); 00315 00316 while (i < j) 00317 { 00318 std::swap (b[i], b[j]); 00319 i++; j--; 00320 } 00321 } 00322 00323 return data; 00324 } 00325 00326 00327 } 00328 00329 } // namespace libMesh 00330 00331 #endif // LIBMESH_UTILITY_H