Go to the documentation of this file.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
00027
00028
00029
00030
00031
00032
00033 #include "domainDecomposition.H"
00034 #include <OpenFOAM/IOstreams.H>
00035 #include <OpenFOAM/SLPtrList.H>
00036 #include <OpenFOAM/boolList.H>
00037 #include <OpenFOAM/primitiveMesh.H>
00038 #include <OpenFOAM/cyclicPolyPatch.H>
00039
00040
00041
00042 void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
00043 {
00044
00045 distributeCells();
00046
00047
00048
00049
00050 Info<< "\nCalculating original mesh data" << endl;
00051
00052
00053 const polyBoundaryMesh& patches = boundaryMesh();
00054 const faceList& fcs = faces();
00055 const labelList& owner = faceOwner();
00056 const labelList& neighbour = faceNeighbour();
00057
00058
00059
00060
00061 Info<< "\nDistributing cells to processors" << endl;
00062
00063
00064 {
00065 List<SLList<label> > procCellList(nProcs_);
00066
00067 forAll (cellToProc_, celli)
00068 {
00069 if (cellToProc_[celli] >= nProcs_)
00070 {
00071 FatalErrorIn("domainDecomposition::decomposeMesh()")
00072 << "Impossible processor label " << cellToProc_[celli]
00073 << "for cell " << celli
00074 << abort(FatalError);
00075 }
00076 else
00077 {
00078 procCellList[cellToProc_[celli]].append(celli);
00079 }
00080 }
00081
00082
00083 forAll (procCellList, procI)
00084 {
00085 procCellAddressing_[procI] = procCellList[procI];
00086 }
00087 }
00088
00089 Info << "\nDistributing faces to processors" << endl;
00090
00091
00092
00093
00094
00095
00096
00097 {
00098 List<SLList<label> > procFaceList(nProcs_);
00099
00100 forAll (neighbour, facei)
00101 {
00102 if (cellToProc_[owner[facei]] == cellToProc_[neighbour[facei]])
00103 {
00104
00105 procFaceList[cellToProc_[owner[facei]]].append(facei);
00106 }
00107 }
00108
00109
00110
00111
00112 List<SLList<label> > interProcBoundaries(nProcs_);
00113
00114
00115 List<SLList<SLList<label> > > interProcBFaces(nProcs_);
00116
00117 List<SLList<label> > procPatchIndex(nProcs_);
00118
00119 forAll (neighbour, facei)
00120 {
00121 if (cellToProc_[owner[facei]] != cellToProc_[neighbour[facei]])
00122 {
00123
00124
00125
00126
00127 label ownerProc = cellToProc_[owner[facei]];
00128 label neighbourProc = cellToProc_[neighbour[facei]];
00129
00130 SLList<label>::iterator curInterProcBdrsOwnIter =
00131 interProcBoundaries[ownerProc].begin();
00132
00133 SLList<SLList<label> >::iterator curInterProcBFacesOwnIter =
00134 interProcBFaces[ownerProc].begin();
00135
00136 bool interProcBouFound = false;
00137
00138
00139
00140 for
00141 (
00142 ;
00143 curInterProcBdrsOwnIter
00144 != interProcBoundaries[ownerProc].end()
00145 && curInterProcBFacesOwnIter
00146 != interProcBFaces[ownerProc].end();
00147 ++curInterProcBdrsOwnIter, ++curInterProcBFacesOwnIter
00148 )
00149 {
00150 if (curInterProcBdrsOwnIter() == neighbourProc)
00151 {
00152
00153 interProcBouFound = true;
00154
00155 curInterProcBFacesOwnIter().append(facei);
00156
00157 SLList<label>::iterator curInterProcBdrsNeiIter =
00158 interProcBoundaries[neighbourProc].begin();
00159
00160 SLList<SLList<label> >::iterator
00161 curInterProcBFacesNeiIter =
00162 interProcBFaces[neighbourProc].begin();
00163
00164 bool neighbourFound = false;
00165
00166
00167
00168 for
00169 (
00170 ;
00171 curInterProcBdrsNeiIter !=
00172 interProcBoundaries[neighbourProc].end()
00173 && curInterProcBFacesNeiIter !=
00174 interProcBFaces[neighbourProc].end();
00175 ++curInterProcBdrsNeiIter,
00176 ++curInterProcBFacesNeiIter
00177 )
00178 {
00179 if (curInterProcBdrsNeiIter() == ownerProc)
00180 {
00181
00182 neighbourFound = true;
00183
00184 curInterProcBFacesNeiIter().append(facei);
00185 }
00186
00187 if (neighbourFound) break;
00188 }
00189
00190 if (interProcBouFound && !neighbourFound)
00191 {
00192 FatalErrorIn("domainDecomposition::decomposeMesh()")
00193 << "Inconsistency in inter - "
00194 << "processor boundary lists for processors "
00195 << ownerProc << " and " << neighbourProc
00196 << abort(FatalError);
00197 }
00198 }
00199
00200 if (interProcBouFound) break;
00201 }
00202
00203 if (!interProcBouFound)
00204 {
00205
00206
00207
00208
00209
00210
00211 interProcBoundaries[ownerProc].append(neighbourProc);
00212 interProcBFaces[ownerProc].append(SLList<label>(facei));
00213
00214
00215 interProcBoundaries[neighbourProc].append(ownerProc);
00216 interProcBFaces[neighbourProc].append(SLList<label>(facei));
00217 }
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 forAll (procPatchSize_, procI)
00228 {
00229 procPatchSize_[procI].setSize(patches.size());
00230 procPatchStartIndex_[procI].setSize(patches.size());
00231 }
00232
00233 forAll (patches, patchi)
00234 {
00235
00236 forAll (procPatchSize_, procI)
00237 {
00238 procPatchSize_[procI][patchi] = 0;
00239 procPatchStartIndex_[procI][patchi] =
00240 procFaceList[procI].size();
00241 }
00242
00243 const label patchStart = patches[patchi].start();
00244
00245 if (!isA<cyclicPolyPatch>(patches[patchi]))
00246 {
00247
00248
00249
00250 const unallocLabelList& patchFaceCells =
00251 patches[patchi].faceCells();
00252
00253 forAll (patchFaceCells, facei)
00254 {
00255 const label curProc = cellToProc_[patchFaceCells[facei]];
00256
00257
00258 procFaceList[curProc].append(patchStart + facei);
00259
00260
00261 procPatchSize_[curProc][patchi]++;
00262 }
00263 }
00264 else
00265 {
00266
00267
00268 const polyPatch& cPatch = patches[patchi];
00269
00270 const label cycOffset = cPatch.size()/2;
00271
00272
00273 const labelList::subList firstFaceCells
00274 (
00275 cPatch.faceCells(),
00276 cycOffset
00277 );
00278
00279 const labelList::subList secondFaceCells
00280 (
00281 cPatch.faceCells(),
00282 cycOffset,
00283 cycOffset
00284 );
00285
00286 forAll (firstFaceCells, facei)
00287 {
00288 if
00289 (
00290 cellToProc_[firstFaceCells[facei]]
00291 != cellToProc_[secondFaceCells[facei]]
00292 )
00293 {
00294
00295
00296
00297
00298
00299
00300 cyclicParallel_ = true;
00301
00302 label ownerProc = cellToProc_[firstFaceCells[facei]];
00303 label neighbourProc =
00304 cellToProc_[secondFaceCells[facei]];
00305
00306 SLList<label>::iterator curInterProcBdrsOwnIter =
00307 interProcBoundaries[ownerProc].begin();
00308
00309 SLList<SLList<label> >::iterator
00310 curInterProcBFacesOwnIter =
00311 interProcBFaces[ownerProc].begin();
00312
00313 bool interProcBouFound = false;
00314
00315
00316
00317 for
00318 (
00319 ;
00320 curInterProcBdrsOwnIter !=
00321 interProcBoundaries[ownerProc].end()
00322 && curInterProcBFacesOwnIter !=
00323 interProcBFaces[ownerProc].end();
00324 ++curInterProcBdrsOwnIter,
00325 ++curInterProcBFacesOwnIter
00326 )
00327 {
00328 if (curInterProcBdrsOwnIter() == neighbourProc)
00329 {
00330
00331
00332 interProcBouFound = true;
00333
00334 curInterProcBFacesOwnIter().append
00335 (patchStart + facei);
00336
00337 SLList<label>::iterator curInterProcBdrsNeiIter
00338 = interProcBoundaries[neighbourProc].begin();
00339
00340 SLList<SLList<label> >::iterator
00341 curInterProcBFacesNeiIter =
00342 interProcBFaces[neighbourProc].begin();
00343
00344 bool neighbourFound = false;
00345
00346
00347
00348 for
00349 (
00350 ;
00351 curInterProcBdrsNeiIter
00352 != interProcBoundaries[neighbourProc].end()
00353 && curInterProcBFacesNeiIter
00354 != interProcBFaces[neighbourProc].end();
00355 ++curInterProcBdrsNeiIter,
00356 ++curInterProcBFacesNeiIter
00357 )
00358 {
00359 if (curInterProcBdrsNeiIter() == ownerProc)
00360 {
00361
00362 neighbourFound = true;
00363
00364 curInterProcBFacesNeiIter()
00365 .append
00366 (
00367 patchStart
00368 + cycOffset
00369 + facei
00370 );
00371 }
00372
00373 if (neighbourFound) break;
00374 }
00375
00376 if (interProcBouFound && !neighbourFound)
00377 {
00378 FatalErrorIn
00379 (
00380 "domainDecomposition::decomposeMesh()"
00381 ) << "Inconsistency in inter-processor "
00382 << "boundary lists for processors "
00383 << ownerProc << " and " << neighbourProc
00384 << " in cyclic boundary matching"
00385 << abort(FatalError);
00386 }
00387 }
00388
00389 if (interProcBouFound) break;
00390 }
00391
00392 if (!interProcBouFound)
00393 {
00394
00395
00396
00397
00398
00399
00400 interProcBoundaries[ownerProc]
00401 .append(neighbourProc);
00402 interProcBFaces[ownerProc]
00403 .append(SLList<label>(patchStart + facei));
00404
00405
00406 interProcBoundaries[neighbourProc]
00407 .append(ownerProc);
00408 interProcBFaces[neighbourProc]
00409 .append
00410 (
00411 SLList<label>
00412 (
00413 patchStart
00414 + cycOffset
00415 + facei
00416 )
00417 );
00418 }
00419 }
00420 else
00421 {
00422
00423 label ownerProc = cellToProc_[firstFaceCells[facei]];
00424
00425
00426 procFaceList[ownerProc].append(patchStart + facei);
00427
00428
00429 procPatchSize_[ownerProc][patchi]++;
00430
00431
00432
00433
00434
00435 }
00436 }
00437
00438
00439
00440
00441 forAll (secondFaceCells, facei)
00442 {
00443 if
00444 (
00445 cellToProc_[firstFaceCells[facei]]
00446 == cellToProc_[secondFaceCells[facei]]
00447 )
00448 {
00449
00450 label ownerProc = cellToProc_[firstFaceCells[facei]];
00451
00452
00453 procFaceList[ownerProc].append
00454 (patchStart + cycOffset + facei);
00455
00456
00457 procPatchSize_[ownerProc][patchi]++;
00458 }
00459 }
00460 }
00461 }
00462
00463
00464
00465 forAll (procFaceList, procI)
00466 {
00467
00468 SLList<label>& curProcFaces = procFaceList[procI];
00469
00470
00471 labelList& curProcFaceAddressing = procFaceAddressing_[procI];
00472
00473 labelList& curProcNeighbourProcessors =
00474 procNeighbourProcessors_[procI];
00475
00476 labelList& curProcProcessorPatchSize =
00477 procProcessorPatchSize_[procI];
00478
00479 labelList& curProcProcessorPatchStartIndex =
00480 procProcessorPatchStartIndex_[procI];
00481
00482
00483 label nFacesOnProcessor = curProcFaces.size();
00484
00485 for
00486 (
00487 SLList<SLList<label> >::iterator curInterProcBFacesIter =
00488 interProcBFaces[procI].begin();
00489 curInterProcBFacesIter != interProcBFaces[procI].end();
00490 ++curInterProcBFacesIter
00491 )
00492 {
00493 nFacesOnProcessor += curInterProcBFacesIter().size();
00494 }
00495
00496 curProcFaceAddressing.setSize(nFacesOnProcessor);
00497
00498
00499
00500
00501
00502
00503
00504 label nFaces = 0;
00505
00506
00507
00508
00509 for
00510 (
00511 SLList<label>::iterator curProcFacesIter = curProcFaces.begin();
00512 curProcFacesIter != curProcFaces.end();
00513 ++curProcFacesIter
00514 )
00515 {
00516 curProcFaceAddressing[nFaces] = curProcFacesIter() + 1;
00517 nFaces++;
00518 }
00519
00520
00521
00522
00523 curProcNeighbourProcessors.setSize
00524 (
00525 interProcBoundaries[procI].size()
00526 );
00527
00528 curProcProcessorPatchSize.setSize
00529 (
00530 interProcBoundaries[procI].size()
00531 );
00532
00533 curProcProcessorPatchStartIndex.setSize
00534 (
00535 interProcBoundaries[procI].size()
00536 );
00537
00538 label nProcPatches = 0;
00539
00540 SLList<label>::iterator curInterProcBdrsIter =
00541 interProcBoundaries[procI].begin();
00542
00543 SLList<SLList<label> >::iterator curInterProcBFacesIter =
00544 interProcBFaces[procI].begin();
00545
00546 for
00547 (
00548 ;
00549 curInterProcBdrsIter != interProcBoundaries[procI].end()
00550 && curInterProcBFacesIter != interProcBFaces[procI].end();
00551 ++curInterProcBdrsIter, ++curInterProcBFacesIter
00552 )
00553 {
00554 curProcNeighbourProcessors[nProcPatches] =
00555 curInterProcBdrsIter();
00556
00557
00558 curProcProcessorPatchStartIndex[nProcPatches] = nFaces;
00559
00560 label& curSize =
00561 curProcProcessorPatchSize[nProcPatches];
00562
00563 curSize = 0;
00564
00565
00566
00567 for
00568 (
00569 SLList<label>::iterator curFacesIter =
00570 curInterProcBFacesIter().begin();
00571 curFacesIter != curInterProcBFacesIter().end();
00572 ++curFacesIter
00573 )
00574 {
00575
00576
00577
00578
00579 if (cellToProc_[owner[curFacesIter()]] == procI)
00580 {
00581 curProcFaceAddressing[nFaces] = curFacesIter() + 1;
00582 }
00583 else
00584 {
00585
00586 curProcFaceAddressing[nFaces] = -(curFacesIter() + 1);
00587 }
00588
00589
00590 curSize++;
00591
00592 nFaces++;
00593 }
00594
00595 nProcPatches++;
00596 }
00597 }
00598 }
00599
00600 Info << "\nCalculating processor boundary addressing" << endl;
00601
00602
00603
00604
00605
00606 forAll (procPatchSize_, procI)
00607 {
00608
00609 const labelList oldPatchSizes = procPatchSize_[procI];
00610
00611 const labelList oldPatchStarts = procPatchStartIndex_[procI];
00612
00613 labelList& curPatchSizes = procPatchSize_[procI];
00614
00615 labelList& curPatchStarts = procPatchStartIndex_[procI];
00616
00617 const labelList& curProcessorPatchSizes =
00618 procProcessorPatchSize_[procI];
00619
00620 labelList& curBoundaryAddressing = procBoundaryAddressing_[procI];
00621
00622 curBoundaryAddressing.setSize
00623 (
00624 oldPatchSizes.size()
00625 + curProcessorPatchSizes.size()
00626 );
00627
00628 label nPatches = 0;
00629
00630 forAll (oldPatchSizes, patchi)
00631 {
00632 if (!filterEmptyPatches || oldPatchSizes[patchi] > 0)
00633 {
00634 curBoundaryAddressing[nPatches] = patchi;
00635
00636 curPatchSizes[nPatches] = oldPatchSizes[patchi];
00637
00638 curPatchStarts[nPatches] = oldPatchStarts[patchi];
00639
00640 nPatches++;
00641 }
00642 }
00643
00644
00645 curPatchSizes.setSize(nPatches);
00646 curPatchStarts.setSize(nPatches);
00647
00648 forAll (curProcessorPatchSizes, procPatchI)
00649 {
00650 curBoundaryAddressing[nPatches] = -1;
00651
00652 nPatches++;
00653 }
00654
00655 curBoundaryAddressing.setSize(nPatches);
00656 }
00657
00658 Info << "\nDistributing points to processors" << endl;
00659
00660
00661
00662
00663
00664 forAll (procPointAddressing_, procI)
00665 {
00666 boolList pointLabels(nPoints(), false);
00667
00668
00669 const labelList& procFaceLabels = procFaceAddressing_[procI];
00670
00671 forAll (procFaceLabels, facei)
00672 {
00673
00674 const labelList& facePoints = fcs[mag(procFaceLabels[facei]) - 1];
00675
00676 forAll (facePoints, pointi)
00677 {
00678
00679 pointLabels[facePoints[pointi]] = true;
00680 }
00681 }
00682
00683
00684 labelList& procPointLabels = procPointAddressing_[procI];
00685
00686 procPointLabels.setSize(pointLabels.size());
00687
00688 label nUsedPoints = 0;
00689
00690 forAll (pointLabels, pointi)
00691 {
00692 if (pointLabels[pointi])
00693 {
00694 procPointLabels[nUsedPoints] = pointi;
00695
00696 nUsedPoints++;
00697 }
00698 }
00699
00700
00701 procPointLabels.setSize(nUsedPoints);
00702 }
00703
00704
00705
00706
00707 {
00708 labelList pointsUsage(nPoints(), 0);
00709
00710
00711
00712 labelHashSet gSharedPoints
00713 (
00714 min(100, nPoints()/1000)
00715 );
00716
00717
00718
00719
00720
00721 for (label procI = 0; procI < nProcs_; procI++)
00722 {
00723
00724 const labelList& curFaceLabels = procFaceAddressing_[procI];
00725
00726
00727 const labelList& curProcessorPatchStarts =
00728 procProcessorPatchStartIndex_[procI];
00729
00730 const labelList& curProcessorPatchSizes =
00731 procProcessorPatchSize_[procI];
00732
00733
00734 pointsUsage = 0;
00735
00736 forAll (curProcessorPatchStarts, patchi)
00737 {
00738 const label curStart = curProcessorPatchStarts[patchi];
00739 const label curEnd = curStart + curProcessorPatchSizes[patchi];
00740
00741 for
00742 (
00743 label facei = curStart;
00744 facei < curEnd;
00745 facei++
00746 )
00747 {
00748
00749
00750
00751 const label curF = mag(curFaceLabels[facei]) - 1;
00752
00753 const face& f = fcs[curF];
00754
00755 forAll (f, pointi)
00756 {
00757 if (pointsUsage[f[pointi]] == 0)
00758 {
00759
00760 pointsUsage[f[pointi]] = patchi + 1;
00761 }
00762 else if (pointsUsage[f[pointi]] != patchi + 1)
00763 {
00764
00765 gSharedPoints.insert(f[pointi]);
00766 }
00767 }
00768 }
00769 }
00770 }
00771
00772
00773 globallySharedPoints_ = gSharedPoints.toc();
00774 sort(globallySharedPoints_);
00775 }
00776 }