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()); }
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 }