1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 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 "uniformSet.H"
28 #include "meshSearch.H"
29 #include "DynamicList.H"
33 #include "passiveParticle.H"
36 #include "addToRunTimeSelectionTable.H"
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 defineTypeNameAndDebug(uniformSet, 0);
43 addToRunTimeSelectionTable(sampledSet, uniformSet, word);
47 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49 // Finds along line (samplePt + t * offset) next sample beyond or equal to
51 // Updates samplePt, sampleI
52 bool Foam::uniformSet::nextSample
54 const point& currentPt,
56 const scalar smallDist,
61 bool pointFound = false;
63 const vector normOffset = offset/mag(offset);
68 for(; sampleI < nPoints_; sampleI++)
70 scalar s = (samplePt - currentPt) & normOffset;
74 // samplePt is close to or beyond currentPt -> use it
86 // Sample singly connected segment. Returns false if end_ reached.
87 bool Foam::uniformSet::trackToBoundary
89 Particle<passiveParticle>& singleParticle,
92 DynamicList<point>& samplingPts,
93 DynamicList<label>& samplingCells,
94 DynamicList<label>& samplingFaces,
95 DynamicList<scalar>& samplingCurveDist
98 // distance vector between sampling points
99 const vector offset = (end_ - start_)/(nPoints_ - 1);
100 const vector smallVec = tol*offset;
101 const scalar smallDist = mag(smallVec);
104 const point& trackPt = singleParticle.position();
108 // Find next samplePt on/after trackPt. Update samplePt, sampleI
109 if (!nextSample(trackPt, offset, smallDist, samplePt, sampleI))
114 Info<< "trackToBoundary : Reached end : samplePt now:"
115 << samplePt << " sampleI now:" << sampleI << endl;
120 if (mag(samplePt - trackPt) < smallDist)
122 // trackPt corresponds with samplePt. Store and use next samplePt
125 Info<< "trackToBoundary : samplePt corresponds to trackPt : "
126 << " trackPt:" << trackPt << " samplePt:" << samplePt
130 samplingPts.append(trackPt);
131 samplingCells.append(singleParticle.cell());
132 samplingFaces.append(-1);
133 samplingCurveDist.append(mag(trackPt - start_));
135 // go to next samplePt
136 if (!nextSample(trackPt, offset, smallDist, samplePt, sampleI))
141 Info<< "trackToBoundary : Reached end : "
142 << " samplePt now:" << samplePt
143 << " sampleI now:" << sampleI
154 Info<< "Searching along trajectory from "
155 << " trackPt:" << trackPt
156 << " trackCellI:" << singleParticle.cell()
157 << " to:" << samplePt << endl;
160 point oldPos = trackPt;
164 singleParticle.stepFraction() = 0;
165 singleParticle.track(samplePt);
169 Info<< "Result of tracking "
170 << " trackPt:" << trackPt
171 << " trackCellI:" << singleParticle.cell()
172 << " trackFaceI:" << singleParticle.face()
173 << " onBoundary:" << singleParticle.onBoundary()
174 << " samplePt:" << samplePt
175 << " smallDist:" << smallDist
181 !singleParticle.onBoundary()
182 && (mag(trackPt - oldPos) < smallDist)
185 if (singleParticle.onBoundary())
187 //Info<< "trackToBoundary : reached boundary" << endl;
188 if (mag(trackPt - samplePt) < smallDist)
190 //Info<< "trackToBoundary : boundary is also sampling point"
192 // Reached samplePt on boundary
193 samplingPts.append(trackPt);
194 samplingCells.append(singleParticle.cell());
195 samplingFaces.append(facei);
196 samplingCurveDist.append(mag(trackPt - start_));
202 //Info<< "trackToBoundary : reached internal sampling point" << endl;
203 // Reached samplePt in cell or on internal face
204 samplingPts.append(trackPt);
205 samplingCells.append(singleParticle.cell());
206 samplingFaces.append(-1);
207 samplingCurveDist.append(mag(trackPt - start_));
209 // go to next samplePt
214 void Foam::uniformSet::calcSamples
216 DynamicList<point>& samplingPts,
217 DynamicList<label>& samplingCells,
218 DynamicList<label>& samplingFaces,
219 DynamicList<label>& samplingSegments,
220 DynamicList<scalar>& samplingCurveDist
223 // distance vector between sampling points
224 if ((nPoints_ < 2) || (mag(end_ - start_) < SMALL))
226 FatalErrorIn("uniformSet::calcSamples()")
227 << "Incorrect sample specification. Either too few points or"
228 << " start equals end point." << endl
229 << "nPoints:" << nPoints_
230 << " start:" << start_
235 const vector offset = (end_ - start_)/(nPoints_ - 1);
236 const vector normOffset = offset/mag(offset);
237 const vector smallVec = tol*offset;
238 const scalar smallDist = mag(smallVec);
240 // Get all boundary intersections
241 List<pointIndexHit> bHits =
242 searchEngine().intersections
248 point bPoint(GREAT, GREAT, GREAT);
251 if (bHits.size() > 0)
253 bPoint = bHits[0].hitPoint();
254 bFaceI = bHits[0].index();
257 // Get first tracking point. Use bPoint, bFaceI if provided.
260 label trackCellI = -1;
261 label trackFaceI = -1;
276 if (trackCellI == -1)
278 // Line start_ - end_ does not intersect domain at all.
279 // (or is along edge)
280 // Set points and cell/face labels to empty lists
287 samplingPts.append(start_);
288 samplingCells.append(trackCellI);
289 samplingFaces.append(trackFaceI);
290 samplingCurveDist.append(0.0);
294 // Track until hit end of all boundary intersections
297 // current segment number
300 // starting index of current segment in samplePts
301 label startSegmentI = 0;
304 point samplePt = start_;
306 // index in bHits; current boundary intersection
311 // Initialize tracking starting from trackPt
312 Cloud<passiveParticle> particles(mesh(), IDLList<passiveParticle>());
314 passiveParticle singleParticle
321 bool reachedBoundary = trackToBoundary
332 // fill sampleSegments
333 for(label i = samplingPts.size() - 1; i >= startSegmentI; --i)
335 samplingSegments.append(segmentI);
339 if (!reachedBoundary)
343 Info<< "calcSamples : Reached end of samples: "
344 << " samplePt now:" << samplePt
345 << " sampleI now:" << sampleI
352 bool foundValidB = false;
354 while (bHitI < bHits.size())
357 (bHits[bHitI].hitPoint() - singleParticle.position())
362 Info<< "Finding next boundary : "
363 << "bPoint:" << bHits[bHitI].hitPoint()
364 << " tracking:" << singleParticle.position()
369 if (dist > smallDist)
371 // hitpoint is past tracking position
383 // No valid boundary intersection found beyond tracking position
387 // Update starting point for tracking
389 trackPt = pushIn(bPoint, trackFaceI);
390 trackCellI = getBoundaryCell(trackFaceI);
394 startSegmentI = samplingPts.size();
399 void Foam::uniformSet::genSamples()
401 // Storage for sample points
402 DynamicList<point> samplingPts;
403 DynamicList<label> samplingCells;
404 DynamicList<label> samplingFaces;
405 DynamicList<label> samplingSegments;
406 DynamicList<scalar> samplingCurveDist;
417 samplingPts.shrink();
418 samplingCells.shrink();
419 samplingFaces.shrink();
420 samplingSegments.shrink();
421 samplingCurveDist.shrink();
433 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
435 Foam::uniformSet::uniformSet
438 const polyMesh& mesh,
439 meshSearch& searchEngine,
446 sampledSet(name, mesh, searchEngine, axis),
460 Foam::uniformSet::uniformSet
463 const polyMesh& mesh,
464 meshSearch& searchEngine,
465 const dictionary& dict
468 sampledSet(name, mesh, searchEngine, dict),
469 start_(dict.lookup("start")),
470 end_(dict.lookup("end")),
471 nPoints_(readLabel(dict.lookup("nPoints")))
482 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
484 Foam::uniformSet::~uniformSet()
488 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
491 Foam::point Foam::uniformSet::getRefPoint(const List<point>& pts) const
493 // Use start point as reference for 'distance'
498 // ************************************************************************* //