33 template<
class ParcelType>
39 template<
class ParcelType>
40 template<
class TrackData>
50 rhoc_ = td.rhoInterp().interpolate(this->position(), tetIs);
52 if (rhoc_ < td.cloud().constProps().rhoMin())
57 <<
"Limiting observed density in cell " << celli <<
" to " 58 << td.cloud().constProps().rhoMin() <<
nl <<
endl;
61 rhoc_ = td.cloud().constProps().rhoMin();
64 Uc_ = td.UInterp().interpolate(this->position(), tetIs);
66 muc_ = td.muInterp().interpolate(this->position(), tetIs);
69 Uc_ = td.cloud().dispersion().update
81 template<
class ParcelType>
82 template<
class TrackData>
90 Uc_ += td.cloud().UTrans()[celli]/massCell(celli);
94 template<
class ParcelType>
95 template<
class TrackData>
105 const scalar np0 = nParticle_;
106 const scalar mass0 = mass();
109 const scalar Re = this->
Re(U_, d_, rhoc_, muc_);
129 this->U_ = calcVelocity(td, dt, celli, Re, muc_, mass0, Su, dUTrans, Spu);
134 if (td.cloud().solution().coupled())
137 td.cloud().UTrans()[celli] += np0*dUTrans;
140 td.cloud().UCoeff()[celli] += np0*Spu;
145 template<
class ParcelType>
146 template<
class TrackData>
160 typedef typename TrackData::cloudType cloudType;
161 typedef typename cloudType::parcelType parcelType;
162 typedef typename cloudType::forceType forceType;
164 const forceType& forces = td.cloud().forces();
167 const parcelType& p =
static_cast<const parcelType&
>(*this);
168 const forceSuSp Fcp = forces.calcCoupled(p, dt, mass, Re, mu);
169 const forceSuSp Fncp = forces.calcNonCoupled(p, dt, mass, Re, mu);
171 const scalar massEff = forces.massEff(p, mass);
178 const vector abp = (Feff.
Sp()*Uc_ + (Feff.
Su() +
Su))/massEff;
179 const scalar bp = Feff.
Sp()/massEff;
184 td.cloud().UIntegrator().integrate(U_, dt, abp, bp);
189 dUTrans += dt*(Feff.
Sp()*(Ures.
average() - Uc_) - Fcp.
Su());
192 const polyMesh& mesh = td.cloud().pMesh();
202 template<
class ParcelType>
225 template<
class ParcelType>
251 template<
class ParcelType>
252 template<
class TrackData>
256 const scalar trackTime
259 typename TrackData::cloudType::parcelType& p =
260 static_cast<typename TrackData::cloudType::parcelType&
>(*this);
262 td.switchProcessor =
false;
263 td.keepParticle =
true;
265 const polyMesh& mesh = td.cloud().pMesh();
267 const scalarField& cellLengthScale = td.cloud().cellLengthScale();
268 const scalar
maxCo = td.cloud().solution().maxCo();
270 scalar tEnd = (1.0 - p.stepFraction())*trackTime;
271 scalar dtMax = trackTime;
272 if (td.cloud().solution().transient())
277 bool tracking =
true;
278 label nTrackingStalled = 0;
280 while (td.keepParticle && !td.switchProcessor && tEnd > ROOTVSMALL)
285 const point start(p.position());
288 scalar dt =
min(dtMax, tEnd);
291 const label celli = p.cell();
293 const scalar magU =
mag(U_);
294 if (p.active() && tracking && (magU > ROOTVSMALL))
296 const scalar d = dt*magU;
297 const scalar dCorr =
min(d, maxCo*cellLengthScale[celli]);
300 *p.trackToFace(p.position() + dCorr*U_/magU, td);
305 scalar newStepFraction = 1.0 - tEnd/trackTime;
311 mag(p.stepFraction() - newStepFraction)
312 < particle::minStepFractionTol
317 if (nTrackingStalled > maxTrackAttempts)
324 nTrackingStalled = 0;
328 p.stepFraction() = newStepFraction;
330 bool calcParcel =
true;
331 if (!tracking && td.cloud().solution().steadyState())
337 if ((dt > ROOTVSMALL) && calcParcel)
340 p.setCellValues(td, dt, celli);
342 if (td.cloud().solution().cellValueSourceCorrection())
344 p.cellValueSourceCorrection(td, dt, celli);
347 p.calc(td, dt, celli);
350 if (p.onBoundary() && td.keepParticle)
352 if (isA<processorPolyPatch>(pbMesh[p.patch(p.face())]))
354 td.switchProcessor =
true;
360 td.cloud().functions().postMove(p, celli, dt, start, td.keepParticle);
363 return td.keepParticle;
367 template<
class ParcelType>
368 template<
class TrackData>
371 typename TrackData::cloudType::parcelType& p =
372 static_cast<typename TrackData::cloudType::parcelType&
>(*this);
374 td.cloud().functions().postFace(p, p.face(), td.keepParticle);
378 template<
class ParcelType>
383 template<
class ParcelType>
384 template<
class TrackData>
390 const scalar trackFraction,
394 typename TrackData::cloudType::parcelType& p =
395 static_cast<typename TrackData::cloudType::parcelType&
>(*this);
398 td.cloud().functions().postPatch
408 if (td.cloud().surfaceFilm().transferParcel(p, pp, td.keepParticle))
416 return td.cloud().patchInteraction().correct
428 template<
class ParcelType>
429 template<
class TrackData>
436 td.switchProcessor =
true;
440 template<
class ParcelType>
441 template<
class TrackData>
453 template<
class ParcelType>
454 template<
class TrackData>
461 td.keepParticle =
false;
465 template<
class ParcelType>
468 ParcelType::transformProperties(T);
474 template<
class ParcelType>
480 ParcelType::transformProperties(separation);
484 template<
class ParcelType>
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
bool hitPatch(const polyPatch &p, TrackData &td, const label patchi, const scalar trackFraction, const tetIndices &tetIs)
Overridable function to handle the particle hitting a patch.
Kinematic parcel class with rotational motion (as spherical particles only) and one/two-way coupling ...
Helper class to supply results of integration.
scalar tTurb_
Time spent in turbulent eddy [s].
Ostream & endl(Ostream &os)
Add newline and flush stream.
KinematicParcel(const polyMesh &mesh, const vector &position, const label celli, const label tetFacei, const label tetPtI)
Construct from owner, position, and cloud owner.
const vector & Su() const
Return const access to the explicit contribution [kg.m/s2].
virtual scalar wallImpactDistance(const vector &n) const
The nearest distance to a wall that the particle can be.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
vector Uc_
Velocity [m/s].
Neighbour processor patch.
Type average() const
Return const access to the average.
Helper container for force Su and Sp terms.
bool move(TrackData &td, const scalar trackTime)
Move the parcel.
scalar dTarget_
Target diameter [m].
Type value() const
Return const access to the value.
scalar rho_
Density [kg/m3].
virtual void transformProperties(const tensor &T)
Transform the physical properties of the particle.
scalar muc_
Viscosity [Pa.s].
void hitFace(int &td)
Overridable function to handle the particle hitting a face.
bool active_
Active flag - tracking inactive when active = false.
label typeId_
Parcel type id.
vector UTurb_
Turbulent velocity fluctuation [m/s].
Storage and named access for the indices of a tet which is part of the decomposition of a cell...
const vector calcVelocity(TrackData &td, const scalar dt, const label celli, const scalar Re, const scalar mu, const scalar mass, const vector &Su, vector &dUTrans, scalar &Spu) const
Calculate new particle velocity.
scalar nParticle_
Number of particles in Parcel.
void cellValueSourceCorrection(TrackData &td, const scalar dt, const label celli)
Correct cell values using latest transfer information.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
void calc(TrackData &td, const scalar dt, const label celli)
Update parcel properties over the time interval.
scalar rhoc_
Density [kg/m3].
vector U_
Velocity of Parcel [m/s].
#define WarningInFunction
Report a warning using Foam::Warning.
void setCellValues(TrackData &td, const scalar dt, const label celli)
Set cell values.
void hitWallPatch(const wallPolyPatch &, TrackData &td, const tetIndices &)
Overridable function to handle the particle hitting a wallPatch.
dimensioned< scalar > mag(const dimensioned< Type > &)
Mesh consisting of general polyhedral cells.
void hitProcessorPatch(const processorPolyPatch &, TrackData &td)
Overridable function to handle the particle hitting a.
A patch is a list of labels that address the faces in the global face list.
tmp< GeometricField< Type, fvPatchField, volMesh > > Su(const GeometricField< Type, fvPatchField, volMesh > &su, const GeometricField< Type, fvPatchField, volMesh > &vf)
scalarField Re(const UList< complex > &cf)
scalar Sp() const
Return const access to the implicit coefficient [kg/s].
dimensionSet transform(const dimensionSet &)