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-2017 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  defineTypeNameAndDebug(sampledSet, 0);
38  defineRunTimeSelectionTable(sampledSet, word);
39 }
40 
41 
42 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
43 
45 {
46  return mesh().faceOwner()[facei];
47 }
48 
49 
51 {
52  if (facei >= mesh().nInternalFaces())
53  {
54  return mesh().faceOwner()[facei];
55  }
56  else
57  {
58  return mesh().faceNeighbour()[facei];
59  }
60 }
61 
62 
64 (
65  const point& p,
66  const label samplei
67 ) const
68 {
69  // Collect the face owner and neighbour cells of the sample into an array
70  // for convenience
71  label cells[4] =
72  {
73  mesh().faceOwner()[faces_[samplei]],
74  getNeighbourCell(faces_[samplei]),
75  mesh().faceOwner()[faces_[samplei+1]],
76  getNeighbourCell(faces_[samplei+1])
77  };
78 
79  // Find the sampled cell by checking the owners and neighbours of the
80  // sampled faces
81  label cellm =
82  (cells[0] == cells[2] || cells[0] == cells[3]) ? cells[0]
83  : (cells[1] == cells[2] || cells[1] == cells[3]) ? cells[1]
84  : -1;
85 
86  if (cellm != -1)
87  {
88  // If found the sampled cell check the point is in the cell
89  // otherwise ignore
90  if (!mesh().pointInCell(p, cellm, searchEngine_.decompMode()))
91  {
92  cellm = -1;
93 
94  if (debug)
95  {
97  << "Could not find mid-point " << p
98  << " cell " << cellm << endl;
99  }
100  }
101  }
102  else
103  {
104  // If the sample does not pass through a single cell check if the point
105  // is in any of the owners or neighbours otherwise ignore
106  for (label i=0; i<4; i++)
107  {
108  if (mesh().pointInCell(p, cells[i], searchEngine_.decompMode()))
109  {
110  return cells[i];
111  }
112  }
113 
114  if (debug)
115  {
117  << "Could not find cell for mid-point" << nl
118  << " samplei: " << samplei
119  << " pts[samplei]: " << operator[](samplei)
120  << " face[samplei]: " << faces_[samplei]
121  << " pts[samplei+1]: " << operator[](samplei+1)
122  << " face[samplei+1]: " << faces_[samplei+1]
123  << " cellio: " << cells[0]
124  << " cellin: " << cells[1]
125  << " celljo: " << cells[2]
126  << " celljn: " << cells[3]
127  << endl;
128  }
129  }
130 
131  return cellm;
132 }
133 
134 
135 Foam::scalar Foam::sampledSet::calcSign
136 (
137  const label facei,
138  const point& sample
139 ) const
140 {
141  vector vec = sample - mesh().faceCentres()[facei];
142 
143  scalar magVec = mag(vec);
144 
145  if (magVec < VSMALL)
146  {
147  // Sample on face centre. Regard as inside
148  return -1;
149  }
150 
151  vec /= magVec;
152 
153  vector n = mesh().faceAreas()[facei];
154 
155  n /= mag(n) + VSMALL;
156 
157  return n & vec;
158 }
159 
160 
162 (
163  const label celli,
164  const point& sample,
165  const scalar smallDist
166 ) const
167 {
168  const cell& myFaces = mesh().cells()[celli];
169 
170  forAll(myFaces, myFacei)
171  {
172  const face& f = mesh().faces()[myFaces[myFacei]];
173 
174  pointHit inter = f.nearestPoint(sample, mesh().points());
175 
176  scalar dist;
177 
178  if (inter.hit())
179  {
180  dist = mag(inter.hitPoint() - sample);
181  }
182  else
183  {
184  dist = mag(inter.missPoint() - sample);
185  }
186 
187  if (dist < smallDist)
188  {
189  return myFaces[myFacei];
190  }
191  }
192  return -1;
193 }
194 
195 
197 (
198  const point& facePt,
199  const label facei
200 ) const
201 {
202  label celli = mesh().faceOwner()[facei];
203  const point& cC = mesh().cellCentres()[celli];
204 
205  point newPosition = facePt;
206 
207  // Taken from particle::initCellFacePt()
208  label tetFacei;
209  label tetPtI;
210  mesh().findTetFacePt(celli, facePt, tetFacei, tetPtI);
211 
212  // This is the tolerance that was defined as a static constant of the
213  // particle class. It is no longer used by particle, following the switch to
214  // barycentric tracking. The only place in which the tolerance is now used
215  // is here. I'm not sure what the purpose of this code is, but it probably
216  // wants removing. It is doing tet-searches for a particle position. This
217  // should almost certainly be left to the particle class.
218  const scalar trackingCorrectionTol = 1e-5;
219 
220  if (tetFacei == -1 || tetPtI == -1)
221  {
222  newPosition = facePt;
223 
224  label trap(1.0/trackingCorrectionTol + 1);
225 
226  label iterNo = 0;
227 
228  do
229  {
230  newPosition += trackingCorrectionTol*(cC - facePt);
231 
233  (
234  celli,
235  newPosition,
236  tetFacei,
237  tetPtI
238  );
239 
240  iterNo++;
241 
242  } while (tetFacei < 0 && iterNo <= trap);
243  }
244 
245  if (tetFacei == -1)
246  {
248  << "After pushing " << facePt << " to " << newPosition
249  << " it is still outside face " << facei
250  << " at " << mesh().faceCentres()[facei]
251  << " of cell " << celli
252  << " at " << cC << endl
253  << "Please change your starting point"
254  << abort(FatalError);
255  }
256 
257  return newPosition;
258 }
259 
260 
262 (
263  const point& samplePt,
264  const point& bPoint,
265  const label bFacei,
266  const scalar smallDist,
267 
268  point& trackPt,
269  label& trackCelli,
270  label& trackFacei
271 ) const
272 {
273  bool isGoodSample = false;
274 
275  if (bFacei == -1)
276  {
277  // No boundary intersection. Try and find cell samplePt is in
278  trackCelli = mesh().findCell(samplePt, searchEngine_.decompMode());
279 
280  if
281  (
282  (trackCelli == -1)
283  || !mesh().pointInCell
284  (
285  samplePt,
286  trackCelli,
287  searchEngine_.decompMode()
288  )
289  )
290  {
291  // Line samplePt - end_ does not intersect domain at all.
292  // (or is along edge)
293 
294  trackCelli = -1;
295  trackFacei = -1;
296 
297  isGoodSample = false;
298  }
299  else
300  {
301  // Start is inside. Use it as tracking point
302 
303  trackPt = samplePt;
304  trackFacei = -1;
305 
306  isGoodSample = true;
307  }
308  }
309  else if (mag(samplePt - bPoint) < smallDist)
310  {
311  // samplePt close to bPoint. Snap to it
312  trackPt = pushIn(bPoint, bFacei);
313  trackFacei = bFacei;
314  trackCelli = getBoundaryCell(trackFacei);
315 
316  isGoodSample = true;
317  }
318  else
319  {
320  scalar sign = calcSign(bFacei, samplePt);
321 
322  if (sign < 0)
323  {
324  // samplePt inside or marginally outside.
325  trackPt = samplePt;
326  trackFacei = -1;
327  trackCelli = mesh().findCell(trackPt, searchEngine_.decompMode());
328 
329  isGoodSample = true;
330  }
331  else
332  {
333  // samplePt outside. use bPoint
334  trackPt = pushIn(bPoint, bFacei);
335  trackFacei = bFacei;
336  trackCelli = getBoundaryCell(trackFacei);
337 
338  isGoodSample = false;
339  }
340  }
341 
342  if (debug)
343  {
345  << " samplePt:" << samplePt
346  << " bPoint:" << bPoint
347  << " bFacei:" << bFacei
348  << endl << " Calculated first tracking point :"
349  << " trackPt:" << trackPt
350  << " trackCelli:" << trackCelli
351  << " trackFacei:" << trackFacei
352  << " isGoodSample:" << isGoodSample
353  << endl;
354  }
355 
356  return isGoodSample;
357 }
358 
359 
361 (
362  const List<point>& samplingPts,
363  const labelList& samplingCells,
364  const labelList& samplingFaces,
365  const labelList& samplingSegments,
366  const scalarList& samplingCurveDist
367 )
368 {
369  setSize(samplingPts.size());
370  cells_.setSize(samplingCells.size());
371  faces_.setSize(samplingFaces.size());
372  segments_.setSize(samplingSegments.size());
373  curveDist_.setSize(samplingCurveDist.size());
374 
375  if
376  (
377  (cells_.size() != size())
378  || (faces_.size() != size())
379  || (segments_.size() != size())
380  || (curveDist_.size() != size())
381  )
382  {
384  << "sizes not equal : "
385  << " points:" << size()
386  << " cells:" << cells_.size()
387  << " faces:" << faces_.size()
388  << " segments:" << segments_.size()
389  << " curveDist:" << curveDist_.size()
390  << abort(FatalError);
391  }
392 
393  forAll(samplingPts, sampleI)
394  {
395  operator[](sampleI) = samplingPts[sampleI];
396  }
397  curveDist_ = samplingCurveDist;
398 
399  cells_ = samplingCells;
400  faces_ = samplingFaces;
401  segments_ = samplingSegments;
402 }
403 
404 
405 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
406 
408 (
409  const word& name,
410  const polyMesh& mesh,
411  const meshSearch& searchEngine,
412  const word& axis
413 )
414 :
415  coordSet(name, axis),
416  mesh_(mesh),
417  searchEngine_(searchEngine),
418  segments_(0),
419  cells_(0),
420  faces_(0)
421 {}
422 
423 
425 (
426  const word& name,
427  const polyMesh& mesh,
428  const meshSearch& searchEngine,
429  const dictionary& dict
430 )
431 :
432  coordSet(name, dict.lookup("axis")),
433  mesh_(mesh),
434  searchEngine_(searchEngine),
435  segments_(0),
436  cells_(0),
437  faces_(0)
438 {}
439 
440 
441 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
442 
444 {}
445 
446 
447 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
448 
450 (
451  const word& name,
452  const polyMesh& mesh,
453  const meshSearch& searchEngine,
454  const dictionary& dict
455 )
456 {
457  const word sampleType(dict.lookup("type"));
458 
459  wordConstructorTable::iterator cstrIter =
460  wordConstructorTablePtr_->find(sampleType);
461 
462  if (cstrIter == wordConstructorTablePtr_->end())
463  {
465  << "Unknown sample type "
466  << sampleType << nl << nl
467  << "Valid sample types : " << endl
468  << wordConstructorTablePtr_->sortedToc()
469  << exit(FatalError);
470  }
471 
472  return autoPtr<sampledSet>
473  (
474  cstrIter()
475  (
476  name,
477  mesh,
478  searchEngine,
479  dict.optionalSubDict(sampleType + "Coeffs")
480  )
481  );
482 }
483 
484 
486 {
487  coordSet::write(os);
488 
489  os << endl << "\t(celli)\t(facei)" << endl;
490 
491  forAll(*this, sampleI)
492  {
493  os << '\t' << cells_[sampleI]
494  << '\t' << faces_[sampleI]
495  << endl;
496  }
497 
498  return os;
499 }
500 
501 
502 // ************************************************************************* //
dimensionedScalar sign(const dimensionedScalar &ds)
Various (local, not parallel) searches on polyMesh; uses (demand driven) octree to search...
Definition: meshSearch.H:57
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
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:162
const double e
Elementary charge.
Definition: doubleFloat.H:78
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
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:450
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1055
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:60
label getNeighbourCell(const label) const
Returns the neigbour cell or the owner if face in on the boundary.
Definition: sampledSet.C:50
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
virtual ~sampledSet()
Destructor.
Definition: sampledSet.C:443
const cellList & cells() const
bool pointInCell(const point &p, label celli, const cellDecomposition=CELL_TETS) const
Test if point p is in the celli.
Definition: polyMesh.C:1284
void setSamples(const List< point > &samplingPts, const labelList &samplingCells, const labelList &samplingFaces, const labelList &samplingSegments, const scalarList &samplingCurveDist)
Sets sample data.
Definition: sampledSet.C:361
const Point & missPoint() const
Return miss point.
Definition: PointHit.H:145
point pushIn(const point &sample, const label facei) const
Moves sample in direction of -n to it is &#39;inside&#39; of facei.
Definition: sampledSet.C:197
points setSize(newPointi)
Ostream & write(Ostream &) const
Output for debugging.
Definition: sampledSet.C:485
dynamicFvMesh & mesh
Holds list of sampling positions.
Definition: coordSet.H:49
const cellShapeList & cells
const pointField & points
const dictionary & optionalSubDict(const word &) const
Find and return a sub-dictionary if found.
Definition: dictionary.C:759
A class for handling words, derived from string.
Definition: word.H:59
Ostream & write(Ostream &os) const
Definition: coordSet.C:134
const Point & hitPoint() const
Return hit point.
Definition: PointHit.H:126
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1049
bool hit() const
Is there a hit.
Definition: PointHit.H:120
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1036
const vectorField & cellCentres() const
errorManip< error > abort(error &err)
Definition: errorManip.H:131
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
static const char nl
Definition: Ostream.H:262
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
label getBoundaryCell(const label) const
Returns cell next to boundary face.
Definition: sampledSet.C:44
defineTypeNameAndDebug(combustionModel, 0)
labelList f(nPoints)
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
sampledSet(const word &name, const polyMesh &mesh, const meshSearch &searchEngine, const word &axis)
Construct from components.
Definition: sampledSet.C:408
const vectorField & faceCentres() const
label pointInCell(const point &p, const label samplei) const
Return the cell in which the point on the sample line.
Definition: sampledSet.C:64
#define WarningInFunction
Report a warning using Foam::Warning.
pointHit nearestPoint(const point &p, const pointField &) const
Return nearest point to face.
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:56
scalar calcSign(const label facei, const point &sample) const
Calculates inproduct of face normal and vector sample-face centre.
Definition: sampledSet.C:136
const vectorField & faceAreas() const
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:1268
label findCell(const point &p, const cellDecomposition=CELL_TETS) const
Find cell enclosing this location and return index.
Definition: polyMesh.C:1394
dimensioned< scalar > mag(const dimensioned< Type > &)
label n
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
bool getTrackingPoint(const point &samplePt, const point &bPoint, const label bFacei, const scalar smallDist, point &trackPt, label &trackCelli, label &trackFacei) const
Calculates start of tracking given samplePt and first boundary.
Definition: sampledSet.C:262
Namespace for OpenFOAM.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:576
#define InfoInFunction
Report an information message using Foam::Info.