FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

multiHoleInjector.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "multiHoleInjector.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <OpenFOAM/Random.H>
00029 #include <OpenFOAM/mathematicalConstants.H>
00030 
00031 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00032 namespace Foam
00033 {
00034 
00035 defineTypeNameAndDebug(multiHoleInjector, 0);
00036 
00037 addToRunTimeSelectionTable
00038 (
00039     injectorType,
00040     multiHoleInjector,
00041     dictionary
00042 );
00043 }
00044 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00045 
00046 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00047 
00048 // Construct from components
00049 Foam::multiHoleInjector::multiHoleInjector
00050 (
00051     const Foam::Time& t,
00052     const Foam::dictionary& dict
00053 )
00054 :
00055     injectorType(t, dict),
00056     propsDict_(dict.subDict(typeName + "Props")),
00057     centerPosition_(propsDict_.lookup("position")),
00058     xyAngle_(readScalar(propsDict_.lookup("xyAngle"))),
00059     zAngle_(readScalar(propsDict_.lookup("zAngle"))),
00060     nHoles_(readLabel(propsDict_.lookup("nHoles"))),
00061     umbrellaAngle_(readScalar(propsDict_.lookup("umbrellaAngle"))),
00062     nozzleTipDiameter_(readScalar(propsDict_.lookup("nozzleTipDiameter"))),
00063     angleSpacing_(propsDict_.lookup("angleSpacing")),
00064     d_(readScalar(propsDict_.lookup("diameter"))),
00065     Cd_(readScalar(propsDict_.lookup("Cd"))),
00066     mass_(readScalar(propsDict_.lookup("mass"))),
00067     nParcels_(readLabel(propsDict_.lookup("nParcels"))),
00068     X_(propsDict_.lookup("X")),
00069     massFlowRateProfile_(propsDict_.lookup("massFlowRateProfile")),
00070     velocityProfile_(massFlowRateProfile_),
00071     injectionPressureProfile_(massFlowRateProfile_),
00072     CdProfile_(massFlowRateProfile_),
00073     TProfile_(propsDict_.lookup("temperatureProfile")),
00074     averageParcelMass_(nHoles_*mass_/nParcels_),
00075     direction_(nHoles_),
00076     position_(nHoles_),
00077     pressureIndependentVelocity_(true),
00078     tangentialInjectionVector1_(nHoles_),
00079     tangentialInjectionVector2_(nHoles_)
00080 {
00081 
00082 
00083     // check if time entries for soi and eoi match
00084     if (mag(massFlowRateProfile_[0][0]-TProfile_[0][0]) > SMALL)
00085     {
00086         FatalError << "multiHoleInjector::multiHoleInjector(const time& t, const dictionary dict) " << endl
00087             << " start-times do not match for TemperatureProfile and massFlowRateProfile."
00088             << abort(FatalError);
00089     }
00090 
00091     if (mag(massFlowRateProfile_[massFlowRateProfile_.size()-1][0]-TProfile_[TProfile_.size()-1][0]) > SMALL)
00092     {
00093         FatalError << "multiHoleInjector::multiHoleInjector(const time& t, const dictionary dict) " << endl
00094             << " end-times do not match for TemperatureProfile and massFlowRateProfile."
00095             << abort(FatalError);
00096     }
00097 
00098     // convert CA to real time
00099     forAll(massFlowRateProfile_, i)
00100     {
00101         massFlowRateProfile_[i][0] = t.userTimeToTime(massFlowRateProfile_[i][0]);
00102         velocityProfile_[i][0] = massFlowRateProfile_[i][0];
00103         injectionPressureProfile_[i][0] = massFlowRateProfile_[i][0];
00104     }
00105     
00106     forAll(TProfile_, i)
00107     {
00108         TProfile_[i][0] = t.userTimeToTime(TProfile_[i][0]);
00109     }
00110 
00111     scalar integratedMFR = integrateTable(massFlowRateProfile_);
00112 
00113     forAll(massFlowRateProfile_, i)
00114     {
00115         // correct the massFlowRateProfile to match the injected mass
00116         massFlowRateProfile_[i][1] *= mass_/integratedMFR;
00117         
00118         CdProfile_[i][0] = massFlowRateProfile_[i][0];
00119         CdProfile_[i][1] = Cd_;
00120     }
00121 
00122     setTangentialVectors();
00123 
00124     // check molar fractions
00125     scalar Xsum = 0.0;
00126     forAll(X_, i)
00127     {
00128         Xsum += X_[i];
00129     }
00130 
00131     if (mag(Xsum - 1.0) > SMALL)
00132     {
00133         Info << "Warning!!!\n multiHoleInjector::multiHoleInjector(const time& t, Istream& is)"
00134             << "X does not add up to 1.0, correcting molar fractions."
00135             << endl;
00136         forAll(X_, i)
00137         {
00138             X_[i] /= Xsum;
00139         }
00140     }
00141 
00142 }
00143 
00144 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00145 
00146 Foam::multiHoleInjector::~multiHoleInjector()
00147 {}
00148 
00149 
00150 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00151 
00152 void Foam::multiHoleInjector::setTangentialVectors()
00153 {
00154     scalar pi180 = mathematicalConstant::pi/180.0;
00155     scalar alpha = xyAngle_*pi180;
00156     scalar phi = zAngle_*pi180;
00157 
00158     vector xp(cos(alpha), sin(alpha), 0.0);
00159     vector zp(cos(alpha)*sin(phi), sin(alpha)*sin(phi), cos(phi));
00160     if (mag(zp-xp) < 1.0e-15)
00161     {
00162         xp = vector(0.0, 0.0, -1.0);
00163         xp -= (xp & zp)*zp;
00164         xp /= mag(xp);
00165     }
00166     vector yp = zp^xp;
00167 
00168 //    Info << "xp = " << xp << endl;
00169 //    Info << "yp = " << yp << endl;
00170 //    Info << "zp = " << zp << endl;
00171 
00172     scalar angle = 0.0;
00173     scalar u = umbrellaAngle_*pi180/2.0;
00174     for(label i=0; i<nHoles_; i++)
00175     {
00176         angle += angleSpacing_[i];
00177         scalar v = angle*pi180;
00178         direction_[i] = cos(v)*sin(u)*xp + sin(v)*sin(u)*yp + cos(u)*zp;
00179         vector dp = direction_[i] - (direction_[i] & zp)*direction_[i];
00180         if (mag(dp) > SMALL)
00181         {
00182             dp /= mag(dp);
00183         }
00184         position_[i] = centerPosition_ + 0.5*nozzleTipDiameter_*dp;
00185 //        Info << "i = " << i << ", dir = " << direction_[i] << ", pos = " << position_[i] << endl;
00186     }
00187 
00188     Random rndGen(label(0));
00189 
00190     for(label i=0; i<nHoles_; i++)
00191     {
00192         vector tangent(vector::zero);
00193         scalar magV = 0;
00194         while (magV < SMALL)
00195         {
00196             vector testThis = rndGen.vector01();
00197             
00198             tangent = testThis - (testThis & direction_[i])*direction_[i];
00199             magV = mag(tangent);
00200         }
00201 
00202         tangentialInjectionVector1_[i] = tangent/magV;
00203         tangentialInjectionVector2_[i] = direction_[i] ^ tangentialInjectionVector1_[i];
00204 
00205     }   
00206 }
00207 
00208 
00209 Foam::label Foam::multiHoleInjector::nParcelsToInject
00210 (
00211     const scalar time0,
00212     const scalar time1
00213 ) const
00214 {
00215 
00216     scalar mInj = mass_*(fractionOfInjection(time1)-fractionOfInjection(time0));
00217     label nParcels = label(mInj/averageParcelMass_ + 0.49);
00218     
00219     return nParcels;
00220 }
00221 
00222 const Foam::vector Foam::multiHoleInjector::position(const label n) const
00223 {
00224     return position_[n];
00225 }
00226 
00227 Foam::vector Foam::multiHoleInjector::position
00228 (
00229     const label n,
00230     const scalar time,
00231     const bool twoD,
00232     const scalar angleOfWedge,
00233     const vector& axisOfSymmetry,
00234     const vector& axisOfWedge,
00235     const vector& axisOfWedgeNormal,
00236     Random& rndGen
00237 ) const
00238 {
00239     if (twoD)
00240     {
00241         scalar is = position_[n] & axisOfSymmetry;
00242         scalar magInj = mag(position_[n] - is*axisOfSymmetry);
00243 
00244         vector halfWedge =
00245             axisOfWedge*cos(0.5*angleOfWedge)
00246           + axisOfWedgeNormal*sin(0.5*angleOfWedge);
00247         halfWedge /= mag(halfWedge);
00248 
00249         return (is*axisOfSymmetry + magInj*halfWedge);
00250     }
00251     else
00252     {
00253         // otherwise, disc injection
00254         scalar iRadius = d_*rndGen.scalar01();
00255         scalar iAngle = 2.0*mathematicalConstant::pi*rndGen.scalar01();
00256 
00257         return
00258         ( 
00259             position_[n]
00260           + iRadius
00261           * (
00262               tangentialInjectionVector1_[n]*cos(iAngle)
00263             + tangentialInjectionVector2_[n]*sin(iAngle)
00264           )
00265         );
00266         
00267     }
00268     return position_[0];
00269 }
00270 
00271 Foam::label Foam::multiHoleInjector::nHoles() const
00272 {
00273     return nHoles_;
00274 }
00275 
00276 Foam::scalar Foam::multiHoleInjector::d() const
00277 {
00278     return d_;
00279 }
00280 
00281 const Foam::vector& Foam::multiHoleInjector::direction
00282 (
00283     const label i,
00284     const scalar time
00285 ) const
00286 {
00287     return direction_[i];
00288 }
00289 
00290 Foam::scalar Foam::multiHoleInjector::mass
00291 (
00292     const scalar time0,
00293     const scalar time1,
00294     const bool twoD,
00295     const scalar angleOfWedge
00296 ) const
00297 {
00298     scalar mInj = mass_*(fractionOfInjection(time1)-fractionOfInjection(time0));
00299 
00300     // correct mass if calculation is 2D 
00301     if (twoD)
00302     {
00303         mInj *= 0.5*angleOfWedge/mathematicalConstant::pi;
00304     }
00305 
00306     return mInj;
00307 }
00308 
00309 Foam::scalar Foam::multiHoleInjector::mass() const
00310 {
00311     return mass_;
00312 }
00313 
00314 const Foam::scalarField& Foam::multiHoleInjector::X() const
00315 {
00316     return X_;
00317 }
00318 
00319 Foam::List<Foam::multiHoleInjector::pair> Foam::multiHoleInjector::T() const
00320 {
00321     return TProfile_;
00322 }
00323 
00324 Foam::scalar Foam::multiHoleInjector::T(const scalar time) const
00325 {
00326     return getTableValue(TProfile_, time);
00327 }
00328 
00329 Foam::scalar Foam::multiHoleInjector::tsoi() const
00330 {
00331     return massFlowRateProfile_[0][0];
00332 }
00333 
00334 Foam::scalar Foam::multiHoleInjector::teoi() const
00335 {
00336     return massFlowRateProfile_[massFlowRateProfile_.size()-1][0];
00337 }
00338 
00339 Foam::scalar Foam::multiHoleInjector::massFlowRate
00340 (
00341     const scalar time
00342 ) const
00343 {
00344     return getTableValue(massFlowRateProfile_, time);
00345 }
00346 
00347 Foam::scalar Foam::multiHoleInjector::injectionPressure
00348 (
00349     const scalar time
00350 ) const
00351 {
00352     return getTableValue(injectionPressureProfile_, time);
00353 }
00354 
00355 Foam::scalar Foam::multiHoleInjector::velocity
00356 (
00357     const scalar time
00358 ) const
00359 {
00360     return getTableValue(velocityProfile_, time);
00361 }
00362 
00363 Foam::List<Foam::multiHoleInjector::pair> Foam::multiHoleInjector::CdProfile() const
00364 {
00365     return CdProfile_;
00366 }
00367 
00368 Foam::scalar Foam::multiHoleInjector::Cd
00369 (
00370     const scalar time
00371 ) const
00372 {
00373     return Cd_;
00374 }
00375 
00376 Foam::scalar Foam::multiHoleInjector::fractionOfInjection(const scalar time) const
00377 {
00378     return integrateTable(massFlowRateProfile_, time)/mass_;
00379 }
00380 
00381 Foam::scalar Foam::multiHoleInjector::injectedMass
00382 (
00383     const scalar t
00384 ) const
00385 {
00386     return mass_*fractionOfInjection(t);
00387 }
00388 
00389 
00390 void Foam::multiHoleInjector::correctProfiles
00391 (
00392     const liquidMixture& fuel,
00393     const scalar referencePressure
00394 )
00395 {
00396 
00397     scalar A = nHoles_*0.25*mathematicalConstant::pi*pow(d_, 2.0);
00398 
00399     forAll(velocityProfile_, i)
00400     {
00401         scalar time = velocityProfile_[i][0];
00402         scalar rho = fuel.rho(referencePressure, T(time), X_);
00403         scalar v = massFlowRateProfile_[i][1]/(Cd_*rho*A);
00404         velocityProfile_[i][1] = v;
00405         injectionPressureProfile_[i][1] = referencePressure + 0.5*rho*v*v;
00406     }
00407 }
00408 
00409 Foam::vector Foam::multiHoleInjector::tan1(const label n) const
00410 {
00411     return tangentialInjectionVector1_[n];
00412 }
00413 
00414 Foam::vector Foam::multiHoleInjector::tan2(const label n) const
00415 {
00416     return tangentialInjectionVector2_[n];
00417 }
00418 
00419 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines