Ejemplo n.º 1
0
void ETAB::breakupParcel
(
    parcel& p,
    const scalar deltaT,
    const vector& Ug,
    const liquidMixture& fuels
) const
{

    scalar T  = p.T();
    scalar pc  = spray_.p()[p.cell()];
    scalar r  = 0.5*p.d();
    scalar r2 = r*r;
    scalar r3 = r*r2;

    scalar rho   = fuels.rho(pc, T, p.X());
    scalar sigma = fuels.sigma(pc, T, p.X());
    scalar mu    = fuels.mu(pc, T, p.X());

    // inverse of characteristic viscous damping time
    scalar rtd = 0.5*Cmu_*mu/(rho*r2);

    // oscillation frequency (squared)
    scalar omega2 = Comega_*sigma/(rho*r3) - rtd*rtd;

    if (omega2 > 0)
    {
        scalar omega = sqrt(omega2);
        scalar romega = 1.0/omega;

        scalar rhog = spray_.rho()[p.cell()];
        scalar We = p.We(Ug, rhog, sigma);
        scalar Wetmp = We/WeCrit_;

        scalar y1 = p.dev() - Wetmp;
        scalar y2 = p.ddev()*romega;

        scalar a = sqrt(y1*y1 + y2*y2);

        // scotty we may have break-up
        if (a+Wetmp > 1.0)
        {
            scalar phic = y1/a;

            // constrain phic within -1 to 1
            phic = max(min(phic, 1), -1);

            scalar phit = acos(phic);
            scalar phi = phit;
            scalar quad = -y2/a;
            if (quad < 0)
            {
                phi = 2*mathematicalConstant::pi - phit;
            }

            scalar tb = 0;

            if (mag(p.dev()) < 1.0)
            {
                scalar theta = acos((1.0 - Wetmp)/a);

                if (theta < phi)
                {
                    if (2*mathematicalConstant::pi-theta >= phi)
                    {
                        theta = -theta;
                    }
                    theta += 2*mathematicalConstant::pi;
                }
                tb = (theta-phi)*romega;

                // breakup occurs
                if (deltaT > tb)
                {
                    p.dev() = 1.0;
                    p.ddev() = -a*omega*sin(omega*tb + phi);
                }
            }

            // update droplet size
            if (deltaT > tb)
            {
                scalar sqrtWe = AWe_*pow(We, 4.0) + 1.0;
                scalar Kbr = k1_*omega*sqrtWe;

                if (We > WeTransition_)
                {
                    sqrtWe = sqrt(We);
                    Kbr =k2_*omega*sqrtWe;
                }

                scalar rWetmp = 1.0/Wetmp;
                scalar cosdtbu = max(-1.0, min(1.0, 1.0-rWetmp));
                scalar dtbu = romega*acos(cosdtbu);
                scalar decay = exp(-Kbr*dtbu);

                scalar rNew = decay*r;
                if (rNew < r)
                {
                    p.d() = 2*rNew;
                    p.dev() = 0;
                    p.ddev() = 0;
                }
            }
        }
    }
    else
    {
        // reset droplet distortion parameters
        p.dev() = 0;
        p.ddev() = 0;
    }
}
void reitzDiwakar::breakupParcel
(
    parcel& p,
    const scalar deltaT,
    const vector& vel,
    const liquidMixture& fuels
) const
{
    /*
        These are the default values for this model...
        static const scalar Cbag   = 6.0;
        static const scalar Cb     = 0.785;
        static const scalar Cstrip = 0.5;
        static const scalar Cs     = 10.0;
    */

    const PtrList<volScalarField>& Y = spray_.composition().Y();

    label Ns = Y.size();
    label cellI = p.cell();
    scalar pressure = spray_.p()[cellI];
    scalar temperature = spray_.T()[cellI];
    scalar Taverage = p.T() + (temperature - p.T())/3.0;

    scalar muAverage = 0.0;
    scalar Winv = 0.0;
    for(label i=0; i<Ns; i++)
    {
        Winv += Y[i][cellI]/spray_.gasProperties()[i].W();
        muAverage += Y[i][cellI]*spray_.gasProperties()[i].mu(Taverage);
    }
    scalar R = specie::RR()*Winv;

    // ideal gas law to evaluate density
    scalar rhoAverage = pressure/R/Taverage;
    scalar nuAverage = muAverage/rhoAverage;
    scalar sigma = fuels.sigma(pressure, p.T(), p.X());

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    //     The We and Re numbers are to be evaluated using the 1/3 rule.
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    scalar WeberNumber = p.We(vel, rhoAverage, sigma);
    scalar ReynoldsNumber = p.Re(vel, nuAverage);

    scalar sqRey = sqrt(ReynoldsNumber);

    if (WeberNumber > Cbag_)
    {
        if (WeberNumber > Cstrip_*sqRey)
        {
            scalar dStrip =
                pow(2.0*Cstrip_*sigma, 2.0)/
                (
                    rhoAverage
                  * pow(mag(p.Urel(vel)), 3.0)
                  * muAverage
                );

            scalar tauStrip =
                Cs_ * p.d()
              * sqrt
                (
                    fuels.rho(pressure, p.T(), p.X())
                    / rhoAverage
                )
              / mag(p.Urel(vel));

            scalar fraction = deltaT/tauStrip;

            // new droplet diameter, implicit calculation
            p.d() = (fraction*dStrip + p.d())/(1.0 + fraction);
        }
        else
        {
            scalar dBag =
                2.0 * Cbag_ * sigma
              / (
                  rhoAverage
                * pow(mag(p.Urel(vel)), 2.0)
                );

            scalar tauBag =
                Cb_ * p.d()
                * sqrt
                  (
                      fuels.rho(pressure, p.T(), p.X())
                    * p.d()
                    / sigma
                  );

            scalar fraction = deltaT/tauBag;

            // new droplet diameter, implicit calculation
            p.d() = (fraction*dBag + p.d())/(1.0 + fraction);
        }

    }

}
Ejemplo n.º 3
0
void blobsSheetAtomization::atomizeParcel
(
    parcel& p,
    const scalar deltaT,
    const vector& vel,
    const liquidMixture& fuels
) const
{

    const PtrList<volScalarField>& Y = spray_.composition().Y();

    label Ns = Y.size();
    label cellI = p.cell();
    scalar pressure = spray_.p()[cellI];
    scalar temperature = spray_.T()[cellI];
    scalar Taverage = p.T() + (temperature - p.T())/3.0;

    scalar Winv = 0.0;
    for(label i=0; i<Ns; i++)
    {
        Winv += Y[i][cellI]/spray_.gasProperties()[i].W();
    }
    scalar R = specie::RR*Winv;

    // ideal gas law to evaluate density
    scalar rhoAverage = pressure/R/Taverage;
    scalar sigma = fuels.sigma(pressure, p.T(), p.X());

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    //     The We and Re numbers are to be evaluated using the 1/3 rule.
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    scalar rhoFuel = fuels.rho(1.0e+5, p.T(), p.X());

    scalar U = mag(p.Urel(vel));

    const injectorType& it =
        spray_.injectors()[label(p.injector())].properties();

    vector itPosition(vector::zero);
    label nHoles = it.nHoles();
    if (nHoles > 1)
    {
        for(label i=0; i<nHoles;i++)
        {
            itPosition += it.position(i);
        }
        itPosition /= nHoles;
    }
    else
    {
        itPosition = it.position(0);
    }
//    const vector itPosition = it.position();


    scalar lBU = B_ * sqrt
    (
        rhoFuel * sigma * p.d() * cos(angle_*mathematicalConstant::pi/360.0)
      / sqr(rhoAverage*U)
    );

    scalar pWalk = mag(p.position() - itPosition);

    if(pWalk > lBU && p.liquidCore() == 1.0)
    {
        p.liquidCore() = 0.0;
    }
}
Ejemplo n.º 4
0
void Foam::SHF::breakupParcel
(
    parcel& p,
    const scalar deltaT,
    const vector& vel,
    const liquidMixtureProperties& fuels
) const
{
    label cellI = p.cell();
    scalar T = p.T();
    scalar pc = spray_.p()[cellI];

    scalar sigma = fuels.sigma(pc, T, p.X());
    scalar rhoLiquid = fuels.rho(pc, T, p.X());
    scalar muLiquid = fuels.mu(pc, T, p.X());
    scalar rhoGas = spray_.rho()[cellI];

    scalar weGas = p.We(vel, rhoGas, sigma);
    scalar weLiquid = p.We(vel, rhoLiquid, sigma);

    // correct the Reynolds number. Reitz is using radius instead of diameter

    scalar reLiquid   = p.Re(rhoLiquid, vel, muLiquid);
    scalar ohnesorge  = sqrt(weLiquid)/(reLiquid + VSMALL);

    vector vRel = p.Urel(vel);

    scalar weGasCorr = weGas/(1.0 + weCorrCoeff_*ohnesorge);

    // droplet deformation characteristic time

    scalar tChar = p.d()/mag(vRel)*sqrt(rhoLiquid/rhoGas);

    scalar tFirst = cInit_*tChar;

    scalar tSecond = 0;
    scalar tCharSecond = 0;


    //  updating the droplet characteristic time
    p.ct() += deltaT;

    if (weGas > weConst_)
    {
        if (weGas < weCrit1_)
        {
            tCharSecond = c1_*pow((weGas - weConst_),cExp1_);
        }
        else if (weGas >= weCrit1_ && weGas <= weCrit2_)
        {
            tCharSecond = c2_*pow((weGas - weConst_),cExp2_);
        }
        else
        {
            tCharSecond = c3_*pow((weGas - weConst_),cExp3_);
        }
    }

    scalar weC = weBuCrit_*(1.0+ohnCoeffCrit_*pow(ohnesorge, ohnExpCrit_));
    scalar weB = weBuBag_*(1.0+ohnCoeffBag_*pow(ohnesorge, ohnExpBag_));
    scalar weMM = weBuMM_*(1.0+ohnCoeffMM_*pow(ohnesorge, ohnExpMM_));

    bool bag = (weGas > weC && weGas < weB);

    bool multimode = (weGas >= weB && weGas <= weMM);

    bool shear = (weGas > weMM);

    tSecond = tCharSecond*tChar;

    scalar tBreakUP = tFirst + tSecond;
    if (p.ct() > tBreakUP)
    {

        scalar d32 =
            coeffD_*p.d()*pow(ohnesorge, onExpD_)*pow(weGasCorr, weExpD_);

        if (bag || multimode)
        {

            scalar d05 = d32Coeff_*d32;

            scalar x = 0.0;
            scalar y = 0.0;
            scalar d = 0.0;
            scalar px = 0.0;

            do
            {
                x = cDmaxBM_*rndGen_.sample01<scalar>();
                d = sqr(x)*d05;
                y = rndGen_.sample01<scalar>();

                px =
                    x
                   /(2.0*sqrt(constant::mathematical::twoPi)*sigma_)
                   *exp(-0.5*sqr((x-mu_)/sigma_));

            } while (y >= px);

            p.d() = d;
            p.ct() = 0.0;
        }

        if (shear)
        {
            scalar dC = weConst_*sigma/(rhoGas*sqr(mag(vRel)));
            scalar d32Red = 4.0*(d32*dC)/(5.0*dC - d32);
            scalar initMass = p.m();

            scalar d05 = d32Coeff_*d32Red;

            scalar x = 0.0;
            scalar y = 0.0;
            scalar d = 0.0;
            scalar px = 0.0;

            do
            {

                x = cDmaxS_*rndGen_.sample01<scalar>();
                d = sqr(x)*d05;
                y = rndGen_.sample01<scalar>();

                px =
                    x
                   /(2.0*sqrt(constant::mathematical::twoPi)*sigma_)
                   *exp(-0.5*sqr((x-mu_)/sigma_));
            } while (y >= px);

            p.d() = dC;
            p.m() = corePerc_*initMass;

            spray_.addParticle
            (
                new parcel
                (
                    p.mesh(),
                    p.position(),
                    p.cell(),
                    p.tetFace(),
                    p.tetPt(),
                    p.n(),
                    d,
                    p.T(),
                    (1.0 - corePerc_)*initMass,
                    0.0,
                    0.0,
                    0.0,
                    -GREAT,
                    p.tTurb(),
                    0.0,
                    scalar(p.injector()),
                    p.U(),
                    p.Uturb(),
                    p.X(),
                    p.fuelNames()
                )
            );

            p.ct() = 0.0;
        }
    }
}
Ejemplo n.º 5
0
void myLISA_3_InjPos::atomizeParcel
(
    parcel& p,
    const scalar deltaT,
    const vector& vel,
    const liquidMixture& fuels
) const
{


    const PtrList<volScalarField>& Y = spray_.composition().Y();

    label Ns = Y.size();
    label cellI = p.cell();
    scalar pressure = spray_.p()[cellI];
    scalar temperature = spray_.T()[cellI];
//--------------------------------------AL____101015--------------------------------//
//  scalar Taverage = p.T() + (temperature - p.T())/3.0;
    scalar Taverage = temperature;
//-----------------------------------------END--------------------------------------//
    scalar Winv = 0.0;

    for(label i=0; i<Ns; i++)
    {
        Winv += Y[i][cellI]/spray_.gasProperties()[i].W();
    }

    scalar R = specie::RR*Winv;

    // ideal gas law to evaluate density
    scalar rhoAverage = pressure/R/Taverage;
    //scalar nuAverage = muAverage/rhoAverage;
    scalar sigma = fuels.sigma(pressure, p.T(), p.X());

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    //     The We and Re numbers are to be evaluated using the 1/3 rule.
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    scalar WeberNumber = p.We(vel, rhoAverage, sigma);

    scalar tau = 0.0;
    scalar dL = 0.0;
    scalar k = 0.0;
    scalar muFuel = fuels.mu(pressure, p.T(), p.X());
    scalar rhoFuel = fuels.rho(1.0e+5, p.T(), p.X());
    scalar nuFuel = muFuel/rhoFuel;

    vector uDir = p.U()/mag(p.U());

    scalar uGas = mag(vel & uDir);
    vector Ug = uGas*uDir;

    /*
        TL
        It might be the relative velocity between Liquid and Gas, but I use the
        absolute velocity of the parcel as suggested by the authors
    */

//    scalar U = mag(p.Urel(vel));
    scalar U = mag(p.U());
    p.ct() += deltaT;

    scalar Q = rhoAverage/rhoFuel;

    const injectorType& it =
        spray_.injectors()[label(p.injector())].properties();

    if (it.nHoles() > 1)
    {
        Info << "Warning: This atomization model is not suitable for multihole injector." << endl
             << "Only the first hole will be used." << endl;
    }

    const vector direction = it.direction(0, spray_.runTime().value());
//--------------------------------CH 101108--------------------------------------------------//
//    const vector itPosition = it.position(0);
    const injectorModel& im = spray_.injection();
    const vector itPosition = it.position(0) + im.injDist(0)*direction/mag(direction);
//------------------------------------END----------------------------------------------------//
    scalar pWalk = mag(p.position() - itPosition);

//  Updating liquid sheet tickness... that is the droplet diameter

//    const vector direction = it.direction(0, spray_.runTime().value());

    scalar h = (p.position() - itPosition) & direction;

    scalar d = sqrt(sqr(pWalk)-sqr(h));

    scalar time = pWalk/mag(p.U());

    scalar elapsedTime = spray_.runTime().value();

    scalar massFlow = it.massFlowRate(max(0.0,elapsedTime-time));

    scalar hSheet = massFlow/(mathematicalConstant::pi*d*rhoFuel*mag(p.U()));

    p.d() = min(hSheet,p.d());

    if(WeberNumber > 27.0/16.0)
    {

        scalar kPos = 0.0;
        scalar kNeg = Q*pow(U, 2.0)*rhoFuel/sigma;

        scalar derivativePos = sqrt
                               (
                                   Q*pow(U,2.0)
                               );

        scalar derivativeNeg =
            (
                8.0*pow(nuFuel, 2.0)*pow(kNeg, 3.0)
                + Q*pow(U, 2.0)*kNeg
                - 3.0*sigma/2.0/rhoFuel*pow(kNeg, 2.0)
            )
            /
            sqrt
            (
                4.0*pow(nuFuel, 2.0)*pow(kNeg, 4.0)
                + Q*pow(U, 2.0)*pow(kNeg, 2.0)
                - sigma*pow(kNeg, 3.0)/rhoFuel
            )
            -
            4.0*nuFuel*kNeg;

        scalar kOld = 0.0;


        for(label i=0; i<40; i++)
        {

            k = kPos - (derivativePos/((derivativeNeg-derivativePos)/(kNeg-kPos)));

            scalar derivativek =
                (
                    8.0*pow(nuFuel, 2.0)*pow(k, 3.0)
                    + Q*pow(U, 2.0)*k
                    - 3.0*sigma/2.0/rhoFuel*pow(k, 2.0)
                )
                /
                sqrt
                (
                    4.0*pow(nuFuel, 2.0)*pow(k, 4.0)
                    + Q*pow(U, 2.0)*pow(k, 2.0)
                    - sigma*pow(k, 3.0)/rhoFuel
                )
                -
                4.0*nuFuel*k;

            if(derivativek > 0)
            {
                derivativePos = derivativek;
                kPos = k;
            }
            else
            {
                derivativeNeg = derivativek;
                kNeg = k;
            }

            if(mag(k-kOld)/k < 1e-4)
            {
                break;
            }

            kOld = k;

        }

        scalar omegaS =
            - 2.0 * nuFuel * pow(k, 2.0)
            + sqrt
            (
                4.0*pow(nuFuel, 2.0)*pow(k, 4.0)
                +   Q*pow(U, 2.0)*pow(k, 2.0)
                -   sigma*pow(k, 3.0)/rhoFuel
            );

        tau = cTau_/omegaS;
        dL = sqrt(8.0*p.d()/k);

    }
    else
    {

        k =
            rhoAverage*pow(U, 2.0)
            /
            2.0*sigma;

//--------------------------------------AL____101011--------------------------------//
//      scalar J = pWalk*p.d()/2.0;
        scalar J = time*hSheet/2.0;
//-----------------------------------------END--------------------------------------//

        tau = pow(3.0*cTau_,2.0/3.0)*cbrt(J*sigma/(sqr(Q)*pow(U,4.0)*rhoFuel));

        dL = sqrt(4.0*p.d()/k);
    }



    scalar kL =
        1.0
        /
        (
            dL *
            pow(0.5 + 1.5 * muFuel/pow((rhoFuel*sigma*dL), 0.5), 0.5)
        );

    scalar dD = cbrt(3.0*mathematicalConstant::pi*pow(dL, 2.0)/kL);
// lisaExp is included in coeffsDict
//    scalar lisaExp = 0.27;
    scalar ambientPressure = 1.0e+5;

    scalar pRatio = spray_.ambientPressure()/ambientPressure;

    dD = dD*pow(pRatio,lisaExp_);

//  modifications to take account of the flash boiling on primary breakUp

    scalar pExp = 0.135;

    scalar chi = 0.0;

    label Nf = fuels.components().size();

    scalar Td = p.T();

    for(label i = 0; i < Nf ; i++)
    {

        if(fuels.properties()[i].pv(spray_.ambientPressure(), Td) >= 0.999*spray_.ambientPressure())
        {

//          The fuel is boiling.....
//          Calculation of the boiling temperature

            scalar tBoilingSurface = Td;

            label Niter = 200;

            for(label k=0; k< Niter ; k++)
            {
                scalar pBoil = fuels.properties()[i].pv(pressure, tBoilingSurface);

                if(pBoil > pressure)
                {
                    tBoilingSurface = tBoilingSurface - (Td-temperature)/Niter;
                }
                else
                {
                    break;
                }
            }

            scalar hl = fuels.properties()[i].hl(spray_.ambientPressure(), tBoilingSurface);
            scalar iTp = fuels.properties()[i].h(spray_.ambientPressure(), Td) - spray_.ambientPressure()/fuels.properties()[i].rho(spray_.ambientPressure(), Td);
            scalar iTb = fuels.properties()[i].h(spray_.ambientPressure(), tBoilingSurface) - spray_.ambientPressure()/fuels.properties()[i].rho(spray_.ambientPressure(), tBoilingSurface);

            chi += p.X()[i]*(iTp-iTb)/hl;

        }
    }

    //  bounding chi

    chi = max(chi, 0.0);
    chi = min(chi, 1.0);

    //  modifing dD to take account of flash boiling

    dD = dD*(1.0 - chi*pow(pRatio, -pExp));
    scalar lBU = Cl_ * mag(p.U())*tau;
    if(pWalk > lBU)
    {

        p.liquidCore() = 0.0;

//      calculate the new diameter with the standard 1D Rosin Rammler distribution

//--------------------------------AL_____101012------------------------------//
// Calculation of the mean radius based on SMR rs. Coefficient factorGamma depends on nExp.
// Note that Reitz either used (Schmidt et al., 1999-01-0496) or skipped (Senecal et al.) this factor!!!
//      scalar factorGamma = 0.75*sqrt(mathematicalConstant::pi);       //nExp=2
        scalar factorGamma = 1.;
        scalar delta = dD/factorGamma;

        /*      dD is the SMD, and the delta is calculated using gama
                function. Here we assume nExp = 2. */
//      scalar delta = dD/(0.75*sqrt(mathematicalConstant::pi));

//        scalar minValue = min(p.d()/20.0,dD/20.0);
        scalar minValue = dD/10.0;

//      delta is divided by 20 instead of 10 in order to make sure of small minValue
//      scalar minValue = min(p.d(),dD/20.0);

//        scalar maxValue = p.d();
        scalar maxValue = dD;

//      The pdf value for 4.0*delta is already very small.
//      scalar maxValue = delta*4.0;

        if(maxValue - minValue < SMALL)
        {
//          minValue = p.d()/20.0;
            minValue = maxValue/20.0;
//-----------------------------------END-------------------------------------//
        }

        scalar range = maxValue - minValue;

        scalar nExp = 3;
        scalar rrd_[500];
//--------------------------------AL_____101012------------------------------//
        scalar probFactorMin = exp(-pow(minValue/delta,nExp));
        scalar probFactorMax = exp(-pow(maxValue/delta,nExp));
        scalar probFactor = 1./(probFactorMin - probFactorMax);
//-----------------------------------END-------------------------------------//
        for(label n=0; n<500; n++)
        {
            scalar xx = minValue + range*n/500;
//-------------------------------AL_____101012-------------------------------//
//          rrd_[n] = 1 - exp(-pow(xx/delta,nExp));
            rrd_[n] = (probFactorMin - exp(-pow(xx/delta,nExp)))*probFactor;
//-----------------------------------END-------------------------------------//
        }


        bool success = false;
        scalar x = 0;
        scalar y = rndGen_.scalar01();
        label k = 0;

        while(!success && (k<500))
        {
            if (rrd_[k]>y)
            {
                success = true;
            }
            k++;

        }
//--------------------------------AL_____101012------------------------------//
//      x = minValue + range*n/500;
        x = minValue + range*(k-0.5)/500.0;
//------------------------------------END------------------------------------//
//  New droplet diameter

        p.d() = x;
        p.ct() = 0.0;

    }


}
Ejemplo n.º 6
0
void reitzKHRT::breakupParcel
(
    parcel& p,
    const scalar deltaT,
    const vector& vel,
    const liquidMixture& fuels
) const
{

    label celli = p.cell();
    scalar T = p.T();
    scalar r = 0.5*p.d();
    scalar pc = spray_.p()[celli];

    scalar sigma = fuels.sigma(pc, T, p.X());
    scalar rhoLiquid = fuels.rho(pc, T, p.X());
    scalar muLiquid = fuels.mu(pc, T, p.X());
    scalar rhoGas = spray_.rho()[celli];
    scalar Np = p.N(rhoLiquid);
    scalar semiMass = Np*pow(p.d(), 3.0);

    scalar weGas      = p.We(vel, rhoGas, sigma);
    scalar weLiquid   = p.We(vel, rhoLiquid, sigma);
    // correct the Reynolds number. Reitz is using radius instead of diameter
    scalar reLiquid   = 0.5*p.Re(rhoLiquid, vel, muLiquid);
    scalar ohnesorge  = sqrt(weLiquid)/(reLiquid + VSMALL);
    scalar taylor     = ohnesorge*sqrt(weGas);

    vector acceleration = p.Urel(vel)/p.tMom();
    vector trajectory = p.U()/mag(p.U());
    scalar gt = (g_ + acceleration) & trajectory;

    // frequency of the fastest growing KH-wave
    scalar omegaKH =
        (0.34 + 0.38*pow(weGas, 1.5))
       /((1 + ohnesorge)*(1 + 1.4*pow(taylor, 0.6)))
       *sqrt(sigma/(rhoLiquid*pow(r, 3)));

    // corresponding KH wave-length.
    scalar lambdaKH =
        9.02
       *r
       *(1.0 + 0.45*sqrt(ohnesorge))
       *(1.0 + 0.4*pow(taylor, 0.7))
       /pow(1.0 + 0.865*pow(weGas, 1.67), 0.6);

    // characteristic Kelvin-Helmholtz breakup time
    scalar tauKH = 3.726*b1_*r/(omegaKH*lambdaKH);

    // stable KH diameter
    scalar dc = 2.0*b0_*lambdaKH;

    // the frequency of the fastest growing RT wavelength.
    scalar helpVariable = mag(gt*(rhoLiquid - rhoGas));
    scalar omegaRT = sqrt
    (
        2.0*pow(helpVariable, 1.5)
       /(3.0*sqrt(3.0*sigma)*(rhoGas + rhoLiquid))
    );

    // RT wave number
    scalar KRT = sqrt(helpVariable/(3.0*sigma + VSMALL));

    // wavelength of the fastest growing RT frequency
    scalar lambdaRT = 2.0*mathematicalConstant::pi*cRT_/(KRT + VSMALL);

    // if lambdaRT < diameter, then RT waves are growing on the surface
    // and we start to keep track of how long they have been growing
    if ((p.ct() > 0) || (lambdaRT < p.d()))
    {
        p.ct() += deltaT;
    }

    // characteristic RT breakup time
    scalar tauRT = cTau_/(omegaRT + VSMALL);

    // check if we have RT breakup
    if ((p.ct() > tauRT) && (lambdaRT < p.d()))
    {
        // the RT breakup creates diameter/lambdaRT new droplets
        p.ct() = -GREAT;
        scalar multiplier = p.d()/lambdaRT;
        scalar nDrops = multiplier*Np;
        p.d() = cbrt(semiMass/nDrops);
    }
    // otherwise check for KH breakup
    else if (dc < p.d())
    {
        // no breakup below Weber = 12
        if (weGas > weberLimit_)
        {

            label injector = label(p.injector());
            scalar fraction = deltaT/tauKH;

            // reduce the diameter according to the rate-equation
            p.d() = (fraction*dc + p.d())/(1.0 + fraction);

            scalar ms = rhoLiquid*Np*pow3(dc)*mathematicalConstant::pi/6.0;
            p.ms() += ms;

            // Total number of parcels for the whole injection event
            label nParcels =
                spray_.injectors()[injector].properties()->nParcelsToInject
                (
                    spray_.injectors()[injector].properties()->tsoi(),
                    spray_.injectors()[injector].properties()->teoi()
                );

            scalar averageParcelMass =
                spray_.injectors()[injector].properties()->mass()/nParcels;

            if (p.ms()/averageParcelMass > msLimit_)
            {
                // set the initial ms value to -GREAT. This prevents
                // new droplets from being formed from the child droplet
                // from the KH instability

                // mass of stripped child parcel
                scalar mc = p.ms();
                // Prevent child parcel from taking too much mass
                if (mc > 0.5*p.m())
                {
                    mc = 0.5*p.m();
                }

                spray_.addParticle
                (
                    new parcel
                    (
                        spray_,
                        p.position(),
                        p.cell(),
                        p.n(),
                        dc,
                        p.T(),
                        mc,
                        0.0,
                        0.0,
                        0.0,
                        -GREAT,
                        p.tTurb(),
                        0.0,
                        p.injector(),
                        p.U(),
                        p.Uturb(),
                        p.X(),
                        p.fuelNames()
                    )
                );

                p.m() -= mc;
                p.ms() = 0.0;
            }
        }
    }
}