ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
utils_histogram.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2023 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <utils/Histogram.hpp>
23
24#include <boost/mpi/collectives/gather.hpp>
25#include <boost/mpi/communicator.hpp>
26#include <boost/serialization/vector.hpp>
27
28#include <cstddef>
29#include <utility>
30#include <vector>
31
32namespace Observables::detail {
33
34/** @brief Gather data from all MPI ranks. */
35template <class Pos>
36auto gather(boost::mpi::communicator const &comm,
37 std::vector<Pos> const &local_pos) {
38 std::vector<std::vector<Pos>> global_pos{};
39 global_pos.reserve(static_cast<std::size_t>(comm.size()));
40 boost::mpi::gather(comm, local_pos, global_pos, 0);
41 return global_pos;
42}
43
44/** @brief Gather data from all MPI ranks. */
45template <class Pos, class Val>
46auto gather(boost::mpi::communicator const &comm,
47 std::vector<Pos> const &local_pos,
48 std::vector<Val> const &local_val) {
49 std::vector<std::vector<Pos>> global_pos{};
50 global_pos.reserve(static_cast<std::size_t>(comm.size()));
51 boost::mpi::gather(comm, local_pos, global_pos, 0);
52 std::vector<std::vector<Val>> global_val{};
53 global_val.reserve(static_cast<std::size_t>(comm.size()));
54 boost::mpi::gather(comm, local_val, global_val, 0);
55 return std::make_pair(global_pos, global_val);
56}
57
58/** @brief Accumulate histogram data gathered from multiple MPI ranks. */
59template <class T, std::size_t N, std::size_t M, class U, class Pos, class Val>
60void accumulate(Utils::Histogram<T, N, M, U> &histogram,
61 std::vector<std::vector<Pos>> const &pos,
62 std::vector<std::vector<Val>> const &val) {
63 for (std::size_t rank = 0u; rank < pos.size(); ++rank) {
64 auto const &pos_vec = pos[rank];
65 auto const &val_vec = val[rank];
66 for (std::size_t i = 0u; i < pos_vec.size(); ++i) {
67 histogram.update(pos_vec[i], val_vec[i]);
68 }
69 }
70}
71
72struct empty_bin_exception {};
73
74/** @brief Normalize histogram by the number of values in each bin. */
75template <class T, std::size_t N, std::size_t M, class U>
76auto normalize_by_bin_size(Utils::Histogram<T, N, M, U> &histogram,
77 bool allow_empty_bins = true) {
78 auto hist_data = histogram.get_histogram();
79 auto tot_count = histogram.get_tot_count();
80 for (std::size_t i = 0u; i < hist_data.size(); ++i) {
81 if (tot_count[i] != 0u) {
82 hist_data[i] /= static_cast<double>(tot_count[i]);
83 } else if (not allow_empty_bins) {
84 throw empty_bin_exception{};
85 }
86 }
87 return hist_data;
88}
89
90} // Namespace Observables::detail
Histogram in Cartesian coordinates.
Definition Histogram.hpp:46
std::vector< std::size_t > get_tot_count() const
Get the histogram count data.
Definition Histogram.hpp:79
std::vector< T > get_histogram() const
Get the histogram data.
Definition Histogram.hpp:74
void update(std::span< const U > pos)
Add data to the histogram.
Definition Histogram.hpp:93