FreeFOAM The Cross-Platform CFD Toolkit
unitInjector.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "unitInjector.H"
28 #include <OpenFOAM/Random.H>
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35  defineTypeNameAndDebug(unitInjector, 0);
36 
38  (
39  injectorType,
40  unitInjector,
41  dictionary
42  );
43 }
44 
45 
46 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
47 
48 // Construct from components
49 Foam::unitInjector::unitInjector
50 (
51  const Foam::Time& t,
52  const Foam::dictionary& dict
53 )
54 :
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  Cd_(readScalar(propsDict_.lookup("Cd"))),
61  mass_(readScalar(propsDict_.lookup("mass"))),
62  nParcels_(readLabel(propsDict_.lookup("nParcels"))),
63  X_(propsDict_.lookup("X")),
64  massFlowRateProfile_(propsDict_.lookup("massFlowRateProfile")),
65  velocityProfile_(massFlowRateProfile_),
66  injectionPressureProfile_(massFlowRateProfile_),
67  CdProfile_(massFlowRateProfile_),
68  TProfile_(propsDict_.lookup("temperatureProfile")),
69  averageParcelMass_(mass_/nParcels_),
70  pressureIndependentVelocity_(true)
71 {
72 
73  // check if time entries for soi and eoi match
74  if (mag(massFlowRateProfile_[0][0]-TProfile_[0][0]) > SMALL)
75  {
77  (
78  "unitInjector::unitInjector(const time& t, const dictionary dict)"
79  )<< "start-times do not match for TemperatureProfile and "
80  << " massFlowRateProfile." << nl << exit (FatalError);
81  }
82 
83  if
84  (
85  mag(massFlowRateProfile_[massFlowRateProfile_.size()-1][0]
86  - TProfile_[TProfile_.size()-1][0])
87  > SMALL
88  )
89  {
91  (
92  "unitInjector::unitInjector(const time& t, const dictionary dict)"
93  )<< "end-times do not match for TemperatureProfile and "
94  << "massFlowRateProfile." << nl << exit(FatalError);
95  }
96 
97  // convert CA to real time
98  forAll(massFlowRateProfile_, i)
99  {
100  massFlowRateProfile_[i][0] =
101  t.userTimeToTime(massFlowRateProfile_[i][0]);
102  velocityProfile_[i][0] = massFlowRateProfile_[i][0];
103  injectionPressureProfile_[i][0] = massFlowRateProfile_[i][0];
104  }
105 
106  forAll(TProfile_, i)
107  {
108  TProfile_[i][0] = t.userTimeToTime(TProfile_[i][0]);
109  }
110 
111  scalar integratedMFR = integrateTable(massFlowRateProfile_);
112 
113  forAll(massFlowRateProfile_, i)
114  {
115  // correct the massFlowRateProfile to match the injected mass
116  massFlowRateProfile_[i][1] *= mass_/integratedMFR;
117 
118  CdProfile_[i][0] = massFlowRateProfile_[i][0];
119  CdProfile_[i][1] = Cd_;
120  }
121 
122  // Normalize the direction vector
123  direction_ /= mag(direction_);
124 
125  setTangentialVectors();
126 
127  // check molar fractions
128  scalar Xsum = 0.0;
129  forAll(X_, i)
130  {
131  Xsum += X_[i];
132  }
133 
134  if (mag(Xsum - 1.0) > SMALL)
135  {
136  WarningIn("unitInjector::unitInjector(const time& t, Istream& is)")
137  << "X does not sum to 1.0, correcting molar fractions."
138  << nl << endl;
139  forAll(X_, i)
140  {
141  X_[i] /= Xsum;
142  }
143  }
144 
145 }
146 
147 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
148 
150 {}
151 
152 
153 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
154 
155 void Foam::unitInjector::setTangentialVectors()
156 {
157  Random rndGen(label(0));
158  scalar magV = 0.0;
159  vector tangent;
160 
161  while (magV < SMALL)
162  {
163  vector testThis = rndGen.vector01();
164 
165  tangent = testThis - (testThis & direction_)*direction_;
166  magV = mag(tangent);
167  }
168 
169  tangentialInjectionVector1_ = tangent/magV;
170  tangentialInjectionVector2_ = direction_ ^ tangentialInjectionVector1_;
171 
172 }
173 
174 
176 (
177  const scalar time0,
178  const scalar time1
179 ) const
180 {
181  scalar mInj = mass_*(fractionOfInjection(time1)-fractionOfInjection(time0));
182  label nParcels = label(mInj/averageParcelMass_ + 0.49);
183  return nParcels;
184 }
185 
186 
187 const Foam::vector Foam::unitInjector::position(const label n) const
188 {
189  return position_;
190 }
191 
192 
194 (
195  const label n,
196  const scalar time,
197  const bool twoD,
198  const scalar angleOfWedge,
199  const vector& axisOfSymmetry,
200  const vector& axisOfWedge,
201  const vector& axisOfWedgeNormal,
202  Random& rndGen
203 ) const
204 {
205  if (twoD)
206  {
207  scalar is = position_ & axisOfSymmetry;
208  scalar magInj = mag(position_ - is*axisOfSymmetry);
209 
210  vector halfWedge =
211  axisOfWedge*cos(0.5*angleOfWedge)
212  + axisOfWedgeNormal*sin(0.5*angleOfWedge);
213  halfWedge /= mag(halfWedge);
214 
215  return (is*axisOfSymmetry + magInj*halfWedge);
216  }
217  else
218  {
219  // otherwise, disc injection
220  scalar iRadius = d_*rndGen.scalar01();
221  scalar iAngle = 2.0*mathematicalConstant::pi*rndGen.scalar01();
222 
223  return
224  (
225  position_
226  + iRadius
227  * (
228  tangentialInjectionVector1_*cos(iAngle)
229  + tangentialInjectionVector2_*sin(iAngle)
230  )
231  );
232 
233  }
234 
235  return position_;
236 }
237 
238 
239 Foam::label Foam::unitInjector::nHoles() const
240 {
241  return 1;
242 }
243 
244 
245 Foam::scalar Foam::unitInjector::d() const
246 {
247  return d_;
248 }
249 
250 
252 (
253  const label i,
254  const scalar time
255 ) const
256 {
257  return direction_;
258 }
259 
260 
261 Foam::scalar Foam::unitInjector::mass
262 (
263  const scalar time0,
264  const scalar time1,
265  const bool twoD,
266  const scalar angleOfWedge
267 ) const
268 {
269  scalar mInj = mass_*(fractionOfInjection(time1)-fractionOfInjection(time0));
270 
271  // correct mass if calculation is 2D
272  if (twoD)
273  {
274  mInj *= 0.5*angleOfWedge/mathematicalConstant::pi;
275  }
276 
277  return mInj;
278 }
279 
280 
281 Foam::scalar Foam::unitInjector::mass() const
282 {
283  return mass_;
284 }
285 
286 
288 {
289  return X_;
290 }
291 
292 
294 {
295  return TProfile_;
296 }
297 
298 
299 Foam::scalar Foam::unitInjector::T(const scalar time) const
300 {
301  return getTableValue(TProfile_, time);
302 }
303 
304 
305 Foam::scalar Foam::unitInjector::tsoi() const
306 {
307  return massFlowRateProfile_[0][0];
308 }
309 
310 
311 Foam::scalar Foam::unitInjector::teoi() const
312 {
313  return massFlowRateProfile_[massFlowRateProfile_.size()-1][0];
314 }
315 
316 
317 Foam::scalar Foam::unitInjector::massFlowRate(const scalar time) const
318 {
319  return getTableValue(massFlowRateProfile_, time);
320 }
321 
322 
323 Foam::scalar Foam::unitInjector::injectionPressure(const scalar time) const
324 {
325  return getTableValue(injectionPressureProfile_, time);
326 }
327 
328 
329 Foam::scalar Foam::unitInjector::velocity(const scalar time) const
330 {
331  return getTableValue(velocityProfile_, time);
332 }
333 
334 
336 {
337  return CdProfile_;
338 }
339 
340 
341 Foam::scalar Foam::unitInjector::Cd(const scalar time) const
342 {
343  return Cd_;
344 }
345 
346 
347 Foam::scalar Foam::unitInjector::fractionOfInjection(const scalar time) const
348 {
349  return integrateTable(massFlowRateProfile_, time)/mass_;
350 }
351 
352 
353 Foam::scalar Foam::unitInjector::injectedMass(const scalar t) const
354 {
355  return mass_*fractionOfInjection(t);
356 }
357 
358 
360 (
361  const liquidMixture& fuel,
362  const scalar referencePressure
363 )
364 {
365  scalar A = 0.25*mathematicalConstant::pi*pow(d_, 2.0);
366  scalar pDummy = 1.0e+5;
367 
368  forAll(velocityProfile_, i)
369  {
370  scalar time = velocityProfile_[i][0];
371  scalar rho = fuel.rho(pDummy, T(time), X_);
372  scalar v = massFlowRateProfile_[i][1]/(Cd_*rho*A);
373  velocityProfile_[i][1] = v;
374  injectionPressureProfile_[i][1] = referencePressure + 0.5*rho*v*v;
375  }
376 }
377 
378 
380 {
381  return tangentialInjectionVector1_;
382 }
383 
384 
386 {
387  return tangentialInjectionVector2_;
388 }
389 
390 
391 // ************************ vim: set sw=4 sts=4 et: ************************ //