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); \