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 699733 : Histogram<KeyType,IdxType>::Histogram (const Parallel::Communicator & comm_in, 36 : const std::vector<KeyType> & d) : 37 : ParallelObject(comm_in), 38 699733 : data(d) 39 : { 40 15284 : libmesh_assert (std::is_sorted (data.begin(), data.end())); 41 699733 : } 42 : 43 : 44 : 45 : template <typename KeyType, typename IdxType> 46 699733 : void Histogram<KeyType,IdxType>::make_histogram (const IdxType nbins, 47 : KeyType max, 48 : KeyType min) 49 : { 50 15284 : libmesh_assert_less (min, max); 51 : 52 : // The width of each bin. Store this as a floating point value 53 715017 : double bin_width = (Parallel::Utils::to_double(max)- 54 699733 : 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 699733 : bin_bounds.resize (nbins+1); 68 699733 : bin_iters.resize (nbins+1, data.begin()); 69 : 70 : // Set the minimum bin boundary iterator 71 699733 : bin_iters[0] = data.begin(); 72 699733 : bin_bounds[0] = Parallel::Utils::to_double(min); 73 : 74 : // Set the internal bin boundary iterators 75 360246650 : for (IdxType b=1; b<nbins; ++b) 76 : { 77 361060033 : bin_bounds[b] = Parallel::Utils::to_double(min) + bin_width * b; 78 : 79 361059835 : bin_iters[b] = 80 359546917 : std::lower_bound (bin_iters[b-1], data.end(), 81 361059835 : Parallel::Utils::Convert<KeyType>::to_key_type(bin_bounds[b])); 82 : } 83 : 84 715017 : bin_iters[nbins] = data.end(); 85 715015 : bin_bounds[nbins] = Parallel::Utils::to_double(max); 86 699733 : } 87 : 88 : 89 : 90 : template <typename KeyType, typename IdxType> 91 699733 : void Histogram<KeyType,IdxType>::build_histogram () 92 : { 93 : // Build a local histogram 94 715017 : std::vector<IdxType> local_hist (this->n_bins()); 95 : 96 360946383 : for (auto b : index_range(local_hist)) 97 361775050 : local_hist[b] = this->local_bin_size(b); 98 : 99 : // Add all the local histograms to get the global histogram 100 699733 : hist = local_hist; 101 699733 : this->comm().sum(hist); 102 : 103 : // All done! 104 699733 : } 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