void Foam::ThermoParcel<ParcelType>::setCellValues
(
    TrackData& td,
    const scalar dt,
    const label cellI
)
{
    KinematicParcel<ParcelType>::setCellValues(td, dt, cellI);

    cpc_ = td.cpInterp().interpolate(this->position(), cellI);

    Tc_ = td.TInterp().interpolate(this->position(), cellI);

    if (Tc_ < td.constProps().TMin())
    {
        WarningIn
        (
            "void Foam::ThermoParcel<ParcelType>::setCellValues"
            "("
            "TrackData&, "
            "const scalar, "
            "const label"
            ")"
        )   << "Limiting observed temperature in cell " << cellI << " to "
            << td.constProps().TMin() <<  nl << endl;

        Tc_ = td.constProps().TMin();
    }
}
Foam::scalar Foam::ThermoParcel<ParcelType>::calcHeatTransfer
(
    TrackData& td,
    const scalar dt,
    const label cellI,
    const scalar Re,
    const scalar Pr,
    const scalar kappa,
    const scalar d,
    const scalar rho,
    const scalar T,
    const scalar cp,
    const scalar NCpW,
    const scalar Sh,
    scalar& dhsTrans
)
{
    if (!td.cloud().heatTransfer().active())
    {
        return T;
    }

    // Calc heat transfer coefficient
    scalar htc = td.cloud().heatTransfer().htc(d, Re, Pr, kappa, NCpW);

    if (mag(htc) < ROOTVSMALL && !td.cloud().radiation())
    {
        return max(T + dt*Sh/(this->volume(d)*rho*cp), td.constProps().TMin());
    }

    const scalar As = this->areaS(d);
    scalar ap = Tc_ + Sh/As/htc;
    scalar bp = 6.0*(Sh/As + htc*(Tc_ - T));
    if (td.cloud().radiation())
    {
        const scalarField& G =
            td.cloud().mesh().objectRegistry::template
            lookupObject<volScalarField>("G");

        const scalar Gc = G[cellI];
        const scalar sigma = radiation::sigmaSB.value();
        const scalar epsilon = td.constProps().epsilon0();

        ap = (ap + epsilon*Gc/(4.0*htc))/(1.0 + epsilon*sigma*pow3(T)/htc);
        bp += 6.0*(epsilon*(Gc/4.0 - sigma*pow4(T)));
    }
    bp /= rho*d*cp*(ap - T);

    // Integrate to find the new parcel temperature
    IntegrationScheme<scalar>::integrationResult Tres =
        td.cloud().TIntegrator().integrate(T, dt, ap, bp);

    scalar Tnew = max(Tres.value(), td.constProps().TMin());

    dhsTrans += dt*htc*As*(0.5*(T + Tnew) - Tc_);

    return Tnew;
}
void Foam::KinematicParcel<ParcelType>::setCellValues
(
    TrackData& td,
    const scalar dt,
    const label cellI
)
{
    rhoc_ = td.rhoInterp().interpolate(this->position(), cellI);
    if (rhoc_ < td.constProps().rhoMin())
    {
        WarningIn
        (
            "void Foam::KinematicParcel<ParcelType>::setCellValues"
            "("
                "TrackData&, "
                "const scalar, "
                "const label"
            ")"
        )   << "Limiting observed density in cell " << cellI << " to "
            << td.constProps().rhoMin() <<  nl << endl;

        rhoc_ = td.constProps().rhoMin();
    }

    Uc_ = td.UInterp().interpolate(this->position(), cellI);

    muc_ = td.muInterp().interpolate(this->position(), cellI);

    // Apply dispersion components to carrier phase velocity
    Uc_ = td.cloud().dispersion().update
    (
        dt,
        cellI,
        U_,
        Uc_,
        UTurb_,
        tTurb_
    );
}
void Foam::ThermoParcel<ParcelType>::calcSurfaceValues
(
    TrackData& td,
    const label cellI,
    const scalar T,
    scalar& Ts,
    scalar& rhos,
    scalar& mus,
    scalar& Pr,
    scalar& kappa
) const
{
    // Surface temperature using two thirds rule
    Ts = (2.0*T + Tc_)/3.0;

    // Assuming thermo props vary linearly with T for small dT
    scalar factor = td.TInterp().interpolate(this->position(), cellI)/Ts;
    rhos = this->rhoc_*factor;
    mus = td.muInterp().interpolate(this->position(), cellI)/factor;

    Pr = td.constProps().Pr();
    kappa = cpc_*mus/Pr;
}