49 template<
class CloudType>
52 dispersionModel_.reset
61 patchInteractionModel_.reset
70 stochasticCollisionModel_.reset
79 surfaceFilmModel_.reset
120 solution_.integrationSchemes()
126 template<
class CloudType>
127 template<
class TrackCloudType>
130 TrackCloudType&
cloud,
131 typename parcelType::trackingData& td
136 log = solution_.log();
138 if (solution_.steadyState())
144 evolveCloud(
cloud, td);
146 if (solution_.coupled())
155 evolveCloud(cloud, td);
157 if (solution_.coupled())
159 cloud.scaleSources();
165 cloud.postEvolve(td);
167 if (solution_.steadyState())
169 cloud.restoreState();
174 template<
class CloudType>
177 if (!cellOccupancyPtr_)
179 cellOccupancyPtr_.reset
181 new List<DynamicList<parcelType*>>(mesh_.nCells())
184 else if (cellOccupancyPtr_().size() != mesh_.nCells())
189 cellOccupancyPtr_().setSize(mesh_.nCells());
192 List<DynamicList<parcelType*>>&
cellOccupancy = cellOccupancyPtr_();
199 for (parcelType&
p : *
this)
206 template<
class CloudType>
212 if (cellOccupancyPtr_)
214 buildCellOccupancy();
219 template<
class CloudType>
220 template<
class TrackCloudType>
223 TrackCloudType& cloud,
224 typename parcelType::trackingData& td
227 if (solution_.coupled())
229 cloud.resetSourceTerms();
232 if (solution_.transient())
234 label preInjectionSize = this->size();
240 if (preInjectionSize != this->size())
242 updateCellOccupancy();
243 preInjectionSize = this->size();
246 injectors_.inject(cloud, td);
250 cloud.motion(cloud, td);
252 stochasticCollision().update(td, solution_.trackTime());
258 injectors_.injectSteadyState(cloud, td, solution_.trackTime());
260 td.part() = parcelType::trackingData::tpLinearTrack;
261 CloudType::move(
cloud, td, solution_.trackTime());
266 template<
class CloudType>
269 const typename parcelType::trackingData& td
276 this->writePositions();
279 this->dispersion().cacheFields(
false);
281 this->patchInteraction().postEvolve();
283 forces_.cacheFields(
false);
285 functions_.postEvolve(td);
287 solution_.nextIter();
289 if (this->db().time().writeTime())
291 outputProperties_.writeObject
295 IOstreamOption::ASCII,
296 this->db().time().writeCompression()
302 if (this->dampingModel().active())
304 this->dampingModel().cacheFields(
false);
306 if (this->packingModel().active())
308 this->packingModel().cacheFields(
false);
313 template<
class CloudType>
316 CloudType::cloudReset(
c);
320 forces_.transfer(
c.forces_);
322 functions_.transfer(
c.functions_);
324 injectors_.transfer(
c.injectors_);
326 dispersionModel_.reset(
c.dispersionModel_.ptr());
327 patchInteractionModel_.reset(
c.patchInteractionModel_.ptr());
328 stochasticCollisionModel_.reset(
c.stochasticCollisionModel_.ptr());
329 surfaceFilmModel_.reset(
c.surfaceFilmModel_.ptr());
331 packingModel_.reset(
c.packingModel_.ptr());
332 dampingModel_.reset(
c.dampingModel_.ptr());
333 isotropyModel_.reset(
c.isotropyModel_.ptr());
335 UIntegrator_.reset(
c.UIntegrator_.ptr());
341 template<
class CloudType>
354 cloudCopyPtr_(nullptr),
361 mesh_.time().constant(),
363 IOobject::MUST_READ_IF_MODIFIED,
375 IOobject::READ_IF_PRESENT,
379 solution_(mesh_, particleProperties_.subDict(
"solution")),
380 constProps_(particleProperties_),
383 particleProperties_.subOrEmptyDict
390 rndGen_(Pstream::myProcNo()),
392 cellLengthScale_(
mag(
cbrt(mesh_.V()))),
402 subModelProperties_.subOrEmptyDict
413 particleProperties_.subOrEmptyDict(
"cloudFunctions"),
418 subModelProperties_.subOrEmptyDict(
"injectionModels"),
421 dispersionModel_(nullptr),
422 patchInteractionModel_(nullptr),
423 stochasticCollisionModel_(nullptr),
424 surfaceFilmModel_(nullptr),
426 packingModel_(nullptr),
427 dampingModel_(nullptr),
428 isotropyModel_(nullptr),
430 UIntegrator_(nullptr),
437 this->
name() +
":UTrans",
440 IOobject::READ_IF_PRESENT,
453 this->
name() +
":UCoeff",
456 IOobject::READ_IF_PRESENT,
465 if (solution_.active())
472 this->deleteLostParticles();
476 if (solution_.resetSourcesOnStartup())
483 template<
class CloudType>
486 KinematicCloud<CloudType>&
c,
492 cloudCopyPtr_(nullptr),
494 particleProperties_(
c.particleProperties_),
495 outputProperties_(
c.outputProperties_),
496 solution_(
c.solution_),
497 constProps_(
c.constProps_),
498 subModelProperties_(
c.subModelProperties_),
499 rndGen_(
c.rndGen_, true),
500 cellOccupancyPtr_(nullptr),
501 cellLengthScale_(
c.cellLengthScale_),
506 pAmbient_(
c.pAmbient_),
508 functions_(
c.functions_),
509 injectors_(
c.injectors_),
510 dispersionModel_(
c.dispersionModel_->clone()),
511 patchInteractionModel_(
c.patchInteractionModel_->clone()),
512 stochasticCollisionModel_(
c.stochasticCollisionModel_->clone()),
513 surfaceFilmModel_(
c.surfaceFilmModel_->clone()),
515 packingModel_(
c.packingModel_->clone()),
516 dampingModel_(
c.dampingModel_->clone()),
517 isotropyModel_(
c.isotropyModel_->clone()),
519 UIntegrator_(
c.UIntegrator_->clone()),
526 this->
name() +
":UTrans",
531 IOobject::NO_REGISTER
547 IOobject::NO_REGISTER
556 template<
class CloudType>
566 cloudCopyPtr_(nullptr),
573 mesh_.time().constant(),
584 name +
"OutputProperties",
595 subModelProperties_(),
597 cellOccupancyPtr_(nullptr),
598 cellLengthScale_(
c.cellLengthScale_),
603 pAmbient_(
c.pAmbient_),
604 forces_(*this,
mesh),
607 dispersionModel_(nullptr),
608 patchInteractionModel_(nullptr),
609 stochasticCollisionModel_(nullptr),
610 surfaceFilmModel_(nullptr),
612 packingModel_(nullptr),
613 dampingModel_(nullptr),
614 isotropyModel_(nullptr),
616 UIntegrator_(nullptr),
625 template<
class CloudType>
629 const scalar lagrangianDt
633 if (constProps_.rho0() != -1)
635 parcel.rho() = constProps_.rho0();
640 template<
class CloudType>
644 const scalar lagrangianDt,
645 const bool fullyDescribed
648 const scalar carrierDt = mesh_.time().deltaTValue();
649 parcel.stepFraction() = (carrierDt - lagrangianDt)/carrierDt;
651 if (parcel.typeId() == -1)
653 parcel.typeId() = constProps_.parcelTypeId();
656 if (parcel.rho() == -1)
659 <<
"The kinematic cloud needs rho0 in the constantProperties " 660 <<
" dictionary. " <<
nl 666 template<
class CloudType>
671 static_cast<KinematicCloud<CloudType>*
> 673 clone(this->
name() +
"Copy").ptr()
679 template<
class CloudType>
682 cloudReset(cloudCopyPtr_());
683 cloudCopyPtr_.clear();
687 template<
class CloudType>
690 UTrans().field() =
Zero;
691 UCoeff().field() = 0.0;
695 template<
class CloudType>
704 const scalar coeff = solution_.relaxCoeff(
name);
709 template<
class CloudType>
717 const scalar coeff = solution_.relaxCoeff(
name);
722 template<
class CloudType>
728 this->
relax(UTrans_(), cloudOldTime.
UTrans(),
"U");
729 this->
relax(UCoeff_(), cloudOldTime.
UCoeff(),
"U");
733 template<
class CloudType>
736 this->scale(UTrans_(),
"U");
737 this->scale(UCoeff_(),
"U");
741 template<
class CloudType>
744 const typename parcelType::trackingData& td
749 label nGeometricD = mesh_.nGeometricD();
751 Log_<<
"\nSolving" << nGeometricD <<
"-D cloud " << this->
name() <<
endl;
753 this->dispersion().cacheFields(
true);
754 forces_.cacheFields(
true);
756 pAmbient_ = constProps_.dict().template
757 getOrDefault<scalar>(
"pAmbient", pAmbient_);
759 if (this->dampingModel().active() || this->packingModel().active())
761 const_cast<typename parcelType::trackingData&
>(td).updateAverages(*
this);
764 if (this->dampingModel().active())
766 this->dampingModel().cacheFields(
true);
768 if (this->packingModel().active())
770 this->packingModel().cacheFields(
true);
773 updateCellOccupancy();
775 functions_.preEvolve(td);
779 template<
class CloudType>
782 if (solution_.canEvolve())
784 typename parcelType::trackingData td(*
this);
790 template<
class CloudType>
791 template<
class TrackCloudType>
794 TrackCloudType& cloud,
795 typename parcelType::trackingData& td
798 td.part() = parcelType::trackingData::tpLinearTrack;
799 CloudType::move(cloud, td, solution_.trackTime());
801 if (isotropyModel_->active())
803 td.updateAverages(cloud);
804 isotropyModel_->calculate();
807 updateCellOccupancy();
811 template<
class CloudType>
826 if (isA<wallPolyPatch>(
pp))
828 const label patchi =
pp.index();
829 const label patchFacei =
pp.whichFace(
p.face());
835 if (U_.boundaryField()[patchi].fixesValue())
837 const vector Uw1(U_.boundaryField()[patchi][patchFacei]);
839 U_.oldTime().boundaryField()[patchi][patchFacei];
841 const scalar
f =
p.currentTimeFraction();
843 const vector Uw(Uw0 +
f*(Uw1 - Uw0));
847 Up = (nnw & Up) + Uw - (nnw & Uw);
853 template<
class CloudType>
856 updateCellOccupancy();
857 injectors_.updateMesh();
858 cellLengthScale_ =
mag(
cbrt(mesh_.V()));
862 template<
class CloudType>
871 template<
class CloudType>
874 const vector linearMomentum =
877 const scalar linearKineticEnergy =
882 const scalar particlePerParcel =
890 <<
" Current number of parcels = " << nTotParcel <<
nl 891 <<
" Current mass in system = " 893 <<
" Linear momentum = " << linearMomentum <<
nl 894 <<
" |Linear momentum| = " <<
mag(linearMomentum) <<
nl 895 <<
" Linear kinetic energy = " << linearKineticEnergy <<
nl 896 <<
" Average particle per parcel = " << particlePerParcel <<
nl;
901 this->patchInteraction().info();
903 if (this->packingModel().active())
907 if (this->db().time().writeTime())
912 const scalar alphaMin =
gMin(
alpha().primitiveField());
915 Log_<<
" Min cell volume fraction = " << alphaMin <<
nl 940 reduce(nMin, minOp<scalar>());
942 Log_<<
" Min dense number of parcels = " << nMin <<
endl;
947 template<
class CloudType>
950 parcelType::readObjects(*
this, obr);
954 template<
class CloudType>
957 parcelType::writeObjects(*
this, obr);
Template class for intrusive linked lists.
#define addProfiling(name, descr)
Define profiling trigger with specified name and description string.
DSMCCloud< dsmcParcel > CloudType
void scaleSources()
Apply scaling to (transient) cloud sources.
void setModels()
Set cloud sub-models.
void relaxSources(const KinematicCloud< CloudType > &cloudOldTime)
Apply relaxation to (steady state) cloud sources.
void storeState()
Store the current cloud state.
dimensionedScalar log(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Type gMin(const FieldField< Field, Type > &f)
void evolveCloud(TrackCloudType &cloud, typename parcelType::trackingData &td)
Evolve the cloud.
constexpr char nl
The newline '\n' character (0x0a)
void setParcelThermoProperties(parcelType &parcel, const scalar lagrangianDt)
Set parcel thermo properties.
void postEvolve(const typename parcelType::trackingData &td)
Post-evolve.
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void relax(DimensionedField< Type, volMesh > &field, const DimensionedField< Type, volMesh > &field0, const word &name) const
Relax field.
volVectorField::Internal & UTrans()
Return reference to momentum source.
Base class for packing models.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
virtual void writeObjects(objectRegistry &obr) const
Write particle fields as objects into the obr registry.
GeometricField< vector, fvPatchField, volMesh > volVectorField
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
void updateCellOccupancy()
Update (i.e. build) the cellOccupancy if it has.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
void buildCellOccupancy()
Build the cellOccupancy.
Templated patch interaction model class.
#define forAll(list, i)
Loop across all elements in list.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
void updateMesh()
Update mesh.
dimensionedScalar alphaMax("alphaMax", dimless/dimTime, laminarTransport)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
#define Log_
Report write to Foam::Info if the class log switch is true.
volScalarField::Internal & UCoeff()
Return coefficient for carrier phase U equation.
void resetSourceTerms()
Reset the cloud source terms.
const word cloudName(propsDict.get< word >("cloud"))
A class for handling words, derived from Foam::string.
void motion(TrackCloudType &cloud, typename parcelType::trackingData &td)
Particle motion.
A cloud is a registry collection of lagrangian particles.
virtual void readObjects(const objectRegistry &obr)
Read particle fields from objects in the obr registry.
dimensionedScalar cbrt(const dimensionedScalar &ds)
void checkParcelProperties(parcelType &parcel, const scalar lagrangianDt, const bool fullyDescribed)
Check parcel properties.
errorManip< error > abort(error &err)
Base cloud calls templated on particle type.
const uniformDimensionedVectorField & g
regionModels::surfaceFilmModel & surfaceFilm
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
int debug
Static debugging option.
Type gMax(const FieldField< Field, Type > &f)
Templated wall surface film model class.
const dimensionedScalar mu
Atomic mass unit.
Base class for collisional return-to-isotropy models.
void preEvolve(const typename parcelType::trackingData &td)
Pre-evolve.
Virtual abstract base class for templated KinematicCloud.
Templated base class for kinematic cloud.
void patchData(const parcelType &p, const polyPatch &pp, vector &normal, vector &Up) const
Calculate the patch normal and velocity to interact with,.
const List< DynamicList< molecule * > > & cellOccupancy
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
void evolve()
Evolve the cloud.
Templated stochastic collision model class.
Mesh data needed to do the Finite Volume discretisation.
const dimensionedScalar c
Speed of light in a vacuum.
Base class for dispersion modelling.
void info()
Print cloud information.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
void restoreState()
Reset the current cloud to the previously stored state.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
void scale(DimensionedField< Type, volMesh > &field, const word &name) const
Scale field.
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const wordHashSet &selectedFields, LIFOStack< regIOobject *> &storedObjects)
Read the selected GeometricFields of the templated type.
void cloudReset(KinematicCloud< CloudType > &c)
Reset state of cloud.
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
A class for managing temporary objects.
Registry of regIOobjects.
virtual void autoMap(const mapPolyMesh &)
Remap the cells of particles corresponding to the.
A patch is a list of labels that address the faces in the global face list.
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
Tensor of scalars, i.e. Tensor<scalar>.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Templated base class for dsmc cloud.
Base class for collisional damping models.
void solve(TrackCloudType &cloud, typename parcelType::trackingData &td)
Solve the cloud - calls all evolution functions.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
static constexpr const zero Zero
Global zero (0)
const dimensionSet dimVelocity