wallBoundedParticle.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-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2019 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "wallBoundedParticle.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
34 (
35  sizeof(wallBoundedParticle) - sizeof(particle)
36 );
37 
38 
39 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
40 
42 {
43  if ((meshEdgeStart_ != -1) == (diagEdge_ != -1))
44  {
46  << "Particle:"
47  << info()
48  << "cannot both be on a mesh edge and a face-diagonal edge."
49  << " meshEdgeStart_:" << meshEdgeStart_
50  << " diagEdge_:" << diagEdge_
51  << abort(FatalError);
52  }
53 
54  const Foam::face& f = mesh().faces()[tetFace()];
55 
56  if (meshEdgeStart_ != -1)
57  {
58  return edge(f[meshEdgeStart_], f.nextLabel(meshEdgeStart_));
59  }
60  else
61  {
62  label faceBasePti = mesh().tetBasePtIs()[tetFace()];
63  if (faceBasePti == -1)
64  {
65  //FatalErrorInFunction
66  //WarningInFunction
67  // << "No base point for face " << tetFace() << ", " << f
68  // << ", produces a decomposition that has a minimum "
69  // << "volume greater than tolerance."
70  // //<< abort(FatalError);
71  // << endl;
72  faceBasePti = 0;
73  }
74 
75  label diagPti = (faceBasePti + diagEdge_)%f.size();
76 
77  return edge(f[faceBasePti], f[diagPti]);
78  }
79 }
80 
81 
83 (
84  const label& celli,
85  label& tetFacei,
86  label& tetPti,
87  const edge& e
88 )
89 {
90  const faceList& pFaces = mesh().faces();
91  const cellList& pCells = mesh().cells();
92 
93  const Foam::face& f = pFaces[tetFacei];
94 
95  const Foam::cell& thisCell = pCells[celli];
96 
97  for (const label facei : thisCell)
98  {
99  // Loop over all other faces of this cell and
100  // find the one that shares this edge
101 
102  if (tetFacei == facei)
103  {
104  continue;
105  }
106 
107  const Foam::face& otherFace = pFaces[facei];
108 
109  label edDir = otherFace.edgeDirection(e);
110 
111  if (edDir == 0)
112  {
113  continue;
114  }
115  else if (f == pFaces[facei])
116  {
117  // This is a necessary condition if using duplicate baffles
118  // (so coincident faces). We need to make sure we don't cross into
119  // the face with the same vertices since we might enter a tracking
120  // loop where it never exits. This test should be cheap
121  // for most meshes so can be left in for 'normal' meshes.
122  continue;
123  }
124  else
125  {
126  //Found edge on other face
127  tetFacei = facei;
128 
129  label eIndex = -1;
130 
131  if (edDir == 1)
132  {
133  // Edge is in the forward circulation of this face, so
134  // work with the start point of the edge
135  eIndex = otherFace.find(e.start());
136  }
137  else
138  {
139  // edDir == -1, so the edge is in the reverse
140  // circulation of this face, so work with the end
141  // point of the edge
142  eIndex = otherFace.find(e.end());
143  }
144 
145  label tetBasePtI = mesh().tetBasePtIs()[facei];
146 
147  if (tetBasePtI == -1)
148  {
149  //FatalErrorInFunction
150  //WarningInFunction
151  // << "No base point for face " << fI << ", " << f
152  // << ", produces a decomposition that has a minimum "
153  // << "volume greater than tolerance."
154  // //<< abort(FatalError);
155  // << endl;
156  tetBasePtI = 0;
157  }
158 
159  // Find eIndex relative to the base point on new face
160  eIndex -= tetBasePtI;
161 
162  if (neg(eIndex))
163  {
164  eIndex = (eIndex + otherFace.size()) % otherFace.size();
165  }
166 
167  if (eIndex == 0)
168  {
169  // The point is the base point, so this is first tet
170  // in the face circulation
171  tetPti = 1;
172  }
173  else if (eIndex == otherFace.size() - 1)
174  {
175  // The point is the last before the base point, so
176  // this is the last tet in the face circulation
177  tetPti = otherFace.size() - 2;
178  }
179  else
180  {
181  tetPti = eIndex;
182  }
183 
184  break;
185  }
186  }
187 }
188 
189 
191 {
192  // Update tetFace, tetPt
193  crossEdgeConnectedFace(cell(), tetFace(), tetPt(), meshEdge);
194 
195  // Update face to be same as tracking one
196  face() = tetFace();
197 
198  // And adapt meshEdgeStart_.
199  const Foam::face& f = mesh().faces()[tetFace()];
200  label fp = f.find(meshEdge[0]);
201 
202  if (f.nextLabel(fp) == meshEdge[1])
203  {
204  meshEdgeStart_ = fp;
205  }
206  else
207  {
208  label fpMin1 = f.rcIndex(fp);
209 
210  if (f[fpMin1] == meshEdge[1])
211  {
212  meshEdgeStart_ = fpMin1;
213  }
214  else
215  {
217  << "Problem :"
218  << " particle:"
219  << info()
220  << "face:" << tetFace()
221  << " verts:" << f
222  << " meshEdge:" << meshEdge
223  << abort(FatalError);
224  }
225  }
226 
227  diagEdge_ = -1;
228 
229  // Check that still on same mesh edge
230  const edge eNew(f[meshEdgeStart_], f.nextLabel(meshEdgeStart_));
231  if (eNew != meshEdge)
232  {
234  << "Problem" << abort(FatalError);
235  }
236 }
237 
238 
240 {
241  if (diagEdge_ == -1)
242  {
244  << "Particle:"
245  << info()
246  << "not on a diagonal edge" << abort(FatalError);
247  }
248  if (meshEdgeStart_ != -1)
249  {
251  << "Particle:"
252  << info()
253  << "meshEdgeStart_:" << meshEdgeStart_ << abort(FatalError);
254  }
255 
256  const Foam::face& f = mesh().faces()[tetFace()];
257 
258  // tetPti starts from 1, goes up to f.size()-2
259 
260  if (tetPt() == diagEdge_)
261  {
262  tetPt() = f.rcIndex(tetPt());
263  }
264  else
265  {
266  label nextTetPt = f.fcIndex(tetPt());
267  if (diagEdge_ == nextTetPt)
268  {
269  tetPt() = nextTetPt;
270  }
271  else
272  {
274  << "Particle:"
275  << info()
276  << "tetPt:" << tetPt()
277  << " diagEdge:" << diagEdge_ << abort(FatalError);
278  }
279  }
280 
281  meshEdgeStart_ = -1;
282 }
283 
284 
286 (
287  const vector& n,
288  const vector& endPosition,
289  label& minEdgei
290 )
291 {
292  // Track p from position to endPosition
293  const triFace tri(currentTetIndices().faceTriIs(mesh(), false));
294 
295  // Check which edge intersects the trajectory.
296  // Project trajectory onto triangle
297  minEdgei = -1;
298  scalar minS = 1; // end position
299 
300  edge currentE(-1, -1);
301  if (meshEdgeStart_ != -1 || diagEdge_ != -1)
302  {
303  currentE = currentEdge();
304  }
305 
306  // Determine path along line position+s*d to see where intersections are.
307  forAll(tri, i)
308  {
309  label j = tri.fcIndex(i);
310 
311  const point& pt0 = mesh().points()[tri[i]];
312  const point& pt1 = mesh().points()[tri[j]];
313 
314  if (edge(tri[i], tri[j]) == currentE)
315  {
316  // Do not check particle is on
317  continue;
318  }
319 
320  // Outwards pointing normal
321  vector edgeNormal = (pt1 - pt0)^n;
322  edgeNormal.normalise();
323 
324  // Determine whether position and end point on either side of edge.
325  scalar sEnd = (endPosition - pt0)&edgeNormal;
326  if (sEnd >= 0)
327  {
328  // endPos is outside triangle. localPosition_ should always be
329  // inside.
330  scalar sStart = (localPosition_ - pt0)&edgeNormal;
331  if (mag(sEnd - sStart) > VSMALL)
332  {
333  scalar s = sStart/(sStart - sEnd);
334 
335  if (s >= 0 && s < minS)
336  {
337  minS = s;
338  minEdgei = i;
339  }
340  }
341  }
342  }
343 
344  if (minEdgei != -1)
345  {
346  localPosition_ += minS*(endPosition - localPosition_);
347  }
348  else
349  {
350  // Did not hit any edge so tracked to the end position. Set position
351  // without any calculation to avoid truncation errors.
352  localPosition_ = endPosition;
353  minS = 1.0;
354  }
355 
356  // Project localPosition_ back onto plane of triangle
357  const point& triPt = mesh().points()[tri[0]];
358  localPosition_ -= ((localPosition_ - triPt)&n)*n;
359 
360  return minS;
361 }
362 
363 
365 (
366  const vector& n,
367  const point& endPosition
368 ) const
369 {
370  const triFace triVerts(currentTetIndices().faceTriIs(mesh(), false));
371  const edge currentE = currentEdge();
372 
373  if
374  (
375  currentE[0] == currentE[1]
376  || !triVerts.found(currentE[0])
377  || !triVerts.found(currentE[1])
378  )
379  {
381  << "Edge " << currentE << " not on triangle " << triVerts
382  << info()
383  << abort(FatalError);
384  }
385 
386 
387  const vector dir = endPosition - localPosition_;
388 
389  forAll(triVerts, i)
390  {
391  label j = triVerts.fcIndex(i);
392  const point& pt0 = mesh().points()[triVerts[i]];
393  const point& pt1 = mesh().points()[triVerts[j]];
394 
395  if (edge(triVerts[i], triVerts[j]) == currentE)
396  {
397  vector edgeNormal = (pt1-pt0)^n;
398  return (dir&edgeNormal) < 0;
399  }
400  }
401 
403  << "Problem" << abort(FatalError);
404 
405  return false;
406 }
407 
408 
409 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
410 
412 (
413  const polyMesh& mesh,
414  const point& position,
415  const label celli,
416  const label tetFacei,
417  const label tetPti,
418  const label meshEdgeStart,
419  const label diagEdge
420 )
421 :
422  particle(mesh, position, celli, tetFacei, tetPti, false),
423  localPosition_(position),
424  meshEdgeStart_(meshEdgeStart),
425  diagEdge_(diagEdge)
426 {}
427 
428 
430 (
431  const polyMesh& mesh,
432  Istream& is,
433  bool readFields,
434  bool newFormat
435 )
436 :
437  particle(mesh, is, readFields, newFormat)
438 {
439  if (readFields)
440  {
441  if (is.format() == IOstream::ASCII)
442  {
443  is >> localPosition_ >> meshEdgeStart_ >> diagEdge_;
444  }
445  if (!is.checkLabelSize<>() || !is.checkScalarSize<>())
446  {
447  // Non-native label or scalar size
448 
449  is.beginRawRead();
450 
451  readRawScalar(is, localPosition_.data(), vector::nComponents);
452  readRawLabel(is, &meshEdgeStart_);
453  readRawLabel(is, &diagEdge_);
454 
455  is.endRawRead();
456  }
457  else
458  {
459  is.read(reinterpret_cast<char*>(&localPosition_), sizeofFields_);
460  }
461  }
462 
463  is.check(FUNCTION_NAME);
464 }
465 
466 
468 (
469  const wallBoundedParticle& p
470 )
471 :
472  particle(p),
473  localPosition_(p.localPosition_),
474  meshEdgeStart_(p.meshEdgeStart_),
475  diagEdge_(p.diagEdge_)
476 {}
477 
478 
479 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
480 
481 Foam::Ostream& Foam::operator<<
482 (
483  Ostream& os,
484  const wallBoundedParticle& p
485 )
486 {
487  if (os.format() == IOstream::ASCII)
488  {
489  os << static_cast<const particle&>(p)
490  << token::SPACE << p.localPosition_
491  << token::SPACE << p.meshEdgeStart_
492  << token::SPACE << p.diagEdge_;
493  }
494  else
495  {
496  os << static_cast<const particle&>(p);
497  os.write
498  (
499  reinterpret_cast<const char*>(&p.localPosition_),
501  );
502  }
503 
504  return os;
505 }
506 
507 
508 Foam::Ostream& Foam::operator<<
509 (
510  Ostream& os,
512 )
513 {
514  const wallBoundedParticle& p = ip.t_;
515 
516  tetPointRef tpr(p.currentTetIndices().tet(p.mesh()));
517 
518  os << " " << static_cast<const particle&>(p) << nl
519  << " tet:" << nl;
520  os << " ";
521  meshTools::writeOBJ(os, tpr.a());
522  os << " ";
523  meshTools::writeOBJ(os, tpr.b());
524  os << " ";
525  meshTools::writeOBJ(os, tpr.c());
526  os << " ";
527  meshTools::writeOBJ(os, tpr.d());
528  os << " l 1 2" << nl
529  << " l 1 3" << nl
530  << " l 1 4" << nl
531  << " l 2 3" << nl
532  << " l 2 4" << nl
533  << " l 3 4" << nl;
534  os << " ";
535  meshTools::writeOBJ(os, p.localPosition_);
536 
537  return os;
538 }
539 
540 
541 // ************************************************************************* //
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1069
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::wallBoundedParticle::sizeofFields_
static const std::size_t sizeofFields_
Size in bytes of the fields.
Definition: wallBoundedParticle.H:151
Foam::InfoProxy
A helper class for outputting values to Ostream.
Definition: InfoProxy.H:47
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputSpray.H:25
Foam::meshTools::otherFace
label otherFace(const primitiveMesh &mesh, const label celli, const label facei, const label edgeI)
Return face on cell using edgeI but not facei. Throws error.
Definition: meshTools.C:555
Foam::wallBoundedParticle::wallBoundedParticle
wallBoundedParticle(const polyMesh &c, const point &position, const label celli, const label tetFacei, const label tetPti, const label meshEdgeStart, const label diagEdge)
Construct from components.
Definition: wallBoundedParticle.C:412
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:203
Foam::tetrahedron::d
const Point & d() const
Definition: tetrahedronI.H:97
Foam::particle::tetFace
label tetFace() const
Return current tet face particle is in.
Definition: particleI.H:161
Foam::primitiveMesh::cells
const cellList & cells() const
Definition: primitiveMeshCells.C:138
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:63
Foam::wallBoundedParticle::meshEdgeStart_
label meshEdgeStart_
Particle is on mesh edge:
Definition: wallBoundedParticle.H:108
Foam::wallBoundedParticle::crossDiagonalEdge
void crossDiagonalEdge()
Cross diagonal edge into different triangle on same face,cell.
Definition: wallBoundedParticle.C:239
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:286
Foam::wallBoundedParticle::info
InfoProxy< wallBoundedParticle > info() const
Return info proxy.
Definition: wallBoundedParticle.H:274
Foam::Vector::normalise
Vector< Cmpt > & normalise()
Normalise the vector by its magnitude.
Definition: VectorI.H:123
Foam::OBJstream::write
virtual Ostream & write(const char c)
Write character.
Definition: OBJstream.C:78
Foam::FixedList::fcIndex
label fcIndex(const label i) const
Definition: FixedListI.H:235
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::IOstream::checkLabelSize
std::enable_if< std::is_integral< T >::value, bool >::type checkLabelSize() const noexcept
Definition: IOstream.H:300
wallBoundedParticle.H
Foam::tetrahedron::c
const Point & c() const
Definition: tetrahedronI.H:90
Foam::Istream::endRawRead
virtual bool endRawRead()=0
End of low-level raw binary read.
Foam::wallBoundedParticle::crossEdgeConnectedFace
void crossEdgeConnectedFace(const label &celli, label &tetFacei, label &tetPti, const edge &e)
Replacement for particle::crossEdgeConnectedFace that avoids bombing.
Definition: wallBoundedParticle.C:83
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::wallBoundedParticle
Particle class that tracks on triangles of boundary faces. Use trackToEdge similar to trackToFace on ...
Definition: wallBoundedParticle.H:63
Foam::particle::mesh
const polyMesh & mesh() const
Return the mesh database.
Definition: particleI.H:137
Foam::IOstream::checkScalarSize
std::enable_if< std::is_floating_point< T >::value, bool >::type checkScalarSize() const noexcept
Definition: IOstream.H:309
Foam::IOstream::check
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:58
Foam::FatalError
error FatalError
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::wallBoundedParticle::isTriAlongTrack
bool isTriAlongTrack(const vector &n, const point &endPosition) const
Is current triangle in the track direction.
Definition: wallBoundedParticle.C:365
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::readFields
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const wordHashSet &selectedFields, LIFOStack< regIOobject * > &storedObjects)
Read the selected GeometricFields of the templated type.
Definition: ReadFieldsTemplates.C:312
Foam::tetrahedron::a
const Point & a() const
Return vertices.
Definition: tetrahedronI.H:76
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1094
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::Istream::beginRawRead
virtual bool beginRawRead()=0
Start of low-level raw binary read.
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::triFace
A triangular face using a FixedList of labels corresponding to mesh vertices.
Definition: triFace.H:69
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::List< face >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::token::SPACE
Space [isspace].
Definition: token.H:125
Foam::particle
Base particle class.
Definition: particle.H:76
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::wallBoundedParticle::currentEdge
edge currentEdge() const
Construct current edge.
Definition: wallBoundedParticle.C:41
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::readRawLabel
label readRawLabel(Istream &is)
Read raw label from binary stream.
Definition: label.C:46
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::tetrahedron::b
const Point & b() const
Definition: tetrahedronI.H:83
Foam::FixedList::found
bool found(const T &val, label pos=0) const
True if the value if found in the list.
Definition: FixedListI.H:332
Foam::wallBoundedParticle::trackFaceTri
scalar trackFaceTri(const vector &n, const vector &endPosition, label &)
Track through single triangle.
Definition: wallBoundedParticle.C:286
Foam::neg
dimensionedScalar neg(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:199
Foam::cell
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:54
pFaces
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::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].reset(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
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::nComponents
static constexpr direction nComponents
Number of components in this vector space.
Definition: VectorSpace.H:101
Foam::wallBoundedParticle::diagEdge_
label diagEdge_
Particle is on diagonal edge:
Definition: wallBoundedParticle.H:115
Foam::tetrahedron
A tetrahedron primitive.
Definition: tetrahedron.H:63
Foam::Istream::read
virtual Istream & read(token &)=0
Return next token from stream.
Foam::polyMesh::tetBasePtIs
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:892