33template<
class TrackCloudType>
36 TrackCloudType&
cloud,
38 const scalar trackFraction
41 typename TrackCloudType::particleType&
p =
42 static_cast<typename TrackCloudType::particleType&
>(*this);
43 typename TrackCloudType::particleType::trackingData& ttd =
44 static_cast<typename TrackCloudType::particleType::trackingData&
>(
td);
48 label origFacei =
face();
49 label patchi =
patch();
53 if (
face() != origFacei)
62 p.hitProcessorPatch(
cloud, ttd);
66 p.hitWallPatch(
cloud, ttd);
70 td.keepParticle =
false;
78template<
class TrackCloudType>
81 TrackCloudType& cloud,
107 scalar trackFraction = 0.0;
109 if (!
td.isWallPatch_[tetFace()])
113 const edge meshEdge(currentEdge());
117 if (
mesh().isInternalFace(tetFace()))
128 tetIndices nbrTi(nbrCelli, tetFace(), tetPt());
130 const bool posVol = (nbrTi.tet(
mesh()).
mag() > 0);
131 const vector path(endPosition - localPosition_);
133 if (posVol == ((nbrTi.faceTri(
mesh()).areaNormal() &
path) < 0))
138 this->cell() = nbrCelli;
139 patchInteraction(cloud,
td, trackFraction);
145 crossEdgeConnectedFace(meshEdge);
146 patchInteraction(cloud,
td, trackFraction);
153 crossEdgeConnectedFace(meshEdge);
154 patchInteraction(
cloud,
td, trackFraction);
162 if (
mesh().isInternalFace(tetFace()))
165 <<
"Can only track on boundary faces."
166 <<
" Face:" << tetFace()
171 const triFace tri(currentTetIndices().faceTriIs(
mesh(),
false));
174 point projectedEndPosition = endPosition;
176 const bool posVol = (currentTetIndices().tet(
mesh()).mag() > 0);
181 projectedEndPosition =
182 localPosition_ - (endPosition - localPosition_);
186 const vector d(endPosition - localPosition_);
187 const scalar magD(
mag(d));
188 if (magD > ROOTVSMALL)
193 meshBb.inflate(ROOTSMALL);
196 projectedEndPosition = localPosition_ -
meshBb.mag()*d/magD;
201 bool ok =
meshBb.intersects
203 projectedEndPosition,
204 localPosition_ - projectedEndPosition,
205 projectedEndPosition,
213 projectedEndPosition = intPt;
221 projectedEndPosition -= ((projectedEndPosition - basePt)&
n)*
n;
225 bool doTrack =
false;
226 if (meshEdgeStart_ == -1 && diagEdge_ == -1)
235 doTrack = isTriAlongTrack(
n, projectedEndPosition);
243 trackFraction = trackFaceTri(
n, projectedEndPosition, triEdgei);
251 return trackFraction;
266 const Foam::face&
f =
mesh().
faces()[ti.face()];
267 const label fp0 = trif[0];
275 meshEdgeStart_ = fp0;
277 crossEdgeConnectedFace(currentEdge());
278 patchInteraction(
cloud,
td, trackFraction);
290 crossEdgeConnectedFace(currentEdge());
291 patchInteraction(
cloud,
td, trackFraction);
296 diagEdge_ = trif[1] - fp0;
299 diagEdge_ +=
f.
size();
306 else if (triEdgei == 1)
310 meshEdgeStart_ = trif[1];
312 crossEdgeConnectedFace(currentEdge());
313 patchInteraction(
cloud,
td, trackFraction);
321 meshEdgeStart_ = trif[2];
323 crossEdgeConnectedFace(currentEdge());
324 patchInteraction(
cloud,
td, trackFraction);
333 meshEdgeStart_ = fp0;
335 crossEdgeConnectedFace(currentEdge());
336 patchInteraction(
cloud,
td, trackFraction);
342 diagEdge_ = trif[2] - fp0;
345 diagEdge_ +=
f.
size();
357 if (meshEdgeStart_ != -1)
360 crossEdgeConnectedFace(currentEdge());
362 patchInteraction(
cloud,
td, trackFraction);
376 return trackFraction;
380template<
class TrackCloudType>
383 TrackCloudType&
cloud,
388 td.switchProcessor =
true;
397 if (meshEdgeStart_ != -1)
399 meshEdgeStart_ =
f.size() - meshEdgeStart_-1;
409template<
class TrackCloudType>
418template<
class TrackCloudType>
428 IOField<point> localPosition
432 c.checkFieldIOobject(c, localPosition);
434 IOField<label> meshEdgeStart
438 c.checkFieldIOobject(c, meshEdgeStart);
440 IOField<label> diagEdge
444 c.checkFieldIOobject(c, diagEdge);
447 for (wallBoundedParticle&
p : c)
449 p.localPosition_ = localPosition[i];
450 p.meshEdgeStart_ = meshEdgeStart[i];
451 p.diagEdge_ = diagEdge[i];
458template<
class TrackCloudType>
463 const label np = c.size();
465 IOField<point> localPosition
470 IOField<label> meshEdgeStart
475 IOField<label> diagEdge
482 for (
const wallBoundedParticle&
p : c)
484 localPosition[i] =
p.localPosition_;
485 meshEdgeStart[i] =
p.meshEdgeStart_;
486 diagEdge[i] =
p.diagEdge_;
491 localPosition.write();
492 meshEdgeStart.write();
A primitive field of type <T> with automated input and output.
@ NO_READ
Nothing to be read.
@ MUST_READ
Reading required.
label rcIndex(const label i) const noexcept
The reverse circular index. The previous index in the list which returns to the last at the beginning...
void size(const label n)
Older name for setAddressableSize.
label fcIndex(const label i) const noexcept
The forward circular index. The next index in the list which returns to the first at the end of the l...
A cloud is a registry collection of lagrangian particles.
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
A face is a list of labels corresponding to mesh vertices.
tetIndices currentTetIndices() const noexcept
Return indices of the current tet that the particle occupies.
label face() const noexcept
Return current face particle is on otherwise -1.
label tetPt() const noexcept
Return current tet face particle is in.
static void readFields(TrackCloudType &c)
Read the fields associated with the owner cloud.
const polyMesh & mesh() const noexcept
Return the mesh database.
label tetFace() const noexcept
Return current tet face particle is in.
label patch() const
Return the index of patch that the particle is on.
label cell() const noexcept
Return current cell particle is in.
static void writeFields(const TrackCloudType &c)
Write the fields associated with the owner cloud.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
virtual const faceList & faces() const
Return raw faces.
virtual const labelList & faceOwner() const
Return face owner.
virtual const labelList & faceNeighbour() const
Return face neighbour.
virtual const pointField & points() const
Return raw points.
A patch is a list of labels that address the faces in the global face list.
const vectorField & faceCentres() const
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
Storage and named access for the indices of a tet which is part of the decomposition of a cell.
label face() const noexcept
Return the face index.
triFace triIs(const polyMesh &mesh, const bool warn=true) const
Local indices corresponding to the tri on the face for this tet. The normal of the tri points out of ...
tetPointRef tet(const polyMesh &mesh) const
The tet geometry for this tet, where point0 is the cell centre.
triPointRef faceTri(const polyMesh &mesh) const
The triangle geometry for the face for this tet. The normal of the tri points out of the cell.
Standard boundBox with extra functionality for use in octree.
A triangular face using a FixedList of labels corresponding to mesh vertices.
vector unitNormal(const UList< point > &points) const
The unit normal.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
Class used to pass tracking data to the trackToFace function.
label meshEdgeStart_
Particle is on mesh edge:
bool isTriAlongTrack(const vector &n, const point &endPosition) const
Is current triangle in the track direction.
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.
label meshEdgeStart() const noexcept
The mesh edge label or -1.
void patchInteraction(TrackCloudType &cloud, trackingData &td, const scalar trackFraction)
Do all patch interaction.
edge currentEdge() const
Construct current edge.
static void writeFields(const CloudType &)
Write.
void hitProcessorPatch(TrackCloudType &cloud, trackingData &td)
Overridable function to handle the particle hitting a processorPatch.
scalar trackToEdge(TrackCloudType &cloud, trackingData &td, const vector &endPosition)
Equivalent of trackToFace.
label diagEdge_
Particle is on diagonal edge:
scalar trackFaceTri(const vector &n, const vector &endPosition, label &)
Track through single triangle.
void crossEdgeConnectedFace(const label &celli, label &tetFacei, label &tetPti, const edge &e)
Replacement for particle::crossEdgeConnectedFace that avoids bombing.
label diagEdge() const noexcept
The diagonal edge label or -1.
void hitWallPatch(TrackCloudType &cloud, trackingData &td)
Overridable function to handle the particle hitting a wallPatch.
point localPosition_
Particle position is updated locally as opposed to via track.
void crossDiagonalEdge()
Cross diagonal edge into different triangle on same face,cell.
static void readFields(CloudType &)
Read.
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
wallPoints::trackData td(isBlockedFace, regionToBlockSize)
Namespace for bounding specifications. At the moment, mostly for tables.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
vector point
Point is a vector.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
List< treeBoundBox > meshBb(1, treeBoundBox(coarseMesh.points()).extend(rndGen, 1e-3))