Beispiel #1
0
void SchillerNaumannDrag::setForce() const
{
    // get viscosity field
    #ifdef comp
        const volScalarField nufField = particleCloud_.turbulence().mu() / rho_;
    #else
        const volScalarField& nufField = particleCloud_.turbulence().nu();
    #endif

    #include "setupProbeModel.H"

    for(int index = 0;index <  particleCloud_.numberOfParticles(); index++)
    {
        //if(mask[index][0])
        //{
            vector drag(0,0,0);
            vector Uturb(0,0,0);
            vector position(0,0,0);
            label cellI = particleCloud_.cellIDs()[index][0];

            if (cellI > -1) // particle Found
            {
                //NP note: one could add pointInterpolated values instead of cell centered
                vector Us = particleCloud_.velocity(index);
                vector Ur = U_[cellI]-Us;
                position     = particleCloud_.position(index);
                
                
                //accounting for turbulent dispersion
                if(particleCloud_.dispersionM().isActive())
                {
                    Uturb=particleCloud_.fluidTurbVel(index);
                    Ur=(U_[cellI]+Uturb)-Us;                                        
                }
                
                
                scalar ds = 2*particleCloud_.radius(index);
                scalar nuf = nufField[cellI];
                scalar rho = rho_[cellI];
                scalar voidfraction = particleCloud_.voidfraction(index);
                scalar magUr = mag(Ur);
                scalar Rep = 0;
                scalar Cd = 0;                
                
                if (magUr > 0)
                {
                   // calc particle Re Nr
                    Rep = ds*magUr/nuf;

                    // calc fluid drag Coeff
                    Cd = max(0.44,24.0/Rep*(1.0+0.15*pow(Rep,0.687)));

                    // calc particle's drag
                    drag = 0.125*Cd*rho*M_PI*ds*ds*magUr*Ur;

                    if (modelType_=="B")
                        drag /= voidfraction;
                }

                if(verbose_ && index >=0 && index <1)
                {
                    Pout << " "<< endl;
                    Pout << "SchillerNaumannDrag drag force verbose: "  << endl;
                    
                    Info << "index = " << index << endl;
                    Pout << "position = " << position << endl;
                    Pout << "Ufluid = " << U_[cellI] << endl; 
                    Pout << "Uturb = " << Uturb << endl; 
                    Pout << "Us = " << Us << endl; 
                    
                    Info << "Ur = " << Ur << endl;
                    Info << "ds = " << ds << endl;
                    Info << "rho = " << rho << endl;
                    Info << "nuf = " << nuf << endl;
                    Info << "voidfraction = " << voidfraction << endl;
                    Info << "Rep = " << Rep << endl;
                    Info << "Cd = " << Cd << endl;
                    Info << "drag = " << drag << endl;
                    
                    Pout << " "<< endl;
                }

                //Set value fields and write the probe
                if(probeIt_)
                {
                    #include "setupProbeModelfields.H"
                    vValues.append(drag);           //first entry must the be the force
                    vValues.append(Ur);
                    sValues.append(Rep);
                    sValues.append(Cd);
                    particleCloud_.probeM().writeProbe(index, sValues, vValues);
                }
            }
            // set force on particle
            if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j];
            else  for(int j=0;j<3;j++) impForces()[index][j] += drag[j];
            for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j];
        //}
    }

}
bool Foam::parcel::move(spray& sDB)
{
    const polyMesh& mesh = cloud().pMesh();
    const polyBoundaryMesh& pbMesh = mesh.boundaryMesh();

    const liquidMixture& fuels = sDB.fuels();

    scalar deltaT = sDB.runTime().deltaT().value();
    label Nf = fuels.components().size();
    label Ns = sDB.composition().Y().size();

    // Calculate the interpolated gas properties at the position of the parcel
    vector Up = sDB.UInterpolator().interpolate(position(), cell())
        + Uturb();
    scalar rhog = sDB.rhoInterpolator().interpolate(position(), cell());
    scalar pg = sDB.pInterpolator().interpolate(position(), cell());
    scalar Tg = sDB.TInterpolator().interpolate(position(), cell());

    scalarField Yfg(Nf, 0.0);

    scalar cpMixture = 0.0;
    for(label i=0; i<Ns; i++)
    {
        const volScalarField& Yi = sDB.composition().Y()[i];
        if (sDB.isLiquidFuel()[i])
        {
            label j = sDB.gasToLiquidIndex()[i];
            scalar Yicelli = Yi[cell()];
            Yfg[j] = Yicelli;
        }
        cpMixture += Yi[cell()]*sDB.gasProperties()[i].Cp(Tg);
    }

    // Correct the gaseous temperature for evaporated fuel

    scalar cellV = sDB.mesh().V()[cell()];
    scalar cellMass = rhog*cellV;
    Tg += sDB.shs()[cell()]/(cpMixture*cellMass);

    // Changed cut-off temperature for evaporation.  HJ, 27/Apr/2011
    Tg = max(273, Tg);

    scalar tauMomentum = GREAT;
    scalar tauHeatTransfer = GREAT;
    scalarField tauEvaporation(Nf, GREAT);
    scalarField tauBoiling(Nf, GREAT);

    bool keepParcel = true;

    setRelaxationTimes
    (
        cell(),
        tauMomentum,
        tauEvaporation,
        tauHeatTransfer,
        tauBoiling,
        sDB,
        rhog,
        Up,
        Tg,
        pg,
        Yfg,
        m()*fuels.Y(X()),
        deltaT
    );


    // set the end-time for the track
    scalar tEnd = (1.0 - stepFraction())*deltaT;

    // Set the maximum time step for this parcel

    // FPK changes: avoid temperature-out-of-range errors
    // in spray tracking.  HJ, 13/Oct/2007
    // tauEvaporation no longer multiplied by 1e20,
    // to account for the evaporation timescale
    // FPK, 13/Oct/2007
    scalar dtMax = min
    (
        tEnd,
        min
        (
            tauMomentum,
            min
            (
                mag(min(tauEvaporation)),
                min
                (
                    mag(tauHeatTransfer),
                    mag(min(tauBoiling))
                )
            )
        )
    )/sDB.subCycles();

    // prevent the number of subcycles from being too many
    // (10 000 seems high enough)
    dtMax = max(dtMax, 1.0e-4*tEnd);

    bool switchProcessor = false;
    vector planeNormal = vector::zero;
    if (sDB.twoD())
    {
        planeNormal = n() ^ sDB.axisOfSymmetry();
        planeNormal /= mag(planeNormal);
    }

    // move the parcel until there is no 'timeLeft'
    while (keepParcel && tEnd > SMALL && !switchProcessor)
    {
        // set the lagrangian time-step
        scalar dt = min(dtMax, tEnd);

        // remember which cell the parcel is in
        // since this will change if a face is hit
        label celli = cell();
        scalar p = sDB.p()[celli];

        // track parcel to face, or end of trajectory
        if (keepParcel)
        {
            // Track and adjust the time step if the trajectory
            // is not completed
            dt *= trackToFace(position() + dt*U_, sDB);

            // Decrement the end-time acording to how much time the track took
            tEnd -= dt;

            // Set the current time-step fraction.
            stepFraction() = 1.0 - tEnd/deltaT;

            if (onBoundary()) // hit face
            {
#               include "boundaryTreatment.H"
            }
        }

        if (keepParcel && sDB.twoD())
        {
            scalar z = position() & sDB.axisOfSymmetry();
            vector r = position() - z*sDB.axisOfSymmetry();

            if (mag(r) > SMALL)
            {
                correctNormal(sDB.axisOfSymmetry());
            }
        }

        // **** calculate the lagrangian source terms ****
        // First we get the 'old' properties.
        // and then 'update' them to get the 'new'
        // properties.
        // The difference is then added to the source terms.

        scalar oRho = fuels.rho(p, T(), X());
        scalarField oMass(Nf, 0.0);
        scalar oHg = 0.0;
        scalar oTotMass = m();
        scalarField oYf(fuels.Y(X()));

        forAll(oMass, i)
        {
            oMass[i] = m()*oYf[i];
            label j = sDB.liquidToGasIndex()[i];
            oHg += oYf[i]*sDB.gasProperties()[j].Hs(T());
        }

        vector oMom = m()*U();
        scalar oHv = fuels.hl(p, T(), X());
        scalar oH = oHg - oHv;
        scalar oPE = (p - fuels.pv(p, T(), X()))/oRho;

        // update the parcel properties (U, T, D)
        updateParcelProperties
        (
            dt,
            sDB,
            celli,
            face()
        );

        scalar nRho = fuels.rho(p, T(), X());
        scalar nHg = 0.0;
        scalarField nMass(Nf, 0.0);
        scalarField nYf(fuels.Y(X()));

        forAll(nMass, i)
        {
            nMass[i] = m()*nYf[i];
            label j = sDB.liquidToGasIndex()[i];
            nHg += nYf[i]*sDB.gasProperties()[j].Hs(T());
        }
Beispiel #3
0
void GidaspowDrag::setForce() const
{
    if (scaleDia_ > 1)
        Info << "Gidaspow using scale = " << scaleDia_ << endl;
    else if (particleCloud_.cg() > 1){
        scaleDia_=particleCloud_.cg();
        Info << "Gidaspow using scale from liggghts cg = " << scaleDia_ << endl;
    }

    // get viscosity field
    #ifdef comp
        const volScalarField nufField = particleCloud_.turbulence().mu() / rho_;
    #else
        const volScalarField& nufField = particleCloud_.turbulence().nu();
    #endif

    vector position(0,0,0);
    scalar voidfraction(1);
    vector Ufluid(0,0,0);
    vector drag(0,0,0);
    label cellI=0;

    vector Us(0,0,0);
    vector Uturb(0,0,0);
    vector Ur(0,0,0);
    scalar ds(0);
    scalar nuf(0);
    scalar rho(0);
    scalar magUr(0);
    scalar Rep(0);
    scalar Vs(0);
    scalar localPhiP(0);

    scalar CdMagUrLag(0);       //Cd of the very particle
    scalar KslLag(0);           //momentum exchange of the very particle (per unit volume)
    scalar betaP(0);             //momentum exchange of the very particle

    interpolationCellPoint<scalar> voidfractionInterpolator_(voidfraction_);
    interpolationCellPoint<vector> UInterpolator_(U_);

    #include "setupProbeModel.H"

    for(int index = 0;index <  particleCloud_.numberOfParticles(); ++index)
    {
        //if(mask[index][0])
        //{
            cellI = particleCloud_.cellIDs()[index][0];
            drag = vector(0,0,0);
            betaP = 0;
            Vs = 0;
            Ufluid =vector(0,0,0);
            voidfraction=0;

            if (cellI > -1) // particle Found
            {
                position     = particleCloud_.position(index);
                if(interpolation_)
                {
	            	//position     = particleCloud_.position(index);
                    voidfraction = voidfractionInterpolator_.interpolate(position,cellI);
                    Ufluid       = UInterpolator_.interpolate(position,cellI);
                    //Ensure interpolated void fraction to be meaningful
                    // Info << " --> voidfraction: " << voidfraction << endl;
                    if(voidfraction>1.00) voidfraction = 1.0;
                    if(voidfraction<0.10) voidfraction = 0.10;
                }
                else
                {
                    voidfraction = voidfraction_[cellI];
                    Ufluid = U_[cellI];                    
                }

                Us = particleCloud_.velocity(index);                    
                Ur = Ufluid-Us;
                
                //accounting for turbulent dispersion
                if(particleCloud_.dispersionM().isActive())
                {
                    Uturb=particleCloud_.fluidTurbVel(index);
                    Ur=(Ufluid+Uturb)-Us;                                        
                }
                                        
                magUr = mag(Ur);
                ds = 2*particleCloud_.radius(index)*phi_;
                rho = rho_[cellI];
                nuf = nufField[cellI];

                Rep=0.0;
                localPhiP = 1.0f-voidfraction+SMALL;
                Vs = ds*ds*ds*M_PI/6;

                //Compute specific drag coefficient (i.e., Force per unit slip velocity and per m³ SUSPENSION)
                //Wen and Yu, 1966
                if(voidfraction > 0.8) //dilute
                {
                    Rep=ds/scaleDia_*voidfraction*magUr/nuf;
                    CdMagUrLag = (24.0*nuf/(ds/scaleDia_*voidfraction)) //1/magUr missing here, but compensated in expression for KslLag!
                                 *(scalar(1)+0.15*Foam::pow(Rep, 0.687));

                    KslLag = 0.75*(
                                            rho*localPhiP*voidfraction*CdMagUrLag
                                          /
                                            (ds/scaleDia_*Foam::pow(voidfraction,2.65))
                                          );
                }
                //Ergun, 1952
                else  //dense
                {
                    KslLag = (150*Foam::pow(localPhiP,2)*nuf*rho)/
                             (voidfraction*ds/scaleDia_*ds/scaleDia_+SMALL)
                            +
                             (1.75*(localPhiP) * magUr * rho)/
                             ((ds/scaleDia_));
                }

                // calc particle's drag coefficient (i.e., Force per unit slip velocity and per m³ PARTICLE)
                betaP = KslLag / localPhiP;

                // calc particle's drag
                drag = Vs * betaP * Ur * scaleDrag_;

                if (modelType_=="B")
                    drag /= voidfraction;

                if(verbose_ && index >=0 && index <1)
                {
                    Pout << " "<< endl;
                    Pout << "Gidaspow drag force verbose: "  << endl;
                    
                    
                    Pout << "magUr = " << magUr << endl;
                    Pout << "localPhiP = " << localPhiP << endl;
                    Pout << "CdMagUrLag = " << CdMagUrLag << endl;
                    
                    Pout << "treatExplicit_ = " << treatExplicit_ << endl;
                    Pout << "implDEM_ = " << implDEM_ << endl;
                    Pout << "modelType_ = " << modelType_ << endl;                    
                    
                    Pout << "KslLag = " << KslLag << endl;                    
                                        
                    Pout << "cellI = " << cellI << endl;
                    Pout << "index = " << index << endl;                    
                    
                    Pout << "Ufluid = " << Ufluid << endl; 
                    Pout << "Uturb = " << Uturb << endl; 
                    Pout << "Us = " << Us << endl; 
                    
                    Pout << "Ur = " << Ur << endl;
                    Pout << "Vs = " << Vs << endl;                    
                    Pout << "ds = " << ds << endl;
                    Pout << "ds/scale = " << ds/scaleDia_ << endl;
                    Pout << "phi = " << phi_ << endl;
                    Pout << "rho = " << rho << endl;
                    Pout << "nuf = " << nuf << endl;
                    Pout << "voidfraction = " << voidfraction << endl;
                    Pout << "Rep = " << Rep << endl;
                    
                    Pout << "localPhiP = " << localPhiP << endl;
                    Pout << "betaP = " << betaP << endl;
                    
                    Pout << "drag = " << drag << endl;                    
                    Pout << "position = " << position << endl;
                    Pout << " "<< endl;
                }

                //Set value fields and write the probe
                if(probeIt_)
                {
                    #include "setupProbeModelfields.H"
                    vValues.append(drag);   //first entry must the be the force
                    vValues.append(Ur);
                    sValues.append(Rep);
                    sValues.append(betaP);
                    sValues.append(voidfraction);
                    particleCloud_.probeM().writeProbe(index, sValues, vValues);
                }
            }

            // set force on particle
            //treatExplicit_ = false by default
            if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j];
            else  for(int j=0;j<3;j++) impForces()[index][j] += drag[j];

            // set Cd
            //implDEM_ = false by default
            if(implDEM_)
            {
                for(int j=0;j<3;j++) fluidVel()[index][j]=Ufluid[j];

                if (modelType_=="B" && cellI > -1)
                    Cds()[index][0] = Vs*betaP/voidfraction*scaleDrag_;
                else
                    Cds()[index][0] = Vs*betaP*scaleDrag_;

            }else{
                for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j];
            }

        //}// end if mask
    }// end loop particles
}