Bug fix supplied by Niklas Nordin:
[OpenFOAM-1.5.x.git] / src / lagrangian / dieselSpray / injector / swirlInjector / swirlInjector.C
blob2d9fa9bf7c0bae992d97bb7d131d43c9bd712f54
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "swirlInjector.H"
28 #include "addToRunTimeSelectionTable.H"
29 #include "Random.H"
30 #include "mathematicalConstants.H"
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 namespace Foam
36     defineTypeNameAndDebug(swirlInjector, 0);
38     addToRunTimeSelectionTable
39     (
40         injectorType,
41         swirlInjector,
42         dictionary
43     );
47 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
49 Foam::swirlInjector::swirlInjector
51     const Foam::Time& t,
52     const Foam::dictionary& dict
55     injectorType(t, dict),
56     propsDict_(dict.subDict(typeName + "Props")),
57     position_(propsDict_.lookup("position")),
58     direction_(propsDict_.lookup("direction")),
59     d_(readScalar(propsDict_.lookup("diameter"))),
60     mass_(readScalar(propsDict_.lookup("mass"))),
61     injectionPressure_(readScalar(propsDict_.lookup("injectionPressure"))),
62     T_(readScalar(propsDict_.lookup("temperature"))),
63     nParcels_(readLabel(propsDict_.lookup("nParcels"))),
64     X_(propsDict_.lookup("X")),
65     massFlowRateProfile_(propsDict_.lookup("massFlowRateProfile")),
66     injectionPressureProfile_(propsDict_.lookup("injectionPressureProfile")),
67     velocityProfile_(massFlowRateProfile_),
68     CdProfile_(massFlowRateProfile_),
69     TProfile_(massFlowRateProfile_),
70     averageParcelMass_(mass_/nParcels_),
71     pressureIndependentVelocity_(false)
73     // convert CA to real time
74     forAll(massFlowRateProfile_, i)
75     {
76         massFlowRateProfile_[i][0] =
77             t.userTimeToTime(massFlowRateProfile_[i][0]);
78     }
79     forAll(injectionPressureProfile_, i)
80     {
81         injectionPressureProfile_[i][0] =
82             t.userTimeToTime(injectionPressureProfile_[i][0]);
83     }
85     // check if time entries match
86     if (mag(massFlowRateProfile_[0][0]-injectionPressureProfile_[0][0]) > SMALL)
87     {
88         FatalErrorIn
89         (
90             "swirlInjector::swirlInjector(const time& t, const dictionary dict)"
91         )   << "Start-times do not match for "
92                "injectionPressureProfile and massFlowRateProfile."
93             << abort(FatalError);
94     }
96     // check if time entries match
97     if
98     (
99         mag
100         (
101             massFlowRateProfile_[massFlowRateProfile_.size() - 1][0]
102           - injectionPressureProfile_[injectionPressureProfile_.size() - 1][0]
103         ) > SMALL
104     )
105     {
106         FatalErrorIn
107         (
108             "swirlInjector::swirlInjector(const time& t, const dictionary dict)"
109         )   << "End-times do not match for "
110                "injectionPressureProfile and massFlowRateProfile."
111             << abort(FatalError);
112     }
114     scalar integratedMFR = integrateTable(massFlowRateProfile_);
115     scalar integratedPressure =
116         integrateTable(injectionPressureProfile_)/(teoi()-tsoi());
118     forAll(massFlowRateProfile_, i)
119     {
120         // correct the massFlowRateProfile to match the injected mass
121         massFlowRateProfile_[i][1] *= mass_/integratedMFR;
123         velocityProfile_[i][0] = massFlowRateProfile_[i][0];
125         TProfile_[i][0] = massFlowRateProfile_[i][0];
126         TProfile_[i][1] = T_;
128         CdProfile_[i][0] = massFlowRateProfile_[i][0];
130     }
132     forAll(injectionPressureProfile_, i)
133     {
134         // correct the pressureProfile to match the injection pressure
135         injectionPressureProfile_[i][1] *=
136             injectionPressure_/integratedPressure;
137     }
139     // Normalize the direction vector
140     direction_ /= mag(direction_);
142     setTangentialVectors();
144     // check molar fractions
145     scalar Xsum = 0.0;
146     forAll(X_, i)
147     {
148         Xsum += X_[i];
149     }
151     if (mag(Xsum - 1.0) > SMALL)
152     {
153         WarningIn
154         (
155             "swirlInjector::swirlInjector(const time& t, const dictionary dict)"
156         )   << "X does not add up to 1.0, correcting molar fractions." << endl;
158         forAll(X_, i)
159         {
160             X_[i] /= Xsum;
161         }
162     }
166 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
168 Foam::swirlInjector::~swirlInjector()
172 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
174 void Foam::swirlInjector::setTangentialVectors()
176     Random rndGen(label(0));
177     scalar magV = 0.0;
178     vector tangent;
180     while (magV < SMALL)
181     {
182         vector testThis = rndGen.vector01();
184         tangent = testThis - (testThis & direction_)*direction_;
185         magV = mag(tangent);
186     }
188     tangentialInjectionVector1_ = tangent/magV;
189     tangentialInjectionVector2_ = direction_ ^ tangentialInjectionVector1_;
192 Foam::label Foam::swirlInjector::nParcelsToInject
194     const scalar time0,
195     const scalar time1
196 ) const
199     scalar mInj = mass_*(fractionOfInjection(time1)-fractionOfInjection(time0));
200     label nParcels = label(mInj/averageParcelMass_ + 0.49);
202     return nParcels;
205 const Foam::vector Foam::swirlInjector::position(const label n) const
207     return position_;
210 Foam::vector Foam::swirlInjector::position
212     const label n,
213     const scalar time,
214     const bool twoD,
215     const scalar angleOfWedge,
216     const vector& axisOfSymmetry,
217     const vector& axisOfWedge,
218     const vector& axisOfWedgeNormal,
219     Random& rndGen
220 ) const
222     if (twoD)
223     {
224         scalar is = position_ & axisOfSymmetry;
225         scalar magInj = mag(position_ - is*axisOfSymmetry);
227         vector halfWedge =
228             axisOfWedge*cos(0.5*angleOfWedge)
229           + axisOfWedgeNormal*sin(0.5*angleOfWedge);
230         halfWedge /= mag(halfWedge);
232         return (is*axisOfSymmetry + magInj*halfWedge);
233     }
234     else
235     {
236         // otherwise, disc injection
237         scalar iRadius = d_*rndGen.scalar01();
238         scalar iAngle = 2.0*mathematicalConstant::pi*rndGen.scalar01();
240         return
241         (
242             position_
243           + iRadius
244           * (
245               tangentialInjectionVector1_*cos(iAngle)
246             + tangentialInjectionVector2_*sin(iAngle)
247           )
248         );
250     }
252     return position_;
255 Foam::label Foam::swirlInjector::nHoles() const
257     return 1;
260 Foam::scalar Foam::swirlInjector::d() const
262     return d_;
265 const Foam::vector& Foam::swirlInjector::direction
267     const label i,
268     const scalar time
269 ) const
271     return direction_;
274 Foam::scalar Foam::swirlInjector::mass
276     const scalar time0,
277     const scalar time1,
278     const bool twoD,
279     const scalar angleOfWedge
280 ) const
282     scalar mInj = mass_*(fractionOfInjection(time1)-fractionOfInjection(time0));
284     // correct mass if calculation is 2D
285     if (twoD)
286     {
287         mInj *= 0.5*angleOfWedge/mathematicalConstant::pi;
288     }
290     return mInj;
293 Foam::scalar Foam::swirlInjector::mass() const
295     return mass_;
298 Foam::List<Foam::swirlInjector::pair>
299 Foam::swirlInjector::massFlowRateProfile() const
301     return massFlowRateProfile_;
304 Foam::scalar Foam::swirlInjector::massFlowRate(const scalar time) const
306     return getTableValue(massFlowRateProfile_, time);
309 Foam::List<Foam::swirlInjector::pair>
310 Foam::swirlInjector::injectionPressureProfile() const
312     return injectionPressureProfile_;
315 Foam::scalar Foam::swirlInjector::injectionPressure(const scalar time) const
317     return getTableValue(injectionPressureProfile_, time);
320 Foam::List<Foam::swirlInjector::pair>
321 Foam::swirlInjector::velocityProfile() const
323     return velocityProfile_;
326 Foam::scalar Foam::swirlInjector::velocity(const scalar time) const
328     return getTableValue(velocityProfile_, time);
331 Foam::List<Foam::swirlInjector::pair> Foam::swirlInjector::CdProfile() const
333     return CdProfile_;
336 Foam::scalar Foam::swirlInjector::Cd(const scalar time) const
338     return getTableValue(CdProfile_, time);
341 const Foam::scalarField& Foam::swirlInjector::X() const
343     return X_;
346 Foam::List<Foam::swirlInjector::pair> Foam::swirlInjector::T() const
348     return TProfile_;
351 Foam::scalar Foam::swirlInjector::T(const scalar time) const
353     return T_;
356 Foam::scalar Foam::swirlInjector::tsoi() const
358     return massFlowRateProfile_[0][0];
361 Foam::scalar Foam::swirlInjector::teoi() const
363     return massFlowRateProfile_[massFlowRateProfile_.size()-1][0];
366 Foam::scalar Foam::swirlInjector::fractionOfInjection(const scalar time) const
368     return integrateTable(massFlowRateProfile_, time)/mass_;
371 Foam::scalar Foam::swirlInjector::injectedMass
373     const scalar t
374 ) const
376     return mass_*fractionOfInjection(t);
379 void Foam::swirlInjector::correctProfiles
381     const liquidMixture& fuel,
382     const scalar referencePressure
386     scalar A = 0.25*mathematicalConstant::pi*pow(d_, 2.0);
387     scalar pDummy = 1.0e+5;
388     scalar rho = fuel.rho(pDummy, T_, X_);
390     forAll(velocityProfile_, i)
391     {
392         scalar Pinj = getTableValue
393         (
394             injectionPressureProfile_,
395             massFlowRateProfile_[i][0]
396         );
397         scalar mfr = massFlowRateProfile_[i][1]/(rho*A);
398         scalar v = sqrt(2.0*(Pinj - referencePressure)/rho);
399         velocityProfile_[i][1] = v;
400         CdProfile_[i][1] = mfr/v;
401     }
404 Foam::vector Foam::swirlInjector::tan1(const label n) const
406     return tangentialInjectionVector1_;
409 Foam::vector Foam::swirlInjector::tan2(const label n) const
411     return tangentialInjectionVector2_;
415 // ************************************************************************* //