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 "syncTools.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 #include <OpenFOAM/processorPolyPatch.H>
00029 #include <OpenFOAM/cyclicPolyPatch.H>
00030 #include <OpenFOAM/globalMeshData.H>
00031 #include <OpenFOAM/contiguous.H>
00032 #include <OpenFOAM/transform.H>
00033
00034
00035
00036 template <class T>
00037 void Foam::syncTools::separateList
00038 (
00039 const vectorField& separation,
00040 UList<T>& field
00041 )
00042 {}
00043
00044
00045 template <class T>
00046 void Foam::syncTools::separateList
00047 (
00048 const vectorField& separation,
00049 Map<T>& field
00050 )
00051 {}
00052
00053
00054 template <class T>
00055 void Foam::syncTools::separateList
00056 (
00057 const vectorField& separation,
00058 EdgeMap<T>& field
00059 )
00060 {}
00061
00062
00063
00064 template <class T, class CombineOp>
00065 void Foam::syncTools::combine
00066 (
00067 Map<T>& pointValues,
00068 const CombineOp& cop,
00069 const label index,
00070 const T& val
00071 )
00072 {
00073 typename Map<T>::iterator iter = pointValues.find(index);
00074
00075 if (iter != pointValues.end())
00076 {
00077 cop(iter(), val);
00078 }
00079 else
00080 {
00081 pointValues.insert(index, val);
00082 }
00083 }
00084
00085
00086
00087 template <class T, class CombineOp>
00088 void Foam::syncTools::combine
00089 (
00090 EdgeMap<T>& edgeValues,
00091 const CombineOp& cop,
00092 const edge& index,
00093 const T& val
00094 )
00095 {
00096 typename EdgeMap<T>::iterator iter = edgeValues.find(index);
00097
00098 if (iter != edgeValues.end())
00099 {
00100 cop(iter(), val);
00101 }
00102 else
00103 {
00104 edgeValues.insert(index, val);
00105 }
00106 }
00107
00108
00109 template <class T, class CombineOp>
00110 void Foam::syncTools::syncPointMap
00111 (
00112 const polyMesh& mesh,
00113 Map<T>& pointValues,
00114 const CombineOp& cop,
00115 const bool applySeparation
00116 )
00117 {
00118 const polyBoundaryMesh& patches = mesh.boundaryMesh();
00119
00120 if (!hasCouples(patches))
00121 {
00122 return;
00123 }
00124
00125
00126 bool hasTransformation = false;
00127
00128 if (Pstream::parRun())
00129 {
00130
00131
00132 forAll(patches, patchI)
00133 {
00134 if
00135 (
00136 isA<processorPolyPatch>(patches[patchI])
00137 && patches[patchI].nPoints() > 0
00138 )
00139 {
00140 const processorPolyPatch& procPatch =
00141 refCast<const processorPolyPatch>(patches[patchI]);
00142
00143
00144
00145 const labelList& meshPts = procPatch.meshPoints();
00146 const labelList& nbrPts = procPatch.neighbPoints();
00147
00148
00149
00150 Map<T> patchInfo(meshPts.size() / 20);
00151
00152 forAll(meshPts, i)
00153 {
00154 typename Map<T>::const_iterator iter =
00155 pointValues.find(meshPts[i]);
00156
00157 if (iter != pointValues.end())
00158 {
00159 if (nbrPts[i] >= 0)
00160 {
00161 patchInfo.insert(nbrPts[i], iter());
00162 }
00163 }
00164 }
00165
00166 OPstream toNeighb(Pstream::blocking, procPatch.neighbProcNo());
00167 toNeighb << patchInfo;
00168 }
00169 }
00170
00171
00172
00173
00174 forAll(patches, patchI)
00175 {
00176 if
00177 (
00178 isA<processorPolyPatch>(patches[patchI])
00179 && patches[patchI].nPoints() > 0
00180 )
00181 {
00182 const processorPolyPatch& procPatch =
00183 refCast<const processorPolyPatch>(patches[patchI]);
00184 checkTransform(procPatch, applySeparation);
00185
00186 IPstream fromNb(Pstream::blocking, procPatch.neighbProcNo());
00187 Map<T> nbrPatchInfo(fromNb);
00188
00189 if (!procPatch.parallel())
00190 {
00191 hasTransformation = true;
00192 transformList(procPatch.forwardT(), nbrPatchInfo);
00193 }
00194 else if (applySeparation && procPatch.separated())
00195 {
00196 hasTransformation = true;
00197 separateList(-procPatch.separation(), nbrPatchInfo);
00198 }
00199
00200 const labelList& meshPts = procPatch.meshPoints();
00201
00202
00203
00204 forAllConstIter
00205 (
00206 typename Map<T>,
00207 nbrPatchInfo,
00208 nbrIter
00209 )
00210 {
00211 combine
00212 (
00213 pointValues,
00214 cop,
00215 meshPts[nbrIter.key()],
00216 nbrIter()
00217 );
00218 }
00219 }
00220 }
00221 }
00222
00223
00224 forAll(patches, patchI)
00225 {
00226 if (isA<cyclicPolyPatch>(patches[patchI]))
00227 {
00228 const cyclicPolyPatch& cycPatch =
00229 refCast<const cyclicPolyPatch>(patches[patchI]);
00230 checkTransform(cycPatch, applySeparation);
00231
00232 const edgeList& coupledPoints = cycPatch.coupledPoints();
00233 const labelList& meshPts = cycPatch.meshPoints();
00234
00235
00236 Map<T> half0Values(meshPts.size() / 20);
00237 Map<T> half1Values(meshPts.size() / 20);
00238
00239 forAll(coupledPoints, i)
00240 {
00241 const edge& e = coupledPoints[i];
00242
00243 typename Map<T>::const_iterator point0Fnd =
00244 pointValues.find(meshPts[e[0]]);
00245
00246 if (point0Fnd != pointValues.end())
00247 {
00248 half0Values.insert(i, point0Fnd());
00249 }
00250
00251 typename Map<T>::const_iterator point1Fnd =
00252 pointValues.find(meshPts[e[1]]);
00253
00254 if (point1Fnd != pointValues.end())
00255 {
00256 half1Values.insert(i, point1Fnd());
00257 }
00258 }
00259
00260 if (!cycPatch.parallel())
00261 {
00262 hasTransformation = true;
00263 transformList(cycPatch.reverseT(), half0Values);
00264 transformList(cycPatch.forwardT(), half1Values);
00265 }
00266 else if (applySeparation && cycPatch.separated())
00267 {
00268 hasTransformation = true;
00269
00270 const vectorField& v = cycPatch.coupledPolyPatch::separation();
00271 separateList(v, half0Values);
00272 separateList(-v, half1Values);
00273 }
00274
00275 forAll(coupledPoints, i)
00276 {
00277 const edge& e = coupledPoints[i];
00278
00279 typename Map<T>::const_iterator half1Fnd = half1Values.find(i);
00280
00281 if (half1Fnd != half1Values.end())
00282 {
00283 combine
00284 (
00285 pointValues,
00286 cop,
00287 meshPts[e[0]],
00288 half1Fnd()
00289 );
00290 }
00291
00292 typename Map<T>::const_iterator half0Fnd = half0Values.find(i);
00293
00294 if (half0Fnd != half0Values.end())
00295 {
00296 combine
00297 (
00298 pointValues,
00299 cop,
00300 meshPts[e[1]],
00301 half0Fnd()
00302 );
00303 }
00304 }
00305 }
00306 }
00307
00308
00309
00310
00311
00312
00313 const globalMeshData& pd = mesh.globalData();
00314
00315 if (pd.nGlobalPoints() > 0)
00316 {
00317 if (hasTransformation)
00318 {
00319 WarningIn
00320 (
00321 "syncTools<class T, class CombineOp>::syncPointMap"
00322 "(const polyMesh&, Map<T>&, const CombineOp&"
00323 ", const bool)"
00324 ) << "There are decomposed cyclics in this mesh with"
00325 << " transformations." << endl
00326 << "This is not supported. The result will be incorrect"
00327 << endl;
00328 }
00329
00330 const labelList& sharedPtLabels = pd.sharedPointLabels();
00331
00332 const labelList& sharedPtAddr = pd.sharedPointAddr();
00333
00334
00335 Map<T> sharedPointValues(sharedPtAddr.size());
00336
00337
00338
00339 forAll(sharedPtLabels, i)
00340 {
00341 label meshPointI = sharedPtLabels[i];
00342
00343 typename Map<T>::const_iterator fnd =
00344 pointValues.find(meshPointI);
00345
00346 if (fnd != pointValues.end())
00347 {
00348 combine
00349 (
00350 sharedPointValues,
00351 cop,
00352 sharedPtAddr[i],
00353 fnd()
00354 );
00355 }
00356 }
00357
00358
00359
00360 if (Pstream::parRun())
00361 {
00362 if (Pstream::master())
00363 {
00364
00365 for
00366 (
00367 int slave=Pstream::firstSlave();
00368 slave<=Pstream::lastSlave();
00369 slave++
00370 )
00371 {
00372 IPstream fromSlave(Pstream::blocking, slave);
00373 Map<T> nbrValues(fromSlave);
00374
00375
00376 forAllConstIter(typename Map<T>, nbrValues, iter)
00377 {
00378 combine
00379 (
00380 sharedPointValues,
00381 cop,
00382 iter.key(),
00383 iter()
00384 );
00385 }
00386 }
00387
00388
00389 for
00390 (
00391 int slave=Pstream::firstSlave();
00392 slave<=Pstream::lastSlave();
00393 slave++
00394 )
00395 {
00396 OPstream toSlave(Pstream::blocking, slave);
00397 toSlave << sharedPointValues;
00398 }
00399 }
00400 else
00401 {
00402
00403 {
00404 OPstream toMaster
00405 (
00406 Pstream::blocking,
00407 Pstream::masterNo()
00408 );
00409 toMaster << sharedPointValues;
00410 }
00411
00412 {
00413 IPstream fromMaster
00414 (
00415 Pstream::blocking,
00416 Pstream::masterNo()
00417 );
00418 fromMaster >> sharedPointValues;
00419 }
00420 }
00421 }
00422
00423
00424
00425
00426
00427
00428 Map<label> sharedToMeshPoint(2*sharedPtAddr.size());
00429 forAll(sharedPtAddr, i)
00430 {
00431 sharedToMeshPoint.insert(sharedPtAddr[i], sharedPtLabels[i]);
00432 }
00433
00434 forAllConstIter(Map<label>, sharedToMeshPoint, iter)
00435 {
00436
00437 typename Map<T>::const_iterator sharedFnd =
00438 sharedPointValues.find(iter.key());
00439
00440 if (sharedFnd != sharedPointValues.end())
00441 {
00442 combine
00443 (
00444 pointValues,
00445 cop,
00446 iter(),
00447 sharedFnd()
00448 );
00449 }
00450 }
00451 }
00452 }
00453
00454
00455 template <class T, class CombineOp>
00456 void Foam::syncTools::syncEdgeMap
00457 (
00458 const polyMesh& mesh,
00459 EdgeMap<T>& edgeValues,
00460 const CombineOp& cop,
00461 const bool applySeparation
00462 )
00463 {
00464 const polyBoundaryMesh& patches = mesh.boundaryMesh();
00465
00466 if (!hasCouples(patches))
00467 {
00468 return;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 if (Pstream::parRun())
00480 {
00481
00482
00483 forAll(patches, patchI)
00484 {
00485 if
00486 (
00487 isA<processorPolyPatch>(patches[patchI])
00488 && patches[patchI].nEdges() > 0
00489 )
00490 {
00491 const processorPolyPatch& procPatch =
00492 refCast<const processorPolyPatch>(patches[patchI]);
00493
00494
00495
00496 const edgeList& edges = procPatch.edges();
00497 const labelList& meshPts = procPatch.meshPoints();
00498 const labelList& nbrPts = procPatch.neighbPoints();
00499
00500 EdgeMap<T> patchInfo(edges.size() / 20);
00501
00502 forAll(edges, i)
00503 {
00504 const edge& e = edges[i];
00505 const edge meshEdge(meshPts[e[0]], meshPts[e[1]]);
00506
00507 typename EdgeMap<T>::const_iterator iter =
00508 edgeValues.find(meshEdge);
00509
00510 if (iter != edgeValues.end())
00511 {
00512 const edge nbrEdge(nbrPts[e[0]], nbrPts[e[1]]);
00513
00514 if (nbrEdge[0] >= 0 && nbrEdge[1] >= 0)
00515 {
00516 patchInfo.insert(nbrEdge, iter());
00517 }
00518 }
00519 }
00520
00521 OPstream toNeighb(Pstream::blocking, procPatch.neighbProcNo());
00522 toNeighb << patchInfo;
00523 }
00524 }
00525
00526
00527
00528
00529 forAll(patches, patchI)
00530 {
00531 if
00532 (
00533 isA<processorPolyPatch>(patches[patchI])
00534 && patches[patchI].nEdges() > 0
00535 )
00536 {
00537 const processorPolyPatch& procPatch =
00538 refCast<const processorPolyPatch>(patches[patchI]);
00539 checkTransform(procPatch, applySeparation);
00540
00541 const labelList& meshPts = procPatch.meshPoints();
00542
00543 IPstream fromNbr(Pstream::blocking, procPatch.neighbProcNo());
00544 EdgeMap<T> nbrPatchInfo(fromNbr);
00545
00546 if (!procPatch.parallel())
00547 {
00548 transformList(procPatch.forwardT(), nbrPatchInfo);
00549 }
00550 else if (applySeparation && procPatch.separated())
00551 {
00552 separateList(-procPatch.separation(), nbrPatchInfo);
00553 }
00554
00555
00556
00557 forAllConstIter
00558 (
00559 typename EdgeMap<T>,
00560 nbrPatchInfo,
00561 nbrIter
00562 )
00563 {
00564 const edge& e = nbrIter.key();
00565 const edge meshEdge(meshPts[e[0]], meshPts[e[1]]);
00566
00567 combine
00568 (
00569 edgeValues,
00570 cop,
00571 meshEdge,
00572 nbrIter()
00573 );
00574 }
00575 }
00576 }
00577 }
00578
00579
00580
00581
00582
00583 forAll(patches, patchI)
00584 {
00585 if (isA<cyclicPolyPatch>(patches[patchI]))
00586 {
00587 const cyclicPolyPatch& cycPatch =
00588 refCast<const cyclicPolyPatch>(patches[patchI]);
00589 checkTransform(cycPatch, applySeparation);
00590
00591 const edgeList& coupledEdges = cycPatch.coupledEdges();
00592 const labelList& meshPts = cycPatch.meshPoints();
00593 const edgeList& edges = cycPatch.edges();
00594
00595
00596 Map<T> half0Values(meshPts.size() / 20);
00597 Map<T> half1Values(meshPts.size() / 20);
00598
00599 forAll(coupledEdges, i)
00600 {
00601 const edge& twoEdges = coupledEdges[i];
00602
00603 {
00604 const edge& e0 = edges[twoEdges[0]];
00605 const edge meshEdge0(meshPts[e0[0]], meshPts[e0[1]]);
00606
00607 typename EdgeMap<T>::const_iterator iter =
00608 edgeValues.find(meshEdge0);
00609
00610 if (iter != edgeValues.end())
00611 {
00612 half0Values.insert(i, iter());
00613 }
00614 }
00615 {
00616 const edge& e1 = edges[twoEdges[1]];
00617 const edge meshEdge1(meshPts[e1[0]], meshPts[e1[1]]);
00618
00619 typename EdgeMap<T>::const_iterator iter =
00620 edgeValues.find(meshEdge1);
00621
00622 if (iter != edgeValues.end())
00623 {
00624 half1Values.insert(i, iter());
00625 }
00626 }
00627 }
00628
00629
00630
00631
00632 if (!cycPatch.parallel())
00633 {
00634 transformList(cycPatch.reverseT(), half0Values);
00635 transformList(cycPatch.forwardT(), half1Values);
00636 }
00637 else if (applySeparation && cycPatch.separated())
00638 {
00639 const vectorField& v = cycPatch.coupledPolyPatch::separation();
00640 separateList(v, half0Values);
00641 separateList(-v, half1Values);
00642 }
00643
00644
00645
00646
00647 forAll(coupledEdges, i)
00648 {
00649 const edge& twoEdges = coupledEdges[i];
00650
00651 typename Map<T>::const_iterator half1Fnd =
00652 half1Values.find(i);
00653
00654 if (half1Fnd != half1Values.end())
00655 {
00656 const edge& e0 = edges[twoEdges[0]];
00657 const edge meshEdge0(meshPts[e0[0]], meshPts[e0[1]]);
00658
00659 combine
00660 (
00661 edgeValues,
00662 cop,
00663 meshEdge0,
00664 half1Fnd()
00665 );
00666 }
00667
00668 typename Map<T>::const_iterator half0Fnd =
00669 half0Values.find(i);
00670 if (half0Fnd != half0Values.end())
00671 {
00672 const edge& e1 = edges[twoEdges[1]];
00673 const edge meshEdge1(meshPts[e1[0]], meshPts[e1[1]]);
00674
00675 combine
00676 (
00677 edgeValues,
00678 cop,
00679 meshEdge1,
00680 half0Fnd()
00681 );
00682 }
00683 }
00684 }
00685 }
00686
00687
00688
00689
00690
00691
00692 const globalMeshData& pd = mesh.globalData();
00693 const labelList& sharedPtAddr = pd.sharedPointAddr();
00694 const labelList& sharedPtLabels = pd.sharedPointLabels();
00695
00696
00697 Map<label> meshToShared(2*sharedPtLabels.size());
00698 forAll(sharedPtLabels, i)
00699 {
00700 meshToShared.insert(sharedPtLabels[i], sharedPtAddr[i]);
00701 }
00702
00703
00704 EdgeMap<T> sharedEdgeValues(meshToShared.size());
00705
00706
00707 EdgeMap<edge> potentialSharedEdge(meshToShared.size());
00708
00709
00710
00711
00712
00713 for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
00714 {
00715 const face& f = mesh.faces()[faceI];
00716
00717 forAll(f, fp)
00718 {
00719 label v0 = f[fp];
00720 label v1 = f[f.fcIndex(fp)];
00721
00722 Map<label>::const_iterator v0Fnd = meshToShared.find(v0);
00723
00724 if (v0Fnd != meshToShared.end())
00725 {
00726 Map<label>::const_iterator v1Fnd = meshToShared.find(v1);
00727
00728 if (v1Fnd != meshToShared.end())
00729 {
00730 const edge meshEdge(v0, v1);
00731
00732
00733 const edge sharedEdge(v0Fnd(), v1Fnd());
00734
00735
00736 potentialSharedEdge.insert(sharedEdge, meshEdge);
00737
00738 typename EdgeMap<T>::const_iterator edgeFnd =
00739 edgeValues.find(meshEdge);
00740
00741 if (edgeFnd != edgeValues.end())
00742 {
00743
00744
00745 combine
00746 (
00747 sharedEdgeValues,
00748 cop,
00749 sharedEdge,
00750 edgeFnd()
00751 );
00752 }
00753 }
00754 }
00755 }
00756 }
00757
00758
00759
00760
00761
00762
00763
00764 if (Pstream::parRun())
00765 {
00766 if (Pstream::master())
00767 {
00768
00769 for
00770 (
00771 int slave=Pstream::firstSlave();
00772 slave<=Pstream::lastSlave();
00773 slave++
00774 )
00775 {
00776 IPstream fromSlave(Pstream::blocking, slave);
00777 EdgeMap<T> nbrValues(fromSlave);
00778
00779
00780 forAllConstIter(typename EdgeMap<T>, nbrValues, iter)
00781 {
00782 combine
00783 (
00784 sharedEdgeValues,
00785 cop,
00786 iter.key(),
00787 iter()
00788 );
00789 }
00790 }
00791
00792
00793 for
00794 (
00795 int slave=Pstream::firstSlave();
00796 slave<=Pstream::lastSlave();
00797 slave++
00798 )
00799 {
00800
00801 OPstream toSlave(Pstream::blocking, slave);
00802 toSlave << sharedEdgeValues;
00803 }
00804 }
00805 else
00806 {
00807
00808 {
00809 OPstream toMaster(Pstream::blocking, Pstream::masterNo());
00810 toMaster << sharedEdgeValues;
00811 }
00812
00813 {
00814 IPstream fromMaster(Pstream::blocking, Pstream::masterNo());
00815 fromMaster >> sharedEdgeValues;
00816 }
00817 }
00818 }
00819
00820
00821
00822
00823
00824
00825 forAllConstIter(typename EdgeMap<edge>, potentialSharedEdge, iter)
00826 {
00827 const edge& sharedEdge = iter.key();
00828 const edge& meshEdge = iter();
00829
00830
00831 typename EdgeMap<T>::const_iterator sharedFnd =
00832 sharedEdgeValues.find(sharedEdge);
00833
00834 if (sharedFnd != sharedEdgeValues.end())
00835 {
00836 combine
00837 (
00838 edgeValues,
00839 cop,
00840 meshEdge,
00841 sharedFnd()
00842 );
00843 }
00844 }
00845 }
00846
00847
00848 template <class T, class CombineOp>
00849 void Foam::syncTools::syncPointList
00850 (
00851 const polyMesh& mesh,
00852 UList<T>& pointValues,
00853 const CombineOp& cop,
00854 const T& nullValue,
00855 const bool applySeparation
00856 )
00857 {
00858 if (pointValues.size() != mesh.nPoints())
00859 {
00860 FatalErrorIn
00861 (
00862 "syncTools<class T, class CombineOp>::syncPointList"
00863 "(const polyMesh&, UList<T>&, const CombineOp&, const T&"
00864 ", const bool)"
00865 ) << "Number of values " << pointValues.size()
00866 << " is not equal to the number of points in the mesh "
00867 << mesh.nPoints() << abort(FatalError);
00868 }
00869
00870 const polyBoundaryMesh& patches = mesh.boundaryMesh();
00871
00872 if (!hasCouples(patches))
00873 {
00874 return;
00875 }
00876
00877
00878 bool hasTransformation = false;
00879
00880 if (Pstream::parRun())
00881 {
00882
00883
00884 forAll(patches, patchI)
00885 {
00886 if
00887 (
00888 isA<processorPolyPatch>(patches[patchI])
00889 && patches[patchI].nPoints() > 0
00890 )
00891 {
00892 const processorPolyPatch& procPatch =
00893 refCast<const processorPolyPatch>(patches[patchI]);
00894
00895
00896 List<T> patchInfo(procPatch.nPoints(), nullValue);
00897
00898 const labelList& meshPts = procPatch.meshPoints();
00899 const labelList& nbrPts = procPatch.neighbPoints();
00900
00901 forAll(nbrPts, pointI)
00902 {
00903 label nbrPointI = nbrPts[pointI];
00904 if (nbrPointI >= 0 && nbrPointI < patchInfo.size())
00905 {
00906 patchInfo[nbrPointI] = pointValues[meshPts[pointI]];
00907 }
00908 }
00909
00910 OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
00911 toNbr << patchInfo;
00912 }
00913 }
00914
00915
00916
00917
00918 forAll(patches, patchI)
00919 {
00920 if
00921 (
00922 isA<processorPolyPatch>(patches[patchI])
00923 && patches[patchI].nPoints() > 0
00924 )
00925 {
00926 const processorPolyPatch& procPatch =
00927 refCast<const processorPolyPatch>(patches[patchI]);
00928 checkTransform(procPatch, applySeparation);
00929
00930 List<T> nbrPatchInfo(procPatch.nPoints());
00931 {
00932
00933
00934 IPstream fromNbr
00935 (
00936 Pstream::blocking,
00937 procPatch.neighbProcNo()
00938 );
00939 fromNbr >> nbrPatchInfo;
00940 }
00941
00942 nbrPatchInfo.setSize(procPatch.nPoints(), nullValue);
00943
00944 if (!procPatch.parallel())
00945 {
00946 hasTransformation = true;
00947 transformList(procPatch.forwardT(), nbrPatchInfo);
00948 }
00949 else if (applySeparation && procPatch.separated())
00950 {
00951 hasTransformation = true;
00952 separateList(-procPatch.separation(), nbrPatchInfo);
00953 }
00954
00955 const labelList& meshPts = procPatch.meshPoints();
00956
00957 forAll(meshPts, pointI)
00958 {
00959 label meshPointI = meshPts[pointI];
00960 cop(pointValues[meshPointI], nbrPatchInfo[pointI]);
00961 }
00962 }
00963 }
00964 }
00965
00966
00967 forAll(patches, patchI)
00968 {
00969 if (isA<cyclicPolyPatch>(patches[patchI]))
00970 {
00971 const cyclicPolyPatch& cycPatch =
00972 refCast<const cyclicPolyPatch>(patches[patchI]);
00973
00974 checkTransform(cycPatch, applySeparation);
00975
00976 const edgeList& coupledPoints = cycPatch.coupledPoints();
00977 const labelList& meshPts = cycPatch.meshPoints();
00978
00979 List<T> half0Values(coupledPoints.size());
00980 List<T> half1Values(coupledPoints.size());
00981
00982 forAll(coupledPoints, i)
00983 {
00984 const edge& e = coupledPoints[i];
00985
00986 label point0 = meshPts[e[0]];
00987 label point1 = meshPts[e[1]];
00988
00989 half0Values[i] = pointValues[point0];
00990 half1Values[i] = pointValues[point1];
00991 }
00992
00993 if (!cycPatch.parallel())
00994 {
00995 hasTransformation = true;
00996 transformList(cycPatch.reverseT(), half0Values);
00997 transformList(cycPatch.forwardT(), half1Values);
00998 }
00999 else if (applySeparation && cycPatch.separated())
01000 {
01001 hasTransformation = true;
01002 const vectorField& v = cycPatch.coupledPolyPatch::separation();
01003 separateList(v, half0Values);
01004 separateList(-v, half1Values);
01005 }
01006
01007 forAll(coupledPoints, i)
01008 {
01009 const edge& e = coupledPoints[i];
01010
01011 label point0 = meshPts[e[0]];
01012 label point1 = meshPts[e[1]];
01013
01014 cop(pointValues[point0], half1Values[i]);
01015 cop(pointValues[point1], half0Values[i]);
01016 }
01017 }
01018 }
01019
01020
01021
01022
01023
01024
01025 const globalMeshData& pd = mesh.globalData();
01026
01027 if (pd.nGlobalPoints() > 0)
01028 {
01029 if (hasTransformation)
01030 {
01031 WarningIn
01032 (
01033 "syncTools<class T, class CombineOp>::syncPointList"
01034 "(const polyMesh&, UList<T>&, const CombineOp&, const T&"
01035 ", const bool)"
01036 ) << "There are decomposed cyclics in this mesh with"
01037 << " transformations." << endl
01038 << "This is not supported. The result will be incorrect"
01039 << endl;
01040 }
01041
01042
01043
01044 List<T> sharedPts(pd.nGlobalPoints(), nullValue);
01045
01046 forAll(pd.sharedPointLabels(), i)
01047 {
01048 label meshPointI = pd.sharedPointLabels()[i];
01049
01050 sharedPts[pd.sharedPointAddr()[i]] = pointValues[meshPointI];
01051 }
01052
01053
01054 Pstream::listCombineGather(sharedPts, cop);
01055 Pstream::listCombineScatter(sharedPts);
01056
01057
01058
01059 forAll(pd.sharedPointLabels(), i)
01060 {
01061 label meshPointI = pd.sharedPointLabels()[i];
01062 pointValues[meshPointI] = sharedPts[pd.sharedPointAddr()[i]];
01063 }
01064 }
01065 }
01066
01067
01068 template <class T, class CombineOp>
01069 void Foam::syncTools::syncPointList
01070 (
01071 const polyMesh& mesh,
01072 const labelList& meshPoints,
01073 UList<T>& pointValues,
01074 const CombineOp& cop,
01075 const T& nullValue,
01076 const bool applySeparation
01077 )
01078 {
01079 if (pointValues.size() != meshPoints.size())
01080 {
01081 FatalErrorIn
01082 (
01083 "syncTools<class T, class CombineOp>::syncPointList"
01084 "(const polyMesh&, const labelList&, UList<T>&, const CombineOp&"
01085 ", const T&, const bool)"
01086 ) << "Number of values " << pointValues.size()
01087 << " is not equal to the number of points "
01088 << meshPoints.size() << abort(FatalError);
01089 }
01090
01091 if (!hasCouples(mesh.boundaryMesh()))
01092 {
01093 return;
01094 }
01095
01096 List<T> meshValues(mesh.nPoints(), nullValue);
01097
01098 forAll(meshPoints, i)
01099 {
01100 meshValues[meshPoints[i]] = pointValues[i];
01101 }
01102
01103 syncTools::syncPointList
01104 (
01105 mesh,
01106 meshValues,
01107 cop,
01108 nullValue,
01109 applySeparation
01110 );
01111
01112 forAll(meshPoints, i)
01113 {
01114 pointValues[i] = meshValues[meshPoints[i]];
01115 }
01116 }
01117
01118
01119 template <class T, class CombineOp>
01120 void Foam::syncTools::syncEdgeList
01121 (
01122 const polyMesh& mesh,
01123 UList<T>& edgeValues,
01124 const CombineOp& cop,
01125 const T& nullValue,
01126 const bool applySeparation
01127 )
01128 {
01129 if (edgeValues.size() != mesh.nEdges())
01130 {
01131 FatalErrorIn
01132 (
01133 "syncTools<class T, class CombineOp>::syncEdgeList"
01134 "(const polyMesh&, UList<T>&, const CombineOp&, const T&"
01135 ", const bool)"
01136 ) << "Number of values " << edgeValues.size()
01137 << " is not equal to the number of edges in the mesh "
01138 << mesh.nEdges() << abort(FatalError);
01139 }
01140
01141 const polyBoundaryMesh& patches = mesh.boundaryMesh();
01142
01143 if (!hasCouples(patches))
01144 {
01145 return;
01146 }
01147
01148
01149 bool hasTransformation = false;
01150
01151 if (Pstream::parRun())
01152 {
01153
01154
01155 forAll(patches, patchI)
01156 {
01157 if
01158 (
01159 isA<processorPolyPatch>(patches[patchI])
01160 && patches[patchI].nEdges() > 0
01161 )
01162 {
01163 const processorPolyPatch& procPatch =
01164 refCast<const processorPolyPatch>(patches[patchI]);
01165
01166 const labelList& meshEdges = procPatch.meshEdges();
01167 const labelList& neighbEdges = procPatch.neighbEdges();
01168
01169
01170 List<T> patchInfo(procPatch.nEdges(), nullValue);
01171
01172 forAll(neighbEdges, edgeI)
01173 {
01174 label nbrEdgeI = neighbEdges[edgeI];
01175
01176 if (nbrEdgeI >= 0 && nbrEdgeI < patchInfo.size())
01177 {
01178 patchInfo[nbrEdgeI] = edgeValues[meshEdges[edgeI]];
01179 }
01180 }
01181
01182 OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
01183 toNbr << patchInfo;
01184 }
01185 }
01186
01187
01188
01189 forAll(patches, patchI)
01190 {
01191 if
01192 (
01193 isA<processorPolyPatch>(patches[patchI])
01194 && patches[patchI].nEdges() > 0
01195 )
01196 {
01197 const processorPolyPatch& procPatch =
01198 refCast<const processorPolyPatch>(patches[patchI]);
01199
01200 checkTransform(procPatch, applySeparation);
01201
01202 const labelList& meshEdges = procPatch.meshEdges();
01203
01204
01205
01206 List<T> nbrPatchInfo(procPatch.nEdges());
01207
01208 {
01209 IPstream fromNeighb
01210 (
01211 Pstream::blocking,
01212 procPatch.neighbProcNo()
01213 );
01214 fromNeighb >> nbrPatchInfo;
01215 }
01216
01217 nbrPatchInfo.setSize(procPatch.nEdges(), nullValue);
01218
01219 if (!procPatch.parallel())
01220 {
01221 hasTransformation = true;
01222 transformList(procPatch.forwardT(), nbrPatchInfo);
01223 }
01224 else if (applySeparation && procPatch.separated())
01225 {
01226 hasTransformation = true;
01227 separateList(-procPatch.separation(), nbrPatchInfo);
01228 }
01229
01230 forAll(meshEdges, edgeI)
01231 {
01232 label meshEdgeI = meshEdges[edgeI];
01233
01234 cop(edgeValues[meshEdgeI], nbrPatchInfo[edgeI]);
01235 }
01236 }
01237 }
01238 }
01239
01240
01241 forAll(patches, patchI)
01242 {
01243 if (isA<cyclicPolyPatch>(patches[patchI]))
01244 {
01245 const cyclicPolyPatch& cycPatch =
01246 refCast<const cyclicPolyPatch>(patches[patchI]);
01247
01248 checkTransform(cycPatch, applySeparation);
01249
01250 const edgeList& coupledEdges = cycPatch.coupledEdges();
01251 const labelList& meshEdges = cycPatch.meshEdges();
01252
01253 List<T> half0Values(coupledEdges.size());
01254 List<T> half1Values(coupledEdges.size());
01255
01256 forAll(coupledEdges, i)
01257 {
01258 const edge& e = coupledEdges[i];
01259
01260 label meshEdge0 = meshEdges[e[0]];
01261 label meshEdge1 = meshEdges[e[1]];
01262
01263 half0Values[i] = edgeValues[meshEdge0];
01264 half1Values[i] = edgeValues[meshEdge1];
01265 }
01266
01267 if (!cycPatch.parallel())
01268 {
01269 hasTransformation = true;
01270 transformList(cycPatch.reverseT(), half0Values);
01271 transformList(cycPatch.forwardT(), half1Values);
01272 }
01273 else if (applySeparation && cycPatch.separated())
01274 {
01275 hasTransformation = true;
01276
01277 const vectorField& v = cycPatch.coupledPolyPatch::separation();
01278 separateList(v, half0Values);
01279 separateList(-v, half1Values);
01280 }
01281
01282 forAll(coupledEdges, i)
01283 {
01284 const edge& e = coupledEdges[i];
01285
01286 label meshEdge0 = meshEdges[e[0]];
01287 label meshEdge1 = meshEdges[e[1]];
01288
01289 cop(edgeValues[meshEdge0], half1Values[i]);
01290 cop(edgeValues[meshEdge1], half0Values[i]);
01291 }
01292 }
01293 }
01294
01295
01296
01297
01298
01299
01300 const globalMeshData& pd = mesh.globalData();
01301
01302 if (pd.nGlobalEdges() > 0)
01303 {
01304 if (hasTransformation)
01305 {
01306 WarningIn
01307 (
01308 "syncTools<class T, class CombineOp>::syncEdgeList"
01309 "(const polyMesh&, UList<T>&, const CombineOp&, const T&"
01310 ", const bool)"
01311 ) << "There are decomposed cyclics in this mesh with"
01312 << " transformations." << endl
01313 << "This is not supported. The result will be incorrect"
01314 << endl;
01315 }
01316
01317
01318 List<T> sharedPts(pd.nGlobalEdges(), nullValue);
01319
01320 forAll(pd.sharedEdgeLabels(), i)
01321 {
01322 label meshEdgeI = pd.sharedEdgeLabels()[i];
01323
01324
01325 sharedPts[pd.sharedEdgeAddr()[i]] = edgeValues[meshEdgeI];
01326 }
01327
01328
01329 Pstream::listCombineGather(sharedPts, cop);
01330 Pstream::listCombineScatter(sharedPts);
01331
01332
01333
01334 forAll(pd.sharedEdgeLabels(), i)
01335 {
01336 label meshEdgeI = pd.sharedEdgeLabels()[i];
01337 edgeValues[meshEdgeI] = sharedPts[pd.sharedEdgeAddr()[i]];
01338 }
01339 }
01340 }
01341
01342
01343 template <class T, class CombineOp>
01344 void Foam::syncTools::syncBoundaryFaceList
01345 (
01346 const polyMesh& mesh,
01347 UList<T>& faceValues,
01348 const CombineOp& cop,
01349 const bool applySeparation
01350 )
01351 {
01352 const label nBFaces = mesh.nFaces() - mesh.nInternalFaces();
01353
01354 if (faceValues.size() != nBFaces)
01355 {
01356 FatalErrorIn
01357 (
01358 "syncTools<class T, class CombineOp>::syncBoundaryFaceList"
01359 "(const polyMesh&, UList<T>&, const CombineOp&"
01360 ", const bool)"
01361 ) << "Number of values " << faceValues.size()
01362 << " is not equal to the number of boundary faces in the mesh "
01363 << nBFaces << abort(FatalError);
01364 }
01365
01366 const polyBoundaryMesh& patches = mesh.boundaryMesh();
01367
01368 if (!hasCouples(patches))
01369 {
01370 return;
01371 }
01372
01373
01374 if (Pstream::parRun())
01375 {
01376
01377
01378 forAll(patches, patchI)
01379 {
01380 if
01381 (
01382 isA<processorPolyPatch>(patches[patchI])
01383 && patches[patchI].size() > 0
01384 )
01385 {
01386 const processorPolyPatch& procPatch =
01387 refCast<const processorPolyPatch>(patches[patchI]);
01388
01389 label patchStart = procPatch.start()-mesh.nInternalFaces();
01390
01391 if (contiguous<T>())
01392 {
01393 OPstream::write
01394 (
01395 Pstream::blocking,
01396 procPatch.neighbProcNo(),
01397 reinterpret_cast<const char*>(&faceValues[patchStart]),
01398 procPatch.size()*sizeof(T)
01399 );
01400 }
01401 else
01402 {
01403 OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
01404 toNbr <<
01405 SubList<T>(faceValues, procPatch.size(), patchStart);
01406 }
01407 }
01408 }
01409
01410
01411
01412
01413 forAll(patches, patchI)
01414 {
01415 if
01416 (
01417 isA<processorPolyPatch>(patches[patchI])
01418 && patches[patchI].size() > 0
01419 )
01420 {
01421 const processorPolyPatch& procPatch =
01422 refCast<const processorPolyPatch>(patches[patchI]);
01423
01424 List<T> nbrPatchInfo(procPatch.size());
01425
01426 if (contiguous<T>())
01427 {
01428 IPstream::read
01429 (
01430 Pstream::blocking,
01431 procPatch.neighbProcNo(),
01432 reinterpret_cast<char*>(nbrPatchInfo.begin()),
01433 nbrPatchInfo.byteSize()
01434 );
01435 }
01436 else
01437 {
01438 IPstream fromNeighb
01439 (
01440 Pstream::blocking,
01441 procPatch.neighbProcNo()
01442 );
01443 fromNeighb >> nbrPatchInfo;
01444 }
01445
01446 if (!procPatch.parallel())
01447 {
01448 transformList(procPatch.forwardT(), nbrPatchInfo);
01449 }
01450 else if (applySeparation && procPatch.separated())
01451 {
01452 separateList(-procPatch.separation(), nbrPatchInfo);
01453 }
01454
01455
01456 label bFaceI = procPatch.start()-mesh.nInternalFaces();
01457
01458 forAll(nbrPatchInfo, i)
01459 {
01460 cop(faceValues[bFaceI++], nbrPatchInfo[i]);
01461 }
01462 }
01463 }
01464 }
01465
01466
01467 forAll(patches, patchI)
01468 {
01469 if (isA<cyclicPolyPatch>(patches[patchI]))
01470 {
01471 const cyclicPolyPatch& cycPatch =
01472 refCast<const cyclicPolyPatch>(patches[patchI]);
01473
01474 label patchStart = cycPatch.start()-mesh.nInternalFaces();
01475
01476 label half = cycPatch.size()/2;
01477 label half1Start = patchStart+half;
01478
01479 List<T> half0Values(SubList<T>(faceValues, half, patchStart));
01480 List<T> half1Values(SubList<T>(faceValues, half, half1Start));
01481
01482 if (!cycPatch.parallel())
01483 {
01484 transformList(cycPatch.reverseT(), half0Values);
01485 transformList(cycPatch.forwardT(), half1Values);
01486 }
01487 else if (applySeparation && cycPatch.separated())
01488 {
01489 const vectorField& v = cycPatch.coupledPolyPatch::separation();
01490 separateList(v, half0Values);
01491 separateList(-v, half1Values);
01492 }
01493
01494 label i0 = patchStart;
01495 forAll(half1Values, i)
01496 {
01497 cop(faceValues[i0++], half1Values[i]);
01498 }
01499
01500 label i1 = half1Start;
01501 forAll(half0Values, i)
01502 {
01503 cop(faceValues[i1++], half0Values[i]);
01504 }
01505 }
01506 }
01507 }
01508
01509
01510 template <class T, class CombineOp>
01511 void Foam::syncTools::syncFaceList
01512 (
01513 const polyMesh& mesh,
01514 UList<T>& faceValues,
01515 const CombineOp& cop,
01516 const bool applySeparation
01517 )
01518 {
01519 if (faceValues.size() != mesh.nFaces())
01520 {
01521 FatalErrorIn
01522 (
01523 "syncTools<class T, class CombineOp>::syncFaceList"
01524 "(const polyMesh&, UList<T>&, const CombineOp&"
01525 ", const bool)"
01526 ) << "Number of values " << faceValues.size()
01527 << " is not equal to the number of faces in the mesh "
01528 << mesh.nFaces() << abort(FatalError);
01529 }
01530
01531 SubList<T> bndValues
01532 (
01533 faceValues,
01534 mesh.nFaces()-mesh.nInternalFaces(),
01535 mesh.nInternalFaces()
01536 );
01537
01538 syncBoundaryFaceList
01539 (
01540 mesh,
01541 bndValues,
01542 cop,
01543 applySeparation
01544 );
01545 }
01546
01547
01548 template <class T>
01549 void Foam::syncTools::swapBoundaryFaceList
01550 (
01551 const polyMesh& mesh,
01552 UList<T>& faceValues,
01553 const bool applySeparation
01554 )
01555 {
01556 syncBoundaryFaceList(mesh, faceValues, eqOp<T>(), applySeparation);
01557 }
01558
01559
01560 template <class T>
01561 void Foam::syncTools::swapFaceList
01562 (
01563 const polyMesh& mesh,
01564 UList<T>& faceValues,
01565 const bool applySeparation
01566 )
01567 {
01568 syncFaceList(mesh, faceValues, eqOp<T>(), applySeparation);
01569 }
01570
01571
01572 template <unsigned nBits, class CombineOp>
01573 void Foam::syncTools::syncFaceList
01574 (
01575 const polyMesh& mesh,
01576 PackedList<nBits>& faceValues,
01577 const CombineOp& cop
01578 )
01579 {
01580 if (faceValues.size() != mesh.nFaces())
01581 {
01582 FatalErrorIn
01583 (
01584 "syncTools<unsigned nBits, class CombineOp>::syncFaceList"
01585 "(const polyMesh&, PackedList<nBits>&, const CombineOp&)"
01586 ) << "Number of values " << faceValues.size()
01587 << " is not equal to the number of faces in the mesh "
01588 << mesh.nFaces() << abort(FatalError);
01589 }
01590
01591 const polyBoundaryMesh& patches = mesh.boundaryMesh();
01592
01593 if (!hasCouples(patches))
01594 {
01595 return;
01596 }
01597
01598
01599 List<List<unsigned int> > patchValues(patches.size());
01600
01601 if (Pstream::parRun())
01602 {
01603
01604
01605 forAll(patches, patchI)
01606 {
01607 if
01608 (
01609 isA<processorPolyPatch>(patches[patchI])
01610 && patches[patchI].size() > 0
01611 )
01612 {
01613 const processorPolyPatch& procPatch =
01614 refCast<const processorPolyPatch>(patches[patchI]);
01615
01616 patchValues[patchI].setSize(procPatch.size());
01617 forAll(procPatch, i)
01618 {
01619 patchValues[patchI][i] =
01620 faceValues.get(procPatch.start()+i);
01621 }
01622
01623 OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
01624 toNbr << patchValues[patchI];
01625 }
01626 }
01627
01628
01629
01630
01631 forAll(patches, patchI)
01632 {
01633 if
01634 (
01635 isA<processorPolyPatch>(patches[patchI])
01636 && patches[patchI].size() > 0
01637 )
01638 {
01639 const processorPolyPatch& procPatch =
01640 refCast<const processorPolyPatch>(patches[patchI]);
01641
01642 {
01643 IPstream fromNbr
01644 (
01645 Pstream::blocking,
01646 procPatch.neighbProcNo()
01647 );
01648 fromNbr >> patchValues[patchI];
01649 }
01650
01651
01652 forAll(procPatch, i)
01653 {
01654 unsigned int patchVal = patchValues[patchI][i];
01655 label meshFaceI = procPatch.start()+i;
01656 unsigned int faceVal = faceValues.get(meshFaceI);
01657 cop(faceVal, patchVal);
01658 faceValues.set(meshFaceI, faceVal);
01659 }
01660 }
01661 }
01662 }
01663
01664
01665 forAll(patches, patchI)
01666 {
01667 if (isA<cyclicPolyPatch>(patches[patchI]))
01668 {
01669 const cyclicPolyPatch& cycPatch =
01670 refCast<const cyclicPolyPatch>(patches[patchI]);
01671
01672 label half = cycPatch.size()/2;
01673
01674 for (label i = 0; i < half; i++)
01675 {
01676 label meshFace0 = cycPatch.start()+i;
01677 unsigned int val0 = faceValues.get(meshFace0);
01678 label meshFace1 = meshFace0 + half;
01679 unsigned int val1 = faceValues.get(meshFace1);
01680
01681 unsigned int t = val0;
01682 cop(t, val1);
01683 faceValues.set(meshFace0, t);
01684
01685 cop(val1, val0);
01686 faceValues.set(meshFace1, val1);
01687 }
01688 }
01689 }
01690 }
01691
01692
01693 template <unsigned nBits>
01694 void Foam::syncTools::swapFaceList
01695 (
01696 const polyMesh& mesh,
01697 PackedList<nBits>& faceValues
01698 )
01699 {
01700 syncFaceList(mesh, faceValues, eqOp<unsigned int>());
01701 }
01702
01703
01704 template <unsigned nBits, class CombineOp>
01705 void Foam::syncTools::syncPointList
01706 (
01707 const polyMesh& mesh,
01708 PackedList<nBits>& pointValues,
01709 const CombineOp& cop,
01710 const unsigned int nullValue
01711 )
01712 {
01713 if (pointValues.size() != mesh.nPoints())
01714 {
01715 FatalErrorIn
01716 (
01717 "syncTools<unsigned nBits, class CombineOp>::syncPointList"
01718 "(const polyMesh&, PackedList<nBits>&, const CombineOp&"
01719 ", const unsigned int&)"
01720 ) << "Number of values " << pointValues.size()
01721 << " is not equal to the number of points in the mesh "
01722 << mesh.nPoints() << abort(FatalError);
01723 }
01724
01725 const polyBoundaryMesh& patches = mesh.boundaryMesh();
01726
01727 if (!hasCouples(patches))
01728 {
01729 return;
01730 }
01731
01732
01733 List<List<unsigned int> > patchValues(patches.size());
01734
01735 if (Pstream::parRun())
01736 {
01737
01738
01739 forAll(patches, patchI)
01740 {
01741 if
01742 (
01743 isA<processorPolyPatch>(patches[patchI])
01744 && patches[patchI].nPoints() > 0
01745 )
01746 {
01747 const processorPolyPatch& procPatch =
01748 refCast<const processorPolyPatch>(patches[patchI]);
01749
01750 patchValues[patchI].setSize(procPatch.nPoints());
01751 patchValues[patchI] = nullValue;
01752
01753 const labelList& meshPts = procPatch.meshPoints();
01754 const labelList& nbrPts = procPatch.neighbPoints();
01755
01756 forAll(nbrPts, pointI)
01757 {
01758 label nbrPointI = nbrPts[pointI];
01759 if (nbrPointI >= 0 && nbrPointI < procPatch.nPoints())
01760 {
01761 patchValues[patchI][nbrPointI] =
01762 pointValues.get(meshPts[pointI]);
01763 }
01764 }
01765
01766 OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
01767 toNbr << patchValues[patchI];
01768 }
01769 }
01770
01771
01772
01773
01774 forAll(patches, patchI)
01775 {
01776 if
01777 (
01778 isA<processorPolyPatch>(patches[patchI])
01779 && patches[patchI].nPoints() > 0
01780 )
01781 {
01782 const processorPolyPatch& procPatch =
01783 refCast<const processorPolyPatch>(patches[patchI]);
01784
01785 {
01786
01787
01788 IPstream fromNbr
01789 (
01790 Pstream::blocking,
01791 procPatch.neighbProcNo()
01792 );
01793 fromNbr >> patchValues[patchI];
01794 }
01795
01796
01797 patchValues[patchI].setSize(procPatch.nPoints(), nullValue);
01798
01799 const labelList& meshPts = procPatch.meshPoints();
01800
01801 forAll(meshPts, pointI)
01802 {
01803 label meshPointI = meshPts[pointI];
01804 unsigned int pointVal = pointValues.get(meshPointI);
01805 cop(pointVal, patchValues[patchI][pointI]);
01806 pointValues.set(meshPointI, pointVal);
01807 }
01808 }
01809 }
01810 }
01811
01812
01813 forAll(patches, patchI)
01814 {
01815 if (isA<cyclicPolyPatch>(patches[patchI]))
01816 {
01817 const cyclicPolyPatch& cycPatch =
01818 refCast<const cyclicPolyPatch>(patches[patchI]);
01819
01820 const edgeList& coupledPoints = cycPatch.coupledPoints();
01821 const labelList& meshPts = cycPatch.meshPoints();
01822
01823 forAll(coupledPoints, i)
01824 {
01825 const edge& e = coupledPoints[i];
01826
01827 label point0 = meshPts[e[0]];
01828 label point1 = meshPts[e[1]];
01829
01830 unsigned int val0 = pointValues.get(point0);
01831 unsigned int t = val0;
01832 unsigned int val1 = pointValues.get(point1);
01833
01834 cop(t, val1);
01835 pointValues.set(point0, t);
01836 cop(val1, val0);
01837 pointValues.set(point1, val1);
01838 }
01839 }
01840 }
01841
01842
01843 const globalMeshData& pd = mesh.globalData();
01844
01845 if (pd.nGlobalPoints() > 0)
01846 {
01847
01848 List<unsigned int> sharedPts(pd.nGlobalPoints(), nullValue);
01849
01850 forAll(pd.sharedPointLabels(), i)
01851 {
01852 label meshPointI = pd.sharedPointLabels()[i];
01853
01854 sharedPts[pd.sharedPointAddr()[i]] = pointValues.get(meshPointI);
01855 }
01856
01857
01858 Pstream::listCombineGather(sharedPts, cop);
01859 Pstream::listCombineScatter(sharedPts);
01860
01861
01862
01863 forAll(pd.sharedPointLabels(), i)
01864 {
01865 label meshPointI = pd.sharedPointLabels()[i];
01866 pointValues.set(meshPointI, sharedPts[pd.sharedPointAddr()[i]]);
01867 }
01868 }
01869 }
01870
01871
01872 template <unsigned nBits, class CombineOp>
01873 void Foam::syncTools::syncEdgeList
01874 (
01875 const polyMesh& mesh,
01876 PackedList<nBits>& edgeValues,
01877 const CombineOp& cop,
01878 const unsigned int nullValue
01879 )
01880 {
01881 if (edgeValues.size() != mesh.nEdges())
01882 {
01883 FatalErrorIn
01884 (
01885 "syncTools<unsigned nBits, class CombineOp>::syncEdgeList"
01886 "(const polyMesh&, PackedList<nBits>&, const CombineOp&"
01887 ", const unsigned int&)"
01888 ) << "Number of values " << edgeValues.size()
01889 << " is not equal to the number of edges in the mesh "
01890 << mesh.nEdges() << abort(FatalError);
01891 }
01892
01893 const polyBoundaryMesh& patches = mesh.boundaryMesh();
01894
01895 if (!hasCouples(patches))
01896 {
01897 return;
01898 }
01899
01900
01901 List<List<unsigned int> > patchValues(patches.size());
01902
01903 if (Pstream::parRun())
01904 {
01905
01906
01907 forAll(patches, patchI)
01908 {
01909 if
01910 (
01911 isA<processorPolyPatch>(patches[patchI])
01912 && patches[patchI].nEdges() > 0
01913 )
01914 {
01915 const processorPolyPatch& procPatch =
01916 refCast<const processorPolyPatch>(patches[patchI]);
01917
01918 patchValues[patchI].setSize(procPatch.nEdges(), nullValue);
01919
01920 const labelList& meshEdges = procPatch.meshEdges();
01921 const labelList& neighbEdges = procPatch.neighbEdges();
01922
01923 forAll(neighbEdges, edgeI)
01924 {
01925 label nbrEdgeI = neighbEdges[edgeI];
01926 if (nbrEdgeI >= 0 && nbrEdgeI < procPatch.nEdges())
01927 {
01928 patchValues[patchI][nbrEdgeI] =
01929 edgeValues.get(meshEdges[edgeI]);
01930 }
01931 }
01932
01933 OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
01934 toNbr << patchValues[patchI];
01935 }
01936 }
01937
01938
01939
01940
01941 forAll(patches, patchI)
01942 {
01943 if
01944 (
01945 isA<processorPolyPatch>(patches[patchI])
01946 && patches[patchI].nEdges() > 0
01947 )
01948 {
01949 const processorPolyPatch& procPatch =
01950 refCast<const processorPolyPatch>(patches[patchI]);
01951
01952 {
01953 IPstream fromNeighb
01954 (
01955 Pstream::blocking,
01956 procPatch.neighbProcNo()
01957 );
01958 fromNeighb >> patchValues[patchI];
01959 }
01960
01961 patchValues[patchI].setSize(procPatch.nEdges(), nullValue);
01962
01963 const labelList& meshEdges = procPatch.meshEdges();
01964
01965 forAll(meshEdges, edgeI)
01966 {
01967 unsigned int patchVal = patchValues[patchI][edgeI];
01968 label meshEdgeI = meshEdges[edgeI];
01969 unsigned int edgeVal = edgeValues.get(meshEdgeI);
01970 cop(edgeVal, patchVal);
01971 edgeValues.set(meshEdgeI, edgeVal);
01972 }
01973 }
01974 }
01975 }
01976
01977
01978 forAll(patches, patchI)
01979 {
01980 if (isA<cyclicPolyPatch>(patches[patchI]))
01981 {
01982 const cyclicPolyPatch& cycPatch =
01983 refCast<const cyclicPolyPatch>(patches[patchI]);
01984
01985 const edgeList& coupledEdges = cycPatch.coupledEdges();
01986 const labelList& meshEdges = cycPatch.meshEdges();
01987
01988 forAll(coupledEdges, i)
01989 {
01990 const edge& e = coupledEdges[i];
01991
01992 label edge0 = meshEdges[e[0]];
01993 label edge1 = meshEdges[e[1]];
01994
01995 unsigned int val0 = edgeValues.get(edge0);
01996 unsigned int t = val0;
01997 unsigned int val1 = edgeValues.get(edge1);
01998
01999 cop(t, val1);
02000 edgeValues.set(edge0, t);
02001 cop(val1, val0);
02002 edgeValues.set(edge1, val1);
02003 }
02004 }
02005 }
02006
02007
02008 const globalMeshData& pd = mesh.globalData();
02009
02010 if (pd.nGlobalEdges() > 0)
02011 {
02012
02013 List<unsigned int> sharedPts(pd.nGlobalEdges(), nullValue);
02014
02015 forAll(pd.sharedEdgeLabels(), i)
02016 {
02017 label meshEdgeI = pd.sharedEdgeLabels()[i];
02018
02019 sharedPts[pd.sharedEdgeAddr()[i]] = edgeValues.get(meshEdgeI);
02020 }
02021
02022
02023 Pstream::listCombineGather(sharedPts, cop);
02024 Pstream::listCombineScatter(sharedPts);
02025
02026
02027
02028 forAll(pd.sharedEdgeLabels(), i)
02029 {
02030 label meshEdgeI = pd.sharedEdgeLabels()[i];
02031 edgeValues.set(meshEdgeI, sharedPts[pd.sharedEdgeAddr()[i]]);
02032 }
02033 }
02034 }
02035
02036
02037