sampledSet.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 | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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
19  for more details.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "sampledSet.H"
27 #include "polyMesh.H"
28 #include "primitiveMesh.H"
29 #include "meshSearch.H"
30 #include "writer.H"
31 #include "particle.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  const scalar sampledSet::tol = 1e-6;
38 
39  defineTypeNameAndDebug(sampledSet, 0);
40  defineRunTimeSelectionTable(sampledSet, word);
41 }
42 
43 
44 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
45 
47 {
48  return mesh().faceOwner()[faceI];
49 }
50 
51 
53 (
54  const label faceI,
55  const point& sample
56 ) const
57 {
58  if (faceI == -1)
59  {
61  << "Illegal face label " << faceI
62  << abort(FatalError);
63  }
64 
65  if (faceI >= mesh().nInternalFaces())
66  {
67  label cellI = getBoundaryCell(faceI);
68 
69  if (!mesh().pointInCell(sample, cellI, searchEngine_.decompMode()))
70  {
72  << "Found cell " << cellI << " using face " << faceI
73  << ". But cell does not contain point " << sample
74  << abort(FatalError);
75  }
76  return cellI;
77  }
78  else
79  {
80  // Try owner and neighbour to see which one contains sample
81 
82  label cellI = mesh().faceOwner()[faceI];
83 
84  if (mesh().pointInCell(sample, cellI, searchEngine_.decompMode()))
85  {
86  return cellI;
87  }
88  else
89  {
90  cellI = mesh().faceNeighbour()[faceI];
91 
92  if (mesh().pointInCell(sample, cellI, searchEngine_.decompMode()))
93  {
94  return cellI;
95  }
96  else
97  {
99  << "None of the neighbours of face "
100  << faceI << " contains point " << sample
101  << abort(FatalError);
102 
103  return -1;
104  }
105  }
106  }
107 }
108 
109 
110 Foam::scalar Foam::sampledSet::calcSign
111 (
112  const label faceI,
113  const point& sample
114 ) const
115 {
116  vector vec = sample - mesh().faceCentres()[faceI];
117 
118  scalar magVec = mag(vec);
119 
120  if (magVec < VSMALL)
121  {
122  // sample on face centre. Regard as inside
123  return -1;
124  }
125 
126  vec /= magVec;
127 
128  vector n = mesh().faceAreas()[faceI];
129 
130  n /= mag(n) + VSMALL;
131 
132  return n & vec;
133 }
134 
135 
136 // Return face (or -1) of face which is within smallDist of sample
138 (
139  const label cellI,
140  const point& sample,
141  const scalar smallDist
142 ) const
143 {
144  const cell& myFaces = mesh().cells()[cellI];
145 
146  forAll(myFaces, myFaceI)
147  {
148  const face& f = mesh().faces()[myFaces[myFaceI]];
149 
150  pointHit inter = f.nearestPoint(sample, mesh().points());
151 
152  scalar dist;
153 
154  if (inter.hit())
155  {
156  dist = mag(inter.hitPoint() - sample);
157  }
158  else
159  {
160  dist = mag(inter.missPoint() - sample);
161  }
162 
163  if (dist < smallDist)
164  {
165  return myFaces[myFaceI];
166  }
167  }
168  return -1;
169 }
170 
171 
172 // 'Pushes' point facePt (which is almost on face) in direction of cell centre
173 // so it is clearly inside.
175 (
176  const point& facePt,
177  const label faceI
178 ) const
179 {
180  label cellI = mesh().faceOwner()[faceI];
181  const point& cC = mesh().cellCentres()[cellI];
182 
183  point newPosition = facePt;
184 
185  // Taken from particle::initCellFacePt()
186  label tetFaceI;
187  label tetPtI;
188  mesh().findTetFacePt(cellI, facePt, tetFaceI, tetPtI);
189 
190  if (tetFaceI == -1 || tetPtI == -1)
191  {
192  newPosition = facePt;
193 
195 
196  label iterNo = 0;
197 
198  do
199  {
200  newPosition += particle::trackingCorrectionTol*(cC - facePt);
201 
203  (
204  cellI,
205  newPosition,
206  tetFaceI,
207  tetPtI
208  );
209 
210  iterNo++;
211 
212  } while (tetFaceI < 0 && iterNo <= trap);
213  }
214 
215  if (tetFaceI == -1)
216  {
218  << "After pushing " << facePt << " to " << newPosition
219  << " it is still outside face " << faceI
220  << " at " << mesh().faceCentres()[faceI]
221  << " of cell " << cellI
222  << " at " << cC << endl
223  << "Please change your starting point"
224  << abort(FatalError);
225  }
226 
227  //Info<< "pushIn : moved " << facePt << " to " << newPosition
228  // << endl;
229 
230  return newPosition;
231 }
232 
233 
234 // Calculates start of tracking given samplePt and first boundary intersection
235 // (bPoint, bFaceI). bFaceI == -1 if no boundary intersection.
236 // Returns true if trackPt is sampling point
238 (
239  const vector& offset,
240  const point& samplePt,
241  const point& bPoint,
242  const label bFaceI,
243 
244  point& trackPt,
245  label& trackCellI,
246  label& trackFaceI
247 ) const
248 {
249  const scalar smallDist = mag(tol*offset);
250 
251  bool isGoodSample = false;
252 
253  if (bFaceI == -1)
254  {
255  // No boundary intersection. Try and find cell samplePt is in
256  trackCellI = mesh().findCell(samplePt, searchEngine_.decompMode());
257 
258  if
259  (
260  (trackCellI == -1)
261  || !mesh().pointInCell
262  (
263  samplePt,
264  trackCellI,
265  searchEngine_.decompMode()
266  )
267  )
268  {
269  // Line samplePt - end_ does not intersect domain at all.
270  // (or is along edge)
271  //Info<< "getTrackingPoint : samplePt outside domain : "
272  // << " samplePt:" << samplePt
273  // << endl;
274 
275  trackCellI = -1;
276  trackFaceI = -1;
277 
278  isGoodSample = false;
279  }
280  else
281  {
282  // start is inside. Use it as tracking point
283  //Info<< "getTrackingPoint : samplePt inside :"
284  // << " samplePt:" << samplePt
285  // << " trackCellI:" << trackCellI
286  // << endl;
287 
288  trackPt = samplePt;
289  trackFaceI = -1;
290 
291  isGoodSample = true;
292  }
293  }
294  else if (mag(samplePt - bPoint) < smallDist)
295  {
296  //Info<< "getTrackingPoint : samplePt:" << samplePt
297  // << " close to bPoint:"
298  // << bPoint << endl;
299 
300  // samplePt close to bPoint. Snap to it
301  trackPt = pushIn(bPoint, bFaceI);
302  trackFaceI = bFaceI;
303  trackCellI = getBoundaryCell(trackFaceI);
304 
305  isGoodSample = true;
306  }
307  else
308  {
309  scalar sign = calcSign(bFaceI, samplePt);
310 
311  if (sign < 0)
312  {
313  // samplePt inside or marginally outside.
314  trackPt = samplePt;
315  trackFaceI = -1;
316  trackCellI = mesh().findCell(trackPt, searchEngine_.decompMode());
317 
318  isGoodSample = true;
319  }
320  else
321  {
322  // samplePt outside. use bPoint
323  trackPt = pushIn(bPoint, bFaceI);
324  trackFaceI = bFaceI;
325  trackCellI = getBoundaryCell(trackFaceI);
326 
327  isGoodSample = false;
328  }
329  }
330 
331  if (debug)
332  {
333  Info<< "sampledSet::getTrackingPoint :"
334  << " offset:" << offset
335  << " samplePt:" << samplePt
336  << " bPoint:" << bPoint
337  << " bFaceI:" << bFaceI
338  << endl << " Calculated first tracking point :"
339  << " trackPt:" << trackPt
340  << " trackCellI:" << trackCellI
341  << " trackFaceI:" << trackFaceI
342  << " isGoodSample:" << isGoodSample
343  << endl;
344  }
345 
346  return isGoodSample;
347 }
348 
349 
351 (
352  const List<point>& samplingPts,
353  const labelList& samplingCells,
354  const labelList& samplingFaces,
355  const labelList& samplingSegments,
356  const scalarList& samplingCurveDist
357 )
358 {
359  setSize(samplingPts.size());
360  cells_.setSize(samplingCells.size());
361  faces_.setSize(samplingFaces.size());
362  segments_.setSize(samplingSegments.size());
363  curveDist_.setSize(samplingCurveDist.size());
364 
365  if
366  (
367  (cells_.size() != size())
368  || (faces_.size() != size())
369  || (segments_.size() != size())
370  || (curveDist_.size() != size())
371  )
372  {
374  << "sizes not equal : "
375  << " points:" << size()
376  << " cells:" << cells_.size()
377  << " faces:" << faces_.size()
378  << " segments:" << segments_.size()
379  << " curveDist:" << curveDist_.size()
380  << abort(FatalError);
381  }
382 
383  forAll(samplingPts, sampleI)
384  {
385  operator[](sampleI) = samplingPts[sampleI];
386  }
387  curveDist_ = samplingCurveDist;
388 
389  cells_ = samplingCells;
390  faces_ = samplingFaces;
391  segments_ = samplingSegments;
392 }
393 
394 
395 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
396 
398 (
399  const word& name,
400  const polyMesh& mesh,
401  const meshSearch& searchEngine,
402  const word& axis
403 )
404 :
405  coordSet(name, axis),
406  mesh_(mesh),
407  searchEngine_(searchEngine),
408  segments_(0),
409  cells_(0),
410  faces_(0)
411 {}
412 
413 
415 (
416  const word& name,
417  const polyMesh& mesh,
418  const meshSearch& searchEngine,
419  const dictionary& dict
420 )
421 :
422  coordSet(name, dict.lookup("axis")),
423  mesh_(mesh),
424  searchEngine_(searchEngine),
425  segments_(0),
426  cells_(0),
427  faces_(0)
428 {}
429 
430 
431 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
432 
434 {}
435 
436 
437 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
438 
440 (
441  const word& name,
442  const polyMesh& mesh,
443  const meshSearch& searchEngine,
444  const dictionary& dict
445 )
446 {
447  const word sampleType(dict.lookup("type"));
448 
449  wordConstructorTable::iterator cstrIter =
450  wordConstructorTablePtr_->find(sampleType);
451 
452  if (cstrIter == wordConstructorTablePtr_->end())
453  {
455  << "Unknown sample type "
456  << sampleType << nl << nl
457  << "Valid sample types : " << endl
458  << wordConstructorTablePtr_->sortedToc()
459  << exit(FatalError);
460  }
461 
462  return autoPtr<sampledSet>
463  (
464  cstrIter()
465  (
466  name,
467  mesh,
468  searchEngine,
469  dict
470  )
471  );
472 }
473 
474 
476 {
477  coordSet::write(os);
478 
479  os << endl << "\t(cellI)\t(faceI)" << endl;
480 
481  forAll(*this, sampleI)
482  {
483  os << '\t' << cells_[sampleI]
484  << '\t' << faces_[sampleI]
485  << endl;
486  }
487 
488  return os;
489 }
490 
491 
492 // ************************************************************************* //
Foam::sampledSet::New
static autoPtr< sampledSet > New(const word &name, const polyMesh &mesh, const meshSearch &searchEngine, const dictionary &dict)
Return a reference to the selected sampledSet.
Definition: sampledSet.C:440
setSize
points setSize(newPointi)
Foam::sampledSet::write
Ostream & write(Ostream &) const
Output for debugging.
Definition: sampledSet.C:475
Foam::PointHit::hit
bool hit() const
Is there a hit.
Definition: PointHit.H:120
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::sampledSet::getCell
label getCell(const label faceI, const point &sample) const
Returns cell using face and containing sample.
Definition: sampledSet.C:53
Foam::meshSearch
Various (local, not parallel) searches on polyMesh; uses (demand driven) octree to search.
Definition: meshSearch.H:57
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::PointHit
This class describes the interaction of a face and a point. It carries the info of a successful hit a...
Definition: PointHit.H:51
Foam::defineRunTimeSelectionTable
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
Foam::dictionary::lookup
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:449
Foam::primitiveMesh::cells
const cellList & cells() const
Definition: primitiveMeshCells.C:136
Foam::sampledSet::pushIn
point pushIn(const point &sample, const label faceI) const
Moves sample in direction of -n to it is 'inside' of faceI.
Definition: sampledSet.C:175
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::sampledSet::~sampledSet
virtual ~sampledSet()
Destructor.
Definition: sampledSet.C:433
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::sign
dimensionedScalar sign(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:179
polyMesh.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
n
label n
Definition: TABSMDCalcMethod2.H:31
sampledSet.H
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::sampledSet::sampledSet
sampledSet(const word &name, const polyMesh &mesh, const meshSearch &searchEngine, const word &axis)
Construct from components.
Definition: sampledSet.C:398
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1017
Foam::sampledSet::getTrackingPoint
bool getTrackingPoint(const vector &offset, const point &samplePt, const point &bPoint, const label bFaceI, point &trackPt, label &trackCellI, label &trackFaceI) const
Calculates start of tracking given samplePt and first boundary.
Definition: sampledSet.C:238
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
Foam::coordSet
Holds list of sampling positions.
Definition: coordSet.H:49
Foam::particle::trackingCorrectionTol
static const scalar trackingCorrectionTol
Fraction of distance to tet centre to move a particle to.
Definition: particle.H:322
Foam::sampledSet::findNearFace
label findNearFace(const label cellI, const point &sample, const scalar smallDist) const
Returns face label (or -1) of face which is close to sample.
Definition: sampledSet.C:138
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::sampledSet::getBoundaryCell
label getBoundaryCell(const label) const
Returns cell next to boundary face.
Definition: sampledSet.C:46
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::sampledSet::calcSign
scalar calcSign(const label faceI, const point &sample) const
Calculates inproduct of face normal and vector sample-face centre.
Definition: sampledSet.C:111
Foam::autoPtr< Foam::sampledSet >
Foam::polyMesh::findCell
label findCell(const point &p, const cellDecomposition=CELL_TETS) const
Find cell enclosing this location and return index.
Definition: polyMesh.C:1411
Foam::primitiveMesh::cellCentres
const vectorField & cellCentres() const
Definition: primitiveMeshCellCentresAndVols.C:211
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1004
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::sampledSet::mesh
const polyMesh & mesh() const
Definition: sampledSet.H:248
meshSearch.H
Foam::sampledSet::setSamples
void setSamples(const List< point > &samplingPts, const labelList &samplingCells, const labelList &samplingFaces, const labelList &samplingSegments, const scalarList &samplingCurveDist)
Sets sample data.
Definition: sampledSet.C:351
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::coordSet::write
Ostream & write(Ostream &os) const
Definition: coordSet.C:136
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::primitiveMesh::faceCentres
const vectorField & faceCentres() const
Definition: primitiveMeshFaceCentresAndAreas.C:130
points
const pointField & points
Definition: gmvOutputHeader.H:1
particle.H
Foam::sampledSet::tol
static const scalar tol
Tolerance when comparing points. Usually relative to difference.
Definition: sampledSet.H:199
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:53
Foam::PointHit::missPoint
const Point & missPoint() const
Return miss point.
Definition: PointHit.H:145
writer.H
Foam::polyMesh::findTetFacePt
void findTetFacePt(const label celli, const point &p, label &tetFacei, label &tetPti) const
Find the tetFacei and tetPti for point p in celli.
Definition: polyMesh.C:1276
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::cell
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:56
Foam::PointHit::hitPoint
const Point & hitPoint() const
Return hit point.
Definition: PointHit.H:126
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Foam::polyMesh::faceNeighbour
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1023
Foam::primitiveMesh::faceAreas
const vectorField & faceAreas() const
Definition: primitiveMeshFaceCentresAndAreas.C:141