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 IOobject::scopedName(this->
name(),
"rhokTrans"),
440 IOobject::READ_IF_PRESENT,
453 IOobject::scopedName(this->
name(),
"UTrans"),
456 IOobject::READ_IF_PRESENT,
469 IOobject::scopedName(this->
name(),
"UCoeff"),
472 IOobject::READ_IF_PRESENT,
481 if (solution_.active())
488 this->deleteLostParticles();
492 if (solution_.resetSourcesOnStartup())
499 template<
class CloudType>
502 KinematicCloud<CloudType>&
c,
508 cloudCopyPtr_(nullptr),
510 particleProperties_(
c.particleProperties_),
511 outputProperties_(
c.outputProperties_),
512 solution_(
c.solution_),
513 constProps_(
c.constProps_),
514 subModelProperties_(
c.subModelProperties_),
515 rndGen_(
c.rndGen_, true),
516 cellOccupancyPtr_(nullptr),
517 cellLengthScale_(
c.cellLengthScale_),
522 pAmbient_(
c.pAmbient_),
524 functions_(
c.functions_),
525 injectors_(
c.injectors_),
526 dispersionModel_(
c.dispersionModel_->clone()),
527 patchInteractionModel_(
c.patchInteractionModel_->clone()),
528 stochasticCollisionModel_(
c.stochasticCollisionModel_->clone()),
529 surfaceFilmModel_(
c.surfaceFilmModel_->clone()),
531 packingModel_(
c.packingModel_->clone()),
532 dampingModel_(
c.dampingModel_->clone()),
533 isotropyModel_(
c.isotropyModel_->clone()),
535 UIntegrator_(
c.UIntegrator_->clone()),
542 IOobject::scopedName(this->
name(),
"rhokTrans"),
547 IOobject::NO_REGISTER
558 IOobject::scopedName(this->
name(),
"UTrans"),
563 IOobject::NO_REGISTER
579 IOobject::NO_REGISTER
588 template<
class CloudType>
598 cloudCopyPtr_(nullptr),
605 mesh_.time().constant(),
616 name +
"OutputProperties",
627 subModelProperties_(),
629 cellOccupancyPtr_(nullptr),
630 cellLengthScale_(
c.cellLengthScale_),
635 pAmbient_(
c.pAmbient_),
636 forces_(*this,
mesh),
639 dispersionModel_(nullptr),
640 patchInteractionModel_(nullptr),
641 stochasticCollisionModel_(nullptr),
642 surfaceFilmModel_(nullptr),
644 packingModel_(nullptr),
645 dampingModel_(nullptr),
646 isotropyModel_(nullptr),
648 UIntegrator_(nullptr),
658 template<
class CloudType>
662 const scalar lagrangianDt
666 if (constProps_.rho0() != -1)
668 parcel.rho() = constProps_.rho0();
673 template<
class CloudType>
677 const scalar lagrangianDt,
678 const bool fullyDescribed
681 const scalar carrierDt = mesh_.time().deltaTValue();
682 parcel.stepFraction() = (carrierDt - lagrangianDt)/carrierDt;
684 if (parcel.typeId() == -1)
686 parcel.typeId() = constProps_.parcelTypeId();
689 if (parcel.rho() == -1)
692 <<
"The kinematic cloud needs rho0 in the constantProperties " 693 <<
" dictionary. " <<
nl 699 template<
class CloudType>
704 static_cast<KinematicCloud<CloudType>*
> 706 clone(this->
name() +
"Copy").ptr()
712 template<
class CloudType>
715 cloudReset(cloudCopyPtr_());
716 cloudCopyPtr_.clear();
720 template<
class CloudType>
723 rhokTrans().field() =
Zero;
724 UTrans().field() =
Zero;
729 template<
class CloudType>
738 const scalar coeff = solution_.relaxCoeff(
name);
743 template<
class CloudType>
751 const scalar coeff = solution_.relaxCoeff(
name);
756 template<
class CloudType>
763 this->
relax(UTrans_(), cloudOldTime.
UTrans(),
"U");
764 this->
relax(UCoeff_(), cloudOldTime.
UCoeff(),
"U");
768 template<
class CloudType>
771 this->scale(rhokTrans_(),
"rhok");
772 this->scale(UTrans_(),
"U");
773 this->scale(UCoeff_(),
"U");
777 template<
class CloudType>
780 const typename parcelType::trackingData& td
785 label nGeometricD = mesh_.nGeometricD();
787 Log_<<
"\nSolving" << nGeometricD <<
"-D cloud " << this->
name() <<
endl;
789 this->dispersion().cacheFields(
true);
790 forces_.cacheFields(
true);
792 pAmbient_ = constProps_.dict().template
793 getOrDefault<scalar>(
"pAmbient", pAmbient_);
795 if (this->dampingModel().active() || this->packingModel().active())
797 const_cast<typename parcelType::trackingData&
>(td).updateAverages(*
this);
800 if (this->dampingModel().active())
802 this->dampingModel().cacheFields(
true);
804 if (this->packingModel().active())
806 this->packingModel().cacheFields(
true);
809 updateCellOccupancy();
811 functions_.preEvolve(td);
815 template<
class CloudType>
818 if (solution_.canEvolve())
820 typename parcelType::trackingData td(*
this);
826 template<
class CloudType>
827 template<
class TrackCloudType>
830 TrackCloudType& cloud,
831 typename parcelType::trackingData& td
834 td.part() = parcelType::trackingData::tpLinearTrack;
835 CloudType::move(cloud, td, solution_.trackTime());
837 if (isotropyModel_->active())
839 td.updateAverages(cloud);
840 isotropyModel_->calculate();
843 updateCellOccupancy();
847 template<
class CloudType>
862 if (isA<wallPolyPatch>(
pp))
864 const label patchi =
pp.index();
865 const label patchFacei =
pp.whichFace(
p.face());
871 if (U_.boundaryField()[patchi].fixesValue())
873 const vector Uw1(U_.boundaryField()[patchi][patchFacei]);
875 U_.oldTime().boundaryField()[patchi][patchFacei];
877 const scalar
f =
p.currentTimeFraction();
879 const vector Uw(Uw0 +
f*(Uw1 - Uw0));
883 Up = (nnw & Up) + Uw - (nnw & Uw);
889 template<
class CloudType>
892 updateCellOccupancy();
893 injectors_.updateMesh();
894 cellLengthScale_ =
mag(
cbrt(mesh_.V()));
898 template<
class CloudType>
907 template<
class CloudType>
910 const vector linearMomentum =
913 const scalar linearKineticEnergy =
918 const scalar particlePerParcel =
926 <<
" Current number of parcels = " << nTotParcel <<
nl 927 <<
" Current mass in system = " 929 <<
" Linear momentum = " << linearMomentum <<
nl 930 <<
" |Linear momentum| = " <<
mag(linearMomentum) <<
nl 931 <<
" Linear kinetic energy = " << linearKineticEnergy <<
nl 932 <<
" Average particle per parcel = " << particlePerParcel <<
nl;
937 this->patchInteraction().info();
939 if (this->packingModel().active())
943 if (this->db().time().writeTime())
948 const scalar alphaMin =
gMin(
alpha().primitiveField());
951 Log_<<
" Min cell volume fraction = " << alphaMin <<
nl 976 reduce(nMin, minOp<scalar>());
978 Log_<<
" Min dense number of parcels = " << nMin <<
endl;
983 template<
class CloudType>
986 parcelType::readObjects(*
this, obr);
990 template<
class CloudType>
993 parcelType::writeObjects(*
this, obr);
Template class for intrusive linked lists.
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)
#define addProfiling(Name, Descr)
Define profiling trigger with specified name and description string.
volScalarField::Internal & rhokTrans()
Return reference to mass for kinematic source.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::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.
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const NameMatchPredicate &selectedFields, DynamicList< regIOobject *> &storedObjects)
Read the selected GeometricFields of the templated type and store on the objectRegistry.
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 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