lagrangian: InjectionModel: Time-varying parcel flow rate
The parcelsPerSecond control can now be specified as a time-varying function. This provides additional control over the temporal distribution of injected parcels, which may be advantageous if, for example, the mass flow rate varies significantly. It also enables variable flow rates of particulates in cases which have a fixed number of particles per parcel.
This commit is contained in:
@ -144,10 +144,7 @@ Foam::ConeInjection<CloudType>::ConeInjection
|
||||
injectorTetPt_(-1),
|
||||
duration_(this->readDuration(dict, owner)),
|
||||
massFlowRate_(this->readMassFlowRate(dict, owner, duration_)),
|
||||
parcelsPerSecond_
|
||||
(
|
||||
this->coeffDict().template lookup<scalar>("parcelsPerSecond")
|
||||
),
|
||||
parcelsPerSecond_(this->readParcelsPerSecond(dict, owner)),
|
||||
thetaInner_
|
||||
(
|
||||
TimeFunction1<scalar>
|
||||
@ -263,10 +260,15 @@ Foam::label Foam::ConeInjection<CloudType>::nParcelsToInject
|
||||
if (time0 >= 0 && time0 < duration_)
|
||||
{
|
||||
//// Standard calculation
|
||||
//return floor(parcelsPerSecond_*(time1 - time0));
|
||||
//return floor(parcelsPerSecond_.integral(time0, time1));
|
||||
|
||||
// Modified calculation to make numbers exact
|
||||
return floor(parcelsPerSecond_*time1 - this->parcelsAddedTotal());
|
||||
return
|
||||
floor
|
||||
(
|
||||
parcelsPerSecond_.integral(0, time1)
|
||||
- this->parcelsAddedTotal()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -217,7 +217,7 @@ private:
|
||||
const TimeFunction1<scalar> massFlowRate_;
|
||||
|
||||
//- Number of parcels to introduce per second
|
||||
const label parcelsPerSecond_;
|
||||
const TimeFunction1<scalar> parcelsPerSecond_;
|
||||
|
||||
//- Inner half-cone angle relative to SOI [deg]
|
||||
const TimeFunction1<scalar> thetaInner_;
|
||||
|
||||
@ -99,9 +99,12 @@ Foam::InjectionModel<CloudType>::readMassFlowRate
|
||||
{
|
||||
const Time& time = owner.mesh().time();
|
||||
|
||||
const bool haveMassFlowRate = dict.found("massFlowRate");
|
||||
const bool haveMassTotal = dict.found("massTotal");
|
||||
|
||||
if (dict.found("nParticle"))
|
||||
{
|
||||
if (dict.found("massFlowRate") || dict.found("massTotal"))
|
||||
if (haveMassFlowRate || haveMassTotal)
|
||||
{
|
||||
IOWarningInFunction(dict)
|
||||
<< "If nParticle is specified then massFlowRate and massTotal "
|
||||
@ -116,7 +119,21 @@ Foam::InjectionModel<CloudType>::readMassFlowRate
|
||||
);
|
||||
}
|
||||
|
||||
if (owner.solution().steadyState())
|
||||
if (owner.solution().steadyState() && haveMassTotal)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Cannot specify the massTotal of a steady injection. Use "
|
||||
<< "massFlowRate instead." << exit(FatalIOError);
|
||||
}
|
||||
|
||||
if (haveMassFlowRate && haveMassTotal)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Cannot specify both massFlowRate and massTotal. Use one or "
|
||||
<< "the other." << exit(FatalIOError);
|
||||
}
|
||||
|
||||
if (owner.solution().steadyState() || haveMassFlowRate)
|
||||
{
|
||||
return TimeFunction1<scalar>(time, "massFlowRate", dict);
|
||||
}
|
||||
@ -153,6 +170,20 @@ Foam::InjectionModel<CloudType>::readMassFlowRate
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
Foam::TimeFunction1<Foam::scalar>
|
||||
Foam::InjectionModel<CloudType>::readParcelsPerSecond
|
||||
(
|
||||
const dictionary& dict,
|
||||
CloudType& owner
|
||||
)
|
||||
{
|
||||
const Time& time = owner.mesh().time();
|
||||
|
||||
return TimeFunction1<scalar>(time, "parcelsPerSecond", dict);
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
Foam::label Foam::InjectionModel<CloudType>::index() const
|
||||
{
|
||||
|
||||
@ -137,6 +137,14 @@ protected:
|
||||
const scalar duration
|
||||
);
|
||||
|
||||
//- Read the number of parcels injected per second for continuous
|
||||
// injections
|
||||
TimeFunction1<scalar> readParcelsPerSecond
|
||||
(
|
||||
const dictionary& dict,
|
||||
CloudType& owner
|
||||
);
|
||||
|
||||
//- Get the index of this injector
|
||||
label index() const;
|
||||
|
||||
|
||||
@ -39,10 +39,7 @@ Foam::MomentumLookupTableInjection<CloudType>::MomentumLookupTableInjection
|
||||
InjectionModel<CloudType>(dict, owner, modelName, typeName),
|
||||
inputFileName_(this->coeffDict().lookup("inputFile")),
|
||||
duration_(this->readDuration(dict, owner)),
|
||||
parcelsPerSecond_
|
||||
(
|
||||
this->coeffDict().template lookup<scalar>("parcelsPerSecond")
|
||||
),
|
||||
parcelsPerSecond_(this->readParcelsPerSecond(dict, owner)),
|
||||
randomise_(readBool(this->coeffDict().lookup("randomise"))),
|
||||
injectors_
|
||||
(
|
||||
@ -131,7 +128,12 @@ Foam::label Foam::MomentumLookupTableInjection<CloudType>::nParcelsToInject
|
||||
{
|
||||
if (time0 >= 0 && time0 < duration_)
|
||||
{
|
||||
return floor(injectorCells_.size()*(time1 - time0)*parcelsPerSecond_);
|
||||
return
|
||||
floor
|
||||
(
|
||||
injectorCells_.size()
|
||||
*parcelsPerSecond_.integral(time0, time1)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -80,7 +80,7 @@ class MomentumLookupTableInjection
|
||||
const scalar duration_;
|
||||
|
||||
//- Number of parcels per injector - common to all injection sources
|
||||
const scalar parcelsPerSecond_;
|
||||
const TimeFunction1<scalar> parcelsPerSecond_;
|
||||
|
||||
//- Flag to indicate to randomise injection positions
|
||||
bool randomise_;
|
||||
|
||||
@ -41,10 +41,7 @@ Foam::PatchInjection<CloudType>::PatchInjection
|
||||
patchInjectionBase(owner.mesh(), this->coeffDict().lookup("patchName")),
|
||||
duration_(this->readDuration(dict, owner)),
|
||||
massFlowRate_(this->readMassFlowRate(dict, owner, duration_)),
|
||||
parcelsPerSecond_
|
||||
(
|
||||
this->coeffDict().template lookup<scalar>("parcelsPerSecond")
|
||||
),
|
||||
parcelsPerSecond_(this->readParcelsPerSecond(dict, owner)),
|
||||
U0_(this->coeffDict().lookup("U0")),
|
||||
sizeDistribution_
|
||||
(
|
||||
@ -106,7 +103,7 @@ Foam::label Foam::PatchInjection<CloudType>::nParcelsToInject
|
||||
{
|
||||
if (time0 >= 0 && time0 < duration_)
|
||||
{
|
||||
scalar nParcels = (time1 - time0)*parcelsPerSecond_;
|
||||
scalar nParcels = parcelsPerSecond_.integral(time0, time1);
|
||||
|
||||
Random& rnd = this->owner().rndGen();
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ class PatchInjection
|
||||
const TimeFunction1<scalar> massFlowRate_;
|
||||
|
||||
//- Number of parcels to introduce per second []
|
||||
const label parcelsPerSecond_;
|
||||
const TimeFunction1<scalar> parcelsPerSecond_;
|
||||
|
||||
//- Initial parcel velocity [m/s]
|
||||
const vector U0_;
|
||||
|
||||
@ -38,10 +38,7 @@ Foam::ReactingLookupTableInjection<CloudType>::ReactingLookupTableInjection
|
||||
InjectionModel<CloudType>(dict, owner, modelName, typeName),
|
||||
inputFileName_(this->coeffDict().lookup("inputFile")),
|
||||
duration_(this->readDuration(dict, owner)),
|
||||
parcelsPerSecond_
|
||||
(
|
||||
this->coeffDict().template lookup<scalar>("parcelsPerSecond")
|
||||
),
|
||||
parcelsPerSecond_(this->readParcelsPerSecond(dict, owner)),
|
||||
randomise_(readBool(this->coeffDict().lookup("randomise"))),
|
||||
injectors_
|
||||
(
|
||||
@ -131,7 +128,12 @@ Foam::label Foam::ReactingLookupTableInjection<CloudType>::nParcelsToInject
|
||||
{
|
||||
if (time0 >= 0 && time0 < duration_)
|
||||
{
|
||||
return floor(injectorCells_.size()*(time1 - time0)*parcelsPerSecond_);
|
||||
return
|
||||
floor
|
||||
(
|
||||
injectorCells_.size()
|
||||
*parcelsPerSecond_.integral(time0, time1)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -79,7 +79,7 @@ class ReactingLookupTableInjection
|
||||
const scalar duration_;
|
||||
|
||||
//- Number of parcels per injector - common to all injection sources
|
||||
const scalar parcelsPerSecond_;
|
||||
const TimeFunction1<scalar> parcelsPerSecond_;
|
||||
|
||||
//- Flag to indicate to randomise injection positions
|
||||
bool randomise_;
|
||||
|
||||
@ -39,10 +39,7 @@ ReactingMultiphaseLookupTableInjection
|
||||
InjectionModel<CloudType>(dict, owner, modelName, typeName),
|
||||
inputFileName_(this->coeffDict().lookup("inputFile")),
|
||||
duration_(this->readDuration(dict, owner)),
|
||||
parcelsPerSecond_
|
||||
(
|
||||
this->coeffDict().template lookup<scalar>("parcelsPerSecond")
|
||||
),
|
||||
parcelsPerSecond_(this->readParcelsPerSecond(dict, owner)),
|
||||
randomise_(readBool(this->coeffDict().lookup("randomise"))),
|
||||
injectors_
|
||||
(
|
||||
@ -136,7 +133,12 @@ Foam::ReactingMultiphaseLookupTableInjection<CloudType>::nParcelsToInject
|
||||
{
|
||||
if (time0 >= 0 && time0 < duration_)
|
||||
{
|
||||
return floor(injectorCells_.size()*(time1 - time0)*parcelsPerSecond_);
|
||||
return
|
||||
floor
|
||||
(
|
||||
injectorCells_.size()
|
||||
*parcelsPerSecond_.integral(time0, time1)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -82,7 +82,7 @@ class ReactingMultiphaseLookupTableInjection
|
||||
const scalar duration_;
|
||||
|
||||
//- Number of parcels per injector - common to all injection sources
|
||||
const scalar parcelsPerSecond_;
|
||||
const TimeFunction1<scalar> parcelsPerSecond_;
|
||||
|
||||
//- Flag to indicate to randomise injection positions
|
||||
bool randomise_;
|
||||
|
||||
@ -39,10 +39,7 @@ Foam::ThermoLookupTableInjection<CloudType>::ThermoLookupTableInjection
|
||||
InjectionModel<CloudType>(dict, owner, modelName, typeName),
|
||||
inputFileName_(this->coeffDict().lookup("inputFile")),
|
||||
duration_(this->readDuration(dict, owner)),
|
||||
parcelsPerSecond_
|
||||
(
|
||||
this->coeffDict().template lookup<scalar>("parcelsPerSecond")
|
||||
),
|
||||
parcelsPerSecond_(this->readParcelsPerSecond(dict, owner)),
|
||||
randomise_(readBool(this->coeffDict().lookup("randomise"))),
|
||||
injectors_
|
||||
(
|
||||
@ -132,7 +129,12 @@ Foam::label Foam::ThermoLookupTableInjection<CloudType>::nParcelsToInject
|
||||
{
|
||||
if (time0 >= 0 && time0 < duration_)
|
||||
{
|
||||
return floor(injectorCells_.size()*(time1 - time0)*parcelsPerSecond_);
|
||||
return
|
||||
floor
|
||||
(
|
||||
injectorCells_.size()
|
||||
*parcelsPerSecond_.integral(time0, time1)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -78,7 +78,7 @@ class ThermoLookupTableInjection
|
||||
const scalar duration_;
|
||||
|
||||
//- Number of parcels per injector - common to all injection sources
|
||||
const scalar parcelsPerSecond_;
|
||||
const TimeFunction1<scalar> parcelsPerSecond_;
|
||||
|
||||
//- Flag to indicate to randomise injection positions
|
||||
bool randomise_;
|
||||
|
||||
@ -69,7 +69,7 @@ subModels
|
||||
model1
|
||||
{
|
||||
type patchInjection;
|
||||
massTotal 40;
|
||||
massFlowRate 10;
|
||||
SOI 1;
|
||||
uniformParcelSize volume;
|
||||
patchName inlet;
|
||||
|
||||
@ -79,31 +79,15 @@ subModels
|
||||
mu 650e-6;
|
||||
sigma 25e-6;
|
||||
}
|
||||
flowRateProfile constant 1;
|
||||
SOI 0;
|
||||
duration 60;
|
||||
}
|
||||
|
||||
model2
|
||||
{
|
||||
type patchInjection;
|
||||
$model1;
|
||||
patchName upperInlet;
|
||||
U0 (18.7939 -6.8404 0);
|
||||
nParticle 1;
|
||||
parcelsPerSecond 1390885;
|
||||
sizeDistribution
|
||||
{
|
||||
type normal;
|
||||
Q 0;
|
||||
min 500e-6;
|
||||
max 800e-6;
|
||||
mu 650e-6;
|
||||
sigma 25e-6;
|
||||
}
|
||||
flowRateProfile constant 1;
|
||||
massTotal 0;
|
||||
SOI 0;
|
||||
duration 60;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -77,7 +77,6 @@ subModels
|
||||
model1
|
||||
{
|
||||
type reactingLookupTableInjection;
|
||||
massTotal 0.5;
|
||||
uniformParcelSize volume;
|
||||
SOI 0;
|
||||
inputFile "parcelInjectionProperties";
|
||||
|
||||
@ -77,7 +77,6 @@ subModels
|
||||
model1
|
||||
{
|
||||
type thermoLookupTableInjection;
|
||||
massTotal 100;
|
||||
uniformParcelSize volume;
|
||||
SOI 0;
|
||||
inputFile "parcelInjectionProperties";
|
||||
|
||||
@ -77,12 +77,12 @@ subModels
|
||||
model1
|
||||
{
|
||||
type coneInjection;
|
||||
SOI 0.000;
|
||||
duration 20.000;
|
||||
SOI 0;
|
||||
duration 20;
|
||||
position (0.3 0.35 1.45);
|
||||
direction (0 0 -1);
|
||||
|
||||
massTotal 10;
|
||||
massFlowRate 0.5;
|
||||
parcelsPerSecond 1000;
|
||||
uniformParcelSize volume;
|
||||
flowRateProfile constant 0.1;
|
||||
|
||||
@ -77,7 +77,6 @@ subModels
|
||||
model1
|
||||
{
|
||||
type reactingLookupTableInjection;
|
||||
massTotal 0.1;
|
||||
uniformParcelSize volume;
|
||||
SOI 0.01;
|
||||
inputFile "parcelInjectionProperties";
|
||||
|
||||
@ -77,7 +77,6 @@ subModels
|
||||
model1
|
||||
{
|
||||
type reactingLookupTableInjection;
|
||||
massTotal 1e-2;
|
||||
uniformParcelSize volume;
|
||||
SOI 0.5;
|
||||
inputFile "parcelInjectionProperties";
|
||||
|
||||
@ -78,7 +78,7 @@ subModels
|
||||
{
|
||||
type patchInjection;
|
||||
SOI 0.01;
|
||||
massTotal 8;
|
||||
massFlowRate 16;
|
||||
uniformParcelSize volume;
|
||||
patchName inletCentral;
|
||||
duration 10000;
|
||||
|
||||
Reference in New Issue
Block a user