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