NREL / EnergyPlus

EnergyPlus™ is a whole building energy simulation program that engineers, architects, and researchers use to model both energy consumption and water use in buildings.
https://energyplus.net
Other
1.07k stars 381 forks source link

sensible + latent output doesn't match total output energy in VRF #10607

Open yujiex opened 1 month ago

yujiex commented 1 month ago

Issue overview

The following is how the sensible and latent output is computed in CalcVRF_FluidTCtrl and CalcVRF

    LoadMet = AirMassFlow * PsyDeltaHSenFnTdb2W2Tdb1W1(TempOut, SpecHumOut, TempIn, SpecHumIn); // sensible {W}
    LatentLoadMet = AirMassFlow * (SpecHumOut - SpecHumIn);                                     // latent {kgWater/s}

The LatentLoadMet in kgWater/s is converted to W in function ReportVRFTerminalUnit

    Real64 const H2OHtOfVap = PsyHgAirFnWTdb(0.0, TempOut);
    // convert latent in kg/s to watts
    TotalConditioning = SensibleConditioning + (LatentConditioning * H2OHtOfVap);

    if (TotalConditioning <= 0.0) {
        state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalCoolingRate = std::abs(TotalConditioning);
        state.dataHVACVarRefFlow->VRFTU(VRFTUNum).TotalHeatingRate = 0.0;
    ...

This is different from the calculation in the GeneralRoutines.cc as follows

        TotalOutput = MassFlow * (Psychrometrics::PsyHFnTdbW(TDB2, W2) - Psychrometrics::PsyHFnTdbW(TDB1, W1)); // total addition/removal rate, {W};
        SensibleOutput = MassFlow * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(TDB2, W2, TDB1, W1); // sensible addition/removal rate, {W};
        LatentOutput = TotalOutput - SensibleOutput;                                                // latent addition/removal rate, {W}

However when adding the sensible output to this latent output computed as the above as (AirMassFlow * (SpecHumOut - SpecHumIn)) * PsyHgAirFnWTdb(0.0, TempOut), the total does not match the TotalOutput computed as follows.

TotalOutput = AirMassFlow * (Psychrometrics::PsyHFnTdbW(TempOut, SpecHumOut) - Psychrometrics::PsyHFnTdbW(TempIn, SpecHumIn)); // total addition/removal rate, {W};

This can be observed by adding this to the code and running the US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf example file using weather file USA_NY_New.York-John.F.Kennedy.Intl.AP.744860_TMY3.epw:

    // calculate sensible load met using delta enthalpy
    LoadMet = AirMassFlow * PsyDeltaHSenFnTdb2W2Tdb1W1(TempOut, SpecHumOut, TempIn, SpecHumIn); // sensible {W}
    LatentLoadMet = AirMassFlow * (SpecHumOut - SpecHumIn);                                     // latent {kgWater/s}
    // debug print
    if (AirMassFlow > 0.0) {
        Real64 diff = abs(LoadMet + LatentLoadMet * PsyHgAirFnWTdb(0.0, TempOut) -
                          AirMassFlow * (Psychrometrics::PsyHFnTdbW(TempOut, SpecHumOut) - Psychrometrics::PsyHFnTdbW(TempIn, SpecHumIn)));
        if (diff > 10) {
            fmt::print("too large difference at {}: diff = {}, TempOut={}, SpecHumOut={}, TempIn={}, SpecHumIn={}\n",
                       state.dataEnvrn->CurMnDyHr,
                       diff,
                       TempOut,
                       SpecHumOut,
                       TempIn,
                       SpecHumIn);
        }
    }

This txt file has all has the output with the debugging print large_diff.txt

The following is an instance with large difference between the TotalOutput and the SensibleOutput + LatentOutput

diff = 10.083951937490237, 
TempOut=18.710784212366956, 
SpecHumOut=0.012661531422619608, 
TempIn=23.888585998167404, 
SpecHumIn=0.014184600203099161

Defect file

US+SF+CZ4A+hp+crawlspace+IECC_2006_VRF.idf with USA_NY_New.York-John.F.Kennedy.Intl.AP.744860_TMY3.epw

Details

Some additional details for this issue (if relevant):

Checklist

Add to this list or remove from it as applicable. This is a simple templated set of guidelines.

mjwitte commented 1 month ago

@yujiex There are some special pysch functions for this that are used by the other DX coils. See https://github.com/NREL/EnergyPlus/blob/15f64911c898c7d5dd3465b2bd472fd107e7f148/src/EnergyPlus/Coils/CoilCoolingDX.cc#L753-L760

Indeed. This is how cooling coil cooling electricity rate (thisDXCoolingCoil.TotalCoolingEnergyRate) is calculated. While the TU cooling rate (thisVRFTU.TotalCoolingRate) uses the calculation in CalcVRF_FluidTCtrl and CalcVRF, so the TU one is a bit different from the coil one. I saw this happening when fixing some unit tests in another VRF branch.

Oh you mean I should change the TU sensible and latent output calculation in CalcVRF_FluidTCtrl and CalcVRF to use this function as well? @mjwitte