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 "searchableSurfaceCollection.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <OpenFOAM/SortableList.H>
00029 #include <OpenFOAM/Time.H>
00030 #include <OpenFOAM/ListOps.H>
00031
00032
00033
00034 namespace Foam
00035 {
00036
00037 defineTypeNameAndDebug(searchableSurfaceCollection, 0);
00038 addToRunTimeSelectionTable
00039 (
00040 searchableSurface,
00041 searchableSurfaceCollection,
00042 dict
00043 );
00044
00045 }
00046
00047
00048
00049
00050 void Foam::searchableSurfaceCollection::findNearest
00051 (
00052 const pointField& samples,
00053 scalarField& minDistSqr,
00054 List<pointIndexHit>& nearestInfo,
00055 labelList& nearestSurf
00056 ) const
00057 {
00058
00059 nearestInfo.setSize(samples.size());
00060 nearestInfo = pointIndexHit();
00061 nearestSurf.setSize(samples.size());
00062 nearestSurf = -1;
00063
00064 List<pointIndexHit> hitInfo(samples.size());
00065
00066 const scalarField localMinDistSqr(samples.size(), GREAT);
00067
00068 forAll(subGeom_, surfI)
00069 {
00070 subGeom_[surfI].findNearest
00071 (
00072 cmptDivide
00073 (
00074 transform_[surfI].localPosition(samples),
00075 scale_[surfI]
00076 ),
00077 localMinDistSqr,
00078 hitInfo
00079 );
00080
00081 forAll(hitInfo, pointI)
00082 {
00083 if (hitInfo[pointI].hit())
00084 {
00085
00086
00087 point globalPt = transform_[surfI].globalPosition
00088 (
00089 cmptMultiply
00090 (
00091 hitInfo[pointI].rawPoint(),
00092 scale_[surfI]
00093 )
00094 );
00095
00096 scalar distSqr = magSqr(globalPt - samples[pointI]);
00097
00098 if (distSqr < minDistSqr[pointI])
00099 {
00100 minDistSqr[pointI] = distSqr;
00101 nearestInfo[pointI].setPoint(globalPt);
00102 nearestInfo[pointI].setHit();
00103 nearestInfo[pointI].setIndex
00104 (
00105 hitInfo[pointI].index()
00106 + indexOffset_[surfI]
00107 );
00108 nearestSurf[pointI] = surfI;
00109 }
00110 }
00111 }
00112 }
00113 }
00114
00115
00116
00117
00118 void Foam::searchableSurfaceCollection::sortHits
00119 (
00120 const List<pointIndexHit>& info,
00121 List<List<pointIndexHit> >& surfInfo,
00122 labelListList& infoMap
00123 ) const
00124 {
00125
00126 labelList nHits(subGeom_.size(), 0);
00127
00128 forAll(info, pointI)
00129 {
00130 if (info[pointI].hit())
00131 {
00132 label index = info[pointI].index();
00133 label surfI = findLower(indexOffset_, index+1);
00134 nHits[surfI]++;
00135 }
00136 }
00137
00138
00139 surfInfo.setSize(subGeom_.size());
00140
00141 infoMap.setSize(subGeom_.size());
00142
00143 forAll(surfInfo, surfI)
00144 {
00145 surfInfo[surfI].setSize(nHits[surfI]);
00146 infoMap[surfI].setSize(nHits[surfI]);
00147 }
00148 nHits = 0;
00149
00150 forAll(info, pointI)
00151 {
00152 if (info[pointI].hit())
00153 {
00154 label index = info[pointI].index();
00155 label surfI = findLower(indexOffset_, index+1);
00156
00157
00158
00159 label localI = nHits[surfI]++;
00160 surfInfo[surfI][localI] = pointIndexHit
00161 (
00162 info[pointI].hit(),
00163 info[pointI].rawPoint(),
00164 index-indexOffset_[surfI]
00165 );
00166 infoMap[surfI][localI] = pointI;
00167 }
00168 }
00169 }
00170
00171
00172
00173
00174 Foam::searchableSurfaceCollection::searchableSurfaceCollection
00175 (
00176 const IOobject& io,
00177 const dictionary& dict
00178 )
00179 :
00180 searchableSurface(io),
00181 instance_(dict.size()),
00182 scale_(dict.size()),
00183 transform_(dict.size()),
00184 subGeom_(dict.size()),
00185 mergeSubRegions_(dict.lookup("mergeSubRegions")),
00186 indexOffset_(dict.size()+1)
00187 {
00188 Info<< "SearchableCollection : " << name() << endl;
00189
00190 label surfI = 0;
00191 label startIndex = 0;
00192 forAllConstIter(dictionary, dict, iter)
00193 {
00194 if (dict.isDict(iter().keyword()))
00195 {
00196 instance_[surfI] = iter().keyword();
00197
00198 const dictionary& subDict = dict.subDict(instance_[surfI]);
00199
00200 scale_[surfI] = subDict.lookup("scale");
00201 transform_.set
00202 (
00203 surfI,
00204 coordinateSystem::New
00205 (
00206 "",
00207 subDict.subDict("transform")
00208 )
00209 );
00210
00211 const word subGeomName(subDict.lookup("surface"));
00212
00213
00214 const searchableSurface& s =
00215 io.db().lookupObject<searchableSurface>(subGeomName);
00216
00217
00218
00219
00220 if (s.size() != s.globalSize())
00221 {
00222 FatalErrorIn
00223 (
00224 "searchableSurfaceCollection::searchableSurfaceCollection"
00225 "(const IOobject&, const dictionary&)"
00226 ) << "Cannot use a distributed surface in a collection."
00227 << exit(FatalError);
00228 }
00229
00230 subGeom_.set(surfI, &const_cast<searchableSurface&>(s));
00231
00232 indexOffset_[surfI] = startIndex;
00233 startIndex += subGeom_[surfI].size();
00234
00235 Info<< " instance : " << instance_[surfI] << endl;
00236 Info<< " surface : " << s.name() << endl;
00237 Info<< " scale : " << scale_[surfI] << endl;
00238 Info<< " coordsys : " << transform_[surfI] << endl;
00239
00240 surfI++;
00241 }
00242 }
00243 indexOffset_[surfI] = startIndex;
00244
00245 instance_.setSize(surfI);
00246 scale_.setSize(surfI);
00247 transform_.setSize(surfI);
00248 subGeom_.setSize(surfI);
00249 indexOffset_.setSize(surfI+1);
00250 }
00251
00252
00253
00254
00255 Foam::searchableSurfaceCollection::~searchableSurfaceCollection()
00256 {}
00257
00258
00259
00260
00261 const Foam::wordList& Foam::searchableSurfaceCollection::regions() const
00262 {
00263 if (regions_.size() == 0)
00264 {
00265 regionOffset_.setSize(subGeom_.size());
00266
00267 DynamicList<word> allRegions;
00268 forAll(subGeom_, surfI)
00269 {
00270 regionOffset_[surfI] = allRegions.size();
00271
00272 if (mergeSubRegions_)
00273 {
00274
00275 allRegions.append(instance_[surfI] + "_" + Foam::name(surfI));
00276 }
00277 else
00278 {
00279 const wordList& subRegions = subGeom_[surfI].regions();
00280
00281 forAll(subRegions, i)
00282 {
00283 allRegions.append(instance_[surfI] + "_" + subRegions[i]);
00284 }
00285 }
00286 }
00287 regions_.transfer(allRegions.shrink());
00288 }
00289 return regions_;
00290 }
00291
00292
00293 Foam::label Foam::searchableSurfaceCollection::size() const
00294 {
00295 return indexOffset_[indexOffset_.size()-1];
00296 }
00297
00298
00299 Foam::pointField Foam::searchableSurfaceCollection::coordinates() const
00300 {
00301
00302 pointField coords(size());
00303
00304
00305 label coordI = 0;
00306
00307 forAll(subGeom_, surfI)
00308 {
00309 const pointField subCoords = subGeom_[surfI].coordinates();
00310
00311 forAll(subCoords, i)
00312 {
00313 coords[coordI++] = transform_[surfI].globalPosition
00314 (
00315 cmptMultiply
00316 (
00317 subCoords[i],
00318 scale_[surfI]
00319 )
00320 );
00321 }
00322 }
00323
00324 return coords;
00325 }
00326
00327
00328 void Foam::searchableSurfaceCollection::findNearest
00329 (
00330 const pointField& samples,
00331 const scalarField& nearestDistSqr,
00332 List<pointIndexHit>& nearestInfo
00333 ) const
00334 {
00335
00336 scalarField minDistSqr(nearestDistSqr);
00337
00338 labelList nearestSurf;
00339 findNearest
00340 (
00341 samples,
00342 minDistSqr,
00343 nearestInfo,
00344 nearestSurf
00345 );
00346 }
00347
00348
00349 void Foam::searchableSurfaceCollection::findLine
00350 (
00351 const pointField& start,
00352 const pointField& end,
00353 List<pointIndexHit>& info
00354 ) const
00355 {
00356 info.setSize(start.size());
00357 info = pointIndexHit();
00358
00359
00360 pointField nearest(end);
00361
00362 List<pointIndexHit> hitInfo(start.size());
00363
00364 forAll(subGeom_, surfI)
00365 {
00366
00367 tmp<pointField> e0 = cmptDivide
00368 (
00369 transform_[surfI].localPosition
00370 (
00371 start
00372 ),
00373 scale_[surfI]
00374 );
00375
00376
00377 tmp<pointField> e1 = cmptDivide
00378 (
00379 transform_[surfI].localPosition
00380 (
00381 nearest
00382 ),
00383 scale_[surfI]
00384 );
00385
00386 subGeom_[surfI].findLine(e0, e1, hitInfo);
00387
00388 forAll(hitInfo, pointI)
00389 {
00390 if (hitInfo[pointI].hit())
00391 {
00392
00393 nearest[pointI] = transform_[surfI].globalPosition
00394 (
00395 cmptMultiply
00396 (
00397 hitInfo[pointI].rawPoint(),
00398 scale_[surfI]
00399 )
00400 );
00401 info[pointI] = hitInfo[pointI];
00402 info[pointI].rawPoint() = nearest[pointI];
00403 info[pointI].setIndex
00404 (
00405 hitInfo[pointI].index()
00406 + indexOffset_[surfI]
00407 );
00408 }
00409 }
00410 }
00411
00412
00413
00414 if (false)
00415 {
00416 forAll(info, pointI)
00417 {
00418 if (info[pointI].hit())
00419 {
00420 vector n(end[pointI] - start[pointI]);
00421 scalar magN = mag(n);
00422
00423 if (magN > SMALL)
00424 {
00425 n /= mag(n);
00426
00427 scalar s = ((info[pointI].rawPoint()-start[pointI])&n);
00428
00429 if (s < 0 || s > 1)
00430 {
00431 FatalErrorIn
00432 (
00433 "searchableSurfaceCollection::findLine(..)"
00434 ) << "point:" << info[pointI]
00435 << " s:" << s
00436 << " outside vector "
00437 << " start:" << start[pointI]
00438 << " end:" << end[pointI]
00439 << abort(FatalError);
00440 }
00441 }
00442 }
00443 }
00444 }
00445 }
00446
00447
00448 void Foam::searchableSurfaceCollection::findLineAny
00449 (
00450 const pointField& start,
00451 const pointField& end,
00452 List<pointIndexHit>& info
00453 ) const
00454 {
00455
00456 findLine(start, end, info);
00457 }
00458
00459
00460 void Foam::searchableSurfaceCollection::findLineAll
00461 (
00462 const pointField& start,
00463 const pointField& end,
00464 List<List<pointIndexHit> >& info
00465 ) const
00466 {
00467
00468 List<pointIndexHit> nearestInfo;
00469 findLine(start, end, nearestInfo);
00470
00471 info.setSize(start.size());
00472 forAll(info, pointI)
00473 {
00474 if (nearestInfo[pointI].hit())
00475 {
00476 info[pointI].setSize(1);
00477 info[pointI][0] = nearestInfo[pointI];
00478 }
00479 else
00480 {
00481 info[pointI].clear();
00482 }
00483 }
00484 }
00485
00486
00487 void Foam::searchableSurfaceCollection::getRegion
00488 (
00489 const List<pointIndexHit>& info,
00490 labelList& region
00491 ) const
00492 {
00493 if (subGeom_.size() == 0)
00494 {}
00495 else if (subGeom_.size() == 1)
00496 {
00497 if (mergeSubRegions_)
00498 {
00499 region.setSize(info.size());
00500 region = regionOffset_[0];
00501 }
00502 else
00503 {
00504 subGeom_[0].getRegion(info, region);
00505 }
00506 }
00507 else
00508 {
00509
00510
00511
00512 List<List<pointIndexHit> > surfInfo;
00513
00514 List<List<label> > infoMap;
00515 sortHits(info, surfInfo, infoMap);
00516
00517 region.setSize(info.size());
00518 region = -1;
00519
00520
00521
00522 if (mergeSubRegions_)
00523 {
00524
00525 forAll(infoMap, surfI)
00526 {
00527 const labelList& map = infoMap[surfI];
00528 forAll(map, i)
00529 {
00530 region[map[i]] = regionOffset_[surfI];
00531 }
00532 }
00533 }
00534 else
00535 {
00536 forAll(infoMap, surfI)
00537 {
00538 labelList surfRegion;
00539 subGeom_[surfI].getRegion(surfInfo[surfI], surfRegion);
00540
00541 const labelList& map = infoMap[surfI];
00542 forAll(map, i)
00543 {
00544 region[map[i]] = regionOffset_[surfI] + surfRegion[i];
00545 }
00546 }
00547 }
00548 }
00549 }
00550
00551
00552 void Foam::searchableSurfaceCollection::getNormal
00553 (
00554 const List<pointIndexHit>& info,
00555 vectorField& normal
00556 ) const
00557 {
00558 if (subGeom_.size() == 0)
00559 {}
00560 else if (subGeom_.size() == 1)
00561 {
00562 subGeom_[0].getNormal(info, normal);
00563 }
00564 else
00565 {
00566
00567
00568
00569 List<List<pointIndexHit> > surfInfo;
00570
00571 List<List<label> > infoMap;
00572 sortHits(info, surfInfo, infoMap);
00573
00574 normal.setSize(info.size());
00575
00576
00577 forAll(surfInfo, surfI)
00578 {
00579 vectorField surfNormal;
00580 subGeom_[surfI].getNormal(surfInfo[surfI], surfNormal);
00581
00582 const labelList& map = infoMap[surfI];
00583 forAll(map, i)
00584 {
00585 normal[map[i]] = surfNormal[i];
00586 }
00587 }
00588 }
00589 }
00590
00591
00592 void Foam::searchableSurfaceCollection::getVolumeType
00593 (
00594 const pointField& points,
00595 List<volumeType>& volType
00596 ) const
00597 {
00598 FatalErrorIn
00599 (
00600 "searchableSurfaceCollection::getVolumeType(const pointField&"
00601 ", List<volumeType>&) const"
00602 ) << "Volume type not supported for collection."
00603 << exit(FatalError);
00604 }
00605
00606
00607 void Foam::searchableSurfaceCollection::distribute
00608 (
00609 const List<treeBoundBox>& bbs,
00610 const bool keepNonLocal,
00611 autoPtr<mapDistribute>& faceMap,
00612 autoPtr<mapDistribute>& pointMap
00613 )
00614 {
00615 forAll(subGeom_, surfI)
00616 {
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 subGeom_[surfI].distribute
00631 (
00632 bbs,
00633 keepNonLocal,
00634 faceMap,
00635 pointMap
00636 );
00637 }
00638 }
00639
00640
00641 void Foam::searchableSurfaceCollection::setField(const labelList& values)
00642 {
00643 forAll(subGeom_, surfI)
00644 {
00645 subGeom_[surfI].setField
00646 (
00647 static_cast<const labelList&>
00648 (
00649 SubList<label>
00650 (
00651 values,
00652 subGeom_[surfI].size(),
00653 indexOffset_[surfI]
00654 )
00655 )
00656 );
00657 }
00658 }
00659
00660
00661 void Foam::searchableSurfaceCollection::getField
00662 (
00663 const List<pointIndexHit>& info,
00664 labelList& values
00665 ) const
00666 {
00667 if (subGeom_.size() == 0)
00668 {}
00669 else if (subGeom_.size() == 1)
00670 {
00671 subGeom_[0].getField(info, values);
00672 }
00673 else
00674 {
00675
00676
00677
00678 List<List<pointIndexHit> > surfInfo;
00679
00680 List<List<label> > infoMap;
00681 sortHits(info, surfInfo, infoMap);
00682
00683
00684 forAll(surfInfo, surfI)
00685 {
00686 labelList surfValues;
00687 subGeom_[surfI].getField(surfInfo[surfI], surfValues);
00688
00689 if (surfValues.size())
00690 {
00691
00692 values.setSize(info.size());
00693
00694 const labelList& map = infoMap[surfI];
00695 forAll(map, i)
00696 {
00697 values[map[i]] = surfValues[i];
00698 }
00699 }
00700 }
00701 }
00702 }
00703
00704
00705