00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <OpenFOAM/Pstream.H>
00027
00028
00029
00030
00031 template<class T>
00032 void Foam::mapDistribute::distribute
00033 (
00034 const Pstream::commsTypes commsType,
00035 const List<labelPair>& schedule,
00036 const label constructSize,
00037 const labelListList& subMap,
00038 const labelListList& constructMap,
00039 List<T>& field
00040 )
00041 {
00042 if (commsType == Pstream::blocking)
00043 {
00044
00045
00046
00047
00048 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00049 {
00050 const labelList& map = subMap[domain];
00051
00052 if (domain != Pstream::myProcNo() && map.size())
00053 {
00054 OPstream toNbr(Pstream::blocking, domain);
00055 toNbr << UIndirectList<T>(field, map);
00056 }
00057 }
00058
00059
00060 const labelList& mySubMap = subMap[Pstream::myProcNo()];
00061
00062 List<T> subField(mySubMap.size());
00063 forAll(mySubMap, i)
00064 {
00065 subField[i] = field[mySubMap[i]];
00066 }
00067
00068
00069 const labelList& map = constructMap[Pstream::myProcNo()];
00070
00071 field.setSize(constructSize);
00072
00073 forAll(map, i)
00074 {
00075 field[map[i]] = subField[i];
00076 }
00077
00078
00079 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00080 {
00081 const labelList& map = constructMap[domain];
00082
00083 if (domain != Pstream::myProcNo() && map.size())
00084 {
00085 IPstream fromNbr(Pstream::blocking, domain);
00086 List<T> subField(fromNbr);
00087
00088 if (subField.size() != map.size())
00089 {
00090 FatalErrorIn
00091 (
00092 "template<class T>\n"
00093 "void mapDistribute::distribute\n"
00094 "(\n"
00095 " const Pstream::commsTypes commsType,\n"
00096 " const List<labelPair>& schedule,\n"
00097 " const label constructSize,\n"
00098 " const labelListList& subMap,\n"
00099 " const labelListList& constructMap,\n"
00100 " List<T>& field\n"
00101 ")\n"
00102 ) << "Expected from processor " << domain
00103 << " " << map.size() << " but received "
00104 << subField.size() << " elements."
00105 << abort(FatalError);
00106 }
00107
00108 forAll(map, i)
00109 {
00110 field[map[i]] = subField[i];
00111 }
00112 }
00113 }
00114 }
00115 else if (commsType == Pstream::scheduled)
00116 {
00117
00118
00119
00120 List<T> newField(constructSize);
00121
00122
00123 UIndirectList<T> subField(field, subMap[Pstream::myProcNo()]);
00124
00125
00126 const labelList& map = constructMap[Pstream::myProcNo()];
00127
00128 forAll(map, i)
00129 {
00130 newField[map[i]] = subField[i];
00131 }
00132
00133
00134 forAll(schedule, i)
00135 {
00136 const labelPair& twoProcs = schedule[i];
00137 label sendProc = twoProcs[0];
00138 label recvProc = twoProcs[1];
00139
00140 if (Pstream::myProcNo() == sendProc)
00141 {
00142
00143 OPstream toNbr(Pstream::scheduled, recvProc);
00144 toNbr << UIndirectList<T>(field, subMap[recvProc]);
00145 }
00146 else
00147 {
00148
00149 IPstream fromNbr(Pstream::scheduled, sendProc);
00150 List<T> subField(fromNbr);
00151
00152 const labelList& map = constructMap[sendProc];
00153
00154 if (subField.size() != map.size())
00155 {
00156 FatalErrorIn
00157 (
00158 "template<class T>\n"
00159 "void mapDistribute::distribute\n"
00160 "(\n"
00161 " const Pstream::commsTypes commsType,\n"
00162 " const List<labelPair>& schedule,\n"
00163 " const label constructSize,\n"
00164 " const labelListList& subMap,\n"
00165 " const labelListList& constructMap,\n"
00166 " List<T>& field\n"
00167 ")\n"
00168 ) << "Expected from processor " << sendProc
00169 << " " << map.size() << " but received "
00170 << subField.size() << " elements."
00171 << abort(FatalError);
00172 }
00173
00174 forAll(map, i)
00175 {
00176 newField[map[i]] = subField[i];
00177 }
00178 }
00179 }
00180 field.transfer(newField);
00181 }
00182 else if (commsType == Pstream::nonBlocking)
00183 {
00184 if (!contiguous<T>())
00185 {
00186 FatalErrorIn
00187 (
00188 "template<class T>\n"
00189 "void mapDistribute::distribute\n"
00190 "(\n"
00191 " const Pstream::commsTypes commsType,\n"
00192 " const List<labelPair>& schedule,\n"
00193 " const label constructSize,\n"
00194 " const labelListList& subMap,\n"
00195 " const labelListList& constructMap,\n"
00196 " List<T>& field\n"
00197 ")\n"
00198 ) << "Non-blocking only supported for contiguous data."
00199 << exit(FatalError);
00200 }
00201
00202
00203
00204 List<List<T > > sendFields(Pstream::nProcs());
00205
00206 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00207 {
00208 const labelList& map = subMap[domain];
00209
00210 if (domain != Pstream::myProcNo() && map.size())
00211 {
00212 List<T>& subField = sendFields[domain];
00213 subField.setSize(map.size());
00214 forAll(map, i)
00215 {
00216 subField[i] = field[map[i]];
00217 }
00218
00219 OPstream::write
00220 (
00221 Pstream::nonBlocking,
00222 domain,
00223 reinterpret_cast<const char*>(subField.begin()),
00224 subField.size()*sizeof(T)
00225 );
00226 }
00227 }
00228
00229
00230
00231 List<List<T > > recvFields(Pstream::nProcs());
00232
00233 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00234 {
00235 const labelList& map = constructMap[domain];
00236
00237 if (domain != Pstream::myProcNo() && map.size())
00238 {
00239 recvFields[domain].setSize(map.size());
00240 IPstream::read
00241 (
00242 Pstream::nonBlocking,
00243 domain,
00244 reinterpret_cast<char*>(recvFields[domain].begin()),
00245 recvFields[domain].size()*sizeof(T)
00246 );
00247 }
00248 }
00249
00250
00251
00252
00253 {
00254 const labelList& map = subMap[Pstream::myProcNo()];
00255
00256 List<T>& subField = sendFields[Pstream::myProcNo()];
00257 subField.setSize(map.size());
00258 forAll(map, i)
00259 {
00260 subField[i] = field[map[i]];
00261 }
00262 }
00263
00264
00265
00266
00267 field.setSize(constructSize);
00268
00269
00270
00271 {
00272 const labelList& map = constructMap[Pstream::myProcNo()];
00273 const List<T>& subField = sendFields[Pstream::myProcNo()];
00274
00275 forAll(map, i)
00276 {
00277 field[map[i]] = subField[i];
00278 }
00279 }
00280
00281
00282
00283
00284 OPstream::waitRequests();
00285 IPstream::waitRequests();
00286
00287
00288
00289 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00290 {
00291 const labelList& map = constructMap[domain];
00292
00293 if (domain != Pstream::myProcNo() && map.size())
00294 {
00295 if (recvFields[domain].size() != map.size())
00296 {
00297 FatalErrorIn
00298 (
00299 "template<class T>\n"
00300 "void mapDistribute::distribute\n"
00301 "(\n"
00302 " const Pstream::commsTypes commsType,\n"
00303 " const List<labelPair>& schedule,\n"
00304 " const label constructSize,\n"
00305 " const labelListList& subMap,\n"
00306 " const labelListList& constructMap,\n"
00307 " List<T>& field\n"
00308 ")\n"
00309 ) << "Expected from processor " << domain
00310 << " " << map.size() << " but received "
00311 << recvFields[domain].size() << " elements."
00312 << abort(FatalError);
00313 }
00314
00315 forAll(map, i)
00316 {
00317 field[map[i]] = recvFields[domain][i];
00318 }
00319 }
00320 }
00321 }
00322 else
00323 {
00324 FatalErrorIn("mapDistribute::distribute(..)")
00325 << "Unknown communication schedule " << commsType
00326 << abort(FatalError);
00327 }
00328 }
00329
00330
00331
00332 template<class T, class CombineOp>
00333 void Foam::mapDistribute::distribute
00334 (
00335 const Pstream::commsTypes commsType,
00336 const List<labelPair>& schedule,
00337 const label constructSize,
00338 const labelListList& subMap,
00339 const labelListList& constructMap,
00340 List<T>& field,
00341 const CombineOp& cop,
00342 const T& nullValue
00343 )
00344 {
00345 if (commsType == Pstream::blocking)
00346 {
00347
00348
00349
00350
00351 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00352 {
00353 const labelList& map = subMap[domain];
00354
00355 if (domain != Pstream::myProcNo() && map.size())
00356 {
00357 OPstream toNbr(Pstream::blocking, domain);
00358 toNbr << UIndirectList<T>(field, map);
00359 }
00360 }
00361
00362
00363 const labelList& mySubMap = subMap[Pstream::myProcNo()];
00364
00365 List<T> subField(mySubMap.size());
00366 forAll(mySubMap, i)
00367 {
00368 subField[i] = field[mySubMap[i]];
00369 }
00370
00371
00372 const labelList& map = constructMap[Pstream::myProcNo()];
00373
00374 field.setSize(constructSize);
00375 field = nullValue;
00376
00377 forAll(map, i)
00378 {
00379 cop(field[map[i]], subField[i]);
00380 }
00381
00382
00383 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00384 {
00385 const labelList& map = constructMap[domain];
00386
00387 if (domain != Pstream::myProcNo() && map.size())
00388 {
00389 IPstream fromNbr(Pstream::blocking, domain);
00390 List<T> subField(fromNbr);
00391
00392 if (subField.size() != map.size())
00393 {
00394 FatalErrorIn
00395 (
00396 "template<class T>\n"
00397 "void mapDistribute::distribute\n"
00398 "(\n"
00399 " const Pstream::commsTypes commsType,\n"
00400 " const List<labelPair>& schedule,\n"
00401 " const label constructSize,\n"
00402 " const labelListList& subMap,\n"
00403 " const labelListList& constructMap,\n"
00404 " List<T>& field\n"
00405 ")\n"
00406 ) << "Expected from processor " << domain
00407 << " " << map.size() << " but received "
00408 << subField.size() << " elements."
00409 << abort(FatalError);
00410 }
00411
00412 forAll(map, i)
00413 {
00414 cop(field[map[i]], subField[i]);
00415 }
00416 }
00417 }
00418 }
00419 else if (commsType == Pstream::scheduled)
00420 {
00421
00422
00423
00424 List<T> newField(constructSize, nullValue);
00425
00426
00427 UIndirectList<T> subField(field, subMap[Pstream::myProcNo()]);
00428
00429
00430 const labelList& map = constructMap[Pstream::myProcNo()];
00431
00432 forAll(map, i)
00433 {
00434 cop(newField[map[i]], subField[i]);
00435 }
00436
00437
00438 forAll(schedule, i)
00439 {
00440 const labelPair& twoProcs = schedule[i];
00441 label sendProc = twoProcs[0];
00442 label recvProc = twoProcs[1];
00443
00444 if (Pstream::myProcNo() == sendProc)
00445 {
00446
00447 OPstream toNbr(Pstream::scheduled, recvProc);
00448 toNbr << UIndirectList<T>(field, subMap[recvProc]);
00449 }
00450 else
00451 {
00452
00453 IPstream fromNbr(Pstream::scheduled, sendProc);
00454 List<T> subField(fromNbr);
00455
00456 const labelList& map = constructMap[sendProc];
00457
00458 if (subField.size() != map.size())
00459 {
00460 FatalErrorIn
00461 (
00462 "template<class T>\n"
00463 "void mapDistribute::distribute\n"
00464 "(\n"
00465 " const Pstream::commsTypes commsType,\n"
00466 " const List<labelPair>& schedule,\n"
00467 " const label constructSize,\n"
00468 " const labelListList& subMap,\n"
00469 " const labelListList& constructMap,\n"
00470 " List<T>& field\n"
00471 ")\n"
00472 ) << "Expected from processor " << sendProc
00473 << " " << map.size() << " but received "
00474 << subField.size() << " elements."
00475 << abort(FatalError);
00476 }
00477
00478 forAll(map, i)
00479 {
00480 cop(newField[map[i]], subField[i]);
00481 }
00482 }
00483 }
00484 field.transfer(newField);
00485 }
00486 else if (commsType == Pstream::nonBlocking)
00487 {
00488 if (!contiguous<T>())
00489 {
00490 FatalErrorIn
00491 (
00492 "template<class T>\n"
00493 "void mapDistribute::distribute\n"
00494 "(\n"
00495 " const Pstream::commsTypes commsType,\n"
00496 " const List<labelPair>& schedule,\n"
00497 " const label constructSize,\n"
00498 " const labelListList& subMap,\n"
00499 " const labelListList& constructMap,\n"
00500 " List<T>& field\n"
00501 ")\n"
00502 ) << "Non-blocking only supported for contiguous data."
00503 << exit(FatalError);
00504 }
00505
00506
00507
00508 List<List<T > > sendFields(Pstream::nProcs());
00509
00510 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00511 {
00512 const labelList& map = subMap[domain];
00513
00514 if (domain != Pstream::myProcNo() && map.size())
00515 {
00516 List<T>& subField = sendFields[domain];
00517 subField.setSize(map.size());
00518 forAll(map, i)
00519 {
00520 subField[i] = field[map[i]];
00521 }
00522
00523 OPstream::write
00524 (
00525 Pstream::nonBlocking,
00526 domain,
00527 reinterpret_cast<const char*>(subField.begin()),
00528 subField.size()*sizeof(T)
00529 );
00530 }
00531 }
00532
00533
00534
00535 List<List<T > > recvFields(Pstream::nProcs());
00536
00537 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00538 {
00539 const labelList& map = constructMap[domain];
00540
00541 if (domain != Pstream::myProcNo() && map.size())
00542 {
00543 recvFields[domain].setSize(map.size());
00544 IPstream::read
00545 (
00546 Pstream::nonBlocking,
00547 domain,
00548 reinterpret_cast<char*>(recvFields[domain].begin()),
00549 recvFields[domain].size()*sizeof(T)
00550 );
00551 }
00552 }
00553
00554
00555
00556 {
00557 const labelList& map = subMap[Pstream::myProcNo()];
00558
00559 List<T>& subField = sendFields[Pstream::myProcNo()];
00560 subField.setSize(map.size());
00561 forAll(map, i)
00562 {
00563 subField[i] = field[map[i]];
00564 }
00565 }
00566
00567
00568
00569
00570 field.setSize(constructSize);
00571 field = nullValue;
00572
00573
00574 {
00575 const labelList& map = constructMap[Pstream::myProcNo()];
00576 const List<T>& subField = sendFields[Pstream::myProcNo()];
00577
00578 forAll(map, i)
00579 {
00580 cop(field[map[i]], subField[i]);
00581 }
00582 }
00583
00584
00585
00586
00587 OPstream::waitRequests();
00588 IPstream::waitRequests();
00589
00590
00591
00592 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00593 {
00594 const labelList& map = constructMap[domain];
00595
00596 if (domain != Pstream::myProcNo() && map.size())
00597 {
00598 if (recvFields[domain].size() != map.size())
00599 {
00600 FatalErrorIn
00601 (
00602 "template<class T>\n"
00603 "void mapDistribute::distribute\n"
00604 "(\n"
00605 " const Pstream::commsTypes commsType,\n"
00606 " const List<labelPair>& schedule,\n"
00607 " const label constructSize,\n"
00608 " const labelListList& subMap,\n"
00609 " const labelListList& constructMap,\n"
00610 " List<T>& field\n"
00611 ")\n"
00612 ) << "Expected from processor " << domain
00613 << " " << map.size() << " but received "
00614 << recvFields[domain].size() << " elements."
00615 << abort(FatalError);
00616 }
00617
00618 forAll(map, i)
00619 {
00620 cop(field[map[i]], recvFields[domain][i]);
00621 }
00622 }
00623 }
00624 }
00625 else
00626 {
00627 FatalErrorIn("mapDistribute::distribute(..)")
00628 << "Unknown communication schedule " << commsType
00629 << abort(FatalError);
00630 }
00631 }
00632
00633
00634