polyLineSet.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------* \
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "polyLineSet.H"
29 #include "meshSearch.H"
30 #include "DynamicList.H"
31 #include "polyMesh.H"
32 
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39  defineTypeNameAndDebug(polyLineSet, 0);
40  addToRunTimeSelectionTable(sampledSet, polyLineSet, word);
41 }
42 
43 const Foam::scalar Foam::polyLineSet::tol = 1e-6;
44 
45 
46 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
47 
48 bool Foam::polyLineSet::trackToBoundary
49 (
50  passiveParticleCloud& particleCloud,
51  passiveParticle& singleParticle,
52  label& sampleI,
53  DynamicList<point>& samplingPts,
54  DynamicList<label>& samplingCells,
55  DynamicList<label>& samplingFaces,
56  DynamicList<scalar>& samplingCurveDist
57 ) const
58 {
59  while (true)
60  {
61  // Local geometry info
62  const vector offset = sampleCoords_[sampleI+1] - sampleCoords_[sampleI];
63  const scalar smallDist = mag(tol*offset);
64 
65  singleParticle.track(offset, 0);
66  const point trackPt = singleParticle.position();
67 
68  if (singleParticle.onBoundaryFace())
69  {
70  //Info<< "trackToBoundary : reached boundary"
71  // << " trackPt:" << trackPt << endl;
72  if
73  (
74  mag(trackPt - sampleCoords_[sampleI+1])
75  < smallDist
76  )
77  {
78  // Reached samplePt on boundary
79  //Info<< "trackToBoundary : boundary. also sampling."
80  // << " trackPt:" << trackPt << " sampleI+1:" << sampleI+1
81  // << endl;
82  samplingPts.append(trackPt);
83  samplingCells.append(singleParticle.cell());
84  samplingFaces.append(singleParticle.face());
85 
86  // trackPt is at sampleI+1
87  samplingCurveDist.append(1.0*(sampleI+1));
88  }
89  return true;
90  }
91 
92  // Reached samplePt in cell
93  samplingPts.append(trackPt);
94  samplingCells.append(singleParticle.cell());
95  samplingFaces.append(-1);
96 
97  // Convert trackPt to fraction inbetween sampleI and sampleI+1
98  scalar dist =
99  mag(trackPt - sampleCoords_[sampleI])
100  / mag(sampleCoords_[sampleI+1] - sampleCoords_[sampleI]);
101  samplingCurveDist.append(sampleI + dist);
102 
103  // go to next samplePt
104  ++sampleI;
105 
106  if (sampleI == sampleCoords_.size() - 1)
107  {
108  // no more samples.
109  //Info<< "trackToBoundary : Reached end : sampleI now:" << sampleI
110  // << endl;
111  return false;
112  }
113  }
114 }
115 
116 
117 void Foam::polyLineSet::calcSamples
118 (
119  DynamicList<point>& samplingPts,
120  DynamicList<label>& samplingCells,
121  DynamicList<label>& samplingFaces,
122  DynamicList<label>& samplingSegments,
123  DynamicList<scalar>& samplingCurveDist
124 ) const
125 {
126  // Check sampling points
127  if (sampleCoords_.size() < 2)
128  {
130  << "Incorrect sample specification. Too few points:"
131  << sampleCoords_ << exit(FatalError);
132  }
133  point oldPoint = sampleCoords_[0];
134  for (label sampleI = 1; sampleI < sampleCoords_.size(); ++sampleI)
135  {
136  if (mag(sampleCoords_[sampleI] - oldPoint) < SMALL)
137  {
139  << "Incorrect sample specification."
140  << " Point " << sampleCoords_[sampleI-1]
141  << " at position " << sampleI-1
142  << " and point " << sampleCoords_[sampleI]
143  << " at position " << sampleI
144  << " are too close" << exit(FatalError);
145  }
146  oldPoint = sampleCoords_[sampleI];
147  }
148 
149  // Force calculation of cloud addressing on all processors
150  const bool oldMoving = const_cast<polyMesh&>(mesh()).moving(false);
151  passiveParticleCloud particleCloud(mesh());
152 
153  // current segment number
154  label segmentI = 0;
155 
156  // starting index of current segment in samplePts
157  label startSegmentI = 0;
158 
159  label sampleI = 0;
160 
161  point lastSample(GREAT, GREAT, GREAT);
162  while (true)
163  {
164  // Get boundary intersection
165  point trackPt;
166  label trackCelli = -1;
167  label trackFacei = -1;
168 
169  do
170  {
171  const vector offset =
172  sampleCoords_[sampleI+1] - sampleCoords_[sampleI];
173  const scalar smallDist = mag(tol*offset);
174 
175 
176  // Get all boundary intersections
177  List<pointIndexHit> bHits = searchEngine().intersections
178  (
179  sampleCoords_[sampleI],
180  sampleCoords_[sampleI+1]
181  );
182 
183  point bPoint(GREAT, GREAT, GREAT);
184  label bFacei = -1;
185 
186  if (bHits.size())
187  {
188  bPoint = bHits[0].hitPoint();
189  bFacei = bHits[0].index();
190  }
191 
192  // Get tracking point
193 
194  bool isSample =
195  getTrackingPoint
196  (
197  sampleCoords_[sampleI],
198  bPoint,
199  bFacei,
200  smallDist,
201 
202  trackPt,
203  trackCelli,
204  trackFacei
205  );
206 
207  if (isSample && (mag(lastSample - trackPt) > smallDist))
208  {
209  //Info<< "calcSamples : getTrackingPoint returned valid sample "
210  // << " trackPt:" << trackPt
211  // << " trackFacei:" << trackFacei
212  // << " trackCelli:" << trackCelli
213  // << " sampleI:" << sampleI
214  // << " dist:" << dist
215  // << endl;
216 
217  samplingPts.append(trackPt);
218  samplingCells.append(trackCelli);
219  samplingFaces.append(trackFacei);
220 
221  // Convert sampling position to unique curve parameter. Get
222  // fraction of distance between sampleI and sampleI+1.
223  scalar dist =
224  mag(trackPt - sampleCoords_[sampleI])
225  / mag(sampleCoords_[sampleI+1] - sampleCoords_[sampleI]);
226  samplingCurveDist.append(sampleI + dist);
227 
228  lastSample = trackPt;
229  }
230 
231  if (trackCelli == -1)
232  {
233  // No intersection found. Go to next point
234  ++sampleI;
235  }
236  } while ((trackCelli == -1) && (sampleI < sampleCoords_.size() - 1));
237 
238  if (sampleI == sampleCoords_.size() - 1)
239  {
240  //Info<< "calcSamples : Reached end of samples: "
241  // << " sampleI now:" << sampleI
242  // << endl;
243  break;
244  }
245 
246  //
247  // Segment sampleI .. sampleI+1 intersected by domain
248  //
249 
250  // Initialize tracking starting from sampleI
251  passiveParticle singleParticle
252  (
253  mesh(),
254  trackPt,
255  trackCelli
256  );
257 
258  bool bReached = trackToBoundary
259  (
260  particleCloud,
261  singleParticle,
262  sampleI,
263  samplingPts,
264  samplingCells,
265  samplingFaces,
266  samplingCurveDist
267  );
268 
269  // fill sampleSegments
270  for (label i = samplingPts.size() - 1; i >= startSegmentI; --i)
271  {
272  samplingSegments.append(segmentI);
273  }
274 
275  if (!bReached)
276  {
277  //Info<< "calcSamples : Reached end of samples: "
278  // << " sampleI now:" << sampleI
279  // << endl;
280  break;
281  }
282  lastSample = singleParticle.position();
283 
284 
285  // Find next boundary.
286  ++sampleI;
287 
288  if (sampleI == sampleCoords_.size() - 1)
289  {
290  //Info<< "calcSamples : Reached end of samples: "
291  // << " sampleI now:" << sampleI
292  // << endl;
293  break;
294  }
295 
296  ++segmentI;
297 
298  startSegmentI = samplingPts.size();
299  }
300 
301  const_cast<polyMesh&>(mesh()).moving(oldMoving);
302 }
303 
304 
305 void Foam::polyLineSet::genSamples()
306 {
307  // Storage for sample points
308  DynamicList<point> samplingPts;
309  DynamicList<label> samplingCells;
310  DynamicList<label> samplingFaces;
311  DynamicList<label> samplingSegments;
312  DynamicList<scalar> samplingCurveDist;
313 
314  calcSamples
315  (
316  samplingPts,
317  samplingCells,
318  samplingFaces,
319  samplingSegments,
320  samplingCurveDist
321  );
322 
323  samplingPts.shrink();
324  samplingCells.shrink();
325  samplingFaces.shrink();
326  samplingSegments.shrink();
327  samplingCurveDist.shrink();
328 
329  // Move into *this
330  setSamples
331  (
332  std::move(samplingPts),
333  std::move(samplingCells),
334  std::move(samplingFaces),
335  std::move(samplingSegments),
336  std::move(samplingCurveDist)
337  );
338 
339  if (debug)
340  {
341  write(Info);
342  }
343 }
344 
345 
346 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
347 
349 (
350  const word& name,
351  const polyMesh& mesh,
352  const meshSearch& searchEngine,
353  const word& axis,
354  const List<point>& sampleCoords
355 )
356 :
357  sampledSet(name, mesh, searchEngine, axis),
358  sampleCoords_(sampleCoords)
359 {
360  genSamples();
361 }
362 
363 
365 (
366  const word& name,
367  const polyMesh& mesh,
368  const meshSearch& searchEngine,
369  const dictionary& dict
370 )
371 :
372  sampledSet(name, mesh, searchEngine, dict),
373  sampleCoords_(dict.get<pointField>("points"))
374 {
375  genSamples();
376 }
377 
378 
379 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::sampledSet
Holds list of sampling points which is filled at construction time. Various implementations of this b...
Definition: sampledSet.H:83
Foam::polyLineSet::tol
static const scalar tol
Definition: polyLineSet.H:131
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::meshSearch
Various (local, not parallel) searches on polyMesh; uses (demand driven) octree to search.
Definition: meshSearch.H:60
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
polyMesh.H
Foam::meshSearch::intersections
List< pointIndexHit > intersections(const point &pStart, const point &pEnd) const
Find all intersections of boundary within segment pStart .. pEnd.
Definition: meshSearch.C:887
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::Field< vector >
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
polyLineSet.H
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::polyLineSet::polyLineSet
polyLineSet(const word &name, const polyMesh &mesh, const meshSearch &searchEngine, const word &axis, const List< point > &samplePoints)
Construct from components.
Definition: polyLineSet.C:349
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
meshSearch.H
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:36
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
DynamicList.H
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)