00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <OpenFOAM/error.H>
00027
00028 #include "RutlandFlashBoil.H"
00029 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00030 #include <OpenFOAM/mathematicalConstants.H>
00031
00032
00033 namespace Foam
00034 {
00035
00036
00037
00038 defineTypeNameAndDebug(RutlandFlashBoil, 0);
00039
00040 addToRunTimeSelectionTable
00041 (
00042 evaporationModel,
00043 RutlandFlashBoil,
00044 dictionary
00045 );
00046
00047
00048
00049
00050
00051 RutlandFlashBoil::RutlandFlashBoil
00052 (
00053 const dictionary& dict
00054 )
00055 :
00056 evaporationModel(dict),
00057 evapDict_(dict.subDict(typeName + "Coeffs")),
00058 preReScFactor_(readScalar(evapDict_.lookup("preReScFactor"))),
00059 ReExponent_(readScalar(evapDict_.lookup("ReExponent"))),
00060 ScExponent_(readScalar(evapDict_.lookup("ScExponent"))),
00061 evaporationScheme_(evapDict_.lookup("evaporationScheme")),
00062 nEvapIter_(0)
00063 {
00064 if (evaporationScheme_ == "implicit")
00065 {
00066 nEvapIter_ = 2;
00067 }
00068 else if (evaporationScheme_ == "explicit")
00069 {
00070 nEvapIter_ = 1;
00071 }
00072 else
00073 {
00074 FatalError
00075 << "evaporationScheme type " << evaporationScheme_
00076 << " unknown.\n"
00077 << "Use implicit or explicit."
00078 << abort(FatalError);
00079 }
00080 }
00081
00082
00083
00084
00085 RutlandFlashBoil::~RutlandFlashBoil()
00086 {}
00087
00088
00089
00090
00091 bool RutlandFlashBoil::evaporation() const
00092 {
00093 return true;
00094 }
00095
00096
00097 scalar RutlandFlashBoil::Sh
00098 (
00099 const scalar ReynoldsNumber,
00100 const scalar SchmidtNumber
00101 ) const
00102 {
00103 return 2.0 + preReScFactor_*pow(ReynoldsNumber,ReExponent_)*pow(SchmidtNumber,ScExponent_);
00104 }
00105
00106 scalar RutlandFlashBoil::relaxationTime
00107 (
00108 const scalar diameter,
00109 const scalar liquidDensity,
00110 const scalar rhoFuelVapor,
00111 const scalar massDiffusionCoefficient,
00112 const scalar ReynoldsNumber,
00113 const scalar SchmidtNumber,
00114 const scalar Xs,
00115 const scalar Xf,
00116 const scalar m0,
00117 const scalar dm,
00118 const scalar dt
00119 ) const
00120 {
00121 scalar time = GREAT;
00122 scalar lgExpr = 0.0;
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 scalar Xratio = (Xs - Xf)/max(SMALL, 1.0 - Xs);
00142
00143 if (Xratio > 0.0)
00144 {
00145 lgExpr = log(1.0 + Xratio);
00146 }
00147
00148
00149
00150
00151
00152 scalar Sherwood = Sh(ReynoldsNumber, SchmidtNumber);
00153
00154 scalar FbExp = 0.7;
00155
00156 scalar logXratio = log(1.0+Xratio);
00157 scalar Fb = 1.0;
00158
00159 if(logXratio > SMALL)
00160 {
00161 Fb = pow((1.0 + Xratio),FbExp) * log(1.0+Xratio)/Xratio;
00162 }
00163
00164
00165
00166 Sherwood = 2.0 + (Sherwood - 2.0)/Fb;
00167
00168 scalar denominator =
00169 6.0 * massDiffusionCoefficient
00170 * Sherwood
00171 * rhoFuelVapor * lgExpr;
00172
00173 if (denominator > SMALL)
00174 {
00175 time = max(VSMALL, liquidDensity * pow(diameter, 2.0)/denominator);
00176 }
00177
00178 return time;
00179 }
00180
00181
00182 scalar RutlandFlashBoil::boilingTime
00183 (
00184 const scalar liquidDensity,
00185 const scalar cpFuel,
00186 const scalar heatOfVapour,
00187 const scalar kappa,
00188 const scalar Nusselt,
00189 const scalar deltaTemp,
00190 const scalar diameter,
00191 const scalar liquidCore,
00192 const scalar ct,
00193 const scalar tDrop,
00194 const scalar tBoilingSurface,
00195 const scalar vapourSurfaceEnthalpy,
00196 const scalar vapourFarEnthalpy,
00197 const scalar cpGas,
00198 const scalar temperature,
00199 const scalar kLiq
00200 ) const
00201 {
00202
00203 scalar time = GREAT;
00204
00205
00206
00207
00208
00209
00210
00211
00212 if(liquidCore > 0.5)
00213 {
00214 if(tDrop > tBoilingSurface)
00215 {
00216
00217
00218 scalar psi = 2.72;
00219 scalar kIncreased = psi * kLiq;
00220 scalar alfa = psi * kIncreased/(liquidDensity * cpFuel);
00221 scalar F = alfa * ct/sqr(0.5 * diameter);
00222
00223 scalar expSum = 0.0;
00224 scalar expSumOld = expSum;
00225
00226 label Niter = 200;
00227
00228 for(label k=0; k < Niter ; k++)
00229 {
00230 expSum += exp(sqr(-k*mathematicalConstant::pi*sqrt(F)/2.0));
00231 if(mag(expSum-expSumOld)/expSum < 1.0e-3)
00232 {
00233 break;
00234 }
00235 expSumOld = expSum;
00236 }
00237 }
00238 }
00239 else
00240 {
00241 scalar dTLB = min(0.5, tDrop - tBoilingSurface);
00242 scalar alfaS = 0.0;
00243
00244 if(dTLB >= 0.0 && dTLB < 5.0)
00245 {
00246 alfaS = 0.76 * pow(dTLB, 0.26);
00247 }
00248 if(dTLB >= 5.0 && dTLB < 25.0)
00249 {
00250 alfaS = 0.027 * pow(dTLB, 2.33);
00251 }
00252 if(dTLB >= 25.0)
00253 {
00254 alfaS = 13.8 * pow(dTLB, 0.39);
00255 }
00256
00257 scalar Gf =
00258 (
00259 4.0 * alfaS * dTLB * mathematicalConstant::pi * sqr(diameter/2.0)
00260 )
00261 /
00262 heatOfVapour;
00263
00264
00265 scalar G = 0.0;
00266 if(temperature > tBoilingSurface)
00267 {
00268 scalar NusseltCorr = Nusselt ;
00269 scalar A = mag((vapourFarEnthalpy-vapourSurfaceEnthalpy)/heatOfVapour);
00270
00271
00272 scalar B = 1.0*mathematicalConstant::pi*kappa/cpGas*diameter*NusseltCorr;
00273 scalar nPos = B * log(1.0 + A)/Gf + 1.0;
00274 scalar nNeg = (1.0/A)*(exp(Gf/B) - 1.0 - A) + 1.0;
00275
00276 scalar Gpos = Gf*nPos;
00277 scalar Gneg = Gf/nNeg;
00278
00279
00280 scalar FgNeg = Gneg + Gf - B * log( 1.0 + ( 1.0 + Gf/Gneg ) * A);
00281
00282 if(FgNeg > 0.0)
00283 {
00284 for(label j = 0; j < 20; j++)
00285 {
00286 Gneg = Gneg/10.0;
00287 Gneg = max(Gneg, VSMALL);
00288 FgNeg = Gneg + Gf - B * log( 1.0 + ( 1.0 + Gf/Gneg ) * A);
00289 if(FgNeg < 0.0)
00290 {
00291 break;
00292 }
00293 }
00294 }
00295
00296 FgNeg = Gneg + Gf - B * log( 1.0 + ( 1.0 + Gf/Gneg ) * A);
00297
00298 G = 0.5*(Gpos+Gneg);
00299 scalar Gold = -100;
00300
00301 label Niter = 200;
00302 label k=0;
00303
00304 if(FgNeg > 0.0)
00305 {
00306 Info << "no convergence" << endl;
00307 }
00308
00309
00310 if(FgNeg < 0.0)
00311 {
00312
00313 for(k=0; k<Niter ; k++)
00314 {
00315
00316 scalar Fg = G + Gf - B * log( 1.0 + ( 1.0 + Gf/G ) * A);
00317
00318 if(Fg > 0)
00319 {
00320 Gpos = G;
00321 G = 0.5*(Gpos+Gneg);
00322 }
00323 else
00324 {
00325 Gneg = G;
00326 G = 0.5*(Gpos+Gneg);
00327 }
00328
00329 Gold = G;
00330 if(mag(G-Gold)/Gold < 1.0e-3)
00331 {
00332 break;
00333 }
00334 }
00335
00336 if(k >= Niter - 1)
00337 {
00338 Info << " No convergence for G " << endl;
00339 }
00340 }
00341 else
00342 {
00343 G = 0.0;
00344 }
00345 }
00346
00347 time = ((4.0/3.0)*mathematicalConstant::pi*pow(diameter/2.0,3.0))*liquidDensity/(G+Gf);
00348 time = max(VSMALL, time);
00349 }
00350
00351 return time;
00352 }
00353
00354 inline label RutlandFlashBoil::nEvapIter() const
00355 {
00356 return nEvapIter_;
00357 }
00358
00359
00360 }
00361
00362