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.1k stars 387 forks source link

VS DX cooling coil outlet air condition calculation problem when PLR is zero for CV system #8543

Closed Nigusse closed 3 years ago

Nigusse commented 3 years ago

Issue overview

A variable speed DX cooling coil in a constant volume system calculates outlet air condition when the compressor part-load-ratio is zero. At low supply air flow rates, the calculated coil outlet temperature can be very low (e.g., -46C) that triggers Psych error message. This is a defect.

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.

Nigusse commented 3 years ago

This issue was observed while addressing issue #8497. Investigation led me to be suspicious about a code section in VS DX Cooling Coil. See the code snippet below and a link here.

        // calculate coil outlet state variables
        state.dataVariableSpeedCoils->LoadSideOutletEnth = state.dataVariableSpeedCoils->LoadSideInletEnth - state.dataVariableSpeedCoils->QLoadTotal / state.dataVariableSpeedCoils->LoadSideMassFlowRate;
        state.dataVariableSpeedCoils->LoadSideOutletDBTemp = state.dataVariableSpeedCoils->LoadSideInletDBTemp - state.dataVariableSpeedCoils->QSensible / (state.dataVariableSpeedCoils->LoadSideMassFlowRate * CpAir);

        MaxHumRat = PsyWFnTdbRhPb(state, state.dataVariableSpeedCoils->LoadSideOutletDBTemp, 0.9999, state.dataVariableSpeedCoils->VarSpeedCoil(DXCoilNum).InletAirPressure, RoutineName);
        MaxOutletEnth = PsyHFnTdbW(state.dataVariableSpeedCoils->LoadSideOutletDBTemp, MaxHumRat);
        if (state.dataVariableSpeedCoils->LoadSideOutletEnth > MaxOutletEnth) {
            state.dataVariableSpeedCoils->LoadSideOutletEnth = MaxOutletEnth;
            // QLoadTotal = state.dataVariableSpeedCoils->LoadSideMassFlowRate * (LoadSideInletEnth - LoadSideOutletEnth)
        }
        state.dataVariableSpeedCoils->LoadSideOutletHumRat = PsyWFnTdbH(state, state.dataVariableSpeedCoils->LoadSideOutletDBTemp, state.dataVariableSpeedCoils->LoadSideOutletEnth, RoutineName);
        if (state.dataVariableSpeedCoils->LoadSideOutletHumRat > MaxHumRat) {
            state.dataVariableSpeedCoils->LoadSideOutletHumRat = MaxHumRat;
        }

The above code section is executed regardless of the compressor PartLoadRatio value. Stepping through the code confirmed that the VS DX cooling coil outlet condition is calculated even when the PartLoadRatio is zero leading to very low temperature (e.g. -34C, -46C) and when the flow rate is smaller. But what is interesting is that here and in code snippet shown below, the VS DX cooling coil outlet is set to coil inlet condition when the PartLoadRatio is zero and the supply fan operating mode is ContFanCycCoil.

        if (CyclingScheme == ContFanCycCoil) {
            // continuous fan, cycling compressor
            state.dataVariableSpeedCoils->VarSpeedCoil(DXCoilNum).OutletAirEnthalpy = PartLoadRatio * state.dataVariableSpeedCoils->LoadSideOutletEnth + (1.0 - PartLoadRatio) * state.dataVariableSpeedCoils->LoadSideInletEnth;
            state.dataVariableSpeedCoils->VarSpeedCoil(DXCoilNum).OutletAirHumRat = PartLoadRatio * state.dataVariableSpeedCoils->LoadSideOutletHumRat + (1.0 - PartLoadRatio) * state.dataVariableSpeedCoils->LoadSideInletHumRat;
            state.dataVariableSpeedCoils->VarSpeedCoil(DXCoilNum).OutletAirDBTemp = PsyTdbFnHW(state.dataVariableSpeedCoils->VarSpeedCoil(DXCoilNum).OutletAirEnthalpy, state.dataVariableSpeedCoils->VarSpeedCoil(DXCoilNum).OutletAirHumRat);
            state.dataVariableSpeedCoils->PLRCorrLoadSideMdot = state.dataVariableSpeedCoils->LoadSideMassFlowRate;
        } else {

Therefore, I do not see a value executing this section of the code (the first snippet) to get the coil outlet condition when the PartLoadRatio is zero and the supply fan operating mode is ContFanCycCoil. As the results I am proposing the following code modification:

        if ( (PartLoadRatio > 0.0 && CyclingScheme == ContFanCycCoil) || (CyclingScheme == CycFanCycCoil) ) {
            // calculate coil outlet state variables
            state.dataVariableSpeedCoils->LoadSideOutletEnth = state.dataVariableSpeedCoils->LoadSideInletEnth - state.dataVariableSpeedCoils->QLoadTotal / state.dataVariableSpeedCoils->LoadSideMassFlowRate;
            state.dataVariableSpeedCoils->LoadSideOutletDBTemp = state.dataVariableSpeedCoils->LoadSideInletDBTemp - state.dataVariableSpeedCoils->QSensible / (state.dataVariableSpeedCoils->LoadSideMassFlowRate * CpAir);

            MaxHumRat = PsyWFnTdbRhPb( state, state.dataVariableSpeedCoils->LoadSideOutletDBTemp, 0.9999, state.dataVariableSpeedCoils->VarSpeedCoil( DXCoilNum ).InletAirPressure, RoutineName );
            MaxOutletEnth = PsyHFnTdbW( state.dataVariableSpeedCoils->LoadSideOutletDBTemp, MaxHumRat );
            if ( state.dataVariableSpeedCoils->LoadSideOutletEnth > MaxOutletEnth ) {
                state.dataVariableSpeedCoils->LoadSideOutletEnth = MaxOutletEnth;
                // QLoadTotal = state.dataVariableSpeedCoils->LoadSideMassFlowRate * (LoadSideInletEnth - LoadSideOutletEnth)
            }
            state.dataVariableSpeedCoils->LoadSideOutletHumRat = PsyWFnTdbH( state, state.dataVariableSpeedCoils->LoadSideOutletDBTemp, state.dataVariableSpeedCoils->LoadSideOutletEnth, RoutineName );
            if ( state.dataVariableSpeedCoils->LoadSideOutletHumRat > MaxHumRat ) {
                state.dataVariableSpeedCoils->LoadSideOutletHumRat = MaxHumRat;
            }
        }