From 769ba804fa1c0b61208c27a2aaac35ba57300ad6 Mon Sep 17 00:00:00 2001
From: Wolfgang Bangerth <bangerth@colostate.edu>
Date: Wed, 12 Jan 2022 21:50:54 -0700
Subject: [PATCH] Validate correctness of input arguments.

---
 .../base/mpi_consensus_algorithms.templates.h | 37 +++++++++++++++++--
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/include/deal.II/base/mpi_consensus_algorithms.templates.h b/include/deal.II/base/mpi_consensus_algorithms.templates.h
index 1e216c979a..e7982b81d4 100644
--- a/include/deal.II/base/mpi_consensus_algorithms.templates.h
+++ b/include/deal.II/base/mpi_consensus_algorithms.templates.h
@@ -150,7 +150,21 @@ namespace Utilities
       {
 #ifdef DEAL_II_WITH_MPI
         // 1)
-        targets              = this->process.compute_targets();
+        targets = this->process.compute_targets();
+        Assert(
+          [this]() {
+            std::vector<unsigned int> my_destinations = this->targets;
+            const unsigned int        n_destinations  = my_destinations.size();
+            std::sort(my_destinations.begin(), my_destinations.end());
+            my_destinations.erase(std::unique(my_destinations.begin(),
+                                              my_destinations.end()),
+                                  my_destinations.end());
+            return (my_destinations.size() == n_destinations);
+          }(),
+          ExcMessage("The consensus algorithms expect that each process "
+                     "only sends a single message to another process, "
+                     "but the targets provided include duplicates."));
+
         const auto n_targets = targets.size();
 
         const int tag_request = Utilities::MPI::internal::Tags::
@@ -428,14 +442,29 @@ namespace Utilities
       PEX<T1, T2>::start_communication()
       {
 #ifdef DEAL_II_WITH_MPI
-        // 1) determine with which processes this process wants to communicate
-        targets = this->process.compute_targets();
-
         const int tag_request = Utilities::MPI::internal::Tags::
           consensus_algorithm_pex_answer_request;
         const int tag_deliver = Utilities::MPI::internal::Tags::
           consensus_algorithm_pex_process_deliver;
 
+
+        // 1) determine with which processes this process wants to communicate
+        // with
+        targets = this->process.compute_targets();
+        Assert(
+          [this]() {
+            std::vector<unsigned int> my_destinations = this->targets;
+            const unsigned int        n_destinations  = my_destinations.size();
+            std::sort(my_destinations.begin(), my_destinations.end());
+            my_destinations.erase(std::unique(my_destinations.begin(),
+                                              my_destinations.end()),
+                                  my_destinations.end());
+            return (my_destinations.size() == n_destinations);
+          }(),
+          ExcMessage("The consensus algorithms expect that each process "
+                     "only sends a single message to another process, "
+                     "but the targets provided include duplicates."));
+
         // 2) determine who wants to communicate with this process
         sources =
           compute_point_to_point_communication_pattern(this->comm, targets);
-- 
2.39.5