1 /*---------------------------------------------------------------------------* \
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2011 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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "polyLineSet.H"
27 #include "meshSearch.H"
28 #include "DynamicList.H"
31 #include "addToRunTimeSelectionTable.H"
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 defineTypeNameAndDebug(polyLineSet, 0);
38 addToRunTimeSelectionTable(sampledSet, polyLineSet, word);
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
44 bool Foam::polyLineSet::trackToBoundary
46 passiveParticle& singleParticle,
48 DynamicList<point>& samplingPts,
49 DynamicList<label>& samplingCells,
50 DynamicList<label>& samplingFaces,
51 DynamicList<scalar>& samplingCurveDist
54 passiveParticleCloud particleCloud(mesh());
55 particle::TrackingData<passiveParticleCloud> trackData(particleCloud);
58 const point& trackPt = singleParticle.position();
62 // Local geometry info
63 const vector offset = sampleCoords_[sampleI+1] - sampleCoords_[sampleI];
64 const scalar smallDist = mag(tol*offset);
66 point oldPos = trackPt;
70 singleParticle.stepFraction() = 0;
71 singleParticle.track(sampleCoords_[sampleI+1], trackData);
75 !singleParticle.onBoundary()
76 && (mag(trackPt - oldPos) < smallDist)
79 if (singleParticle.onBoundary())
81 //Info<< "trackToBoundary : reached boundary"
82 // << " trackPt:" << trackPt << endl;
85 mag(trackPt - sampleCoords_[sampleI+1])
89 // Reached samplePt on boundary
90 //Info<< "trackToBoundary : boundary. also sampling."
91 // << " trackPt:" << trackPt << " sampleI+1:" << sampleI+1
93 samplingPts.append(trackPt);
94 samplingCells.append(singleParticle.cell());
95 samplingFaces.append(facei);
97 // trackPt is at sampleI+1
98 samplingCurveDist.append(1.0*(sampleI+1));
103 // Reached samplePt in cell
104 samplingPts.append(trackPt);
105 samplingCells.append(singleParticle.cell());
106 samplingFaces.append(-1);
108 // Convert trackPt to fraction inbetween sampleI and sampleI+1
110 mag(trackPt - sampleCoords_[sampleI])
111 / mag(sampleCoords_[sampleI+1] - sampleCoords_[sampleI]);
112 samplingCurveDist.append(sampleI + dist);
114 // go to next samplePt
117 if (sampleI == sampleCoords_.size() - 1)
120 //Info<< "trackToBoundary : Reached end : sampleI now:" << sampleI
128 void Foam::polyLineSet::calcSamples
130 DynamicList<point>& samplingPts,
131 DynamicList<label>& samplingCells,
132 DynamicList<label>& samplingFaces,
133 DynamicList<label>& samplingSegments,
134 DynamicList<scalar>& samplingCurveDist
137 // Check sampling points
138 if (sampleCoords_.size() < 2)
140 FatalErrorIn("polyLineSet::calcSamples()")
141 << "Incorrect sample specification. Too few points:"
142 << sampleCoords_ << exit(FatalError);
144 point oldPoint = sampleCoords_[0];
145 for (label sampleI = 1; sampleI < sampleCoords_.size(); sampleI++)
147 if (mag(sampleCoords_[sampleI] - oldPoint) < SMALL)
149 FatalErrorIn("polyLineSet::calcSamples()")
150 << "Incorrect sample specification."
151 << " Point " << sampleCoords_[sampleI-1]
152 << " at position " << sampleI-1
153 << " and point " << sampleCoords_[sampleI]
154 << " at position " << sampleI
155 << " are too close" << exit(FatalError);
157 oldPoint = sampleCoords_[sampleI];
160 // Force calculation of minimum-tet decomposition.
161 (void) mesh().tetBasePtIs();
163 // current segment number
166 // starting index of current segment in samplePts
167 label startSegmentI = 0;
171 point lastSample(GREAT, GREAT, GREAT);
174 // Get boundary intersection
176 label trackCellI = -1;
177 label trackFaceI = -1;
181 const vector offset =
182 sampleCoords_[sampleI+1] - sampleCoords_[sampleI];
183 const scalar smallDist = mag(tol*offset);
186 // Get all boundary intersections
187 List<pointIndexHit> bHits = searchEngine().intersections
189 sampleCoords_[sampleI],
190 sampleCoords_[sampleI+1]
193 point bPoint(GREAT, GREAT, GREAT);
198 bPoint = bHits[0].hitPoint();
199 bFaceI = bHits[0].index();
202 // Get tracking point
207 sampleCoords_[sampleI+1] - sampleCoords_[sampleI],
208 sampleCoords_[sampleI],
217 if (isSample && (mag(lastSample - trackPt) > smallDist))
219 //Info<< "calcSamples : getTrackingPoint returned valid sample "
220 // << " trackPt:" << trackPt
221 // << " trackFaceI:" << trackFaceI
222 // << " trackCellI:" << trackCellI
223 // << " sampleI:" << sampleI
224 // << " dist:" << dist
227 samplingPts.append(trackPt);
228 samplingCells.append(trackCellI);
229 samplingFaces.append(trackFaceI);
231 // Convert sampling position to unique curve parameter. Get
232 // fraction of distance between sampleI and sampleI+1.
234 mag(trackPt - sampleCoords_[sampleI])
235 / mag(sampleCoords_[sampleI+1] - sampleCoords_[sampleI]);
236 samplingCurveDist.append(sampleI + dist);
238 lastSample = trackPt;
241 if (trackCellI == -1)
243 // No intersection found. Go to next point
246 } while ((trackCellI == -1) && (sampleI < sampleCoords_.size() - 1));
248 if (sampleI == sampleCoords_.size() - 1)
250 //Info<< "calcSamples : Reached end of samples: "
251 // << " sampleI now:" << sampleI
257 // Segment sampleI .. sampleI+1 intersected by domain
260 // Initialize tracking starting from sampleI
261 passiveParticle singleParticle
268 bool bReached = trackToBoundary
278 // fill sampleSegments
279 for (label i = samplingPts.size() - 1; i >= startSegmentI; --i)
281 samplingSegments.append(segmentI);
286 //Info<< "calcSamples : Reached end of samples: "
287 // << " sampleI now:" << sampleI
291 lastSample = singleParticle.position();
294 // Find next boundary.
297 if (sampleI == sampleCoords_.size() - 1)
299 //Info<< "calcSamples : Reached end of samples: "
300 // << " sampleI now:" << sampleI
307 startSegmentI = samplingPts.size();
312 void Foam::polyLineSet::genSamples()
314 // Storage for sample points
315 DynamicList<point> samplingPts;
316 DynamicList<label> samplingCells;
317 DynamicList<label> samplingFaces;
318 DynamicList<label> samplingSegments;
319 DynamicList<scalar> samplingCurveDist;
330 samplingPts.shrink();
331 samplingCells.shrink();
332 samplingFaces.shrink();
333 samplingSegments.shrink();
334 samplingCurveDist.shrink();
347 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
349 Foam::polyLineSet::polyLineSet
352 const polyMesh& mesh,
353 meshSearch& searchEngine,
355 const List<point>& sampleCoords
358 sampledSet(name, mesh, searchEngine, axis),
359 sampleCoords_(sampleCoords)
370 Foam::polyLineSet::polyLineSet
373 const polyMesh& mesh,
374 meshSearch& searchEngine,
375 const dictionary& dict
378 sampledSet(name, mesh, searchEngine, dict),
379 sampleCoords_(dict.lookup("points"))
390 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
392 Foam::polyLineSet::~polyLineSet()
396 // ************************************************************************* //