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 "surfaceToCell.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 #include <meshTools/meshSearch.H>
00029 #include <triSurface/triSurface.H>
00030 #include <meshTools/triSurfaceSearch.H>
00031 #include <meshTools/cellClassification.H>
00032
00033 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00034
00035
00036
00037 namespace Foam
00038 {
00039
00040 defineTypeNameAndDebug(surfaceToCell, 0);
00041
00042 addToRunTimeSelectionTable(topoSetSource, surfaceToCell, word);
00043
00044 addToRunTimeSelectionTable(topoSetSource, surfaceToCell, istream);
00045
00046 }
00047
00048
00049 Foam::topoSetSource::addToUsageTable Foam::surfaceToCell::usage_
00050 (
00051 surfaceToCell::typeName,
00052 "\n Usage: surfaceToCell"
00053 "<surface> <outsidePoints> <cut> <inside> <outside> <near> <curvature>\n\n"
00054 " <surface> name of triSurface\n"
00055 " <outsidePoints> list of points that define outside\n"
00056 " <cut> boolean whether to include cells cut by surface\n"
00057 " <inside> ,, ,, inside surface\n"
00058 " <outside> ,, ,, outside surface\n"
00059 " <near> scalar; include cells with centre <= near to surface\n"
00060 " <curvature> scalar; include cells close to strong curvature"
00061 " on surface\n"
00062 " (curvature defined as difference in surface normal at nearest"
00063 " point on surface for each vertex of cell)\n\n"
00064 );
00065
00066
00067
00068
00069 Foam::label Foam::surfaceToCell::getNearest
00070 (
00071 const triSurfaceSearch& querySurf,
00072 const label pointI,
00073 const point& pt,
00074 const vector& span,
00075 Map<label>& cache
00076 )
00077 {
00078 Map<label>::const_iterator iter = cache.find(pointI);
00079
00080 if (iter != cache.end())
00081 {
00082
00083 return iter();
00084 }
00085 else
00086 {
00087 pointIndexHit inter = querySurf.nearest(pt, span);
00088
00089
00090 label triI = inter.index();
00091
00092
00093 cache.insert(pointI, triI);
00094
00095 return triI;
00096 }
00097 }
00098
00099
00100
00101
00102
00103 bool Foam::surfaceToCell::differingPointNormals
00104 (
00105 const triSurfaceSearch& querySurf,
00106
00107 const vector& span,
00108 const label cellI,
00109 const label cellTriI,
00110
00111 Map<label>& pointToNearest
00112 ) const
00113 {
00114 const triSurface& surf = querySurf.surface();
00115 const vectorField& normals = surf.faceNormals();
00116
00117 const faceList& faces = mesh().faces();
00118 const pointField& points = mesh().points();
00119
00120 const labelList& cFaces = mesh().cells()[cellI];
00121
00122 forAll(cFaces, cFaceI)
00123 {
00124 const face& f = faces[cFaces[cFaceI]];
00125
00126 forAll(f, fp)
00127 {
00128 label pointI = f[fp];
00129
00130 label pointTriI =
00131 getNearest
00132 (
00133 querySurf,
00134 pointI,
00135 points[pointI],
00136 span,
00137 pointToNearest
00138 );
00139
00140 if (pointTriI != -1 && pointTriI != cellTriI)
00141 {
00142 scalar cosAngle = normals[pointTriI] & normals[cellTriI];
00143
00144 if (cosAngle < 0.9)
00145 {
00146 return true;
00147 }
00148 }
00149 }
00150 }
00151 return false;
00152 }
00153
00154
00155 void Foam::surfaceToCell::combine(topoSet& set, const bool add) const
00156 {
00157 cpuTime timer;
00158
00159 if (includeCut_ || includeInside_ || includeOutside_)
00160 {
00161
00162
00163
00164
00165
00166
00167
00168 meshSearch queryMesh(mesh_, true);
00169
00170
00171
00172 forAll(outsidePoints_, outsideI)
00173 {
00174 const point& outsidePoint = outsidePoints_[outsideI];
00175
00176
00177 label cellI = queryMesh.findCell(outsidePoint, -1, false);
00178 if (returnReduce(cellI, maxOp<label>()) == -1)
00179 {
00180 FatalErrorIn("surfaceToCell::combine(topoSet&, const bool)")
00181 << "outsidePoint " << outsidePoint
00182 << " is not inside any cell"
00183 << exit(FatalError);
00184 }
00185 }
00186
00187
00188
00189 cellClassification cellType
00190 (
00191 mesh_,
00192 queryMesh,
00193 querySurf(),
00194 outsidePoints_
00195 );
00196
00197
00198 Info<< " Marked inside/outside in = "
00199 << timer.cpuTimeIncrement() << " s" << endl << endl;
00200
00201
00202 forAll(cellType, cellI)
00203 {
00204 label cType = cellType[cellI];
00205
00206 if
00207 (
00208 (
00209 includeCut_
00210 && (cType == cellClassification::CUT)
00211 )
00212 || (
00213 includeInside_
00214 && (cType == cellClassification::INSIDE)
00215 )
00216 || (
00217 includeOutside_
00218 && (cType == cellClassification::OUTSIDE)
00219 )
00220 )
00221 {
00222 addOrDelete(set, cellI, add);
00223 }
00224 }
00225 }
00226
00227
00228 if (nearDist_ > 0)
00229 {
00230
00231
00232
00233
00234 const pointField& ctrs = mesh_.cellCentres();
00235
00236
00237 const vector span(nearDist_, nearDist_, nearDist_);
00238
00239
00240 if (curvature_ < -1)
00241 {
00242 Info<< " Selecting cells with cellCentre closer than "
00243 << nearDist_ << " to surface" << endl;
00244
00245
00246
00247 forAll(ctrs, cellI)
00248 {
00249 const point& c = ctrs[cellI];
00250
00251 pointIndexHit inter = querySurf().nearest(c, span);
00252
00253 if (inter.hit() && (mag(inter.hitPoint() - c) < nearDist_))
00254 {
00255 addOrDelete(set, cellI, add);
00256 }
00257 }
00258
00259 Info<< " Determined nearest surface point in = "
00260 << timer.cpuTimeIncrement() << " s" << endl << endl;
00261
00262 }
00263 else
00264 {
00265
00266
00267 Info<< " Selecting cells with cellCentre closer than "
00268 << nearDist_ << " to surface and curvature factor"
00269 << " less than " << curvature_ << endl;
00270
00271
00272 Map<label> pointToNearest(mesh_.nCells()/10);
00273
00274 forAll(ctrs, cellI)
00275 {
00276 const point& c = ctrs[cellI];
00277
00278 pointIndexHit inter = querySurf().nearest(c, span);
00279
00280 if (inter.hit() && (mag(inter.hitPoint() - c) < nearDist_))
00281 {
00282 if
00283 (
00284 differingPointNormals
00285 (
00286 querySurf(),
00287 span,
00288 cellI,
00289 inter.index(),
00290 pointToNearest
00291 )
00292 )
00293 {
00294 addOrDelete(set, cellI, add);
00295 }
00296 }
00297 }
00298
00299 Info<< " Determined nearest surface point in = "
00300 << timer.cpuTimeIncrement() << " s" << endl << endl;
00301 }
00302 }
00303 }
00304
00305
00306 void Foam::surfaceToCell::checkSettings() const
00307 {
00308 if
00309 (
00310 (nearDist_ < 0)
00311 && (curvature_ < -1)
00312 && (
00313 (includeCut_ && includeInside_ && includeOutside_)
00314 || (!includeCut_ && !includeInside_ && !includeOutside_)
00315 )
00316 )
00317 {
00318 FatalErrorIn
00319 (
00320 "surfaceToCell:checkSettings()"
00321 ) << "Illegal include cell specification."
00322 << " Result would be either all or no cells." << endl
00323 << "Please set one of includeCut, includeInside, includeOutside"
00324 << " to true, set nearDistance to a value > 0"
00325 << " or set curvature to a value -1 .. 1."
00326 << exit(FatalError);
00327 }
00328 }
00329
00330
00331
00332
00333
00334 Foam::surfaceToCell::surfaceToCell
00335 (
00336 const polyMesh& mesh,
00337 const fileName& surfName,
00338 const pointField& outsidePoints,
00339 const bool includeCut,
00340 const bool includeInside,
00341 const bool includeOutside,
00342 const scalar nearDist,
00343 const scalar curvature
00344 )
00345 :
00346 topoSetSource(mesh),
00347 surfName_(surfName),
00348 outsidePoints_(outsidePoints),
00349 includeCut_(includeCut),
00350 includeInside_(includeInside),
00351 includeOutside_(includeOutside),
00352 nearDist_(nearDist),
00353 curvature_(curvature),
00354 surfPtr_(new triSurface(surfName_)),
00355 querySurfPtr_(new triSurfaceSearch(*surfPtr_)),
00356 IOwnPtrs_(true)
00357 {
00358 checkSettings();
00359 }
00360
00361
00362
00363 Foam::surfaceToCell::surfaceToCell
00364 (
00365 const polyMesh& mesh,
00366 const fileName& surfName,
00367 const triSurface& surf,
00368 const triSurfaceSearch& querySurf,
00369 const pointField& outsidePoints,
00370 const bool includeCut,
00371 const bool includeInside,
00372 const bool includeOutside,
00373 const scalar nearDist,
00374 const scalar curvature
00375 )
00376 :
00377 topoSetSource(mesh),
00378 surfName_(surfName),
00379 outsidePoints_(outsidePoints),
00380 includeCut_(includeCut),
00381 includeInside_(includeInside),
00382 includeOutside_(includeOutside),
00383 nearDist_(nearDist),
00384 curvature_(curvature),
00385 surfPtr_(&surf),
00386 querySurfPtr_(&querySurf),
00387 IOwnPtrs_(false)
00388 {
00389 checkSettings();
00390 }
00391
00392
00393
00394 Foam::surfaceToCell::surfaceToCell
00395 (
00396 const polyMesh& mesh,
00397 const dictionary& dict
00398 )
00399 :
00400 topoSetSource(mesh),
00401 surfName_(dict.lookup("file")),
00402 outsidePoints_(dict.lookup("outsidePoints")),
00403 includeCut_(readBool(dict.lookup("includeCut"))),
00404 includeInside_(readBool(dict.lookup("includeInside"))),
00405 includeOutside_(readBool(dict.lookup("includeOutside"))),
00406 nearDist_(readScalar(dict.lookup("nearDistance"))),
00407 curvature_(readScalar(dict.lookup("curvature"))),
00408 surfPtr_(new triSurface(surfName_)),
00409 querySurfPtr_(new triSurfaceSearch(*surfPtr_)),
00410 IOwnPtrs_(true)
00411 {
00412 checkSettings();
00413 }
00414
00415
00416
00417 Foam::surfaceToCell::surfaceToCell
00418 (
00419 const polyMesh& mesh,
00420 Istream& is
00421 )
00422 :
00423 topoSetSource(mesh),
00424 surfName_(checkIs(is)),
00425 outsidePoints_(checkIs(is)),
00426 includeCut_(readBool(checkIs(is))),
00427 includeInside_(readBool(checkIs(is))),
00428 includeOutside_(readBool(checkIs(is))),
00429 nearDist_(readScalar(checkIs(is))),
00430 curvature_(readScalar(checkIs(is))),
00431 surfPtr_(new triSurface(surfName_)),
00432 querySurfPtr_(new triSurfaceSearch(*surfPtr_)),
00433 IOwnPtrs_(true)
00434 {
00435 checkSettings();
00436 }
00437
00438
00439
00440
00441 Foam::surfaceToCell::~surfaceToCell()
00442 {
00443 if (IOwnPtrs_)
00444 {
00445 if (surfPtr_)
00446 {
00447 delete surfPtr_;
00448 }
00449 if (querySurfPtr_)
00450 {
00451 delete querySurfPtr_;
00452 }
00453 }
00454 }
00455
00456
00457
00458
00459 void Foam::surfaceToCell::applyToSet
00460 (
00461 const topoSetSource::setAction action,
00462 topoSet& set
00463 ) const
00464 {
00465 if ( (action == topoSetSource::NEW) || (action == topoSetSource::ADD))
00466 {
00467 Info<< " Adding cells in relation to surface " << surfName_
00468 << " ..." << endl;
00469
00470 combine(set, true);
00471 }
00472 else if (action == topoSetSource::DELETE)
00473 {
00474 Info<< " Removing cells in relation to surface " << surfName_
00475 << " ..." << endl;
00476
00477 combine(set, false);
00478 }
00479 }
00480
00481
00482