Chi-Tech
chi_meshcontinuum_communicator.cc
Go to the documentation of this file.
1#include "chi_meshcontinuum.h"
2
3#include "chi_runtime.h"
4#include "chi_log.h"
5
7
8//###################################################################
9/**Gets the communicator-set for interprocess communication,
10 * associated with this mesh. If not created yet, it will create it.*/
11std::shared_ptr<chi::ChiMPICommunicatorSet>
13{
14 //================================================== Build the communicator
15 Chi::log.Log0Verbose1() << "Building communicator.";
16 std::set<int> local_graph_edges;
17
18 //================================================== Loop over local cells
19 //Populate local_graph_edges
20 local_graph_edges.insert(Chi::mpi.location_id); //add current location
21 for (auto& cell : local_cells)
22 {
23 for (auto& face : cell.faces_)
24 {
25 if (face.has_neighbor_)
26 if (not face.IsNeighborLocal(*this))
27 local_graph_edges.insert(face.GetNeighborPartitionID(*this));
28 }//for f
29 }//for local cells
30
31 //============================================= Convert set to vector
32 //This is just done for convenience because MPI
33 //needs a contiguous array
34 std::vector<int> local_connections(local_graph_edges.begin(),
35 local_graph_edges.end());
36
37 //============================================= Broadcast local connection size
39 << "Communicating local connections.";
40
41 std::vector<std::vector<int>> global_graph(Chi::mpi.process_count,
42 std::vector<int>());
43 for (int locI=0;locI< Chi::mpi.process_count; locI++)
44 {
45 int locI_num_connections = static_cast<int>(local_connections.size());
46
47 //If chi::mpi.location_id == locI then this call will
48 //act like a send instead of receive. Otherwise
49 //It receives the count.
50 MPI_Bcast(&locI_num_connections,1,MPI_INT,locI,Chi::mpi.comm);
51
52 if (Chi::mpi.location_id != locI)
53 {global_graph[locI].resize(locI_num_connections,-1);}
54 else
55 {
56 std::copy(local_connections.begin(),
57 local_connections.end(),
58 std::back_inserter(global_graph[locI]));
59 }
60 }
61
62
63
64 //============================================= Broadcast local connections
65 for (int locI=0;locI< Chi::mpi.process_count; locI++)
66 {
67 //If chi::mpi.location_id == locI then this call will
68 //act like a send instead of receive. Otherwise
69 //It receives the count.
70 MPI_Bcast(global_graph[locI].data(),
71 static_cast<int>(global_graph[locI].size()),
72 MPI_INT,locI,Chi::mpi.comm);
73 }
74
76 << "Done communicating local connections.";
77
78
79 //============================================= Build groups
80 MPI_Group world_group;
81 MPI_Comm_group(Chi::mpi.comm,&world_group);
82
83 std::vector<MPI_Group> location_groups;
84 location_groups.resize(Chi::mpi.process_count, MPI_Group());
85
86 for (int locI=0;locI< Chi::mpi.process_count; locI++)
87 {
88 MPI_Group_incl(world_group,
89 static_cast<int>(global_graph[locI].size()),
90 global_graph[locI].data(),
91 &location_groups[locI]);
92 }
93
94 //============================================= Build communicators
95 std::vector<MPI_Comm> communicators;
97 << "Building communicators.";
98 communicators.resize(Chi::mpi.process_count, MPI_Comm());
99
100 for (int locI=0;locI< Chi::mpi.process_count; locI++)
101 {
102 int err = MPI_Comm_create_group(Chi::mpi.comm,
103 location_groups[locI],
104 0, //tag
105 &communicators[locI]);
106
107 if (err != MPI_SUCCESS)
108 {
110 << "Communicator creation failed.";
111 }
112 }
113
115 << "Done building communicators.";
116
117 return std::make_shared<chi::ChiMPICommunicatorSet>(
118 communicators, location_groups, world_group);
119}
120
static chi::ChiLog & log
Definition: chi_runtime.h:81
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
LogStream Log0Verbose1()
Definition: chi_log.h:234
const int & process_count
Total number of processes.
Definition: mpi_info.h:27
LocalCellHandler local_cells
MPILocalCommSetPtr MakeMPILocalCommunicatorSet() const