diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C index 1a594764378b2d237cb8aaf0c5b93654ef62e9b5..8ed5e0c26210de9b31be3b430c0b2dbe8a772728 100644 --- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C +++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C @@ -36,43 +36,32 @@ License // * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * // template<class ParcelType> -Foam::scalar Foam::KinematicCloud<ParcelType>::setNumberOfParticles +void Foam::KinematicCloud<ParcelType>::addNewParcel ( - const label nParcels, - const scalar pDiameter, - const scalar pVolumeFraction, - const scalar pRho, - const scalar pVolume + const vector& position, + const label cellId, + const scalar d, + const vector& U, + const scalar nParticles, + const scalar lagrangianDt ) { - scalar nP = 0.0; - switch (parcelBasis_) - { - case pbMass: - { - nP = pVolumeFraction*massTotal_/nParcels - /(pRho*mathematicalConstant::pi/6.0*pow(pDiameter, 3)); - break; - } - case pbNumber: - { - nP = pVolumeFraction*massTotal_/(pRho*pVolume); - break; - } - default: - { - nP = 0.0; - FatalErrorIn - ( - "Foam::KinematicCloud<ParcelType>::setNumberOfParticles" - "(const label, const scalar, const scalar, const scalar, " - "const scalar)" - )<< "Unknown parcelBasis type" << nl - << exit(FatalError); - } - } + ParcelType* pPtr = new ParcelType + ( + *this, + parcelTypeId_, + position, + cellId, + d, + U, + nParticles, + constProps_ + ); - return nP; + scalar continuousDt = this->db().time().deltaT().value(); + pPtr->stepFraction() = (continuousDt - lagrangianDt)/continuousDt; + + addParticle(pPtr); } @@ -107,14 +96,6 @@ Foam::KinematicCloud<ParcelType>::KinematicCloud parcelTypeId_(readLabel(particleProperties_.lookup("parcelTypeId"))), coupled_(particleProperties_.lookup("coupled")), rndGen_(label(0)), - time0_(this->db().time().value()), - parcelBasisType_(particleProperties_.lookup("parcelBasisType")), - parcelBasis_(pbNumber), - massTotal_ - ( - dimensionedScalar(particleProperties_.lookup("massTotal")).value() - ), - massInjected_(0.0), rho_(rho), U_(U), mu_(mu), @@ -160,9 +141,6 @@ Foam::KinematicCloud<ParcelType>::KinematicCloud particleProperties_.subDict("integrationSchemes") ) ), - nInjections_(0), - nParcelsAdded_(0), - nParcelsAddedTotal_(0), UTrans_ ( IOobject @@ -191,27 +169,7 @@ Foam::KinematicCloud<ParcelType>::KinematicCloud mesh_, dimensionedScalar("zero", dimensionSet(1, 0, -1, 0, 0), 0.0) ) -{ - if (parcelBasisType_ == "mass") - { - parcelBasis_ = pbMass; - } - else if (parcelBasisType_ == "number") - { - parcelBasis_ = pbNumber; - } - else - { - FatalErrorIn - ( - "Foam::KinematicCloud<ParcelType>::KinematicCloud" - "(const word&, const volScalarField&" - ", const volVectorField&, const volScalarField&, const " - "dimensionedVector&)" - )<< "parcelBasisType must be either 'number' or 'mass'" << nl - << exit(FatalError); - } -} +{} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // @@ -265,160 +223,19 @@ void Foam::KinematicCloud<ParcelType>::evolve() g_.value() ); - inject(); - - if (coupled_) - { - resetSourceTerms(); - } - - Cloud<ParcelType>::move(td); -} - - -template<class ParcelType> -void Foam::KinematicCloud<ParcelType>::inject() -{ - scalar time = this->db().time().value(); - - scalar pRho = constProps_.rho0(); - - this->injection().prepareForNextTimeStep(time0_, time); - - // Number of parcels to introduce during this timestep - const label nParcels = this->injection().nParcels(); - - // Return if no parcels are required - if (!nParcels) - { - this->postInjectCheck(); - return; - } - - // Volume of particles to introduce during this timestep - scalar pVolume = this->injection().volume(); - - // Volume fraction to introduce during this timestep - scalar pVolumeFraction = this->injection().volumeFraction(); - - // Duration of injection period during this timestep - scalar deltaT = min - ( - this->db().time().deltaT().value(), - min - ( - time - this->injection().timeStart(), - this->injection().timeEnd() - time0_ - ) - ); - - // Pad injection time if injection starts during this timestep - scalar padTime = max - ( - 0.0, - this->injection().timeStart() - time0_ - ); - - // Introduce new parcels linearly with time - for (label iParcel=0; iParcel<nParcels; iParcel++) - { - // Calculate the pseudo time of injection for parcel 'iParcel' - scalar timeInj = time0_ + padTime + deltaT*iParcel/nParcels; - - // Determine injected parcel properties - vector pPosition = this->injection().position - ( - iParcel, - timeInj, - this->meshInfo() - ); - - // Diameter of parcels - scalar pDiameter = this->injection().d0(iParcel, timeInj); - - // Number of particles per parcel - scalar pNumberOfParticles = setNumberOfParticles - ( - nParcels, - pDiameter, - pVolumeFraction, - pRho, - pVolume - ); - - // Velocity of parcels - vector pU = this->injection().velocity - ( - iParcel, - timeInj, - this->meshInfo() - ); - - // Determine the injection cell - label pCell = -1; - this->injection().findInjectorCellAndPosition(pCell, pPosition); - - if (pCell >= 0) - { - // construct the parcel that is to be injected - ParcelType* pPtr = new ParcelType - ( - *this, - parcelTypeId_, - pPosition, - pCell, - pDiameter, - pU, - pNumberOfParticles, - constProps_ - ); - - scalar dt = time - timeInj; - - pPtr->stepFraction() = (this->db().time().deltaT().value() - dt) - /this->time().deltaT().value(); - - this->injectParcel(pPtr); - } - } - - this->postInjectCheck(); + this->injection().inject(td); if (debug) { this->dumpParticlePositions(); } -} - - -template<class ParcelType> -void Foam::KinematicCloud<ParcelType>::injectParcel(ParcelType* p) -{ - addParticle(p); - nParcelsAdded_++; - nParcelsAddedTotal_++; - massInjected_ += p->mass()*p->nParticle(); -} - -template<class ParcelType> -void Foam::KinematicCloud<ParcelType>::postInjectCheck() -{ - if (nParcelsAdded_) + if (coupled_) { - Pout<< "\n--> Cloud: " << this->name() << nl - << " Added " << nParcelsAdded_ - << " new parcels" << nl << endl; + resetSourceTerms(); } - // Reset parcel counters - nParcelsAdded_ = 0; - - // Set time for start of next injection - time0_ = this->db().time().value(); - - // Increment number of injections - nInjections_++; + Cloud<ParcelType>::move(td); } @@ -427,9 +244,11 @@ void Foam::KinematicCloud<ParcelType>::info() const { Info<< "Cloud name: " << this->name() << nl << " Parcels added during this run = " - << returnReduce(nParcelsAddedTotal_, sumOp<label>()) << nl + << returnReduce(this->injection().nParcelsAddedTotal(), sumOp<label>()) + << nl << " Mass introduced during this run = " - << returnReduce(massInjected_, sumOp<scalar>()) << nl + << returnReduce(this->injection().massInjected(), sumOp<scalar>()) + << nl << " Current number of parcels = " << returnReduce(this->size(), sumOp<label>()) << nl << " Current mass in system = " @@ -445,7 +264,7 @@ void Foam::KinematicCloud<ParcelType>::dumpParticlePositions() const ( this->db().time().path()/"parcelPositions_" + this->name() + "_" - + name(this->nInjections_) + ".obj" + + name(this->injection().nInjections()) + ".obj" ); forAllConstIter(typename KinematicCloud<ParcelType>, *this, iter) diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H index 0d3781413cbb72236afdd2554dc640890e9fba92..556dbc3546b68efd4ba78bffec84d839a1dfd2e2 100644 --- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H +++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H @@ -85,19 +85,6 @@ class KinematicCloud public kinematicCloud { -public: - - // Enumerations - - //- Parcel basis representation options - // i.e constant number of particles OR constant mass per parcel - enum parcelBasis - { - pbNumber, - pbMass - }; - - private: // Private data @@ -126,22 +113,6 @@ private: //- Random number generator - used by some injection routines Random rndGen_; - //- Time at beginning of timestep - scalar time0_; - - - // Injection properties - - //- Parcel basis - const word parcelBasisType_; - parcelBasis parcelBasis_; - - //- Total mass to inject [kg] - scalar massTotal_; - - //- Total mass injected to date [kg] - scalar massInjected_; - // References to the carrier gas fields @@ -161,9 +132,8 @@ private: const dimensionedVector& g_; - // Interpolation - - dictionary interpolationSchemes_; + //- Interpolation schemes dictionary + dictionary interpolationSchemes_; // References to the cloud sub-models @@ -190,17 +160,6 @@ private: autoPtr<vectorIntegrationScheme> UIntegrator_; - // Counters - - //- Number of injections counter - label nInjections_; - - //- Running counters describing parcels added during each - // injection - label nParcelsAdded_; - label nParcelsAddedTotal_; - - // Sources //- Momentum @@ -219,30 +178,6 @@ private: void operator=(const KinematicCloud&); -protected: - - // Protected member functions - - //- Set the number of particles per parcel - scalar setNumberOfParticles - ( - const label nParcels, - const scalar pDiameter, - const scalar pVolumeFraction, - const scalar pRho, - const scalar pVolume - ); - - //- Inject more parcels - void inject(); - - //- Inject parcel if it is valid - delete otherwise - void injectParcel(ParcelType* p); - - //- Post-injection checks - void postInjectCheck(); - - public: // Constructors @@ -286,12 +221,6 @@ public: //- Return refernce to the random object inline Random& rndGen(); - //- Return the start of injection interval time - inline scalar time0() const; - - //- Return a reference to the mass of particles to introduce - inline scalar massTotal() const; - // References to the carrier gas fields @@ -380,15 +309,6 @@ public: void dumpParticlePositions() const; - // Counters - - //- Return the number of injections - inline label nInjections() const; - - //- Return the total number parcels added - inline label nParcelsAddedTotal() const; - - // Fields //- Return the particle volume fraction field @@ -402,6 +322,17 @@ public: // Cloud evolution functions + //- Add new parcel + void addNewParcel + ( + const vector& position, + const label cellId, + const scalar d, + const vector& U, + const scalar nParticles, + const scalar lagrangianDt + ); + //- Reset the spray source terms void resetSourceTerms(); diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H index 73a891dcb33422d13239ee5dbb0dc22ea37248cd..7124410731a8c8ba5ac5a46405f9647f05ef6455 100644 --- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H +++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H @@ -155,41 +155,6 @@ Foam::KinematicCloud<ParcelType>::UIntegrator() const } -template<class ParcelType> -inline Foam::label Foam::KinematicCloud<ParcelType>::nInjections() const -{ - return nInjections_; -} - - -template<class ParcelType> -inline Foam::label Foam::KinematicCloud<ParcelType>::nParcelsAddedTotal() const -{ - return nParcelsAddedTotal_; -} - - -template<class ParcelType> -inline Foam::scalar Foam::KinematicCloud<ParcelType>::time0() const -{ - return time0_; -} - - -template<class ParcelType> -inline Foam::scalar Foam::KinematicCloud<ParcelType>::massTotal() const -{ - return massTotal_; -} - - -template<class ParcelType> -inline Foam::scalar Foam::KinematicCloud<ParcelType>::massInjected() const -{ - return massInjected_; -} - - template<class ParcelType> inline Foam::scalar Foam::KinematicCloud<ParcelType>::massInSystem() const { diff --git a/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.C b/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.C index 4bad7642727b81043196feb55ebc140a557f83bd..95f2e9810ecedda303f92d499784235e8124d21c 100644 --- a/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.C +++ b/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.C @@ -29,6 +29,42 @@ License #include "MassTransferModel.H" #include "SurfaceReactionModel.H" +// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * // + +template<class ParcelType> +void Foam::ReactingCloud<ParcelType>::addNewParcel +( + const vector& position, + const label cellId, + const scalar d, + const vector& U, + const scalar nParticles, + const scalar lagrangianDt +) +{ + ParcelType* pPtr = new ParcelType + ( + *this, + this->parcelTypeId(), + position, + cellId, + d, + U, + nParticles, + composition().YGas0(), + composition().YLiquid0(), + composition().YSolid0(), + composition().YMixture0(), + constProps_ + ); + + scalar continuousDt = this->db().time().deltaT().value(); + pPtr->stepFraction() = (continuousDt - lagrangianDt)/continuousDt; + + addParticle(pPtr); +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class ParcelType> @@ -174,133 +210,19 @@ void Foam::ReactingCloud<ParcelType>::evolve() this->g().value() ); - inject(); + this->injection().inject(td); - if (this->coupled()) - { - resetSourceTerms(); - } - - Cloud<ParcelType>::move(td); -} - - -template<class ParcelType> -void Foam::ReactingCloud<ParcelType>::inject() -{ - scalar time = this->db().time().value(); - - scalar pRho = this->constProps().rho0(); - - this->injection().prepareForNextTimeStep(this->time0(), time); - - // Number of parcels to introduce during this timestep - const label nParcels = this->injection().nParcels(); - - // Return if no parcels are required - if (!nParcels) + if (debug) { - this->postInjectCheck(); - return; + this->dumpParticlePositions(); } - // Volume of particles to introduce during this timestep - scalar pVolume = this->injection().volume(); - - // Volume fraction to introduce during this timestep - scalar pVolumeFraction = this->injection().volumeFraction(); - - // Duration of injection period during this timestep - scalar deltaT = min - ( - this->db().time().deltaT().value(), - min - ( - time - this->injection().timeStart(), - this->injection().timeEnd() - this->time0() - ) - ); - - // Pad injection time if injection starts during this timestep - scalar padTime = max - ( - 0.0, - this->injection().timeStart() - this->time0() - ); - - // Introduce new parcels linearly with time - for (label iParcel=0; iParcel<nParcels; iParcel++) + if (this->coupled()) { - // Calculate the pseudo time of injection for parcel 'iParcel' - scalar timeInj = this->time0() + padTime + deltaT*iParcel/nParcels; - - // Determine injected parcel properties - vector pPosition = this->injection().position - ( - iParcel, - timeInj, - this->meshInfo() - ); - - // Diameter of parcels - scalar pDiameter = this->injection().d0(iParcel, timeInj); - - // Number of particles per parcel - scalar pNumberOfParticles = this->setNumberOfParticles - ( - nParcels, - pDiameter, - pVolumeFraction, - pRho, - pVolume - ); - - // Velocity of parcels - vector pU = this->injection().velocity - ( - iParcel, - timeInj, - this->meshInfo() - ); - - // Determine the injection cell - label pCell = -1; - this->injection().findInjectorCellAndPosition(pCell, pPosition); - - if (pCell >= 0) - { - // construct the parcel that is to be injected - ParcelType* pPtr = new ParcelType - ( - *this, - this->parcelTypeId(), - pPosition, - pCell, - pDiameter, - pU, - pNumberOfParticles, - composition().YGas0(), - composition().YLiquid0(), - composition().YSolid0(), - composition().YMixture0(), - this->constProps() - ); - - scalar dt = time - timeInj; - - pPtr->stepFraction() = (this->db().time().deltaT().value() - dt) - /this->db().time().deltaT().value(); - - this->injectParcel(pPtr); - } + resetSourceTerms(); } - this->postInjectCheck(); - - if (debug) - { - this->dumpParticlePositions(); - } + Cloud<ParcelType>::move(td); } diff --git a/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.H b/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.H index 9ce5c98b1aa35210762b134ebfc4510a0a611e30..e257d04484d7e2078e09540e57b477ef23ce42ad 100644 --- a/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.H +++ b/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.H @@ -114,12 +114,6 @@ class ReactingCloud void operator=(const ReactingCloud&); -protected: - - //- Inject more parcels - void inject(); - - public: //- Runtime type information @@ -199,6 +193,17 @@ public: // Cloud evolution functions + //- Add new parcel + void addNewParcel + ( + const vector& position, + const label cellId, + const scalar d, + const vector& U, + const scalar nParticles, + const scalar lagrangianDt + ); + //- Reset the spray source terms void resetSourceTerms(); diff --git a/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.C b/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.C index c585d22fd30171a2e3888fa09f84db87b6c306a9..184d6d8aae8f78bea66bdf054e4f78fb12f9906c 100644 --- a/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.C +++ b/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.C @@ -30,6 +30,38 @@ License #include "interpolationCellPoint.H" #include "ThermoParcel.H" +// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * // + +template<class ParcelType> +void Foam::ThermoCloud<ParcelType>::addNewParcel +( + const vector& position, + const label cellId, + const scalar d, + const vector& U, + const scalar nParticles, + const scalar lagrangianDt +) +{ + ParcelType* pPtr = new ParcelType + ( + *this, + this->parcelTypeId(), + position, + cellId, + d, + U, + nParticles, + constProps_ + ); + + scalar continuousDt = this->db().time().deltaT().value(); + pPtr->stepFraction() = (continuousDt - lagrangianDt)/continuousDt; + + addParticle(pPtr); +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class ParcelType> @@ -167,7 +199,12 @@ void Foam::ThermoCloud<ParcelType>::evolve() this->g().value() ); - inject(td); + this->injection().inject(td); + + if (debug) + { + this->dumpParticlePositions(); + } if (this->coupled()) { @@ -178,16 +215,4 @@ void Foam::ThermoCloud<ParcelType>::evolve() } -template<class ParcelType> -template<class TrackingData> -void Foam::ThermoCloud<ParcelType>::inject -( - TrackingData& td -) -{ - // Injection is same as for KinematicCloud<ParcelType> - KinematicCloud<ParcelType>::inject(td); -} - - // ************************************************************************* // diff --git a/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.H b/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.H index ba7930af30949e96324f28e4f0b855f81dc9bc45..a3a0044c476ae8f6ebde2b74ee5261ed2ee76306 100644 --- a/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.H +++ b/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.H @@ -116,13 +116,6 @@ class ThermoCloud void operator=(const ThermoCloud&); -protected: - - //- Inject more parcels - template<class TrackingData> - void inject(TrackingData& td); - - public: //- Runtime type information @@ -173,7 +166,7 @@ public: // Modelling options - //- Radiation flag + //- Radiation flag inline bool radiation() const; @@ -208,6 +201,17 @@ public: // Cloud evolution functions + //- Add new parcel + void addNewParcel + ( + const vector& position, + const label cellId, + const scalar d, + const vector& U, + const scalar nParticles, + const scalar lagrangianDt + ); + //- Reset the spray source terms void resetSourceTerms(); diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C index f23dc19c0a1d9aeb8a8430bd7afb4de79920559f..f3c1caaa31ac71e3ede7abeac60f425645166063 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C @@ -25,109 +25,22 @@ License \*---------------------------------------------------------------------------*/ #include "InjectionModel.H" +#include "mathematicalConstants.H" -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -template<class CloudType> -Foam::InjectionModel<CloudType>::InjectionModel -( - const dictionary& dict, - CloudType& owner, - const word& type -) -: dict_(dict), - owner_(owner), - coeffDict_(dict.subDict(type + "Coeffs")), - SOI_(readScalar(coeffDict_.lookup("SOI"))), - volumeTotal_(0.0), - timeStep0_(0.0), - nParcels_(0), - volume_(0.0) -{} - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -template<class CloudType> -Foam::InjectionModel<CloudType>::~InjectionModel() -{} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -template<class CloudType> -const CloudType& Foam::InjectionModel<CloudType>::owner() const -{ - return owner_; -} - - -template<class CloudType> -CloudType& Foam::InjectionModel<CloudType>::owner() -{ - return owner_; -} - - -template<class CloudType> -const Foam::dictionary& Foam::InjectionModel<CloudType>::dict() const -{ - return dict_; -} - - -template<class CloudType> -const Foam::dictionary& Foam::InjectionModel<CloudType>::coeffDict() const -{ - return coeffDict_; -} - - -template<class CloudType> -Foam::scalar Foam::InjectionModel<CloudType>::timeStart() const -{ - return SOI_; -} - - -template<class CloudType> -Foam::scalar Foam::InjectionModel<CloudType>::volumeTotal() const -{ - return volumeTotal_; -} - - -template<class CloudType> -Foam::label Foam::InjectionModel<CloudType>::nParcels() const -{ - return nParcels_; -} - - -template<class CloudType> -Foam::scalar Foam::InjectionModel<CloudType>::volume() const -{ - return volume_; -} - - -template<class CloudType> -Foam::scalar Foam::InjectionModel<CloudType>::volumeFraction() const -{ - return volume_/volumeTotal_; -} - +// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * // template<class CloudType> void Foam::InjectionModel<CloudType>::prepareForNextTimeStep ( const scalar time0, - const scalar time1 + const scalar time1, + label& nParcels, + scalar& volume ) { // Initialise values - nParcels_ = 0; - volume_ = 0.0; + nParcels = 0; + volume = 0.0; // Return if not started injection event if (time1 < SOI_) @@ -141,13 +54,13 @@ void Foam::InjectionModel<CloudType>::prepareForNextTimeStep scalar t1 = time1 - SOI_; // Number of parcels to inject - nParcels_ = nParcelsToInject(t0, t1); + nParcels = nParcelsToInject(t0, t1); // Volume of parcels to inject - volume_ = volumeToInject(t0, t1); + volume = volumeToInject(t0, t1); // Hold previous time if no parcels, but non-zero volume fraction - if ((nParcels_ == 0) && (volume_ > 0.0)) + if ((nParcels == 0) && (volume > 0.0)) { // hold value of timeStep0_ } @@ -210,6 +123,203 @@ void Foam::InjectionModel<CloudType>::findInjectorCellAndPosition } +template<class CloudType> +Foam::scalar Foam::InjectionModel<CloudType>::setNumberOfParticles +( + const label nParcels, + const scalar diameter, + const scalar volumeFraction, + const scalar rho, + const scalar volume +) +{ + scalar nP = 0.0; + switch (parcelBasis_) + { + case pbMass: + { + nP = volumeFraction*massTotal_/nParcels + /(rho*mathematicalConstant::pi/6.0*pow3(diameter)); + break; + } + case pbNumber: + { + nP = volumeFraction*massTotal_/(rho*volume); + break; + } + default: + { + nP = 0.0; + FatalErrorIn + ( + "void Foam::InjectionModel<CloudType>::setNumberOfParticles" + "(const label, const scalar, const scalar, const scalar, " + "const scalar)" + )<< "Unknown parcelBasis type" << nl + << exit(FatalError); + } + } + + return nP; +} + + +template<class CloudType> +void Foam::InjectionModel<CloudType>::postInjectCheck() +{ + if (nParcelsAdded_ > 0) + { + Pout<< "\n--> Cloud: " << owner_.name() << nl + << " Added " << nParcelsAdded_ + << " new parcels" << nl << endl; + } + + // Increment total number of parcels added + nParcelsAddedTotal_ += nParcelsAdded_; + + // Reset parcel counters + nParcelsAdded_ = 0; + + // Update time for start of next injection + time0_ = owner_.db().time().value(); + + // Increment number of injections + nInjections_++; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class CloudType> +Foam::InjectionModel<CloudType>::InjectionModel +( + const dictionary& dict, + CloudType& owner, + const word& type +) +: dict_(dict), + owner_(owner), + coeffDict_(dict.subDict(type + "Coeffs")), + SOI_(readScalar(coeffDict_.lookup("SOI"))), + volumeTotal_(0.0), + massTotal_(dimensionedScalar(coeffDict_.lookup("massTotal")).value()), + massInjected_(0.0), + nInjections_(0), + nParcelsAdded_(0), + nParcelsAddedTotal_(0), + parcelBasisType_(coeffDict_.lookup("parcelBasisType")), + parcelBasis_(pbNumber), + time0_(owner.db().time().value()), + timeStep0_(0.0) +{ + if (parcelBasisType_ == "mass") + { + parcelBasis_ = pbMass; + } + else if (parcelBasisType_ == "number") + { + parcelBasis_ = pbNumber; + } + else + { + FatalErrorIn + ( + "Foam::InjectionModel<CloudType>::InjectionModel" + "(const dictionary&, CloudType&, const word&)" + )<< "parcelBasisType must be either 'number' or 'mass'" << nl + << exit(FatalError); + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template<class CloudType> +Foam::InjectionModel<CloudType>::~InjectionModel() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class CloudType> +template<class TrackData> +void Foam::InjectionModel<CloudType>::inject(TrackData& td) +{ + const scalar time = owner_.db().time().value(); + const scalar continuousDt = owner_.db().time().deltaT().value(); + + // Prepare for next time step + nParcelsAdded_ = 0; + label nParcels = 0; + scalar volume = 0.0; + prepareForNextTimeStep(time0_, time, nParcels, volume); + + // Return if no parcels are required + if (nParcels == 0) + { + postInjectCheck(); + return; + } + + // Particle density given by constant properties + const scalar rho = td.constProps().rho0(); + + // Volume fraction to introduce during this timestep + const scalar volFraction = volumeFraction(volume); + + // Duration of injection period during this timestep + const scalar deltaT = min + ( + continuousDt, + min(time - SOI_, timeEnd() - time0_) + ); + + // Pad injection time if injection starts during this timestep + const scalar padTime = max(0.0, SOI_ - time0_); + + // Introduce new parcels linearly with time + for (label iParcel=0; iParcel<nParcels; iParcel++) + { + // Calculate the pseudo time of injection for parcel 'iParcel' + scalar timeInj = time0_ + padTime + deltaT*iParcel/nParcels; + + // Determine injected parcel properties + vector pos = position(iParcel, timeInj, owner_.meshInfo()); + + // Diameter of parcels + scalar d = d0(iParcel, timeInj); + + // Number of particles per parcel + scalar nP = setNumberOfParticles + ( + nParcels, + d, + volFraction, + rho, + volume + ); + + // Velocity of parcels + vector U = velocity(iParcel, timeInj, owner_.meshInfo()); + + // Determine the injection cell + label cellI = -1; + findInjectorCellAndPosition(cellI, pos); + + if (cellI >= 0) + { + scalar dt = time - timeInj; + td.cloud().addNewParcel(pos, cellI, d, U, nP, dt); + + massInjected_ += nP*rho*mathematicalConstant::pi*pow3(d)/6.0; + nParcelsAdded_++; + } + } + + postInjectCheck(); +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "NewInjectionModel.C" diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.H index 0b00ebeda95c90c63448921a79cdd16e12744962..0df2a5ef6d26ff21a8ac9071fced6cd0ddf5f092 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.H @@ -55,6 +55,21 @@ template<class CloudType> class InjectionModel { +public: + + // Enumerations + + //- Parcel basis representation options + // i.e constant number of particles OR constant mass per parcel + enum parcelBasis + { + pbNumber, + pbMass + }; + + +private: + // Private data //- The cloud dictionary @@ -74,23 +89,46 @@ protected: // Global injection properties //- Start of injection [s] - scalar SOI_; + const scalar SOI_; //- Total volume of parcels to introduce [m^3] // Initialised in the individual injection models scalar volumeTotal_; + //- Total mass to inject [kg] + const scalar massTotal_; + + //- Total mass injected to date [kg] + scalar massInjected_; + + + // Counters + + //- Number of injections counter + label nInjections_; + + //- Running counter of parcels added during each injection + label nParcelsAdded_; + + //- Running counter of total number of parcels added + label nParcelsAddedTotal_; + // Injection properties per Lagrangian time step - //- Time at start of injection time step [s] - scalar timeStep0_; + // Parcel basis + + //- Parcel basis name + const word parcelBasisType_; - //- Number of parcels to introduce [] - label nParcels_; + //- Parcel basis enumeration + parcelBasis parcelBasis_; - //- Volume of parcels to introduce [m^3] - scalar volume_; + //- Continuous phase time at start of injection time step [s] + scalar time0_; + + //- Time at start of injection time step [s] + scalar timeStep0_; // Protected member functions @@ -110,6 +148,37 @@ protected: ) const = 0; + //- Determine properties for next time step/injection interval + void prepareForNextTimeStep + ( + const scalar time0, + const scalar time1, + label& nParcels, + scalar& volume + ); + + //- Find the cell that contains the injector position + // Will modify position slightly towards the owner cell centroid + virtual void findInjectorCellAndPosition + ( + label& cellI, + vector& position + ); + + //- Set number of particles to inject given parcel properties + scalar setNumberOfParticles + ( + const label nParcels, + const scalar diameter, + const scalar volumeFraction, + const scalar rho, + const scalar volume + ); + + //- Post injection checks + void postInjectCheck(); + + public: //- Runtime type information @@ -140,33 +209,31 @@ public: ); - // Destructor - - virtual ~InjectionModel(); + //- Destructor + virtual ~InjectionModel(); - // Selector - - static autoPtr<InjectionModel<CloudType> > New - ( - const dictionary& dict, - CloudType& owner - ); + //- Selector + static autoPtr<InjectionModel<CloudType> > New + ( + const dictionary& dict, + CloudType& owner + ); // Access + //- Return the owner cloud dictionary + inline const dictionary& dict() const; + //- Return const access the owner cloud object - const CloudType& owner() const; + inline const CloudType& owner() const; //- Return non-const access the owner cloud object for manipulation - CloudType& owner(); - - //- Return the dictionary - const dictionary& dict() const; + inline CloudType& owner(); //- Return the coefficients dictionary - const dictionary& coeffDict() const; + inline const dictionary& coeffDict() const; // Member Functions @@ -178,44 +245,41 @@ public: // Global information //- Return the start-of-injection time - scalar timeStart() const; + inline scalar timeStart() const; //- Return the total volume to be injected across the event - scalar volumeTotal() const; + inline scalar volumeTotal() const; + + //- Return mass of particles to introduce + inline scalar massTotal() const; + + //- Return mass of particles injected (cummulative) + inline scalar massInjected() const; //- Return the end-of-injection time virtual scalar timeEnd() const = 0; + // Counters - // Per Lagrangian time step properties + //- Return the number of injections + inline label nInjections() const; - //- Determine properties for next time step/injection interval - void prepareForNextTimeStep - ( - const scalar time0, - const scalar time1 - ); + //- Return the total number parcels added + inline label nParcelsAddedTotal() const; - //- Return the number of parcels to introduce - label nParcels() const; - //- Return the volume of parcels to introduce - scalar volume() const; + // Per-injection event functions + + //- Main injection loop + template<class TrackData> + void inject(TrackData& td); //- Return the volume fraction to introduce - scalar volumeFraction() const; + inline scalar volumeFraction(const scalar volume) const; // Injection geometry - //- Find the cell that contains the injector position - // Will modify position slightly towards the owner cell centroid - virtual void findInjectorCellAndPosition - ( - label& cellI, - vector& position - ); - //- Return the injection position virtual vector position ( @@ -241,6 +305,10 @@ public: }; +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "InjectionModelI.H" + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam