Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 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 : // C++ includes 20 : #include <algorithm> // is_sorted, lower_bound 21 : 22 : // Local includes 23 : #include "libmesh/parallel_histogram.h" 24 : #include "libmesh/parallel.h" 25 : #include "libmesh/parallel_conversion_utils.h" 26 : #include "libmesh/parallel_hilbert.h" 27 : 28 : namespace libMesh 29 : { 30 : 31 : 32 : 33 : namespace Parallel { 34 : template <typename KeyType, typename IdxType> 35 697941 : Histogram<KeyType,IdxType>::Histogram (const Parallel::Communicator & comm_in, 36 : const std::vector<KeyType> & d) : 37 : ParallelObject(comm_in), 38 697941 : data(d) 39 : { 40 15230 : libmesh_assert (std::is_sorted (data.begin(), data.end())); 41 697941 : } 42 : 43 : 44 : 45 : template <typename KeyType, typename IdxType> 46 697941 : void Histogram<KeyType,IdxType>::make_histogram (const IdxType nbins, 47 : KeyType max, 48 : KeyType min) 49 : { 50 15230 : libmesh_assert_less (min, max); 51 : 52 : // The width of each bin. Store this as a floating point value 53 713171 : double bin_width = (Parallel::Utils::to_double(max)- 54 697941 : Parallel::Utils::to_double(min))/static_cast<double>(nbins); 55 : 56 : 57 : // The idea for 4 bins of size d is this: 58 : // 59 : // 0 1 2 3 4 60 : // |----------|----------|-----------|----------| 61 : // min 0 min+d 1 min+2d 2 min+3d 3 max 62 : 63 : 64 : 65 : // Set the iterators corresponding to the boundaries 66 : // as defined above. This takes nbins * O(log N) time. 67 697941 : bin_bounds.resize (nbins+1); 68 697941 : bin_iters.resize (nbins+1, data.begin()); 69 : 70 : // Set the minimum bin boundary iterator 71 697941 : bin_iters[0] = data.begin(); 72 697941 : bin_bounds[0] = Parallel::Utils::to_double(min); 73 : 74 : // Set the internal bin boundary iterators 75 359348550 : for (IdxType b=1; b<nbins; ++b) 76 : { 77 360158379 : bin_bounds[b] = Parallel::Utils::to_double(min) + bin_width * b; 78 : 79 360158181 : bin_iters[b] = 80 358650609 : std::lower_bound (bin_iters[b-1], data.end(), 81 360158181 : Parallel::Utils::Convert<KeyType>::to_key_type(bin_bounds[b])); 82 : } 83 : 84 713171 : bin_iters[nbins] = data.end(); 85 713169 : bin_bounds[nbins] = Parallel::Utils::to_double(max); 86 697941 : } 87 : 88 : 89 : 90 : template <typename KeyType, typename IdxType> 91 697941 : void Histogram<KeyType,IdxType>::build_histogram () 92 : { 93 : // Build a local histogram 94 713171 : std::vector<IdxType> local_hist (this->n_bins()); 95 : 96 360046491 : for (auto b : index_range(local_hist)) 97 360871550 : local_hist[b] = this->local_bin_size(b); 98 : 99 : // Add all the local histograms to get the global histogram 100 697941 : hist = local_hist; 101 697941 : this->comm().sum(hist); 102 : 103 : // All done! 104 697941 : } 105 : 106 : } 107 : 108 : 109 : // Explicitly instantiate for int, double 110 : template class LIBMESH_EXPORT Parallel::Histogram<int, unsigned int>; 111 : template class LIBMESH_EXPORT Parallel::Histogram<double, unsigned int>; 112 : #ifdef LIBMESH_HAVE_LIBHILBERT 113 : template class LIBMESH_EXPORT Parallel::Histogram<Parallel::DofObjectKey, unsigned int>; 114 : #endif 115 : 116 : } // namespace libMesh