1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "sampledSet.H"
29 #include "primitiveMesh.H"
30 #include "meshSearch.H"
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 const scalar sampledSet::tol = 1e-6;
39 defineTypeNameAndDebug(sampledSet, 0);
40 defineRunTimeSelectionTable(sampledSet, word);
44 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
46 Foam::label Foam::sampledSet::getBoundaryCell(const label faceI) const
48 return mesh().faceOwner()[faceI];
52 Foam::label Foam::sampledSet::getCell
62 "sampledSet::getCell(const label, const point&)"
63 ) << "Illegal face label " << faceI
67 if (faceI >= mesh().nInternalFaces())
69 label cellI = getBoundaryCell(faceI);
71 if (!mesh().pointInCell(sample, cellI))
75 "sampledSet::getCell(const label, const point&)"
76 ) << "Found cell " << cellI << " using face " << faceI
77 << ". But cell does not contain point " << sample
84 // Try owner and neighbour to see which one contains sample
86 label cellI = mesh().faceOwner()[faceI];
88 if (mesh().pointInCell(sample, cellI))
94 cellI = mesh().faceNeighbour()[faceI];
96 if (mesh().pointInCell(sample, cellI))
104 "sampledSet::getCell(const label, const point&)"
105 ) << "None of the neighbours of face "
106 << faceI << " contains point " << sample
107 << abort(FatalError);
116 Foam::scalar Foam::sampledSet::calcSign
122 vector vec = sample - mesh().faceCentres()[faceI];
124 scalar magVec = mag(vec);
128 // sample on face centre. Regard as inside
134 vector n = mesh().faceAreas()[faceI];
136 n /= mag(n) + VSMALL;
142 // Return face (or -1) of face which is within smallDist of sample
143 Foam::label Foam::sampledSet::findNearFace
147 const scalar smallDist
150 const cell& myFaces = mesh().cells()[cellI];
152 forAll(myFaces, myFaceI)
154 const face& f = mesh().faces()[myFaces[myFaceI]];
156 pointHit inter = f.nearestPoint(sample, mesh().points());
162 dist = mag(inter.hitPoint() - sample);
166 dist = mag(inter.missPoint() - sample);
169 if (dist < smallDist)
171 return myFaces[myFaceI];
178 // 'Pushes' point facePt (which is almost on face) in direction of cell centre
179 // so it is clearly inside.
180 Foam::point Foam::sampledSet::pushIn
186 label cellI = mesh().faceOwner()[faceI];
188 const point& cellCtr = mesh().cellCentres()[cellI];
191 facePt + tol*(cellCtr - facePt);
193 if (!searchEngine().pointInCell(newSample, cellI))
197 "sampledSet::pushIn(const point&, const label)"
198 ) << "After pushing " << facePt << " to " << newSample
199 << " it is still outside faceI " << faceI << endl
200 << "Please change your starting point"
201 << abort(FatalError);
203 //Info<< "pushIn : moved " << facePt << " to " << newSample
210 // Calculates start of tracking given samplePt and first boundary intersection
211 // (bPoint, bFaceI). bFaceI == -1 if no boundary intersection.
212 // Returns true if trackPt is sampling point
213 bool Foam::sampledSet::getTrackingPoint
215 const vector& offset,
216 const point& samplePt,
225 const scalar smallDist = mag(tol*offset);
227 bool isGoodSample = false;
231 // No boundary intersection. Try and find cell samplePt is in
232 trackCellI = mesh().findCell(samplePt);
237 || !mesh().pointInCell(samplePt, trackCellI)
240 // Line samplePt - end_ does not intersect domain at all.
241 // (or is along edge)
242 //Info<< "getTrackingPoint : samplePt outside domain : "
243 // << " samplePt:" << samplePt
249 isGoodSample = false;
253 // start is inside. Use it as tracking point
254 //Info<< "getTrackingPoint : samplePt inside :"
255 // << " samplePt:" << samplePt
256 // << " trackCellI:" << trackCellI
265 else if (mag(samplePt - bPoint) < smallDist)
267 //Info<< "getTrackingPoint : samplePt:" << samplePt
268 // << " close to bPoint:"
269 // << bPoint << endl;
271 // samplePt close to bPoint. Snap to it
272 trackPt = pushIn(bPoint, bFaceI);
274 trackCellI = getBoundaryCell(trackFaceI);
280 scalar sign = calcSign(bFaceI, samplePt);
284 // samplePt inside or marginally outside.
287 trackCellI = mesh().findCell(trackPt);
293 // samplePt outside. use bPoint
294 trackPt = pushIn(bPoint, bFaceI);
296 trackCellI = getBoundaryCell(trackFaceI);
298 isGoodSample = false;
304 Info<< "sampledSet::getTrackingPoint :"
305 << " offset:" << offset
306 << " samplePt:" << samplePt
307 << " bPoint:" << bPoint
308 << " bFaceI:" << bFaceI
309 << endl << " Calculated first tracking point :"
310 << " trackPt:" << trackPt
311 << " trackCellI:" << trackCellI
312 << " trackFaceI:" << trackFaceI
313 << " isGoodSample:" << isGoodSample
321 void Foam::sampledSet::setSamples
323 const List<point>& samplingPts,
324 const labelList& samplingCells,
325 const labelList& samplingFaces,
326 const labelList& samplingSegments,
327 const scalarList& samplingCurveDist
330 setSize(samplingPts.size());
331 cells_.setSize(samplingCells.size());
332 faces_.setSize(samplingFaces.size());
333 segments_.setSize(samplingSegments.size());
334 curveDist_.setSize(samplingCurveDist.size());
338 (cells_.size() != size())
339 || (faces_.size() != size())
340 || (segments_.size() != size())
341 || (curveDist_.size() != size())
344 FatalErrorIn("sampledSet::setSamples()")
345 << "sizes not equal : "
346 << " points:" << size()
347 << " cells:" << cells_.size()
348 << " faces:" << faces_.size()
349 << " segments:" << segments_.size()
350 << " curveDist:" << curveDist_.size()
351 << abort(FatalError);
354 forAll(samplingPts, sampleI)
356 operator[](sampleI) = samplingPts[sampleI];
358 cells_ = samplingCells;
359 faces_ = samplingFaces;
360 segments_ = samplingSegments;
361 curveDist_ = samplingCurveDist;
365 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
367 Foam::sampledSet::sampledSet
370 const polyMesh& mesh,
371 meshSearch& searchEngine,
375 coordSet(name, axis),
377 searchEngine_(searchEngine),
385 Foam::sampledSet::sampledSet
388 const polyMesh& mesh,
389 meshSearch& searchEngine,
390 const dictionary& dict
393 coordSet(name, dict.lookup("axis")),
395 searchEngine_(searchEngine),
403 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
405 Foam::sampledSet::~sampledSet()
409 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
411 Foam::autoPtr<Foam::sampledSet> Foam::sampledSet::New
414 const polyMesh& mesh,
415 meshSearch& searchEngine,
416 const dictionary& dict
419 word sampleType(dict.lookup("type"));
421 wordConstructorTable::iterator cstrIter =
422 wordConstructorTablePtr_->find(sampleType);
424 if (cstrIter == wordConstructorTablePtr_->end())
428 "sampledSet::New(const word&, "
429 "const polyMesh&, meshSearch&, const dictionary&)"
430 ) << "Unknown sample type " << sampleType
432 << "Valid sample types : " << endl
433 << wordConstructorTablePtr_->toc()
437 return autoPtr<sampledSet>
450 Foam::Ostream& Foam::sampledSet::write(Ostream& os) const
454 os << endl << "\t(cellI)\t(faceI)" << endl;
456 forAll(*this, sampleI)
458 os << '\t' << cells_[sampleI]
459 << '\t' << faces_[sampleI]
467 // ************************************************************************* //