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 "interactionLists.H"
00027
00028
00029
00030 Foam::scalar Foam::interactionLists::transTol = 1e-12;
00031
00032
00033
00034
00035 void Foam::interactionLists::buildCellReferralLists()
00036 {
00037 Info<< nl << "Determining molecule referring schedule" << endl;
00038
00039 const referredCellList& refIntL(ril());
00040
00041 DynamicList<label> referralProcs;
00042
00043
00044
00045 forAll(refIntL, rIL)
00046 {
00047 const referredCell& rC(refIntL[rIL]);
00048
00049 if (findIndex(referralProcs, rC.sourceProc()) == -1)
00050 {
00051 referralProcs.append(rC.sourceProc());
00052 }
00053 }
00054
00055 referralProcs.shrink();
00056
00057
00058
00059 List<DynamicList<label> > cellSendingReferralLists(referralProcs.size());
00060
00061
00062
00063
00064 List<DynamicList<autoPtr<DynamicList<label> > > >
00065 cellReceivingReferralLists(referralProcs.size());
00066
00067
00068
00069 forAll(refIntL, rIL)
00070 {
00071 const referredCell& rC(refIntL[rIL]);
00072
00073 label rPI = findIndex(referralProcs, rC.sourceProc());
00074
00075 DynamicList<autoPtr<DynamicList<label> > >& rRL(cellReceivingReferralLists[rPI]);
00076
00077 DynamicList<label>& sRL(cellSendingReferralLists[rPI]);
00078
00079 label existingSource = findIndex(sRL, rC.sourceCell());
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 if (existingSource == -1)
00090 {
00091 sRL.append(rC.sourceCell());
00092
00093 rRL.append
00094 (
00095 autoPtr<DynamicList<label> >(new DynamicList<label> (labelList(1,rIL)))
00096 );
00097 }
00098 else
00099 {
00100 rRL[existingSource]->append(rIL);
00101
00102 rRL[existingSource]->shrink();
00103 }
00104 }
00105
00106 forAll(referralProcs, rPI)
00107 {
00108 DynamicList<autoPtr<DynamicList<label> > >& rRL(cellReceivingReferralLists[rPI]);
00109
00110 DynamicList<label>& sRL(cellSendingReferralLists[rPI]);
00111
00112 sRL.shrink();
00113
00114 rRL.shrink();
00115 }
00116
00117
00118
00119
00120 cellReceivingReferralLists_.setSize(referralProcs.size());
00121
00122 cellSendingReferralLists_.setSize(referralProcs.size());
00123
00124 forAll(referralProcs, rPI)
00125 {
00126 DynamicList<autoPtr<DynamicList<label> > >& rRL(cellReceivingReferralLists[rPI]);
00127
00128 labelListList translLL(rRL.size());
00129
00130 forAll(rRL, rRLI)
00131 {
00132 translLL[rRLI] = rRL[rRLI]();
00133 }
00134
00135 cellReceivingReferralLists_[rPI] = receivingReferralList
00136 (
00137 referralProcs[rPI],
00138 translLL
00139 );
00140 }
00141
00142
00143
00144 forAll(referralProcs, rPI)
00145 {
00146
00147 DynamicList<label>& sRL(cellSendingReferralLists[rPI]);
00148
00149 if (referralProcs[rPI] != Pstream::myProcNo())
00150 {
00151 if (Pstream::parRun())
00152 {
00153 OPstream toInteractingProc
00154 (
00155 Pstream::blocking,
00156 referralProcs[rPI]
00157 );
00158
00159 toInteractingProc << sendingReferralList
00160 (
00161 Pstream::myProcNo(),
00162 sRL
00163 );
00164 }
00165 }
00166 }
00167
00168
00169
00170 forAll(referralProcs, rPI)
00171 {
00172 if (referralProcs[rPI] != Pstream::myProcNo())
00173 {
00174 if (Pstream::parRun())
00175 {
00176 IPstream fromInteractingProc
00177 (
00178 Pstream::blocking,
00179 referralProcs[rPI]
00180 );
00181
00182 fromInteractingProc >> cellSendingReferralLists_[rPI];
00183 }
00184 }
00185 else
00186 {
00187 cellSendingReferralLists_[rPI] = sendingReferralList
00188 (
00189 Pstream::myProcNo(),
00190 cellSendingReferralLists[rPI]
00191 );
00192 }
00193 }
00194 }
00195
00196
00197
00198
00199
00200 Foam::interactionLists::interactionLists
00201 (
00202 const polyMesh& mesh,
00203 scalar rCutMaxSqr,
00204 bool pointPointListBuild
00205 )
00206 :
00207 mesh_(mesh),
00208 rCutMaxSqr_(rCutMaxSqr),
00209 dil_(*this, pointPointListBuild),
00210 ril_(*this, pointPointListBuild),
00211 cellSendingReferralLists_(),
00212 cellReceivingReferralLists_()
00213 {
00214 buildCellReferralLists();
00215 }
00216
00217
00218 Foam::interactionLists::interactionLists(const polyMesh& mesh)
00219 :
00220 mesh_(mesh),
00221 dil_(*this),
00222 ril_(*this)
00223 {}
00224
00225
00226
00227
00228 Foam::interactionLists::~interactionLists()
00229 {}
00230
00231
00232
00233
00234 bool Foam::interactionLists::testPointPointDistance
00235 (
00236 const label ptI,
00237 const label ptJ
00238 ) const
00239 {
00240 return (magSqr(mesh_.points()[ptI] - mesh_.points()[ptJ]) <= rCutMaxSqr_);
00241 }
00242
00243
00244 bool Foam::interactionLists::testEdgeEdgeDistance
00245 (
00246 const edge& eI,
00247 const edge& eJ
00248 ) const
00249 {
00250 const vector& eJs(mesh_.points()[eJ.start()]);
00251 const vector& eJe(mesh_.points()[eJ.end()]);
00252
00253 return testEdgeEdgeDistance(eI, eJs, eJe);
00254 }
00255
00256
00257 bool Foam::interactionLists::testPointFaceDistance
00258 (
00259 const label p,
00260 const label faceNo
00261 ) const
00262 {
00263 const vector& pointPosition(mesh_.points()[p]);
00264
00265 return testPointFaceDistance(pointPosition, faceNo);
00266 }
00267
00268
00269 bool Foam::interactionLists::testPointFaceDistance
00270 (
00271 const label p,
00272 const referredCell& refCell
00273 ) const
00274 {
00275 const vector& pointPosition(mesh_.points()[p]);
00276
00277 forAll (refCell.faces(), rCF)
00278 {
00279 if
00280 (
00281 testPointFaceDistance
00282 (
00283 pointPosition,
00284 refCell.faces()[rCF],
00285 refCell.vertexPositions(),
00286 refCell.faceCentres()[rCF],
00287 refCell.faceAreas()[rCF]
00288 )
00289 )
00290 {
00291 return true;
00292 }
00293 }
00294
00295 return false;
00296 }
00297
00298
00299 bool Foam::interactionLists::testPointFaceDistance
00300 (
00301 const vectorList& pointsToTest,
00302 const label faceNo
00303 ) const
00304 {
00305 forAll(pointsToTest, pTT)
00306 {
00307 const vector& p(pointsToTest[pTT]);
00308
00309
00310
00311
00312
00313 if (testPointFaceDistance(p, faceNo))
00314 {
00315 return true;
00316 }
00317 }
00318
00319 return false;
00320 }
00321
00322
00323 bool Foam::interactionLists::testPointFaceDistance
00324 (
00325 const vector& p,
00326 const label faceNo
00327 ) const
00328 {
00329 const face& faceToTest(mesh_.faces()[faceNo]);
00330
00331 const vector& faceC(mesh_.faceCentres()[faceNo]);
00332
00333 const vector& faceA(mesh_.faceAreas()[faceNo]);
00334
00335 const vectorList& points(mesh_.points());
00336
00337 return testPointFaceDistance
00338 (
00339 p,
00340 faceToTest,
00341 points,
00342 faceC,
00343 faceA
00344 );
00345 }
00346
00347
00348 bool Foam::interactionLists::testPointFaceDistance
00349 (
00350 const vector& p,
00351 const labelList& faceToTest,
00352 const vectorList& points,
00353 const vector& faceC,
00354 const vector& faceA
00355 ) const
00356 {
00357 vector faceN(faceA/mag(faceA));
00358
00359 scalar perpDist((p - faceC) & faceN);
00360
00361 if (magSqr(perpDist) > rCutMaxSqr_)
00362 {
00363 return false;
00364 }
00365
00366 vector pointOnPlane = (p - faceN * perpDist);
00367
00368 if (magSqr(faceC - pointOnPlane) < rCutMaxSqr_*1e-8)
00369 {
00370
00371
00372
00373
00374
00375
00376 return (magSqr(pointOnPlane - p) <= rCutMaxSqr_);
00377 }
00378
00379 vector xAxis = (faceC - pointOnPlane)/mag(faceC - pointOnPlane);
00380
00381 vector yAxis =
00382 ((faceC - pointOnPlane) ^ faceN)
00383 /mag((faceC - pointOnPlane) ^ faceN);
00384
00385 List<vector2D> local2DVertices(faceToTest.size());
00386
00387 forAll(faceToTest, fTT)
00388 {
00389 const vector& V(points[faceToTest[fTT]]);
00390
00391 if (magSqr(V-p) <= rCutMaxSqr_)
00392 {
00393 return true;
00394 }
00395
00396 local2DVertices[fTT] = vector2D
00397 (
00398 ((V - pointOnPlane) & xAxis),
00399 ((V - pointOnPlane) & yAxis)
00400 );
00401 }
00402
00403 scalar localFaceCx((faceC - pointOnPlane) & xAxis);
00404
00405 scalar la_valid = -1;
00406
00407 forAll(local2DVertices, fV)
00408 {
00409 const vector2D& va(local2DVertices[fV]);
00410
00411 const vector2D& vb
00412 (
00413 local2DVertices[(fV + 1) % local2DVertices.size()]
00414 );
00415
00416 if (mag(vb.y()-va.y()) > SMALL)
00417 {
00418 scalar la =
00419 (
00420 va.x() - va.y()*((vb.x() - va.x())/(vb.y() - va.y()))
00421 )
00422 /localFaceCx;
00423
00424 scalar lv = -va.y()/(vb.y() - va.y());
00425
00426
00427 if (la >= 0 && la <= 1 && lv >= 0 && lv <= 1)
00428 {
00429 la_valid = la;
00430
00431 break;
00432 }
00433 }
00434 }
00435
00436 if (la_valid < 0)
00437 {
00438
00439 return (magSqr(pointOnPlane-p) <= rCutMaxSqr_);
00440 }
00441 else
00442 {
00443
00444
00445 return
00446 (
00447 magSqr(pointOnPlane + la_valid*(faceC - pointOnPlane) - p)
00448 <= rCutMaxSqr_
00449 );
00450 }
00451
00452
00453
00454
00455 FatalErrorIn("interactionLists.C") << nl
00456 << "point " << p << " to face " << faceToTest
00457 << " comparison did not find a nearest point"
00458 << " to be inside or outside face."
00459 << abort(FatalError);
00460
00461 return false;
00462 }
00463
00464
00465 bool Foam::interactionLists::testEdgeEdgeDistance
00466 (
00467 const edge& eI,
00468 const vector& eJs,
00469 const vector& eJe
00470 ) const
00471 {
00472 vector a(eI.vec(mesh_.points()));
00473 vector b(eJe - eJs);
00474
00475 const vector& eIs(mesh_.points()[eI.start()]);
00476
00477 vector c(eJs - eIs);
00478
00479 vector crossab = a ^ b;
00480 scalar magCrossSqr = magSqr(crossab);
00481
00482 if (magCrossSqr > VSMALL)
00483 {
00484
00485
00486
00487 scalar s = ((c ^ b) & crossab)/magCrossSqr;
00488 scalar t = ((c ^ a) & crossab)/magCrossSqr;
00489
00490
00491
00492
00493
00494 return
00495 (
00496 s >= 0
00497 && s <= 1
00498 && t >= 0
00499 && t <= 1
00500 && magSqr(eIs + a*s - eJs - b*t) <= rCutMaxSqr_
00501 );
00502 }
00503
00504 return false;
00505 }
00506
00507
00508 const Foam::labelList Foam::interactionLists::realCellsInRangeOfSegment
00509 (
00510 const labelList& segmentFaces,
00511 const labelList& segmentEdges,
00512 const labelList& segmentPoints
00513 ) const
00514 {
00515 DynamicList<label> realCellsFoundInRange;
00516
00517 forAll(segmentFaces, sF)
00518 {
00519 const label f = segmentFaces[sF];
00520
00521 forAll (mesh_.points(), p)
00522 {
00523 if (testPointFaceDistance(p, f))
00524 {
00525 const labelList& pCells(mesh_.pointCells()[p]);
00526
00527 forAll(pCells, pC)
00528 {
00529 const label cellI(pCells[pC]);
00530
00531 if (findIndex(realCellsFoundInRange, cellI) == -1)
00532 {
00533 realCellsFoundInRange.append(cellI);
00534 }
00535 }
00536 }
00537 }
00538 }
00539
00540 forAll(segmentPoints, sP)
00541 {
00542 const label p = segmentPoints[sP];
00543
00544 forAll(mesh_.faces(), f)
00545 {
00546 if (testPointFaceDistance(p, f))
00547 {
00548 const label cellO(mesh_.faceOwner()[f]);
00549
00550 if (findIndex(realCellsFoundInRange, cellO) == -1)
00551 {
00552 realCellsFoundInRange.append(cellO);
00553 }
00554
00555 if (mesh_.isInternalFace(f))
00556 {
00557
00558
00559 const label cellN(mesh_.faceNeighbour()[f]);
00560
00561 if (findIndex(realCellsFoundInRange, cellN) == -1)
00562 {
00563 realCellsFoundInRange.append(cellN);
00564 }
00565 }
00566 }
00567 }
00568 }
00569
00570 forAll(segmentEdges, sE)
00571 {
00572 const edge& eJ(mesh_.edges()[segmentEdges[sE]]);
00573
00574 forAll (mesh_.edges(), edgeIIndex)
00575 {
00576 const edge& eI(mesh_.edges()[edgeIIndex]);
00577
00578 if (testEdgeEdgeDistance(eI, eJ))
00579 {
00580 const labelList& eICells(mesh_.edgeCells()[edgeIIndex]);
00581
00582 forAll(eICells, eIC)
00583 {
00584 const label cellI(eICells[eIC]);
00585
00586 if (findIndex(realCellsFoundInRange, cellI) == -1)
00587 {
00588 realCellsFoundInRange.append(cellI);
00589 }
00590 }
00591 }
00592 }
00593 }
00594
00595 return realCellsFoundInRange.shrink();
00596 }
00597
00598
00599 const Foam::labelList Foam::interactionLists::referredCellsInRangeOfSegment
00600 (
00601 const List<referredCell>& referredInteractionList,
00602 const labelList& segmentFaces,
00603 const labelList& segmentEdges,
00604 const labelList& segmentPoints
00605 ) const
00606 {
00607 DynamicList<label> referredCellsFoundInRange;
00608
00609 forAll(segmentFaces, sF)
00610 {
00611 const label f = segmentFaces[sF];
00612
00613 forAll(referredInteractionList, rIL)
00614 {
00615 const vectorList& refCellPoints
00616 = referredInteractionList[rIL].vertexPositions();
00617
00618 if (testPointFaceDistance(refCellPoints, f))
00619 {
00620 if (findIndex(referredCellsFoundInRange, rIL) == -1)
00621 {
00622 referredCellsFoundInRange.append(rIL);
00623 }
00624 }
00625 }
00626 }
00627
00628 forAll(segmentPoints, sP)
00629 {
00630 const label p = segmentPoints[sP];
00631
00632 forAll(referredInteractionList, rIL)
00633 {
00634 const referredCell& refCell(referredInteractionList[rIL]);
00635
00636 if (testPointFaceDistance(p, refCell))
00637 {
00638 if (findIndex(referredCellsFoundInRange, rIL) == -1)
00639 {
00640 referredCellsFoundInRange.append(rIL);
00641 }
00642 }
00643 }
00644 }
00645
00646 forAll(segmentEdges, sE)
00647 {
00648 const edge& eI(mesh_.edges()[segmentEdges[sE]]);
00649
00650 forAll(referredInteractionList, rIL)
00651 {
00652 const vectorList& refCellPoints
00653 = referredInteractionList[rIL].vertexPositions();
00654
00655 const edgeList& refCellEdges
00656 = referredInteractionList[rIL].edges();
00657
00658 forAll(refCellEdges, rCE)
00659 {
00660 const edge& eJ(refCellEdges[rCE]);
00661
00662 if
00663 (
00664 testEdgeEdgeDistance
00665 (
00666 eI,
00667 refCellPoints[eJ.start()],
00668 refCellPoints[eJ.end()]
00669 )
00670 )
00671 {
00672 if(findIndex(referredCellsFoundInRange, rIL) == -1)
00673 {
00674 referredCellsFoundInRange.append(rIL);
00675 }
00676 }
00677 }
00678 }
00679 }
00680
00681 return referredCellsFoundInRange.shrink();
00682 }
00683
00684
00685