diff --git a/src/lagrangian/intermediate/parcels/include/makeParcelInjectionModels.H b/src/lagrangian/intermediate/parcels/include/makeParcelInjectionModels.H index 76e6c0b5d1..d1b28c39df 100644 --- a/src/lagrangian/intermediate/parcels/include/makeParcelInjectionModels.H +++ b/src/lagrangian/intermediate/parcels/include/makeParcelInjectionModels.H @@ -30,6 +30,7 @@ License #include "CellZoneInjection.H" #include "ConeInjection.H" +#include "ConeNozzleInjection.H" #include "FieldActivatedInjection.H" #include "InflationInjection.H" #include "KinematicLookupTableInjection.H" diff --git a/src/lagrangian/intermediate/parcels/include/makeReactingMultiphaseParcelInjectionModels.H b/src/lagrangian/intermediate/parcels/include/makeReactingMultiphaseParcelInjectionModels.H index 6dc5f69610..f77e3824f8 100644 --- a/src/lagrangian/intermediate/parcels/include/makeReactingMultiphaseParcelInjectionModels.H +++ b/src/lagrangian/intermediate/parcels/include/makeReactingMultiphaseParcelInjectionModels.H @@ -30,6 +30,7 @@ License #include "CellZoneInjection.H" #include "ConeInjection.H" +#include "ConeNozzleInjection.H" #include "FieldActivatedInjection.H" #include "ManualInjection.H" #include "NoInjection.H" diff --git a/src/lagrangian/intermediate/parcels/include/makeReactingParcelInjectionModels.H b/src/lagrangian/intermediate/parcels/include/makeReactingParcelInjectionModels.H index 274f92e36e..b58f36322e 100644 --- a/src/lagrangian/intermediate/parcels/include/makeReactingParcelInjectionModels.H +++ b/src/lagrangian/intermediate/parcels/include/makeReactingParcelInjectionModels.H @@ -30,6 +30,7 @@ License #include "CellZoneInjection.H" #include "ConeInjection.H" +#include "ConeNozzleInjection.H" #include "FieldActivatedInjection.H" #include "ManualInjection.H" #include "NoInjection.H" diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C new file mode 100644 index 0000000000..28ca032f2e --- /dev/null +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C @@ -0,0 +1,376 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "ConeNozzleInjection.H" +#include "DataEntry.H" +#include "mathematicalConstants.H" +#include "distributionModel.H" + +using namespace Foam::constant; + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::ConeNozzleInjection::ConeNozzleInjection +( + const dictionary& dict, + CloudType& owner +) +: + InjectionModel(dict, owner, typeName), + injectionMethod_(imPoint), + outerNozzleDiameter_ + ( + readScalar(this->coeffDict().lookup("outerNozzleDiameter")) + ), + innerNozzleDiameter_ + ( + readScalar(this->coeffDict().lookup("innerNozzleDiameter")) + ), + duration_(readScalar(this->coeffDict().lookup("duration"))), + position_(this->coeffDict().lookup("position")), + injectorCell_(-1), + tetFaceI_(-1), + tetPtI_(-1), + direction_(this->coeffDict().lookup("direction")), + parcelsPerSecond_ + ( + readScalar(this->coeffDict().lookup("parcelsPerSecond")) + ), + volumeFlowRate_ + ( + DataEntry::New + ( + "volumeFlowRate", + this->coeffDict() + ) + ), + Cd_ + ( + DataEntry::New + ( + "Cd", + this->coeffDict() + ) + ), + thetaInner_ + ( + DataEntry::New + ( + "thetaInner", + this->coeffDict() + ) + ), + thetaOuter_ + ( + DataEntry::New + ( + "thetaOuter", + this->coeffDict() + ) + ), + sizeDistribution_ + ( + distributionModels::distributionModel::New + ( + this->coeffDict().subDict("sizeDistribution"), + owner.rndGen() + ) + ), + tanVec1_(vector::zero), + tanVec2_(vector::zero), + normal_(vector::zero) +{ + if (innerNozzleDiameter_ >= outerNozzleDiameter_) + { + FatalErrorIn + ( + "Foam::ConeNozzleInjection::ConeNozzleInjection" + "(" + "const dictionary&, " + "CloudType&" + ")" + )<< "innerNozzleDiameter >= outerNozzleDiameter" << nl + << exit(FatalError); + } + + word injectionMethodType = this->coeffDict().lookup("injectionMethod"); + + if (injectionMethodType == "disc") + { + injectionMethod_ = imDisc; + } + else if (injectionMethodType == "point") + { + injectionMethod_ = imPoint; + + // Set/cache the injector cell + this->findCellAtPosition + ( + injectorCell_, + tetFaceI_, + tetPtI_, + position_, + false + ); + } + else + { + FatalErrorIn + ( + "Foam::InjectionModel::InjectionModel" + "(" + "const dictionary&, " + "CloudType&" + ")" + )<< "injectionMethod must be either 'point' or 'disc'" << nl + << exit(FatalError); + } + + cachedRandom& rndGen = this->owner().rndGen(); + + // Normalise direction vector + direction_ /= mag(direction_); + + // Determine direction vectors tangential to direction + vector tangent = vector::zero; + scalar magTangent = 0.0; + + while(magTangent < SMALL) + { + vector v = rndGen.sample01(); + + tangent = v - (v & direction_)*direction_; + magTangent = mag(tangent); + } + + tanVec1_ = tangent/magTangent; + tanVec2_ = direction_^tanVec1_; + + // Set total volume to inject + this->volumeTotal_ = volumeFlowRate_().integrate(0.0, duration_); +} + + +template +Foam::ConeNozzleInjection::ConeNozzleInjection +( + const ConeNozzleInjection& im +) +: + InjectionModel(im), + injectionMethod_(im.injectionMethod_), + outerNozzleDiameter_(im.outerNozzleDiameter_), + innerNozzleDiameter_(im.innerNozzleDiameter_), + duration_(im.duration_), + position_(im.position_), + injectorCell_(im.injectorCell_), + direction_(im.direction_), + parcelsPerSecond_(im.parcelsPerSecond_), + volumeFlowRate_(im.volumeFlowRate_().clone().ptr()), + Cd_(im.Cd_().clone().ptr()), + thetaInner_(im.thetaInner_().clone().ptr()), + thetaOuter_(im.thetaOuter_().clone().ptr()), + sizeDistribution_(im.sizeDistribution_().clone().ptr()), + tanVec1_(im.tanVec1_), + tanVec2_(im.tanVec1_), + normal_(im.normal_) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template +Foam::ConeNozzleInjection::~ConeNozzleInjection() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +Foam::scalar Foam::ConeNozzleInjection::timeEnd() const +{ + return this->SOI_ + duration_; +} + + +template +Foam::label Foam::ConeNozzleInjection::parcelsToInject +( + const scalar time0, + const scalar time1 +) +{ + if ((time0 >= 0.0) && (time0 < duration_)) + { + return floor((time1 - time0)*parcelsPerSecond_); + } + else + { + return 0; + } +} + + +template +Foam::scalar Foam::ConeNozzleInjection::volumeToInject +( + const scalar time0, + const scalar time1 +) +{ + if ((time0 >= 0.0) && (time0 < duration_)) + { + return volumeFlowRate_().integrate(time0, time1); + } + else + { + return 0.0; + } +} + + +template +void Foam::ConeNozzleInjection::setPositionAndCell +( + const label, + const label, + const scalar, + vector& position, + label& cellOwner, + label& tetFaceI, + label& tetPtI +) +{ + cachedRandom& rndGen = this->owner().rndGen(); + + scalar beta = mathematical::twoPi*rndGen.sample01(); + normal_ = tanVec1_*cos(beta) + tanVec2_*sin(beta); + + switch (injectionMethod_) + { + case imPoint: + { + position = position_; + cellOwner = injectorCell_; + tetFaceI = tetFaceI_; + tetPtI = tetPtI_; + + break; + } + case imDisc: + { + scalar frac = rndGen.sample01(); + scalar dr = outerNozzleDiameter_ - innerNozzleDiameter_; + scalar r = 0.5*(innerNozzleDiameter_ + frac*dr); + position = position_ + r*normal_; + + this->findCellAtPosition + ( + cellOwner, + tetFaceI, + tetPtI, + position, + false + ); + break; + } + default: + { + FatalErrorIn + ( + "void Foam::ConeNozzleInjection::setPositionAndCell" + "(" + "const label, " + "const label, " + "const scalar, " + "vector&, " + "label&" + ")" + )<< "Unknown injectionMethod type" << nl + << exit(FatalError); + } + } +} + + +template +void Foam::ConeNozzleInjection::setProperties +( + const label parcelI, + const label, + const scalar time, + typename CloudType::parcelType& parcel +) +{ + cachedRandom& rndGen = this->owner().rndGen(); + + // set particle velocity + const scalar deg2Rad = mathematical::pi/180.0; + + scalar t = time - this->SOI_; + scalar ti = thetaInner_().value(t); + scalar to = thetaOuter_().value(t); + scalar coneAngle = rndGen.sample01()*(to - ti) + ti; + + coneAngle *= deg2Rad; + scalar alpha = sin(coneAngle); + scalar dcorr = cos(coneAngle); + + vector normal = alpha*normal_; + vector dirVec = dcorr*direction_; + dirVec += normal; + dirVec /= mag(dirVec); + + scalar Ao = 0.25*mathematical::pi*outerNozzleDiameter_*outerNozzleDiameter_; + scalar Ai = 0.25*mathematical::pi*innerNozzleDiameter_*innerNozzleDiameter_; + scalar massFlowRate = + this->massTotal()*volumeFlowRate_().value(t)/this->volumeTotal(); + + scalar rho = this->owner().constProps().rho0(); +// scalar Umag = massFlowRate/(parcel.rho()*Cd_().value(t)*(Ao - Ai)); + scalar Umag = massFlowRate/(rho*Cd_().value(t)*(Ao - Ai)); + parcel.U() = Umag*dirVec; + + // set particle diameter + parcel.d() = sizeDistribution_->sample(); +} + + +template +bool Foam::ConeNozzleInjection::fullyDescribed() const +{ + return false; +} + + +template +bool Foam::ConeNozzleInjection::validInjection(const label) +{ + return true; +} + + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.H new file mode 100644 index 0000000000..d5e9a6fc7f --- /dev/null +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.H @@ -0,0 +1,235 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Class + Foam::ConeNozzleInjection + +Description + Cone injection + + - User specifies + - time of start of injection + - injector position + - direction (along injection axis) + - parcel flow rate + - discharge coefficient, Cd + - inner and outer cone angles + + - Parcel diameters obtained by size distribution model + + - Parcel velocity is calculated as: + + U = V_dot/(A * Cd), where V_dot is the volume flow rate + + Based on the old 'unitInjection' model + +SourceFiles + ConeNozzleInjection.C + +\*---------------------------------------------------------------------------*/ + +#ifndef ConeNozzleInjection_H +#define ConeNozzleInjection_H + +#include "InjectionModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes + +template +class DataEntry; + +class distributionModel; + +/*---------------------------------------------------------------------------*\ + Class ConeNozzleInjection Declaration +\*---------------------------------------------------------------------------*/ + +template +class ConeNozzleInjection +: + public InjectionModel +{ +public: + + //- Injection method enumeration + enum injectionMethod + { + imPoint, + imDisc + }; + + +private: + + // Private data + + //- point/disc injection method + injectionMethod injectionMethod_; + + //- Outer nozzle diameter [m] + const scalar outerNozzleDiameter_; + + //- Inner nozzle diameter [m] + const scalar innerNozzleDiameter_; + + //- Injection duration [s] + const scalar duration_; + + //- Injector position [m] + vector position_; + + //- Cell containing injector position [] + label injectorCell_; + + //- Index of tet face for injector cell + label tetFaceI_; + + //- Index of tet point for injector cell + label tetPtI_; + + //- Injector direction [] + vector direction_; + + //- Number of parcels to introduce per second [] + const label parcelsPerSecond_; + + //- Volume flow rate of parcels to introduce relative to SOI [m^3/s] + const autoPtr > volumeFlowRate_; + + //- Discharge coefficient, relative to SOI [m/s] + const autoPtr > Cd_; + + //- Inner cone angle relative to SOI [deg] + const autoPtr > thetaInner_; + + //- Outer cone angle relative to SOI [deg] + const autoPtr > thetaOuter_; + + //- Parcel size PDF model + const autoPtr sizeDistribution_; + + + // Tangential vectors to the direction vector + + //- First tangential vector + vector tanVec1_; + + //- Second tangential vector + vector tanVec2_; + + //- injection vector orthogonal to direction + vector normal_; + + +public: + + //- Runtime type information + TypeName("coneNozzleInjection"); + + + // Constructors + + //- Construct from dictionary + ConeNozzleInjection(const dictionary& dict, CloudType& owner); + + //- Construct copy + ConeNozzleInjection(const ConeNozzleInjection& im); + + //- Construct and return a clone + virtual autoPtr > clone() const + { + return autoPtr > + ( + new ConeNozzleInjection(*this) + ); + } + + + //- Destructor + virtual ~ConeNozzleInjection(); + + + // Member Functions + + //- Return the end-of-injection time + scalar timeEnd() const; + + //- Number of parcels to introduce relative to SOI + virtual label parcelsToInject(const scalar time0, const scalar time1); + + //- Volume of parcels to introduce relative to SOI + virtual scalar volumeToInject(const scalar time0, const scalar time1); + + + // Injection geometry + + //- Set the injection position and owner cell + virtual void setPositionAndCell + ( + const label parcelI, + const label nParcels, + const scalar time, + vector& position, + label& cellOwner, + label& tetFaceI, + label& tetPtI + ); + + //- Set the parcel properties + virtual void setProperties + ( + const label parcelI, + const label nParcels, + const scalar time, + typename CloudType::parcelType& parcel + ); + + //- Flag to identify whether model fully describes the parcel + virtual bool fullyDescribed() const; + + //- Return flag to identify whether or not injection of parcelI is + // permitted + virtual bool validInjection(const label parcelI); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "ConeNozzleInjection.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C index 1f87dc029c..b88107caea 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C @@ -594,7 +594,7 @@ void Foam::InjectionModel::inject(TrackData& td) // Assign new parcel properties in injection model setProperties(parcelI, newParcels, timeInj, *pPtr); - // Check new parcel properties + // Check/set new parcel properties td.cloud().checkParcelProperties(*pPtr, dt, fullyDescribed()); // Apply correction to velocity for 2-D cases diff --git a/src/lagrangian/spray/parcels/include/makeSprayParcelInjectionModels.H b/src/lagrangian/spray/parcels/include/makeSprayParcelInjectionModels.H index 513bd6c213..681ba882b1 100644 --- a/src/lagrangian/spray/parcels/include/makeSprayParcelInjectionModels.H +++ b/src/lagrangian/spray/parcels/include/makeSprayParcelInjectionModels.H @@ -29,11 +29,11 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "ConeInjection.H" +#include "ConeNozzleInjection.H" #include "FieldActivatedInjection.H" #include "ManualInjection.H" #include "NoInjection.H" #include "PatchInjection.H" -//#include "UnitInjection.H" //#include "CommonRailInjection.H" //#include "MultiHoleInjection.H" @@ -43,6 +43,7 @@ License \ makeInjectionModel(CloudType); \ makeInjectionModelType(ConeInjection, CloudType); \ + makeInjectionModelType(ConeNozzleInjection, CloudType); \ makeInjectionModelType(FieldActivatedInjection, CloudType); \ makeInjectionModelType(ManualInjection, CloudType); \ makeInjectionModelType(NoInjection, CloudType); \