Exemplo n.º 1
0
bool Foam::solidParticle::move
(
    solidParticleCloud& cloud,
    trackingData& td,
    const scalar trackTime
)
{
    td.switchProcessor = false;
    td.keepParticle = true;

    while (td.keepParticle && !td.switchProcessor && stepFraction() < 1)
    {
        if (debug)
        {
            Info<< "Time = " << mesh().time().timeName()
                << " trackTime = " << trackTime
                << " steptFraction() = " << stepFraction() << endl;
        }


        const scalar sfrac = stepFraction();

        const scalar f = 1 - stepFraction();
        trackToAndHitFace(f*trackTime*U_, f, cloud, td);

        const scalar dt = (stepFraction() - sfrac)*trackTime;

        const tetIndices tetIs = this->currentTetIndices();
        scalar rhoc = td.rhoInterp().interpolate(this->coordinates(), tetIs);
        vector Uc = td.UInterp().interpolate(this->coordinates(), tetIs);
        scalar nuc = td.nuInterp().interpolate(this->coordinates(), tetIs);

        scalar rhop = cloud.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);
    }

    return td.keepParticle;
}
Exemplo n.º 2
0
//- 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;
}
Exemplo n.º 3
0
bool Foam::molecule::move
(
    moleculeCloud& cloud,
    trackingData& td,
    const scalar trackTime
)
{
    td.switchProcessor = false;
    td.keepParticle = true;

    const constantProperties& constProps(cloud.constProps(id_));

    if (td.part() == 0)
    {
        // First leapfrog velocity adjust part, required before tracking+force
        // part

        v_ += 0.5*trackTime*a_;

        pi_ += 0.5*trackTime*tau_;
    }
    else if (td.part() == 1)
    {
        // Leapfrog tracking part

        while (td.keepParticle && !td.switchProcessor && stepFraction() < 1)
        {
            const scalar f = 1 - stepFraction();
            trackToAndHitFace(f*trackTime*v_, f, cloud, td);
        }
    }
    else if (td.part() == 2)
    {
        // Leapfrog orientation adjustment, carried out before force calculation
        // but after tracking stage, i.e. rotation carried once linear motion
        // complete.

        if (!constProps.pointMolecule())
        {
            const diagTensor& momentOfInertia(constProps.momentOfInertia());

            tensor R;

            if (!constProps.linearMolecule())
            {
                R = rotationTensorX(0.5*trackTime*pi_.x()/momentOfInertia.xx());
                pi_ = pi_ & R;
                Q_ = Q_ & R;
            }

            R = rotationTensorY(0.5*trackTime*pi_.y()/momentOfInertia.yy());
            pi_ = pi_ & R;
            Q_ = Q_ & R;

            R = rotationTensorZ(trackTime*pi_.z()/momentOfInertia.zz());
            pi_ = pi_ & R;
            Q_ = Q_ & R;

            R = rotationTensorY(0.5*trackTime*pi_.y()/momentOfInertia.yy());
            pi_ = pi_ & R;
            Q_ = Q_ & R;

            if (!constProps.linearMolecule())
            {
                R = rotationTensorX(0.5*trackTime*pi_.x()/momentOfInertia.xx());
                pi_ = pi_ & R;
                Q_ = Q_ & R;
            }
        }

        setSitePositions(constProps);
    }
    else if (td.part() == 3)
    {
        // Second leapfrog velocity adjust part, required after tracking+force
        // part

        scalar m = constProps.mass();

        a_ = Zero;

        tau_ = Zero;

        forAll(siteForces_, s)
        {
            const vector& f = siteForces_[s];

            a_ += f/m;

            tau_ += (constProps.siteReferencePositions()[s] ^ (Q_.T() & f));
        }

        v_ += 0.5*trackTime*a_;

        pi_ += 0.5*trackTime*tau_;

        if (constProps.pointMolecule())
        {
            tau_ = Zero;

            pi_ = Zero;
        }

        if (constProps.linearMolecule())
        {
            tau_.x() = 0.0;

            pi_.x() = 0.0;
        }
    }
Exemplo n.º 4
0
bool Foam::molecule::move(molecule::trackingData& td, const scalar trackTime)
{
    td.switchProcessor = false;
    td.keepParticle = true;

    const constantProperties& constProps(td.cloud().constProps(id_));

    if (td.part() == 0)
    {
        // First leapfrog velocity adjust part, required before tracking+force
        // part

        v_ += 0.5*trackTime*a_;

        pi_ += 0.5*trackTime*tau_;
    }
    else if (td.part() == 1)
    {
        // Leapfrog tracking part

        scalar tEnd = (1.0 - stepFraction())*trackTime;
        scalar dtMax = tEnd;

        while (td.keepParticle && !td.switchProcessor && tEnd > ROOTVSMALL)
        {
            // set the lagrangian time-step
            scalar dt = min(dtMax, tEnd);

            dt *= trackToFace(position() + dt*v_, td);

            tEnd -= dt;
            stepFraction() = 1.0 - tEnd/trackTime;
        }
    }
    else if (td.part() == 2)
    {
        // Leapfrog orientation adjustment, carried out before force calculation
        // but after tracking stage, i.e. rotation carried once linear motion
        // complete.

        if (!constProps.pointMolecule())
        {
            const diagTensor& momentOfInertia(constProps.momentOfInertia());

            tensor R;

            if (!constProps.linearMolecule())
            {
                R = rotationTensorX(0.5*trackTime*pi_.x()/momentOfInertia.xx());
                pi_ = pi_ & R;
                Q_ = Q_ & R;
            }

            R = rotationTensorY(0.5*trackTime*pi_.y()/momentOfInertia.yy());
            pi_ = pi_ & R;
            Q_ = Q_ & R;

            R = rotationTensorZ(trackTime*pi_.z()/momentOfInertia.zz());
            pi_ = pi_ & R;
            Q_ = Q_ & R;

            R = rotationTensorY(0.5*trackTime*pi_.y()/momentOfInertia.yy());
            pi_ = pi_ & R;
            Q_ = Q_ & R;

            if (!constProps.linearMolecule())
            {
                R = rotationTensorX(0.5*trackTime*pi_.x()/momentOfInertia.xx());
                pi_ = pi_ & R;
                Q_ = Q_ & R;
            }
        }

        setSitePositions(constProps);
    }
    else if (td.part() == 3)
    {
        // Second leapfrog velocity adjust part, required after tracking+force
        // part

        scalar m = constProps.mass();

        a_ = vector::zero;

        tau_ = vector::zero;

        forAll(siteForces_, s)
        {
            const vector& f = siteForces_[s];

            a_ += f/m;

            tau_ += (constProps.siteReferencePositions()[s] ^ (Q_.T() & f));
        }

        v_ += 0.5*trackTime*a_;

        pi_ += 0.5*trackTime*tau_;

        if (constProps.pointMolecule())
        {
            tau_ = vector::zero;

            pi_ = vector::zero;
        }

        if (constProps.linearMolecule())
        {
            tau_.x() = 0.0;

            pi_.x() = 0.0;
        }
    }
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());
        }
Exemplo n.º 6
0
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;
}