Go to the documentation of this file.
39 template<
class TrackData>
47 faceI_ = patchFace(patchI, faceI_);
51 template<
class TrackData>
59 refCast<const coupledPolyPatch>(mesh_.boundaryMesh()[patchI]);
75 transformProperties(
T);
85 transformProperties(-
s);
88 tetFaceI_ = faceI_ + ppp.
start();
111 tetPtI_ = mesh_.faces()[tetFaceI_].size() - 1 - tetPtI_;
114 if (stepFraction_ > (1.0 - SMALL))
121 faceI_ += ppp.
start();
128 template<
class CloudType>
141 c.checkFieldIOobject(
c, origProcId);
150 p.origProc_ = origProcId[i];
158 template<
class CloudType>
177 origProc[i] = iter().origProc_;
178 origId[i] = iter().origId_;
187 template<
class TrackData>
193 while (!onBoundary() && stepFraction_ < 1.0 - SMALL)
195 stepFraction_ += trackToFace(endPosition, td)*(1.0 - stepFraction_);
202 template<
class TrackData>
205 const vector& endPosition,
209 typedef typename TrackData::cloudType cloudType;
210 typedef typename cloudType::particleType particleType;
232 scalar trackFraction = 0.0;
280 scalar lambdaMin = VGREAT;
293 scalar lambdaDistanceTolerance =
294 lambdaDistanceToleranceCoeff*mesh_.cellVolumes()[cellI_];
306 bool own = (mesh_.faceOwner()[tetFaceI_] == cellI_);
308 label tetBasePtI = mesh_.tetBasePtIs()[tetFaceI_];
310 label basePtI =
f[tetBasePtI];
312 label facePtI = (tetPtI_ + tetBasePtI) %
f.
size();
313 label otherFacePtI =
f.fcIndex(facePtI);
321 fPtBI = otherFacePtI;
325 fPtAI = otherFacePtI;
337 if (lambdaMin < SMALL)
343 Pout<<
"tracking rescue using tetCentre from " << position();
346 position_ += trackingCorrectionTol*(tet.
centre() - position_);
350 Pout<<
" to " << position() <<
" due to "
354 cloud.trackingRescue();
356 return trackFraction;
359 if (triI != -1 && mesh_.moving())
364 return trackFraction;
369 tetAreas[0] = tet.
Sa();
370 tetAreas[1] = tet.
Sb();
371 tetAreas[2] = tet.
Sc();
372 tetAreas[3] = tet.
Sd();
376 tetPlaneBasePtIs[0] = basePtI;
377 tetPlaneBasePtIs[1] =
f[fPtAI];
378 tetPlaneBasePtIs[2] = basePtI;
379 tetPlaneBasePtIs[3] = basePtI;
388 lambdaDistanceTolerance
410 if (tris.empty() && faceI_ < 0)
412 position_ = endPosition;
424 scalar lam = tetLambda
430 tetPlaneBasePtIs[tI],
434 lambdaDistanceTolerance
504 if (lambdaMin > SMALL)
506 if (lambdaMin <= 1.0)
508 trackFraction += lambdaMin*(1 - trackFraction);
509 position_ += lambdaMin*(endPosition - position_);
513 position_ = endPosition;
525 }
while (faceI_ < 0);
527 particleType&
p =
static_cast<particleType&
>(*this);
530 if (internalFace(faceI_))
539 if (cellI_ == mesh_.faceOwner()[faceI_])
541 cellI_ = mesh_.faceNeighbour()[faceI_];
543 else if (cellI_ == mesh_.faceNeighbour()[faceI_])
545 cellI_ = mesh_.faceOwner()[faceI_];
555 label origFaceI = faceI_;
556 label patchI = patch(faceI_);
565 mesh_.boundaryMesh()[patchI],
574 if (faceI_ != origFaceI)
576 patchI = patch(faceI_);
581 if (isA<wedgePolyPatch>(patch))
588 else if (isA<symmetryPlanePolyPatch>(patch))
590 p.hitSymmetryPlanePatch
595 else if (isA<symmetryPolyPatch>(patch))
602 else if (isA<cyclicPolyPatch>(patch))
609 else if (isA<cyclicAMIPolyPatch>(patch))
615 endPosition - position_
618 else if (isA<processorPolyPatch>(patch))
625 else if (isA<wallPolyPatch>(patch))
634 p.hitPatch(patch, td);
639 if (lambdaMin < SMALL)
648 Pout<<
"tracking rescue for lambdaMin:" << lambdaMin
649 <<
"from " << position();
652 position_ += trackingCorrectionTol*(tet.
centre() - position_);
656 cloud.hasWallImpactDistance()
657 && !internalFace(faceHitTetIs.
face())
658 &&
cloud.cellHasWallFaces()[faceHitTetIs.
cell()]
665 label patchI =
patches.patchID()[fI - mesh_.nInternalFaces()];
667 if (isA<wallPolyPatch>(
patches[patchI]))
687 const scalar r =
p.wallImpactDistance(nHat);
695 trackingCorrectionTol
697 (wallTet.
centre() - (position_ + r*nHat))
698 - (nHat & (tet.
centre() - position_))*nHat
705 Pout<<
" to " << position() <<
endl;
708 cloud.trackingRescue();
711 return trackFraction;
715 template<
class CloudType>
727 if (!(
cloud.hasWallImpactDistance() &&
cloud.cellHasWallFaces()[cellI_]))
732 particleType&
p =
static_cast<particleType&
>(*this);
736 const Foam::cell& thisCell = mesh_.cells()[cellI_];
738 scalar lambdaDistanceTolerance =
739 lambdaDistanceToleranceCoeff*mesh_.cellVolumes()[cellI_];
745 label fI = thisCell[cFI];
747 if (internalFace(fI))
752 label patchI =
patches.patchID()[fI - mesh_.nInternalFaces()];
754 if (isA<wallPolyPatch>(
patches[patchI]))
777 scalar r =
p.wallImpactDistance(nHat);
779 vector toPlusRNHat = to + r*nHat;
783 scalar tetClambda = tetLambda
793 lambdaDistanceTolerance
796 if ((tetClambda <= 0.0) || (tetClambda >= 1.0))
806 vector fromPlusRNHat = from + r*nHat;
820 lambdaDistanceTolerance
866 scalar m = stepFraction_ + lam - (stepFraction_*lam);
875 point tPtA = tri00.a() + m*(tri.
a() - tri00.a());
876 point tPtB = tri00.b() + m*(tri.
b() - tri00.b());
877 point tPtC = tri00.c() + m*(tri.
c() - tri00.c());
885 hitInfo = t.intersection
887 fromPlusRNHat + m*(to - from),
916 closestTetIs = tetIs;
925 template<
class TrackData>
930 template<
class TrackData>
944 template<
class TrackData>
952 <<
"Hitting a wedge patch should not be possible."
958 transformProperties(
I - 2.0*nf*nf);
962 template<
class TrackData>
972 transformProperties(
I - 2.0*nf*nf);
976 template<
class TrackData>
986 transformProperties(
I - 2.0*nf*nf);
990 template<
class TrackData>
999 cellI_ = mesh_.faceOwner()[faceI_];
1004 tetPtI_ = mesh_.faces()[tetFaceI_].size() - 1 - tetPtI_;
1021 : receiveCpp.
forwardT()[patchFacei]
1023 transformProperties(
T);
1033 transformProperties(-
s);
1038 template<
class TrackData>
1057 <<
"Particle lost across " << cyclicAMIPolyPatch::typeName
1058 <<
" patches " << cpp.
name() <<
" and " << receiveCpp.
name()
1063 faceI_ = patchFaceI + receiveCpp.
start();
1065 cellI_ = mesh_.faceOwner()[faceI_];
1070 tetPtI_ = mesh_.faces()[tetFaceI_].size() - 1 - tetPtI_;
1081 : receiveCpp.
forwardT()[patchFaceI]
1083 transformProperties(
T);
1093 transformProperties(-
s);
1098 template<
class TrackData>
1103 template<
class TrackData>
1113 template<
class TrackData>
Templated 3D tensor derived from VectorSpace adding construction from 9 components,...
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
virtual bool write() const
bool hitPatch(const polyPatch &, TrackData &td, const label patchI, const scalar trackFraction, const tetIndices &tetIs)
Overridable function to handle the particle hitting a.
label pointFace(const label faceI, const vector &n, point &p) const
Return face index on neighbour patch which shares point p.
virtual const vectorField & separation() const
If the planes are separated the separation vector.
tetPointRef tet(const polyMesh &mesh) const
Return the geometry corresponding to this tet from the.
bool hit() const
Is there a hit.
label origId() const
Return const access to the particle id on originating processor.
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
A primitive field of type <T> with automated input and output.
void hitWedgePatch(const wedgePolyPatch &, TrackData &td)
Overridable function to handle the particle hitting a wedgePatch.
Wedge front and back plane patch.
void hitFace(TrackData &td)
Overridable function to handle the particle hitting a face.
#define forAll(list, i)
Loop across all elements in list.
label transformGlobalFace(const label facei) const
This class describes the interaction of a face and a point. It carries the info of a successful hit a...
scalar trackToFace(const vector &endPosition, TrackData &td)
Track particle to a given position and returns 1.0 if the.
const cyclicPolyPatch & neighbPatch() const
virtual const tensorField & forwardT() const
Return face transformation tensor.
virtual bool write() const
Write using setting from DB.
triPointRef oldFaceTri(const polyMesh &mesh) const
Return the geometry corresponding to the tri on the.
Ostream & endl(Ostream &os)
Add newline and flush stream.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
dimensioned< scalar > mag(const dimensioned< Type > &)
label tetPt() const
Return the characterising tetPtI.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
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]
virtual bool parallel() const
Are the cyclic planes parallel.
bool headerOk()
Read and check header info.
A triangle primitive used to calculate face normals and swept volumes.
virtual bool separated() const
Are the planes separated.
void hitSymmetryPatch(const symmetryPolyPatch &, TrackData &td)
Overridable function to handle the particle hitting a.
const Point & c() const
Return third vertex.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Pre-declare SubField and related Field type.
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
vector normal() const
Return vector normal.
triPointRef faceTri(const polyMesh &mesh) const
Return the geometry corresponding to the tri on the.
A patch is a list of labels that address the faces in the global face list.
void hitSymmetryPlanePatch(const symmetryPlanePolyPatch &, TrackData &td)
Overridable function to handle the particle hitting a.
const Point & a() const
Return first vertex.
label face() const
Return the face.
void hitCyclicPatch(const cyclicPolyPatch &, TrackData &td)
Overridable function to handle the particle hitting a cyclicPatch.
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Symmetry patch for non-planar or multi-plane patches.
Neighbour processor patch.
Helper IO class to read and write particle positions.
Templated base class for dsmc cloud.
static const sphericalTensor I(1)
label faceBasePt() const
Return the face base point.
virtual const cyclicAMIPolyPatch & neighbPatch() const
Return a reference to the neighbour patch.
const Point & b() const
Return second vertex.
virtual void transformPosition(pointField &l) const
Transform a patch-based position from other side to this side.
ParticleType particleType
errorManip< error > abort(error &err)
const labelUList & faceCells() const
Return face-cell addressing.
void correctAfterParallelTransfer(const label patchI, TrackData &td)
Convert processor patch addressing to the global equivalents.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().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))
label start() const
Return start label of this patch in the polyMesh face list.
label cell() const
Return the cell.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Storage and named access for the indices of a tet which is part of the decomposition of a cell.
A cloud is a collection of lagrangian particles.
void hitWallPatch(const wallPolyPatch &, TrackData &td, const tetIndices &tetIs)
Overridable function to handle the particle hitting a wallPatch.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
vector Sa() const
Return face normal.
label whichFace(const label l) const
Return label of face in patch from global face label.
prefixOSstream Pout(cout, "Pout")
void hitCyclicAMIPatch(const cyclicAMIPolyPatch &, TrackData &td, const vector &direction)
Overridable function to handle the particle hitting a cyclicAMIPatch.
virtual void transformPosition(pointField &) const =0
Transform a patch-based position from other side to this side.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void hitWallFaces(const CloudType &td, const vector &from, const vector &to, scalar &lambdaMin, tetIndices &closestTetIs)
A 1D vector of objects of type <T> with a fixed size <Size>.
Point centre() const
Return centre (centroid)
label track(const vector &endPosition, TrackData &td)
Track particle to end of trajectory.
pointHit intersection(const point &p, const vector &q, const intersection::algorithm alg, const scalar tol=0.0) const
Fast intersection with a ray.
const dimensionedScalar c
Speed of light in a vacuum.
static void readFields(CloudType &c)
Read the fields associated with the owner cloud.
void hitProcessorPatch(const processorPolyPatch &, TrackData &td)
Overridable function to handle the particle hitting a.
A face is a list of labels corresponding to mesh vertices.
void size(const label)
Override size to be inconsistent with allocated storage.
void prepareForParallelTransfer(const label patchI, TrackData &td)
Convert global addressing to the processor patch.
static void writeFields(const CloudType &c)
Write the fields associated with the owner cloud.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
const word & name() const
Return name.
A cell is defined as a list of faces with extra functionality.
dimensionedScalar lambda(laminarTransport.lookup("lambda"))
cloud(const cloud &)
Disallow default bitwise copy construct.
A normal distribution model.
static List< tetIndices > faceTetIndices(const polyMesh &mesh, label fI, label cI)
Return the tet decomposition of the given face, with.
Cyclic patch for Arbitrary Mesh Interface (AMI)