$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 // C++ includes 00020 #include <algorithm> // std::lower_bound 00021 00022 // Local includes 00023 #include "libmesh/parallel_histogram.h" 00024 #ifdef LIBMESH_HAVE_LIBHILBERT 00025 # include "hilbert.h" 00026 #endif 00027 #include "libmesh/parallel.h" 00028 #include "libmesh/parallel_conversion_utils.h" 00029 00030 namespace libMesh 00031 { 00032 00033 00034 00035 namespace Parallel { 00036 template <typename KeyType, typename IdxType> 00037 Histogram<KeyType,IdxType>::Histogram (const Parallel::Communicator &comm_in, 00038 const std::vector<KeyType>& d) : 00039 ParallelObject(comm_in), 00040 data(d) 00041 { 00042 libmesh_assert (Parallel::Utils::is_sorted (data)); 00043 } 00044 00045 00046 00047 template <typename KeyType, typename IdxType> 00048 void Histogram<KeyType,IdxType>::make_histogram (const IdxType nbins, 00049 KeyType max, 00050 KeyType min) 00051 { 00052 libmesh_assert_less (min, max); 00053 00054 // The width of each bin. Store this as a floating point value 00055 double bin_width = (Parallel::Utils::to_double(max)- 00056 Parallel::Utils::to_double(min))/static_cast<double>(nbins); 00057 00058 00059 // The idea for 4 bins of size d is this: 00060 // 00061 // 0 1 2 3 4 00062 // |----------|----------|-----------|----------| 00063 // min 0 min+d 1 min+2d 2 min+3d 3 max 00064 00065 00066 00067 // Set the iterators corresponding to the boundaries 00068 // as defined above. This takes nbins * O(log N) time. 00069 bin_bounds.resize (nbins+1); 00070 bin_iters.resize (nbins+1, data.begin()); 00071 00072 // Set the minimum bin boundary iterator 00073 bin_iters[0] = data.begin(); 00074 bin_bounds[0] = Parallel::Utils::to_double(min); 00075 00076 // Set the internal bin boundary iterators 00077 for (IdxType b=1; b<nbins; ++b) 00078 { 00079 bin_bounds[b] = Parallel::Utils::to_double(min) + bin_width * b; 00080 00081 bin_iters[b] = std::lower_bound (bin_iters[b-1], data.end(), 00082 Parallel::Utils::to_key_type<KeyType>(bin_bounds[b])); 00083 } 00084 00085 bin_iters[nbins] = data.end(); 00086 bin_bounds[nbins] = Parallel::Utils::to_double(max); 00087 } 00088 00089 00090 00091 template <typename KeyType, typename IdxType> 00092 void Histogram<KeyType,IdxType>::build_histogram () 00093 { 00094 // Build a local histogram 00095 std::vector<IdxType> local_hist (this->n_bins()); 00096 00097 for (IdxType b=0; b<this->n_bins(); b++) 00098 local_hist[b] = this->local_bin_size(b); 00099 00100 // Add all the local histograms to get the global histogram 00101 hist = local_hist; 00102 this->comm().sum(hist); 00103 00104 // All done! 00105 } 00106 00107 } 00108 00109 00110 // Explicitly instantiate for int, double 00111 template class Parallel::Histogram<int, unsigned int>; 00112 template class Parallel::Histogram<double, unsigned int>; 00113 #ifdef LIBMESH_HAVE_LIBHILBERT 00114 template class Parallel::Histogram<Hilbert::HilbertIndices, unsigned int>; 00115 #endif 00116 00117 } // namespace libMesh