1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "ConeInjection.H"
27 #include "DataEntry.H"
28 #include "mathematicalConstants.H"
29 #include "unitConversion.H"
31 using namespace Foam::constant::mathematical;
33 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 template<class CloudType>
36 Foam::ConeInjection<CloudType>::ConeInjection
38 const dictionary& dict,
42 InjectionModel<CloudType>(dict, owner, typeName),
43 positionAxis_(this->coeffDict().lookup("positionAxis")),
44 injectorCells_(positionAxis_.size()),
45 injectorTetFaces_(positionAxis_.size()),
46 injectorTetPts_(positionAxis_.size()),
47 duration_(readScalar(this->coeffDict().lookup("duration"))),
50 readScalar(this->coeffDict().lookup("parcelsPerInjector"))
54 DataEntry<scalar>::New("flowRateProfile", this->coeffDict())
56 Umag_(DataEntry<scalar>::New("Umag", this->coeffDict())),
57 thetaInner_(DataEntry<scalar>::New("thetaInner", this->coeffDict())),
58 thetaOuter_(DataEntry<scalar>::New("thetaOuter", this->coeffDict())),
61 distributionModels::distributionModel::New
63 this->coeffDict().subDict("sizeDistribution"), owner.rndGen()
66 nInjected_(this->parcelsAddedTotal()),
67 tanVec1_(positionAxis_.size()),
68 tanVec2_(positionAxis_.size())
70 // Normalise direction vector and determine direction vectors
71 // tangential to injector axis direction
72 forAll(positionAxis_, i)
74 vector& axis = positionAxis_[i].second();
78 vector tangent = vector::zero;
79 scalar magTangent = 0.0;
81 cachedRandom& rnd = this->owner().rndGen();
82 while (magTangent < SMALL)
84 vector v = rnd.sample01<vector>();
86 tangent = v - (v & axis)*axis;
87 magTangent = mag(tangent);
90 tanVec1_[i] = tangent/magTangent;
91 tanVec2_[i] = axis^tanVec1_[i];
94 // Set total volume to inject
95 this->volumeTotal_ = flowRateProfile_().integrate(0.0, duration_);
97 // Set/cache the injector cells
98 forAll(positionAxis_, i)
100 this->findCellAtPosition
103 injectorTetFaces_[i],
105 positionAxis_[i].first()
111 template<class CloudType>
112 Foam::ConeInjection<CloudType>::ConeInjection
114 const ConeInjection<CloudType>& im
117 InjectionModel<CloudType>(im),
118 positionAxis_(im.positionAxis_),
119 injectorCells_(im.injectorCells_),
120 injectorTetFaces_(im.injectorTetFaces_),
121 injectorTetPts_(im.injectorTetPts_),
122 duration_(im.duration_),
123 parcelsPerInjector_(im.parcelsPerInjector_),
124 flowRateProfile_(im.flowRateProfile_().clone().ptr()),
125 Umag_(im.Umag_().clone().ptr()),
126 thetaInner_(im.thetaInner_().clone().ptr()),
127 thetaOuter_(im.thetaOuter_().clone().ptr()),
128 sizeDistribution_(im.sizeDistribution_().clone().ptr()),
129 nInjected_(im.nInjected_),
130 tanVec1_(im.tanVec1_),
131 tanVec2_(im.tanVec2_)
135 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
137 template<class CloudType>
138 Foam::ConeInjection<CloudType>::~ConeInjection()
142 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
144 template<class CloudType>
145 Foam::scalar Foam::ConeInjection<CloudType>::timeEnd() const
147 return this->SOI_ + duration_;
151 template<class CloudType>
152 Foam::label Foam::ConeInjection<CloudType>::parcelsToInject
158 if ((time0 >= 0.0) && (time0 < duration_))
160 const scalar targetVolume = flowRateProfile_().integrate(0, time1);
162 const label targetParcels =
163 parcelsPerInjector_*targetVolume/this->volumeTotal_;
165 const label nToInject = targetParcels - nInjected_;
167 nInjected_ += nToInject;
169 return positionAxis_.size()*nToInject;
178 template<class CloudType>
179 Foam::scalar Foam::ConeInjection<CloudType>::volumeToInject
185 if ((time0 >= 0.0) && (time0 < duration_))
187 return flowRateProfile_().integrate(time0, time1);
196 template<class CloudType>
197 void Foam::ConeInjection<CloudType>::setPositionAndCell
208 const label i = parcelI % positionAxis_.size();
210 position = positionAxis_[i].first();
211 cellOwner = injectorCells_[i];
212 tetFaceI = injectorTetFaces_[i];
213 tetPtI = injectorTetPts_[i];
217 template<class CloudType>
218 void Foam::ConeInjection<CloudType>::setProperties
223 typename CloudType::parcelType& parcel
226 cachedRandom& rnd = this->owner().rndGen();
228 // set particle velocity
229 const label i = parcelI % positionAxis_.size();
231 scalar t = time - this->SOI_;
232 scalar ti = thetaInner_().value(t);
233 scalar to = thetaOuter_().value(t);
234 scalar coneAngle = degToRad(rnd.position<scalar>(ti, to));
236 scalar alpha = sin(coneAngle);
237 scalar dcorr = cos(coneAngle);
238 scalar beta = twoPi*rnd.sample01<scalar>();
240 vector normal = alpha*(tanVec1_[i]*cos(beta) + tanVec2_[i]*sin(beta));
241 vector dirVec = dcorr*positionAxis_[i].second();
243 dirVec /= mag(dirVec);
245 parcel.U() = Umag_().value(t)*dirVec;
247 // set particle diameter
248 parcel.d() = sizeDistribution_().sample();
252 template<class CloudType>
253 bool Foam::ConeInjection<CloudType>::fullyDescribed() const
259 template<class CloudType>
260 bool Foam::ConeInjection<CloudType>::validInjection(const label)
266 // ************************************************************************* //