//- Move a softParticle from one position to another. bool Foam::softParticle::move ( trackingData& td, const scalar trackTime ) { td.switchProcessor = false; td.keepParticle = true; const polyBoundaryMesh& pbMesh = mesh_.boundaryMesh(); scalar tEnd = (1.0 - stepFraction())*trackTime; scalar dtMax = tEnd; while (td.keepParticle && !td.switchProcessor && tEnd > ROOTVSMALL) { if (debug) { Pout<< "Time = " << mesh_.time().timeName() << " trackTime = " << trackTime << " steptFraction() = " << stepFraction() << endl; Pout<< "Before trackToFace, particle tag is: " << ptag() << ". Particle position is: " << position() << endl; } scalar dt = min(dtMax, tEnd); dt *= trackToFace(position() + dt*moveU_, td); tEnd -= dt; stepFraction() = 1.0 - tEnd/trackTime; if (debug) { Pout<< "After trackToFace, particle tag is: " << ptag() << ". Particle position is: " << position() << endl; } if (onBoundary() && td.keepParticle) { if (isA<processorPolyPatch>(pbMesh[patch(face())])) { td.switchProcessor = true; // Pout<< "Cross the processor boundary.." << endl; } } } return td.keepParticle; }
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()); }
bool Foam::solidParticle::move(solidParticle::trackData& td) { td.switchProcessor = false; td.keepParticle = true; const polyMesh& mesh = cloud().pMesh(); const polyBoundaryMesh& pbMesh = mesh.boundaryMesh(); scalar deltaT = mesh.time().deltaT().value(); scalar tEnd = (1.0 - stepFraction())*deltaT; scalar dtMax = tEnd; while (td.keepParticle && !td.switchProcessor && tEnd > SMALL) { if (debug) { Info<< "Time = " << mesh.time().timeName() << " deltaT = " << deltaT << " tEnd = " << tEnd << " steptFraction() = " << stepFraction() << endl; } // 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(); dt *= trackToFace(position() + dt*U_, td); tEnd -= dt; stepFraction() = 1.0 - tEnd/deltaT; cellPointWeight cpw(mesh, position(), celli, face()); scalar rhoc = td.rhoInterp().interpolate(cpw); vector Uc = td.UInterp().interpolate(cpw); scalar nuc = td.nuInterp().interpolate(cpw); scalar rhop = td.spc().rhop(); scalar magUr = mag(Uc - U_); scalar ReFunc = 1.0; scalar Re = magUr*d_/nuc; if (Re > 0.01) { ReFunc += 0.15*pow(Re, 0.687); } scalar Dc = (24.0*nuc/d_)*ReFunc*(3.0/4.0)*(rhoc/(d_*rhop)); U_ = (U_ + dt*(Dc*Uc + (1.0 - rhoc/rhop)*td.g()))/(1.0 + dt*Dc); if (onBoundary() && td.keepParticle) { // Bug fix. HJ, 25/Aug/2010 if (face() > -1) { if (isType<processorPolyPatch>(pbMesh[patch(face())])) { td.switchProcessor = true; } } } } return td.keepParticle; }
bool Box::onBoundary(Point p, double fudge) { return onBoundary(_min.x, p.x, fudge) || onBoundary(_max.x, p.x, fudge) || onBoundary(_min.y, p.y, fudge) || onBoundary(_max.y, p.y, fudge); }