bool Foam::CollidingParcel<ParcelType>::move
(
    TrackData& td,
    const scalar trackTime
)
{
    typename TrackData::cloudType::parcelType& p =
        static_cast<typename TrackData::cloudType::parcelType&>(*this);

    switch (td.part())
    {
        case TrackData::tpVelocityHalfStep:
        {
            // First and last leapfrog velocity adjust part, required
            // before and after tracking and force calculation

            p.U() += 0.5*trackTime*p.f()/p.mass();

            p.angularMomentum() += 0.5*trackTime*p.torque();

            td.keepParticle = true;
            td.switchProcessor = false;

            break;
        }

        case TrackData::tpLinearTrack:
        {
            ParcelType::move(td, trackTime);

            break;
        }

        case TrackData::tpRotationalTrack:
        {
            NotImplemented;

            break;
        }

        default:
        {
            FatalErrorInFunction
                << td.part() << " is an invalid part of the tracking method."
                << abort(FatalError);
        }
    }

    return td.keepParticle;
}
void  Foam::KinematicCloud<CloudType>::motion(TrackData& td)
{
    td.part() = TrackData::tpLinearTrack;
    CloudType::move(td,  solution_.trackTime());

    updateCellOccupancy();
}
void  Foam::CollidingCloud<CloudType>::moveCollide
(
    TrackData& td,
    const scalar deltaT
)
{
    td.part() = TrackData::tpVelocityHalfStep;
    CloudType::move(td,  deltaT);

    td.part() = TrackData::tpLinearTrack;
    CloudType::move(td,  deltaT);

    // td.part() = TrackData::tpRotationalTrack;
    // CloudType::move(td);

    this->updateCellOccupancy();

    this->collision().collide();

    td.part() = TrackData::tpVelocityHalfStep;
    CloudType::move(td,  deltaT);
}
示例#4
0
void Foam::KinematicCloud<CloudType>::evolveCloud(TrackData& td)
{
    if (solution_.coupled())
    {
        td.cloud().resetSourceTerms();
    }

    if (solution_.transient())
    {
        label preInjectionSize = this->size();

        this->surfaceFilm().inject(td);

        // Update the cellOccupancy if the size of the cloud has changed
        // during the injection.
        if (preInjectionSize != this->size())
        {
            updateCellOccupancy();
            preInjectionSize = this->size();
        }

        injectors_.inject(td);


        // Assume that motion will update the cellOccupancy as necessary
        // before it is required.
        td.cloud().motion(td);

        stochasticCollision().update(solution_.trackTime());
    }
    else
    {
//        this->surfaceFilm().injectSteadyState(td);

        injectors_.injectSteadyState(td, solution_.trackTime());

        td.part() = TrackData::tpLinearTrack;
        CloudType::move(td,  solution_.trackTime());
    }
}
示例#5
0
bool Foam::CollidingParcel<ParcelType>::move
(
    TrackData& td,
    const scalar trackTime
)
{
    typename TrackData::cloudType::parcelType& p =
        static_cast<typename TrackData::cloudType::parcelType&>(*this);

    td.switchProcessor = false;
    td.keepParticle = true;

    const polyMesh& mesh = td.cloud().pMesh();
    const polyBoundaryMesh& pbMesh = mesh.boundaryMesh();
    const scalarField& V = mesh.cellVolumes();

    switch (td.part())
    {
        case TrackData::tpVelocityHalfStep:
        {
            // First and last leapfrog velocity adjust part, required
            // before and after tracking and force calculation

            p.U() += 0.5*trackTime*p.f()/p.mass();

            p.angularMomentum() += 0.5*trackTime*p.torque();

            break;
        }

        case TrackData::tpLinearTrack:
        {
            scalar tEnd = (1.0 - p.stepFraction())*trackTime;
            const scalar dtMax = tEnd;

            while (td.keepParticle && !td.switchProcessor && tEnd > ROOTVSMALL)
            {
                // Apply correction to position for reduced-D cases
                meshTools::constrainToMeshCentre(mesh, p.position());

                // 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
                const label cellI = p.cell();

                const scalar magU = mag(p.U());
                if (p.active() && magU > ROOTVSMALL)
                {
                    const scalar d = dt*magU;
                    const scalar maxCo = td.cloud().solution().maxCo();
                    const scalar dCorr = min(d, maxCo*cbrt(V[cellI]));
                    dt *=
                        dCorr/d
                       *p.trackToFace(p.position() + dCorr*p.U()/magU, td);
                }

                tEnd -= dt;
                p.stepFraction() = 1.0 - tEnd/trackTime;

                // Avoid problems with extremely small timesteps
                if (dt > ROOTVSMALL)
                {
                    // Update cell based properties
                    p.setCellValues(td, dt, cellI);

                    if (td.cloud().solution().cellValueSourceCorrection())
                    {
                        p.cellValueSourceCorrection(td, dt, cellI);
                    }

                    p.calc(td, dt, cellI);
                }

                if (p.onBoundary() && td.keepParticle)
                {
                    if (isA<processorPolyPatch>(pbMesh[p.patch(p.face())]))
                    {
                        td.switchProcessor = true;
                    }
                }

                p.age() += dt;
            }

            break;
        }

        case TrackData::tpRotationalTrack:
        {
            notImplemented("TrackData::tpRotationalTrack");

            break;
        }

        default:
        {
            FatalErrorIn
            (
                "CollidingParcel<ParcelType>::move(TrackData&, const scalar)"
            )   << td.part() << " is an invalid part of the tracking method."
                << abort(FatalError);
        }
    }

    return td.keepParticle;
}
示例#6
0
void Foam::SprayCloud<CloudType>::motion(TrackData& td)
{
    const scalar dt = this->solution().trackTime();

    td.part() = TrackData::tpLinearTrack;
    CloudType::move(td, dt);

    this->updateCellOccupancy();

    if (stochasticCollision().active())
    {
        const liquidMixtureProperties& liqMix = this->composition().liquids();

        label i = 0;
        forAllIter(typename SprayCloud<CloudType>, *this, iter)
        {
            label j = 0;
            forAllIter(typename SprayCloud<CloudType>, *this, jter)
            {
                if (j > i)
                {
                    parcelType& p = iter();
                    scalar Vi = this->mesh().V()[p.cell()];
                    scalarField X1(liqMix.X(p.Y()));
                    scalar sigma1 = liqMix.sigma(p.pc(), p.T(), X1);
                    scalar mp = p.mass()*p.nParticle();

                    parcelType& q = jter();
                    scalar Vj = this->mesh().V()[q.cell()];
                    scalarField X2(liqMix.X(q.Y()));
                    scalar sigma2 = liqMix.sigma(q.pc(), q.T(), X2);
                    scalar mq = q.mass()*q.nParticle();

                    bool updateProperties = stochasticCollision().update
                    (
                        dt,
                        this->rndGen(),
                        p.position(),
                        mp,
                        p.d(),
                        p.nParticle(),
                        p.U(),
                        p.rho(),
                        p.T(),
                        p.Y(),
                        sigma1,
                        p.cell(),
                        Vi,
                        q.position(),
                        mq,
                        q.d(),
                        q.nParticle(),
                        q.U(),
                        q.rho(),
                        q.T(),
                        q.Y(),
                        sigma2,
                        q.cell(),
                        Vj
                    );

                    // for coalescence we need to update the density and
                    // the diameter cause of the temp/conc/mass-change
                    if (updateProperties)
                    {
                        if (mp > VSMALL)
                        {
                            scalarField Xp(liqMix.X(p.Y()));
                            p.rho() = liqMix.rho(p.pc(), p.T(), Xp);
                            p.Cp() = liqMix.Cp(p.pc(), p.T(), Xp);
                            p.d() =
                                cbrt
                                (
                                    6.0*mp
                                   /(
                                        p.nParticle()
                                       *p.rho()
                                       *constant::mathematical::pi
                                    )
                                );
                        }

                        if (mq > VSMALL)
                        {
                            scalarField Xq(liqMix.X(q.Y()));
                            q.rho() = liqMix.rho(q.pc(), q.T(), Xq);
                            q.Cp() = liqMix.Cp(q.pc(), q.T(), Xq);
                            q.d() =
                                cbrt
                                (
                                    6.0*mq
                                   /(
                                        q.nParticle()
                                       *q.rho()
                                       *constant::mathematical::pi
                                    )
                                );
                        }
                    }
                }
                j++;
            }
            i++;
        }

        // remove coalesced particles (diameter set to 0)
        forAllIter(typename SprayCloud<CloudType>, *this, iter)
        {
            parcelType& p = iter();
            if (p.mass() < VSMALL)
            {
                this->deleteParticle(p);
            }
        }
    }
}