37template<
class ParcelType>
38Foam::label Foam::KinematicParcel<ParcelType>::maxTrackAttempts = 1;
43template<
class ParcelType>
44template<
class TrackCloudType>
47 TrackCloudType&
cloud,
55 if (
td.rhoc() <
cloud.constProps().rhoMin())
60 <<
"Limiting observed density in cell " << this->
cell()
61 <<
" to " <<
cloud.constProps().rhoMin() <<
nl <<
endl;
64 td.rhoc() =
cloud.constProps().rhoMin();
73template<
class ParcelType>
74template<
class TrackCloudType>
77 TrackCloudType&
cloud,
82 td.Uc() =
cloud.dispersion().update
94template<
class ParcelType>
95template<
class TrackCloudType>
98 TrackCloudType&
cloud,
103 typename TrackCloudType::parcelType&
p =
104 static_cast<typename TrackCloudType::parcelType&
>(*this);
106 this->UCorrect_ =
Zero;
109 cloud.dampingModel().velocityCorrection(
p, dt);
112 cloud.packingModel().velocityCorrection(
p, dt);
116template<
class ParcelType>
117template<
class TrackCloudType>
120 TrackCloudType&
cloud,
129template<
class ParcelType>
130template<
class TrackCloudType>
133 TrackCloudType&
cloud,
140 const scalar np0 = nParticle_;
141 const scalar mass0 = mass();
144 const scalar
Re = this->Re(
td);
165 calcVelocity(
cloud,
td, dt,
Re,
td.muc(), mass0,
Su, dUTrans, Spu);
167 this->U_ += this->UCorrect_;
171 if (
cloud.solution().coupled())
174 cloud.UTrans()[this->
cell()] += np0*dUTrans;
182template<
class ParcelType>
183template<
class TrackCloudType>
186 TrackCloudType& cloud,
197 const typename TrackCloudType::parcelType&
p =
198 static_cast<const typename TrackCloudType::parcelType&
>(*this);
199 typename TrackCloudType::parcelType::trackingData& ttd =
200 static_cast<typename TrackCloudType::parcelType::trackingData&
>(
td);
202 const typename TrackCloudType::forceType& forces = cloud.forces();
205 const forceSuSp Fcp = forces.calcCoupled(
p, ttd, dt, mass, Re,
mu);
206 const forceSuSp Fncp = forces.calcNonCoupled(
p, ttd, dt, mass, Re,
mu);
207 const scalar massEff = forces.massEff(
p, ttd, mass);
233 const vector acp = (Fcp.Sp()*
td.Uc() + Fcp.Su())/massEff;
234 const vector ancp = (Fncp.Su() +
Su)/massEff;
235 const scalar bcp = Fcp.Sp()/massEff;
238 const vector deltaU = cloud.UIntegrator().delta(U_, dt, acp + ancp, bcp);
239 const vector deltaUncp = ancp*dt;
240 const vector deltaUcp = deltaU - deltaUncp;
243 vector Unew = U_ + deltaU;
245 dUTrans -= massEff*deltaUcp;
250 const polyMesh&
mesh = cloud.pMesh();
251 meshTools::constrainDirection(
mesh,
mesh.solutionD(), Unew);
252 meshTools::constrainDirection(
mesh,
mesh.solutionD(), dUTrans);
260template<
class ParcelType>
263 const KinematicParcel<ParcelType>&
p
269 nParticle_(
p.nParticle_),
271 dTarget_(
p.dTarget_),
277 UCorrect_(
p.UCorrect_)
281template<
class ParcelType>
291 nParticle_(
p.nParticle_),
293 dTarget_(
p.dTarget_),
299 UCorrect_(
p.UCorrect_)
305template<
class ParcelType>
306template<
class TrackCloudType>
309 TrackCloudType&
cloud,
311 const scalar trackTime
314 auto&
p =
static_cast<typename TrackCloudType::parcelType&
>(*this);
316 static_cast<typename TrackCloudType::parcelType::trackingData&
>(
td);
318 ttd.switchProcessor =
false;
319 ttd.keepParticle =
true;
325 while (ttd.keepParticle && !ttd.switchProcessor &&
p.stepFraction() < 1)
328 const point start =
p.position();
329 const scalar sfrac =
p.stepFraction();
335 const scalar l = cellLengthScale[
p.cell()];
338 const vector d =
p.deviationFromMeshCentre();
343 scalar
f = 1 -
p.stepFraction();
349 p.trackToFace(
f*
s - d,
f);
358 p.stepFraction() +=
f;
361 const scalar dt = (
p.stepFraction() - sfrac)*trackTime;
367 p.setCellValues(
cloud, ttd);
369 p.calcDispersion(
cloud, ttd, dt);
371 if (
solution.cellValueSourceCorrection())
373 p.cellValueSourceCorrection(
cloud, ttd, dt);
376 p.calcUCorrection(
cloud, ttd, dt);
383 if (
p.active() &&
p.onFace())
385 ttd.keepParticle =
cloud.functions().postFace(
p, ttd);
388 ttd.keepParticle =
cloud.functions().postMove(
p, dt, start, ttd);
390 if (
p.active() &&
p.onFace() && ttd.keepParticle)
396 return ttd.keepParticle;
400template<
class ParcelType>
401template<
class TrackCloudType>
404 TrackCloudType&
cloud,
408 auto&
p =
static_cast<typename TrackCloudType::parcelType&
>(*this);
410 static_cast<typename TrackCloudType::parcelType::trackingData&
>(
td);
415 td.keepParticle =
cloud.functions().postPatch(
p,
pp, ttd);
422 else if (cloud.surfaceFilm().transferParcel(
p,
pp,
td.keepParticle))
435 cloud.patchInteraction().addToEscapedParcels(nParticle_*mass());
439 return cloud.patchInteraction().correct(
p,
pp,
td.keepParticle);
444template<
class ParcelType>
445template<
class TrackCloudType>
452 td.switchProcessor =
true;
456template<
class ParcelType>
457template<
class TrackCloudType>
468template<
class ParcelType>
471 ParcelType::transformProperties(
T);
477template<
class ParcelType>
483 ParcelType::transformProperties(separation);
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Kinematic parcel class with rotational motion (as spherical particles only) and one/two-way coupling ...
virtual void transformProperties(const tensor &T)
Transform the physical properties of the particle.
void calcUCorrection(TrackCloudType &cloud, trackingData &td, const scalar dt)
Correct U following MP-PIC sub-models.
vector UTurb_
Turbulent velocity fluctuation [m/s].
void calcDispersion(TrackCloudType &cloud, trackingData &td, const scalar dt)
Apply dispersion to the carrier phase velocity and update.
scalar d() const
Return const access to diameter.
void cellValueSourceCorrection(TrackCloudType &cloud, trackingData &td, const scalar dt)
Correct cell values using latest transfer information.
scalar Re(const trackingData &td) const
Reynolds number.
scalar tTurb_
Time spent in turbulent eddy [s].
const vector calcVelocity(TrackCloudType &cloud, trackingData &td, const scalar dt, const scalar Re, const scalar mu, const scalar mass, const vector &Su, vector &dUTrans, scalar &Spu) const
Calculate new particle velocity.
scalar massCell(const trackingData &td) const
Cell owner mass.
scalar mass() const
Particle mass.
KinematicParcel(const polyMesh &mesh, const barycentric &coordinates, const label celli, const label tetFacei, const label tetPti)
Construct from mesh, coordinates and topology.
void hitProcessorPatch(TrackCloudType &cloud, trackingData &td)
Overridable function to handle the particle hitting a.
bool hitPatch(TrackCloudType &cloud, trackingData &td)
Overridable function to handle the particle hitting a patch.
vector UCorrect_
Velocity correction due to collisions MPPIC [m/s].
void setCellValues(TrackCloudType &cloud, trackingData &td)
Set cell values.
bool move(TrackCloudType &cloud, trackingData &td, const scalar trackTime)
Move the parcel.
void hitWallPatch(TrackCloudType &cloud, trackingData &td)
Overridable function to handle the particle hitting a wallPatch.
vector U_
Velocity of Parcel [m/s].
scalar nParticle_
Number of particles in Parcel.
void calc(TrackCloudType &cloud, trackingData &td, const scalar dt)
Update parcel properties over the time interval.
A cell is defined as a list of faces with extra functionality.
Stores all relevant solution info for cloud.
A cloud is a registry collection of lagrangian particles.
Helper container for force Su and Sp terms.
const vector & Su() const
Return const access to the explicit contribution [kg.m/s2].
scalar Sp() const
Return const access to the implicit coefficient [kg/s].
const polyMesh & mesh() const noexcept
Return the mesh database.
label cell() const noexcept
Return current cell particle is in.
Mesh consisting of general polyhedral cells.
A patch is a list of labels that address the faces in the global face list.
static bool constraintType(const word &patchType)
Return true if the given type is a constraint type.
Selector class for relaxation factors, solver type and solution.
Storage and named access for the indices of a tet which is part of the decomposition of a cell.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
PtrList< coordinateSystem > coordinates(solidRegions.size())
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))
wallPoints::trackData td(isBlockedFace, regionToBlockSize)
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for handling debugging switches.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
refinementData transform(const tensor &, const refinementData val)
No-op rotational transform for base types.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
vector point
Point is a vector.
static constexpr const zero Zero
Global zero (0).
scalarField Re(const UList< complex > &cmplx)
Extract real component.
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
void Su(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
constexpr char nl
The newline '\n' character (0x0a).