1 #include "../../include/parallelNucleationList.h" 2 #include "../../include/nucleus.h" 3 #include <deal.II/base/mpi.h> 4 #include <deal.II/base/utilities.h> 20 int numProcs=dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD);
21 int thisProc=dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
24 for (
int proc_index=0; proc_index < numProcs-1; proc_index++){
25 if (thisProc == proc_index){
26 sendUpdate(thisProc+1);
28 else if (thisProc == proc_index+1){
29 receiveUpdate(thisProc-1);
31 MPI_Barrier(MPI_COMM_WORLD);
35 if (thisProc == numProcs-1){
36 resolveNucleationConflicts(min_dist_between_nuclei, old_num_nuclei);
40 broadcastUpdate(numProcs-1, thisProc);
44 resolveNucleationConflicts(min_dist_between_nuclei, old_num_nuclei);
56 int currnonucs=newnuclei.size();
59 MPI_Send(&currnonucs, 1, MPI_INT, procno, 0, MPI_COMM_WORLD);
63 std::vector<unsigned int> s_index;
65 std::vector<double> s_center_x;
67 std::vector<double> s_center_y;
69 std::vector<double> s_center_z;
71 std::vector<double> s_semiaxis_a;
72 std::vector<double> s_semiaxis_b;
73 std::vector<double> s_semiaxis_c;
75 std::vector<double> s_seededTime;
77 std::vector<double> s_seedingTime;
79 std::vector<unsigned int> s_seedingTimestep;
81 std::vector<unsigned int> s_orderParameterIndex;
84 for (
typename std::vector<
nucleus<dim> >::const_iterator thisNuclei=newnuclei.begin(); thisNuclei!=newnuclei.end(); ++thisNuclei){
85 s_index.push_back(thisNuclei->index);
86 dealii::Point<dim> s_center=thisNuclei->center;
87 s_center_x.push_back(s_center[0]);
88 s_center_y.push_back(s_center[1]);
90 s_center_z.push_back(s_center[2]);
92 s_semiaxis_a.push_back(thisNuclei->semiaxes[0]);
93 s_semiaxis_b.push_back(thisNuclei->semiaxes[1]);
95 s_semiaxis_c.push_back(thisNuclei->semiaxes[2]);
97 s_seededTime.push_back(thisNuclei->seededTime);
98 s_seedingTime.push_back(thisNuclei->seedingTime);
99 s_seedingTimestep.push_back(thisNuclei->seedingTimestep);
100 s_orderParameterIndex.push_back(thisNuclei->orderParameterIndex);
103 MPI_Send(&s_index[0], currnonucs, MPI_UNSIGNED, procno, 1, MPI_COMM_WORLD);
104 MPI_Send(&s_center_x[0], currnonucs, MPI_DOUBLE, procno, 2, MPI_COMM_WORLD);
105 MPI_Send(&s_center_y[0], currnonucs, MPI_DOUBLE, procno, 3, MPI_COMM_WORLD);
107 MPI_Send(&s_center_z[0], currnonucs, MPI_DOUBLE, procno, 4, MPI_COMM_WORLD);
108 MPI_Send(&s_semiaxis_c[0], currnonucs, MPI_DOUBLE, procno, 7, MPI_COMM_WORLD);
111 MPI_Send(&s_semiaxis_a[0], currnonucs, MPI_DOUBLE, procno, 5, MPI_COMM_WORLD);
112 MPI_Send(&s_semiaxis_b[0], currnonucs, MPI_DOUBLE, procno, 6, MPI_COMM_WORLD);
114 MPI_Send(&s_seededTime[0], currnonucs, MPI_DOUBLE, procno, 8, MPI_COMM_WORLD);
115 MPI_Send(&s_seedingTime[0], currnonucs, MPI_DOUBLE, procno, 9, MPI_COMM_WORLD);
116 MPI_Send(&s_seedingTimestep[0], currnonucs, MPI_UNSIGNED, procno, 10, MPI_COMM_WORLD);
117 MPI_Send(&s_orderParameterIndex[0], currnonucs, MPI_UNSIGNED, procno, 11, MPI_COMM_WORLD);
130 MPI_Recv(&recvnonucs, 1, MPI_INT, procno, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
135 std::vector<unsigned int> r_index(recvnonucs,0);
137 std::vector<double> r_center_x(recvnonucs,0.0);
139 std::vector<double> r_center_y(recvnonucs,0.0);
141 std::vector<double> r_center_z(recvnonucs,0.0);
143 std::vector<double> r_semiaxis_a(recvnonucs,0.0);
144 std::vector<double> r_semiaxis_b(recvnonucs,0.0);
145 std::vector<double> r_semiaxis_c(recvnonucs,0.0);
147 std::vector<double> r_seededTime(recvnonucs,0.0);
149 std::vector<double> r_seedingTime(recvnonucs,0.0);
151 std::vector<unsigned int> r_seedingTimestep(recvnonucs,0);
153 std::vector<unsigned int> r_orderParameterIndex(recvnonucs,0);
156 MPI_Recv(&r_index[0], recvnonucs, MPI_UNSIGNED, procno, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
157 MPI_Recv(&r_center_x[0], recvnonucs, MPI_DOUBLE, procno, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
158 MPI_Recv(&r_center_y[0], recvnonucs, MPI_DOUBLE, procno, 3, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
160 MPI_Recv(&r_center_z[0], recvnonucs, MPI_DOUBLE, procno, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
161 MPI_Recv(&r_semiaxis_c[0], recvnonucs, MPI_DOUBLE, procno, 7, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
164 MPI_Recv(&r_semiaxis_a[0], recvnonucs, MPI_DOUBLE, procno, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
165 MPI_Recv(&r_semiaxis_b[0], recvnonucs, MPI_DOUBLE, procno, 6, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
167 MPI_Recv(&r_seededTime[0], recvnonucs, MPI_DOUBLE, procno, 8, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
168 MPI_Recv(&r_seedingTime[0], recvnonucs, MPI_DOUBLE, procno, 9, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
169 MPI_Recv(&r_seedingTimestep[0], recvnonucs, MPI_UNSIGNED, procno, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
170 MPI_Recv(&r_orderParameterIndex[0], recvnonucs, MPI_UNSIGNED, procno, 11, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
173 for (
int jnuc=0; jnuc<=recvnonucs-1; jnuc++){
175 temp->
index=r_index[jnuc];
176 dealii::Point<dim> r_center;
177 r_center[0]=r_center_x[jnuc];
178 r_center[1]=r_center_y[jnuc];
180 r_center[2]=r_center_z[jnuc];
182 temp->
semiaxes.push_back(r_semiaxis_a[jnuc]);
183 temp->
semiaxes.push_back(r_semiaxis_b[jnuc]);
185 temp->
semiaxes.push_back(r_semiaxis_c[jnuc]);
190 newnuclei.push_back(*temp);
203 int currnonucs = newnuclei.size();
204 MPI_Bcast(&currnonucs, 1, MPI_INT, broadcastProc, MPI_COMM_WORLD);
208 unsigned int initial_vec_size;
209 if (thisProc == broadcastProc){
210 initial_vec_size = 0;
213 initial_vec_size = currnonucs;
217 std::vector<unsigned int> r_index(initial_vec_size,0);
219 std::vector<double> r_center_x(initial_vec_size,0.0);
221 std::vector<double> r_center_y(initial_vec_size,0.0);
223 std::vector<double> r_center_z(initial_vec_size,0.0);
225 std::vector<double> r_semiaxis_a(initial_vec_size,0.0);
226 std::vector<double> r_semiaxis_b(initial_vec_size,0.0);
227 std::vector<double> r_semiaxis_c(initial_vec_size,0.0);
229 std::vector<double> r_seededTime(initial_vec_size,0.0);
231 std::vector<double> r_seedingTime(initial_vec_size,0.0);
233 std::vector<unsigned int> r_seedingTimestep(initial_vec_size,0);
235 std::vector<unsigned int> r_orderParameterIndex(initial_vec_size,0);
237 if (thisProc == broadcastProc){
238 for (
typename std::vector<
nucleus<dim> >::iterator thisNuclei=newnuclei.begin(); thisNuclei!=newnuclei.end(); ++thisNuclei){
239 r_index.push_back(thisNuclei->index);
240 dealii::Point<dim> s_center=thisNuclei->center;
241 r_center_x.push_back(s_center[0]);
242 r_center_y.push_back(s_center[1]);
244 r_center_z.push_back(s_center[2]);
247 r_semiaxis_a.push_back(thisNuclei->semiaxes[0]);
248 r_semiaxis_b.push_back(thisNuclei->semiaxes[1]);
250 r_semiaxis_c.push_back(thisNuclei->semiaxes[2]);
253 r_seededTime.push_back(thisNuclei->seededTime);
254 r_seedingTime.push_back(thisNuclei->seedingTime);
255 r_seedingTimestep.push_back(thisNuclei->seedingTimestep);
256 r_orderParameterIndex.push_back(thisNuclei->orderParameterIndex);
261 MPI_Bcast(&r_index[0], currnonucs, MPI_UNSIGNED, broadcastProc, MPI_COMM_WORLD);
262 MPI_Bcast(&r_center_x[0], currnonucs, MPI_DOUBLE, broadcastProc, MPI_COMM_WORLD);
263 MPI_Bcast(&r_center_y[0], currnonucs, MPI_DOUBLE, broadcastProc, MPI_COMM_WORLD);
265 MPI_Bcast(&r_center_z[0], currnonucs, MPI_DOUBLE, broadcastProc, MPI_COMM_WORLD);
267 MPI_Bcast(&r_semiaxis_a[0], currnonucs, MPI_DOUBLE, broadcastProc, MPI_COMM_WORLD);
268 MPI_Bcast(&r_semiaxis_b[0], currnonucs, MPI_DOUBLE, broadcastProc, MPI_COMM_WORLD);
270 MPI_Bcast(&r_semiaxis_c[0], currnonucs, MPI_DOUBLE, broadcastProc, MPI_COMM_WORLD);
272 MPI_Bcast(&r_seededTime[0], currnonucs, MPI_DOUBLE, broadcastProc, MPI_COMM_WORLD);
273 MPI_Bcast(&r_seedingTime[0], currnonucs, MPI_DOUBLE, broadcastProc, MPI_COMM_WORLD);
274 MPI_Bcast(&r_seedingTimestep[0], currnonucs, MPI_UNSIGNED, broadcastProc, MPI_COMM_WORLD);
275 MPI_Bcast(&r_orderParameterIndex[0], currnonucs, MPI_UNSIGNED, broadcastProc, MPI_COMM_WORLD);
280 for (
int jnuc=0; jnuc<=currnonucs-1; jnuc++){
282 temp->
index=r_index[jnuc];
283 dealii::Point<dim> r_center;
284 r_center[0]=r_center_x[jnuc];
285 r_center[1]=r_center_y[jnuc];
287 r_center[2]=r_center_z[jnuc];
289 temp->
semiaxes.push_back(r_semiaxis_a[jnuc]);
290 temp->
semiaxes.push_back(r_semiaxis_b[jnuc]);
292 temp->
semiaxes.push_back(r_semiaxis_c[jnuc]);
298 newnuclei.push_back(*temp);
310 std::vector<nucleus<dim> > newnuclei_cleaned;
312 for (
unsigned int nuc_index=0; nuc_index<newnuclei.size(); nuc_index++){
315 for (
unsigned int prev_nuc_index=0; prev_nuc_index<nuc_index; prev_nuc_index++){
319 if (newnuclei[nuc_index].center.distance(newnuclei[prev_nuc_index].center) < min_dist_between_nuclei){
321 std::cout <<
"Conflict between nuclei! Distance is: " << newnuclei[nuc_index].center.distance(newnuclei[prev_nuc_index].center)
322 <<
" Conflict removed."<< std::endl;
328 newnuclei[nuc_index].index = old_num_nuclei + newnuclei_cleaned.size();
329 newnuclei_cleaned.push_back(newnuclei[nuc_index]);
333 newnuclei = newnuclei_cleaned;
346 int numProcs=dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD);
347 int thisProc=dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
352 for (
int proc_index=0; proc_index < numProcs-1; proc_index++){
353 if (thisProc == proc_index){
354 int currnonucs= nuclei_to_remove.size();
355 MPI_Send(&currnonucs, 1, MPI_INT, thisProc+1, 0, MPI_COMM_WORLD);
356 MPI_Send(&nuclei_to_remove[0], currnonucs, MPI_UNSIGNED, thisProc+1, 1, MPI_COMM_WORLD);
358 else if (thisProc == proc_index+1){
360 MPI_Recv(&recvnonucs, 1, MPI_INT, thisProc-1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
361 std::vector<unsigned int> recieved_nuclei_to_remove(recvnonucs);
362 MPI_Recv(&recieved_nuclei_to_remove[0], recvnonucs, MPI_UNSIGNED, thisProc-1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
363 nuclei_to_remove.insert(nuclei_to_remove.end(), recieved_nuclei_to_remove.begin(), recieved_nuclei_to_remove.end());
366 MPI_Barrier(MPI_COMM_WORLD);
370 int currnonucs= nuclei_to_remove.size();
371 MPI_Bcast(&currnonucs, 1, MPI_INT, numProcs-1, MPI_COMM_WORLD);
372 std::vector<unsigned int> recieved_nuclei_to_remove(currnonucs);
373 if (thisProc == numProcs-1){
374 recieved_nuclei_to_remove = nuclei_to_remove;
376 MPI_Bcast(&recieved_nuclei_to_remove[0], currnonucs, MPI_UNSIGNED, numProcs-1, MPI_COMM_WORLD);
377 nuclei_to_remove = recieved_nuclei_to_remove;
380 for (
unsigned int i=0; i<nuclei_to_remove.size(); i++){
381 std::cout << thisProc <<
": " << nuclei_to_remove[i] << std::endl;
385 std::vector<nucleus<dim> > pruned_list;
386 for (
unsigned int nuc = 0; nuc < newnuclei.size(); nuc++){
387 bool pruneNucleus =
false;
388 for (
unsigned int i = 0; i < nuclei_to_remove.size(); i++){
389 if (nuclei_to_remove[i] == nuclei_size+nuc){
395 pruned_list.push_back(newnuclei[nuc]);
void receiveUpdate(int procno)
dealii::Point< dim > center
void resolveNucleationConflicts(double min_dist_between_nuclei, unsigned int old_num_nuclei)
parallelNucleationList(std::vector< nucleus< dim > > _newnuclei)
std::vector< nucleus< dim > > removeSubsetOfNuclei(std::vector< unsigned int > nuclei_to_remove, unsigned int nuclei_size)
void broadcastUpdate(int broadcastProc, int thisProc)
std::vector< double > semiaxes
unsigned int seedingTimestep
void sendUpdate(int procno) const
unsigned int orderParameterIndex
std::vector< nucleus< dim > > buildGlobalNucleiList(double min_dist_between_nuclei, unsigned int old_num_nuclei)