23#include "system/System.hpp"
29#include <boost/mpi/communicator.hpp>
30#include <boost/range/combine.hpp>
44 return this->evaluate(comm, local_particles_1, {}, {});
49 return this->evaluate(comm, local_particles_1, local_particles_2, {});
53RDF::evaluate(boost::mpi::communicator
const &comm,
57 auto const positions_1 = detail::get_all_particle_positions(
58 comm, local_particles_1,
ids1(),
traits,
false);
59 auto const positions_2 = detail::get_all_particle_positions(
60 comm, local_particles_2,
ids2(),
traits,
false);
62 if (comm.rank() != 0) {
68 auto const inv_bin_width = 1.0 / bin_width;
69 std::vector<double> res(
n_r_bins, 0.0);
71 auto op = [
this, inv_bin_width, &cnt, &res, &box_geo](
auto const &pos1,
73 auto const dist = box_geo.get_mi_vector(pos1, pos2).norm();
75 auto ind =
static_cast<long>(std::floor((dist -
min_r) * inv_bin_width));
76 ind = std::clamp(ind, 0l,
static_cast<long>(
n_r_bins) - 1l);
82 if (local_particles_2.empty()) {
85 auto const combine_1 = boost::combine(
ids1(), positions_1);
86 auto const combine_2 = boost::combine(
ids2(), positions_2);
88 auto op2 = [&op](
auto const &it1,
auto const &it2) {
89 auto const &[id1, pos1] = it1;
90 auto const &[id2, pos2] = it2;
95 auto cmp = [](
auto const &it1,
auto const &it2) {
96 auto const &[id1, pos1] = it1;
97 auto const &[id2, pos2] = it2;
106 auto const volume = box_geo.volume();
107 for (std::size_t i = 0u; i < res.size(); ++i) {
108 auto const r_in =
static_cast<double>(i) * bin_width +
min_r;
109 auto const r_out = r_in + bin_width;
110 auto const bin_volume =
111 (4. / 3.) * std::numbers::pi *
112 (Utils::int_pow<3>(r_out) - Utils::int_pow<3>(r_in));
113 res[i] *= volume / (bin_volume *
static_cast<double>(cnt));
Vector implementation and trait types for boost qvm interoperability.
std::vector< int > & ids2()
std::vector< int > & ids1()
std::vector< double > operator()(boost::mpi::communicator const &comm) const final
std::shared_ptr< BoxGeometry > box_geo
auto fetch_particles(std::vector< int > const &ids)
Fetch a group of particles.
std::vector< std::reference_wrapper< Particle const > > ParticleReferenceRange
void for_each_pair(ForwardIterator first, ForwardIterator last, BinaryOp op)
Execute op for each pair of elements in [first, last) once.
void for_each_cartesian_pair_if(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryOp op, BinaryCmp cmp)
Execute op for each pair of elements between [first1, last1) and [first2, last2) if a condition is sa...