コード例 #1
0
Foam::tmp<Foam::volScalarField> Foam::XiEqModels::basicSubGrid::XiEq() const
{
    const fvMesh& mesh = Su_.mesh();
    const volVectorField& U = mesh.lookupObject<volVectorField>("U");

    const volScalarField& Nv = mesh.lookupObject<volScalarField>("Nv");
    const volSymmTensorField& nsv =
        mesh.lookupObject<volSymmTensorField>("nsv");

    volScalarField magU(mag(U));
    volVectorField Uhat
    (
        U/(mag(U) + dimensionedScalar("Usmall", U.dimensions(), 1e-4))
    );

    const scalarField Cw = pow(mesh.V(), 2.0/3.0);

    tmp<volScalarField> tN
    (
        new volScalarField
        (
            IOobject
            (
                "tN",
                mesh.time().constant(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            mesh,
            dimensionedScalar("zero", Nv.dimensions(), 0.0),
            zeroGradientFvPatchVectorField::typeName
        )
    );

    volScalarField& N = tN();

    N.internalField() = Nv.internalField()*Cw;

    tmp<volSymmTensorField> tns
    (
        new volSymmTensorField
        (
            IOobject
            (
                "tns",
                U.mesh().time().timeName(),
                U.mesh(),
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            U.mesh(),
            dimensionedSymmTensor
            (
                "zero",
                nsv.dimensions(),
                pTraits<symmTensor>::zero
            ),
             zeroGradientFvPatchSymmTensorField::typeName
        )
    );

    volSymmTensorField& ns = tns();

    ns.internalField() = nsv.internalField()*Cw;

    volScalarField n(max(N - (Uhat & ns & Uhat), scalar(1e-4)));

    volScalarField b((Uhat & B_ & Uhat)/sqrt(n));

    volScalarField up(sqrt((2.0/3.0)*turbulence_.k()));

    volScalarField XiSubEq
    (
        scalar(1)
      + max(2.2*sqrt(b), min(0.34*magU/up*sqrt(b), scalar(1.6)))
      * min(n, scalar(1))
    );

    return (XiSubEq*XiEqModel_->XiEq());
}
コード例 #2
0
// solve vegetation model
void modifiedVegetationModel::solve(volVectorField& U, volScalarField& T, volScalarField& w)
{
    // solve radiation within vegetation
    radiation();

    const double p_ = 101325;

    // Magnitude of velocity
    volScalarField magU("magU", mag(U));

    // Bounding velocity
    bound(magU, UMin_);

    // solve aerodynamic, stomatal resistance
    volScalarField new_Tl("new_Tl", Tl_);

    // info
    Info << "    max leaf temp tl=" << max(T.internalField())
         << "k, iteration i=0" << endl;

    scalar maxError, maxRelError;
    int i;

    // solve leaf temperature, iteratively.
    int maxIter = 500;
    for (i=1; i<=maxIter; i++)
    {
        // Solve aerodynamc, stomatal resistance
        resistance(magU, T, w, new_Tl);

        forAll(LAD_, cellI)
        {
            if (LAD_[cellI] > 10*SMALL)
            {
                // Initial leaf temperature
                if (i==1)
                    Tl_[cellI];// = T[cellI];//*0. + 300.;//T[cellI];

                // Calculate saturated density, specific humidity
                rhosat_[cellI] = calc_rhosat(Tl_[cellI]);
                evsat_[cellI] = calc_evsat(Tl_[cellI]);
                wsat_[cellI] = 0.621945*(evsat_[cellI]/(p_-evsat_[cellI])); // ASHRAE 1, eq.23

                // Calculate transpiration rate]);
                E_[cellI] = nEvapSides_.value()*LAD_[cellI]*rhoa_.value()*(wsat_[cellI]-w[cellI])/(ra_[cellI]+rs_[cellI]);
                //E_[cellI] = 0.0; // No evapotranspiration

                // Calculate latent heat flux
                Ql_[cellI] = lambda_.value()*E_[cellI];

                // Calculate new leaf temperature
                new_Tl[cellI] = T[cellI] + (Rn_[cellI] - Ql_[cellI])*(ra_[cellI]/(2.0*rhoa_.value()*cpa_.value()*LAD_[cellI]));

            }
        }

        // info
        Info << "    max leaf temp tl=" << gMax(new_Tl.internalField())
             << " K, iteration i="   << i << endl;

        // Check rel. L-infinity error
        maxError = gMax(mag(new_Tl.internalField()-Tl_.internalField()));
        maxRelError = maxError/gMax(mag(new_Tl.internalField()));

        // update leaf temp.
        forAll(Tl_, cellI)
            Tl_[cellI] = 0.5*Tl_[cellI]+0.5*new_Tl[cellI];

         // convergence check
         if (maxRelError < 1e-8)
             break;
    }
    Tl_.correctBoundaryConditions();

    // Iteration info
    Info << "Vegetation model:  Solving for Tl, Final residual = " << maxError
         << ", Final relative residual = " << maxRelError
         << ", No Iterations " << i << endl;

    Info << "temperature parameters: max Tl = " << gMax(Tl_)
         << ", min T = " << gMin(T) << ", max T = " << gMax(T) << endl;

    Info << "resistances: max rs = " << gMax(rs_)
         << ", max ra = " << gMax(ra_) << endl;

    // Final: Solve aerodynamc, stomatal resistance
    resistance(magU, T, w, Tl_);

    // Final: Update sensible and latent heat flux
    forAll(LAD_, cellI)
    {
        if (LAD_[cellI] > 10*SMALL)
        {
            // Calculate saturated density, specific humidity
            rhosat_[cellI] = calc_rhosat(Tl_[cellI]);
            evsat_[cellI] = calc_evsat(Tl_[cellI]);
            wsat_[cellI] = 0.621945*(evsat_[cellI]/(p_-evsat_[cellI])); // ASHRAE 1, eq.23

            // Calculate transpiration rate
            E_[cellI] = nEvapSides_.value()*LAD_[cellI]*rhoa_.value()*(wsat_[cellI]-w[cellI])/(ra_[cellI]+rs_[cellI]); // todo: implement switch for double or single side

            // Calculate latent heat flux
            Ql_[cellI] = lambda_.value()*E_[cellI];

            // Calculate sensible heat flux
            Qs_[cellI] = 2.0*rhoa_.value()*cpa_.value()*LAD_[cellI]*(Tl_[cellI]-T[cellI])/ra_[cellI];
        }
    }
    rhosat_.correctBoundaryConditions();
    wsat_.correctBoundaryConditions();
    E_.correctBoundaryConditions();
    Ql_.correctBoundaryConditions();
    Qs_.correctBoundaryConditions();


}