diff --git a/design/FY2021/ReportIndividualInfiltrationObject.md b/design/FY2021/ReportIndividualInfiltrationObject.md new file mode 100644 index 00000000000..4c3860f0402 --- /dev/null +++ b/design/FY2021/ReportIndividualInfiltrationObject.md @@ -0,0 +1,96 @@ +# Add ZoneInfiltration Output Variables for Individual objects(Issue #8209) +================ + +**Yueyue Zhou, NREL** + + - 25 June 2021 + + +## Background ## + +Excerpts lifted from [issue #8209](https://github.com/NREL/EnergyPlus/issues/8209) + + - There can be one infiltration object serving multiple zones, and there can be multiple infiltration objects serving the same zone. Currently the output variables only report at zone level, which is good for the first case. However, for the second case, there's no way to obtain, e.g., Sensible Heat Gain Energy specific to each object. + - Some related discussion in [Add Space PR](https://github.com/NREL/EnergyPlus/pull/8394#discussion_r530585696): + - Dan Macumber: Is it possible to make infiltration or ventilation at the space level? That would simplify input for cases where ventilation requirements are a function of space type. + - Jason Degraw: I think it is possible, I think we probably just want to avoid having both (e.g. SpaceInfiltration _and_ ZoneInfiltration). Moving everything to the space level will probably be more work, but if that's the right solution then we should do that. + - Scott Horowitz: Whether it's SpaceInfiltration or ZoneInfiltration, it'd be nice to be able to get individual outputs for each object. With current EnergyPlus, you can have multiple ZoneInfiltration objects in a zone, but can only get aggregate outputs (i.e., the key for Zone Infiltration Sensible Heat Gain Energy is a zone object, not an infiltration object). + - Richard Raustad: Should probably have outputs for both space and zone to show individual as well as aggregated. + - Edwin Lee: I agree with this: limit to one input approach but output at both the space and zone level. + + +## E-mail and Conference Call Conclusions ## + +*None yet.* + +## Overview ## + +This work will implement code changes that calculate infiltration output variables at individual levels. Proposed list of variables to report is: + + - Infiltration Sensible Heat Loss Energy + - Infiltration Sensible Heat Gain Energy + - Infiltration Latent Heat Loss Energy + - Infiltration Latent Heat Gain Energy + - Infiltration Total Heat Loss Energy + - Infiltration Total Heat Gain Energy + - Infiltration Current Density Volume Flow Rate + - Infiltration Standard Density Volume Flow Rate + - Infiltration Current Density Volume + - Infiltration Standard Density Volume + - Infiltration Mass + - Infiltration Mass Flow Rate + - Infiltration Air Change Rate + +Considering the mapping of multiple infiltration and multiple zone, it might require two-level reporting, eg: +1. **Infiltration1** is serving ThermalZoneList where **ThermalZone1** and **ThermalZone2** are included +2. **Infiltration2** is serving **ThermalZone1** only + +Then we will want Sensible Heat Loss to be reported in the csv file with the format like (similar to how PEOPLE is reported): + + - ThermalZone1 Infiltration1: Infiltiration Sensible Heat Loss Energy + - ThermalZone1 Infiltration2: Infiltiration Sensible Heat Loss Energy + - ThermalZone2 Infiltration1: Infiltiration Sensible Heat Loss Energy . + +The impacted infiltration objects are: +- [ZoneInfiltration:DesignFlowRate](https://bigladdersoftware.com/epx/docs/9-4/input-output-reference/group-airflow.html#zoneinfiltrationdesignflowrate) (Primary) +- [ZoneInfiltration:EffectiveLeakageArea](https://bigladdersoftware.com/epx/docs/9-4/input-output-reference/group-airflow.html#zoneinfiltrationeffectiveleakagearea) (Optional depends on implementation) +- [ZoneInfiltration:FlowCoefficient](https://bigladdersoftware.com/epx/docs/9-4/input-output-reference/group-airflow.html#zoneinfiltrationflowcoefficient) (Optional depends on implementation) + +## Approach ## + +### Existing approach description ### + +Below description takes Infiltiration Sensible Heat Loss as an example: +Current E+ reported variable is **ZnAirRpt(ZoneLoop).InfilHeatLoss**, it is calcualted at *HVACManager.cc* function *ReportAirHeatBalance* with a zone loop, the equation is: + + ZnAirRpt(ZoneLoop).InfilHeatLoss = 0.001 * state.dataHeatBalFanSys->MCPI(ZoneLoop) * (state.dataHeatBalFanSys->MAT(ZoneLoop) - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys * DataGlobalConstants::SecInHour * 1000.0 * ADSCorrectionFactor; + +where the **state.dataHeatBalFanSys->MCPI(ZoneLoop)** is the summed (infiltration mass flow * air specific heat) at zone level, it is calculated at *ZoneEquipmentManager.cc* in function *CalcAirFlowSimple* , see: + + + In infiltration object loop (example of ZoneInfiltration:DesignFlowRate): + NZ = state.dataHeatBal->Infiltration(j).ZonePtr; // zone index + MCpI_temp = state.dataHeatBal->Infiltration(j).VolumeFlowRate * AirDensity * CpAir; + state.dataHeatBalFanSys->MCPI(NZ) += MCpI_temp; + +And data initialization of state.dataHeatBal->Infiltration is in HeatBalanceAirManager.cc + +### Proposed approach ### + +The idea is to follow how`People` object is implemented to report both individual and zone level outputs. + +The requested feature will be implemented by allocating new variable `state.dataHeatBal->Infiltration(NumInfil).HeatLoss`, etc. Since `state.dataHeatBal->Infiltration` already arranges and contains infiltration objects that only point to single zone (instead of zone or zone list), the total number of `state.dataHeatBal->Infiltration` should be equal to `state.dataHeatBal->TotInfiltration`. This structure will store calculated infiltration data at object level. It will be calculated at HVACManager.cc or ZoneEquipmentManager.cc or HeatBalanceAirManager.cc depending on detailed implementation. + +New variables will be set up for Infiltration objects. + +## Testing + +No new example file needed. Assume it isn't supposed to be any diffs expected on ci testing. Local tests should verify that the new variables are able to be requested and reported correctly. + +## Input Output Reference Documentation ## + +Need to update the output descriptions for infiltration objects as reporting both at zone and individual object level. + +## IDD Changes and Transition + +None \ No newline at end of file diff --git a/doc/input-output-reference/src/overview/group-airflow.tex b/doc/input-output-reference/src/overview/group-airflow.tex index a7751c8f914..f47242e1e29 100644 --- a/doc/input-output-reference/src/overview/group-airflow.tex +++ b/doc/input-output-reference/src/overview/group-airflow.tex @@ -413,6 +413,41 @@ \subsubsection{Inputs}\label{inputs-2-005} \subsubsection{Outputs}\label{outputs-003} +Zone Infiltration objects have output variables for individual objects and for zone totals. + +Object level outputs include: + +\begin{itemize} +\item + HVAC,Sum,Infiltration Sensible Heat Loss Energy {[}J{]} +\item + HVAC,Sum,Infiltration Sensible Heat Gain Energy {[}J{]} +\item + HVAC,Sum,Infiltration Latent Heat Loss Energy {[}J{]} +\item + HVAC,Sum,Infiltration Latent Heat Gain Energy {[}J{]} +\item + HVAC,Sum,Infiltration Total Heat Loss Energy {[}J{]} +\item + HVAC,Sum,Infiltration Total Heat Gain Energy {[}J{]} +\item + HVAC,Average,Infiltration Current Density Volume Flow Rate {[}m3/s{]} +\item + HVAC,Average,Infiltration Standard Density Volume Flow Rate {[}m3/s{]} +\item + HVAC,Sum,Infiltration Current Density Volume {[}m3{]} +\item + HVAC,Sum,Infiltration Standard Density Volume {[}m3{]} +\item + HVAC,Sum,Infiltration Mass {[}kg{]} +\item + HVAC,Sum,Infiltration Mass Flow Rate {[}kg/s{]} +\item + HVAC,Average,Infiltration Air Change Rate {[}ach{]} +\end{itemize} + +Zone level outputs include: + \begin{itemize} \item HVAC,Sum,Zone Infiltration Sensible Heat Loss Energy {[}J{]} diff --git a/src/EnergyPlus/DataHeatBalance.hh b/src/EnergyPlus/DataHeatBalance.hh index 951bc415722..0e2fe6c2bc6 100644 --- a/src/EnergyPlus/DataHeatBalance.hh +++ b/src/EnergyPlus/DataHeatBalance.hh @@ -896,24 +896,41 @@ namespace DataHeatBalance { Real64 BasicStackCoefficient; // "Cs" Stack coefficient Real64 BasicWindCoefficient; // "Cw" wind coefficient // Flow Coefficient, AIM-2, Walker and Wilson terms - Real64 FlowCoefficient; // "c" Flow coefficient - Real64 AIM2StackCoefficient; // "Cs" stack coefficient - Real64 AIM2WindCoefficient; // "Cw" wind coefficient - Real64 PressureExponent; // "n" pressure power law exponent - Real64 ShelterFactor; // "s" shelter factor - bool EMSOverrideOn; // if true then EMS is requesting to override - Real64 EMSAirFlowRateValue; // value EMS is setting for air flow rate - bool QuadratureSum; // If quadrature sum of zone air balance method is used - int OABalancePtr; // A pointer to ZoneAirBalance If quadrature is true - Real64 VolumeFlowRate; // infiltration air volume flow rate - Real64 MassFlowRate; // infiltration air mass flow rate + Real64 FlowCoefficient; // "c" Flow coefficient + Real64 AIM2StackCoefficient; // "Cs" stack coefficient + Real64 AIM2WindCoefficient; // "Cw" wind coefficient + Real64 PressureExponent; // "n" pressure power law exponent + Real64 ShelterFactor; // "s" shelter factor + bool EMSOverrideOn; // if true then EMS is requesting to override + Real64 EMSAirFlowRateValue; // value EMS is setting for air flow rate + bool QuadratureSum; // If quadrature sum of zone air balance method is used + int OABalancePtr; // A pointer to ZoneAirBalance If quadrature is true + Real64 VolumeFlowRate; // infiltration air volume flow rate + Real64 MassFlowRate; // infiltration air mass flow rate + Real64 MCpI_temp; // INFILTRATION MASS FLOW * AIR SPECIFIC HEAT + Real64 InfilHeatGain; // Heat Gain {J} due to infiltration + Real64 InfilHeatLoss; // Heat Loss {J} due to infiltration + Real64 InfilLatentGain; // Latent Gain {J} due to infiltration + Real64 InfilLatentLoss; // Latent Loss {J} due to infiltration + Real64 InfilTotalGain; // Total Gain {J} due to infiltration (sensible+latent) + Real64 InfilTotalLoss; // Total Loss {J} due to infiltration (sensible+latent) + Real64 InfilVolumeCurDensity; // Volume of Air {m3} due to infiltration at current zone air density + Real64 InfilVolumeStdDensity; // Volume of Air {m3} due to infiltration at standard density (adjusted for elevation) + Real64 InfilVdotCurDensity; // Volume flow rate of Air {m3/s} due to infiltration at current zone air density + Real64 InfilVdotStdDensity; // Volume flow rate of Air {m3/s} due to infiltration standard density (adjusted elevation) + Real64 InfilMdot; // Mass flow rate {kg/s} due to infiltration for reporting + Real64 InfilMass; // Mass of Air {kg} due to infiltration + Real64 InfilAirChangeRate; // Infiltration air change rate {ach} // Default Constructor InfiltrationData() : ZonePtr(0), SchedPtr(0), ModelType(0), DesignLevel(0.0), ConstantTermCoef(0.0), TemperatureTermCoef(0.0), VelocityTermCoef(0.0), VelocitySQTermCoef(0.0), LeakageArea(0.0), BasicStackCoefficient(0.0), BasicWindCoefficient(0.0), FlowCoefficient(0.0), AIM2StackCoefficient(0.0), AIM2WindCoefficient(0.0), PressureExponent(0.0), ShelterFactor(0.0), EMSOverrideOn(false), - EMSAirFlowRateValue(0.0), QuadratureSum(false), OABalancePtr(0), VolumeFlowRate(0.0), MassFlowRate(0.0) + EMSAirFlowRateValue(0.0), QuadratureSum(false), OABalancePtr(0), VolumeFlowRate(0.0), MassFlowRate(0.0), MCpI_temp(0.0), + InfilHeatGain(0.0), InfilHeatLoss(0.0), InfilLatentGain(0.0), InfilLatentLoss(0.0), InfilTotalGain(0.0), InfilTotalLoss(0.0), + InfilVolumeCurDensity(0.0), InfilVolumeStdDensity(0.0), InfilVdotCurDensity(0.0), InfilVdotStdDensity(0.0), InfilMdot(0.0), + InfilMass(0.0), InfilAirChangeRate(0.0) { } }; diff --git a/src/EnergyPlus/HVACManager.cc b/src/EnergyPlus/HVACManager.cc index 312d2182438..f868efcf5f6 100644 --- a/src/EnergyPlus/HVACManager.cc +++ b/src/EnergyPlus/HVACManager.cc @@ -2323,6 +2323,104 @@ void UpdateZoneListAndGroupLoads(EnergyPlusData &state) } // GroupNum } +void ReportInfiltrations(EnergyPlusData &state) +{ + // SUBROUTINE INFORMATION: + // AUTHOR Yueyue Zhou + // DATE WRITTEN July 2021 + + // PURPOSE OF THIS SUBROUTINE: + // This subroutine currently creates the values for standard Infiltration object level reporting + + // METHODOLOGY EMPLOYED: + + // REFERENCES: + + using DataHVACGlobals::CycleOn; + using DataHVACGlobals::CycleOnZoneFansOnly; + using Psychrometrics::PsyCpAirFnW; + using Psychrometrics::PsyHgAirFnWTdb; + using Psychrometrics::PsyRhoAirFnPbTdbW; + int j; // Loop Counter + int NZ; // A pointer + // SUBROUTINE PARAMETER DEFINITIONS: + static std::string const RoutineName("ReportInfiltrations"); + + // SUBROUTINE LOCAL VARIABLE DECLARATIONS: + Real64 AirDensity; // Density of air (kg/m^3) + Real64 CpAir; // Heat capacity of air (J/kg-C) + Real64 TotalLoad; // Total loss or gain + Real64 H2OHtOfVap; // Heat of vaporization of air + Real64 ADSCorrectionFactor; // Correction factor of air flow model values when ADS is simulated + auto &Zone(state.dataHeatBal->Zone); + auto &Infiltration(state.dataHeatBal->Infiltration); + auto &TimeStepSys(state.dataHVACGlobal->TimeStepSys); + + for (j = 1; j <= state.dataHeatBal->TotInfiltration; ++j) { + + NZ = state.dataHeatBal->Infiltration(j).ZonePtr; + ADSCorrectionFactor = 1.0; + if (state.dataAirflowNetwork->SimulateAirflowNetwork == AirflowNetwork::AirflowNetworkControlSimpleADS) { + // CR7608 IF (TurnFansOn .AND. AirflowNetworkZoneFlag(NZ)) ADSCorrectionFactor=0 + if ((state.dataZoneEquip->ZoneEquipAvail(NZ) == CycleOn || state.dataZoneEquip->ZoneEquipAvail(NZ) == CycleOnZoneFansOnly) && + state.dataAirflowNetwork->AirflowNetworkZoneFlag(NZ)) + ADSCorrectionFactor = 0.0; + } + + CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat); + Infiltration(j).InfilMdot = Infiltration(j).MCpI_temp / CpAir * ADSCorrectionFactor; + Infiltration(j).InfilMass = Infiltration(j).InfilMdot * TimeStepSys * DataGlobalConstants::SecInHour; + + if (state.dataHeatBalFanSys->MAT(NZ) > Zone(NZ).OutDryBulbTemp) { + + Infiltration(j).InfilHeatLoss = Infiltration(j).MCpI_temp * (state.dataHeatBalFanSys->MAT(NZ) - Zone(NZ).OutDryBulbTemp) * TimeStepSys * + DataGlobalConstants::SecInHour * ADSCorrectionFactor; + Infiltration(j).InfilHeatGain = 0.0; + + } else if (state.dataHeatBalFanSys->MAT(NZ) <= Zone(NZ).OutDryBulbTemp) { + + Infiltration(j).InfilHeatGain = Infiltration(j).MCpI_temp * (Zone(NZ).OutDryBulbTemp - state.dataHeatBalFanSys->MAT(NZ)) * TimeStepSys * + DataGlobalConstants::SecInHour * ADSCorrectionFactor; + Infiltration(j).InfilHeatLoss = 0.0; + } + + // Report infiltration latent gains and losses + H2OHtOfVap = PsyHgAirFnWTdb(state.dataHeatBalFanSys->ZoneAirHumRat(NZ), state.dataHeatBalFanSys->MAT(NZ)); + if (state.dataHeatBalFanSys->ZoneAirHumRat(NZ) > state.dataEnvrn->OutHumRat) { + + Infiltration(j).InfilLatentLoss = Infiltration(j).InfilMdot * (state.dataHeatBalFanSys->ZoneAirHumRat(NZ) - state.dataEnvrn->OutHumRat) * + H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour; + Infiltration(j).InfilLatentGain = 0.0; + + } else if (state.dataHeatBalFanSys->ZoneAirHumRat(NZ) <= state.dataEnvrn->OutHumRat) { + + Infiltration(j).InfilLatentGain = Infiltration(j).InfilMdot * (state.dataEnvrn->OutHumRat - state.dataHeatBalFanSys->ZoneAirHumRat(NZ)) * + H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour; + Infiltration(j).InfilLatentLoss = 0.0; + } + // Total infiltration losses and gains + TotalLoad = Infiltration(j).InfilHeatGain + Infiltration(j).InfilLatentGain - Infiltration(j).InfilHeatLoss - Infiltration(j).InfilLatentLoss; + if (TotalLoad > 0) { + Infiltration(j).InfilTotalGain = TotalLoad; + Infiltration(j).InfilTotalLoss = 0.0; + } else { + Infiltration(j).InfilTotalGain = 0.0; + Infiltration(j).InfilTotalLoss = -TotalLoad; + } + // CR7751 second, calculate using indoor conditions for density property + AirDensity = PsyRhoAirFnPbTdbW( + state, state.dataEnvrn->OutBaroPress, state.dataHeatBalFanSys->MAT(NZ), state.dataHeatBalFanSys->ZoneAirHumRatAvg(NZ), RoutineName); + Infiltration(j).InfilVdotCurDensity = Infiltration(j).InfilMdot / AirDensity; + Infiltration(j).InfilVolumeCurDensity = Infiltration(j).InfilVdotCurDensity * TimeStepSys * DataGlobalConstants::SecInHour; + Infiltration(j).InfilAirChangeRate = Infiltration(j).InfilVolumeCurDensity / (TimeStepSys * Zone(NZ).Volume); + + // CR7751 third, calculate using standard dry air at nominal elevation + AirDensity = state.dataEnvrn->StdRhoAir; + Infiltration(j).InfilVdotStdDensity = Infiltration(j).InfilMdot / AirDensity; + Infiltration(j).InfilVolumeStdDensity = Infiltration(j).InfilVdotStdDensity * TimeStepSys * DataGlobalConstants::SecInHour; + } +} + void ReportAirHeatBalance(EnergyPlusData &state) { @@ -2429,6 +2527,8 @@ void ReportAirHeatBalance(EnergyPlusData &state) state.dataHVACMgr->ReportAirHeatBalanceFirstTimeFlag = false; } + ReportInfiltrations(state); + for (ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ... // Break the infiltration load into heat gain and loss components @@ -2443,16 +2543,16 @@ void ReportAirHeatBalance(EnergyPlusData &state) if (state.dataHeatBalFanSys->MAT(ZoneLoop) > Zone(ZoneLoop).OutDryBulbTemp) { - ZnAirRpt(ZoneLoop).InfilHeatLoss = 0.001 * state.dataHeatBalFanSys->MCPI(ZoneLoop) * + ZnAirRpt(ZoneLoop).InfilHeatLoss = state.dataHeatBalFanSys->MCPI(ZoneLoop) * (state.dataHeatBalFanSys->MAT(ZoneLoop) - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys * - DataGlobalConstants::SecInHour * 1000.0 * ADSCorrectionFactor; + DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).InfilHeatGain = 0.0; } else if (state.dataHeatBalFanSys->MAT(ZoneLoop) <= Zone(ZoneLoop).OutDryBulbTemp) { - ZnAirRpt(ZoneLoop).InfilHeatGain = 0.001 * state.dataHeatBalFanSys->MCPI(ZoneLoop) * + ZnAirRpt(ZoneLoop).InfilHeatGain = state.dataHeatBalFanSys->MCPI(ZoneLoop) * (Zone(ZoneLoop).OutDryBulbTemp - state.dataHeatBalFanSys->MAT(ZoneLoop)) * TimeStepSys * - DataGlobalConstants::SecInHour * 1000.0 * ADSCorrectionFactor; + DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).InfilHeatLoss = 0.0; } // Report infiltration latent gains and losses @@ -2460,16 +2560,16 @@ void ReportAirHeatBalance(EnergyPlusData &state) H2OHtOfVap = PsyHgAirFnWTdb(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop), state.dataHeatBalFanSys->MAT(ZoneLoop)); if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) > state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).InfilLatentLoss = 0.001 * state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir * + ZnAirRpt(ZoneLoop).InfilLatentLoss = state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir * (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataEnvrn->OutHumRat) * H2OHtOfVap * - TimeStepSys * DataGlobalConstants::SecInHour * 1000.0 * ADSCorrectionFactor; + TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).InfilLatentGain = 0.0; } else if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) <= state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).InfilLatentGain = 0.001 * state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir * + ZnAirRpt(ZoneLoop).InfilLatentGain = state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir * (state.dataEnvrn->OutHumRat - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop)) * H2OHtOfVap * - TimeStepSys * DataGlobalConstants::SecInHour * 1000.0 * ADSCorrectionFactor; + TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).InfilLatentLoss = 0.0; } // Total infiltration losses and gains @@ -2484,13 +2584,10 @@ void ReportAirHeatBalance(EnergyPlusData &state) } // first calculate mass flows using outside air heat capacity for consistency with input to heat balance - CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat); - ZnAirRpt(ZoneLoop).InfilMass = - (state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).InfilMdot = (state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir) * ADSCorrectionFactor; - ZnAirRpt(ZoneLoop).VentilMass = - (state.dataHeatBalFanSys->MCPV(ZoneLoop) / CpAir) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; + ZnAirRpt(ZoneLoop).InfilMass = ZnAirRpt(ZoneLoop).InfilMdot * TimeStepSys * DataGlobalConstants::SecInHour; ZnAirRpt(ZoneLoop).VentilMdot = (state.dataHeatBalFanSys->MCPV(ZoneLoop) / CpAir) * ADSCorrectionFactor; + ZnAirRpt(ZoneLoop).VentilMass = ZnAirRpt(ZoneLoop).VentilMdot * TimeStepSys * DataGlobalConstants::SecInHour; // CR7751 second, calculate using indoor conditions for density property AirDensity = PsyRhoAirFnPbTdbW(state, @@ -2498,23 +2595,19 @@ void ReportAirHeatBalance(EnergyPlusData &state) state.dataHeatBalFanSys->MAT(ZoneLoop), state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneLoop), RoutineName3); - ZnAirRpt(ZoneLoop).InfilVolumeCurDensity = - (state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir / AirDensity) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; + ZnAirRpt(ZoneLoop).InfilVdotCurDensity = ZnAirRpt(ZoneLoop).InfilMdot / AirDensity; + ZnAirRpt(ZoneLoop).InfilVolumeCurDensity = ZnAirRpt(ZoneLoop).InfilVdotCurDensity * TimeStepSys * DataGlobalConstants::SecInHour; ZnAirRpt(ZoneLoop).InfilAirChangeRate = ZnAirRpt(ZoneLoop).InfilVolumeCurDensity / (TimeStepSys * Zone(ZoneLoop).Volume); - ZnAirRpt(ZoneLoop).InfilVdotCurDensity = (state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir / AirDensity) * ADSCorrectionFactor; - ZnAirRpt(ZoneLoop).VentilVolumeCurDensity = - (state.dataHeatBalFanSys->MCPV(ZoneLoop) / CpAir / AirDensity) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; + ZnAirRpt(ZoneLoop).VentilVdotCurDensity = ZnAirRpt(ZoneLoop).VentilMdot / AirDensity; + ZnAirRpt(ZoneLoop).VentilVolumeCurDensity = ZnAirRpt(ZoneLoop).VentilVdotCurDensity * TimeStepSys * DataGlobalConstants::SecInHour; ZnAirRpt(ZoneLoop).VentilAirChangeRate = ZnAirRpt(ZoneLoop).VentilVolumeCurDensity / (TimeStepSys * Zone(ZoneLoop).Volume); - ZnAirRpt(ZoneLoop).VentilVdotCurDensity = (state.dataHeatBalFanSys->MCPV(ZoneLoop) / CpAir / AirDensity) * ADSCorrectionFactor; // CR7751 third, calculate using standard dry air at nominal elevation AirDensity = state.dataEnvrn->StdRhoAir; - ZnAirRpt(ZoneLoop).InfilVolumeStdDensity = - (state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir / AirDensity) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; - ZnAirRpt(ZoneLoop).InfilVdotStdDensity = (state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir / AirDensity) * ADSCorrectionFactor; - ZnAirRpt(ZoneLoop).VentilVolumeStdDensity = - (state.dataHeatBalFanSys->MCPV(ZoneLoop) / CpAir / AirDensity) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; - ZnAirRpt(ZoneLoop).VentilVdotStdDensity = (state.dataHeatBalFanSys->MCPV(ZoneLoop) / CpAir / AirDensity) * ADSCorrectionFactor; + ZnAirRpt(ZoneLoop).InfilVdotStdDensity = ZnAirRpt(ZoneLoop).InfilMdot / AirDensity; + ZnAirRpt(ZoneLoop).InfilVolumeStdDensity = ZnAirRpt(ZoneLoop).InfilVdotStdDensity * TimeStepSys * DataGlobalConstants::SecInHour; + ZnAirRpt(ZoneLoop).VentilVdotStdDensity = ZnAirRpt(ZoneLoop).VentilMdot / AirDensity; + ZnAirRpt(ZoneLoop).VentilVolumeStdDensity = ZnAirRpt(ZoneLoop).VentilVdotStdDensity * TimeStepSys * DataGlobalConstants::SecInHour; // ZnAirRpt(ZoneLoop)%VentilFanElec = 0.0 ZnAirRpt(ZoneLoop).VentilAirTemp = 0.0; @@ -2555,14 +2648,14 @@ void ReportAirHeatBalance(EnergyPlusData &state) // Report ventilation latent gains and losses H2OHtOfVap = PsyHgAirFnWTdb(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop), state.dataHeatBalFanSys->MAT(ZoneLoop)); if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) > state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).VentilLatentLoss = 0.001 * state.dataHeatBalFanSys->MCPV(ZoneLoop) / CpAir * + ZnAirRpt(ZoneLoop).VentilLatentLoss = ZnAirRpt(ZoneLoop).VentilMdot * (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataEnvrn->OutHumRat) * - H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * 1000.0 * ADSCorrectionFactor; + H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour; ZnAirRpt(ZoneLoop).VentilLatentGain = 0.0; } else if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) <= state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).VentilLatentGain = 0.001 * state.dataHeatBalFanSys->MCPV(ZoneLoop) / CpAir * + ZnAirRpt(ZoneLoop).VentilLatentGain = ZnAirRpt(ZoneLoop).VentilMdot * (state.dataEnvrn->OutHumRat - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop)) * - H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * 1000.0 * ADSCorrectionFactor; + H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour; ZnAirRpt(ZoneLoop).VentilLatentLoss = 0.0; } // Total ventilation losses and gains @@ -2818,14 +2911,14 @@ void ReportAirHeatBalance(EnergyPlusData &state) } H2OHtOfVap = PsyHgAirFnWTdb(state.dataEnvrn->OutHumRat, Zone(ZoneLoop).OutDryBulbTemp); if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) > state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).OABalanceLatentLoss = 0.001 * state.dataHeatBalFanSys->MDotOA(ZoneLoop) * + ZnAirRpt(ZoneLoop).OABalanceLatentLoss = state.dataHeatBalFanSys->MDotOA(ZoneLoop) * (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataEnvrn->OutHumRat) * - H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * 1000.0 * ADSCorrectionFactor; + H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).OABalanceLatentGain = 0.0; } else if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) <= state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).OABalanceLatentGain = 0.001 * state.dataHeatBalFanSys->MDotOA(ZoneLoop) * + ZnAirRpt(ZoneLoop).OABalanceLatentGain = state.dataHeatBalFanSys->MDotOA(ZoneLoop) * (state.dataEnvrn->OutHumRat - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop)) * - H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * 1000.0 * ADSCorrectionFactor; + H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).OABalanceLatentLoss = 0.0; } // Total ventilation losses and gains diff --git a/src/EnergyPlus/HeatBalanceAirManager.cc b/src/EnergyPlus/HeatBalanceAirManager.cc index 9b59499715b..fef842f11b8 100644 --- a/src/EnergyPlus/HeatBalanceAirManager.cc +++ b/src/EnergyPlus/HeatBalanceAirManager.cc @@ -1189,6 +1189,99 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err // setup zone-level infiltration reports for (Loop = 1; Loop <= state.dataHeatBal->TotInfiltration; ++Loop) { if (state.dataHeatBal->Infiltration(Loop).ZonePtr > 0 && !state.dataHeatBal->Infiltration(Loop).QuadratureSum) { + // Object report variables + SetupOutputVariable(state, + "Infiltration Sensible Heat Loss Energy", + OutputProcessor::Unit::J, + state.dataHeatBal->Infiltration(Loop).InfilHeatLoss, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Sensible Heat Gain Energy", + OutputProcessor::Unit::J, + state.dataHeatBal->Infiltration(Loop).InfilHeatGain, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Latent Heat Loss Energy", + OutputProcessor::Unit::J, + state.dataHeatBal->Infiltration(Loop).InfilLatentLoss, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Latent Heat Gain Energy", + OutputProcessor::Unit::J, + state.dataHeatBal->Infiltration(Loop).InfilLatentGain, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Total Heat Loss Energy", + OutputProcessor::Unit::J, + state.dataHeatBal->Infiltration(Loop).InfilTotalLoss, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Total Heat Gain Energy", + OutputProcessor::Unit::J, + state.dataHeatBal->Infiltration(Loop).InfilTotalGain, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Current Density Volume Flow Rate", + OutputProcessor::Unit::m3_s, + state.dataHeatBal->Infiltration(Loop).InfilVdotCurDensity, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Standard Density Volume Flow Rate", + OutputProcessor::Unit::m3_s, + state.dataHeatBal->Infiltration(Loop).InfilVdotStdDensity, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Current Density Volume", + OutputProcessor::Unit::m3, + state.dataHeatBal->Infiltration(Loop).InfilVolumeCurDensity, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Standard Density Volume", + OutputProcessor::Unit::m3, + state.dataHeatBal->Infiltration(Loop).InfilVolumeStdDensity, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Mass", + OutputProcessor::Unit::kg, + state.dataHeatBal->Infiltration(Loop).InfilMass, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Mass Flow Rate", + OutputProcessor::Unit::kg_s, + state.dataHeatBal->Infiltration(Loop).InfilMdot, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + state.dataHeatBal->Infiltration(Loop).Name); + SetupOutputVariable(state, + "Infiltration Air Change Rate", + OutputProcessor::Unit::ach, + state.dataHeatBal->Infiltration(Loop).InfilAirChangeRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + state.dataHeatBal->Infiltration(Loop).Name); + if (RepVarSet(state.dataHeatBal->Infiltration(Loop).ZonePtr)) { RepVarSet(state.dataHeatBal->Infiltration(Loop).ZonePtr) = false; SetupOutputVariable(state, diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index 46d060a489e..9397b51c4b0 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -6096,6 +6096,7 @@ void CalcAirFlowSimple(EnergyPlusData &state, if (state.dataHeatBal->Infiltration(j).QuadratureSum) { state.dataHeatBal->ZoneAirBalance(state.dataHeatBal->Infiltration(j).OABalancePtr).InfMassFlowRate += MCpI_temp / CpAir; } else { + state.dataHeatBal->Infiltration(j).MCpI_temp = MCpI_temp; state.dataHeatBalFanSys->MCPI(NZ) += MCpI_temp; state.dataHeatBalFanSys->OAMFL(NZ) += MCpI_temp / CpAir; state.dataHeatBalFanSys->MCPTI(NZ) += MCpI_temp * TempExt; diff --git a/src/EnergyPlus/ZoneEquipmentManager.hh b/src/EnergyPlus/ZoneEquipmentManager.hh index 62816421493..2656ba46063 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.hh +++ b/src/EnergyPlus/ZoneEquipmentManager.hh @@ -159,6 +159,8 @@ namespace ZoneEquipmentManager { void AutoCalcDOASControlStrategy(EnergyPlusData &state); + void ReportInfiltrations(EnergyPlusData &state); + void ReportZoneSizingDOASInputs(EnergyPlusData &state, std::string const &ZoneName, // the name of the zone std::string const &DOASCtrlStrategy, // DOAS control strategy diff --git a/tst/EnergyPlus/unit/HVACManager.unit.cc b/tst/EnergyPlus/unit/HVACManager.unit.cc index b35a6e3ad19..af870adff6b 100644 --- a/tst/EnergyPlus/unit/HVACManager.unit.cc +++ b/tst/EnergyPlus/unit/HVACManager.unit.cc @@ -65,12 +65,19 @@ #include #include #include +#include +#include #include +#include +#include #include "Fixtures/EnergyPlusFixture.hh" using namespace EnergyPlus; using namespace HVACManager; +using namespace EnergyPlus::HeatBalanceManager; +using namespace EnergyPlus::HeatBalanceAirManager; +using namespace EnergyPlus::ZoneEquipmentManager; TEST_F(EnergyPlusFixture, CrossMixingReportTest) { @@ -141,6 +148,228 @@ TEST_F(EnergyPlusFixture, CrossMixingReportTest) state->dataHeatBalFanSys->ZoneAirHumRatAvg.deallocate(); } +TEST_F(EnergyPlusFixture, InfiltrationObjectLevelReport) +{ + + std::string const idf_objects = delimited_string({ + "Zone,Zone1;", + + "Zone,Zone2;", + + "Zone,Zone3;", + + "Zone,Zone4;", + + "ZoneList,", + " ZoneList,", + " Zone1,", + " Zone2;", + + "ZoneInfiltration:EffectiveLeakageArea,", + " Zone3 Infil, !- Name", + " Zone3, !- Zone or ZoneList Name", + " AlwaysOn, !- Schedule Name", + " 500.0, !- Effective Air Leakage Area", + " 0.000145, !- Stack Coefficient", + " 0.000174; !- Wind Coefficient", + + "ZoneInfiltration:FlowCoefficient,", + " Zone4 Infil, !- Name", + " Zone4, !- Zone or ZoneList Name", + " AlwaysOn, !- Schedule Name", + " 0.05, !- Flow Coefficient", + " 0.089, !- Stack Coefficient", + " 0.67, !- Pressure Exponent", + " 0.156, !- Wind Coefficient", + " 0.64; !- Shelter Factor", + + "ZoneInfiltration:DesignFlowRate,", + " Zonelist Infil, !- Name", + " ZoneList, !- Zone or ZoneList Name", + " AlwaysOn, !- Schedule Name", + " flow/zone, !- Design Flow Rate Calculation Method", + " 0.07, !- Design Flow Rate{ m3 / s }", + " , !- Flow per Zone Floor Area{ m3 / s - m2 }", + " , !- Flow per Exterior Surface Area{ m3 / s - m2 }", + " , !- Air Changes per Hour{ 1 / hr }", + " 1, !- Constant Term Coefficient", + " 0, !- Temperature Term Coefficient", + " 0, !- Velocity Term Coefficient", + " 0; !- Velocity Squared Term Coefficient", + + "Schedule:Constant,", + "AlwaysOn,", + "Fraction,", + "1.0;", + }); + + ASSERT_TRUE(process_idf(idf_objects)); + EXPECT_FALSE(has_err_output()); + + bool ErrorsFound(false); + ScheduleManager::ProcessScheduleInput(*state); + GetZoneData(*state, ErrorsFound); + AllocateHeatBalArrays(*state); + GetSimpleAirModelInputs(*state, ErrorsFound); + + EXPECT_EQ(state->dataHeatBal->TotInfiltration, 4); // one per zone + + state->dataHeatBalFanSys->MAT.allocate(state->dataGlobal->NumOfZones); + state->dataHeatBalFanSys->ZoneAirHumRat.allocate(state->dataGlobal->NumOfZones); + state->dataHeatBalFanSys->MCPM.allocate(state->dataGlobal->NumOfZones); + state->dataHeatBalFanSys->MCPTM.allocate(state->dataGlobal->NumOfZones); + + state->dataHeatBalFanSys->MCPI.allocate(state->dataGlobal->NumOfZones); + state->dataHeatBalFanSys->OAMFL.allocate(state->dataGlobal->NumOfZones); + state->dataHeatBalFanSys->MCPTI.allocate(state->dataGlobal->NumOfZones); + state->dataZoneEquip->ZoneEquipConfig.allocate(state->dataGlobal->NumOfZones); + + state->dataHeatBalFanSys->MAT(1) = 21.0; + state->dataHeatBalFanSys->MAT(2) = 22.0; + state->dataHeatBalFanSys->MAT(3) = 23.0; + state->dataHeatBalFanSys->MAT(4) = 24.0; + state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; + state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.001; + state->dataHeatBalFanSys->ZoneAirHumRat(3) = 0.001; + state->dataHeatBalFanSys->ZoneAirHumRat(4) = 0.001; + + state->dataHeatBal->AirFlowFlag = true; + state->dataEnvrn->OutBaroPress = 101325.0; + state->dataEnvrn->OutHumRat = 0.0005; + state->dataEnvrn->StdRhoAir = 1.20; + state->dataEnvrn->WindSpeed = 1.0; + state->dataHeatBal->Zone(1).WindSpeed = 1.0; + state->dataHeatBal->Zone(2).WindSpeed = 1.0; + state->dataHeatBal->Zone(3).WindSpeed = 1.0; + state->dataHeatBal->Zone(4).WindSpeed = 1.0; + state->dataHeatBal->Zone(1).OutDryBulbTemp = 15.0; + state->dataHeatBal->Zone(2).OutDryBulbTemp = 15.0; + state->dataHeatBal->Zone(3).OutDryBulbTemp = 15.0; + state->dataHeatBal->Zone(4).OutDryBulbTemp = 15.0; + state->dataScheduleMgr->Schedule(1).CurrentValue = 1.0; + state->dataHVACGlobal->TimeStepSys = 1.0; + state->dataGlobal->TimeStepZone = 1.0; + state->dataGlobal->TimeStepZoneSec = 3600; + + CalcAirFlowSimple(*state, 2); + + EXPECT_NEAR(state->dataHeatBal->Infiltration(1).MCpI_temp, 0.07 * 1.2242 * 1005.77, 0.01); // zone level reporting matches object level + EXPECT_NEAR(state->dataHeatBal->Infiltration(2).MCpI_temp, 0.07 * 1.2242 * 1005.77, 0.01); // zone level reporting matches object level + EXPECT_NEAR(state->dataHeatBal->Infiltration(3).MCpI_temp, 22.486, 0.01); // zone level reporting matches object level + EXPECT_NEAR(state->dataHeatBal->Infiltration(4).MCpI_temp, 24.459, 0.01); // zone level reporting matches object level + + EXPECT_EQ(state->dataHeatBalFanSys->MCPI(1), state->dataHeatBal->Infiltration(1).MCpI_temp); // zone level reporting matches object level + EXPECT_EQ(state->dataHeatBalFanSys->MCPI(2), state->dataHeatBal->Infiltration(2).MCpI_temp); // zone level reporting matches object level + EXPECT_EQ(state->dataHeatBalFanSys->MCPI(3), state->dataHeatBal->Infiltration(3).MCpI_temp); // zone level reporting matches object level + EXPECT_EQ(state->dataHeatBalFanSys->MCPI(4), state->dataHeatBal->Infiltration(4).MCpI_temp); // zone level reporting matches object level + + ReportAirHeatBalance(*state); + + auto &ZnAirRpt(state->dataHeatBal->ZnAirRpt); + EXPECT_NEAR(ZnAirRpt(1).InfilHeatLoss, state->dataHeatBal->Infiltration(1).InfilHeatLoss, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(2).InfilHeatLoss, state->dataHeatBal->Infiltration(2).InfilHeatLoss, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(3).InfilHeatLoss, state->dataHeatBal->Infiltration(3).InfilHeatLoss, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(4).InfilHeatLoss, state->dataHeatBal->Infiltration(4).InfilHeatLoss, 0.000001); // zone level reporting matches object level + + EXPECT_NEAR(ZnAirRpt(1).InfilHeatGain, state->dataHeatBal->Infiltration(1).InfilHeatGain, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(2).InfilHeatGain, state->dataHeatBal->Infiltration(2).InfilHeatGain, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(3).InfilHeatGain, state->dataHeatBal->Infiltration(3).InfilHeatGain, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(4).InfilHeatGain, state->dataHeatBal->Infiltration(4).InfilHeatGain, 0.000001); // zone level reporting matches object level + + EXPECT_NEAR( + ZnAirRpt(1).InfilTotalLoss, state->dataHeatBal->Infiltration(1).InfilTotalLoss, 0.000001); // zone level reporting matches object level + EXPECT_NEAR( + ZnAirRpt(2).InfilTotalLoss, state->dataHeatBal->Infiltration(2).InfilTotalLoss, 0.000001); // zone level reporting matches object level + EXPECT_NEAR( + ZnAirRpt(3).InfilTotalLoss, state->dataHeatBal->Infiltration(3).InfilTotalLoss, 0.000001); // zone level reporting matches object level + EXPECT_NEAR( + ZnAirRpt(4).InfilTotalLoss, state->dataHeatBal->Infiltration(4).InfilTotalLoss, 0.000001); // zone level reporting matches object level + + EXPECT_NEAR( + ZnAirRpt(1).InfilTotalGain, state->dataHeatBal->Infiltration(1).InfilTotalGain, 0.000001); // zone level reporting matches object level + EXPECT_NEAR( + ZnAirRpt(2).InfilTotalGain, state->dataHeatBal->Infiltration(2).InfilTotalGain, 0.000001); // zone level reporting matches object level + EXPECT_NEAR( + ZnAirRpt(3).InfilTotalGain, state->dataHeatBal->Infiltration(3).InfilTotalGain, 0.000001); // zone level reporting matches object level + EXPECT_NEAR( + ZnAirRpt(4).InfilTotalGain, state->dataHeatBal->Infiltration(4).InfilTotalGain, 0.000001); // zone level reporting matches object level + + EXPECT_NEAR(ZnAirRpt(1).InfilMass, state->dataHeatBal->Infiltration(1).InfilMass, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(2).InfilMass, state->dataHeatBal->Infiltration(2).InfilMass, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(3).InfilMass, state->dataHeatBal->Infiltration(3).InfilMass, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(4).InfilMass, state->dataHeatBal->Infiltration(4).InfilMass, 0.000001); // zone level reporting matches object level + + EXPECT_NEAR(ZnAirRpt(1).InfilMdot, state->dataHeatBal->Infiltration(1).InfilMdot, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(2).InfilMdot, state->dataHeatBal->Infiltration(2).InfilMdot, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(3).InfilMdot, state->dataHeatBal->Infiltration(3).InfilMdot, 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(4).InfilMdot, state->dataHeatBal->Infiltration(4).InfilMdot, 0.000001); // zone level reporting matches object level + + EXPECT_NEAR(ZnAirRpt(1).InfilVolumeCurDensity, + state->dataHeatBal->Infiltration(1).InfilVolumeCurDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(2).InfilVolumeCurDensity, + state->dataHeatBal->Infiltration(2).InfilVolumeCurDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(3).InfilVolumeCurDensity, + state->dataHeatBal->Infiltration(3).InfilVolumeCurDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(4).InfilVolumeCurDensity, + state->dataHeatBal->Infiltration(4).InfilVolumeCurDensity, + 0.000001); // zone level reporting matches object level + + EXPECT_NEAR(ZnAirRpt(1).InfilAirChangeRate, + state->dataHeatBal->Infiltration(1).InfilAirChangeRate, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(2).InfilAirChangeRate, + state->dataHeatBal->Infiltration(2).InfilAirChangeRate, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(3).InfilAirChangeRate, + state->dataHeatBal->Infiltration(3).InfilAirChangeRate, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(4).InfilAirChangeRate, + state->dataHeatBal->Infiltration(4).InfilAirChangeRate, + 0.000001); // zone level reporting matches object level + + EXPECT_NEAR(ZnAirRpt(1).InfilVdotCurDensity, + state->dataHeatBal->Infiltration(1).InfilVdotCurDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(2).InfilVdotCurDensity, + state->dataHeatBal->Infiltration(2).InfilVdotCurDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(3).InfilVdotCurDensity, + state->dataHeatBal->Infiltration(3).InfilVdotCurDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(4).InfilVdotCurDensity, + state->dataHeatBal->Infiltration(4).InfilVdotCurDensity, + 0.000001); // zone level reporting matches object level + + EXPECT_NEAR(ZnAirRpt(1).InfilVolumeStdDensity, + state->dataHeatBal->Infiltration(1).InfilVolumeStdDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(2).InfilVolumeStdDensity, + state->dataHeatBal->Infiltration(2).InfilVolumeStdDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(3).InfilVolumeStdDensity, + state->dataHeatBal->Infiltration(3).InfilVolumeStdDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(4).InfilVolumeStdDensity, + state->dataHeatBal->Infiltration(4).InfilVolumeStdDensity, + 0.000001); // zone level reporting matches object level + + EXPECT_NEAR(ZnAirRpt(1).InfilVdotStdDensity, + state->dataHeatBal->Infiltration(1).InfilVdotStdDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(2).InfilVdotStdDensity, + state->dataHeatBal->Infiltration(2).InfilVdotStdDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(3).InfilVdotStdDensity, + state->dataHeatBal->Infiltration(3).InfilVdotStdDensity, + 0.000001); // zone level reporting matches object level + EXPECT_NEAR(ZnAirRpt(4).InfilVdotStdDensity, + state->dataHeatBal->Infiltration(4).InfilVdotStdDensity, + 0.000001); // zone level reporting matches object level +} + TEST_F(EnergyPlusFixture, InfiltrationReportTest) { diff --git a/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc b/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc index cc1cd084c5e..1d79f1055c7 100644 --- a/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc +++ b/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,7 @@ using namespace EnergyPlus::DataLoopNode; using namespace EnergyPlus::DataZoneEquipment; using namespace EnergyPlus::HeatBalanceAirManager; using namespace EnergyPlus::HeatBalanceManager; +using namespace EnergyPlus::HVACManager; TEST_F(EnergyPlusFixture, ZoneEquipmentManager_CalcZoneMassBalanceTest) {