74 number_of_pools_was_requested_ = (requested_number_of_pools != 0);
75 int number_of_pools = (requested_number_of_pools == 0) ? 1 : requested_number_of_pools;
78 throw std::invalid_argument(
79 "Number of MPI ranks (" + std::to_string(
world_size()) +
80 ") is not divisible by the requested number of k-point pools (" +
82 "). Each pool must have the same number of ranks. "
83 "Choose a number of pools that divides evenly into the rank count.");
93 if (inter_pool_communicator_ != MPI_COMM_NULL) {
94 MPI_Comm_free(&inter_pool_communicator_);
307 int local_number_of_physical_kpoints,
308 int number_of_spin_components,
309 int number_of_values_per_state)
const override {
310 if (local_number_of_physical_kpoints < 0 || number_of_spin_components < 1 ||
311 number_of_values_per_state < 1) {
312 throw std::invalid_argument(
"Global k-point assembly received invalid dimensions.");
314 const std::size_t expected_local_size =
315 static_cast<std::size_t
>(local_number_of_physical_kpoints) * number_of_spin_components *
316 number_of_values_per_state;
317 if (local_data.size() != expected_local_size) {
318 throw std::invalid_argument(
319 "Global k-point assembly data size does not match its dimensions.");
322 int root_local_number_of_physical_kpoints =
324 int global_number_of_physical_kpoints = 0;
325 MPI_Allreduce(&root_local_number_of_physical_kpoints,
326 &global_number_of_physical_kpoints,
332 std::vector<Real> global_data(
static_cast<std::size_t
>(global_number_of_physical_kpoints) *
333 number_of_spin_components * number_of_values_per_state,
336 for (
int spin_index = 0; spin_index < number_of_spin_components; ++spin_index) {
337 for (
int local_kpoint_index = 0;
338 local_kpoint_index < local_number_of_physical_kpoints;
339 ++local_kpoint_index) {
340 int local_state_index =
341 spin_index * local_number_of_physical_kpoints + local_kpoint_index;
342 int global_state_index = spin_index * global_number_of_physical_kpoints +
344 std::copy_n(local_data.begin() +
static_cast<std::size_t
>(local_state_index) *
345 number_of_values_per_state,
346 number_of_values_per_state,
347 global_data.begin() +
static_cast<std::size_t
>(global_state_index) *
348 number_of_values_per_state);
352 if (!global_data.empty()) {
353 MPI_Allreduce(MPI_IN_PLACE,
355 static_cast<int>(global_data.size()),