particleI.H
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-2016 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 "polyMesh.H"
27 #include "Time.H"
28 
29 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30 
31 inline void Foam::particle::findTris
32 (
33  const vector& position,
34  DynamicList<label>& faceList,
35  const tetPointRef& tet,
36  const FixedList<vector, 4>& tetAreas,
37  const FixedList<label, 4>& tetPlaneBasePtIs,
38  const scalar tol
39 ) const
40 {
41  faceList.clear();
42 
43  const point Ct = tet.centre();
44 
45  for (label i = 0; i < 4; i++)
46  {
47  scalar lambda = tetLambda
48  (
49  Ct,
50  position,
51  i,
52  tetAreas[i],
53  tetPlaneBasePtIs[i],
54  celli_,
55  tetFacei_,
56  tetPtI_,
57  tol
58  );
59 
60  if ((lambda > 0.0) && (lambda < 1.0))
61  {
62  faceList.append(i);
63  }
64  }
65 }
66 
67 
68 inline Foam::scalar Foam::particle::tetLambda
69 (
70  const vector& from,
71  const vector& to,
72  const label triI,
73  const vector& n,
74  const label tetPlaneBasePtI,
75  const label celli,
76  const label tetFacei,
77  const label tetPtI,
78  const scalar tol
79 ) const
80 {
81  const pointField& pPts = mesh_.points();
82 
83  if (mesh_.moving())
84  {
85  return movingTetLambda
86  (
87  from,
88  to,
89  triI,
90  n,
91  tetPlaneBasePtI,
92  celli,
93  tetFacei,
94  tetPtI,
95  tol
96  );
97  }
98 
99  const point& base = pPts[tetPlaneBasePtI];
100 
101  scalar lambdaNumerator = (base - from) & n;
102  scalar lambdaDenominator = (to - from) & n;
103 
104  // n carries the area of the tet faces, so the dot product with a
105  // delta-length has the units of volume. Comparing the component of each
106  // delta-length in the direction of n times the face area to a fraction of
107  // the cell volume.
108 
109  if (mag(lambdaDenominator) < tol)
110  {
111  if (mag(lambdaNumerator) < tol)
112  {
113  // Track starts on the face, and is potentially
114  // parallel to it. +-tol/+-tol is not a good
115  // comparison, return 0.0, in anticipation of tet
116  // centre correction.
117  return 0.0;
118  }
119  else
120  {
121  if (mag((to - from)) < tol/mag(n))
122  {
123  // 'Zero' length track (compared to the tolerance, which is
124  // based on the cell volume, divided by the tet face area), not
125  // along the face, face cannot be crossed.
126  return GREAT;
127  }
128  else
129  {
130  // Trajectory is non-zero and parallel to face
131  lambdaDenominator = sign(lambdaDenominator)*SMALL;
132  }
133  }
134  }
135 
136  return lambdaNumerator/lambdaDenominator;
137 }
138 
139 
140 inline Foam::scalar Foam::particle::movingTetLambda
141 (
142  const vector& from,
143  const vector& to,
144  const label triI,
145  const vector& n,
146  const label tetPlaneBasePtI,
147  const label celli,
148  const label tetFacei,
149  const label tetPtI,
150  const scalar tol
151 ) const
152 {
153  const pointField& pPts = mesh_.points();
154  const pointField& oldPPts = mesh_.oldPoints();
155 
156  // Base point of plane at end of motion
157  const point& b = pPts[tetPlaneBasePtI];
158 
159  // n: Normal of plane at end of motion
160 
161  // Base point of plane at start of timestep
162  const point& b00 = oldPPts[tetPlaneBasePtI];
163 
164  // Base point of plane at start of tracking portion (cast forward by
165  // stepFraction)
166  point b0 = b00 + stepFraction_*(b - b00);
167 
168  // Normal of plane at start of tracking portion
169  vector n0 = Zero;
170 
171  {
172  tetIndices tetIs(celli, tetFacei, tetPtI, mesh_);
173 
174  // Tet at timestep start
175  tetPointRef tet00 = tetIs.oldTet(mesh_);
176 
177  // Tet at timestep end
178  tetPointRef tet = tetIs.tet(mesh_);
179 
180  point tet0PtA = tet00.a() + stepFraction_*(tet.a() - tet00.a());
181  point tet0PtB = tet00.b() + stepFraction_*(tet.b() - tet00.b());
182  point tet0PtC = tet00.c() + stepFraction_*(tet.c() - tet00.c());
183  point tet0PtD = tet00.d() + stepFraction_*(tet.d() - tet00.d());
184 
185  // Tracking portion start tet (cast forward by stepFraction)
186  tetPointRef tet0(tet0PtA, tet0PtB, tet0PtC, tet0PtD);
187 
188  switch (triI)
189  {
190  case 0:
191  {
192  n0 = tet0.Sa();
193  break;
194  }
195  case 1:
196  {
197  n0 = tet0.Sb();
198  break;
199  }
200  case 2:
201  {
202  n0 = tet0.Sc();
203  break;
204  }
205  case 3:
206  {
207  n0 = tet0.Sd();
208  break;
209  }
210  default:
211  {
212  break;
213  }
214  }
215  }
216 
217  if (mag(n0) < SMALL)
218  {
219  // If the old normal is zero (for example in layer addition)
220  // then use the current normal;
221  n0 = n;
222  }
223 
224  scalar lambdaNumerator = 0;
225  scalar lambdaDenominator = 0;
226 
227  vector dP = to - from;
228  vector dN = n - n0;
229  vector dB = b - b0;
230  vector dS = from - b0;
231 
232  if (mag(dN) > SMALL)
233  {
234  scalar a = (dP - dB) & dN;
235  scalar b = ((dP - dB) & n0) + (dS & dN);
236  scalar c = dS & n0;
237 
238  if (mag(a) > SMALL)
239  {
240 
241  // Solve quadratic for lambda
242  scalar discriminant = sqr(b) - 4.0*a*c;
243 
244  if (discriminant < 0)
245  {
246  // Imaginary roots only - face not crossed
247  return GREAT;
248  }
249  else
250  {
251  scalar q = -0.5*(b + sign(b)*Foam::sqrt(discriminant));
252 
253  if (mag(q) < VSMALL)
254  {
255  // If q is zero, then l1 = q/a is the required
256  // value of lambda, and is zero.
257  return 0.0;
258  }
259 
260  scalar l1 = q/a;
261  scalar l2 = c/q;
262 
263  // There will be two roots, a big one and a little
264  // one, choose the little one.
265 
266  if (mag(l1) < mag(l2))
267  {
268  return l1;
269  }
270  else
271  {
272  return l2;
273  }
274  }
275  }
276  {
277  // When a is zero, solve the first order polynomial
278  lambdaNumerator = -c;
279  lambdaDenominator = b;
280  }
281  }
282  else
283  {
284  // When n = n0 is zero, there is no plane rotation, solve the
285  // first order polynomial
286  lambdaNumerator = -(dS & n0);
287  lambdaDenominator = ((dP - dB) & n0);
288  }
289 
290  if (mag(lambdaDenominator) < tol)
291  {
292  if (mag(lambdaNumerator) < tol)
293  {
294  // Track starts on the face, and is potentially
295  // parallel to it. +-tol)/+-tol is not a good
296  // comparison, return 0.0, in anticipation of tet
297  // centre correction.
298  return 0.0;
299  }
300  else
301  {
302  if (mag((to - from)) < tol/mag(n))
303  {
304  // Zero length track, not along the face, face
305  // cannot be crossed.
306  return GREAT;
307  }
308  else
309  {
310  // Trajectory is non-zero and parallel to face
311  lambdaDenominator = sign(lambdaDenominator)*SMALL;
312  }
313  }
314  }
315 
316  return lambdaNumerator/lambdaDenominator;
317 }
318 
319 
320 
322 {
323  const labelList& pOwner = mesh_.faceOwner();
324  const faceList& pFaces = mesh_.faces();
325 
326  bool own = (pOwner[tetFacei_] == celli_);
327 
328  const Foam::face& f = pFaces[tetFacei_];
329 
330  label tetBasePtI = mesh_.tetBasePtIs()[tetFacei_];
331 
332  if (tetBasePtI == -1)
333  {
335  << "No base point for face " << tetFacei_ << ", " << f
336  << ", produces a valid tet decomposition."
337  << abort(FatalError);
338  }
339 
340  label facePtI = (tetPtI_ + tetBasePtI) % f.size();
341  label otherFacePtI = f.fcIndex(facePtI);
342 
343  switch (triI)
344  {
345  case 0:
346  {
347  // Crossing this triangle changes tet to that in the
348  // neighbour cell over tetFacei
349 
350  // Modification of celli_ will happen by other indexing,
351  // tetFacei_ and tetPtI don't change.
352 
353  break;
354  }
355  case 1:
356  {
358  (
359  celli_,
360  tetFacei_,
361  tetPtI_,
362  Foam::edge(f[facePtI], f[otherFacePtI])
363  );
364 
365  break;
366  }
367  case 2:
368  {
369  if (own)
370  {
371  if (tetPtI_ < f.size() - 2)
372  {
373  tetPtI_ = f.fcIndex(tetPtI_);
374  }
375  else
376  {
378  (
379  celli_,
380  tetFacei_,
381  tetPtI_,
382  Foam::edge(f[tetBasePtI], f[otherFacePtI])
383  );
384  }
385  }
386  else
387  {
388  if (tetPtI_ > 1)
389  {
390  tetPtI_ = f.rcIndex(tetPtI_);
391  }
392  else
393  {
395  (
396  celli_,
397  tetFacei_,
398  tetPtI_,
399  Foam::edge(f[tetBasePtI], f[facePtI])
400  );
401  }
402  }
403 
404  break;
405  }
406  case 3:
407  {
408  if (own)
409  {
410  if (tetPtI_ > 1)
411  {
412  tetPtI_ = f.rcIndex(tetPtI_);
413  }
414  else
415  {
417  (
418  celli_,
419  tetFacei_,
420  tetPtI_,
421  Foam::edge(f[tetBasePtI], f[facePtI])
422  );
423  }
424  }
425  else
426  {
427  if (tetPtI_ < f.size() - 2)
428  {
429  tetPtI_ = f.fcIndex(tetPtI_);
430  }
431  else
432  {
434  (
435  celli_,
436  tetFacei_,
437  tetPtI_,
438  Foam::edge(f[tetBasePtI], f[otherFacePtI])
439  );
440  }
441  }
442 
443  break;
444  }
445  default:
446  {
448  << "Tet tri face index error, can only be 0..3, supplied "
449  << triI << abort(FatalError);
450 
451  break;
452  }
453  }
454 }
455 
456 
458 (
459  const label& celli,
460  label& tetFacei,
461  label& tetPtI,
462  const edge& e
463 )
464 {
465  const faceList& pFaces = mesh_.faces();
466  const cellList& pCells = mesh_.cells();
467 
468  const Foam::face& f = pFaces[tetFacei];
469 
470  const Foam::cell& thisCell = pCells[celli];
471 
472  forAll(thisCell, cFI)
473  {
474  // Loop over all other faces of this cell and
475  // find the one that shares this edge
476 
477  label fI = thisCell[cFI];
478 
479  if (tetFacei == fI)
480  {
481  continue;
482  }
483 
484  const Foam::face& otherFace = pFaces[fI];
485 
486  label edDir = otherFace.edgeDirection(e);
487 
488  if (edDir == 0)
489  {
490  continue;
491  }
492  else if (f == pFaces[fI])
493  {
494  // This is a necessary condition if using duplicate baffles
495  // (so coincident faces). We need to make sure we don't cross into
496  // the face with the same vertices since we might enter a tracking
497  // loop where it never exits. This test should be cheap
498  // for most meshes so can be left in for 'normal' meshes.
499  continue;
500  }
501  else
502  {
503  //Found edge on other face
504  tetFacei = fI;
505 
506  label eIndex = -1;
507 
508  if (edDir == 1)
509  {
510  // Edge is in the forward circulation of this face, so
511  // work with the start point of the edge
512  eIndex = findIndex(otherFace, e.start());
513  }
514  else
515  {
516  // edDir == -1, so the edge is in the reverse
517  // circulation of this face, so work with the end
518  // point of the edge
519  eIndex = findIndex(otherFace, e.end());
520  }
521 
522  label tetBasePtI = mesh_.tetBasePtIs()[fI];
523 
524  if (tetBasePtI == -1)
525  {
527  << "No base point for face " << fI << ", " << f
528  << ", produces a decomposition that has a minimum "
529  << "volume greater than tolerance."
530  << abort(FatalError);
531  }
532 
533  // Find eIndex relative to the base point on new face
534  eIndex -= tetBasePtI;
535 
536  if (neg(eIndex))
537  {
538  eIndex = (eIndex + otherFace.size()) % otherFace.size();
539  }
540 
541  if (eIndex == 0)
542  {
543  // The point is the base point, so this is first tet
544  // in the face circulation
545  tetPtI = 1;
546  }
547  else if (eIndex == otherFace.size() - 1)
548  {
549  // The point is the last before the base point, so
550  // this is the last tet in the face circulation
551  tetPtI = otherFace.size() - 2;
552  }
553  else
554  {
555  tetPtI = eIndex;
556  }
557 
558  break;
559  }
560  }
561 }
562 
563 
564 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
565 
567 {
568  label id = particleCount_++;
569 
570  if (id == labelMax)
571  {
573  << "Particle counter has overflowed. This might cause problems"
574  << " when reconstructing particle tracks." << endl;
575  }
576  return id;
577 }
578 
579 
581 {
582  return mesh_;
583 }
584 
585 
587 {
588  return position_;
589 }
590 
591 
593 {
594  return position_;
595 }
596 
597 
599 {
600  return celli_;
601 }
602 
603 
605 {
606  return celli_;
607 }
608 
609 
611 {
612  return tetFacei_;
613 }
614 
615 
617 {
618  return tetFacei_;
619 }
620 
621 
623 {
624  return tetPtI_;
625 }
626 
627 
629 {
630  return tetPtI_;
631 }
632 
633 
635 {
637 }
638 
639 
641 {
642  return currentTetIndices().tet(mesh_);
643 }
644 
645 
647 {
649 }
650 
651 
653 {
655 }
656 
657 
659 {
660  return facei_;
661 }
662 
663 
665 {
666  return facei_;
667 }
668 
669 
671 {
672  if (celli_ == -1)
673  {
675  (
676  position_,
677  celli_,
678  tetFacei_,
679  tetPtI_
680  );
681 
682  if (celli_ == -1)
683  {
685  << "cell, tetFace and tetPt search failure at position "
686  << position_ << abort(FatalError);
687  }
688  }
689  else
690  {
692 
693  if (tetFacei_ == -1 || tetPtI_ == -1)
694  {
695  label oldCelli = celli_;
696 
698  (
699  position_,
700  celli_,
701  tetFacei_,
702  tetPtI_
703  );
704 
705  if (celli_ == -1 || tetFacei_ == -1 || tetPtI_ == -1)
706  {
707  // The particle has entered this function with a cell
708  // number, but hasn't been able to find a cell to
709  // occupy.
710 
711  if (!mesh_.pointInCellBB(position_, oldCelli, 0.1))
712  {
713  // If the position is not inside the (slightly
714  // extended) bound-box of the cell that it thought
715  // it should be in, then this is considered an
716  // error.
717 
719  << "position " << position_ << nl
720  << " for requested cell " << oldCelli << nl
721  << " If this is a restart or "
722  "reconstruction/decomposition etc. it is likely that"
723  " the write precision is not sufficient.\n"
724  " Either increase 'writePrecision' or "
725  "set 'writeFormat' to 'binary'"
726  << abort(FatalError);
727  }
728 
729  // The position is in the (slightly extended)
730  // bound-box of the cell. This situation may arise
731  // because the face decomposition of the cell is not
732  // the same as when the particle acquired the cell
733  // index. For example, it has been read into a mesh
734  // that has made a different face base-point decision
735  // for a boundary face and now this particle is in a
736  // position that is not in the mesh. Gradually move
737  // the particle towards the centre of the cell that it
738  // thought that it was in.
739 
740  celli_ = oldCelli;
741 
742  point newPosition = position_;
743 
744  const point& cC = mesh_.cellCentres()[celli_];
745 
746  label trap(1.0/trackingCorrectionTol + 1);
747 
748  label iterNo = 0;
749 
750  do
751  {
752  newPosition += trackingCorrectionTol*(cC - position_);
753 
755  (
756  celli_,
757  newPosition,
758  tetFacei_,
759  tetPtI_
760  );
761 
762  iterNo++;
763 
764  } while (tetFacei_ < 0 && iterNo <= trap);
765 
766  if (tetFacei_ == -1)
767  {
769  << "cell, tetFace and tetPt search failure at position "
770  << position_ << abort(FatalError);
771  }
772 
773  if (debug)
774  {
776  << "Particle moved from " << position_
777  << " to " << newPosition
778  << " in cell " << celli_
779  << " tetFace " << tetFacei_
780  << " tetPt " << tetPtI_ << nl
781  << " (A fraction of "
782  << 1.0 - mag(cC - newPosition)/mag(cC - position_)
783  << " of the distance to the cell centre)"
784  << " because a decomposition tetFace and tetPt "
785  << "could not be found."
786  << endl;
787  }
788 
789  position_ = newPosition;
790  }
791 
792  if (debug && celli_ != oldCelli)
793  {
795  << "Particle at position " << position_
796  << " searched for a cell, tetFace and tetPt." << nl
797  << " Found"
798  << " cell " << celli_
799  << " tetFace " << tetFacei_
800  << " tetPt " << tetPtI_ << nl
801  << " This is a different cell to that which was supplied"
802  << " (" << oldCelli << ")." << nl
803  << endl;
804  }
805  }
806  }
807 }
808 
809 
810 inline bool Foam::particle::onBoundary() const
811 {
812  return facei_ != -1 && facei_ >= mesh_.nInternalFaces();
813 }
814 
815 
816 inline Foam::scalar& Foam::particle::stepFraction()
817 {
818  return stepFraction_;
819 }
820 
821 
822 inline Foam::scalar Foam::particle::stepFraction() const
823 {
824  return stepFraction_;
825 }
826 
827 
829 {
830  return origProc_;
831 }
832 
833 
835 {
836  return origProc_;
837 }
838 
839 
841 {
842  return origId_;
843 }
844 
845 
847 {
848  return origId_;
849 }
850 
851 
852 inline bool Foam::particle::softImpact() const
853 {
854  return false;
855 }
856 
857 
858 inline Foam::scalar Foam::particle::currentTime() const
859 {
860  return
861  mesh_.time().value()
863 }
864 
865 
866 inline bool Foam::particle::internalFace(const label facei) const
867 {
868  return mesh_.isInternalFace(facei);
869 }
870 
871 
872 bool Foam::particle::boundaryFace(const label facei) const
873 {
874  return !internalFace(facei);
875 }
876 
877 
878 inline Foam::label Foam::particle::patch(const label facei) const
879 {
880  return mesh_.boundaryMesh().whichPatch(facei);
881 }
882 
883 
885 (
886  const label patchi,
887  const label facei
888 ) const
889 {
890  return mesh_.boundaryMesh()[patchi].whichFace(facei);
891 }
892 
893 
895 {
896  return facei_;
897 }
898 
899 
900 // ************************************************************************* //
bool onBoundary() const
Is the particle on the boundary/(or outside the domain)?
Definition: particleI.H:810
label & tetPt()
Return current tet face particle is in.
Definition: particleI.H:628
label end() const
Return end vertex label.
Definition: edgeI.H:92
const Time & time() const
Return time.
dimensionedScalar sign(const dimensionedScalar &ds)
int edgeDirection(const edge &) const
Return the edge direction on the face.
Definition: face.C:779
A tetrahedron primitive.
Definition: tetrahedron.H:62
void findTris(const vector &position, DynamicList< label > &faceList, const tetPointRef &tet, const FixedList< vector, 4 > &tetAreas, const FixedList< label, 4 > &tetPlaneBasePtIs, const scalar tol) const
Find the tet tri faces between position and tet centre.
Definition: particleI.H:32
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
scalar currentTime() const
Return the particle current time.
Definition: particleI.H:858
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
static const scalar trackingCorrectionTol
Fraction of distance to tet centre to move a particle to.
Definition: particle.H:326
scalar movingTetLambda(const vector &from, const vector &to, const label triI, const vector &tetArea, const label tetPlaneBasePtI, const label celli, const label tetFacei, const label tetPtI, const scalar tol) const
Find the lambda value for a moving tri face.
Definition: particleI.H:141
label getNewParticleID() const
Get unique particle creation id.
Definition: particleI.H:566
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
A 1D vector of objects of type <T> with a fixed size <Size>.
Definition: FixedList.H:53
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
triPointRef faceTri(const polyMesh &mesh) const
Return the geometry corresponding to the tri on the.
Definition: tetIndicesI.H:109
void initCellFacePt()
Check the stored cell value (setting if necessary) and.
Definition: particleI.H:670
scalar tetLambda(const vector &from, const vector &to, const label triI, const vector &tetArea, const label tetPlaneBasePtI, const label celli, const label tetFacei, const label tetPtI, const scalar tol) const
Find the lambda value for the line to-from across the.
Definition: particleI.H:69
dimensionedSymmTensor sqr(const dimensionedVector &dv)
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
label tetPtI_
Index of the point on the face that defines the decomposed.
Definition: particle.H:158
const Point & c() const
Definition: tetrahedronI.H:87
void crossEdgeConnectedFace(const label &celli, label &tetFacei, label &tetPtI, const edge &e)
Cross the from the given face across the given edge of the.
Definition: particleI.H:458
tetIndices currentTetIndices() const
Return the indices of the current tet that the.
Definition: particleI.H:634
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
label faceInterpolation() const
Return the index of the face to be used in the interpolation.
Definition: particleI.H:894
const Type & value() const
Return const reference to value.
vector position_
Position of particle.
Definition: particle.H:140
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
label origId() const
Return const access to the particle id on originating processor.
Definition: particleI.H:840
const cellList & cells() const
dimensionedScalar neg(const dimensionedScalar &ds)
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
label origId_
Local particle id on originating processor.
Definition: particle.H:164
bool internalFace(const label facei) const
Is this global face an internal face?
Definition: particleI.H:866
const Point & a() const
Return vertices.
Definition: tetrahedronI.H:73
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
Definition: UListI.H:58
tetPointRef currentTet() const
Return the geometry of the current tet that the.
Definition: particleI.H:640
scalar & stepFraction()
Return the fraction of time-step completed.
Definition: particleI.H:816
label origProc_
Originating processor id.
Definition: particle.H:161
const vector & position() const
Return current particle position.
Definition: particleI.H:586
label patch(const label facei) const
Which patch is particle on.
Definition: particleI.H:878
void findCellFacePt(const point &p, label &celli, label &tetFacei, label &tetPti) const
Find the cell, tetFacei and tetPti for point p.
Definition: polyMesh.C:1201
Point centre() const
Return centre (centroid)
Definition: tetrahedronI.H:164
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
bool softImpact() const
Return the impact model to be used, soft or hard (default).
Definition: particleI.H:852
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints,-1);const cellModel &hex=*(cellModeller::lookup("hex"));labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){pointMap[i]=i;}for(label i=0;i< nPoints;i++){if(f[i] > 0.0){hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells]=cellShape(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei){if(edges[ei].mag(points)< SMALL){label start=pointMap[edges[ei].start()];while(start!=pointMap[start]){start=pointMap[start];}label end=pointMap[edges[ei].end()];while(end!=pointMap[end]){end=pointMap[end];}label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;}}cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){cellShape &cs=cellShapes[celli];forAll(cs, i){cs[i]=pointMap[cs[i]];}cs.collapse();}label bcIDs[11]={-1, 0, 2, 4,-1, 5,-1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={&wallPolyPatch::typeName,&wallPolyPatch::typeName,&wallPolyPatch::typeName,&wallPolyPatch::typeName,&symmetryPolyPatch::typeName,&wedgePolyPatch::typeName,&polyPatch::typeName,&polyPatch::typeName,&polyPatch::typeName,&polyPatch::typeName,&symmetryPolyPatch::typeName,&oldCyclicPolyPatch::typeName};enum patchTypeNames{PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={"piston","valve","liner","cylinderHead","axis","wedge","inflow","outflow","presin","presout","symmetryPlane","cyclic"};List< SLList< face > > pFaces[nBCs]
Definition: readKivaGrid.H:235
const polyMesh & mesh_
Reference to the polyMesh database.
Definition: particle.H:137
triPointRef oldFaceTri(const polyMesh &mesh) const
Return the geometry corresponding to the tri on the.
Definition: tetIndicesI.H:140
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:292
const vectorField & cellCentres() const
static const label labelMax
Definition: label.H:62
static const zero Zero
Definition: zero.H:91
vector normal() const
Return the normal of the tri on tetFacei_ for the.
Definition: particleI.H:646
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:1273
Storage and named access for the indices of a tet which is part of the decomposition of a cell...
Definition: tetIndices.H:81
scalar stepFraction_
Fraction of time-step completed.
Definition: particle.H:149
const Point & b() const
Definition: tetrahedronI.H:80
errorManip< error > abort(error &err)
Definition: errorManip.H:131
label celli_
Index of the cell it is in.
Definition: particle.H:143
label tetFacei_
Index of the face that owns the decomposed tet that the.
Definition: particle.H:153
label start() const
Return start vertex label.
Definition: edgeI.H:81
label & face()
Return current face particle is on otherwise -1.
Definition: particleI.H:664
static const char nl
Definition: Ostream.H:262
label origProc() const
Return const access to the originating processor id.
Definition: particleI.H:828
const labelList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:818
labelList f(nPoints)
void tetNeighbour(label triI)
Modify the tet owner data by crossing triI.
Definition: particleI.H:321
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
label rcIndex(const label i) const
Return the reverse circular index, i.e. the previous index.
Definition: UListI.H:65
scalar deltaTValue() const
Return time step value.
Definition: TimeStateI.H:41
tetPointRef oldTet(const polyMesh &mesh) const
Return the geometry corresponding to this tet from the.
Definition: tetIndicesI.H:84
bool boundaryFace(const label facei) const
Is this global face a boundary face?
Definition: particleI.H:872
label patchi
bool pointInCellBB(const point &p, label celli, scalar inflationFraction=0) const
Return true if the point in the cell bounding box.
#define WarningInFunction
Report a warning using Foam::Warning.
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:56
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
const dimensionedScalar c
Speed of light in a vacuum.
dimensionedScalar lambda(laminarTransport.lookup("lambda"))
const Point & d() const
Definition: tetrahedronI.H:94
label & cell()
Return current cell particle is in.
Definition: particleI.H:604
dimensioned< scalar > mag(const dimensioned< Type > &)
label n
static label particleCount_
Cumulative particle counter - used to provode unique ID.
Definition: particle.H:319
const polyMesh & mesh() const
Return the mesh database.
Definition: particleI.H:580
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
label & tetFace()
Return current tet face particle is in.
Definition: particleI.H:616
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1017
label patchFace(const label patchi, const label facei) const
Which face of this patch is this particle on.
Definition: particleI.H:885
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:224
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1004
vector oldNormal() const
Return the normal of the tri on tetFacei_ for the.
Definition: particleI.H:652
label nInternalFaces() const
tetPointRef tet(const polyMesh &mesh) const
Return the geometry corresponding to this tet from the.
Definition: tetIndicesI.H:66
label otherFace(const primitiveMesh &, const label celli, const label facei, const label edgeI)
Return face on cell using edgeI but not facei. Throws error.
Definition: meshTools.C:536
vector normal() const
Return vector normal.
Definition: triangleI.H:103
label facei_
Face index if the particle is on a face otherwise -1.
Definition: particle.H:146