diff --git a/design/FY2024/chiller_heater_part_load_fix.md b/design/FY2024/chiller_heater_part_load_fix.md new file mode 100644 index 00000000000..bb966f0f756 --- /dev/null +++ b/design/FY2024/chiller_heater_part_load_fix.md @@ -0,0 +1,106 @@ +DEFECT: Fix for Chiller Heater Always Assuming Evaporator is at Full Load +================ + +**Rick Strand, University of Illinois at Urbana-Champaign** + + - Original Date: July 22, 2024 + - Revision Date: July 30, 2024 + + +## Justification for New Feature ## + +The current heater mode portion of the chiller heater model in PlantCentralGSHP.cc is written with the built-in assumption that the evaporator is running at full load. When the condenser load comes back at less than full load, the evaporator load is never adjusted and reports load and electric power at full load. This is not correct and resulted in a defect being logged (Defect 10065). This document is a plan for a potential solution to this problem. + +## E-mail and Conference Call Conclusions ## + +July 24, 2024: Discussed this on the technicalities call. Decision was made to not implement an iteration strategy but to simply make an approximation of the PLR from the condenser load and then multiple full load evaporator load, compressor power, and false loading by that PLR. Not ideal, but given all of the suspected problems in this model, it was decided to not invest too heavily in this now and turn this into a potential development topic in the future. + +## Overview ## + +The heat pump model for the ChillerHeater model is contained in the PlantCentralGSHP.cc file. The model allows for various modes of operation: off (0), cooling only (1), heating only (2), heat recovery (3), cooling dominant (4), and heating dominant (5). Off mode is obvious--no loads, nothing happening. When in cooling or heating only mode, the heat rejection is lost/sent to the other thermal environment. When in heat recovery mode, heat rejection at the condenser is used for heating purposes in the HVAC system. Cooling and heating dominant modes have heat recovery but there is more heat recovery than is needed so the excess is rejected to whatever the outside environment is. The cooling controlled modes (1, 3, and 4) are simulated using the CalcChillerModel in CentralPlantGSHP.cc. The heating controlled modes (2 and 5) are simulated using the CalcChillerHeaterModel in CentralPlantGSHP.cc. The cooling controlled modes seem to be working without any known issues. The heating modes run the condenser to the correct load for heating. However, a user noticed that there was an issue with the reported evaporator load and power consumption which always seemed to be relatively constant at a high level whenever the condenser was needed for a heating load. This was traced back to the assumptions in the heater portion of the chiller heater model. + +The simlation flow in the heater portion of the model is summarized as follows. Once it is identified that the chiller is in one of the heating modes, the chiller is assumed to run at full capacity to get an evaporator load, a compressor power consumption, and any false load for when the chiller is below the minimum part load ratio. A condenser load at full power is calculated from this information. This condenser load is then adjusted to fit the actual heating need. From this condenser load, flows or temperatures are adjusted for this load as needed on the condenser side. The simulation then moves on from there. + +The problem here is that the evaporator load and the compressor power are still at full load and are never adjusted when the condenser load gets reduced because the heating load does not require full load. This is the source of the error--evaporator load and compressor power never change in heating mode regardless of the actual part load ratio based on the condenser load. PLR simply stays at near 100%. This is not correct and leads to over-estimation of both the evaporator load and the compressor power consumption. + +## Original Approach ## + +Note: before the actual fix takes place, it was decided to make a code improvement pass through the current chiller heater model. This has already taken place and has been merged into develop. The point was to make the code re-usable within the chiller heater model but it also realized some improvements in the cooling mode subroutine as well. The changes took several different code sections and turned them into smaller subroutines. The heating mode code is now much easier to follow, reducing the size of the routine by a factor of more than 3 (based on printouts of the routine before and after restructuring). The real benefit will be seen when the problem is fixed as the algorithm should stay fairly compact and easy to follow (hopefully). + +The approach to this problem is to for the most part leave the initial pass at full load in tact. The code still needs to know what the condenser is capable of from a heating standpoint. If the required heating load (HeatingLoadToMeet) is larger than the condenser load at full power, then there is no change to be made. However, when the condenser load is reduced because the HeatingLoadToMeet is less than the condenser load at full power, there needs to be additional code to handle this case. + +When the QCondenser is initially calculated based on full load evaporator conditions, a new variable (qCondOrig or something like that) tracking the original value will be set equal to this value. After QCondenser is compared to HeatingLoadToMeet and then potentially modified by the new restructured subroutine adjustChillerHeaterFlowTemp, QCondenser will be compared to qCondOrig. If QCondenser is lower than qCondOrig, then this means that we are no longer at full load and need to go into an adjustment procedure. + +Adjustment Procedure: The adjustment process to obtain a revised/appropriate evaporator load and compressor power will take place in the code after the initial pass to adjust the chiller heater flow rate and temperature. The code in CalcChillerHeaterModel, after restructuring, looks like this: + + if (CurrentMode == 2 || this->SimulHtgDominant) { + if (CondMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance && CondDeltaTemp > 0.0) { + this->adjustChillerHeaterFlowTemp(state, QCondenser, CondMassFlowRate, CondOutletTemp, CondInletTemp, CondDeltaTemp); + } else { + QCondenser = 0.0; + CondOutletTemp = CondInletTemp; + } + } + +New code will be added right after the call to adjustChillerHeaterFlowTemp. There will need to be an iteration loop as there is no guarantee that one pass will obtain the correct evaporator conditions. The iteration loop will end after 20 attempts or when the latest condenser load is sufficiently similar to the condenser load from the previous iteration. + +Before the iteration loop, set iteration number to zero and old condenser load to full load (qCondOrig) and new condenser load to existing condenser load. + +During the iteration loop (while iteration is less than 20 and difference between old and new QCondenser is outside of tolerance), the following functions will be done: + +Step 0: Update last iteration condenser load and iteration number + +Step 1: Calculate PLR based on comparison of last iteration condenser load to full condenser load, limit to MaxPartLoadRatio. + +Step 2: Calculate QEvaporator and EvapOutletTemp based on new PartLoadRatio. Could potentially be turned into a new subroutine. + +Step 3: Call checkEvapOutletTemp. This in all likelihood won't do anything because it just makes sure that the minimum evaporator temperature limits are not violated, but it still needs to be run just in case. + +Step 4: Call calcPLRAndCyclingRatio. This shouldn't change PLR because it was just used to calculate a new QEvaporator. It could, however, result in some false loading if PLR drops below the minimum. + +Step 5: Recalculate CHPower, the compressor power using the same equation used from previously in this routine. Could potentially be turned into a new function (one line). + +Step 6: Recalculate ActualCOP. Could Could potentially be turned into a new function. + +Step 7: Calculate the new QCondenser for this iteration. Reuse existing code that limits this based on minPLR, HeatingLoadToMeet. + +Step 8: Call adjustChillerHeaterFlowTemp to adjust flow rate and temperature if necessary. + +At this point, a new QCondenser has been calculated so the iteration cycle is done. No additional code is needed after the iteration cycle as it should just be able to pick up where it left off as it currently does. + +## Modified Approach ## + +During the technicalities call, it was suggested that rather than iterating, we should just approximate the PLR from the condenser load and then multiply evaporator load and compressor power by this PLR. The false load was also factored in this way though in this case it was probably zero at full load anyway. Other problems in the algorithm were also fixed along the way. No guarantees that this model is now 100% bug free but it should be improved. + +## Testing/Validation/Data Sources ## + +Testing will be done using the existing user input file that shows the problem. Comparisons will be made between develop and the new version to establish that the results have changed after the fix has been implemented and that the new output makes sense. + +Unit testing: as this is being handled as part of a bug fix, at least two unit tests will be generated. As there are several new subroutines, the unit tests will likely center on these new subroutines. + +## Input Output Reference Documentation ## + +No changes needed--this is an algorithm fix that does not require input changes. + +## Input Description ## + +No changes needed--this is an algorithm fix that does not require input changes. + +## Outputs Description ## + +No changes needed--this is an algorithm fix that does not require input changes or new output. + +## Engineering Reference ## + +Currently, the Engineering Reference has a section for the chiller heater model (ChillerHeaterPerformance\:Electric:EIR). The subsection entitled "Heating-only mode and Simultaneous cooling-heating mode" essentially outlines the calculation process in heating only (2) and heating dominant (5) modes. Additional text will be added to the end of this section to describe the work implemented as part of this fix that will outline the steps in a similar fashion to what is shown above in the Approach section of this document. + +## Example File and Transition Changes ## + +No transition changes are needed since there is no change to the input. A change to an existing input file that has a chiller heater equipment may be needed to show differences in output, but it likely will without any changes to the .idf. So, there are no changes anticipated to existing example files either. + +## References ## + +Current code in PlantCentralGSHP.cc + + + diff --git a/doc/engineering-reference/src/special-modules-reporting/resilience-metrics.tex b/doc/engineering-reference/src/special-modules-reporting/resilience-metrics.tex index 8f2b0d478dc..3055edd3414 100644 --- a/doc/engineering-reference/src/special-modules-reporting/resilience-metrics.tex +++ b/doc/engineering-reference/src/special-modules-reporting/resilience-metrics.tex @@ -66,69 +66,17 @@ \subsubsection{Heat Index}\label{heat-index} \end{tabular} \end{table} -The computation of the heat index is a refinement of a result obtained by +Before version 24.2, the computation of the heat index is a refinement of a result obtained by multiple regression analysis carried out by Lans P. Rothfusz and described in a -1990 National Weather Service (NWS) Technical Attachment (SR 90-23) [4-5]. The -calculation is based on degree Fahrenheit. +1990 National Weather Service (NWS) Technical Attachment (SR 90-23) [4-5]. -The regression equation of Rothfusz is -\begin{equation} \label{eq:rm-1} -HI = c_1 + c_2T + c_3R + c_4TR + c_5T^2 + c_6R^2 + c_7T^2R + c_8TR^2 + c_9T^2R^2 -\end{equation} - -where - -HI = heat index (expressed as an apparent temperature in degrees Fahrenheit), - -T = ambient dry-bulb temperature (in degrees Fahrenheit), - -R = relative humidity (percentage value between 0 and 100), - -$c_1$ = -42.379, - -$c_2$ = 2.04901523, - -$c_3$ = 10.14333127, - -$c_4$ = -0.22475541, - -$c_5$ = -0.00683783, - -$c_6$ = -0.05481717, - -$c_7$ = 0.00122874, - -$c_8$ = 0.00085282, - -$c_9$ = -0.00000199. - -If the RH is less than 13\% and the temperature is between 80 and \IP{112}{\fahrenheit}, then -the following adjustment is subtracted from HI: - -\begin{equation} \label{eq:rm-2} -HI = (13 - R) / 4 * ((17 - |T - 95|) / 17)^{0.5} -\end{equation} - -Otherwise, if the RH is greater than 85\% and the temperature is between 80 and -\IP{87}{\fahrenheit}, then the following adjustment is added to HI: - -\begin{equation} \label{eq:rm-3} -HI = (R - 85) / 10 * (87 - T) / 5 -\end{equation} - -The Rothfusz regression is not appropriate when conditions of temperature and -humidity warrant a heat index value below about \IP{80}{\fahrenheit}. In those cases, a simpler -formula is applied to calculate values consistent with Steadman's results: - -\begin{equation} \label{eq:rm-4} -HI = 0.5 * (T + 61.0 + (T - 68.0) * 1.2 + (R * 0.094)) -\end{equation} - -In practice, the simple formula is computed first based on the temperature and -humidity. If this heat index value is \IP{80}{\fahrenheit} or higher, the full regression -equation along with any adjustment as described above is applied. The Rothfusz -regression is not valid for extreme temperature and relative humidity conditions -beyond the range of data considered by Steadman. +Starting from version 24.2, the heat index calculation adopts the extended heat +index method developed by Lu \& Romps [17]. The previous heat index gives +unrealistic results for very hot and humid or very cold and dry conditions. The +extended index extends the domain of the heat index calculation to all +combinations of temperature and relative humidity and gives a more realistic heat +index for the extreme conditions. The implementation in EnergyPlus is based on +the released Python code by Lu and Romps [18]. The Heat Index Hours (accumulated hours for a space) and Heat Index OccupantHours (accumulated hours for the sum of all occupants in a space) of @@ -516,3 +464,11 @@ \subsection{References} {[}16{]} ACGIH, Threshold Limit Values (TLVs) and Biological Exposure Indices (BEIs), 2012. doi:10.1073/pnas.0703993104. + +{[}17{]} Lu, Yi-Chuan, and David M. Romps. ``Extending the heat index''. Journal +of Applied Meteorology and Climatology 61, no. 10 (2022): 1367-1383. +doi:10.1073/pnas.0703993104. + +{[}18{]} Lu, Yi-Chuan, and David M. Romps. ``Lu and Romps, Extending the heat index, JAMC, 2022'', +Physics of Climate, February 23, 2023. +https://romps.berkeley.edu/papers/pubs-2020-heatindex.html. diff --git a/src/EnergyPlus/AirflowNetwork/src/Solver.cpp b/src/EnergyPlus/AirflowNetwork/src/Solver.cpp index bafc6e46b22..47073976e3a 100644 --- a/src/EnergyPlus/AirflowNetwork/src/Solver.cpp +++ b/src/EnergyPlus/AirflowNetwork/src/Solver.cpp @@ -11228,13 +11228,15 @@ namespace AirflowNetwork { found = true; } } - if (!found) { - ShowSevereError(m_state, format("{}Fan:ZoneExhaust is not defined in {}", RoutineName, CurrentModuleObject)); - ShowContinueError(m_state, - "Zone Air Exhaust Node in ZoneHVAC:EquipmentConnections =" + - m_state.dataLoopNodes->NodeID(m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k))); - ErrorsFound = true; - } + } + if (!found) { + ShowSevereError(m_state, format("{}Fan:ZoneExhaust is not defined in {}", RoutineName, CurrentModuleObject)); + ShowContinueError( + m_state, + format("The inlet node of the {} Fan:ZoneExhaust is not defined in the {}'s ZoneHVAC:EquipmentConnections", + m_state.dataZoneEquip->ZoneEquipList(j).EquipName, + m_state.dataZoneEquip->ZoneEquipConfig(j).ZoneName)); + ErrorsFound = true; } } } diff --git a/src/EnergyPlus/CMakeLists.txt b/src/EnergyPlus/CMakeLists.txt index cfb928e00dc..56f664ba014 100644 --- a/src/EnergyPlus/CMakeLists.txt +++ b/src/EnergyPlus/CMakeLists.txt @@ -262,6 +262,8 @@ set(SRC EvaporativeFluidCoolers.hh ExhaustAirSystemManager.cc ExhaustAirSystemManager.hh + ExtendedHI.cc + ExtendedHI.hh ExteriorEnergyUse.cc ExteriorEnergyUse.hh ExternalInterface.cc diff --git a/src/EnergyPlus/Coils/CoilCoolingDXCurveFitOperatingMode.cc b/src/EnergyPlus/Coils/CoilCoolingDXCurveFitOperatingMode.cc index 0d4976bbcde..0067efabb32 100644 --- a/src/EnergyPlus/Coils/CoilCoolingDXCurveFitOperatingMode.cc +++ b/src/EnergyPlus/Coils/CoilCoolingDXCurveFitOperatingMode.cc @@ -291,7 +291,7 @@ void CoilCoolingDXCurveFitOperatingMode::CalcOperatingMode(EnergyPlus::EnergyPlu // Currently speedNum is 1-based, while this->speeds are zero-based auto &thisspeed(this->speeds[max(speedNum - 1, 0)]); - if (((speedNum == 1) && (PLR == 0.0)) || (inletNode.MassFlowRate == 0.0)) { + if ((speedNum == 0) || ((speedNum == 1) && (PLR == 0.0)) || (inletNode.MassFlowRate == 0.0)) { outletNode.Temp = inletNode.Temp; outletNode.HumRat = inletNode.HumRat; outletNode.Enthalpy = inletNode.Enthalpy; diff --git a/src/EnergyPlus/Coils/CoilCoolingDXCurveFitSpeed.cc b/src/EnergyPlus/Coils/CoilCoolingDXCurveFitSpeed.cc index ec56fbabc15..7e2af833675 100644 --- a/src/EnergyPlus/Coils/CoilCoolingDXCurveFitSpeed.cc +++ b/src/EnergyPlus/Coils/CoilCoolingDXCurveFitSpeed.cc @@ -838,7 +838,7 @@ Real64 CoilCoolingDXCurveFitSpeed::calcEffectiveSHR(const DataLoopNode::NodeData To1 = aa + Tcl; Error = 1.0; while (Error > 0.001) { - To2 = aa - Tcl * (std::exp(-To1 / Tcl) - 1.0); + To2 = aa - Tcl * std::expm1(-To1 / Tcl); Error = std::abs((To2 - To1) / To1); To1 = To2; } diff --git a/src/EnergyPlus/DXCoils.cc b/src/EnergyPlus/DXCoils.cc index 8d8b60fe067..c77543a6427 100644 --- a/src/EnergyPlus/DXCoils.cc +++ b/src/EnergyPlus/DXCoils.cc @@ -16787,7 +16787,7 @@ void CalcVRFCoolingCoil_FluidTCtrl(EnergyPlusData &state, } // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals - if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF; + if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = thisDXCoil.CoolingCoilRuntimeFraction; // Check for saturation error and modify temperature at constant enthalpy if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) { diff --git a/src/EnergyPlus/DaylightingManager.cc b/src/EnergyPlus/DaylightingManager.cc index 073ad84dffe..7ae0f6da916 100644 --- a/src/EnergyPlus/DaylightingManager.cc +++ b/src/EnergyPlus/DaylightingManager.cc @@ -771,7 +771,7 @@ void CalcDayltgCoeffsRefPoints(EnergyPlusData &state, int const daylightCtrlNum) } auto &thisDayltgCtrl = dl->daylightControl(daylightCtrlNum); - auto &thisEnclDaylight = dl->enclDaylight(thisDayltgCtrl.enclIndex); + auto const &thisEnclDaylight = dl->enclDaylight(thisDayltgCtrl.enclIndex); int zoneNum = thisDayltgCtrl.zoneIndex; // Azimuth of view vector in absolute coord sys Real64 AZVIEW = (thisDayltgCtrl.ViewAzimuthForGlare + state.dataHeatBal->Zone(zoneNum).RelNorth + state.dataHeatBal->BuildingAzimuth + @@ -811,7 +811,7 @@ void CalcDayltgCoeffsRefPoints(EnergyPlusData &state, int const daylightCtrlNum) BRef = 0; for (int IL = 1; IL <= thisDayltgCtrl.TotalDaylRefPoints; ++IL) { - auto &refPt = thisDayltgCtrl.refPts(IL); + auto const &refPt = thisDayltgCtrl.refPts(IL); // Reference point in absolute coordinate system Vector3 RREF = refPt.absCoords; @@ -1067,7 +1067,6 @@ void CalcDayltgCoeffsMapPoints(EnergyPlusData &state, int const mapNum) // In the following four variables, I=1 for clear sky, 2 for overcast. int numRefPts; // Number of daylighting reference points in a zone - int IL; // Reference point counter // glare calculation (radians) int IConst; // Construction counter int ICtrl; // Window control counter @@ -1122,7 +1121,7 @@ void CalcDayltgCoeffsMapPoints(EnergyPlusData &state, int const mapNum) Vector3 VIEWVC2; if (dl->mapFirstTime && (int)dl->illumMaps.size() > 0) { - IL = -999; + int IL = -999; for (int MapNum = 1; MapNum <= (int)dl->illumMaps.size(); ++MapNum) { IL = max(IL, dl->illumMaps(MapNum).TotalMapRefPoints); } @@ -1132,7 +1131,7 @@ void CalcDayltgCoeffsMapPoints(EnergyPlusData &state, int const mapNum) auto &illumMap = dl->illumMaps(mapNum); int enclNum = illumMap.enclIndex; - auto &thisEnclDaylight = dl->enclDaylight(enclNum); + auto const &thisEnclDaylight = dl->enclDaylight(enclNum); // Azimuth of view vector in absolute coord sys - set to zero here, because glare isn't calculated for map points // but these are arguments to some of the functions that are shared with regular reference points, so initalize here. @@ -1165,7 +1164,7 @@ void CalcDayltgCoeffsMapPoints(EnergyPlusData &state, int const mapNum) } for (int IL = 1; IL <= numRefPts; ++IL) { - auto &refPt = illumMap.refPts(IL); + auto const &refPt = illumMap.refPts(IL); Vector3 RREF = refPt.absCoords; // ------------- @@ -2407,7 +2406,7 @@ void InitializeCFSStateData(EnergyPlusData &state, } } // do JSurf = 1, TotSurfaces if (TotHits <= 0) { - auto &sIncRay = state.dataBSDFWindow->ComplexWind(iWin).Geom(CurFenState).sInc(IRay); + auto const &sIncRay = state.dataBSDFWindow->ComplexWind(iWin).Geom(CurFenState).sInc(IRay); // This ray reached the sky or ground unobstructed if (sIncRay.z < 0.0) { // A ground ray @@ -2665,7 +2664,7 @@ Real64 CalcObstrMultiplier(EnergyPlusData &state, // Phi = 0 at the horizon; Phi = Pi/2 at the zenith. // Locals - auto &dl = state.dataDayltg; + auto const &dl = state.dataDayltg; auto &s_surf = state.dataSurface; bool hitObs; // True iff obstruction is hit @@ -3962,7 +3961,6 @@ void GetInputIlluminanceMap(EnergyPlusData &state, bool &ErrorsFound) CheckForGeometricTransform(state, doTransform, OldAspectRatio, NewAspectRatio); - auto &ip = state.dataInputProcessing->inputProcessor; auto const &ipsc = state.dataIPShortCut; ipsc->cCurrentModuleObject = "Output:IlluminanceMap"; int TotIllumMaps = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cCurrentModuleObject); @@ -3973,6 +3971,7 @@ void GetInputIlluminanceMap(EnergyPlusData &state, bool &ErrorsFound) int IOStat; int NumAlpha; int NumNumber; + auto &ip = state.dataInputProcessing->inputProcessor; for (int MapNum = 1; MapNum <= TotIllumMaps; ++MapNum) { ip->getObjectItem(state, ipsc->cCurrentModuleObject, @@ -4736,7 +4735,7 @@ void GetInputDayliteRefPt(EnergyPlusData &state, bool &ErrorsFound) { // Perform GetInput function for the Daylighting:ReferencePoint object // Glazer - July 2016 - auto &dl = state.dataDayltg; + auto const &dl = state.dataDayltg; auto &ip = state.dataInputProcessing->inputProcessor; auto const &ipsc = state.dataIPShortCut; ipsc->cCurrentModuleObject = "Daylighting:ReferencePoint"; @@ -4784,7 +4783,7 @@ void GetInputDayliteRefPt(EnergyPlusData &state, bool &ErrorsFound) bool doesDayLightingUseDElight(EnergyPlusData &state) { - auto &dl = state.dataDayltg; + auto const &dl = state.dataDayltg; for (auto const &znDayl : dl->daylightControl) { if (znDayl.DaylightMethod == DaylightingMethod::DElight) { return true; @@ -5630,7 +5629,7 @@ void manageDaylighting(EnergyPlusData &state) if (state.dataEnvrn->SunIsUp && (state.dataEnvrn->BeamSolarRad + state.dataEnvrn->GndSolarRad + state.dataEnvrn->DifSolarRad > 0.0)) { for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) { - auto &enclSol = state.dataViewFactor->EnclSolInfo(enclNum); + auto const &enclSol = state.dataViewFactor->EnclSolInfo(enclNum); if (enclSol.TotalEnclosureDaylRefPoints == 0 || !enclSol.HasInterZoneWindow) continue; DayltgInterReflIllFrIntWins(state, enclNum); @@ -5699,7 +5698,6 @@ void DayltgInteriorIllum(EnergyPlusData &state, int ISWFLG; // Switchable glazing flag: =1 if one or more windows in a zone // has switchable glazing that adjusts visible transmittance to just meet // daylighting setpoint; =0 otherwise. - int ICtrl; // Window shading control pointer Real64 VTRAT; // Ratio between switched and unswitched visible transmittance at normal incidence Real64 BACL; // Window background (surround) luminance for glare calc (cd/m2) Real64 SkyWeight; // Weighting factor used to average two different sky types @@ -5937,22 +5935,22 @@ void DayltgInteriorIllum(EnergyPlusData &state, auto &daylFromWinAtRefPt = thisDayltgCtrl.refPts(IL).extWins(loop).lums; auto &tmpDayl = tmpDaylFromWinAtRefPt(IL, loop); for (int iWinCover = 0; iWinCover < (int)WinCover::Num; ++iWinCover) { - auto const &dfhr = DFHR[iWinCover]; - auto const &bfhr = BFHR[iWinCover]; - auto const &sfhr = SFHR[iWinCover]; + auto const &dfhr3 = DFHR[iWinCover]; + auto const &bfhr3 = BFHR[iWinCover]; + auto const &sfhr3 = SFHR[iWinCover]; // What is this? if (iWinCover == iWinCover_Shaded && !ShadedOrDiffusingGlassWin) break; daylFromWinAtRefPt[iLum_Illum][iWinCover] = - dfhr.sun * state.dataEnvrn->HISUNF + - HorIllSkyFac * (dfhr.sky[iSky1] * SkyWeight * horIllSky1 + dfhr.sky[iSky2] * (1.0 - SkyWeight) * horIllSky2); + dfhr3.sun * state.dataEnvrn->HISUNF + + HorIllSkyFac * (dfhr3.sky[iSky1] * SkyWeight * horIllSky1 + dfhr3.sky[iSky2] * (1.0 - SkyWeight) * horIllSky2); daylFromWinAtRefPt[iLum_Back][iWinCover] = - bfhr.sun * state.dataEnvrn->HISUNF + - HorIllSkyFac * (bfhr.sky[iSky1] * SkyWeight * horIllSky1 + bfhr.sky[iSky2] * (1.0 - SkyWeight) * horIllSky2); + bfhr3.sun * state.dataEnvrn->HISUNF + + HorIllSkyFac * (bfhr3.sky[iSky1] * SkyWeight * horIllSky1 + bfhr3.sky[iSky2] * (1.0 - SkyWeight) * horIllSky2); daylFromWinAtRefPt[iLum_Source][iWinCover] = - sfhr.sun * state.dataEnvrn->HISUNF + - HorIllSkyFac * (sfhr.sky[iSky1] * SkyWeight * horIllSky1 + sfhr.sky[iSky2] * (1.0 - SkyWeight) * horIllSky2); + sfhr3.sun * state.dataEnvrn->HISUNF + + HorIllSkyFac * (sfhr3.sky[iSky1] * SkyWeight * horIllSky1 + sfhr3.sky[iSky2] * (1.0 - SkyWeight) * horIllSky2); daylFromWinAtRefPt[iLum_Source][iWinCover] = max(daylFromWinAtRefPt[iLum_Source][iWinCover], 0.0); @@ -6238,7 +6236,7 @@ void DayltgInteriorIllum(EnergyPlusData &state, continueOuterLoop = false; continue; } - ICtrl = s_surf->Surface(IWin).activeWindowShadingControl; + int ICtrl = s_surf->Surface(IWin).activeWindowShadingControl; if (!s_surf->Surface(IWin).HasShadeControl) { continueOuterLoop = false; continue; @@ -6271,7 +6269,7 @@ void DayltgInteriorIllum(EnergyPlusData &state, rdayil[iLum_Back] = refPt.lums[iLum_Back] - wdayil[iLum_Back][iWinCover_Bare] + wdayil[iLum_Back][iWinCover_Shaded]; } else { // switchable glazings already in partially switched state when calc the RDAYIL(IL) & RBACLU(IL) - auto &tmpDayl = tmpDaylFromWinAtRefPt(loop, IL); + auto const &tmpDayl = tmpDaylFromWinAtRefPt(loop, IL); rdayil[iLum_Illum] = dl->DaylIllum(IL) - wdayil[iLum_Illum][iWinCover_Shaded] + tmpDayl[iLum_Illum][iWinCover_Shaded]; rdayil[iLum_Back] = refPt.lums[iLum_Back] - wdayil[iLum_Back][iWinCover_Shaded] + tmpDayl[iLum_Back][iWinCover_Shaded]; } @@ -6379,7 +6377,7 @@ void DayltgInteriorIllum(EnergyPlusData &state, ANY_BLIND(s_surf->SurfWinShadingFlag(IWin))) continue; - ICtrl = s_surf->Surface(IWin).activeWindowShadingControl; + int ICtrl = s_surf->Surface(IWin).activeWindowShadingControl; if (!s_surf->Surface(IWin).HasShadeControl) continue; if (s_surf->WindowShadingControl(ICtrl).GlareControlIsActive) { @@ -8324,7 +8322,7 @@ Real64 DayltgSkyLuminance(EnergyPlusData const &state, // PHSKY ranges from 0 to Pi starting with 0 at the horizon and Pi/2 at the zenith. // FUNCTION LOCAL VARIABLE DECLARATIONS: - auto &dl = state.dataDayltg; + auto const &dl = state.dataDayltg; Real64 G = 0.0; // Angle between sun and element of sky (radians) Real64 COSG = 0.0; // Cosine of G @@ -8766,11 +8764,11 @@ void DayltgInteriorMapIllum(EnergyPlusData &state) if (s_surf->SurfWinWindowModelType(IWin) == WindowModel::BSDF) break; if (NOT_SHADED(s_surf->SurfWinShadingFlag(IWin)) && !s_surf->SurfWinSolarDiffusing(IWin)) break; } - auto const &dfhr = DFHR[iWinCover]; + auto const &dfhr3 = DFHR[iWinCover]; thisMap.refPts(ILB).winLums(loop)[iWinCover] = tmpDFHR[iWinCover].sun * state.dataEnvrn->HISUNF + - HorIllSkyFac * (dfhr.sky[iSky1] * SkyWeight * tmpHorIll.sky[iSky1] + - dfhr.sky[iSky2] * (1.0 - SkyWeight) * tmpHorIll.sky[iSky2]); + HorIllSkyFac * (dfhr3.sky[iSky1] * SkyWeight * tmpHorIll.sky[iSky1] + + dfhr3.sky[iSky2] * (1.0 - SkyWeight) * tmpHorIll.sky[iSky2]); } } // End of reference point loop @@ -9521,7 +9519,7 @@ void DayltgInterReflIllFrIntWins(EnergyPlusData &state, int const enclNum) auto &s_surf = state.dataSurface; auto &enclDayl = dl->enclDaylight(enclNum); - auto &enclSol = state.dataViewFactor->EnclSolInfo(enclNum); + auto const &enclSol = state.dataViewFactor->EnclSolInfo(enclNum); enclDayl.InterReflIllFrIntWins = 0.0; @@ -9617,8 +9615,7 @@ void CalcMinIntWinSolidAngs(EnergyPlusData &state) Vector3 W23 = W3 - W2; Real64 HW = W21.magnitude(); Real64 WW = W23.magnitude(); - Vector3 WC = - (is_Rectangle) ? (W2 + (W23 + W21) / 2.0) : (is_Triangle ? (W2 + (W23 + W21) / 3.0) : (W2 + (W23 + W21) / 3.0)); + Vector3 WC = (is_Rectangle) ? (W2 + (W23 + W21) / 2.0) : (W2 + (W23 + W21) / 3.0); // Vector from ref point to center of window Vector3 REFWC = WC - RREF; diff --git a/src/EnergyPlus/ExtendedHI.cc b/src/EnergyPlus/ExtendedHI.cc new file mode 100644 index 00000000000..a585e8c37a0 --- /dev/null +++ b/src/EnergyPlus/ExtendedHI.cc @@ -0,0 +1,538 @@ +// EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois, +// The Regents of the University of California, through Lawrence Berkeley National Laboratory +// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge +// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other +// contributors. All rights reserved. +// +// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the +// U.S. Government consequently retains certain rights. As such, the U.S. Government has been +// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, +// worldwide license in the Software to reproduce, distribute copies to the public, prepare +// derivative works, and perform publicly and display publicly, and to permit others to do so. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// (1) Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, +// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific prior +// written permission. +// +// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form +// without changes from the version obtained under this License, or (ii) Licensee makes a +// reference solely to the software portion of its product, Licensee must refer to the +// software as "EnergyPlus version X" software, where "X" is the version number Licensee +// obtained under this License and may not use a different name for the software. Except as +// specifically required in this Section (4), Licensee shall not use in a company name, a +// product name, in advertising, publicity, or other promotional activities any name, trade +// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly +// similar designation, without the U.S. Department of Energy's prior written consent. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// Adapted from the code Version 1.1 released by Yi-Chuan Lu on February 23, 2023. +// +// @article{20heatindex, +// Title = {Extending the Heat Index}, +// Author = {Yi-Chuan Lu and David M. Romps}, +// Journal = {Journal of Applied Meteorology and Climatology}, +// Year = {2022}, +// Volume = {61}, +// Number = {10}, +// Pages = {1367--1383}, +// Year = {2022}, +// } +// + +#include + +#include +#include +#include +#include + +namespace EnergyPlus { + +namespace ExtendedHI { + // Thermodynamic parameters + constexpr Real64 Ttrip = 273.16; // K + constexpr Real64 ptrip = 611.65; // Pa + constexpr Real64 E0v = 2.3740e6; // J/kg + constexpr Real64 E0s = 0.3337e6; // J/kg + constexpr Real64 rgasa = 287.04; // J/kg/K + constexpr Real64 rgasv = 461.; // J/kg/K + constexpr Real64 cva = 719.; // J/kg/K + constexpr Real64 cvv = 1418.; // J/kg/K + constexpr Real64 cvl = 4119.; // J/kg/K + constexpr Real64 cvs = 1861.; // J/kg/K + constexpr Real64 cpa = cva + rgasa; + constexpr Real64 cpv = cvv + rgasv; + + // The saturation vapor pressure + Real64 pvstar(Real64 T) + { + if (T == 0.0) { + return 0.0; + } else if (T < Ttrip) { + return ptrip * pow((T / Ttrip), ((cpv - cvs) / rgasv)) * exp((E0v + E0s - (cvv - cvs) * Ttrip) / rgasv * (1. / Ttrip - 1. / T)); + } else { + return ptrip * pow((T / Ttrip), ((cpv - cvl) / rgasv)) * exp((E0v - (cvv - cvl) * Ttrip) / rgasv * (1. / Ttrip - 1. / T)); + } + return 0.0; + } + + // The latent heat of vaporization of water + Real64 Le(Real64 T) + { + return (E0v + (cvv - cvl) * (T - Ttrip) + rgasv * T); + } + + // Thermoregulatory parameters + constexpr Real64 sigma = 5.67e-8; // W/m^2/K^4 , Stefan-Boltzmann constant + constexpr Real64 epsilon = 0.97; // , emissivity of surface, steadman1979 + constexpr Real64 M = 83.6; // kg , mass of average US adults, fryar2018 + constexpr Real64 H = 1.69; // m , height of average US adults, fryar2018 + Real64 A = 0.202 * pow(M, 0.425) * pow(H, 0.725); // m^2 , DuBois formula, parson2014 + constexpr Real64 cpc = 3492.; // J/kg/K , specific heat capacity of core, gagge1972 + Real64 C = M * cpc / A; // , heat capacity of core + constexpr Real64 r = 124.; // Pa/K , Zf/Rf, steadman1979 + constexpr Real64 Q = 180.; // W/m^2 , metabolic rate per skin area, steadman1979 + constexpr Real64 phi_salt = 0.9; // , vapor saturation pressure level of saline solution, steadman1979 + constexpr Real64 Tc = 310.; // K , core temperature, steadman1979 + Real64 Pc = phi_salt * pvstar(Tc); // , core vapor pressure + Real64 L = Le(310.); // , latent heat of vaporization at 310 K + constexpr Real64 p = 1.013e5; // Pa , atmospheric pressure + constexpr Real64 eta = 1.43e-6; // kg/J , "inhaled mass" / "metabolic rate", steadman1979 + constexpr Real64 Pa0 = 1.6e3; // Pa , reference air vapor pressure in regions III, IV, V, VI, steadman1979 + + // Function to calculate respiratory heat loss, W/m^2 + Real64 Qv(Real64 Ta, Real64 Pa) + { + return eta * Q * (cpa * (Tc - Ta) + L * rgasa / (p * rgasv) * (Pc - Pa)); + } + + // Function to calculate mass transfer resistance through skin, Pa m^2/W + Real64 Zs(Real64 Rs) + { + return (Rs == 0.0387) ? 52.1 : 6.0e8 * std::pow(Rs, 5); + } + + // Function to calculate heat transfer resistance through air, exposed part of skin, K m^2/W + Real64 Ra(Real64 Ts, Real64 Ta) + { + constexpr Real64 hc = 17.4; + constexpr Real64 phi_rad = 0.85; + Real64 hr = epsilon * phi_rad * sigma * (std::pow(Ts, 2) + std::pow(Ta, 2)) * (Ts + Ta); + return 1.0 / (hc + hr); + } + + // Function to calculate heat transfer resistance through air, clothed part of skin, K m^2/W + Real64 Ra_bar(Real64 Tf, Real64 Ta) + { + constexpr Real64 hc = 11.6; + constexpr Real64 phi_rad = 0.79; + Real64 hr = epsilon * phi_rad * sigma * (std::pow(Tf, 2) + std::pow(Ta, 2)) * (Tf + Ta); + return 1.0 / (hc + hr); + } + + // Function to calculate heat transfer resistance through air, when being naked, K m^2/W + Real64 Ra_un(Real64 Ts, Real64 Ta) + { + constexpr Real64 hc = 12.3; + constexpr Real64 phi_rad = 0.80; + Real64 hr = epsilon * phi_rad * sigma * (std::pow(Ts, 2) + std::pow(Ta, 2)) * (Ts + Ta); + return 1.0 / (hc + hr); + } + + constexpr Real64 Za = 60.6 / 17.4; // Pa m^2/W, mass transfer resistance through air, exposed part of skin + constexpr Real64 Za_bar = 60.6 / 11.6; // Pa m^2/W, mass transfer resistance through air, clothed part of skin + constexpr Real64 Za_un = 60.6 / 12.3; // Pa m^2/W, mass transfer resistance through air, when being naked + + constexpr Real64 tol = 1e-8; + constexpr Real64 maxIter = 100; + Real64 find_eqvar_phi(EnergyPlusData &state, Real64 Ta, Real64 RH) + { + + Real64 phi = 0.84; + Real64 Pa = RH * pvstar(Ta); + Real64 Rs = 0.0387; + Real64 m = (Pc - Pa) / (Zs(Rs) + Za); + Real64 Ts; + int SolFla; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Ts, + [&](Real64 Ts) { return (Ts - Ta) / Ra(Ts, Ta) + (Pc - Pa) / (Zs(Rs) + Za) - (Tc - Ts) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m)), + std::max(Tc, Ta) + Rs * std::abs(m)); + Real64 flux1 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs; + if (flux1 <= 0.0) { + phi = 1.0 - (Q - Qv(Ta, Pa)) * Rs / (Tc - Ts); + } + return phi; + } + + Real64 find_eqvar_Rf(EnergyPlusData &state, Real64 Ta, Real64 RH) + { + Real64 Pa = RH * pvstar(Ta); + Real64 Rs = 0.0387; + Real64 phi = 0.84; + Real64 m_bar = (Pc - Pa) / (Zs(Rs) + Za_bar); + Real64 m = (Pc - Pa) / (Zs(Rs) + Za); + Real64 Ts; + int SolFla; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Ts, + [&](Real64 Ts) { return (Ts - Ta) / Ra(Ts, Ta) + (Pc - Pa) / (Zs(Rs) + Za) - (Tc - Ts) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m)), + std::max(Tc, Ta) + Rs * std::abs(m)); + Real64 Tf; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Tf, + [&](Real64 Tf) { return (Tf - Ta) / Ra_bar(Tf, Ta) + (Pc - Pa) / (Zs(Rs) + Za_bar) - (Tc - Tf) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m_bar)), + std::max(Tc, Ta) + Rs * std::abs(m_bar)); + Real64 flux1 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs; + Real64 flux2 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs - phi * (Tc - Tf) / Rs; + Real64 Rf; + if (flux1 <= 0.0) { + Rf = std::numeric_limits::infinity(); + } else if (flux2 <= 0.0) { + Real64 Ts_bar = Tc - (Q - Qv(Ta, Pa)) * Rs / phi + (1.0 / phi - 1.0) * (Tc - Ts); + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Tf, + [&](Real64 Tf) { + return (Tf - Ta) / Ra_bar(Tf, Ta) + (Pc - Pa) * (Tf - Ta) / ((Zs(Rs) + Za_bar) * (Tf - Ta) + r * Ra_bar(Tf, Ta) * (Ts_bar - Tf)) - + (Tc - Ts_bar) / Rs; + }, + Ta, + Ts_bar); + Rf = Ra_bar(Tf, Ta) * (Ts_bar - Tf) / (Tf - Ta); + } else { + Rf = 0.0; + } + return Rf; + } + + Real64 find_eqvar_rs(EnergyPlusData &state, Real64 Ta, Real64 RH) + { + + Real64 Pa = RH * pvstar(Ta); + Real64 phi = 0.84; + Real64 Rs = 0.0387; + Real64 m = (Pc - Pa) / (Zs(Rs) + Za); + Real64 m_bar = (Pc - Pa) / (Zs(Rs) + Za_bar); + Real64 Ts; + int SolFla; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Ts, + [&](Real64 Ts) { return (Ts - Ta) / Ra(Ts, Ta) + (Pc - Pa) / (Zs(Rs) + Za) - (Tc - Ts) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m)), + std::max(Tc, Ta) + Rs * std::abs(m)); + Real64 Tf; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Tf, + [&](Real64 Tf) { return (Tf - Ta) / Ra_bar(Tf, Ta) + (Pc - Pa) / (Zs(Rs) + Za_bar) - (Tc - Tf) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m_bar)), + std::max(Tc, Ta) + Rs * std::abs(m_bar)); + Real64 flux1 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs; + Real64 flux2 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs - phi * (Tc - Tf) / Rs; + Real64 flux3 = Q - Qv(Ta, Pa) - (Tc - Ta) / Ra_un(Tc, Ta) - (phi_salt * pvstar(Tc) - Pa) / Za_un; + if (flux1 > 0 && flux2 > 0) { + if (flux3 < 0.0) { + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Ts, + [&](Real64 Ts) { return (Ts - Ta) / Ra_un(Ts, Ta) + (Pc - Pa) / (Zs((Tc - Ts) / (Q - Qv(Ta, Pa))) + Za_un) - (Q - Qv(Ta, Pa)); }, + 0.0, + Tc); + Rs = (Tc - Ts) / (Q - Qv(Ta, Pa)); + Real64 Ps = Pc - (Pc - Pa) * Zs(Rs) / (Zs(Rs) + Za_un); + if (Ps > phi_salt * pvstar(Ts)) { + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Ts, + [&](Real64 Ts) { return (Ts - Ta) / Ra_un(Ts, Ta) + (phi_salt * pvstar(Ts) - Pa) / Za_un - (Q - Qv(Ta, Pa)); }, + 0.0, + Tc); + Rs = (Tc - Ts) / (Q - Qv(Ta, Pa)); + } + } else { + Rs = 0.0; + } + } + return Rs; + } + + Real64 find_eqvar_dTcdt(EnergyPlusData &state, Real64 Ta, Real64 RH) + { + Real64 dTcdt = 0.0; + Real64 Pa = RH * pvstar(Ta); + Real64 Rs = 0.0387; + Real64 phi = 0.84; + Real64 m = (Pc - Pa) / (Zs(Rs) + Za); + Real64 m_bar = (Pc - Pa) / (Zs(Rs) + Za_bar); + Real64 Ts; + int SolFla; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Ts, + [&](Real64 Ts) { return (Ts - Ta) / Ra(Ts, Ta) + (Pc - Pa) / (Zs(Rs) + Za) - (Tc - Ts) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m)), + std::max(Tc, Ta) + Rs * std::abs(m)); + Real64 Tf; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Tf, + [&](Real64 Tf) { return (Tf - Ta) / Ra_bar(Tf, Ta) + (Pc - Pa) / (Zs(Rs) + Za_bar) - (Tc - Tf) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m_bar)), + std::max(Tc, Ta) + Rs * std::abs(m_bar)); + Real64 flux1 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs; + Real64 flux2 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs - phi * (Tc - Tf) / Rs; + Real64 flux3 = Q - Qv(Ta, Pa) - (Tc - Ta) / Ra_un(Tc, Ta) - (phi_salt * pvstar(Tc) - Pa) / Za_un; + if (flux1 > 0.0 && flux2 > 0.0 && flux3 >= 0.0) { + dTcdt = (1.0 / C) * flux3; + } + return dTcdt; + } + + int find_eqvar_name(EnergyPlusData &state, Real64 Ta, Real64 RH) + { + + Real64 Pa = RH * pvstar(Ta); + Real64 Rs = 0.0387; + Real64 phi = 0.84; + Real64 m = (Pc - Pa) / (Zs(Rs) + Za); + Real64 m_bar = (Pc - Pa) / (Zs(Rs) + Za_bar); + + int SolFla; + Real64 Ts; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Ts, + [&](Real64 Ts) { return (Ts - Ta) / Ra(Ts, Ta) + (Pc - Pa) / (Zs(Rs) + Za) - (Tc - Ts) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m)), + std::max(Tc, Ta) + Rs * std::abs(m)); + + Real64 Tf; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Tf, + [&](Real64 Tf) { return (Tf - Ta) / Ra_bar(Tf, Ta) + (Pc - Pa) / (Zs(Rs) + Za_bar) - (Tc - Tf) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m_bar)), + std::max(Tc, Ta) + Rs * std::abs(m_bar)); + Real64 flux1 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs; + Real64 flux2 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs - phi * (Tc - Tf) / Rs; + + if (flux1 <= 0.0) { + return static_cast(EqvarName::Phi); + } else if (flux2 <= 0.0) { + return static_cast(EqvarName::Rf); + } else { + Real64 flux3 = Q - Qv(Ta, Pa) - (Tc - Ta) / Ra_un(Tc, Ta) - (phi_salt * pvstar(Tc) - Pa) / Za_un; + if (flux3 < 0.0) { + return static_cast(EqvarName::Rs); + } else { + return static_cast(EqvarName::DTcdt); + } + } + } + + // given T and RH, returns a key and value pair + Real64 find_eqvar_value(EnergyPlusData &state, Real64 Ta, Real64 RH) + { + Real64 Pa = RH * pvstar(Ta); + Real64 Rs = 0.0387; + Real64 phi = 0.84; + Real64 dTcdt = 0.0; + Real64 m = (Pc - Pa) / (Zs(Rs) + Za); + Real64 m_bar = (Pc - Pa) / (Zs(Rs) + Za_bar); + + int SolFla; + Real64 Ts; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Ts, + [&](Real64 Ts) { return (Ts - Ta) / Ra(Ts, Ta) + (Pc - Pa) / (Zs(Rs) + Za) - (Tc - Ts) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m)), + std::max(Tc, Ta) + Rs * std::abs(m)); + + Real64 Tf; + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Tf, + [&](Real64 Tf) { return (Tf - Ta) / Ra_bar(Tf, Ta) + (Pc - Pa) / (Zs(Rs) + Za_bar) - (Tc - Tf) / Rs; }, + std::max(0.0, std::min(Tc, Ta) - Rs * std::abs(m_bar)), + std::max(Tc, Ta) + Rs * std::abs(m_bar)); + Real64 flux1 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs; + Real64 flux2 = Q - Qv(Ta, Pa) - (1.0 - phi) * (Tc - Ts) / Rs - phi * (Tc - Tf) / Rs; + Real64 Rf; + + if (flux1 <= 0.0) { + phi = 1.0 - (Q - Qv(Ta, Pa)) * Rs / (Tc - Ts); + return phi; + } else if (flux2 <= 0.0) { + Real64 Ts_bar = Tc - (Q - Qv(Ta, Pa)) * Rs / phi + (1.0 / phi - 1.0) * (Tc - Ts); + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Tf, + [&](Real64 Tf) { + return (Tf - Ta) / Ra_bar(Tf, Ta) + (Pc - Pa) * (Tf - Ta) / ((Zs(Rs) + Za_bar) * (Tf - Ta) + r * Ra_bar(Tf, Ta) * (Ts_bar - Tf)) - + (Tc - Ts_bar) / Rs; + }, + Ta, + Ts_bar); + Rf = Ra_bar(Tf, Ta) * (Ts_bar - Tf) / (Tf - Ta); + return Rf; + } else { + Real64 flux3 = Q - Qv(Ta, Pa) - (Tc - Ta) / Ra_un(Tc, Ta) - (phi_salt * pvstar(Tc) - Pa) / Za_un; + if (flux3 < 0.0) { + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Ts, + [&](Real64 Ts) { return (Ts - Ta) / Ra_un(Ts, Ta) + (Pc - Pa) / (Zs((Tc - Ts) / (Q - Qv(Ta, Pa))) + Za_un) - (Q - Qv(Ta, Pa)); }, + 0.0, + Tc); + Rs = (Tc - Ts) / (Q - Qv(Ta, Pa)); + Real64 Ps = Pc - (Pc - Pa) * Zs(Rs) / (Zs(Rs) + Za_un); + if (Ps > phi_salt * pvstar(Ts)) { + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + Ts, + [&](Real64 Ts) { return (Ts - Ta) / Ra_un(Ts, Ta) + (phi_salt * pvstar(Ts) - Pa) / Za_un - (Q - Qv(Ta, Pa)); }, + 0.0, + Tc); + Rs = (Tc - Ts) / (Q - Qv(Ta, Pa)); + } + return Rs; + } else { + Rs = 0.0; + dTcdt = (1.0 / C) * flux3; + return dTcdt; + } + } + } + + // Convert the find_T function + Real64 find_T(EnergyPlusData &state, int eqvar_name, Real64 eqvar) + { + Real64 T; + int SolFla; + + if (eqvar_name == static_cast(EqvarName::Phi)) { + General::SolveRoot( + state, tol, maxIter, SolFla, T, [&](Real64 T) { return find_eqvar_phi(state, T, 1.0) - eqvar; }, 0.0, 240.0); + } else if (eqvar_name == static_cast(EqvarName::Rf)) { + General::SolveRoot( + state, + tol, + maxIter, + SolFla, + T, + [&](Real64 T) { return (find_eqvar_Rf(state, T, std::min(1.0, Pa0 / pvstar(T)))) - eqvar; }, + 230.0, + 300.0); + } else if (eqvar_name == static_cast(EqvarName::Rs)) { + General::SolveRoot( + state, tol, maxIter, SolFla, T, [&](Real64 T) { return find_eqvar_rs(state, T, Pa0 / pvstar(T)) - eqvar; }, 295.0, 350.0); + } else { + General::SolveRoot( + state, tol, maxIter, SolFla, T, [&](Real64 T) { return find_eqvar_dTcdt(state, T, Pa0 / pvstar(T)) - eqvar; }, 340.0, 1000.0); + } + + return T; + } + + Real64 heatindex(EnergyPlusData &state, Real64 Ta, Real64 RH) + { + + // Ta: temperature in Kelvin + // RH: relative humidity in range of 0.0 to 1.0 + // The function computes the extended heat index, in Kelvinn + + auto const HVACSystemRootSolverBackup = state.dataRootFinder->HVACSystemRootFinding.HVACSystemRootSolver; + state.dataRootFinder->HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverAlgorithm::Bisection; + int eqvar_name = find_eqvar_name(state, Ta, RH); + Real64 eqvar_value = find_eqvar_value(state, Ta, RH); + + Real64 T = find_T(state, eqvar_name, eqvar_value); + + if (Ta == 0.0) T = 0.0; + + state.dataRootFinder->HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverBackup; + return T; + } + +} // namespace ExtendedHI +} // namespace EnergyPlus diff --git a/src/EnergyPlus/ExtendedHI.hh b/src/EnergyPlus/ExtendedHI.hh new file mode 100644 index 00000000000..b839ea571eb --- /dev/null +++ b/src/EnergyPlus/ExtendedHI.hh @@ -0,0 +1,91 @@ +// EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois, +// The Regents of the University of California, through Lawrence Berkeley National Laboratory +// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge +// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other +// contributors. All rights reserved. +// +// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the +// U.S. Government consequently retains certain rights. As such, the U.S. Government has been +// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, +// worldwide license in the Software to reproduce, distribute copies to the public, prepare +// derivative works, and perform publicly and display publicly, and to permit others to do so. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// (1) Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, +// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific prior +// written permission. +// +// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form +// without changes from the version obtained under this License, or (ii) Licensee makes a +// reference solely to the software portion of its product, Licensee must refer to the +// software as "EnergyPlus version X" software, where "X" is the version number Licensee +// obtained under this License and may not use a different name for the software. Except as +// specifically required in this Section (4), Licensee shall not use in a company name, a +// product name, in advertising, publicity, or other promotional activities any name, trade +// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly +// similar designation, without the U.S. Department of Energy's prior written consent. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef extendedHI_hh_INCLUDED +#define extendedHI_hh_INCLUDED + +// EnergyPlus Headers +#include +#include +#include + +namespace EnergyPlus { + +// Forward declarations +struct EnergyPlusData; + +namespace ExtendedHI { + + enum class EqvarName + { + Invalid = -1, + Phi = 1, + Rf = 2, + Rs = 3, + DTcdt = 4, + Num + }; + + Real64 pvstar(Real64 T); + Real64 Le(Real64 T); + Real64 Qv(Real64 Ta, Real64 Pa); + Real64 Zs(Real64 Rs); + Real64 Ra(Real64 Ts, Real64 Ta); + Real64 Ra_bar(Real64 Tf, Real64 Ta); + Real64 Ra_un(Real64 Ts, Real64 Ta); + int find_eqvar_name(EnergyPlusData &state, Real64 Ta, Real64 RH); + Real64 find_eqvar_value(EnergyPlusData &state, Real64 Ta, Real64 RH); + Real64 find_eqvar_phi(EnergyPlusData &state, Real64 Ta, Real64 RH); + Real64 find_eqvar_Rf(EnergyPlusData &state, Real64 Ta, Real64 RH); + Real64 find_eqvar_rs(EnergyPlusData &state, Real64 Ta, Real64 RH); + Real64 find_T(EnergyPlusData &state, int eqvar_name, Real64 eqvar); + Real64 heatindex(EnergyPlusData &state, Real64 Ta, Real64 RH); + +} // namespace ExtendedHI +} // namespace EnergyPlus + +#endif diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 6bb48f857f3..b6888cca627 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -266,7 +266,7 @@ void SimulateVRF(EnergyPlusData &state, if (state.dataHVACVarRefFlow->VRF(VRFCondenser).VRFAlgorithmType == AlgorithmType::FluidTCtrl) { // Algorithm Type: VRF model based on physics, applicable for Fluid Temperature Control - state.dataHVACVarRefFlow->VRF(VRFCondenser).CalcVRFCondenser_FluidTCtrl(state); + state.dataHVACVarRefFlow->VRF(VRFCondenser).CalcVRFCondenser_FluidTCtrl(state, FirstHVACIteration); } else { // Algorithm Type: VRF model based on system curve CalcVRFCondenser(state, VRFCondenser); @@ -11010,7 +11010,7 @@ void VRFTerminalUnitEquipment::CalcVRFIUVariableTeTc(EnergyPlusData &state, } } -void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) +void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state, const bool FirstHVACIteration) { // SUBROUTINE INFORMATION: @@ -11141,7 +11141,7 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) Real64 Pipe_DeltP_h; // Piping Loss Algorithm Parameter: Pipe pressure drop (h) [Pa] Real64 Pipe_Q_c; // Piping Loss Algorithm Parameter: Heat loss (c) [W] Real64 Pipe_Q_h; // Piping Loss Algorithm Parameter: Heat loss (h) [W] - Real64 Q_c_TU_PL; // Cooling load to be met at heating mode, including the piping loss(W) + Real64 Q_c_TU_PL; // Cooling load to be met at cooling mode, including the piping loss(W) Real64 Q_h_TU_PL; // Heating load to be met at heating mode, including the piping loss (W) Real64 Q_h_OU; // outdoor unit condenser heat release (cooling mode) [W] Real64 Q_c_OU; // outdoor unit evaporator heat extract (heating mode) [W] @@ -11419,56 +11419,40 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) C_cap_operation = this->VRFOU_CapModFactor( state, h_comp_in, h_IU_evap_in, max(min(Psuction, RefPHigh), RefPLow), Tsuction + SH_Comp, Tsuction + 8, CapMinTc - 5); - if (Q_c_TU_PL * C_cap_operation < CompEvaporatingCAPSpdMin) { - // Required cooling load is less than the min cooling capacity, on-off strategy - - this->VRFOperationSimPath = 11; - - CyclingRatio = Q_c_TU_PL * C_cap_operation / CompEvaporatingCAPSpdMin; - double CyclingRatioFrac = 0.85 + 0.15 * CyclingRatio; - double HPRTF = CyclingRatio / CyclingRatioFrac; - Ncomp = CompEvaporatingPWRSpdMin * HPRTF; // - CompSpdActual = this->CompressorSpeed(1); // - this->CondensingTemp = CapMinTc; // - - } else { - // Required cooling load is greater than or equal to the min cooling capacity + // Iteration_Ncomp: Perform iterations to calculate Ncomp (Label10) + Counter = 1; + Ncomp = TU_CoolingLoad / this->CoolingCOP; + Ncomp_new = Ncomp; + Label10:; + Q_h_OU = Q_c_TU_PL + Ncomp_new; // Ncomp_new may be updated during Iteration_Ncomp Label10 + + // *VRF OU TeTc calculations + m_air = this->OUAirFlowRate * RhoAir; + SC_OU = this->SC; + this->VRFOU_TeTc(state, HXOpMode::CondMode, Q_h_OU, SC_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->CondensingTemp); + this->CondensingTemp = min(CapMaxTc, this->CondensingTemp); + this->SC = SC_OU; + + // *VEF OU Compressor Simulation at cooling mode: Specify the compressor speed and power consumption + this->VRFOU_CalcCompC(state, + TU_CoolingLoad, + Tsuction, + this->CondensingTemp, + Psuction, + T_comp_in, + h_comp_in, + h_IU_evap_in, + Pipe_Q_c, + CapMaxTc, + Q_h_OU, + CompSpdActual, + Ncomp, + CyclingRatio); - // Iteration_Ncomp: Perform iterations to calculate Ncomp (Label10) - Counter = 1; - Ncomp = TU_CoolingLoad / this->CoolingCOP; + if ((std::abs(Ncomp - Ncomp_new) > (Tolerance * Ncomp_new)) && (Counter < 30)) { Ncomp_new = Ncomp; - Label10:; - Q_h_OU = Q_c_TU_PL + Ncomp_new; // Ncomp_new may be updated during Iteration_Ncomp Label10 - - // *VRF OU TeTc calculations - m_air = this->OUAirFlowRate * RhoAir; - SC_OU = this->SC; - this->VRFOU_TeTc( - state, HXOpMode::CondMode, Q_h_OU, SC_OU, m_air, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, Tfs, this->CondensingTemp); - this->CondensingTemp = min(CapMaxTc, this->CondensingTemp); - this->SC = SC_OU; - - // *VEF OU Compressor Simulation at cooling mode: Specify the compressor speed and power consumption - this->VRFOU_CalcCompC(state, - TU_CoolingLoad, - Tsuction, - this->CondensingTemp, - Psuction, - T_comp_in, - h_comp_in, - h_IU_evap_in, - Pipe_Q_c, - CapMaxTc, - Q_h_OU, - CompSpdActual, - Ncomp); - - if ((std::abs(Ncomp - Ncomp_new) > (Tolerance * Ncomp_new)) && (Counter < 30)) { - Ncomp_new = Ncomp; - Counter = Counter + 1; - goto Label10; - } + Counter = Counter + 1; + goto Label10; } // Update h_IU_evap_in in iterations Label12 @@ -11490,6 +11474,8 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) } // Key outputs of this subroutine + Ncomp *= CyclingRatio; + Q_h_OU *= CyclingRatio; this->CompActSpeed = max(CompSpdActual, 0.0); this->Ncomp = max(Ncomp, 0.0) / this->EffCompInverter; // 0.95 is the efficiency of the compressor inverter, can come from IDF //@minor this->OUFanPower = this->RatedOUFanPower; //@ * pow_3( CondFlowRatio ) @@ -11975,7 +11961,7 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) this->HeatingCapacity = 0.0; // Include the piping loss this->PipingCorrectionHeating = 1.0; // 1 means no piping loss - state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) = MaxCap; // yujie: default value is MaxCap = 1e+20, not 0 + state.dataHVACVarRefFlow->MaxHeatingCapacity(VRFCond) = MaxCap; // default value is MaxCap = 1e+20, not 0 this->CoolingCapacity = 0.0; // Include the piping loss this->PipingCorrectionCooling = 1.0; @@ -12348,6 +12334,25 @@ void VRFCondenserEquipment::CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state) // Calculate the IU Te/Tc for the next time step this->CalcVRFIUTeTc_FluidTCtrl(state); + // update coil and IU evaporating temperature, also keep coil RTF updated with the condenser side cycling ratio, for the FluidTCtrl model + for (int VRFTUNum = 1; VRFTUNum <= state.dataHVACVarRefFlow->NumVRFTU; ++VRFTUNum) { + auto const &thisTU = state.dataHVACVarRefFlow->VRFTU(VRFTUNum); + auto &coolingCoil = state.dataDXCoils->DXCoil(thisTU.CoolCoilIndex); + if (this->adjustedTe && (!FirstHVACIteration)) { + coolingCoil.EvaporatingTemp = this->EvaporatingTemp; + this->IUEvaporatingTemp = this->EvaporatingTemp; + } + + int PLF; + if (coolingCoil.PLFFPLR(1) > 0 && this->VRFCondCyclingRatio < 1.0) { + PLF = Curve::CurveValue(state, coolingCoil.PLFFPLR(1), this->VRFCondCyclingRatio); // Calculate part-load factor + } else { + PLF = 1.0; + } + if (coolingCoil.TotalCoolingEnergyRate > 0.0) { + coolingCoil.CoolingCoilRuntimeFraction = this->VRFCondCyclingRatio / PLF; + } + } } void VRFTerminalUnitEquipment::ControlVRF_FluidTCtrl(EnergyPlusData &state, @@ -13847,7 +13852,8 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state, Real64 MaxOutdoorUnitTc, // The maximum temperature that Tc can be at heating mode [C] Real64 &OUCondHeatRelease, // Condenser heat release (cooling mode) [W] Real64 &CompSpdActual, // Actual compressor running speed [rps] - Real64 &Ncomp // Compressor power [W] + Real64 &Ncomp, // Compressor power [W] + Real64 &CyclingRatio // Cycling Ratio [W] ) { @@ -13855,6 +13861,7 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state, // AUTHOR Xiufeng Pang // DATE WRITTEN Feb 2014 // MODIFIED Rongpeng Zhang, Jan 2016 + // MODIFIED Yujie Xu, Sep 2023 // RE-ENGINEERED na // PURPOSE OF THIS SUBROUTINE: @@ -13910,7 +13917,8 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state, Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa] Real64 T_discharge_new; // Condensing temperature, for temporary use in iterations [C] Real64 Tfs; // Temperature of the air at the coil surface [C]] - Real64 Tolerance(0.05); // Tolerance for condensing temperature calculation [C} + Real64 constexpr Tolerance(0.05); // Tolerance for condensing temperature calculation [C] + Real64 constexpr TeTol(0.5); // Tolerance for the difference between Te and SmallLoadTe Array1D CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W] Array1D CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W] @@ -13939,6 +13947,7 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state, C_cap_operation = this->VRFOU_CapModFactor( state, Pipe_h_comp_in, Pipe_h_IU_in, max(min(P_suction, RefPHigh), RefPLow), T_suction + Modifi_SH, T_suction + 8, T_discharge - 5); + this->adjustedTe = false; for (CounterCompSpdTemp = 1; CounterCompSpdTemp <= NumOfCompSpdInput; CounterCompSpdTemp++) { // Iteration to find the VRF speed that can meet the required load, Iteration DoName1 @@ -13987,14 +13996,26 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state, MinRefriPe = this->refrig->getSatPressure(state, -15, RoutineName); MinOutdoorUnitPe = max(P_discharge - this->CompMaxDeltaP, MinRefriPe); MinOutdoorUnitTe = this->refrig->getSatTemperature(state, max(min(MinOutdoorUnitPe, RefPHigh), RefPLow), RoutineName); + // Te can't be smaller than user input lower bound + MinOutdoorUnitTe = max(this->IUEvapTempLow, MinOutdoorUnitTe); auto f = [&state, T_discharge_new, CondHeat, CAPFT](Real64 const T_suc) { return CompResidual_FluidTCtrl(state, T_discharge_new, CondHeat, CAPFT, T_suc); }; General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, SmallLoadTe, f, MinOutdoorUnitTe, - T_suction); // SmallLoadTe is the updated Te' - if (SolFla < 0) SmallLoadTe = 6; // MinOutdoorUnitTe; //SmallLoadTe( Te'_new ) is constant during iterations + T_suction); // SmallLoadTe is the updated Te' + if (SolFla == -1) { + // show error not converging + ShowWarningMessage(state, format("{}: low load Te adjustment failed for {}", RoutineName, this->Name)); + ShowContinueErrorTimeStamp(state, ""); + ShowContinueError(state, format(" Iteration limit [{}] exceeded in calculating OU evaporating temperature", MaxIter)); + } else if (SolFla == -2) { + // demand < capacity at both endpoints of the Te range, assuming f(x) is roughly monotonic than this is the low load case + assert(f(T_suction) < 0); + // TeTol is added to prevent the final updated Te to go out of bounds + SmallLoadTe = 6 + TeTol; // MinOutdoorUnitTe; //SmallLoadTe( Te'_new ) is constant during iterations + } // Get an updated Te corresponding to the updated Te' // VRFOU_TeModification( VRFCond, this->EvaporatingTemp, SmallLoadTe, Pipe_h_IU_in, OutdoorDryBulb, Pipe_Te_assumed, @@ -14006,6 +14027,7 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state, NumIteTe = 1; MaxNumIteTe = (this->EvaporatingTemp - SmallLoadTe) / 0.1 + 1; // upper bound and lower bound of Te iterations Pipe_Te_assumed = this->EvaporatingTemp - 0.1; + this->adjustedTe = true; Label11:; Pipe_m_ref = 0; // Total Ref Flow Rate( kg/s ) @@ -14072,14 +14094,14 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state, T_suction = this->refrig->getSatTemperature(state, max(min(Pipe_Pe_assumed - Pipe_DeltP, RefPHigh), RefPLow), RoutineName); - if ((std::abs(T_suction - SmallLoadTe) > 0.5) && (Pipe_Te_assumed < this->EvaporatingTemp) && (Pipe_Te_assumed > SmallLoadTe) && + if ((std::abs(T_suction - SmallLoadTe) > TeTol) && (Pipe_Te_assumed < this->EvaporatingTemp) && (Pipe_Te_assumed > SmallLoadTe) && (NumIteTe < MaxNumIteTe)) { Pipe_Te_assumed = Pipe_Te_assumed - 0.1; NumIteTe = NumIteTe + 1; goto Label11; } - if (std::abs(T_suction - SmallLoadTe) > 0.5) { + if (std::abs(T_suction - SmallLoadTe) > TeTol) { NumIteTe = 999; T_suction = SmallLoadTe; Pipe_SH_merged = 3.0; @@ -14131,12 +14153,21 @@ void VRFCondenserEquipment::VRFOU_CalcCompC(EnergyPlusData &state, goto Label13; } - if (CapDiff > (Tolerance * Cap_Eva0)) NumIteCcap = 999; + // when it gets here, either NumIteCcap = 30 or CapDiff > (Tolerance * Cap_Eva0) + if (CapDiff > (Tolerance * Cap_Eva0) && (Cap_Eva1 - Cap_Eva0) >= 0.0) { + NumIteCcap = 999; + CyclingRatio = Cap_Eva0 / Cap_Eva1; + } else { + CyclingRatio = 1.0; + } Ncomp = this->RatedCompPower * CurveValue(state, this->OUCoolingPWRFT(CounterCompSpdTemp), T_discharge, T_suction); + OUCondHeatRelease = Ncomp + Cap_Eva1; this->CondensingTemp = T_discharge; // OU Tc' is updated due to OUCondHeatRelease updates, which is caused by IU Te' updates // during low load conditions + this->EvaporatingTemp = T_suction; + this->IUEvaporatingTemp = T_suction; break; // EXIT DoName1 @@ -14212,7 +14243,7 @@ void VRFCondenserEquipment::VRFOU_CalcCompH( Real64 RefTSat; // Saturated temperature of the refrigerant [C] Real64 RefPLow; // Low Pressure Value for Ps (>0.0) [Pa] Real64 RefPHigh; // High Pressure Value for Ps (max in tables) [Pa] - Real64 Tolerance(0.05); // Tolerance for condensing temperature calculation [C} + Real64 constexpr Tolerance(0.05); // Tolerance for condensing temperature calculation [C} Array1D CompEvaporatingPWRSpd; // Array for the compressor power at certain speed [W] Array1D CompEvaporatingCAPSpd; // Array for the evaporating capacity at certain speed [W] diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.hh b/src/EnergyPlus/HVACVariableRefrigerantFlow.hh index d34e72a3a4a..8487e49cfab 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.hh +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.hh @@ -387,6 +387,7 @@ namespace HVACVariableRefrigerantFlow { Real64 VRFOperationSimPath; // simulation path indicating the VRF operation mode [--] bool checkPlantCondTypeOneTime; int CondenserCapErrIdx; // recurring condenser capacity error index + bool adjustedTe; // Default Constructor VRFCondenserEquipment() @@ -427,7 +428,7 @@ namespace HVACVariableRefrigerantFlow { RatedHeatCapacity(0.0), RatedCompPower(14000.0), RatedCompPowerPerCapcity(0.35), RatedOUFanPower(0.0), RatedOUFanPowerPerCapcity(0.0), RateBFOUEvap(0.45581), RateBFOUCond(0.21900), RefPipDiaSuc(0.0), RefPipDiaDis(0.0), RefPipLen(0.0), RefPipEquLen(0.0), RefPipHei(0.0), RefPipInsThi(0.0), RefPipInsCon(0.0), SH(0.0), SC(0.0), SCHE(0.0), SHLow(0.0), SCLow(0.0), SHHigh(0.0), SCHigh(0.0), - VRFOperationSimPath(0.0), checkPlantCondTypeOneTime(true), CondenserCapErrIdx(0) + VRFOperationSimPath(0.0), checkPlantCondTypeOneTime(true), CondenserCapErrIdx(0), adjustedTe(false) { } @@ -449,7 +450,7 @@ namespace HVACVariableRefrigerantFlow { void SizeVRFCondenser(EnergyPlusData &state); - void CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state); + void CalcVRFCondenser_FluidTCtrl(EnergyPlusData &state, const bool FirstHVACIteration); void CalcVRFIUTeTc_FluidTCtrl(EnergyPlusData &state); @@ -526,7 +527,8 @@ namespace HVACVariableRefrigerantFlow { Real64 MaxOutdoorUnitTc, // The maximum temperature that Tc can be at heating mode [C] Real64 &OUCondHeatRelease, // Condenser heat release (cooling mode) [W] Real64 &CompSpdActual, // Actual compressor running speed [rps] - Real64 &Ncomp // Compressor power [W] + Real64 &Ncomp, // Compressor power [W] + Real64 &CyclingRatio // Cycling Ratio [W] ); void diff --git a/src/EnergyPlus/HeatBalanceSurfaceManager.cc b/src/EnergyPlus/HeatBalanceSurfaceManager.cc index ebc34fb2388..3faf6e3dda9 100644 --- a/src/EnergyPlus/HeatBalanceSurfaceManager.cc +++ b/src/EnergyPlus/HeatBalanceSurfaceManager.cc @@ -87,6 +87,7 @@ #include #include #include +#include #include #include #include @@ -356,7 +357,7 @@ void InitSurfaceHeatBalance(EnergyPlusData &state) } } - // yujie: variable thermal solar absorptance overrides + // variable thermal solar absorptance overrides UpdateVariableAbsorptances(state); // Do the Begin Environment initializations @@ -5516,36 +5517,13 @@ void CalcThermalResilience(EnergyPlusData &state) // The heat index equation set is fit to Fahrenheit units, so the zone air temperature values are first convert to F, // then heat index is calculated and converted back to C. if (state.dataHeatBalSurfMgr->reportVarHeatIndex || state.dataOutRptTab->displayThermalResilienceSummary) { - // Constance for heat index regression equation of Rothfusz. - Real64 constexpr c1 = -42.379; - Real64 constexpr c2 = 2.04901523; - Real64 constexpr c3 = 10.14333127; - Real64 constexpr c4 = -.22475541; - Real64 constexpr c5 = -.00683783; - Real64 constexpr c6 = -.05481717; - Real64 constexpr c7 = .00122874; - Real64 constexpr c8 = .00085282; - Real64 constexpr c9 = -.00000199; for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV; Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg; - Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress) * 100.0; + Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress); Real64 const ZoneTF = ZoneT * (9.0 / 5.0) + 32.0; - Real64 HI; - - if (ZoneTF < 80) { - HI = 0.5 * (ZoneTF + 61.0 + (ZoneTF - 68.0) * 1.2 + (ZoneRH * 0.094)); - } else { - HI = c1 + c2 * ZoneTF + c3 * ZoneRH + c4 * ZoneTF * ZoneRH + c5 * ZoneTF * ZoneTF + c6 * ZoneRH * ZoneRH + - c7 * ZoneTF * ZoneTF * ZoneRH + c8 * ZoneTF * ZoneRH * ZoneRH + c9 * ZoneTF * ZoneTF * ZoneRH * ZoneRH; - if (ZoneRH < 13 && ZoneTF < 112) { - HI -= (13 - ZoneRH) / 4 * std::sqrt((17 - abs(ZoneTF - 95)) / 17); - } else if (ZoneRH > 85 && ZoneTF < 87) { - HI += (ZoneRH - 85) / 10 * (87 - ZoneTF) / 5; - } - } - HI = (HI - 32.0) * (5.0 / 9.0); - state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex = HI; + // calculate extended heat index + state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex = ExtendedHI::heatindex(state, ZoneT + Constant::Kelvin, ZoneRH) - Constant::Kelvin; } } if (state.dataHeatBalSurfMgr->reportVarHumidex || state.dataOutRptTab->displayThermalResilienceSummary) { diff --git a/src/EnergyPlus/HeatRecovery.cc b/src/EnergyPlus/HeatRecovery.cc index 687580fe2e5..7fcd2cf1432 100644 --- a/src/EnergyPlus/HeatRecovery.cc +++ b/src/EnergyPlus/HeatRecovery.cc @@ -517,7 +517,7 @@ namespace HeatRecovery { thisExchanger.EconoLockOut = static_cast(toggle); } - // yujie: read new curves here + // read new curves here thisExchanger.HeatEffectSensibleCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(11)); // convert curve name to number thisExchanger.HeatEffectLatentCurveIndex = diff --git a/src/EnergyPlus/PlantCentralGSHP.cc b/src/EnergyPlus/PlantCentralGSHP.cc index 8b8c4ba8332..64630dd0ea5 100644 --- a/src/EnergyPlus/PlantCentralGSHP.cc +++ b/src/EnergyPlus/PlantCentralGSHP.cc @@ -2361,11 +2361,14 @@ void WrapperSpecs::CalcChillerHeaterModel(EnergyPlusData &state) // Mode 3 and 5 use cooling side data stored from the chilled water loop // Mode 4 uses all data from the chilled water loop due to no heating demand - if (this->SimulClgDominant || CurrentMode == 3) { + // Fix for Defect #10065: When the heating load is dominant and the Current Mode is 3, + // simulation must go through the "heating" side to properly update the power consumption. + // Otherwise, the power consumption could come back zero for heating and cooling. + if (this->SimulClgDominant || (CurrentMode == 3 && !this->SimulHtgDominant)) { CurrentMode = 3; QCondenser = this->ChillerHeater(ChillerHeaterNum).Report.QCondSimul; - this->adjustChillerHeaterFlowTemp(state, QCondenser, CondMassFlowRate, CondOutletTemp, CondInletTemp, CondDeltaTemp); - } else { // Either Mode 2 or 3 or 5 + this->adjustChillerHeaterCondFlowTemp(state, QCondenser, CondMassFlowRate, CondOutletTemp, CondInletTemp, CondDeltaTemp); + } else { // Either Mode 2 or 3 (heating dominant) or 5 if (this->SimulHtgDominant) { CurrentMode = 5; } else { @@ -2456,6 +2459,7 @@ void WrapperSpecs::CalcChillerHeaterModel(EnergyPlusData &state) QCondenser = CHPower * this->ChillerHeater(ChillerHeaterNum).OpenMotorEff + QEvaporator + state.dataPlantCentralGSHP->ChillerFalseLoadRate; + Real64 qCondenserFullLoad = QCondenser; // Determine heating load for this heater and pass the remaining load to the next chiller heater Real64 CondenserCapMin = QCondenser * MinPartLoadRat; @@ -2470,11 +2474,32 @@ void WrapperSpecs::CalcChillerHeaterModel(EnergyPlusData &state) // then recalculate heating load this chiller heater can meet if (CurrentMode == 2 || this->SimulHtgDominant) { if (CondMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance && CondDeltaTemp > 0.0) { - this->adjustChillerHeaterFlowTemp(state, QCondenser, CondMassFlowRate, CondOutletTemp, CondInletTemp, CondDeltaTemp); + this->adjustChillerHeaterCondFlowTemp(state, QCondenser, CondMassFlowRate, CondOutletTemp, CondInletTemp, CondDeltaTemp); + if (qCondenserFullLoad > 0.0) { + Real64 constexpr diffTolerance = 0.0001; + if (((qCondenserFullLoad - QCondenser) / qCondenserFullLoad) > diffTolerance) { + // QCondenser was reduced, so reduce evaporator side quantities by a factor of the condenser based PLR + PartLoadRat = max(MinPartLoadRat, min((QCondenser / qCondenserFullLoad), MaxPartLoadRat)); + QCondenser = PartLoadRat * qCondenserFullLoad; + this->adjustChillerHeaterCondFlowTemp( + state, QCondenser, CondMassFlowRate, CondOutletTemp, CondInletTemp, CondDeltaTemp); + // In most situations here, QCondenser will not be reduced here, but it has to be taken into account. This will + // potentially violate the minPLR but this will keep the solution simple for now. + // So, basically multiply all terms in the energy balance by the same factor to maintain the energy balance. + Real64 modifiedPLR = QCondenser / qCondenserFullLoad; + QEvaporator *= modifiedPLR; + CHPower *= modifiedPLR; + PartLoadRat = modifiedPLR; + state.dataPlantCentralGSHP->ChillerFalseLoadRate *= modifiedPLR; + // Now re-adjust things on the evaporator side to get the correct flows/temperatures + this->adjustChillerHeaterEvapFlowTemp(state, QEvaporator, EvapMassFlowRate, EvapOutletTemp, EvapInletTemp); + } + } } else { QCondenser = 0.0; CondOutletTemp = CondInletTemp; } + state.dataPlantCentralGSHP->ChillerPartLoadRatio = PartLoadRat; } } // End of calculation depending on the modes @@ -2551,15 +2576,15 @@ void WrapperSpecs::CalcChillerHeaterModel(EnergyPlusData &state) } } -void WrapperSpecs::adjustChillerHeaterFlowTemp(EnergyPlusData &state, - Real64 &QCondenser, - Real64 &CondMassFlowRate, - Real64 &CondOutletTemp, - Real64 const CondInletTemp, - Real64 const CondDeltaTemp) +void WrapperSpecs::adjustChillerHeaterCondFlowTemp(EnergyPlusData &state, + Real64 &QCondenser, + Real64 &CondMassFlowRate, + Real64 &CondOutletTemp, + Real64 const CondInletTemp, + Real64 const CondDeltaTemp) { // Based on whether this is variable or constant flow, adjust either flow or outlet temperature and also the load - static constexpr std::string_view RoutineName("adjustChillerHeaterFlow"); + static constexpr std::string_view RoutineName("adjustChillerHeaterCondFlowTemp"); Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state, state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).FluidName, CondInletTemp, @@ -2587,6 +2612,34 @@ void WrapperSpecs::adjustChillerHeaterFlowTemp(EnergyPlusData &state, } } +void WrapperSpecs::adjustChillerHeaterEvapFlowTemp( + EnergyPlusData &state, Real64 const qEvaporator, Real64 &evapMassFlowRate, Real64 &evapOutletTemp, Real64 const evapInletTemp) +{ + // Adjust flow and outlet temperature for the evaporator side without modifying the heat transfer rate + Real64 constexpr lowLoad = 0.001; + static constexpr std::string_view routineName("adjustChillerHeaterEvapFlowTemp"); + Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state, + state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).FluidName, + evapInletTemp, + state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).FluidIndex, + routineName); + Real64 evapDeltaTemp = evapInletTemp - evapOutletTemp; + + if ((qEvaporator < lowLoad) || (evapDeltaTemp <= 0.0)) { + evapMassFlowRate = 0.0; + evapOutletTemp = evapInletTemp; + } else { + if (this->VariableFlowCH) { // for variable flow, adjust flow if higher than max value passed in + Real64 evapMassFlowRateCalc = qEvaporator / evapDeltaTemp / Cp; + if (evapMassFlowRateCalc > evapMassFlowRate) evapMassFlowRateCalc = evapMassFlowRate; + evapMassFlowRate = evapMassFlowRateCalc; + } + // Adjust temperature for either flow type to maintain agreement with qEvaporator + evapDeltaTemp = qEvaporator / evapMassFlowRate / Cp; + evapOutletTemp = evapInletTemp - evapDeltaTemp; + } +} + Real64 WrapperSpecs::setChillerHeaterCondTemp(EnergyPlusData &state, int const numChillerHeater, Real64 const condEnteringTemp, Real64 const condLeavingTemp) { @@ -2636,7 +2689,7 @@ void WrapperSpecs::checkEvapOutletTemp(EnergyPlusData &state, Real64 const lowTempLimitEout, Real64 const evapInletTemp, Real64 &qEvaporator, - Real64 &evapMassFlowRate, + Real64 const evapMassFlowRate, Real64 const Cp) { // Check evaporator temperature low limit and adjust capacity if needed @@ -2653,10 +2706,9 @@ void WrapperSpecs::checkEvapOutletTemp(EnergyPlusData &state, // Check if the outlet temperature exceeds the node minimum temperature and adjust capacity if needed if (evapOutletTemp < this->ChillerHeater(numChillerHeater).EvapOutletNode.TempMin) { - if ((this->ChillerHeater(numChillerHeater).EvapInletNode.Temp - this->ChillerHeater(numChillerHeater).EvapOutletNode.TempMin) > - DataPlant::DeltaTempTol) { + if ((evapInletTemp - this->ChillerHeater(numChillerHeater).EvapOutletNode.TempMin) > DataPlant::DeltaTempTol) { evapOutletTemp = this->ChillerHeater(numChillerHeater).EvapOutletNode.TempMin; - Real64 evapDeltaTemp = this->ChillerHeater(numChillerHeater).EvapOutletNode.TempMin - evapOutletTemp; + Real64 evapDeltaTemp = evapInletTemp - evapOutletTemp; qEvaporator = evapMassFlowRate * Cp * evapDeltaTemp; } else { qEvaporator = 0.0; @@ -2674,24 +2726,22 @@ void WrapperSpecs::calcPLRAndCyclingRatio(EnergyPlusData &state, Real64 &frac) { // Calculate PLR (actualPartLoadRatio) based on evaporator load and available capacity, factoring in max PLR - if (availChillerCap > 0.0) { - actualPartLoadRatio = max(0.0, min((qEvaporator / availChillerCap), maxPartLoadRatio)); + if (availChillerCap <= 0.0) { + actualPartLoadRatio = 0; + frac = 1.0; } else { - actualPartLoadRatio = 0.0; + actualPartLoadRatio = max(0.0, min((qEvaporator / availChillerCap), maxPartLoadRatio)); + // If chiller cycles below minimum part load ratio, frac = amount of time chiller is ON during this time step + if (minPartLoadRatio > 0.0) { + frac = min(1.0, (actualPartLoadRatio / minPartLoadRatio)); + } else { + frac = 1.0; + } + actualPartLoadRatio = max(actualPartLoadRatio, minPartLoadRatio); } - // Chiller cycles below minimum part load ratio, frac = amount of time chiller is ON during this time step - if (actualPartLoadRatio < minPartLoadRatio) frac = min(1.0, (actualPartLoadRatio / minPartLoadRatio)); - if (frac <= 0.0) frac = 1.0; // CR 9303 COP reporting issue, it should be greater than zero in this routine state.dataPlantCentralGSHP->ChillerCyclingRatio = frac; - // Chiller is false loading below PLR = minimum unloading ratio, find PLR used for energy calculation - if (availChillerCap > 0.0) { - actualPartLoadRatio = max(actualPartLoadRatio, minPartLoadRatio); - } else { - actualPartLoadRatio = 0.0; - } - // Evaporator part load ratio state.dataPlantCentralGSHP->ChillerPartLoadRatio = actualPartLoadRatio; diff --git a/src/EnergyPlus/PlantCentralGSHP.hh b/src/EnergyPlus/PlantCentralGSHP.hh index 1744470956f..f359393f1ec 100644 --- a/src/EnergyPlus/PlantCentralGSHP.hh +++ b/src/EnergyPlus/PlantCentralGSHP.hh @@ -415,12 +415,15 @@ namespace PlantCentralGSHP { void CalcChillerHeaterModel(EnergyPlusData &state); - void adjustChillerHeaterFlowTemp(EnergyPlusData &state, - Real64 &QCondenser, - Real64 &CondMassFlowRate, - Real64 &CondOutletTemp, - Real64 const CondInletTemp, - Real64 const CondDeltaTemp); + void adjustChillerHeaterCondFlowTemp(EnergyPlusData &state, + Real64 &QCondenser, + Real64 &CondMassFlowRate, + Real64 &CondOutletTemp, + Real64 const CondInletTemp, + Real64 const CondDeltaTemp); + + void adjustChillerHeaterEvapFlowTemp( + EnergyPlusData &state, Real64 const qEvaporator, Real64 &evapMassFlowRate, Real64 &evapOutletTemp, Real64 const evapInletTemp); Real64 setChillerHeaterCondTemp(EnergyPlusData &state, int const numChillerHeater, Real64 const condEnteringTemp, Real64 const condLeavingTemp); @@ -433,7 +436,7 @@ namespace PlantCentralGSHP { Real64 const lowTempLimitEout, Real64 evapInletTemp, Real64 &qEvaporator, - Real64 &evapMassFlowRate, + Real64 const evapMassFlowRate, Real64 const Cp); void calcPLRAndCyclingRatio(EnergyPlusData &state, diff --git a/src/EnergyPlus/PurchasedAirManager.cc b/src/EnergyPlus/PurchasedAirManager.cc index 3fd4bf0c89d..af26373459a 100644 --- a/src/EnergyPlus/PurchasedAirManager.cc +++ b/src/EnergyPlus/PurchasedAirManager.cc @@ -213,16 +213,8 @@ void GetPurchasedAir(EnergyPlusData &state) using ZonePlenum::GetReturnPlenumIndex; // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int PurchAirNum; - int NumAlphas; - int NumNums; - int IOStat; - int CtrlZone; // zone index - int NodeNum; // node index static constexpr std::string_view RoutineName("GetPurchasedAir: "); // include trailing blank space bool ErrorsFound(false); // If errors detected in input - bool IsOANodeListed; // Flag for OA node name listed in OutdoorAir:Node or Nodelist - bool UniqueNodeError; // Flag for non-unique node error(s) auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject; cCurrentModuleObject = "ZoneHVAC:IdealLoadsAirSystem"; @@ -236,8 +228,11 @@ void GetPurchasedAir(EnergyPlusData &state) state.dataPurchasedAirMgr->CheckEquipName = true; if (state.dataPurchasedAirMgr->NumPurchAir > 0) { + int NumAlphas; + int NumNums; + int IOStat; InitUniqueNodeCheck(state, cCurrentModuleObject); - for (PurchAirNum = 1; PurchAirNum <= state.dataPurchasedAirMgr->NumPurchAir; ++PurchAirNum) { + for (int PurchAirNum = 1; PurchAirNum <= state.dataPurchasedAirMgr->NumPurchAir; ++PurchAirNum) { PurchAir(PurchAirNum).cObjectName = cCurrentModuleObject; state.dataInputProcessing->inputProcessor->getObjectItem(state, @@ -283,7 +278,7 @@ void GetPurchasedAir(EnergyPlusData &state) DataLoopNode::ConnectionType::Outlet, NodeInputManager::CompFluidStream::Primary, ObjectIsNotParent); - UniqueNodeError = false; + bool UniqueNodeError = false; CheckUniqueNodeNames(state, state.dataIPShortCut->cAlphaFieldNames(3), UniqueNodeError, @@ -509,6 +504,7 @@ void GetPurchasedAir(EnergyPlusData &state) NodeInputManager::CompFluidStream::Primary, ObjectIsNotParent); // Check if OA node is initialized in OutdoorAir:Node or OutdoorAir:Nodelist + bool IsOANodeListed; // Flag for OA node name listed in OutdoorAir:Node or Nodelist CheckAndAddAirNodeNumber(state, PurchAir(PurchAirNum).OutdoorAirNodeNum, IsOANodeListed); if ((!IsOANodeListed) && state.dataGlobal->DisplayExtraWarnings) { ShowWarningError(state, format("{}{}=\"{} missing data", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1))); @@ -590,9 +586,9 @@ void GetPurchasedAir(EnergyPlusData &state) PurchAir(PurchAirNum).HtRecSenEff = state.dataIPShortCut->rNumericArgs(10); PurchAir(PurchAirNum).HtRecLatEff = state.dataIPShortCut->rNumericArgs(11); - for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) { + for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) { if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue; - for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) { + for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) { if (PurchAir(PurchAirNum).ZoneSupplyAirNodeNum == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) { PurchAir(PurchAirNum).ZonePtr = CtrlZone; } @@ -670,7 +666,7 @@ void GetPurchasedAir(EnergyPlusData &state) EndUniqueNodeCheck(state, cCurrentModuleObject); } - for (PurchAirNum = 1; PurchAirNum <= state.dataPurchasedAirMgr->NumPurchAir; ++PurchAirNum) { + for (int PurchAirNum = 1; PurchAirNum <= state.dataPurchasedAirMgr->NumPurchAir; ++PurchAirNum) { // Setup Output variables // energy variables @@ -1160,16 +1156,7 @@ void InitPurchasedAir(EnergyPlusData &state, int const PurchAirNum, int const Co using ZonePlenum::GetReturnPlenumName; // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int Loop; - bool UnitOn; // simple checks for error - bool CoolOn; // simple checks for error - bool HeatOn; // simple checks for error - int SupplyNodeNum; // Node number for ideal loads supply node - int ExhaustNodeNum; // Node number for ideal loads exhaust node - int NodeIndex; // Array index of zone inlet or zone exhaust node that matches ideal loads node - bool UseReturnNode; // simple checks for error - - auto &PurchAir(state.dataPurchasedAirMgr->PurchAir); + bool UnitOn; // simple checks for error // Do the Begin Simulation initializations if (state.dataPurchasedAirMgr->InitPurchasedAirMyOneTimeFlag) { @@ -1185,43 +1172,45 @@ void InitPurchasedAir(EnergyPlusData &state, int const PurchAirNum, int const Co // need to check all units to see if they are on Zone Equipment List or issue warning if (!state.dataPurchasedAirMgr->InitPurchasedAirZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) { state.dataPurchasedAirMgr->InitPurchasedAirZoneEquipmentListChecked = true; - for (Loop = 1; Loop <= state.dataPurchasedAirMgr->NumPurchAir; ++Loop) { + for (int Loop = 1; Loop <= state.dataPurchasedAirMgr->NumPurchAir; ++Loop) { + auto &PurchAirLoop = state.dataPurchasedAirMgr->PurchAir(Loop); // link with return plenum if used (i.e., PlenumExhaustAirNodeNum will be non-zero) - if (PurchAir(Loop).PlenumExhaustAirNodeNum > 0) { - PurchAir(Loop).ReturnPlenumIndex = GetReturnPlenumIndex(state, PurchAir(Loop).PlenumExhaustAirNodeNum); - if (PurchAir(Loop).ReturnPlenumIndex > 0) { - GetReturnPlenumName(state, PurchAir(Loop).ReturnPlenumIndex, PurchAir(Loop).ReturnPlenumName); + if (PurchAirLoop.PlenumExhaustAirNodeNum > 0) { + PurchAirLoop.ReturnPlenumIndex = GetReturnPlenumIndex(state, PurchAirLoop.PlenumExhaustAirNodeNum); + if (PurchAirLoop.ReturnPlenumIndex > 0) { + GetReturnPlenumName(state, PurchAirLoop.ReturnPlenumIndex, PurchAirLoop.ReturnPlenumName); InitializePlenumArrays(state, Loop); } else { ShowSevereError(state, format("InitPurchasedAir: {} = {} cannot find ZoneHVAC:ReturnPlenum. It will not be simulated.", - PurchAir(Loop).cObjectName, - PurchAir(Loop).Name)); + PurchAirLoop.cObjectName, + PurchAirLoop.Name)); } } - if (CheckZoneEquipmentList(state, PurchAir(Loop).cObjectName, PurchAir(Loop).Name)) continue; + if (CheckZoneEquipmentList(state, PurchAirLoop.cObjectName, PurchAirLoop.Name)) continue; ShowSevereError(state, format("InitPurchasedAir: {} = {} is not on any ZoneHVAC:EquipmentList. It will not be simulated.", - PurchAir(Loop).cObjectName, - PurchAir(Loop).Name)); + PurchAirLoop.cObjectName, + PurchAirLoop.Name)); } } + auto &PurchAir = state.dataPurchasedAirMgr->PurchAir(PurchAirNum); // one time inits for each unit - links PurchAirNum with static input data from ControlledZoneNum and ActualZoneNum if (!state.dataPurchasedAirMgr->InitPurchasedAirOneTimeUnitInitsDone(PurchAirNum)) { state.dataPurchasedAirMgr->InitPurchasedAirOneTimeUnitInitsDone(PurchAirNum) = true; // Is the supply node really a zone inlet node? // this check has to be done here because of SimPurchasedAir passing in ControlledZoneNum - SupplyNodeNum = PurchAir(PurchAirNum).ZoneSupplyAirNodeNum; + int SupplyNodeNum = PurchAir.ZoneSupplyAirNodeNum; if (SupplyNodeNum > 0) { - NodeIndex = FindNumberInList(SupplyNodeNum, - state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode, - state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes); + int NodeIndex = FindNumberInList(SupplyNodeNum, + state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode, + state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes); if (NodeIndex == 0) { - ShowSevereError(state, format("InitPurchasedAir: In {} = {}", PurchAir(PurchAirNum).cObjectName, PurchAir(PurchAirNum).Name)); + ShowSevereError(state, format("InitPurchasedAir: In {} = {}", PurchAir.cObjectName, PurchAir.Name)); ShowContinueError(state, format("Zone Supply Air Node Name={} is not a zone inlet node.", state.dataLoopNodes->NodeID(SupplyNodeNum))); ShowContinueError( @@ -1234,14 +1223,14 @@ void InitPurchasedAir(EnergyPlusData &state, int const PurchAirNum, int const Co // Set recirculation node number // If exhaust node is specified, then recirculation is exhaust node, otherwise use zone return node // this check has to be done here because of SimPurchasedAir passing in ControlledZoneNum - UseReturnNode = false; - if (PurchAir(PurchAirNum).ZoneExhaustAirNodeNum > 0) { - ExhaustNodeNum = PurchAir(PurchAirNum).ZoneExhaustAirNodeNum; - NodeIndex = FindNumberInList(ExhaustNodeNum, - state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode, - state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumExhaustNodes); + bool UseReturnNode = false; + if (PurchAir.ZoneExhaustAirNodeNum > 0) { + int ExhaustNodeNum = PurchAir.ZoneExhaustAirNodeNum; + int NodeIndex = FindNumberInList(ExhaustNodeNum, + state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode, + state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumExhaustNodes); if (NodeIndex == 0) { - ShowSevereError(state, format("InitPurchasedAir: In {} = {}", PurchAir(PurchAirNum).cObjectName, PurchAir(PurchAirNum).Name)); + ShowSevereError(state, format("InitPurchasedAir: In {} = {}", PurchAir.cObjectName, PurchAir.Name)); ShowContinueError(state, format("Zone Exhaust Air Node Name={} is not a zone exhaust node.", state.dataLoopNodes->NodeID(ExhaustNodeNum))); ShowContinueError( @@ -1250,23 +1239,23 @@ void InitPurchasedAir(EnergyPlusData &state, int const PurchAirNum, int const Co ShowContinueError(state, "Zone return air node will be used for ideal loads recirculation air."); UseReturnNode = true; } else { - PurchAir(PurchAirNum).ZoneRecircAirNodeNum = PurchAir(PurchAirNum).ZoneExhaustAirNodeNum; + PurchAir.ZoneRecircAirNodeNum = PurchAir.ZoneExhaustAirNodeNum; } } else { UseReturnNode = true; } if (UseReturnNode) { if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumReturnNodes == 1) { - PurchAir(PurchAirNum).ZoneRecircAirNodeNum = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNode(1); + PurchAir.ZoneRecircAirNodeNum = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNode(1); } else if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumReturnNodes > 1) { - ShowWarningError(state, format("InitPurchasedAir: In {} = {}", PurchAir(PurchAirNum).cObjectName, PurchAir(PurchAirNum).Name)); + ShowWarningError(state, format("InitPurchasedAir: In {} = {}", PurchAir.cObjectName, PurchAir.Name)); ShowContinueError(state, "No Zone Exhaust Air Node Name has been specified for this system and the zone has more than one Return Air Node."); ShowContinueError(state, format("Using the first return air node ={}", state.dataLoopNodes->NodeID(state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNode(1)))); } else { - ShowFatalError(state, format("InitPurchasedAir: In {} = {}", PurchAir(PurchAirNum).cObjectName, PurchAir(PurchAirNum).Name)); + ShowFatalError(state, format("InitPurchasedAir: In {} = {}", PurchAir.cObjectName, PurchAir.Name)); ShowContinueError( state, " Invalid recirculation node. No exhaust or return node has been specified for this zone in ZoneHVAC:EquipmentConnections."); @@ -1274,9 +1263,9 @@ void InitPurchasedAir(EnergyPlusData &state, int const PurchAirNum, int const Co } } // If there is OA and economizer is active, then there must be a limit on cooling flow rate - if (PurchAir(PurchAirNum).OutdoorAir && (PurchAir(PurchAirNum).EconomizerType != Econ::NoEconomizer)) { - if ((PurchAir(PurchAirNum).CoolingLimit == LimitType::NoLimit) || (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitCapacity)) { - ShowSevereError(state, format("InitPurchasedAir: In {} = {}", PurchAir(PurchAirNum).cObjectName, PurchAir(PurchAirNum).Name)); + if (PurchAir.OutdoorAir && (PurchAir.EconomizerType != Econ::NoEconomizer)) { + if ((PurchAir.CoolingLimit == LimitType::NoLimit) || (PurchAir.CoolingLimit == LimitType::LimitCapacity)) { + ShowSevereError(state, format("InitPurchasedAir: In {} = {}", PurchAir.cObjectName, PurchAir.Name)); ShowContinueError(state, "There is outdoor air with economizer active but there is no limit on cooling air flow rate."); ShowContinueError(state, "Cooling Limit must be set to LimitFlowRate or LimitFlowRateAndCapacity, and Maximum Cooling Air Flow Rate " @@ -1296,17 +1285,15 @@ void InitPurchasedAir(EnergyPlusData &state, int const PurchAirNum, int const Co // Do the Begin Environment initializations if (state.dataGlobal->BeginEnvrnFlag && state.dataPurchasedAirMgr->InitPurchasedAirMyEnvrnFlag(PurchAirNum)) { - if ((PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRateAndCapacity)) { - PurchAir(PurchAirNum).MaxHeatMassFlowRate = state.dataEnvrn->StdRhoAir * PurchAir(PurchAirNum).MaxHeatVolFlowRate; + if ((PurchAir.HeatingLimit == LimitType::LimitFlowRate) || (PurchAir.HeatingLimit == LimitType::LimitFlowRateAndCapacity)) { + PurchAir.MaxHeatMassFlowRate = state.dataEnvrn->StdRhoAir * PurchAir.MaxHeatVolFlowRate; } else { - PurchAir(PurchAirNum).MaxHeatMassFlowRate = 0.0; + PurchAir.MaxHeatMassFlowRate = 0.0; } - if ((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity)) { - PurchAir(PurchAirNum).MaxCoolMassFlowRate = state.dataEnvrn->StdRhoAir * PurchAir(PurchAirNum).MaxCoolVolFlowRate; + if ((PurchAir.CoolingLimit == LimitType::LimitFlowRate) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity)) { + PurchAir.MaxCoolMassFlowRate = state.dataEnvrn->StdRhoAir * PurchAir.MaxCoolVolFlowRate; } else { - PurchAir(PurchAirNum).MaxCoolMassFlowRate = 0.0; + PurchAir.MaxCoolMassFlowRate = 0.0; } state.dataPurchasedAirMgr->InitPurchasedAirMyEnvrnFlag(PurchAirNum) = false; } @@ -1317,95 +1304,95 @@ void InitPurchasedAir(EnergyPlusData &state, int const PurchAirNum, int const Co // These initializations are done every iteration // check that supply air temps can meet the zone thermostat setpoints - if (PurchAir(PurchAirNum).MinCoolSuppAirTemp > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ControlledZoneNum) && - state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ControlledZoneNum) != 0 && PurchAir(PurchAirNum).CoolingLimit == LimitType::NoLimit) { + if (PurchAir.MinCoolSuppAirTemp > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ControlledZoneNum) && + state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ControlledZoneNum) != 0 && PurchAir.CoolingLimit == LimitType::NoLimit) { // Check if the unit is scheduled off UnitOn = true; - // IF (PurchAir(PurchAirNum)%AvailSchedPtr > 0) THEN - if (GetCurrentScheduleValue(state, PurchAir(PurchAirNum).AvailSchedPtr) <= 0) { + // IF (PurchAir%AvailSchedPtr > 0) THEN + if (GetCurrentScheduleValue(state, PurchAir.AvailSchedPtr) <= 0) { UnitOn = false; } // END IF // Check if cooling available - CoolOn = true; - // IF (PurchAir(PurchAirNum)%CoolSchedPtr > 0) THEN - if (GetCurrentScheduleValue(state, PurchAir(PurchAirNum).CoolSchedPtr) <= 0) { + bool CoolOn = true; + // IF (PurchAir%CoolSchedPtr > 0) THEN + if (GetCurrentScheduleValue(state, PurchAir.CoolSchedPtr) <= 0) { CoolOn = false; } // END IF if (UnitOn && CoolOn) { - if (PurchAir(PurchAirNum).CoolErrIndex == 0) { + if (PurchAir.CoolErrIndex == 0) { ShowSevereError(state, format("InitPurchasedAir: For {} = {} serving Zone {}", - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, + PurchAir.cObjectName, + PurchAir.Name, state.dataHeatBal->Zone(ControlledZoneNum).Name)); ShowContinueError(state, format("..the minimum supply air temperature for cooling [{:.2R}] is greater than the zone cooling mean air " "temperature (MAT) setpoint [{:.2R}].", - PurchAir(PurchAirNum).MinCoolSuppAirTemp, + PurchAir.MinCoolSuppAirTemp, state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ControlledZoneNum))); ShowContinueError(state, "..For operative and comfort thermostat controls, the MAT setpoint is computed."); ShowContinueError(state, "..This error may indicate that the mean radiant temperature or another comfort factor is too warm."); ShowContinueError(state, "Unit availability is nominally ON and Cooling availability is nominally ON."); - ShowContinueError(state, format("Limit Cooling Capacity Type={}", cLimitType(PurchAir(PurchAirNum).CoolingLimit))); + ShowContinueError(state, format("Limit Cooling Capacity Type={}", cLimitType(PurchAir.CoolingLimit))); // could check for optemp control or comfort control here ShowContinueErrorTimeStamp(state, ""); } ShowRecurringSevereErrorAtEnd(state, - "InitPurchasedAir: For " + PurchAir(PurchAirNum).cObjectName + " = " + PurchAir(PurchAirNum).Name + - " serving Zone " + state.dataHeatBal->Zone(ControlledZoneNum).Name + + "InitPurchasedAir: For " + PurchAir.cObjectName + " = " + PurchAir.Name + " serving Zone " + + state.dataHeatBal->Zone(ControlledZoneNum).Name + ", the minimum supply air temperature for cooling error continues", - PurchAir(PurchAirNum).CoolErrIndex, - PurchAir(PurchAirNum).MinCoolSuppAirTemp, - PurchAir(PurchAirNum).MinCoolSuppAirTemp, + PurchAir.CoolErrIndex, + PurchAir.MinCoolSuppAirTemp, + PurchAir.MinCoolSuppAirTemp, _, "C", "C"); } } - if (PurchAir(PurchAirNum).MaxHeatSuppAirTemp < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ControlledZoneNum) && - state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ControlledZoneNum) != 0 && PurchAir(PurchAirNum).HeatingLimit == LimitType::NoLimit) { + if (PurchAir.MaxHeatSuppAirTemp < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ControlledZoneNum) && + state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ControlledZoneNum) != 0 && PurchAir.HeatingLimit == LimitType::NoLimit) { // Check if the unit is scheduled off UnitOn = true; - // IF (PurchAir(PurchAirNum)%AvailSchedPtr > 0) THEN - if (GetCurrentScheduleValue(state, PurchAir(PurchAirNum).AvailSchedPtr) <= 0) { + // IF (PurchAir%AvailSchedPtr > 0) THEN + if (GetCurrentScheduleValue(state, PurchAir.AvailSchedPtr) <= 0) { UnitOn = false; } // END IF // Check if heating and cooling available - HeatOn = true; - // IF (PurchAir(PurchAirNum)%HeatSchedPtr > 0) THEN - if (GetCurrentScheduleValue(state, PurchAir(PurchAirNum).HeatSchedPtr) <= 0) { + bool HeatOn = true; + // IF (PurchAir%HeatSchedPtr > 0) THEN + if (GetCurrentScheduleValue(state, PurchAir.HeatSchedPtr) <= 0) { HeatOn = false; } // END IF if (UnitOn && HeatOn) { - if (PurchAir(PurchAirNum).HeatErrIndex == 0) { + if (PurchAir.HeatErrIndex == 0) { ShowSevereMessage(state, format("InitPurchasedAir: For {} = {} serving Zone {}", - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, + PurchAir.cObjectName, + PurchAir.Name, state.dataHeatBal->Zone(ControlledZoneNum).Name)); ShowContinueError(state, format("..the maximum supply air temperature for heating [{:.2R}] is less than the zone mean air temperature " "heating setpoint [{:.2R}].", - PurchAir(PurchAirNum).MaxHeatSuppAirTemp, + PurchAir.MaxHeatSuppAirTemp, state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ControlledZoneNum))); ShowContinueError(state, "..For operative and comfort thermostat controls, the MAT setpoint is computed."); ShowContinueError(state, "..This error may indicate that the mean radiant temperature or another comfort factor is too cold."); ShowContinueError(state, "Unit availability is nominally ON and Heating availability is nominally ON."); - ShowContinueError(state, format("Limit Heating Capacity Type={}", cLimitType(PurchAir(PurchAirNum).HeatingLimit))); + ShowContinueError(state, format("Limit Heating Capacity Type={}", cLimitType(PurchAir.HeatingLimit))); // could check for optemp control or comfort control here ShowContinueErrorTimeStamp(state, ""); } ShowRecurringSevereErrorAtEnd(state, - "InitPurchasedAir: For " + PurchAir(PurchAirNum).cObjectName + " = " + PurchAir(PurchAirNum).Name + - " serving Zone " + state.dataHeatBal->Zone(ControlledZoneNum).Name + + "InitPurchasedAir: For " + PurchAir.cObjectName + " = " + PurchAir.Name + " serving Zone " + + state.dataHeatBal->Zone(ControlledZoneNum).Name + ", maximum supply air temperature for heating error continues", - PurchAir(PurchAirNum).HeatErrIndex, - PurchAir(PurchAirNum).MaxHeatSuppAirTemp, - PurchAir(PurchAirNum).MaxHeatSuppAirTemp, + PurchAir.HeatErrIndex, + PurchAir.MaxHeatSuppAirTemp, + PurchAir.MaxHeatSuppAirTemp, _, "C", "C"); @@ -1448,35 +1435,23 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) static constexpr std::string_view RoutineName("SizePurchasedAir: "); // include trailing blank space // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - bool IsAutoSize; // Indicator to autosize - Real64 MaxHeatVolFlowRateDes; // Autosized maximum heating air flow for reporting - Real64 MaxHeatVolFlowRateUser; // Hardsized maximum heating air flow for reporting - Real64 MaxCoolVolFlowRateDes; // Autosized maximum cooling air flow for reporting - Real64 MaxCoolVolFlowRateUser; // Hardsized maximum cooling air flow for reporting - Real64 MaxHeatSensCapDes; // Autosized maximum sensible heating capacity for reporting - Real64 MaxHeatSensCapUser; // Hardsized maximum sensible heating capacity for reporting - Real64 MaxCoolTotCapDes; // Autosized maximum sensible cooling capacity for reporting - Real64 MaxCoolTotCapUser; // Hardsized maximum sensible cooling capacity for reporting - std::string CompName; // component name - std::string CompType; // component type - std::string SizingString; // input field sizing description (e.g., Nominal Capacity) - Real64 TempSize; // autosized value of coil input field - int FieldNum = 2; // IDD numeric field number where input field description is found - int SizingMethod; // Integer representation of sizing method name (e.g., CoolingAirflowSizing, HeatingAirflowSizing, CoolingCapacitySizing, - // HeatingCapacitySizing, etc.) - bool PrintFlag; // TRUE when sizing information is reported in the eio file - int zoneHVACIndex; // index of zoneHVAC equipment sizing specification - int SAFMethod(0); // supply air flow rate sizing method (SupplyAirFlowRate, FlowPerFloorArea, FractionOfAutosizedCoolingAirflow, - // FractionOfAutosizedHeatingAirflow ...) - int CapSizingMethod(0); // capacity sizing methods (HeatingDesignCapacity, CapacityPerFloorArea, FractionOfAutosizedCoolingCapacity, and - // FractionOfAutosizedHeatingCapacity ) + Real64 MaxHeatVolFlowRateDes; // Autosized maximum heating air flow for reporting + Real64 MaxHeatVolFlowRateUser; // Hardsized maximum heating air flow for reporting + Real64 MaxCoolVolFlowRateDes; // Autosized maximum cooling air flow for reporting + Real64 MaxCoolVolFlowRateUser; // Hardsized maximum cooling air flow for reporting + Real64 MaxHeatSensCapDes; // Autosized maximum sensible heating capacity for reporting + Real64 MaxHeatSensCapUser; // Hardsized maximum sensible heating capacity for reporting + Real64 MaxCoolTotCapDes; // Autosized maximum sensible cooling capacity for reporting + Real64 MaxCoolTotCapUser; // Hardsized maximum sensible cooling capacity for reporting + std::string CompName; // component name + std::string CompType; // component type + Real64 TempSize; // autosized value of coil input field + // FractionOfAutosizedHeatingCapacity ) Real64 CoolingAirVolFlowDes(0.0); // cooling supply air flow rate Real64 HeatingAirVolFlowDes(0.0); // heating supply air flow rate - auto &PurchAir(state.dataPurchasedAirMgr->PurchAir); - auto &ZoneEqSizing(state.dataSize->ZoneEqSizing); + auto &PurchAir = state.dataPurchasedAirMgr->PurchAir(PurchAirNum); - IsAutoSize = false; MaxHeatVolFlowRateDes = 0.0; MaxHeatVolFlowRateUser = 0.0; MaxCoolVolFlowRateDes = 0.0; @@ -1488,14 +1463,23 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) state.dataSize->ZoneHeatingOnlyFan = false; state.dataSize->ZoneCoolingOnlyFan = false; - CompType = PurchAir(PurchAirNum).cObjectName; - CompName = PurchAir(PurchAirNum).Name; - bool ErrorsFound = false; + CompType = PurchAir.cObjectName; + CompName = PurchAir.Name; if (state.dataSize->CurZoneEqNum > 0) { - if (PurchAir(PurchAirNum).HVACSizingIndex > 0) { - state.dataSize->DataZoneNumber = PurchAir(PurchAirNum).ZonePtr; - zoneHVACIndex = PurchAir(PurchAirNum).HVACSizingIndex; + auto &ZoneEqSizing = state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum); + std::string SizingString; // input field sizing description (e.g., Nominal Capacity) + int FieldNum; // IDD numeric field number where input field description is found + bool PrintFlag; // TRUE when sizing information is reported in the eio file + bool ErrorsFound = false; + if (PurchAir.HVACSizingIndex > 0) { + state.dataSize->DataZoneNumber = PurchAir.ZonePtr; + int zoneHVACIndex = PurchAir.HVACSizingIndex; + int SAFMethod; // supply air flow rate sizing method (SupplyAirFlowRate, FlowPerFloorArea, FractionOfAutosizedCoolingAirflow, + // FractionOfAutosizedHeatingAirflow, HeatingCapacitySizing, etc.) + int CapSizingMethod; // capacity sizing methods (HeatingDesignCapacity, CapacityPerFloorArea, FractionOfAutosizedCoolingCapacity, and + int SizingMethod; // Integer representation of sizing method name (e.g., CoolingAirflowSizing, HeatingAirflowSizing, + // CoolingCapacitySizing) FieldNum = 5; // N5 , \field Maximum Heating Air Flow Rate PrintFlag = true; @@ -1504,12 +1488,11 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) SizingMethod = HeatingAirflowSizing; state.dataSize->ZoneHeatingOnlyFan = true; SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingSAFMethod; - ZoneEqSizing(state.dataSize->CurZoneEqNum).SizingMethod(SizingMethod) = SAFMethod; + ZoneEqSizing.SizingMethod(SizingMethod) = SAFMethod; if (SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea || SAFMethod == FractionOfAutosizedHeatingAirflow) { if (SAFMethod == SupplyAirFlowRate) { if ((state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow == AutoSize) && - ((PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRateAndCapacity))) { + ((PurchAir.HeatingLimit == LimitType::LimitFlowRate) || (PurchAir.HeatingLimit == LimitType::LimitFlowRateAndCapacity))) { TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow; HeatingAirFlowSizer sizingHeatingAirFlow; sizingHeatingAirFlow.overrideSizingString(SizingString); @@ -1527,10 +1510,10 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) } } } else if (SAFMethod == FlowPerFloorArea) { - ZoneEqSizing(state.dataSize->CurZoneEqNum).SystemAirFlow = true; - ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow * - state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea; - TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow; + ZoneEqSizing.SystemAirFlow = true; + ZoneEqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow * + state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea; + TempSize = ZoneEqSizing.AirVolFlow; state.dataSize->DataScalableSizingON = true; HeatingAirFlowSizer sizingHeatingAirFlow; sizingHeatingAirFlow.overrideSizingString(SizingString); @@ -1540,8 +1523,7 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) } else if (SAFMethod == FractionOfAutosizedHeatingAirflow) { state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow; if ((state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow == AutoSize) && - ((PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRateAndCapacity))) { + ((PurchAir.HeatingLimit == LimitType::LimitFlowRate) || (PurchAir.HeatingLimit == LimitType::LimitFlowRateAndCapacity))) { TempSize = AutoSize; state.dataSize->DataScalableSizingON = true; HeatingAirFlowSizer sizingHeatingAirFlow; @@ -1559,8 +1541,7 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) TempSize = AutoSize; PrintFlag = false; if ((state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow == AutoSize) && - ((PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRateAndCapacity))) { + ((PurchAir.HeatingLimit == LimitType::LimitFlowRate) || (PurchAir.HeatingLimit == LimitType::LimitFlowRateAndCapacity))) { TempSize = AutoSize; state.dataSize->DataScalableSizingON = true; HeatingCapacitySizer sizerHeatingCapacity; @@ -1579,25 +1560,23 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) } } MaxHeatVolFlowRateDes = max(0.0, HeatingAirVolFlowDes); - PurchAir(PurchAirNum).MaxHeatVolFlowRate = MaxHeatVolFlowRateDes; + PurchAir.MaxHeatVolFlowRate = MaxHeatVolFlowRateDes; state.dataSize->ZoneHeatingOnlyFan = false; CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod; - ZoneEqSizing(state.dataSize->CurZoneEqNum).CapSizingMethod = CapSizingMethod; + ZoneEqSizing.CapSizingMethod = CapSizingMethod; if (CapSizingMethod == HeatingDesignCapacity || CapSizingMethod == CapacityPerFloorArea || CapSizingMethod == FractionOfAutosizedHeatingCapacity) { if (CapSizingMethod == HeatingDesignCapacity) { if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity > 0.0) { - ZoneEqSizing(state.dataSize->CurZoneEqNum).HeatingCapacity = true; - ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad = - state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity; + ZoneEqSizing.HeatingCapacity = true; + ZoneEqSizing.DesHeatingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity; } TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity; } else if (CapSizingMethod == CapacityPerFloorArea) { - ZoneEqSizing(state.dataSize->CurZoneEqNum).HeatingCapacity = true; - ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad = - state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity * - state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea; + ZoneEqSizing.HeatingCapacity = true; + ZoneEqSizing.DesHeatingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity * + state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea; state.dataSize->DataScalableSizingON = true; } else if (CapSizingMethod == FractionOfAutosizedHeatingCapacity) { state.dataSize->DataFracOfAutosizedHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity; @@ -1616,46 +1595,25 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) if (MaxHeatSensCapDes < HVAC::SmallLoad) { MaxHeatSensCapDes = 0.0; } - if (IsAutoSize) { - PurchAir(PurchAirNum).MaxHeatSensCap = MaxHeatSensCapDes; + if (PurchAir.MaxHeatSensCap > 0.0 && MaxHeatSensCapDes > 0.0) { + MaxHeatSensCapUser = PurchAir.MaxHeatSensCap; BaseSizer::reportSizerOutput(state, - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, + PurchAir.cObjectName, + PurchAir.Name, "Design Size Maximum Sensible Heating Capacity [W]", - MaxHeatSensCapDes); - // If there is OA, check if sizing calcs have OA>0, throw warning if not - if ((PurchAir(PurchAirNum).OutdoorAir) && (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA == 0.0)) { - ShowWarningError(state, - format("InitPurchasedAir: In {} = {}", PurchAir(PurchAirNum).cObjectName, PurchAir(PurchAirNum).Name)); - ShowContinueError(state, "There is outdoor air specified in this object, but the design outdoor air flow rate for this "); - ShowContinueError(state, "zone is zero. The Maximum Sensible Heating Capacity will be autosized for zero outdoor air flow. "); - ShowContinueError(state, - format("Check the outdoor air specifications in the Sizing:Zone object for zone {}.", - state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneName)); - } - } else { - if (PurchAir(PurchAirNum).MaxHeatSensCap > 0.0 && MaxHeatSensCapDes > 0.0) { - MaxHeatSensCapUser = PurchAir(PurchAirNum).MaxHeatSensCap; - BaseSizer::reportSizerOutput(state, - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, - "Design Size Maximum Sensible Heating Capacity [W]", - MaxHeatSensCapDes, - "User-Specified Maximum Sensible Heating Capacity [W]", - MaxHeatSensCapUser); - if (state.dataGlobal->DisplayExtraWarnings) { - if ((std::abs(MaxHeatSensCapDes - MaxHeatSensCapUser) / MaxHeatSensCapUser) > state.dataSize->AutoVsHardSizingThreshold) { - ShowMessage(state, - format("SizePurchasedAir: Potential issue with equipment sizing for {} {}", - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name)); - ShowContinueError(state, - format("...User-Specified Maximum Sensible Heating Capacity of {:.2R} [W]", MaxHeatSensCapUser)); - ShowContinueError( - state, format("...differs from Design Size Maximum Sensible Heating Capacity of {:.2R} [W]", MaxHeatSensCapDes)); - ShowContinueError(state, "This may, or may not, indicate mismatched component sizes."); - ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components."); - } + MaxHeatSensCapDes, + "User-Specified Maximum Sensible Heating Capacity [W]", + MaxHeatSensCapUser); + if (state.dataGlobal->DisplayExtraWarnings) { + if ((std::abs(MaxHeatSensCapDes - MaxHeatSensCapUser) / MaxHeatSensCapUser) > state.dataSize->AutoVsHardSizingThreshold) { + ShowMessage( + state, + format("SizePurchasedAir: Potential issue with equipment sizing for {} {}", PurchAir.cObjectName, PurchAir.Name)); + ShowContinueError(state, format("...User-Specified Maximum Sensible Heating Capacity of {:.2R} [W]", MaxHeatSensCapUser)); + ShowContinueError( + state, format("...differs from Design Size Maximum Sensible Heating Capacity of {:.2R} [W]", MaxHeatSensCapDes)); + ShowContinueError(state, "This may, or may not, indicate mismatched component sizes."); + ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components."); } } } @@ -1665,13 +1623,12 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod > 0) { state.dataSize->ZoneCoolingOnlyFan = true; SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod; - ZoneEqSizing(state.dataSize->CurZoneEqNum).SizingMethod(SizingMethod) = SAFMethod; + ZoneEqSizing.SizingMethod(SizingMethod) = SAFMethod; if (SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea || SAFMethod == FractionOfAutosizedCoolingAirflow) { if (SAFMethod == SupplyAirFlowRate) { if ((state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow == AutoSize) && - ((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity) || - (PurchAir(PurchAirNum).OutdoorAir && PurchAir(PurchAirNum).EconomizerType != Econ::NoEconomizer))) { + ((PurchAir.CoolingLimit == LimitType::LimitFlowRate) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity) || + (PurchAir.OutdoorAir && PurchAir.EconomizerType != Econ::NoEconomizer))) { TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow; CoolingAirFlowSizer sizingCoolingAirFlow; sizingCoolingAirFlow.overrideSizingString(SizingString); @@ -1687,10 +1644,10 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) } } } else if (SAFMethod == FlowPerFloorArea) { - ZoneEqSizing(state.dataSize->CurZoneEqNum).SystemAirFlow = true; - ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow * - state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea; - TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow; + ZoneEqSizing.SystemAirFlow = true; + ZoneEqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow * + state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea; + TempSize = ZoneEqSizing.AirVolFlow; state.dataSize->DataScalableSizingON = true; CoolingAirFlowSizer sizingCoolingAirFlow; std::string stringOverride = "Maximum Cooling Air Flow Rate [m3/s]"; @@ -1701,9 +1658,8 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) CoolingAirVolFlowDes = sizingCoolingAirFlow.size(state, TempSize, ErrorsFound); } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) { if ((state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow == AutoSize) && - ((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity) || - (PurchAir(PurchAirNum).OutdoorAir && PurchAir(PurchAirNum).EconomizerType != Econ::NoEconomizer))) { + ((PurchAir.CoolingLimit == LimitType::LimitFlowRate) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity) || + (PurchAir.OutdoorAir && PurchAir.EconomizerType != Econ::NoEconomizer))) { state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow; TempSize = AutoSize; state.dataSize->DataScalableSizingON = true; @@ -1720,9 +1676,8 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) } } else if (SAFMethod == FlowPerCoolingCapacity) { if ((state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow == AutoSize) && - ((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity) || - (PurchAir(PurchAirNum).OutdoorAir && PurchAir(PurchAirNum).EconomizerType != Econ::NoEconomizer))) { + ((PurchAir.CoolingLimit == LimitType::LimitFlowRate) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity) || + (PurchAir.OutdoorAir && PurchAir.EconomizerType != Econ::NoEconomizer))) { SizingMethod = CoolingCapacitySizing; TempSize = AutoSize; PrintFlag = false; @@ -1744,28 +1699,26 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) } } MaxCoolVolFlowRateDes = max(0.0, CoolingAirVolFlowDes); - PurchAir(PurchAirNum).MaxCoolVolFlowRate = MaxCoolVolFlowRateDes; + PurchAir.MaxCoolVolFlowRate = MaxCoolVolFlowRateDes; state.dataSize->ZoneCoolingOnlyFan = false; state.dataSize->DataScalableSizingON = false; CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod; - ZoneEqSizing(state.dataSize->CurZoneEqNum).CapSizingMethod = CapSizingMethod; + ZoneEqSizing.CapSizingMethod = CapSizingMethod; if (CapSizingMethod == CoolingDesignCapacity || CapSizingMethod == CapacityPerFloorArea || CapSizingMethod == FractionOfAutosizedCoolingCapacity) { if (CapSizingMethod == CoolingDesignCapacity) { if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity > 0.0) { - ZoneEqSizing(state.dataSize->CurZoneEqNum).CoolingCapacity = true; - ZoneEqSizing(state.dataSize->CurZoneEqNum).DesCoolingLoad = - state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity; + ZoneEqSizing.CoolingCapacity = true; + ZoneEqSizing.DesCoolingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity; } else { state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolMassFlow; } TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity; } else if (CapSizingMethod == CapacityPerFloorArea) { - ZoneEqSizing(state.dataSize->CurZoneEqNum).CoolingCapacity = true; - ZoneEqSizing(state.dataSize->CurZoneEqNum).DesCoolingLoad = - state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity * - state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea; + ZoneEqSizing.CoolingCapacity = true; + ZoneEqSizing.DesCoolingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity * + state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea; state.dataSize->DataScalableSizingON = true; } else if (CapSizingMethod == FractionOfAutosizedCoolingCapacity) { state.dataSize->DataFracOfAutosizedHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity; @@ -1773,11 +1726,11 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) TempSize = AutoSize; } } - SizingMethod = CoolingCapacitySizing; + // SizingMethod = CoolingCapacitySizing; SizingString = ""; state.dataSize->ZoneCoolingOnlyFan = true; PrintFlag = false; - TempSize = PurchAir(PurchAirNum).MaxCoolTotCap; + TempSize = PurchAir.MaxCoolTotCap; CoolingCapacitySizer sizerCoolingCapacity; sizerCoolingCapacity.overrideSizingString(SizingString); sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName); @@ -1786,45 +1739,25 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) if (MaxCoolTotCapDes < HVAC::SmallLoad) { MaxCoolTotCapDes = 0.0; } - if (IsAutoSize) { - PurchAir(PurchAirNum).MaxCoolTotCap = MaxCoolTotCapDes; + if (PurchAir.MaxCoolTotCap > 0.0 && MaxCoolTotCapDes > 0.0) { + MaxCoolTotCapUser = PurchAir.MaxCoolTotCap; BaseSizer::reportSizerOutput(state, - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, + PurchAir.cObjectName, + PurchAir.Name, "Design Size Maximum Total Cooling Capacity [W]", - MaxCoolTotCapDes); - // If there is OA, check if sizing calcs have OA>0, throw warning if not - if ((PurchAir(PurchAirNum).OutdoorAir) && (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA == 0.0)) { - ShowWarningError(state, - format("SizePurchasedAir: In {} = {}", PurchAir(PurchAirNum).cObjectName, PurchAir(PurchAirNum).Name)); - ShowContinueError(state, "There is outdoor air specified in this object, but the design outdoor air flow rate for this "); - ShowContinueError(state, "zone is zero. The Maximum Total Cooling Capacity will be autosized for zero outdoor air flow. "); - ShowContinueError(state, - format("Check the outdoor air specifications in the Sizing:Zone object for zone {}.", - state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneName)); - } - } else { - if (PurchAir(PurchAirNum).MaxCoolTotCap > 0.0 && MaxCoolTotCapDes > 0.0) { - MaxCoolTotCapUser = PurchAir(PurchAirNum).MaxCoolTotCap; - BaseSizer::reportSizerOutput(state, - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, - "Design Size Maximum Total Cooling Capacity [W]", - MaxCoolTotCapDes, - "User-Specified Maximum Total Cooling Capacity [W]", - MaxCoolTotCapUser); - if (state.dataGlobal->DisplayExtraWarnings) { - if ((std::abs(MaxCoolTotCapDes - MaxCoolTotCapUser) / MaxCoolTotCapUser) > state.dataSize->AutoVsHardSizingThreshold) { - ShowMessage(state, - format("SizePurchasedAir: Potential issue with equipment sizing for {} {}", - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name)); - ShowContinueError(state, format("User-Specified Maximum Total Cooling Capacity of {:.2R} [W]", MaxCoolTotCapUser)); - ShowContinueError(state, - format("differs from Design Size Maximum Total Cooling Capacity of {:.2R} [W]", MaxCoolTotCapDes)); - ShowContinueError(state, "This may, or may not, indicate mismatched component sizes."); - ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components."); - } + MaxCoolTotCapDes, + "User-Specified Maximum Total Cooling Capacity [W]", + MaxCoolTotCapUser); + if (state.dataGlobal->DisplayExtraWarnings) { + if ((std::abs(MaxCoolTotCapDes - MaxCoolTotCapUser) / MaxCoolTotCapUser) > state.dataSize->AutoVsHardSizingThreshold) { + ShowMessage( + state, + format("SizePurchasedAir: Potential issue with equipment sizing for {} {}", PurchAir.cObjectName, PurchAir.Name)); + ShowContinueError(state, format("User-Specified Maximum Total Cooling Capacity of {:.2R} [W]", MaxCoolTotCapUser)); + ShowContinueError(state, + format("differs from Design Size Maximum Total Cooling Capacity of {:.2R} [W]", MaxCoolTotCapDes)); + ShowContinueError(state, "This may, or may not, indicate mismatched component sizes."); + ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components."); } } } @@ -1832,56 +1765,54 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) } else { // SizingString = "Maximum Heating Air Flow Rate [m3/s]"; - SizingMethod = HeatingAirflowSizing; + // SizingMethod = HeatingAirflowSizing; FieldNum = 5; SizingString = state.dataPurchasedAirMgr->PurchAirNumericFields(PurchAirNum).FieldNames(FieldNum) + " [m3/s]"; - IsAutoSize = false; + bool IsAutoSize = false; PrintFlag = true; - if ((PurchAir(PurchAirNum).MaxHeatVolFlowRate == AutoSize) && - ((PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRateAndCapacity))) { + if ((PurchAir.MaxHeatVolFlowRate == AutoSize) && + ((PurchAir.HeatingLimit == LimitType::LimitFlowRate) || (PurchAir.HeatingLimit == LimitType::LimitFlowRateAndCapacity))) { IsAutoSize = true; } if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue - if (PurchAir(PurchAirNum).MaxHeatVolFlowRate > 0.0) { + if (PurchAir.MaxHeatVolFlowRate > 0.0) { HeatingAirFlowSizer sizingHeatingAirFlow; sizingHeatingAirFlow.overrideSizingString(SizingString); // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex); sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName); - PurchAir(PurchAirNum).MaxHeatVolFlowRate = - sizingHeatingAirFlow.size(state, PurchAir(PurchAirNum).MaxHeatVolFlowRate, ErrorsFound); + PurchAir.MaxHeatVolFlowRate = sizingHeatingAirFlow.size(state, PurchAir.MaxHeatVolFlowRate, ErrorsFound); } MaxHeatVolFlowRateDes = 0.0; } else { state.dataSize->ZoneHeatingOnlyFan = true; - TempSize = PurchAir(PurchAirNum).MaxHeatVolFlowRate; + TempSize = PurchAir.MaxHeatVolFlowRate; HeatingAirFlowSizer sizingHeatingAirFlow; sizingHeatingAirFlow.overrideSizingString(SizingString); // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex); sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName); - MaxHeatVolFlowRateDes = sizingHeatingAirFlow.size(state, PurchAir(PurchAirNum).MaxHeatVolFlowRate, ErrorsFound); - PurchAir(PurchAirNum).MaxHeatVolFlowRate = MaxHeatVolFlowRateDes; + MaxHeatVolFlowRateDes = sizingHeatingAirFlow.size(state, PurchAir.MaxHeatVolFlowRate, ErrorsFound); + PurchAir.MaxHeatVolFlowRate = MaxHeatVolFlowRateDes; state.dataSize->ZoneHeatingOnlyFan = false; } IsAutoSize = false; - SizingMethod = HeatingCapacitySizing; + // SizingMethod = HeatingCapacitySizing; FieldNum = 6; // N6, \field Maximum Sensible Heating Capacity SizingString = state.dataPurchasedAirMgr->PurchAirNumericFields(PurchAirNum).FieldNames(FieldNum) + " [m3/s]"; - if ((PurchAir(PurchAirNum).MaxHeatSensCap == AutoSize) && ((PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitCapacity) || - (PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRateAndCapacity))) { + if ((PurchAir.MaxHeatSensCap == AutoSize) && + ((PurchAir.HeatingLimit == LimitType::LimitCapacity) || (PurchAir.HeatingLimit == LimitType::LimitFlowRateAndCapacity))) { IsAutoSize = true; } if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue - if (PurchAir(PurchAirNum).MaxHeatSensCap > 0.0) { + if (PurchAir.MaxHeatSensCap > 0.0) { HeatingCapacitySizer sizerHeatingCapacity; sizerHeatingCapacity.overrideSizingString(SizingString); sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName); - MaxHeatSensCapDes = sizerHeatingCapacity.size(state, PurchAir(PurchAirNum).MaxHeatSensCap, ErrorsFound); + MaxHeatSensCapDes = sizerHeatingCapacity.size(state, PurchAir.MaxHeatSensCap, ErrorsFound); } } else { - TempSize = PurchAir(PurchAirNum).MaxHeatSensCap; - ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA; + TempSize = PurchAir.MaxHeatSensCap; + ZoneEqSizing.OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA; state.dataSize->ZoneHeatingOnlyFan = true; PrintFlag = false; HeatingCapacitySizer sizerHeatingCapacity; @@ -1894,15 +1825,12 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) MaxHeatSensCapDes = 0.0; } if (IsAutoSize) { - PurchAir(PurchAirNum).MaxHeatSensCap = MaxHeatSensCapDes; - BaseSizer::reportSizerOutput(state, - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, - "Design Size Maximum Sensible Heating Capacity [W]", - MaxHeatSensCapDes); + PurchAir.MaxHeatSensCap = MaxHeatSensCapDes; + BaseSizer::reportSizerOutput( + state, PurchAir.cObjectName, PurchAir.Name, "Design Size Maximum Sensible Heating Capacity [W]", MaxHeatSensCapDes); // If there is OA, check if sizing calcs have OA>0, throw warning if not - if ((PurchAir(PurchAirNum).OutdoorAir) && (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA == 0.0)) { - ShowWarningError(state, format("InitPurchasedAir: In {} = {}", PurchAir(PurchAirNum).cObjectName, PurchAir(PurchAirNum).Name)); + if ((PurchAir.OutdoorAir) && (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA == 0.0)) { + ShowWarningError(state, format("InitPurchasedAir: In {} = {}", PurchAir.cObjectName, PurchAir.Name)); ShowContinueError(state, "There is outdoor air specified in this object, but the design outdoor air flow rate for this "); ShowContinueError(state, "zone is zero. The Maximum Sensible Heating Capacity will be autosized for zero outdoor air flow. "); ShowContinueError(state, @@ -1910,21 +1838,20 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneName)); } } else { - if (PurchAir(PurchAirNum).MaxHeatSensCap > 0.0 && MaxHeatSensCapDes > 0.0) { - MaxHeatSensCapUser = PurchAir(PurchAirNum).MaxHeatSensCap; + if (PurchAir.MaxHeatSensCap > 0.0 && MaxHeatSensCapDes > 0.0) { + MaxHeatSensCapUser = PurchAir.MaxHeatSensCap; BaseSizer::reportSizerOutput(state, - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, + PurchAir.cObjectName, + PurchAir.Name, "Design Size Maximum Sensible Heating Capacity [W]", MaxHeatSensCapDes, "User-Specified Maximum Sensible Heating Capacity [W]", MaxHeatSensCapUser); if (state.dataGlobal->DisplayExtraWarnings) { if ((std::abs(MaxHeatSensCapDes - MaxHeatSensCapUser) / MaxHeatSensCapUser) > state.dataSize->AutoVsHardSizingThreshold) { - ShowMessage(state, - format("SizePurchasedAir: Potential issue with equipment sizing for {} {}", - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name)); + ShowMessage( + state, + format("SizePurchasedAir: Potential issue with equipment sizing for {} {}", PurchAir.cObjectName, PurchAir.Name)); ShowContinueError(state, format("...User-Specified Maximum Sensible Heating Capacity of {:.2R} [W]", MaxHeatSensCapUser)); ShowContinueError( state, format("...differs from Design Size Maximum Sensible Heating Capacity of {:.2R} [W]", MaxHeatSensCapDes)); @@ -1937,26 +1864,24 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) PrintFlag = true; IsAutoSize = false; - if ((PurchAir(PurchAirNum).MaxCoolVolFlowRate == AutoSize) && - ((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity) || - (PurchAir(PurchAirNum).OutdoorAir && PurchAir(PurchAirNum).EconomizerType != Econ::NoEconomizer))) { + if ((PurchAir.MaxCoolVolFlowRate == AutoSize) && + ((PurchAir.CoolingLimit == LimitType::LimitFlowRate) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity) || + (PurchAir.OutdoorAir && PurchAir.EconomizerType != Econ::NoEconomizer))) { IsAutoSize = true; } if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue - if (PurchAir(PurchAirNum).MaxCoolVolFlowRate > 0.0) { + if (PurchAir.MaxCoolVolFlowRate > 0.0) { CoolingAirFlowSizer sizingCoolingAirFlow; std::string stringOverride = "Maximum Cooling Air Flow Rate [m3/s]"; if (state.dataGlobal->isEpJSON) stringOverride = "maximum_cooling_air_flow_rate [m3/s]"; sizingCoolingAirFlow.overrideSizingString(stringOverride); // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex); sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName); - PurchAir(PurchAirNum).MaxCoolVolFlowRate = - sizingCoolingAirFlow.size(state, PurchAir(PurchAirNum).MaxCoolVolFlowRate, ErrorsFound); + PurchAir.MaxCoolVolFlowRate = sizingCoolingAirFlow.size(state, PurchAir.MaxCoolVolFlowRate, ErrorsFound); } } else { state.dataSize->ZoneCoolingOnlyFan = true; - TempSize = PurchAir(PurchAirNum).MaxCoolVolFlowRate; + TempSize = PurchAir.MaxCoolVolFlowRate; CoolingAirFlowSizer sizingCoolingAirFlow; std::string stringOverride = "Maximum Cooling Air Flow Rate [m3/s]"; if (state.dataGlobal->isEpJSON) stringOverride = "maximum_cooling_air_flow_rate [m3/s]"; @@ -1964,30 +1889,30 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex); sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName); MaxCoolVolFlowRateDes = sizingCoolingAirFlow.size(state, TempSize, ErrorsFound); - PurchAir(PurchAirNum).MaxCoolVolFlowRate = MaxCoolVolFlowRateDes; + PurchAir.MaxCoolVolFlowRate = MaxCoolVolFlowRateDes; state.dataSize->ZoneCoolingOnlyFan = false; } IsAutoSize = false; - SizingMethod = CoolingCapacitySizing; + // SizingMethod = CoolingCapacitySizing; FieldNum = 8; // N8, \field Maximum Total Cooling Capacity SizingString = state.dataPurchasedAirMgr->PurchAirNumericFields(PurchAirNum).FieldNames(FieldNum) + " [m3/s]"; - if ((PurchAir(PurchAirNum).MaxCoolTotCap == AutoSize) && ((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitCapacity) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity))) { + if ((PurchAir.MaxCoolTotCap == AutoSize) && + ((PurchAir.CoolingLimit == LimitType::LimitCapacity) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity))) { IsAutoSize = true; } if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue - if (PurchAir(PurchAirNum).MaxCoolTotCap > 0.0) { + if (PurchAir.MaxCoolTotCap > 0.0) { CoolingCapacitySizer sizerCoolingCapacity; sizerCoolingCapacity.overrideSizingString(SizingString); sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName); - PurchAir(PurchAirNum).MaxCoolTotCap = sizerCoolingCapacity.size(state, PurchAir(PurchAirNum).MaxCoolTotCap, ErrorsFound); + PurchAir.MaxCoolTotCap = sizerCoolingCapacity.size(state, PurchAir.MaxCoolTotCap, ErrorsFound); } } else { state.dataSize->ZoneCoolingOnlyFan = true; - ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA; + ZoneEqSizing.OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA; PrintFlag = false; - TempSize = PurchAir(PurchAirNum).MaxCoolTotCap; + TempSize = PurchAir.MaxCoolTotCap; CoolingCapacitySizer sizerCoolingCapacity; sizerCoolingCapacity.overrideSizingString(SizingString); sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName); @@ -1998,15 +1923,12 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) MaxCoolTotCapDes = 0.0; } if (IsAutoSize) { - PurchAir(PurchAirNum).MaxCoolTotCap = MaxCoolTotCapDes; - BaseSizer::reportSizerOutput(state, - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, - "Design Size Maximum Total Cooling Capacity [W]", - MaxCoolTotCapDes); + PurchAir.MaxCoolTotCap = MaxCoolTotCapDes; + BaseSizer::reportSizerOutput( + state, PurchAir.cObjectName, PurchAir.Name, "Design Size Maximum Total Cooling Capacity [W]", MaxCoolTotCapDes); // If there is OA, check if sizing calcs have OA>0, throw warning if not - if ((PurchAir(PurchAirNum).OutdoorAir) && (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA == 0.0)) { - ShowWarningError(state, format("SizePurchasedAir: In {} = {}", PurchAir(PurchAirNum).cObjectName, PurchAir(PurchAirNum).Name)); + if ((PurchAir.OutdoorAir) && (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA == 0.0)) { + ShowWarningError(state, format("SizePurchasedAir: In {} = {}", PurchAir.cObjectName, PurchAir.Name)); ShowContinueError(state, "There is outdoor air specified in this object, but the design outdoor air flow rate for this "); ShowContinueError(state, "zone is zero. The Maximum Total Cooling Capacity will be autosized for zero outdoor air flow. "); ShowContinueError(state, @@ -2014,21 +1936,20 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneName)); } } else { - if (PurchAir(PurchAirNum).MaxCoolTotCap > 0.0 && MaxCoolTotCapDes > 0.0) { - MaxCoolTotCapUser = PurchAir(PurchAirNum).MaxCoolTotCap; + if (PurchAir.MaxCoolTotCap > 0.0 && MaxCoolTotCapDes > 0.0) { + MaxCoolTotCapUser = PurchAir.MaxCoolTotCap; BaseSizer::reportSizerOutput(state, - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, + PurchAir.cObjectName, + PurchAir.Name, "Design Size Maximum Total Cooling Capacity [W]", MaxCoolTotCapDes, "User-Specified Maximum Total Cooling Capacity [W]", MaxCoolTotCapUser); if (state.dataGlobal->DisplayExtraWarnings) { if ((std::abs(MaxCoolTotCapDes - MaxCoolTotCapUser) / MaxCoolTotCapUser) > state.dataSize->AutoVsHardSizingThreshold) { - ShowMessage(state, - format("SizePurchasedAir: Potential issue with equipment sizing for {} {}", - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name)); + ShowMessage( + state, + format("SizePurchasedAir: Potential issue with equipment sizing for {} {}", PurchAir.cObjectName, PurchAir.Name)); ShowContinueError(state, format("User-Specified Maximum Total Cooling Capacity of {:.2R} [W]", MaxCoolTotCapUser)); ShowContinueError(state, format("differs from Design Size Maximum Total Cooling Capacity of {:.2R} [W]", MaxCoolTotCapDes)); @@ -2040,18 +1961,6 @@ void SizePurchasedAir(EnergyPlusData &state, int const PurchAirNum) } } } - - // IF (PurchAir(PurchAirNum)%OutdoorAir .AND. PurchAir(PurchAirNum)%OutsideAirVolFlowRate == AutoSize) THEN - // IF (CurZoneEqNum > 0) THEN - // CALL CheckZoneSizing(TRIM(PurchAir(PurchAirNum)%cObjectName), PurchAir(PurchAirNum)%Name) - // PurchAir(PurchAirNum)%OutsideAirVolFlowRate = FinalZoneSizing(CurZoneEqNum)%MinOA - // IF (PurchAir(PurchAirNum)%OutsideAirVolFlowRate < SmallAirVolFlow) THEN - // PurchAir(PurchAirNum)%OutsideAirVolFlowRate = 0.0 - // END IF - // CALL BaseSizer::reportSizerOutput(TRIM(PurchAir(PurchAirNum)%cObjectName), PurchAir(PurchAirNum)%Name, & - // 'Outdoor Air Flow Rate [m3/s]', PurchAir(PurchAirNum)%OutsideAirVolFlowRate ) - // END IF - // END IF } void CalcPurchAirLoads(EnergyPlusData &state, @@ -2115,19 +2024,19 @@ void CalcPurchAirLoads(EnergyPlusData &state, // REAL(r64) :: SpecHumOut ! Specific humidity ratio of outlet air (kg moisture / kg moist air) // REAL(r64) :: SpecHumIn ! Specific humidity ratio of inlet [zone] air (kg moisture / kg moist air) - auto &PurchAir(state.dataPurchasedAirMgr->PurchAir); + auto &PurchAir = state.dataPurchasedAirMgr->PurchAir(PurchAirNum); // Sign convention: SysOutputProvided <0 Supply air is heated on entering zone (zone is cooled) // SysOutputProvided >0 Supply air is cooled on entering zone (zone is heated) - InNodeNum = PurchAir(PurchAirNum).ZoneSupplyAirNodeNum; + InNodeNum = PurchAir.ZoneSupplyAirNodeNum; ZoneNodeNum = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode; - OANodeNum = PurchAir(PurchAirNum).OutdoorAirNodeNum; - RecircNodeNum = PurchAir(PurchAirNum).ZoneRecircAirNodeNum; + OANodeNum = PurchAir.OutdoorAirNodeNum; + RecircNodeNum = PurchAir.ZoneRecircAirNodeNum; SupplyMassFlowRate = 0.0; OAMassFlowRate = 0.0; - PurchAir(PurchAirNum).MinOAMassFlowRate = 0.0; - PurchAir(PurchAirNum).TimeEconoActive = 0.0; - PurchAir(PurchAirNum).TimeHtRecActive = 0.0; + PurchAir.MinOAMassFlowRate = 0.0; + PurchAir.TimeEconoActive = 0.0; + PurchAir.TimeHtRecActive = 0.0; SysOutputProvided = 0.0; MoistOutputProvided = 0.0; CoolSensOutput = 0.0; @@ -2146,29 +2055,29 @@ void CalcPurchAirLoads(EnergyPlusData &state, if (allocated(state.dataAvail->ZoneComp)) { auto &availMgr = state.dataAvail->ZoneComp(DataZoneEquipment::ZoneEquipType::PurchasedAir).ZoneCompAvailMgrs(PurchAirNum); availMgr.ZoneNum = ControlledZoneNum; - PurchAir(PurchAirNum).availStatus = availMgr.availStatus; + PurchAir.availStatus = availMgr.availStatus; // Check if the hybrid ventilation availability manager is turning the unit off - if (PurchAir(PurchAirNum).availStatus == Avail::Status::ForceOff) { + if (PurchAir.availStatus == Avail::Status::ForceOff) { UnitOn = false; } } // Check if the unit is scheduled off - // IF (PurchAir(PurchAirNum)%AvailSchedPtr > 0) THEN - if (GetCurrentScheduleValue(state, PurchAir(PurchAirNum).AvailSchedPtr) <= 0) { + // IF (PurchAir%AvailSchedPtr > 0) THEN + if (GetCurrentScheduleValue(state, PurchAir.AvailSchedPtr) <= 0) { UnitOn = false; } // END IF // Check if heating and cooling available HeatOn = true; - // IF (PurchAir(PurchAirNum)%HeatSchedPtr > 0) THEN - if (GetCurrentScheduleValue(state, PurchAir(PurchAirNum).HeatSchedPtr) <= 0) { + // IF (PurchAir%HeatSchedPtr > 0) THEN + if (GetCurrentScheduleValue(state, PurchAir.HeatSchedPtr) <= 0) { HeatOn = false; } // END IF CoolOn = true; - // IF (PurchAir(PurchAirNum)%CoolSchedPtr > 0) THEN - if (GetCurrentScheduleValue(state, PurchAir(PurchAirNum).CoolSchedPtr) <= 0) { + // IF (PurchAir%CoolSchedPtr > 0) THEN + if (GetCurrentScheduleValue(state, PurchAir.CoolSchedPtr) <= 0) { CoolOn = false; } // END IF @@ -2179,12 +2088,12 @@ void CalcPurchAirLoads(EnergyPlusData &state, CalcPurchAirMinOAMassFlow(state, PurchAirNum, ControlledZoneNum, OAMassFlowRate); // EMS override point Purch air outdoor air massflow rate..... - if (PurchAir(PurchAirNum).EMSOverrideOAMdotOn) { - OAMassFlowRate = PurchAir(PurchAirNum).EMSValueOAMassFlowRate; + if (PurchAir.EMSOverrideOAMdotOn) { + OAMassFlowRate = PurchAir.EMSValueOAMassFlowRate; } // Calculate minimum outdoor air sensible and latent load - if (PurchAir(PurchAirNum).OutdoorAir) { + if (PurchAir.OutdoorAir) { CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(OANodeNum).HumRat); MinOASensOutput = OAMassFlowRate * CpAir * (state.dataLoopNodes->Node(OANodeNum).Temp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); MinOALatOutput = OAMassFlowRate * (state.dataLoopNodes->Node(OANodeNum).HumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); @@ -2192,7 +2101,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, MinOASensOutput = 0.0; MinOALatOutput = 0.0; } - SupplyMassFlowRate = OAMassFlowRate; + // SupplyMassFlowRate = OAMassFlowRate; // Check if cooling of the supply air stream is required @@ -2207,54 +2116,51 @@ void CalcPurchAirLoads(EnergyPlusData &state, // Min OA mass flow rate // Check if OA flow rate greater than max cooling airflow limit - if (((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity)) && - (OAMassFlowRate > PurchAir(PurchAirNum).MaxCoolMassFlowRate)) { + if (((PurchAir.CoolingLimit == LimitType::LimitFlowRate) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity)) && + (OAMassFlowRate > PurchAir.MaxCoolMassFlowRate)) { OAVolFlowRate = OAMassFlowRate / state.dataEnvrn->StdRhoAir; - if (PurchAir(PurchAirNum).OAFlowMaxCoolOutputError < 1) { - ++PurchAir(PurchAirNum).OAFlowMaxCoolOutputError; + if (PurchAir.OAFlowMaxCoolOutputError < 1) { + ++PurchAir.OAFlowMaxCoolOutputError; ShowWarningError(state, format("{} \"{}\" Requested outdoor air flow rate = {:.5T} [m3/s] exceeds limit.", - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, + PurchAir.cObjectName, + PurchAir.Name, OAVolFlowRate)); - ShowContinueError( - state, - format(" Will be reduced to the Maximum Cooling Air Flow Rate = {:.5T} [m3/s]", PurchAir(PurchAirNum).MaxCoolVolFlowRate)); + ShowContinueError(state, + format(" Will be reduced to the Maximum Cooling Air Flow Rate = {:.5T} [m3/s]", PurchAir.MaxCoolVolFlowRate)); ShowContinueErrorTimeStamp(state, ""); } else { ShowRecurringWarningErrorAtEnd( state, - PurchAir(PurchAirNum).cObjectName + " \"" + PurchAir(PurchAirNum).Name + + PurchAir.cObjectName + " \"" + PurchAir.Name + "\" Requested outdoor air flow rate [m3/s] reduced to Maximum Cooling Air Flow Rate warning continues...", - PurchAir(PurchAirNum).OAFlowMaxCoolOutputIndex, + PurchAir.OAFlowMaxCoolOutputIndex, OAVolFlowRate); } - OAMassFlowRate = PurchAir(PurchAirNum).MaxCoolMassFlowRate; + OAMassFlowRate = PurchAir.MaxCoolMassFlowRate; } else { // Model economizer - if (PurchAir(PurchAirNum).EconomizerType != Econ::NoEconomizer) { - if (((PurchAir(PurchAirNum).EconomizerType == Econ::DifferentialDryBulb) && - (state.dataLoopNodes->Node(OANodeNum).Temp < state.dataLoopNodes->Node(PurchAir(PurchAirNum).ZoneRecircAirNodeNum).Temp)) || - ((PurchAir(PurchAirNum).EconomizerType == Econ::DifferentialEnthalpy) && - (state.dataLoopNodes->Node(OANodeNum).Enthalpy < - state.dataLoopNodes->Node(PurchAir(PurchAirNum).ZoneRecircAirNodeNum).Enthalpy))) { + if (PurchAir.EconomizerType != Econ::NoEconomizer) { + if (((PurchAir.EconomizerType == Econ::DifferentialDryBulb) && + (state.dataLoopNodes->Node(OANodeNum).Temp < state.dataLoopNodes->Node(PurchAir.ZoneRecircAirNodeNum).Temp)) || + ((PurchAir.EconomizerType == Econ::DifferentialEnthalpy) && + (state.dataLoopNodes->Node(OANodeNum).Enthalpy < state.dataLoopNodes->Node(PurchAir.ZoneRecircAirNodeNum).Enthalpy))) { // Calculate supply MassFlowRate based on sensible load but limit to Max Cooling Supply Air Flow Rate if specified CpAir = PsyCpAirFnW(thisZoneHB.airHumRat); DeltaT = (state.dataLoopNodes->Node(OANodeNum).Temp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); if (DeltaT < -HVAC::SmallTempDiff) { SupplyMassFlowRate = QZnCoolSP / CpAir / DeltaT; - if (((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity)) && - (PurchAir(PurchAirNum).MaxCoolMassFlowRate > 0.0)) { - SupplyMassFlowRate = min(max(SupplyMassFlowRate, 0.0), PurchAir(PurchAirNum).MaxCoolMassFlowRate); + if (((PurchAir.CoolingLimit == LimitType::LimitFlowRate) || + (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity)) && + (PurchAir.MaxCoolMassFlowRate > 0.0)) { + SupplyMassFlowRate = min(max(SupplyMassFlowRate, 0.0), PurchAir.MaxCoolMassFlowRate); } if (SupplyMassFlowRate > OAMassFlowRate) { EconoOn = true; OAMassFlowRate = SupplyMassFlowRate; - PurchAir(PurchAirNum).TimeEconoActive = state.dataHVACGlobal->TimeStepSys; + PurchAir.TimeEconoActive = state.dataHVACGlobal->TimeStepSys; } } } @@ -2266,7 +2172,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, SupplyMassFlowRateForCool = 0.0; if (CoolOn) { CpAir = PsyCpAirFnW(thisZoneHB.airHumRat); - DeltaT = (PurchAir(PurchAirNum).MinCoolSuppAirTemp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); + DeltaT = (PurchAir.MinCoolSuppAirTemp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); if (DeltaT < -HVAC::SmallTempDiff) { SupplyMassFlowRateForCool = QZnCoolSP / CpAir / DeltaT; } @@ -2275,9 +2181,9 @@ void CalcPurchAirLoads(EnergyPlusData &state, // Mass flow rate to meet dehumidification load, if applicable, at Minimum Cooling Supply Humidity Ratio SupplyMassFlowRateForDehum = 0.0; if (CoolOn) { - if (PurchAir(PurchAirNum).DehumidCtrlType == HumControl::Humidistat) { + if (PurchAir.DehumidCtrlType == HumControl::Humidistat) { MdotZnDehumidSP = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).RemainingOutputReqToDehumidSP; - DeltaHumRat = (PurchAir(PurchAirNum).MinCoolSuppAirHumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); + DeltaHumRat = (PurchAir.MinCoolSuppAirHumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); if ((DeltaHumRat < -SmallDeltaHumRat) && (MdotZnDehumidSP < 0.0)) { SupplyMassFlowRateForDehum = MdotZnDehumidSP / DeltaHumRat; } @@ -2289,11 +2195,10 @@ void CalcPurchAirLoads(EnergyPlusData &state, // and if dehumidification control = humidistat or none SupplyMassFlowRateForHumid = 0.0; if (HeatOn) { - if (PurchAir(PurchAirNum).HumidCtrlType == HumControl::Humidistat) { - if ((PurchAir(PurchAirNum).DehumidCtrlType == HumControl::Humidistat) || - (PurchAir(PurchAirNum).DehumidCtrlType == HumControl::None)) { + if (PurchAir.HumidCtrlType == HumControl::Humidistat) { + if ((PurchAir.DehumidCtrlType == HumControl::Humidistat) || (PurchAir.DehumidCtrlType == HumControl::None)) { MdotZnHumidSP = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).RemainingOutputReqToHumidSP; - DeltaHumRat = (PurchAir(PurchAirNum).MaxHeatSuppAirHumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); + DeltaHumRat = (PurchAir.MaxHeatSuppAirHumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); if ((DeltaHumRat > SmallDeltaHumRat) && (MdotZnHumidSP > 0.0)) { SupplyMassFlowRateForHumid = MdotZnHumidSP / DeltaHumRat; } @@ -2302,9 +2207,8 @@ void CalcPurchAirLoads(EnergyPlusData &state, } // If cooling capacity is limited to zero, SupplyMassFlowRate* should be set to zero - if (((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitCapacity) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity)) && - (PurchAir(PurchAirNum).MaxCoolTotCap == 0)) { + if (((PurchAir.CoolingLimit == LimitType::LimitCapacity) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity)) && + (PurchAir.MaxCoolTotCap == 0)) { SupplyMassFlowRateForCool = 0; SupplyMassFlowRateForDehum = 0; SupplyMassFlowRateForHumid = 0; @@ -2313,14 +2217,13 @@ void CalcPurchAirLoads(EnergyPlusData &state, // Supply mass flow is greatest of these, but limit to cooling max flow rate, if applicable SupplyMassFlowRate = max(0.0, OAMassFlowRate, SupplyMassFlowRateForCool, SupplyMassFlowRateForDehum, SupplyMassFlowRateForHumid); // EMS override point Purch air massflow rate..... but only if unit is on, i.e. SupplyMassFlowRate>0.0 - if (PurchAir(PurchAirNum).EMSOverrideMdotOn) { - SupplyMassFlowRate = PurchAir(PurchAirNum).EMSValueMassFlowRate; + if (PurchAir.EMSOverrideMdotOn) { + SupplyMassFlowRate = PurchAir.EMSValueMassFlowRate; OAMassFlowRate = min(OAMassFlowRate, SupplyMassFlowRate); } - if (((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity)) && - (PurchAir(PurchAirNum).MaxCoolMassFlowRate > 0.0)) { - SupplyMassFlowRate = min(SupplyMassFlowRate, PurchAir(PurchAirNum).MaxCoolMassFlowRate); + if (((PurchAir.CoolingLimit == LimitType::LimitFlowRate) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity)) && + (PurchAir.MaxCoolMassFlowRate > 0.0)) { + SupplyMassFlowRate = min(SupplyMassFlowRate, PurchAir.MaxCoolMassFlowRate); } if (SupplyMassFlowRate <= HVAC::VerySmallMassFlow) SupplyMassFlowRate = 0.0; @@ -2330,8 +2233,8 @@ void CalcPurchAirLoads(EnergyPlusData &state, PurchAirNum, OAMassFlowRate, SupplyMassFlowRate, - PurchAir(PurchAirNum).MixedAirTemp, - PurchAir(PurchAirNum).MixedAirHumRat, + PurchAir.MixedAirTemp, + PurchAir.MixedAirHumRat, MixedAirEnthalpy, OperatingMode); @@ -2341,61 +2244,59 @@ void CalcPurchAirLoads(EnergyPlusData &state, if (SupplyMassFlowRate > 0.0) { // Calculate supply temp at SupplyMassFlowRate and recheck limit on Minimum Cooling Supply Air Temperature CpAir = PsyCpAirFnW(thisZoneHB.airHumRat); - PurchAir(PurchAirNum).SupplyTemp = QZnCoolSP / (CpAir * SupplyMassFlowRate) + state.dataLoopNodes->Node(ZoneNodeNum).Temp; - PurchAir(PurchAirNum).SupplyTemp = max(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).MinCoolSuppAirTemp); + PurchAir.SupplyTemp = QZnCoolSP / (CpAir * SupplyMassFlowRate) + state.dataLoopNodes->Node(ZoneNodeNum).Temp; + PurchAir.SupplyTemp = max(PurchAir.SupplyTemp, PurchAir.MinCoolSuppAirTemp); // This is the cooling mode, so SupplyTemp can't be more than MixedAirTemp - PurchAir(PurchAirNum).SupplyTemp = min(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).MixedAirTemp); - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; - SupplyEnthalpy = PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).SupplyHumRat); + PurchAir.SupplyTemp = min(PurchAir.SupplyTemp, PurchAir.MixedAirTemp); + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; + SupplyEnthalpy = PsyHFnTdbW(PurchAir.SupplyTemp, PurchAir.SupplyHumRat); // Check sensible load vs max total cooling capacity, if specified, and adjust supply temp before applying humidity controls // Will check again later, too - if ((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitCapacity) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity)) { - CpAir = PsyCpAirFnW(PurchAir(PurchAirNum).MixedAirHumRat); + if ((PurchAir.CoolingLimit == LimitType::LimitCapacity) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity)) { + CpAir = PsyCpAirFnW(PurchAir.MixedAirHumRat); CoolSensOutput = SupplyMassFlowRate * (MixedAirEnthalpy - SupplyEnthalpy); - if (CoolSensOutput >= PurchAir(PurchAirNum).MaxCoolTotCap) { - CoolSensOutput = PurchAir(PurchAirNum).MaxCoolTotCap; + if (CoolSensOutput >= PurchAir.MaxCoolTotCap) { + CoolSensOutput = PurchAir.MaxCoolTotCap; SupplyEnthalpy = MixedAirEnthalpy - CoolSensOutput / SupplyMassFlowRate; - PurchAir(PurchAirNum).SupplyTemp = PsyTdbFnHW(SupplyEnthalpy, PurchAir(PurchAirNum).SupplyHumRat); + PurchAir.SupplyTemp = PsyTdbFnHW(SupplyEnthalpy, PurchAir.SupplyHumRat); // This is the cooling mode, so SupplyTemp can't be more than MixedAirTemp - PurchAir(PurchAirNum).SupplyTemp = min(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).MixedAirTemp); + PurchAir.SupplyTemp = min(PurchAir.SupplyTemp, PurchAir.MixedAirTemp); } // Capacity limit exceeded } // Set supply humidity ratio for cooling/dehumidification - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; - switch (PurchAir(PurchAirNum).DehumidCtrlType) { + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; + switch (PurchAir.DehumidCtrlType) { case HumControl::None: { - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; // Unnecessary line? + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; // Unnecessary line? } break; case HumControl::ConstantSensibleHeatRatio: { // SHR = CoolSensOutput/CoolTotOutput // CoolTotOutput = CoolSensOutput/SHR - CpAir = PsyCpAirFnW(PurchAir(PurchAirNum).MixedAirHumRat); - CoolSensOutput = SupplyMassFlowRate * CpAir * (PurchAir(PurchAirNum).MixedAirTemp - PurchAir(PurchAirNum).SupplyTemp); - CoolTotOutput = CoolSensOutput / PurchAir(PurchAirNum).CoolSHR; + CpAir = PsyCpAirFnW(PurchAir.MixedAirHumRat); + CoolSensOutput = SupplyMassFlowRate * CpAir * (PurchAir.MixedAirTemp - PurchAir.SupplyTemp); + CoolTotOutput = CoolSensOutput / PurchAir.CoolSHR; SupplyEnthalpy = MixedAirEnthalpy - CoolTotOutput / SupplyMassFlowRate; // Limit for overdrying (avoid Pysch errors which occur if SupplyEnthalpy is too low for SupplyTemp) - SupplyEnthalpy = max(SupplyEnthalpy, PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, 0.00001)); - PurchAir(PurchAirNum).SupplyHumRat = - min(PurchAir(PurchAirNum).SupplyHumRat, PsyWFnTdbH(state, PurchAir(PurchAirNum).SupplyTemp, SupplyEnthalpy, RoutineName)); + SupplyEnthalpy = max(SupplyEnthalpy, PsyHFnTdbW(PurchAir.SupplyTemp, 0.00001)); + PurchAir.SupplyHumRat = min(PurchAir.SupplyHumRat, PsyWFnTdbH(state, PurchAir.SupplyTemp, SupplyEnthalpy, RoutineName)); // Apply min cooling humidity ratio limit - PurchAir(PurchAirNum).SupplyHumRat = max(PurchAir(PurchAirNum).SupplyHumRat, PurchAir(PurchAirNum).MinCoolSuppAirHumRat); + PurchAir.SupplyHumRat = max(PurchAir.SupplyHumRat, PurchAir.MinCoolSuppAirHumRat); // But don't let it be higher than incoming MixedAirHumRat - PurchAir(PurchAirNum).SupplyHumRat = min(PurchAir(PurchAirNum).SupplyHumRat, PurchAir(PurchAirNum).MixedAirHumRat); + PurchAir.SupplyHumRat = min(PurchAir.SupplyHumRat, PurchAir.MixedAirHumRat); } break; case HumControl::Humidistat: { MdotZnDehumidSP = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).RemainingOutputReqToDehumidSP; SupplyHumRatForDehum = MdotZnDehumidSP / SupplyMassFlowRate + state.dataLoopNodes->Node(ZoneNodeNum).HumRat; - SupplyHumRatForDehum = max(SupplyHumRatForDehum, PurchAir(PurchAirNum).MinCoolSuppAirHumRat); - PurchAir(PurchAirNum).SupplyHumRat = min(PurchAir(PurchAirNum).MixedAirHumRat, SupplyHumRatForDehum); + SupplyHumRatForDehum = max(SupplyHumRatForDehum, PurchAir.MinCoolSuppAirHumRat); + PurchAir.SupplyHumRat = min(PurchAir.MixedAirHumRat, SupplyHumRatForDehum); } break; case HumControl::ConstantSupplyHumidityRatio: { - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MinCoolSuppAirHumRat; + PurchAir.SupplyHumRat = PurchAir.MinCoolSuppAirHumRat; } break; default: { - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; } break; } @@ -2403,68 +2304,65 @@ void CalcPurchAirLoads(EnergyPlusData &state, // This section is the cooling section, so humidification should activate only if humidification control = humidistat // and if dehumidification control = humidistat or none if (HeatOn) { - if (PurchAir(PurchAirNum).HumidCtrlType == HumControl::Humidistat) { - if ((PurchAir(PurchAirNum).DehumidCtrlType == HumControl::Humidistat) || - (PurchAir(PurchAirNum).DehumidCtrlType == HumControl::None)) { + if (PurchAir.HumidCtrlType == HumControl::Humidistat) { + if ((PurchAir.DehumidCtrlType == HumControl::Humidistat) || (PurchAir.DehumidCtrlType == HumControl::None)) { MdotZnHumidSP = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).RemainingOutputReqToHumidSP; SupplyHumRatForHumid = MdotZnHumidSP / SupplyMassFlowRate + state.dataLoopNodes->Node(ZoneNodeNum).HumRat; - SupplyHumRatForHumid = min(SupplyHumRatForHumid, PurchAir(PurchAirNum).MaxHeatSuppAirHumRat); - PurchAir(PurchAirNum).SupplyHumRat = max(PurchAir(PurchAirNum).SupplyHumRat, SupplyHumRatForHumid); + SupplyHumRatForHumid = min(SupplyHumRatForHumid, PurchAir.MaxHeatSuppAirHumRat); + PurchAir.SupplyHumRat = max(PurchAir.SupplyHumRat, SupplyHumRatForHumid); } } } // Limit supply humidity ratio to saturation at supply outlet temp - SupplyHumRatOrig = PurchAir(PurchAirNum).SupplyHumRat; - SupplyHumRatSat = PsyWFnTdbRhPb(state, PurchAir(PurchAirNum).SupplyTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineName); - PurchAir(PurchAirNum).SupplyHumRat = min(SupplyHumRatOrig, SupplyHumRatSat); - SupplyEnthalpy = PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).SupplyHumRat); + SupplyHumRatOrig = PurchAir.SupplyHumRat; + SupplyHumRatSat = PsyWFnTdbRhPb(state, PurchAir.SupplyTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineName); + PurchAir.SupplyHumRat = min(SupplyHumRatOrig, SupplyHumRatSat); + SupplyEnthalpy = PsyHFnTdbW(PurchAir.SupplyTemp, PurchAir.SupplyHumRat); // Check max total Cooling capacity, if specified - if ((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitCapacity) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity)) { + if ((PurchAir.CoolingLimit == LimitType::LimitCapacity) || (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity)) { // If dehumidifying, compare total cooling to the limit - if (PurchAir(PurchAirNum).SupplyHumRat < PurchAir(PurchAirNum).MixedAirHumRat) { // Dehumidifying + if (PurchAir.SupplyHumRat < PurchAir.MixedAirHumRat) { // Dehumidifying CoolTotOutput = SupplyMassFlowRate * (MixedAirEnthalpy - SupplyEnthalpy); - if ((CoolTotOutput) > PurchAir(PurchAirNum).MaxCoolTotCap) { - CoolTotOutput = PurchAir(PurchAirNum).MaxCoolTotCap; + if ((CoolTotOutput) > PurchAir.MaxCoolTotCap) { + CoolTotOutput = PurchAir.MaxCoolTotCap; SupplyEnthalpy = MixedAirEnthalpy - CoolTotOutput / SupplyMassFlowRate; // Adjust output based on dehumidification control type - switch (PurchAir(PurchAirNum).DehumidCtrlType) { + switch (PurchAir.DehumidCtrlType) { case HumControl::ConstantSensibleHeatRatio: { // Adjust both supply temp and humidity ratio to maintain SHR // SHR = CoolSensOutput/CoolTotOutput // CoolSensOutput = SHR*CoolTotOutput - CpAir = PsyCpAirFnW(PurchAir(PurchAirNum).MixedAirHumRat); - CoolSensOutput = CoolTotOutput * PurchAir(PurchAirNum).CoolSHR; - PurchAir(PurchAirNum).SupplyTemp = PurchAir(PurchAirNum).MixedAirTemp - CoolSensOutput / (CpAir * SupplyMassFlowRate); + CpAir = PsyCpAirFnW(PurchAir.MixedAirHumRat); + CoolSensOutput = CoolTotOutput * PurchAir.CoolSHR; + PurchAir.SupplyTemp = PurchAir.MixedAirTemp - CoolSensOutput / (CpAir * SupplyMassFlowRate); // This is the cooling mode, so SupplyTemp can't be more than MixedAirTemp - PurchAir(PurchAirNum).SupplyTemp = min(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).MixedAirTemp); + PurchAir.SupplyTemp = min(PurchAir.SupplyTemp, PurchAir.MixedAirTemp); // Limit for overdrying (avoid Pysch errors which occur if SupplyEnthalpy is too low for SupplyTemp) - SupplyEnthalpy = max(SupplyEnthalpy, PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, 0.00001)); - PurchAir(PurchAirNum).SupplyHumRat = PsyWFnTdbH(state, PurchAir(PurchAirNum).SupplyTemp, SupplyEnthalpy, RoutineName); + SupplyEnthalpy = max(SupplyEnthalpy, PsyHFnTdbW(PurchAir.SupplyTemp, 0.00001)); + PurchAir.SupplyHumRat = PsyWFnTdbH(state, PurchAir.SupplyTemp, SupplyEnthalpy, RoutineName); } break; case HumControl::Humidistat: { // Keep supply temp and adjust humidity ratio to reduce load - PurchAir(PurchAirNum).SupplyHumRat = PsyWFnTdbH(state, PurchAir(PurchAirNum).SupplyTemp, SupplyEnthalpy, RoutineName); + PurchAir.SupplyHumRat = PsyWFnTdbH(state, PurchAir.SupplyTemp, SupplyEnthalpy, RoutineName); } break; case HumControl::None: case HumControl::ConstantSupplyHumidityRatio: { // Keep humidity ratio and adjust supply temp // Check if latent output exceeds capacity - CpAir = PsyCpAirFnW(PurchAir(PurchAirNum).MixedAirHumRat); - CoolSensOutput = SupplyMassFlowRate * CpAir * (PurchAir(PurchAirNum).MixedAirTemp - PurchAir(PurchAirNum).SupplyTemp); + CpAir = PsyCpAirFnW(PurchAir.MixedAirHumRat); + CoolSensOutput = SupplyMassFlowRate * CpAir * (PurchAir.MixedAirTemp - PurchAir.SupplyTemp); CoolLatOutput = CoolTotOutput - CoolSensOutput; - if (CoolLatOutput >= PurchAir(PurchAirNum).MaxCoolTotCap) { - PurchAir(PurchAirNum).SupplyTemp = PurchAir(PurchAirNum).MixedAirTemp; - PurchAir(PurchAirNum).SupplyHumRat = - PsyWFnTdbH(state, PurchAir(PurchAirNum).SupplyTemp, SupplyEnthalpy, RoutineName); - CoolLatOutput = PurchAir(PurchAirNum).MaxCoolTotCap; + if (CoolLatOutput >= PurchAir.MaxCoolTotCap) { + PurchAir.SupplyTemp = PurchAir.MixedAirTemp; + PurchAir.SupplyHumRat = PsyWFnTdbH(state, PurchAir.SupplyTemp, SupplyEnthalpy, RoutineName); + CoolLatOutput = PurchAir.MaxCoolTotCap; } else { - PurchAir(PurchAirNum).SupplyTemp = PsyTdbFnHW(SupplyEnthalpy, PurchAir(PurchAirNum).SupplyHumRat); + PurchAir.SupplyTemp = PsyTdbFnHW(SupplyEnthalpy, PurchAir.SupplyHumRat); // This is the cooling mode, so SupplyTemp can't be more than MixedAirTemp - PurchAir(PurchAirNum).SupplyTemp = min(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).MixedAirTemp); + PurchAir.SupplyTemp = min(PurchAir.SupplyTemp, PurchAir.MixedAirTemp); } } break; default: @@ -2473,15 +2371,15 @@ void CalcPurchAirLoads(EnergyPlusData &state, // Limit supply humidity ratio to saturation at supply outlet temp // If saturation exceeded, then honor capacity limit and set to dew point at supplyenthalpy - SupplyHumRatOrig = PurchAir(PurchAirNum).SupplyHumRat; - SupplyHumRatSat = PsyWFnTdbRhPb(state, PurchAir(PurchAirNum).SupplyTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineName); + SupplyHumRatOrig = PurchAir.SupplyHumRat; + SupplyHumRatSat = PsyWFnTdbRhPb(state, PurchAir.SupplyTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineName); if (SupplyHumRatSat < SupplyHumRatOrig) { - PurchAir(PurchAirNum).SupplyTemp = PsyTsatFnHPb(state, SupplyEnthalpy, state.dataEnvrn->OutBaroPress, RoutineName); + PurchAir.SupplyTemp = PsyTsatFnHPb(state, SupplyEnthalpy, state.dataEnvrn->OutBaroPress, RoutineName); // This is the cooling mode, so SupplyTemp can't be more than MixedAirTemp - PurchAir(PurchAirNum).SupplyTemp = min(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).MixedAirTemp); - PurchAir(PurchAirNum).SupplyHumRat = PsyWFnTdbH(state, PurchAir(PurchAirNum).SupplyTemp, SupplyEnthalpy, RoutineName); - SupplyEnthalpy = PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).SupplyHumRat); + PurchAir.SupplyTemp = min(PurchAir.SupplyTemp, PurchAir.MixedAirTemp); + PurchAir.SupplyHumRat = PsyWFnTdbH(state, PurchAir.SupplyTemp, SupplyEnthalpy, RoutineName); + SupplyEnthalpy = PsyHFnTdbW(PurchAir.SupplyTemp, PurchAir.SupplyHumRat); // CpAir = PsyCpAirFnW(MixedAirHumRat) // CoolSensOutput = SupplyMassFlowRate * CpAir * (MixedAirTemp - SupplyTemp) // CoolTotOutput = SupplyMassFlowRate * (MixedAirEnthalpy - SupplyEnthalpy) @@ -2490,19 +2388,19 @@ void CalcPurchAirLoads(EnergyPlusData &state, } else { // Not dehumidifying // If not dehumidifying, compare sensible cooling to the limit // This section will only increase supply temp, so no need to recheck for super-saturation - CpAir = PsyCpAirFnW(PurchAir(PurchAirNum).MixedAirHumRat); - CoolSensOutput = SupplyMassFlowRate * CpAir * (PurchAir(PurchAirNum).MixedAirTemp - PurchAir(PurchAirNum).SupplyTemp); - if (CoolSensOutput >= PurchAir(PurchAirNum).MaxCoolTotCap) { - CoolSensOutput = PurchAir(PurchAirNum).MaxCoolTotCap; - PurchAir(PurchAirNum).SupplyTemp = PurchAir(PurchAirNum).MixedAirTemp - CoolSensOutput / (SupplyMassFlowRate * CpAir); + CpAir = PsyCpAirFnW(PurchAir.MixedAirHumRat); + CoolSensOutput = SupplyMassFlowRate * CpAir * (PurchAir.MixedAirTemp - PurchAir.SupplyTemp); + if (CoolSensOutput >= PurchAir.MaxCoolTotCap) { + CoolSensOutput = PurchAir.MaxCoolTotCap; + PurchAir.SupplyTemp = PurchAir.MixedAirTemp - CoolSensOutput / (SupplyMassFlowRate * CpAir); } // Capacity limit exceeded } // Dehumidifying or not } // Capacity limit active } else { // SupplyMassFlowRate is zero SupplyEnthalpy = MixedAirEnthalpy; - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; - PurchAir(PurchAirNum).SupplyTemp = PurchAir(PurchAirNum).MixedAirTemp; + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; + PurchAir.SupplyTemp = PurchAir.MixedAirTemp; CoolSensOutput = 0.0; CoolTotOutput = 0.0; } @@ -2522,40 +2420,38 @@ void CalcPurchAirLoads(EnergyPlusData &state, // Min OA mass flow rate // Check if OA flow rate greater than max heating airflow limit - if (((PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRateAndCapacity)) && - (OAMassFlowRate > PurchAir(PurchAirNum).MaxHeatMassFlowRate)) { + if (((PurchAir.HeatingLimit == LimitType::LimitFlowRate) || (PurchAir.HeatingLimit == LimitType::LimitFlowRateAndCapacity)) && + (OAMassFlowRate > PurchAir.MaxHeatMassFlowRate)) { OAVolFlowRate = OAMassFlowRate / state.dataEnvrn->StdRhoAir; - if (PurchAir(PurchAirNum).OAFlowMaxHeatOutputError < 1) { - ++PurchAir(PurchAirNum).OAFlowMaxHeatOutputError; + if (PurchAir.OAFlowMaxHeatOutputError < 1) { + ++PurchAir.OAFlowMaxHeatOutputError; ShowWarningError(state, format("{} \"{}\" Requested outdoor air flow rate = {:.5T} [m3/s] exceeds limit.", - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, + PurchAir.cObjectName, + PurchAir.Name, OAVolFlowRate)); - ShowContinueError( - state, - format(" Will be reduced to the Maximum Heating Air Flow Rate = {:.5T} [m3/s]", PurchAir(PurchAirNum).MaxHeatVolFlowRate)); + ShowContinueError(state, + format(" Will be reduced to the Maximum Heating Air Flow Rate = {:.5T} [m3/s]", PurchAir.MaxHeatVolFlowRate)); ShowContinueErrorTimeStamp(state, ""); } else { ShowRecurringWarningErrorAtEnd( state, - PurchAir(PurchAirNum).cObjectName + " \"" + PurchAir(PurchAirNum).Name + + PurchAir.cObjectName + " \"" + PurchAir.Name + "\" Requested outdoor air flow rate [m3/s] reduced to Maximum Heating Air Flow Rate warning continues...", - PurchAir(PurchAirNum).OAFlowMaxHeatOutputIndex, + PurchAir.OAFlowMaxHeatOutputIndex, OAVolFlowRate); } - OAMassFlowRate = PurchAir(PurchAirNum).MaxHeatMassFlowRate; + OAMassFlowRate = PurchAir.MaxHeatMassFlowRate; } - SupplyMassFlowRate = OAMassFlowRate; + // SupplyMassFlowRate = OAMassFlowRate; // Determine supply mass flow rate // Mass flow rate to meet sensible load, at Minimum Cooling Supply Air Temperature SupplyMassFlowRateForHeat = 0.0; if ((HeatOn) && (OperatingMode == OpMode::Heat)) { CpAir = PsyCpAirFnW(thisZoneHB.airHumRat); - DeltaT = (PurchAir(PurchAirNum).MaxHeatSuppAirTemp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); + DeltaT = (PurchAir.MaxHeatSuppAirTemp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); if (DeltaT > HVAC::SmallTempDiff) { SupplyMassFlowRateForHeat = QZnHeatSP / CpAir / DeltaT; } @@ -2567,11 +2463,11 @@ void CalcPurchAirLoads(EnergyPlusData &state, // and if humidification control = humidistat or none or if operating in deadband mode SupplyMassFlowRateForDehum = 0.0; if (CoolOn) { - if (PurchAir(PurchAirNum).DehumidCtrlType == HumControl::Humidistat) { - if ((PurchAir(PurchAirNum).HumidCtrlType == HumControl::Humidistat) || - (PurchAir(PurchAirNum).HumidCtrlType == HumControl::None) || (OperatingMode == OpMode::DeadBand)) { + if (PurchAir.DehumidCtrlType == HumControl::Humidistat) { + if ((PurchAir.HumidCtrlType == HumControl::Humidistat) || (PurchAir.HumidCtrlType == HumControl::None) || + (OperatingMode == OpMode::DeadBand)) { MdotZnDehumidSP = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).RemainingOutputReqToDehumidSP; - DeltaHumRat = (PurchAir(PurchAirNum).MinCoolSuppAirHumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); + DeltaHumRat = (PurchAir.MinCoolSuppAirHumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); if ((DeltaHumRat < -SmallDeltaHumRat) && (MdotZnDehumidSP < 0.0)) { SupplyMassFlowRateForDehum = MdotZnDehumidSP / DeltaHumRat; } @@ -2582,9 +2478,9 @@ void CalcPurchAirLoads(EnergyPlusData &state, // Mass flow rate to meet humidification load, if applicable, at Maximum Heating Supply Humidity Ratio SupplyMassFlowRateForHumid = 0.0; if (HeatOn) { - if (PurchAir(PurchAirNum).HumidCtrlType == HumControl::Humidistat) { + if (PurchAir.HumidCtrlType == HumControl::Humidistat) { MdotZnHumidSP = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).RemainingOutputReqToHumidSP; - DeltaHumRat = (PurchAir(PurchAirNum).MaxHeatSuppAirHumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); + DeltaHumRat = (PurchAir.MaxHeatSuppAirHumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); if ((DeltaHumRat > SmallDeltaHumRat) && (MdotZnHumidSP > 0.0)) { SupplyMassFlowRateForHumid = MdotZnHumidSP / DeltaHumRat; } @@ -2592,9 +2488,8 @@ void CalcPurchAirLoads(EnergyPlusData &state, } // If heating capacity is limited to zero, SupplyMassFlowRate* should be set to zero - if (((PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitCapacity) || - (PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRateAndCapacity)) && - (PurchAir(PurchAirNum).MaxHeatSensCap == 0)) { + if (((PurchAir.HeatingLimit == LimitType::LimitCapacity) || (PurchAir.HeatingLimit == LimitType::LimitFlowRateAndCapacity)) && + (PurchAir.MaxHeatSensCap == 0)) { SupplyMassFlowRateForHeat = 0; SupplyMassFlowRateForDehum = 0; SupplyMassFlowRateForHumid = 0; @@ -2603,14 +2498,13 @@ void CalcPurchAirLoads(EnergyPlusData &state, // Supply mass flow is greatest of these, but limit to heating max flow rate, if applicable SupplyMassFlowRate = max(0.0, OAMassFlowRate, SupplyMassFlowRateForHeat, SupplyMassFlowRateForDehum, SupplyMassFlowRateForHumid); // EMS override point Purch air massflow rate..... but only if unit is on, i.e. SupplyMassFlowRate>0.0 - if (PurchAir(PurchAirNum).EMSOverrideMdotOn) { - SupplyMassFlowRate = PurchAir(PurchAirNum).EMSValueMassFlowRate; + if (PurchAir.EMSOverrideMdotOn) { + SupplyMassFlowRate = PurchAir.EMSValueMassFlowRate; OAMassFlowRate = min(OAMassFlowRate, SupplyMassFlowRate); } - if (((PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRate) || - (PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRateAndCapacity)) && - (PurchAir(PurchAirNum).MaxHeatMassFlowRate > 0.0)) { - SupplyMassFlowRate = min(SupplyMassFlowRate, PurchAir(PurchAirNum).MaxHeatMassFlowRate); + if (((PurchAir.HeatingLimit == LimitType::LimitFlowRate) || (PurchAir.HeatingLimit == LimitType::LimitFlowRateAndCapacity)) && + (PurchAir.MaxHeatMassFlowRate > 0.0)) { + SupplyMassFlowRate = min(SupplyMassFlowRate, PurchAir.MaxHeatMassFlowRate); } if (SupplyMassFlowRate <= HVAC::VerySmallMassFlow) SupplyMassFlowRate = 0.0; @@ -2620,8 +2514,8 @@ void CalcPurchAirLoads(EnergyPlusData &state, PurchAirNum, OAMassFlowRate, SupplyMassFlowRate, - PurchAir(PurchAirNum).MixedAirTemp, - PurchAir(PurchAirNum).MixedAirHumRat, + PurchAir.MixedAirTemp, + PurchAir.MixedAirHumRat, MixedAirEnthalpy, OperatingMode); @@ -2631,97 +2525,93 @@ void CalcPurchAirLoads(EnergyPlusData &state, if ((HeatOn) && (OperatingMode == OpMode::Heat)) { // Calculate supply temp at SupplyMassFlowRate and check limit on Maximum Heating Supply Air Temperature CpAir = PsyCpAirFnW(thisZoneHB.airHumRat); - PurchAir(PurchAirNum).SupplyTemp = QZnHeatSP / (CpAir * SupplyMassFlowRate) + state.dataLoopNodes->Node(ZoneNodeNum).Temp; - PurchAir(PurchAirNum).SupplyTemp = min(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).MaxHeatSuppAirTemp); + PurchAir.SupplyTemp = QZnHeatSP / (CpAir * SupplyMassFlowRate) + state.dataLoopNodes->Node(ZoneNodeNum).Temp; + PurchAir.SupplyTemp = min(PurchAir.SupplyTemp, PurchAir.MaxHeatSuppAirTemp); // This is the heating mode, so SupplyTemp can't be less than MixedAirTemp - PurchAir(PurchAirNum).SupplyTemp = max(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).MixedAirTemp); + PurchAir.SupplyTemp = max(PurchAir.SupplyTemp, PurchAir.MixedAirTemp); // Check max heating capacity, if specified - if ((PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitCapacity) || - (PurchAir(PurchAirNum).HeatingLimit == LimitType::LimitFlowRateAndCapacity)) { - CpAir = PsyCpAirFnW(PurchAir(PurchAirNum).MixedAirHumRat); - HeatSensOutput = SupplyMassFlowRate * CpAir * (PurchAir(PurchAirNum).SupplyTemp - PurchAir(PurchAirNum).MixedAirTemp); - if (HeatSensOutput > PurchAir(PurchAirNum).MaxHeatSensCap) { - PurchAir(PurchAirNum).SupplyTemp = - PurchAir(PurchAirNum).MaxHeatSensCap / (SupplyMassFlowRate * CpAir) + PurchAir(PurchAirNum).MixedAirTemp; - HeatSensOutput = PurchAir(PurchAirNum).MaxHeatSensCap; + if ((PurchAir.HeatingLimit == LimitType::LimitCapacity) || (PurchAir.HeatingLimit == LimitType::LimitFlowRateAndCapacity)) { + CpAir = PsyCpAirFnW(PurchAir.MixedAirHumRat); + HeatSensOutput = SupplyMassFlowRate * CpAir * (PurchAir.SupplyTemp - PurchAir.MixedAirTemp); + if (HeatSensOutput > PurchAir.MaxHeatSensCap) { + PurchAir.SupplyTemp = PurchAir.MaxHeatSensCap / (SupplyMassFlowRate * CpAir) + PurchAir.MixedAirTemp; + HeatSensOutput = PurchAir.MaxHeatSensCap; } } } else { // Heat is off or operating mode is deadband (i.e. don't do any heating) - PurchAir(PurchAirNum).SupplyTemp = PurchAir(PurchAirNum).MixedAirTemp; + PurchAir.SupplyTemp = PurchAir.MixedAirTemp; } // Set supply humidity ratio first for heating/humidification - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; - switch (PurchAir(PurchAirNum).HumidCtrlType) { + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; + switch (PurchAir.HumidCtrlType) { case HumControl::None: { - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; } break; case HumControl::Humidistat: { MdotZnHumidSP = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).RemainingOutputReqToHumidSP; SupplyHumRatForHumid = MdotZnHumidSP / SupplyMassFlowRate + state.dataLoopNodes->Node(ZoneNodeNum).HumRat; - SupplyHumRatForHumid = min(SupplyHumRatForHumid, PurchAir(PurchAirNum).MaxHeatSuppAirHumRat); - PurchAir(PurchAirNum).SupplyHumRat = max(PurchAir(PurchAirNum).SupplyHumRat, SupplyHumRatForHumid); + SupplyHumRatForHumid = min(SupplyHumRatForHumid, PurchAir.MaxHeatSuppAirHumRat); + PurchAir.SupplyHumRat = max(PurchAir.SupplyHumRat, SupplyHumRatForHumid); } break; case HumControl::ConstantSupplyHumidityRatio: { if (OperatingMode == OpMode::Heat) { // If this results in dehumidification, must check cooling capacity limit - if (PurchAir(PurchAirNum).MixedAirHumRat > PurchAir(PurchAirNum).MaxHeatSuppAirHumRat) { - if ((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitCapacity) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity)) { - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MaxHeatSuppAirHumRat; - SupplyEnthalpy = PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).SupplyHumRat); + if (PurchAir.MixedAirHumRat > PurchAir.MaxHeatSuppAirHumRat) { + if ((PurchAir.CoolingLimit == LimitType::LimitCapacity) || + (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity)) { + PurchAir.SupplyHumRat = PurchAir.MaxHeatSuppAirHumRat; + SupplyEnthalpy = PsyHFnTdbW(PurchAir.SupplyTemp, PurchAir.SupplyHumRat); CoolTotOutput = SupplyMassFlowRate * (MixedAirEnthalpy - SupplyEnthalpy); - CpAir = PsyCpAirFnW(PurchAir(PurchAirNum).MixedAirHumRat); - CoolSensOutput = SupplyMassFlowRate * CpAir * (PurchAir(PurchAirNum).MixedAirTemp - PurchAir(PurchAirNum).SupplyTemp); + CpAir = PsyCpAirFnW(PurchAir.MixedAirHumRat); + CoolSensOutput = SupplyMassFlowRate * CpAir * (PurchAir.MixedAirTemp - PurchAir.SupplyTemp); CoolLatOutput = CoolTotOutput - CoolSensOutput; - if (CoolLatOutput >= PurchAir(PurchAirNum).MaxCoolTotCap) { - CoolLatOutput = PurchAir(PurchAirNum).MaxCoolTotCap; + if (CoolLatOutput >= PurchAir.MaxCoolTotCap) { + CoolLatOutput = PurchAir.MaxCoolTotCap; CoolTotOutput = CoolSensOutput + CoolLatOutput; SupplyEnthalpy = MixedAirEnthalpy - CoolTotOutput / SupplyMassFlowRate; - PurchAir(PurchAirNum).SupplyHumRat = - PsyWFnTdbH(state, PurchAir(PurchAirNum).SupplyTemp, SupplyEnthalpy, RoutineName); + PurchAir.SupplyHumRat = PsyWFnTdbH(state, PurchAir.SupplyTemp, SupplyEnthalpy, RoutineName); } } else { - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MaxHeatSuppAirHumRat; + PurchAir.SupplyHumRat = PurchAir.MaxHeatSuppAirHumRat; } } else { - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MaxHeatSuppAirHumRat; + PurchAir.SupplyHumRat = PurchAir.MaxHeatSuppAirHumRat; } } else { - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; } } break; default: { - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; } break; } - SupplyEnthalpy = PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).SupplyHumRat); + // SupplyEnthalpy = PsyHFnTdbW(PurchAir.SupplyTemp, PurchAir.SupplyHumRat); // Check supply humidity ratio for dehumidification (SupplyHumRatForHumid should always be < SupplyHumRatForDehum) // This section is the heating/deadband section, so dehumidification should activate // only if dehumidification control = humidistat // and if humidification control = humidistat or none or if operating in deadband mode if (CoolOn) { - if (PurchAir(PurchAirNum).DehumidCtrlType == HumControl::Humidistat) { - if ((PurchAir(PurchAirNum).HumidCtrlType == HumControl::Humidistat) || - (PurchAir(PurchAirNum).HumidCtrlType == HumControl::None) || (OperatingMode == OpMode::DeadBand)) { + if (PurchAir.DehumidCtrlType == HumControl::Humidistat) { + if ((PurchAir.HumidCtrlType == HumControl::Humidistat) || (PurchAir.HumidCtrlType == HumControl::None) || + (OperatingMode == OpMode::DeadBand)) { MdotZnDehumidSP = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).RemainingOutputReqToDehumidSP; SupplyHumRatForDehum = MdotZnDehumidSP / SupplyMassFlowRate + state.dataLoopNodes->Node(ZoneNodeNum).HumRat; - SupplyHumRatForDehum = max(SupplyHumRatForDehum, PurchAir(PurchAirNum).MinCoolSuppAirHumRat); - PurchAir(PurchAirNum).SupplyHumRat = min(PurchAir(PurchAirNum).SupplyHumRat, SupplyHumRatForDehum); - SupplyEnthalpy = PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).SupplyHumRat); - if (PurchAir(PurchAirNum).SupplyHumRat < PurchAir(PurchAirNum).MixedAirHumRat) { + SupplyHumRatForDehum = max(SupplyHumRatForDehum, PurchAir.MinCoolSuppAirHumRat); + PurchAir.SupplyHumRat = min(PurchAir.SupplyHumRat, SupplyHumRatForDehum); + SupplyEnthalpy = PsyHFnTdbW(PurchAir.SupplyTemp, PurchAir.SupplyHumRat); + if (PurchAir.SupplyHumRat < PurchAir.MixedAirHumRat) { // At this point, the system is heating or deadband but dehumidifying, check max cooling cap limit - CpAir = PsyCpAirFnW(PurchAir(PurchAirNum).MixedAirHumRat); - SensOutput = SupplyMassFlowRate * CpAir * (PurchAir(PurchAirNum).SupplyTemp - PurchAir(PurchAirNum).MixedAirTemp); + CpAir = PsyCpAirFnW(PurchAir.MixedAirHumRat); + SensOutput = SupplyMassFlowRate * CpAir * (PurchAir.SupplyTemp - PurchAir.MixedAirTemp); LatOutput = SupplyMassFlowRate * (SupplyEnthalpy - MixedAirEnthalpy) - SensOutput; - if ((PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitCapacity) || - (PurchAir(PurchAirNum).CoolingLimit == LimitType::LimitFlowRateAndCapacity)) { - if (LatOutput > PurchAir(PurchAirNum).MaxCoolTotCap) { - LatOutput = PurchAir(PurchAirNum).MaxCoolTotCap; + if ((PurchAir.CoolingLimit == LimitType::LimitCapacity) || + (PurchAir.CoolingLimit == LimitType::LimitFlowRateAndCapacity)) { + if (LatOutput > PurchAir.MaxCoolTotCap) { + LatOutput = PurchAir.MaxCoolTotCap; SupplyEnthalpy = MixedAirEnthalpy + (LatOutput + SensOutput) / SupplyMassFlowRate; - PurchAir(PurchAirNum).SupplyHumRat = - PsyWFnTdbH(state, PurchAir(PurchAirNum).SupplyTemp, SupplyEnthalpy, RoutineName); + PurchAir.SupplyHumRat = PsyWFnTdbH(state, PurchAir.SupplyTemp, SupplyEnthalpy, RoutineName); } } } @@ -2731,16 +2621,15 @@ void CalcPurchAirLoads(EnergyPlusData &state, // Limit supply humidity ratio to saturation at supply outlet temp - SupplyHumRatOrig = PurchAir(PurchAirNum).SupplyHumRat; - PurchAir(PurchAirNum).SupplyHumRat = - min(PurchAir(PurchAirNum).SupplyHumRat, - PsyWFnTdbRhPb(state, PurchAir(PurchAirNum).SupplyTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineName)); - SupplyEnthalpy = PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).SupplyHumRat); + SupplyHumRatOrig = PurchAir.SupplyHumRat; + PurchAir.SupplyHumRat = + min(PurchAir.SupplyHumRat, PsyWFnTdbRhPb(state, PurchAir.SupplyTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineName)); + SupplyEnthalpy = PsyHFnTdbW(PurchAir.SupplyTemp, PurchAir.SupplyHumRat); } else { // SupplyMassFlowRate is zero SupplyEnthalpy = MixedAirEnthalpy; - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; - PurchAir(PurchAirNum).SupplyTemp = PurchAir(PurchAirNum).MixedAirTemp; + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; + PurchAir.SupplyTemp = PurchAir.MixedAirTemp; HeatSensOutput = 0.0; } @@ -2748,59 +2637,56 @@ void CalcPurchAirLoads(EnergyPlusData &state, if (SupplyMassFlowRate > 0.0) { // EMS override point Purch air supply temp and humidty ratio ..... but only if unit is on, SupplyMassFlowRate>0.0 - if (PurchAir(PurchAirNum).EMSOverrideSupplyTempOn) { - PurchAir(PurchAirNum).SupplyTemp = PurchAir(PurchAirNum).EMSValueSupplyTemp; + if (PurchAir.EMSOverrideSupplyTempOn) { + PurchAir.SupplyTemp = PurchAir.EMSValueSupplyTemp; } - if (PurchAir(PurchAirNum).EMSOverrideSupplyHumRatOn) { - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).EMSValueSupplyHumRat; + if (PurchAir.EMSOverrideSupplyHumRatOn) { + PurchAir.SupplyHumRat = PurchAir.EMSValueSupplyHumRat; } - SupplyEnthalpy = PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).SupplyHumRat); + SupplyEnthalpy = PsyHFnTdbW(PurchAir.SupplyTemp, PurchAir.SupplyHumRat); // compute coil loads - if ((PurchAir(PurchAirNum).SupplyHumRat == PurchAir(PurchAirNum).MixedAirHumRat) && - (PurchAir(PurchAirNum).SupplyTemp == PurchAir(PurchAirNum).MixedAirTemp)) { + if ((PurchAir.SupplyHumRat == PurchAir.MixedAirHumRat) && (PurchAir.SupplyTemp == PurchAir.MixedAirTemp)) { // If no change in humrat or temp, then set loads to zero - PurchAir(PurchAirNum).SenCoilLoad = 0.0; - PurchAir(PurchAirNum).LatCoilLoad = 0.0; - } else if ((PurchAir(PurchAirNum).SupplyHumRat == PurchAir(PurchAirNum).MixedAirHumRat) && - (PurchAir(PurchAirNum).SupplyTemp != PurchAir(PurchAirNum).MixedAirTemp)) { + PurchAir.SenCoilLoad = 0.0; + PurchAir.LatCoilLoad = 0.0; + } else if ((PurchAir.SupplyHumRat == PurchAir.MixedAirHumRat) && (PurchAir.SupplyTemp != PurchAir.MixedAirTemp)) { // If no change in humrat, then set latent load to zero and use enthalpies to calculate sensible load - PurchAir(PurchAirNum).SenCoilLoad = SupplyMassFlowRate * (SupplyEnthalpy - MixedAirEnthalpy); - PurchAir(PurchAirNum).LatCoilLoad = 0.0; + PurchAir.SenCoilLoad = SupplyMassFlowRate * (SupplyEnthalpy - MixedAirEnthalpy); + PurchAir.LatCoilLoad = 0.0; } else { - CpAir = PsyCpAirFnW(PurchAir(PurchAirNum).MixedAirHumRat); - PurchAir(PurchAirNum).SenCoilLoad = - SupplyMassFlowRate * CpAir * (PurchAir(PurchAirNum).SupplyTemp - PurchAir(PurchAirNum).MixedAirTemp); - PurchAir(PurchAirNum).LatCoilLoad = SupplyMassFlowRate * (SupplyEnthalpy - MixedAirEnthalpy) - PurchAir(PurchAirNum).SenCoilLoad; + CpAir = PsyCpAirFnW(PurchAir.MixedAirHumRat); + PurchAir.SenCoilLoad = SupplyMassFlowRate * CpAir * (PurchAir.SupplyTemp - PurchAir.MixedAirTemp); + PurchAir.LatCoilLoad = SupplyMassFlowRate * (SupplyEnthalpy - MixedAirEnthalpy) - PurchAir.SenCoilLoad; } // Apply heating and cooling availability schedules to sensible load - if (((PurchAir(PurchAirNum).SenCoilLoad > 0.0) && !HeatOn) || ((PurchAir(PurchAirNum).SenCoilLoad < 0.0) && !CoolOn)) { + if (((PurchAir.SenCoilLoad > 0.0) && !HeatOn) || ((PurchAir.SenCoilLoad < 0.0) && !CoolOn)) { // Coil is off - PurchAir(PurchAirNum).SenCoilLoad = 0.0; - PurchAir(PurchAirNum).SupplyTemp = PurchAir(PurchAirNum).MixedAirTemp; + PurchAir.SenCoilLoad = 0.0; + PurchAir.SupplyTemp = PurchAir.MixedAirTemp; } // Apply heating and cooling availability schedules to latent load - if (((PurchAir(PurchAirNum).LatCoilLoad > 0.0) && !HeatOn) || ((PurchAir(PurchAirNum).LatCoilLoad < 0.0) && !CoolOn)) { + if (((PurchAir.LatCoilLoad > 0.0) && !HeatOn) || ((PurchAir.LatCoilLoad < 0.0) && !CoolOn)) { // Coil is off - PurchAir(PurchAirNum).LatCoilLoad = 0.0; - PurchAir(PurchAirNum).SupplyHumRat = PurchAir(PurchAirNum).MixedAirHumRat; + PurchAir.LatCoilLoad = 0.0; + PurchAir.SupplyHumRat = PurchAir.MixedAirHumRat; } // Double-check if saturation exceeded, then thow warning, shouldn't happen here, don't reset, just warn - SupplyHumRatOrig = PurchAir(PurchAirNum).SupplyHumRat; - SupplyHumRatSat = PsyWFnTdbRhPb(state, PurchAir(PurchAirNum).SupplyTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineName); + SupplyHumRatOrig = PurchAir.SupplyHumRat; + SupplyHumRatSat = PsyWFnTdbRhPb(state, PurchAir.SupplyTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineName); DeltaHumRat = SupplyHumRatOrig - SupplyHumRatSat; if (DeltaHumRat > SmallDeltaHumRat) { - if (PurchAir(PurchAirNum).SaturationOutputError < 1) { - ++PurchAir(PurchAirNum).SaturationOutputError; + if (PurchAir.SaturationOutputError < 1) { + ++PurchAir.SaturationOutputError; ShowWarningError(state, format("{} \"{}\" Supply humidity ratio = {:.5T} exceeds saturation limit {:.5T} [kgWater/kgDryAir]", - PurchAir(PurchAirNum).cObjectName, - PurchAir(PurchAirNum).Name, + PurchAir.cObjectName, + PurchAir.Name, SupplyHumRatOrig, SupplyHumRatSat)); ShowContinueError(state, " Simulation continuing . . . "); @@ -2808,38 +2694,37 @@ void CalcPurchAirLoads(EnergyPlusData &state, } else { ShowRecurringWarningErrorAtEnd( state, - PurchAir(PurchAirNum).cObjectName + " \"" + PurchAir(PurchAirNum).Name + + PurchAir.cObjectName + " \"" + PurchAir.Name + "\" Supply humidity ratio exceeds saturation limit warning continues, delta max/min [kgWater/kgDryAir]...", - PurchAir(PurchAirNum).SaturationOutputIndex, + PurchAir.SaturationOutputIndex, DeltaHumRat, DeltaHumRat); } } - SupplyEnthalpy = PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).SupplyHumRat); + SupplyEnthalpy = PsyHFnTdbW(PurchAir.SupplyTemp, PurchAir.SupplyHumRat); CpAir = PsyCpAirFnW(thisZoneHB.airHumRat); - SysOutputProvided = SupplyMassFlowRate * CpAir * (PurchAir(PurchAirNum).SupplyTemp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); - MoistOutputProvided = - SupplyMassFlowRate * (PurchAir(PurchAirNum).SupplyHumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); // Latent rate, kg/s + SysOutputProvided = SupplyMassFlowRate * CpAir * (PurchAir.SupplyTemp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); + MoistOutputProvided = SupplyMassFlowRate * (PurchAir.SupplyHumRat - state.dataLoopNodes->Node(ZoneNodeNum).HumRat); // Latent rate, kg/s - PurchAir(PurchAirNum).SenOutputToZone = SysOutputProvided; - PurchAir(PurchAirNum).LatOutputToZone = - SupplyMassFlowRate * (SupplyEnthalpy - state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy) - PurchAir(PurchAirNum).SenOutputToZone; + PurchAir.SenOutputToZone = SysOutputProvided; + PurchAir.LatOutputToZone = + SupplyMassFlowRate * (SupplyEnthalpy - state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy) - PurchAir.SenOutputToZone; CpAir = PsyCpAirFnW(thisZoneHB.airHumRat); - if (PurchAir(PurchAirNum).OutdoorAir) { - PurchAir(PurchAirNum).OASenOutput = + if (PurchAir.OutdoorAir) { + PurchAir.OASenOutput = OAMassFlowRate * CpAir * (state.dataLoopNodes->Node(OANodeNum).Temp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); - PurchAir(PurchAirNum).OALatOutput = + PurchAir.OALatOutput = OAMassFlowRate * (state.dataLoopNodes->Node(OANodeNum).Enthalpy - state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy) - - PurchAir(PurchAirNum).OASenOutput; + PurchAir.OASenOutput; } else { - PurchAir(PurchAirNum).OASenOutput = 0.0; - PurchAir(PurchAirNum).OALatOutput = 0.0; + PurchAir.OASenOutput = 0.0; + PurchAir.OALatOutput = 0.0; } if (state.dataContaminantBalance->Contaminant.CO2Simulation) { - if (PurchAir(PurchAirNum).OutdoorAir) { + if (PurchAir.OutdoorAir) { state.dataLoopNodes->Node(InNodeNum).CO2 = ((SupplyMassFlowRate - OAMassFlowRate) * state.dataLoopNodes->Node(RecircNodeNum).CO2 + OAMassFlowRate * state.dataLoopNodes->Node(OANodeNum).CO2) / SupplyMassFlowRate; @@ -2848,7 +2733,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, } } if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) { - if (PurchAir(PurchAirNum).OutdoorAir) { + if (PurchAir.OutdoorAir) { state.dataLoopNodes->Node(InNodeNum).GenContam = ((SupplyMassFlowRate - OAMassFlowRate) * state.dataLoopNodes->Node(RecircNodeNum).GenContam + OAMassFlowRate * state.dataLoopNodes->Node(OANodeNum).GenContam) / @@ -2861,15 +2746,15 @@ void CalcPurchAirLoads(EnergyPlusData &state, SysOutputProvided = 0.0; MoistOutputProvided = 0.0; - PurchAir(PurchAirNum).SenOutputToZone = 0.0; - PurchAir(PurchAirNum).LatOutputToZone = 0.0; - PurchAir(PurchAirNum).SenCoilLoad = 0.0; - PurchAir(PurchAirNum).LatCoilLoad = 0.0; - PurchAir(PurchAirNum).OASenOutput = 0.0; - PurchAir(PurchAirNum).OALatOutput = 0.0; + PurchAir.SenOutputToZone = 0.0; + PurchAir.LatOutputToZone = 0.0; + PurchAir.SenCoilLoad = 0.0; + PurchAir.LatCoilLoad = 0.0; + PurchAir.OASenOutput = 0.0; + PurchAir.OALatOutput = 0.0; - PurchAir(PurchAirNum).MixedAirTemp = state.dataLoopNodes->Node(RecircNodeNum).Temp; - PurchAir(PurchAirNum).MixedAirHumRat = state.dataLoopNodes->Node(RecircNodeNum).HumRat; + PurchAir.MixedAirTemp = state.dataLoopNodes->Node(RecircNodeNum).Temp; + PurchAir.MixedAirHumRat = state.dataLoopNodes->Node(RecircNodeNum).HumRat; if (state.dataContaminantBalance->Contaminant.CO2Simulation) { state.dataLoopNodes->Node(InNodeNum).CO2 = state.dataLoopNodes->Node(ZoneNodeNum).CO2; @@ -2879,11 +2764,11 @@ void CalcPurchAirLoads(EnergyPlusData &state, } } - state.dataLoopNodes->Node(InNodeNum).Temp = PurchAir(PurchAirNum).SupplyTemp; - state.dataLoopNodes->Node(InNodeNum).HumRat = PurchAir(PurchAirNum).SupplyHumRat; + state.dataLoopNodes->Node(InNodeNum).Temp = PurchAir.SupplyTemp; + state.dataLoopNodes->Node(InNodeNum).HumRat = PurchAir.SupplyHumRat; state.dataLoopNodes->Node(InNodeNum).Enthalpy = SupplyEnthalpy; state.dataLoopNodes->Node(InNodeNum).MassFlowRate = SupplyMassFlowRate; - if (PurchAir(PurchAirNum).OutdoorAir) state.dataLoopNodes->Node(OANodeNum).MassFlowRate = OAMassFlowRate; + if (PurchAir.OutdoorAir) state.dataLoopNodes->Node(OANodeNum).MassFlowRate = OAMassFlowRate; } else { // purchased air OFF @@ -2902,31 +2787,31 @@ void CalcPurchAirLoads(EnergyPlusData &state, } state.dataLoopNodes->Node(InNodeNum).MassFlowRate = 0.0; - if (PurchAir(PurchAirNum).OutdoorAir) state.dataLoopNodes->Node(OANodeNum).MassFlowRate = 0.0; - PurchAir(PurchAirNum).SenHeatRate = 0.0; - PurchAir(PurchAirNum).SenCoolRate = 0.0; - PurchAir(PurchAirNum).TotCoolRate = 0.0; - - PurchAir(PurchAirNum).SenOutputToZone = 0.0; - PurchAir(PurchAirNum).LatOutputToZone = 0.0; - PurchAir(PurchAirNum).SenCoilLoad = 0.0; - PurchAir(PurchAirNum).LatCoilLoad = 0.0; - PurchAir(PurchAirNum).OASenOutput = 0.0; - PurchAir(PurchAirNum).OALatOutput = 0.0; - PurchAir(PurchAirNum).MixedAirTemp = state.dataLoopNodes->Node(RecircNodeNum).Temp; - PurchAir(PurchAirNum).MixedAirHumRat = state.dataLoopNodes->Node(RecircNodeNum).HumRat; - PurchAir(PurchAirNum).SupplyTemp = state.dataLoopNodes->Node(InNodeNum).Temp; - PurchAir(PurchAirNum).SupplyHumRat = state.dataLoopNodes->Node(InNodeNum).HumRat; + if (PurchAir.OutdoorAir) state.dataLoopNodes->Node(OANodeNum).MassFlowRate = 0.0; + PurchAir.SenHeatRate = 0.0; + PurchAir.SenCoolRate = 0.0; + PurchAir.TotCoolRate = 0.0; + + PurchAir.SenOutputToZone = 0.0; + PurchAir.LatOutputToZone = 0.0; + PurchAir.SenCoilLoad = 0.0; + PurchAir.LatCoilLoad = 0.0; + PurchAir.OASenOutput = 0.0; + PurchAir.OALatOutput = 0.0; + PurchAir.MixedAirTemp = state.dataLoopNodes->Node(RecircNodeNum).Temp; + PurchAir.MixedAirHumRat = state.dataLoopNodes->Node(RecircNodeNum).HumRat; + PurchAir.SupplyTemp = state.dataLoopNodes->Node(InNodeNum).Temp; + PurchAir.SupplyHumRat = state.dataLoopNodes->Node(InNodeNum).HumRat; } - PurchAir(PurchAirNum).OutdoorAirMassFlowRate = OAMassFlowRate; - PurchAir(PurchAirNum).OutdoorAirVolFlowRateStdRho = OAMassFlowRate / state.dataEnvrn->StdRhoAir; - PurchAir(PurchAirNum).SupplyAirMassFlowRate = SupplyMassFlowRate; + PurchAir.OutdoorAirMassFlowRate = OAMassFlowRate; + PurchAir.OutdoorAirVolFlowRateStdRho = OAMassFlowRate / state.dataEnvrn->StdRhoAir; + PurchAir.SupplyAirMassFlowRate = SupplyMassFlowRate; - PurchAir(PurchAirNum).SupplyAirVolFlowRateStdRho = SupplyMassFlowRate / state.dataEnvrn->StdRhoAir; + PurchAir.SupplyAirVolFlowRateStdRho = SupplyMassFlowRate / state.dataEnvrn->StdRhoAir; - if (PurchAir(PurchAirNum).PlenumExhaustAirNodeNum > 0) { - state.dataLoopNodes->Node(PurchAir(PurchAirNum).PlenumExhaustAirNodeNum).MassFlowRate = SupplyMassFlowRate; + if (PurchAir.PlenumExhaustAirNodeNum > 0) { + state.dataLoopNodes->Node(PurchAir.PlenumExhaustAirNodeNum).MassFlowRate = SupplyMassFlowRate; } state.dataLoopNodes->Node(RecircNodeNum).MassFlowRate = SupplyMassFlowRate; } @@ -2941,8 +2826,6 @@ void CalcPurchAirMinOAMassFlow(EnergyPlusData &state, // SUBROUTINE INFORMATION: // AUTHOR M. Witte (GARD) // DATE WRITTEN Jun 2011 (taken from HVACSingleDuctSystem.cc and adapted for Ideal Loads System) - // MODIFIED na - // RE-ENGINEERED na // PURPOSE OF THIS SUBROUTINE: // Calculates the amount of outside air required based on optional user input. @@ -2952,27 +2835,24 @@ void CalcPurchAirMinOAMassFlow(EnergyPlusData &state, // User input defines method used to calculate OA. // FUNCTION PARAMETER DEFINITIONS: - bool constexpr UseMinOASchFlag(true); // Always use min OA schedule in calculations. - - // FUNCTION LOCAL VARIABLE DECLARATIONS: - bool UseOccSchFlag; // TRUE = use actual occupancy, FALSE = use total zone people - Real64 OAVolumeFlowRate; // outside air flow rate (m3/s) + bool constexpr UseMinOASchFlag = true; // Always use min OA schedule in calculations. - auto &PurchAir(state.dataPurchasedAirMgr->PurchAir); + auto &PurchAir = state.dataPurchasedAirMgr->PurchAir(PurchAirNum); - if (PurchAir(PurchAirNum).OutdoorAir) { + if (PurchAir.OutdoorAir) { + bool UseOccSchFlag; // TRUE = use actual occupancy, FALSE = use total zone people - if (PurchAir(PurchAirNum).DCVType == DCV::OccupancySchedule) { + if (PurchAir.DCVType == DCV::OccupancySchedule) { UseOccSchFlag = true; } else { UseOccSchFlag = false; } - OAVolumeFlowRate = - DataSizing::calcDesignSpecificationOutdoorAir(state, PurchAir(PurchAirNum).OARequirementsPtr, ZoneNum, UseOccSchFlag, UseMinOASchFlag); + Real64 OAVolumeFlowRate = + DataSizing::calcDesignSpecificationOutdoorAir(state, PurchAir.OARequirementsPtr, ZoneNum, UseOccSchFlag, UseMinOASchFlag); OAMassFlowRate = OAVolumeFlowRate * state.dataEnvrn->StdRhoAir; // If DCV with CO2SetPoint then check required OA flow to meet CO2 setpoint - if (PurchAir(PurchAirNum).DCVType == DCV::CO2SetPoint) { + if (PurchAir.DCVType == DCV::CO2SetPoint) { OAMassFlowRate = max(OAMassFlowRate, state.dataContaminantBalance->ZoneSysContDemand(ZoneNum).OutputRequiredToCO2SP); } @@ -2981,7 +2861,7 @@ void CalcPurchAirMinOAMassFlow(EnergyPlusData &state, } else { // No outdoor air OAMassFlowRate = 0.0; } - PurchAir(PurchAirNum).MinOAMassFlowRate = OAMassFlowRate; + PurchAir.MinOAMassFlowRate = OAMassFlowRate; } void CalcPurchAirMixedAir(EnergyPlusData &state, @@ -3023,17 +2903,17 @@ void CalcPurchAirMixedAir(EnergyPlusData &state, bool HeatRecOn; Real64 CpAir; // Specific heat [J/kg-C] reused in multiple places - auto &PurchAir(state.dataPurchasedAirMgr->PurchAir); + auto &PurchAir = state.dataPurchasedAirMgr->PurchAir(PurchAirNum); // Initializations - OANodeNum = PurchAir(PurchAirNum).OutdoorAirNodeNum; - RecircNodeNum = PurchAir(PurchAirNum).ZoneRecircAirNodeNum; + OANodeNum = PurchAir.OutdoorAirNodeNum; + RecircNodeNum = PurchAir.ZoneRecircAirNodeNum; RecircMassFlowRate = 0.0; RecircTemp = state.dataLoopNodes->Node(RecircNodeNum).Temp; RecircHumRat = state.dataLoopNodes->Node(RecircNodeNum).HumRat; RecircEnthalpy = state.dataLoopNodes->Node(RecircNodeNum).Enthalpy; - if (PurchAir(PurchAirNum).OutdoorAir) { + if (PurchAir.OutdoorAir) { OAInletTemp = state.dataLoopNodes->Node(OANodeNum).Temp; OAInletHumRat = state.dataLoopNodes->Node(OANodeNum).HumRat; OAInletEnthalpy = state.dataLoopNodes->Node(OANodeNum).Enthalpy; @@ -3050,22 +2930,22 @@ void CalcPurchAirMixedAir(EnergyPlusData &state, } HeatRecOn = false; - if (PurchAir(PurchAirNum).OutdoorAir && (OAMassFlowRate > 0.0)) { + if (PurchAir.OutdoorAir && (OAMassFlowRate > 0.0)) { // Determine if heat recovery is beneficial - if (PurchAir(PurchAirNum).HtRecType == HeatRecovery::Sensible) { + if (PurchAir.HtRecType == HeatRecovery::Sensible) { if ((OperatingMode == OpMode::Heat) && (RecircTemp > OAInletTemp)) HeatRecOn = true; if ((OperatingMode == OpMode::Cool) && (RecircTemp < OAInletTemp)) HeatRecOn = true; } - if (PurchAir(PurchAirNum).HtRecType == HeatRecovery::Enthalpy) { + if (PurchAir.HtRecType == HeatRecovery::Enthalpy) { if ((OperatingMode == OpMode::Heat) && (RecircEnthalpy > OAInletEnthalpy)) HeatRecOn = true; if ((OperatingMode == OpMode::Cool) && (RecircEnthalpy < OAInletEnthalpy)) HeatRecOn = true; } // Calculate heat recovery if active if (HeatRecOn) { - PurchAir(PurchAirNum).TimeHtRecActive = state.dataHVACGlobal->TimeStepSys; - OAAfterHtRecTemp = OAInletTemp + PurchAir(PurchAirNum).HtRecSenEff * (RecircTemp - OAInletTemp); - if (PurchAir(PurchAirNum).HtRecType == HeatRecovery::Enthalpy) - OAAfterHtRecHumRat = OAInletHumRat + PurchAir(PurchAirNum).HtRecLatEff * (RecircHumRat - OAInletHumRat); + PurchAir.TimeHtRecActive = state.dataHVACGlobal->TimeStepSys; + OAAfterHtRecTemp = OAInletTemp + PurchAir.HtRecSenEff * (RecircTemp - OAInletTemp); + if (PurchAir.HtRecType == HeatRecovery::Enthalpy) + OAAfterHtRecHumRat = OAInletHumRat + PurchAir.HtRecLatEff * (RecircHumRat - OAInletHumRat); OAAfterHtRecEnthalpy = PsyHFnTdbW(OAAfterHtRecTemp, OAAfterHtRecHumRat); // Check for saturation in supply outlet and reset temp, then humidity ratio at constant enthalpy if (PsyTsatFnHPb(state, OAAfterHtRecEnthalpy, state.dataEnvrn->OutBaroPress, RoutineName) > OAAfterHtRecTemp) { @@ -3091,16 +2971,16 @@ void CalcPurchAirMixedAir(EnergyPlusData &state, // Calculate OA and heat recovery sensible and latent rates CpAir = PsyCpAirFnW(OAInletHumRat); - PurchAir(PurchAirNum).HtRecSenOutput = OAMassFlowRate * CpAir * (OAAfterHtRecTemp - OAInletTemp); - PurchAir(PurchAirNum).HtRecLatOutput = OAMassFlowRate * (OAAfterHtRecEnthalpy - OAInletEnthalpy) - PurchAir(PurchAirNum).HtRecSenOutput; + PurchAir.HtRecSenOutput = OAMassFlowRate * CpAir * (OAAfterHtRecTemp - OAInletTemp); + PurchAir.HtRecLatOutput = OAMassFlowRate * (OAAfterHtRecEnthalpy - OAInletEnthalpy) - PurchAir.HtRecSenOutput; } else { // No outdoor air RecircMassFlowRate = SupplyMassFlowRate; MixedAirTemp = RecircTemp; MixedAirHumRat = RecircHumRat; MixedAirEnthalpy = RecircEnthalpy; - PurchAir(PurchAirNum).HtRecSenOutput = 0.0; - PurchAir(PurchAirNum).HtRecLatOutput = 0.0; + PurchAir.HtRecSenOutput = 0.0; + PurchAir.HtRecLatOutput = 0.0; } } @@ -3127,25 +3007,24 @@ void UpdatePurchasedAir(EnergyPlusData &state, int const PurchAirNum, bool const FirstCall = true; // just used to avoid redundant calulations SupPathInletChanged = false; // don't care if something changes - auto &PurchAir(state.dataPurchasedAirMgr->PurchAir); + auto &PurchAir = state.dataPurchasedAirMgr->PurchAir(PurchAirNum); - if (PurchAir(PurchAirNum).ReturnPlenumIndex > 0) { + if (PurchAir.ReturnPlenumIndex > 0) { // if connected to a return plenum, set the flag that this ideal loads air system was simulated - state.dataPurchasedAirMgr->PurchAirPlenumArrays(PurchAir(PurchAirNum).ReturnPlenumIndex) - .IsSimulated(PurchAir(PurchAirNum).PurchAirArrayIndex) = true; + state.dataPurchasedAirMgr->PurchAirPlenumArrays(PurchAir.ReturnPlenumIndex).IsSimulated(PurchAir.PurchAirArrayIndex) = true; // if all ideal loads air systems connected to the same plenum have been simulated, simulate the zone air plenum - if (all(state.dataPurchasedAirMgr->PurchAirPlenumArrays(PurchAir(PurchAirNum).ReturnPlenumIndex).IsSimulated)) { + if (all(state.dataPurchasedAirMgr->PurchAirPlenumArrays(PurchAir.ReturnPlenumIndex).IsSimulated)) { SimAirZonePlenum(state, - PurchAir(PurchAirNum).ReturnPlenumName, + PurchAir.ReturnPlenumName, DataZoneEquipment::AirLoopHVACZone::ReturnPlenum, - PurchAir(PurchAirNum).ReturnPlenumIndex, + PurchAir.ReturnPlenumIndex, FirstHVACIteration, FirstCall, SupPathInletChanged); // reset this plenums flags for next iteration - state.dataPurchasedAirMgr->PurchAirPlenumArrays(PurchAir(PurchAirNum).ReturnPlenumIndex).IsSimulated = false; + state.dataPurchasedAirMgr->PurchAirPlenumArrays(PurchAir.ReturnPlenumIndex).IsSimulated = false; } } } @@ -3165,84 +3044,84 @@ void ReportPurchasedAir(EnergyPlusData &state, int const PurchAirNum) // Using/Aliasing Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec; - auto &PurchAir(state.dataPurchasedAirMgr->PurchAir); + auto &PurchAir = state.dataPurchasedAirMgr->PurchAir(PurchAirNum); // Sort out heating and cooling rates - PurchAir(PurchAirNum).SenHeatRate = max(PurchAir(PurchAirNum).SenCoilLoad, 0.0); - PurchAir(PurchAirNum).SenCoolRate = std::abs(min(PurchAir(PurchAirNum).SenCoilLoad, 0.0)); - PurchAir(PurchAirNum).LatHeatRate = max(PurchAir(PurchAirNum).LatCoilLoad, 0.0); - PurchAir(PurchAirNum).LatCoolRate = std::abs(min(PurchAir(PurchAirNum).LatCoilLoad, 0.0)); - PurchAir(PurchAirNum).TotHeatRate = PurchAir(PurchAirNum).SenHeatRate + PurchAir(PurchAirNum).LatHeatRate; - PurchAir(PurchAirNum).TotCoolRate = PurchAir(PurchAirNum).SenCoolRate + PurchAir(PurchAirNum).LatCoolRate; - - PurchAir(PurchAirNum).ZoneSenHeatRate = max(PurchAir(PurchAirNum).SenOutputToZone, 0.0); - PurchAir(PurchAirNum).ZoneSenCoolRate = std::abs(min(PurchAir(PurchAirNum).SenOutputToZone, 0.0)); - PurchAir(PurchAirNum).ZoneLatHeatRate = max(PurchAir(PurchAirNum).LatOutputToZone, 0.0); - PurchAir(PurchAirNum).ZoneLatCoolRate = std::abs(min(PurchAir(PurchAirNum).LatOutputToZone, 0.0)); - PurchAir(PurchAirNum).ZoneTotHeatRate = PurchAir(PurchAirNum).ZoneSenHeatRate + PurchAir(PurchAirNum).ZoneLatHeatRate; - PurchAir(PurchAirNum).ZoneTotCoolRate = PurchAir(PurchAirNum).ZoneSenCoolRate + PurchAir(PurchAirNum).ZoneLatCoolRate; + PurchAir.SenHeatRate = max(PurchAir.SenCoilLoad, 0.0); + PurchAir.SenCoolRate = std::abs(min(PurchAir.SenCoilLoad, 0.0)); + PurchAir.LatHeatRate = max(PurchAir.LatCoilLoad, 0.0); + PurchAir.LatCoolRate = std::abs(min(PurchAir.LatCoilLoad, 0.0)); + PurchAir.TotHeatRate = PurchAir.SenHeatRate + PurchAir.LatHeatRate; + PurchAir.TotCoolRate = PurchAir.SenCoolRate + PurchAir.LatCoolRate; + + PurchAir.ZoneSenHeatRate = max(PurchAir.SenOutputToZone, 0.0); + PurchAir.ZoneSenCoolRate = std::abs(min(PurchAir.SenOutputToZone, 0.0)); + PurchAir.ZoneLatHeatRate = max(PurchAir.LatOutputToZone, 0.0); + PurchAir.ZoneLatCoolRate = std::abs(min(PurchAir.LatOutputToZone, 0.0)); + PurchAir.ZoneTotHeatRate = PurchAir.ZoneSenHeatRate + PurchAir.ZoneLatHeatRate; + PurchAir.ZoneTotCoolRate = PurchAir.ZoneSenCoolRate + PurchAir.ZoneLatCoolRate; // Sort out outdoor air "loads" // OASenOutput = Outdoor air sensible output relative to zone conditions [W], <0 means OA is cooler than zone air // OALatOutput = Outdoor air latent output relative to zone conditions [W], <0 means OA is drier than zone air - if (PurchAir(PurchAirNum).SenCoilLoad > 0.0) { // Heating is active - PurchAir(PurchAirNum).OASenHeatRate = std::abs(min(PurchAir(PurchAirNum).OASenOutput, 0.0)); + if (PurchAir.SenCoilLoad > 0.0) { // Heating is active + PurchAir.OASenHeatRate = std::abs(min(PurchAir.OASenOutput, 0.0)); } else { - PurchAir(PurchAirNum).OASenHeatRate = 0.0; + PurchAir.OASenHeatRate = 0.0; } - if (PurchAir(PurchAirNum).SenCoilLoad < 0.0) { // Cooling is active - PurchAir(PurchAirNum).OASenCoolRate = max(PurchAir(PurchAirNum).OASenOutput, 0.0); + if (PurchAir.SenCoilLoad < 0.0) { // Cooling is active + PurchAir.OASenCoolRate = max(PurchAir.OASenOutput, 0.0); } else { - PurchAir(PurchAirNum).OASenCoolRate = 0.0; + PurchAir.OASenCoolRate = 0.0; } - if (PurchAir(PurchAirNum).LatCoilLoad > 0.0) { // Humidification is active - PurchAir(PurchAirNum).OALatHeatRate = std::abs(min(PurchAir(PurchAirNum).OALatOutput, 0.0)); + if (PurchAir.LatCoilLoad > 0.0) { // Humidification is active + PurchAir.OALatHeatRate = std::abs(min(PurchAir.OALatOutput, 0.0)); } else { - PurchAir(PurchAirNum).OALatHeatRate = 0.0; + PurchAir.OALatHeatRate = 0.0; } - if (PurchAir(PurchAirNum).LatCoilLoad < 0.0) { // Dehumidification is active - PurchAir(PurchAirNum).OALatCoolRate = max(PurchAir(PurchAirNum).OALatOutput, 0.0); + if (PurchAir.LatCoilLoad < 0.0) { // Dehumidification is active + PurchAir.OALatCoolRate = max(PurchAir.OALatOutput, 0.0); } else { - PurchAir(PurchAirNum).OALatCoolRate = 0.0; + PurchAir.OALatCoolRate = 0.0; } - PurchAir(PurchAirNum).OATotHeatRate = PurchAir(PurchAirNum).OASenHeatRate + PurchAir(PurchAirNum).OALatHeatRate; - PurchAir(PurchAirNum).OATotCoolRate = PurchAir(PurchAirNum).OASenCoolRate + PurchAir(PurchAirNum).OALatCoolRate; - - PurchAir(PurchAirNum).HtRecSenHeatRate = max(PurchAir(PurchAirNum).HtRecSenOutput, 0.0); - PurchAir(PurchAirNum).HtRecSenCoolRate = std::abs(min(PurchAir(PurchAirNum).HtRecSenOutput, 0.0)); - PurchAir(PurchAirNum).HtRecLatHeatRate = max(PurchAir(PurchAirNum).HtRecLatOutput, 0.0); - PurchAir(PurchAirNum).HtRecLatCoolRate = std::abs(min(PurchAir(PurchAirNum).HtRecLatOutput, 0.0)); - PurchAir(PurchAirNum).HtRecTotHeatRate = PurchAir(PurchAirNum).HtRecSenHeatRate + PurchAir(PurchAirNum).HtRecLatHeatRate; - PurchAir(PurchAirNum).HtRecTotCoolRate = PurchAir(PurchAirNum).HtRecSenCoolRate + PurchAir(PurchAirNum).HtRecLatCoolRate; - - PurchAir(PurchAirNum).SenHeatEnergy = PurchAir(PurchAirNum).SenHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).SenCoolEnergy = PurchAir(PurchAirNum).SenCoolRate * TimeStepSysSec; - PurchAir(PurchAirNum).LatHeatEnergy = PurchAir(PurchAirNum).LatHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).LatCoolEnergy = PurchAir(PurchAirNum).LatCoolRate * TimeStepSysSec; - PurchAir(PurchAirNum).TotHeatEnergy = PurchAir(PurchAirNum).TotHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).TotCoolEnergy = PurchAir(PurchAirNum).TotCoolRate * TimeStepSysSec; - - PurchAir(PurchAirNum).ZoneSenHeatEnergy = PurchAir(PurchAirNum).ZoneSenHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).ZoneSenCoolEnergy = PurchAir(PurchAirNum).ZoneSenCoolRate * TimeStepSysSec; - PurchAir(PurchAirNum).ZoneLatHeatEnergy = PurchAir(PurchAirNum).ZoneLatHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).ZoneLatCoolEnergy = PurchAir(PurchAirNum).ZoneLatCoolRate * TimeStepSysSec; - PurchAir(PurchAirNum).ZoneTotHeatEnergy = PurchAir(PurchAirNum).ZoneTotHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).ZoneTotCoolEnergy = PurchAir(PurchAirNum).ZoneTotCoolRate * TimeStepSysSec; - - PurchAir(PurchAirNum).OASenHeatEnergy = PurchAir(PurchAirNum).OASenHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).OASenCoolEnergy = PurchAir(PurchAirNum).OASenCoolRate * TimeStepSysSec; - PurchAir(PurchAirNum).OALatHeatEnergy = PurchAir(PurchAirNum).OALatHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).OALatCoolEnergy = PurchAir(PurchAirNum).OALatCoolRate * TimeStepSysSec; - PurchAir(PurchAirNum).OATotHeatEnergy = PurchAir(PurchAirNum).OATotHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).OATotCoolEnergy = PurchAir(PurchAirNum).OATotCoolRate * TimeStepSysSec; - - PurchAir(PurchAirNum).HtRecSenHeatEnergy = PurchAir(PurchAirNum).HtRecSenHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).HtRecSenCoolEnergy = PurchAir(PurchAirNum).HtRecSenCoolRate * TimeStepSysSec; - PurchAir(PurchAirNum).HtRecLatHeatEnergy = PurchAir(PurchAirNum).HtRecLatHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).HtRecLatCoolEnergy = PurchAir(PurchAirNum).HtRecLatCoolRate * TimeStepSysSec; - PurchAir(PurchAirNum).HtRecTotHeatEnergy = PurchAir(PurchAirNum).HtRecTotHeatRate * TimeStepSysSec; - PurchAir(PurchAirNum).HtRecTotCoolEnergy = PurchAir(PurchAirNum).HtRecTotCoolRate * TimeStepSysSec; + PurchAir.OATotHeatRate = PurchAir.OASenHeatRate + PurchAir.OALatHeatRate; + PurchAir.OATotCoolRate = PurchAir.OASenCoolRate + PurchAir.OALatCoolRate; + + PurchAir.HtRecSenHeatRate = max(PurchAir.HtRecSenOutput, 0.0); + PurchAir.HtRecSenCoolRate = std::abs(min(PurchAir.HtRecSenOutput, 0.0)); + PurchAir.HtRecLatHeatRate = max(PurchAir.HtRecLatOutput, 0.0); + PurchAir.HtRecLatCoolRate = std::abs(min(PurchAir.HtRecLatOutput, 0.0)); + PurchAir.HtRecTotHeatRate = PurchAir.HtRecSenHeatRate + PurchAir.HtRecLatHeatRate; + PurchAir.HtRecTotCoolRate = PurchAir.HtRecSenCoolRate + PurchAir.HtRecLatCoolRate; + + PurchAir.SenHeatEnergy = PurchAir.SenHeatRate * TimeStepSysSec; + PurchAir.SenCoolEnergy = PurchAir.SenCoolRate * TimeStepSysSec; + PurchAir.LatHeatEnergy = PurchAir.LatHeatRate * TimeStepSysSec; + PurchAir.LatCoolEnergy = PurchAir.LatCoolRate * TimeStepSysSec; + PurchAir.TotHeatEnergy = PurchAir.TotHeatRate * TimeStepSysSec; + PurchAir.TotCoolEnergy = PurchAir.TotCoolRate * TimeStepSysSec; + + PurchAir.ZoneSenHeatEnergy = PurchAir.ZoneSenHeatRate * TimeStepSysSec; + PurchAir.ZoneSenCoolEnergy = PurchAir.ZoneSenCoolRate * TimeStepSysSec; + PurchAir.ZoneLatHeatEnergy = PurchAir.ZoneLatHeatRate * TimeStepSysSec; + PurchAir.ZoneLatCoolEnergy = PurchAir.ZoneLatCoolRate * TimeStepSysSec; + PurchAir.ZoneTotHeatEnergy = PurchAir.ZoneTotHeatRate * TimeStepSysSec; + PurchAir.ZoneTotCoolEnergy = PurchAir.ZoneTotCoolRate * TimeStepSysSec; + + PurchAir.OASenHeatEnergy = PurchAir.OASenHeatRate * TimeStepSysSec; + PurchAir.OASenCoolEnergy = PurchAir.OASenCoolRate * TimeStepSysSec; + PurchAir.OALatHeatEnergy = PurchAir.OALatHeatRate * TimeStepSysSec; + PurchAir.OALatCoolEnergy = PurchAir.OALatCoolRate * TimeStepSysSec; + PurchAir.OATotHeatEnergy = PurchAir.OATotHeatRate * TimeStepSysSec; + PurchAir.OATotCoolEnergy = PurchAir.OATotCoolRate * TimeStepSysSec; + + PurchAir.HtRecSenHeatEnergy = PurchAir.HtRecSenHeatRate * TimeStepSysSec; + PurchAir.HtRecSenCoolEnergy = PurchAir.HtRecSenCoolRate * TimeStepSysSec; + PurchAir.HtRecLatHeatEnergy = PurchAir.HtRecLatHeatRate * TimeStepSysSec; + PurchAir.HtRecLatCoolEnergy = PurchAir.HtRecLatCoolRate * TimeStepSysSec; + PurchAir.HtRecTotHeatEnergy = PurchAir.HtRecTotHeatRate * TimeStepSysSec; + PurchAir.HtRecTotCoolEnergy = PurchAir.HtRecTotCoolRate * TimeStepSysSec; } Real64 GetPurchasedAirOutAirMassFlow(EnergyPlusData &state, int const PurchAirNum) @@ -3482,10 +3361,7 @@ void InitializePlenumArrays(EnergyPlusData &state, int const PurchAirNum) // FUNCTION LOCAL VARIABLE DECLARATIONS: int ReturnPlenumIndex; // index to ZoneHVAC:ReturnPlenum object - int ReturnPlenumNum; // loop counter bool PlenumNotFound; // logical to determine if same plenum is used by other ideal loads air systems - int Loop; // loop counters - int Loop2; // loop counters Array1D_int TempPurchArray; // temporary array used for dynamic allocation Array1D_bool TempIsSimulated; // temporary array used for dynamic allocation @@ -3520,7 +3396,7 @@ void InitializePlenumArrays(EnergyPlusData &state, int const PurchAirNum) } else { // find the correct index to PurchAirPlenumArrays - for (ReturnPlenumNum = 1; ReturnPlenumNum <= state.dataPurchasedAirMgr->NumPlenumArrays; ++ReturnPlenumNum) { + for (int ReturnPlenumNum = 1; ReturnPlenumNum <= state.dataPurchasedAirMgr->NumPlenumArrays; ++ReturnPlenumNum) { if (ReturnPlenumIndex != state.dataPurchasedAirMgr->PurchAirPlenumArrays(ReturnPlenumNum).ReturnPlenumIndex) continue; // allocate temporary arrays and save existing data @@ -3543,7 +3419,7 @@ void InitializePlenumArrays(EnergyPlusData &state, int const PurchAirNum) .IsSimulated.allocate(state.dataPurchasedAirMgr->PurchAirPlenumArrays(ReturnPlenumNum).NumPurchAir); // re-initialize previous data - for (Loop = 1; Loop < state.dataPurchasedAirMgr->PurchAirPlenumArrays(ReturnPlenumNum).NumPurchAir; ++Loop) { + for (int Loop = 1; Loop < state.dataPurchasedAirMgr->PurchAirPlenumArrays(ReturnPlenumNum).NumPurchAir; ++Loop) { state.dataPurchasedAirMgr->PurchAirPlenumArrays(ReturnPlenumNum).PurchAirArray(Loop) = TempPurchArray(Loop); state.dataPurchasedAirMgr->PurchAirPlenumArrays(ReturnPlenumNum).IsSimulated(Loop) = TempIsSimulated(Loop); } @@ -3569,7 +3445,7 @@ void InitializePlenumArrays(EnergyPlusData &state, int const PurchAirNum) // allocate temporary array and save existing data state.dataPurchasedAirMgr->TempPurchAirPlenumArrays.allocate(state.dataPurchasedAirMgr->NumPlenumArrays); - for (Loop = 1; Loop < state.dataPurchasedAirMgr->NumPlenumArrays; ++Loop) { + for (int Loop = 1; Loop < state.dataPurchasedAirMgr->NumPlenumArrays; ++Loop) { state.dataPurchasedAirMgr->TempPurchAirPlenumArrays(Loop).NumPurchAir = state.dataPurchasedAirMgr->PurchAirPlenumArrays(Loop).NumPurchAir; state.dataPurchasedAirMgr->TempPurchAirPlenumArrays(Loop).ReturnPlenumIndex = @@ -3578,7 +3454,7 @@ void InitializePlenumArrays(EnergyPlusData &state, int const PurchAirNum) state.dataPurchasedAirMgr->PurchAirPlenumArrays(Loop).NumPurchAir); state.dataPurchasedAirMgr->TempPurchAirPlenumArrays(Loop).IsSimulated.allocate( state.dataPurchasedAirMgr->PurchAirPlenumArrays(Loop).NumPurchAir); - for (Loop2 = 1; Loop2 <= state.dataPurchasedAirMgr->PurchAirPlenumArrays(Loop).NumPurchAir; ++Loop2) { + for (int Loop2 = 1; Loop2 <= state.dataPurchasedAirMgr->PurchAirPlenumArrays(Loop).NumPurchAir; ++Loop2) { state.dataPurchasedAirMgr->TempPurchAirPlenumArrays(Loop).PurchAirArray(Loop2) = state.dataPurchasedAirMgr->PurchAirPlenumArrays(Loop).PurchAirArray(Loop2); state.dataPurchasedAirMgr->TempPurchAirPlenumArrays(Loop).IsSimulated(Loop2) = @@ -3592,7 +3468,7 @@ void InitializePlenumArrays(EnergyPlusData &state, int const PurchAirNum) state.dataPurchasedAirMgr->PurchAirPlenumArrays.allocate(state.dataPurchasedAirMgr->NumPlenumArrays); // allocate member arrays to same size as before - for (Loop = 1; Loop < state.dataPurchasedAirMgr->NumPlenumArrays; ++Loop) { + for (int Loop = 1; Loop < state.dataPurchasedAirMgr->NumPlenumArrays; ++Loop) { state.dataPurchasedAirMgr->PurchAirPlenumArrays(Loop).PurchAirArray.allocate( state.dataPurchasedAirMgr->TempPurchAirPlenumArrays(Loop).NumPurchAir); state.dataPurchasedAirMgr->PurchAirPlenumArrays(Loop).IsSimulated.allocate( diff --git a/src/EnergyPlus/WindowManager.cc b/src/EnergyPlus/WindowManager.cc index 67875d0a3ed..793ca54ed47 100644 --- a/src/EnergyPlus/WindowManager.cc +++ b/src/EnergyPlus/WindowManager.cc @@ -281,7 +281,6 @@ namespace Window { Real64 EpsGlIR; // IR absorptance of front or back of isolated glass Real64 RhoGlIR; // IR reflectance of inside face of inside glass int NGlass; // Number of glass layers in a construction - int LayNum; // Layer number for a glass layer int LayPtr; // Material number corresponding to LayNum Real64 Phi; // Incidence angle (deg) Real64 CosPhi; // Cosine of incidence angle @@ -504,7 +503,7 @@ namespace Window { // Loop over glass layers in the construction for (int IGlass = 1; IGlass <= NGlass; ++IGlass) { - LayNum = 1 + 2 * (IGlass - 1); + int LayNum = 1 + 2 * (IGlass - 1); if (ExtShade || ExtBlind || ExtScreen) LayNum = 2 + 2 * (IGlass - 1); if (BGShade || BGBlind) { LayNum = 1; @@ -801,7 +800,7 @@ namespace Window { // Loop over glass layers in the construction. for (int IGlass = 1; IGlass <= NGlass; ++IGlass) { - LayNum = 1 + (NGlass - IGlass) * 2; + int LayNum = 1 + (NGlass - IGlass) * 2; if (ExtShade || ExtBlind || ExtScreen) LayNum = 2 + (NGlass - IGlass) * 2; if (BGShade || BGBlind) { if (NGlass == 2) { @@ -1505,11 +1504,11 @@ namespace Window { assert(matFen != nullptr); if (mat->group == Material::Group::Shade) { - Real64 EpsGlIR = s_mat->materials(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay - 1))->AbsorpThermalBack; - Real64 RhoGlIR = 1 - EpsGlIR; - Real64 TauShIR = matFen->TransThermal; - Real64 EpsShIR = matFen->AbsorpThermal; - Real64 RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR); + EpsGlIR = s_mat->materials(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay - 1))->AbsorpThermalBack; + RhoGlIR = 1 - EpsGlIR; + TauShIR = matFen->TransThermal; + EpsShIR = matFen->AbsorpThermal; + RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR); surfShade.effShadeEmi = EpsShIR * (1.0 + RhoGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR)); surfShade.effGlassEmi = EpsGlIR * TauShIR / (1.0 - RhoGlIR * RhoShIR); @@ -1528,9 +1527,9 @@ namespace Window { surfShade.blind.TAR.interpSlatAng( matBlind->TARs[surfShade.blind.slatAngIdxLo], matBlind->TARs[surfShade.blind.slatAngIdxHi], surfShade.blind.slatAngInterpFac); - Real64 TauShIR = surfShade.blind.TAR.IR.Ft.Tra; - Real64 EpsShIR = surfShade.blind.TAR.IR.Bk.Emi; - Real64 RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR); + TauShIR = surfShade.blind.TAR.IR.Ft.Tra; + EpsShIR = surfShade.blind.TAR.IR.Bk.Emi; + RhoShIR = max(0.0, 1.0 - TauShIR - EpsShIR); surfShade.effShadeEmi = EpsShIR * (1.0 + surfShade.glass.rhoIR * TauShIR / (1.0 - surfShade.glass.rhoIR * RhoShIR)); surfShade.effGlassEmi = surfShade.glass.epsIR * TauShIR / (1.0 - surfShade.glass.rhoIR * RhoShIR); @@ -1594,7 +1593,6 @@ namespace Window { { // Initializes variables used in the window optical and thermal calculation. - int ConstrNum; // Construction number Real64 FrWidth; // Window frame width {m} Real64 FrEdgeWidth; // Frame edge width {m} Real64 DivWidth; // Window divider width {m} @@ -1603,8 +1601,6 @@ namespace Window { Real64 GlWidth; // Width of glazed part of window {m} int NumHorDividers; // Number of horizontal divider elements int NumVertDividers; // Number of vertical divider elements - int BaseSurfNum; // Base surface number - int MatNum; // Material number int DifOverrideCount; // Count the number of SolarDiffusing material overrides auto &s_mat = state.dataMaterial; @@ -1650,7 +1646,6 @@ namespace Window { GlWidth = surf.Width; NumVertDividers = frdiv.VertDividers; NumHorDividers = frdiv.HorDividers; - BaseSurfNum = surf.BaseSurf; s_surf->SurfWinFrameConductance(SurfNum) = frdiv.FrameConductance; s_surf->SurfWinFrameSolAbsorp(SurfNum) = frdiv.FrameSolAbsorp; s_surf->SurfWinFrameVisAbsorp(SurfNum) = frdiv.FrameVisAbsorp; @@ -1694,8 +1689,8 @@ namespace Window { if (surf.Class != SurfaceClass::Window || surf.ExtBoundCond != ExternalEnvironment || s_surf->SurfWinStormWinConstr(SurfNum) != 0) continue; - ConstrNum = surf.Construction; - MatNum = state.dataConstruction->Construct(ConstrNum).LayerPoint(state.dataConstruction->Construct(ConstrNum).TotLayers); + int ConstrNum = surf.Construction; + int MatNum = state.dataConstruction->Construct(ConstrNum).LayerPoint(state.dataConstruction->Construct(ConstrNum).TotLayers); auto const *mat = s_mat->materials(MatNum); if (mat->group != Material::Group::Glass) continue; @@ -1779,7 +1774,7 @@ namespace Window { // back reflectance at angle of incidence std::array, maxGlassLayers> rbadjPhi = {0.0}; - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; // For each glass layer find tPhi, rfPhi, and rbPhi at each wavelength for (int in = 1; in <= ngllayer; ++in) { @@ -1920,7 +1915,7 @@ namespace Window { { Real64 num = 0.0; Real64 denom = 0.0; - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; for (int i = 1; i <= nume - 1; ++i) { Real64 const esol = (wm->wle[i] - wm->wle[i - 1]) * 0.5 * (wm->e[i - 1] + wm->e[i]); @@ -1944,7 +1939,7 @@ namespace Window { Real64 y30new = 0.0; Real64 y30ils1 = 0.0; - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; for (int i = 2; i <= nume; ++i) { // Autodesk:BoundsViolation e|wle|p(i-1) @ i=1: Changed start index from 1 to 2: wle // values prevented this violation from occurring in practice @@ -2010,7 +2005,7 @@ namespace Window { // // PURPOSE OF THIS SUBROUTINE: // Subroutine to direct whether to use exterior or interior window routines - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; if (state.dataGlobal->KickOffSizing || state.dataGlobal->KickOffSimulation) return; @@ -2077,8 +2072,6 @@ namespace Window { // (temperature of innermost face) [C] int SurfNumAdj; // An interzone surface's number in the adjacent zone - int ZoneNumAdj; // An interzone surface's adjacent zone number - int TotLay; // Total number of layers in a construction // (sum of solid layers and gap layers) int TotGlassLay; // Total number of glass layers in a construction int LayPtr; // Material number for a layer @@ -2110,7 +2103,6 @@ namespace Window { Real64 SurfOutsideEmiss; // temporary for result of outside surface emissivity Real64 Tsout; // temporary for result of outside surface temp in Kelvin - int temp; // Shorthand references auto &surf = s_surf->Surface(SurfNum); @@ -2120,14 +2112,13 @@ namespace Window { if (s_surf->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { - temp = 0; + int temp = 0; // Simon: Complex fenestration state works only with tarcog CalcComplexWindowThermal( state, SurfNum, temp, HextConvCoeff, SurfInsideTemp, SurfOutsideTemp, SurfOutsideEmiss, DataBSDFWindow::Condition::Invalid); - auto &constr = state.dataConstruction->Construct(ConstrNum); - TotGlassLay = constr.TotGlassLayers; + auto const &constr = state.dataConstruction->Construct(ConstrNum); wm->ngllayer = constr.TotSolidLayers; // Simon: This is necessary to keep for frame calculations // Simon: need to transfer surface temperatures because of frames calculation @@ -2174,7 +2165,7 @@ namespace Window { } else { // regular window, not BSDF, not EQL Window // Added for thermochromic windows - auto &constr = state.dataConstruction->Construct(ConstrNum); + auto const &constr = state.dataConstruction->Construct(ConstrNum); wm->locTCFlag = (constr.isTCWindow); if (wm->locTCFlag) { @@ -2201,7 +2192,6 @@ namespace Window { } // end new TC code - TotLay = constr.TotLayers; TotGlassLay = constr.TotGlassLayers; wm->ngllayer = TotGlassLay; wm->nglface = 2 * wm->ngllayer; @@ -2273,7 +2263,7 @@ namespace Window { if (ANY_SHADE_SCREEN(ShadeFlag) || ANY_BLIND(ShadeFlag)) { IConst = s_surf->SurfWinActiveShadedConstruction(SurfNum); } - TotLay = state.dataConstruction->Construct(IConst).TotLayers; + int TotLay = state.dataConstruction->Construct(IConst).TotLayers; int IGlass = 0; int IGap = 0; @@ -2392,8 +2382,7 @@ namespace Window { if (SurfNumAdj > 0) { // Interzone window - ZoneNumAdj = s_surf->Surface(SurfNumAdj).Zone; - Real64 RefAirTemp = s_surf->Surface(SurfNumAdj).getInsideAirTemperature(state, SurfNumAdj); + RefAirTemp = s_surf->Surface(SurfNumAdj).getInsideAirTemperature(state, SurfNumAdj); state.dataHeatBal->SurfTempEffBulkAir(SurfNumAdj) = RefAirTemp; wm->tout = RefAirTemp + Constant::Kelvin; // outside air temperature @@ -2697,7 +2686,7 @@ namespace Window { Real64 pr; // Gap gas Prandtl number Real64 nu; // Gap gas Nusselt number - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; if (nglasslayer == 1) { Bface(1) = wm->Outir * wm->emis[0] + wm->hcout * wm->tout + wm->AbsRadGlassFace[0]; @@ -3343,7 +3332,6 @@ namespace Window { Real64 TauShIR = 0.0; // Long-wave transmittance of isolated shade/blind Real64 sconsh = 0.0; // shade/blind conductance (W/m2-K) - WinShadingType ShadeFlag = WinShadingType::NoShade; // Shading flag // radiation from lights and zone equipment absorbed by faces of shade/blind (W/m2) Real64 ShadeArea = 0.0; // shade/blind area (m2) // Real64 CondHeatGainGlass = 0.0; // Conduction through inner glass layer, outside to inside (W) @@ -3354,7 +3342,6 @@ namespace Window { Real64 CpAirOutlet = 0.0; // Heat capacity of air from window gap (J/kg-K) Real64 CpAirZone = 0.0; // Heat capacity of zone air (J/kg-K) Real64 InletAirHumRat = 0.0; // Humidity ratio of air from window gap entering fan - int InsideFaceIndex = 0; // intermediate variable for index of inside face in thetas Array1D hr = Array1D(2 * maxGlassLayers); // Radiative conductance (W/m2-K) Array1D AbsRadShadeFace(2); // Solar radiation, short-wave radiation from lights, and long-wave @@ -3370,7 +3357,7 @@ namespace Window { auto &s_surf = state.dataSurface; wm->nglfacep = wm->nglface; - ShadeFlag = s_surf->SurfWinShadingFlag(SurfNum); + WinShadingType ShadeFlag = s_surf->SurfWinShadingFlag(SurfNum); ZoneNum = s_surf->Surface(SurfNum).Zone; AbsRadShadeFace = 0.0; @@ -3420,6 +3407,7 @@ namespace Window { (s_surf->surfIntConv(SurfNum).model == Convect::HcInt::ASHRAETARP)) { // coef model is "detailed" and not prescribed by user // need to find inside face index, varies with shade/blind etc. + int InsideFaceIndex; // intermediate variable for index of inside face in thetas if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) { InsideFaceIndex = wm->nglfacep; } else { @@ -3906,7 +3894,6 @@ namespace Window { int ConstrNumSh; // Shaded construction number int MatNumSh; // Material number of shade/blind layer - int nglassfaces; // Number of glass faces in contruction // In the following, "gaps" refer to the gaps on either side of the shade/blind Array1D TGlassFace(2); // Temperature of glass surfaces facing gaps (K) Array1D TShadeFace(2); // Temperature of shade surfaces facing gaps (K) @@ -3954,7 +3941,6 @@ namespace Window { ConstrNumSh = surf.activeShadedConstruction; ShadeFlag = s_surf->SurfWinShadingFlag(SurfNum); - nglassfaces = 2 * state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers; if (state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers == 2) { // Double glazing MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(3); @@ -4130,9 +4116,9 @@ namespace Window { auto &s_mat = state.dataMaterial; auto &s_surf = state.dataSurface; - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; - auto &surf = s_surf->Surface(SurfNum); + auto const &surf = s_surf->Surface(SurfNum); ConstrNum = surf.Construction; NGlass = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; @@ -4219,7 +4205,6 @@ namespace Window { // SUBROUTINE LOCAL VARIABLE DECLARATIONS: int ConstrNumSh; // Shaded construction number - int MatNumSh; // Material number of shade/blind layer // In the following, "gaps" refer to the gaps on either side of the shade/blind Array1D TGlassFace(2); // Temperature of glass surfaces facing gaps (K) Array1D TShadeFace(2); // Temperature of shade surfaces facing gaps (K) @@ -4244,7 +4229,7 @@ namespace Window { // REAL(r64) :: AirProps(8) ! Air properties auto &s_surf = state.dataSurface; - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; // Air properties // Dens dDens/dT Con dCon/dT Vis dVis/dT Prandtl dPrandtl/dT @@ -4254,14 +4239,12 @@ namespace Window { ShadeFlag = s_surf->SurfWinShadingFlag(SurfNum); if (state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers == 2) { // Double glazing - MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(3); IGapInc = 0; for (int IGap = 1; IGap <= 2; ++IGap) { TGlassFace(IGap) = wm->thetas[IGap]; TShadeFace(IGap) = wm->thetas[IGap + 3]; } } else { // Triple glazing - MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(5); IGapInc = 1; for (int IGap = 1; IGap <= 2; ++IGap) { TGlassFace(IGap) = wm->thetas[IGap + 2]; @@ -4328,8 +4311,6 @@ namespace Window { // SUBROUTINE INFORMATION: // AUTHOR F. Winkelmann, adapted from Numerical Recipes // DATE WRITTEN February 2000 - // MODIFIED na - // RE-ENGINEERED na // PURPOSE OF THIS SUBROUTINE: // Performs LU decomposition of a matrix. @@ -4341,8 +4322,6 @@ namespace Window { int imax; // Temporary variable // as output: decomposed matrix - Real64 aamax; // Absolute value of largest element of matrix - assert(n <= 10); // vv sizing std::array vv = {0.0}; // Stores the implicit scaling of each row @@ -4363,7 +4342,7 @@ namespace Window { } ajac(j, i) = sum; } - aamax = 0.0; + Real64 aamax = 0.0; for (int i = j; i <= n; ++i) { Real64 sum = ajac(j, i); for (int k = 1; k <= j - 1; ++k) { @@ -4420,13 +4399,11 @@ namespace Window { // b is also output as the solution, x // b is also output as the solution, x - int ii; // Intermediate variables - int ll; Real64 sum; // Summation variable - ii = 0; + int ii = 0; for (int i = 1; i <= n; ++i) { - ll = indx(i); + int ll = indx(i); sum = b(ll); b(ll) = b(i); if (ii != 0) { @@ -4654,7 +4631,7 @@ namespace Window { Array1D fvis(10); // Viscosity of each gas in a mixture (g/m-s) Array1D fdens(10); // Density of each gas in a mixture (kg/m3) - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; NMix = wm->gaps[IGap - 1].numGases; @@ -4746,12 +4723,11 @@ namespace Window { Real64 ressum; // Resistance sum (m2-K/W) int StormWinFlagPrevDay; // Previous time step value (day) of storm window flag int StormWinFlagThisDay; // Current time step value (day) of storm window flag - int nglfacePrevDay; // Previous time step value (dya) of number of glass faces (may differ // current time step value, nglface, if storm window was // added or removed during the current time step). auto &s_surf = state.dataSurface; - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; StormWinFlagPrevDay = s_surf->SurfWinStormWinFlagPrevDay(SurfNum); StormWinFlagThisDay = s_surf->SurfWinStormWinFlag(SurfNum); @@ -4806,7 +4782,7 @@ namespace Window { // temperature values, although calculated here, are not used. The shade/blind face numbers // during the previous time step depend on whether a storm window glass layer was added to // or removed from the window during the current time step. - nglfacePrevDay = wm->nglface; + int nglfacePrevDay = wm->nglface; if (StormWinFlagPrevDay == 0 && StormWinFlagThisDay == 1) nglfacePrevDay = wm->nglface - 2; if (StormWinFlagPrevDay == 1 && StormWinFlagThisDay == 0) nglfacePrevDay = wm->nglface + 2; wm->thetas[wm->nglface] = s_surf->SurfaceWindow(SurfNum).thetaFace[nglfacePrevDay + 1]; @@ -4890,10 +4866,10 @@ namespace Window { Real64 g; Real64 ang; - auto &s_surf = state.dataSurface; - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; if (SurfNum > 0) { + auto const &s_surf = state.dataSurface; asp = s_surf->Surface(SurfNum).Height / wm->gaps[IGap - 1].width; } else { // SurfNum = 0 when NusseltNumber is called from CalcNominalWindowCond, which applies to a // particular construction. So window height is not known and we assume 5 ft (1.524 m) @@ -5524,7 +5500,6 @@ namespace Window { Array2D D(6, 16); // Powers of independent variable Real64 ACON; // Intermediate variables Real64 SUM; - int KP1; int LP1; int NM1; @@ -5558,7 +5533,7 @@ namespace Window { // Solve the simultaneous equations using Gauss elimination NM1 = N - 1; for (int K = 1; K <= NM1; ++K) { - KP1 = K + 1; + int KP1 = K + 1; for (int i = KP1; i <= N; ++i) { ACON = A(K, i) / A(K, K); B(i) -= B(K) * ACON; @@ -5619,7 +5594,6 @@ namespace Window { Array2D D(6, 16); // Powers of independent variable Real64 ACON; // Intermediate variables Real64 SUM; - int KP1; int LP1; int NM1; @@ -5653,7 +5627,7 @@ namespace Window { // Solve the simultaneous equations using Gauss elimination NM1 = N - 1; for (int K = 1; K <= NM1; ++K) { - KP1 = K + 1; + int KP1 = K + 1; for (int i = KP1; i <= N; ++i) { ACON = A(K, i) / A(K, K); B(i) -= B(K) * ACON; @@ -6441,7 +6415,7 @@ namespace Window { // init the surface convective and radiative adjustment ratio for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { - auto &thisSpace = state.dataHeatBal->space(spaceNum); + auto const &thisSpace = state.dataHeatBal->space(spaceNum); int const firstSurfWin = thisSpace.WindowSurfaceFirst; int const lastSurfWin = thisSpace.WindowSurfaceLast; for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { @@ -6466,12 +6440,12 @@ namespace Window { Array1D const hgap, // Conductive gap conductance [W/m2-K] Real64 &NominalConductance, // Nominal center-of-glass conductance, including air films Real64 &SHGC, // Nominal center-of-glass solar heat gain coefficient for - Real64 &TSolNorm // Overall beam solar transmittance at normal incidence + Real64 const TSolNorm // Overall beam solar transmittance at normal incidence ) { Array1D hGapTot(5); // Combined radiative and conductive gap conductance [W/m2-K] - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; Real64 hOutRad = wm->emis[0] * Constant::StefanBoltzmann * 0.5 * pow_3(wm->tout + wm->thetas[0]); Real64 rOut = 1.0 / (hOutRad + wm->hcout); Real64 hInRad = wm->emis[wm->nglface - 1] * Constant::StefanBoltzmann * 0.5 * pow_3(wm->tin + wm->thetas[wm->nglface - 1]); @@ -6721,7 +6695,7 @@ namespace Window { Real64 temdiff; // Inside/outside air temperature difference (K) Real64 ressum; // Resistance sum (m2-K/W) - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; rguess(1) = 1.0 / (wm->hcout + hrad); rguess(wm->nglface + 1) = 1.0 / (hcinStartValue + hrad); @@ -6770,7 +6744,6 @@ namespace Window { Real64 TempVar(0.0); // just temporary usage for complex fenestration - int Layer; Real64 NominalConductanceWinter; // Nominal center-of-glass conductance of a window construction // for ASHRAE winter conditions (W/m2-K): // Inside air temperature = 21.1C (70F) @@ -6786,14 +6759,10 @@ namespace Window { Real64 SHGCWinter(0.0); // Center-of-glass solar heat gain coefficient for ASHRAE Real64 SHGCSummer(0.0); // winter and summer conditions - Real64 TransSolNorm; // Window construction solar transmittance at normal incidence - Real64 TransVisNorm; // Window construction visible transmittance at normal incidence - int errFlag; // Error flag - std::string SolarDiffusing; // 'Yes' if glass is solar diffusing; otherwise 'No' (clear glass) - std::string SpectralDataName; - std::string OpticalDataType; + Real64 TransSolNorm; // Window construction solar transmittance at normal incidence + Real64 TransVisNorm; // Window construction visible transmittance at normal incidence + int errFlag; // Error flag - auto &s_mat = state.dataMaterial; auto &wm = state.dataWindowManager; ScanForReports(state, "Constructions", wm->DoReport, "Constructions"); @@ -6811,6 +6780,7 @@ namespace Window { [](Construction::ConstructionProps const &e) { return e.WindowTypeEQL; })) wm->HasEQLWindows = true; // for reporting purpose only if (wm->DoReport && (wm->HasWindows || wm->HasComplexWindows || wm->HasEQLWindows)) { + auto const &s_mat = state.dataMaterial; // Write Descriptions print(state.files.eio, "{}\n", @@ -6992,8 +6962,9 @@ namespace Window { // Write(OutputFileConstrainParams, 705) TRIM(Construct(ThisNum)%Name), SHGCSummer ,TransVisNorm for (int i = 1; i <= construct.TotLayers; ++i) { - Layer = construct.LayerPoint(i); + int Layer = construct.LayerPoint(i); auto const *mat = s_mat->materials(Layer); + std::string SpectralDataName; switch (mat->group) { @@ -7066,7 +7037,7 @@ namespace Window { case Material::Group::GlassSimple: { auto const *matGlass = dynamic_cast(mat); assert(matGlass != nullptr); - SolarDiffusing = "No"; + std::string SolarDiffusing = "No"; if (matGlass->SolarDiffusing) SolarDiffusing = "Yes"; if (matGlass->windowOpticalData == Window::OpticalDataModel::Spectral) { @@ -7105,7 +7076,7 @@ namespace Window { case Material::Group::GlassEQL: { auto const *matEQL = dynamic_cast(mat); assert(matEQL != nullptr); - OpticalDataType = "SpectralAverage"; + std::string OpticalDataType = "SpectralAverage"; SpectralDataName = ""; static constexpr std::string_view Format_708( " WindowMaterial:Glazing:EquivalentLayer,{},{},{},{:.5R},{:.5R},{:.5R},{:.5R},{:.5R}" @@ -8435,18 +8406,13 @@ namespace Window { int NumAlphas; // Number of Alphas for each GetobjectItem call int NumNumbers; // Number of Numbers for each GetobjectItem call int NumArgs; - int IOStatus; Array1D_string cAlphaArgs; // Alpha input items for object Array1D rNumericArgs; // Numeric input items for object std::string cCurrentModuleObject; - std::string cSolarSpectrum; - std::string cVisibleSpectrum; - int iSolarSpectrum(0); - int iVisibleSpectrum(0); int NumSiteSpectrum(0); - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; if (wm->RunMeOnceFlag) return; @@ -8471,6 +8437,7 @@ namespace Window { rNumericArgs.dimension(NumNumbers, 0.0); if (NumSiteSpectrum == 1) { + int IOStatus; state.dataInputProcessing->inputProcessor->getObjectItem(state, cCurrentModuleObject, 1, @@ -8487,8 +8454,8 @@ namespace Window { } // now read custom solar and visible spectrum data - cSolarSpectrum = state.dataIPShortCut->cAlphaArgs(3); - cVisibleSpectrum = state.dataIPShortCut->cAlphaArgs(4); + std::string cSolarSpectrum = state.dataIPShortCut->cAlphaArgs(3); + std::string cVisibleSpectrum = state.dataIPShortCut->cAlphaArgs(4); cCurrentModuleObject = "Site:SpectrumData"; NumSiteSpectrum = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject); @@ -8504,8 +8471,8 @@ namespace Window { cAlphaArgs.allocate(NumAlphas); rNumericArgs.dimension(NumNumbers, 0.0); - iSolarSpectrum = 0; - iVisibleSpectrum = 0; + int iSolarSpectrum = 0; + int iVisibleSpectrum = 0; for (int Loop = 1; Loop <= NumSiteSpectrum; ++Loop) { // Step 2 - read user-defined spectrum data state.dataInputProcessing->inputProcessor->getObjectItem(state, @@ -8578,7 +8545,7 @@ namespace Window { void initWindowModel(EnergyPlusData &state) { const std::string objectName = "WindowsCalculationEngine"; - auto &wm = state.dataWindowManager; + auto const &wm = state.dataWindowManager; wm->inExtWindowModel = CWindowModel::WindowModelFactory(state, objectName); wm->winOpticalModel = CWindowOpticalModel::WindowOpticalModelFactory(state); } // InitWindowModel() diff --git a/src/EnergyPlus/WindowManager.hh b/src/EnergyPlus/WindowManager.hh index 23936c62ea8..e1560589a29 100644 --- a/src/EnergyPlus/WindowManager.hh +++ b/src/EnergyPlus/WindowManager.hh @@ -325,7 +325,7 @@ namespace Window { Array1D hgap, // Conductive gap conductance [W/m2-K] Real64 &NominalConductance, // Nominal center-of-glass conductance, including air films Real64 &SHGC, // Nominal center-of-glass solar heat gain coefficient for - Real64 &TSolNorm // Overall beam solar transmittance at normal incidence + Real64 TSolNorm // Overall beam solar transmittance at normal incidence ); void WindowTempsForNominalCond(EnergyPlusData &state, diff --git a/src/EnergyPlus/WindowModel.cc b/src/EnergyPlus/WindowModel.cc index 8feb11bbf12..48b277f535e 100644 --- a/src/EnergyPlus/WindowModel.cc +++ b/src/EnergyPlus/WindowModel.cc @@ -80,13 +80,13 @@ namespace Window { // PURPOSE OF THIS SUBROUTINE: // Reads input and creates instance of WindowModel object - int NumNums; - int NumAlphas; - int IOStat; auto aModel = std::make_unique(); // (AUTO_OK) int numCurrModels = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, objectName); if (numCurrModels > 0) { + int NumNums; + int NumAlphas; + int IOStat; state.dataInputProcessing->inputProcessor->getObjectItem( state, objectName, 1, state.dataIPShortCut->cAlphaArgs, NumAlphas, state.dataIPShortCut->rNumericArgs, NumNums, IOStat); // Please consider using getEnumValue pattern here. diff --git a/src/EnergyPlus/ZoneAirLoopEquipmentManager.cc b/src/EnergyPlus/ZoneAirLoopEquipmentManager.cc index e8eafa14f85..92af6665c4b 100644 --- a/src/EnergyPlus/ZoneAirLoopEquipmentManager.cc +++ b/src/EnergyPlus/ZoneAirLoopEquipmentManager.cc @@ -217,28 +217,25 @@ namespace ZoneAirLoopEquipmentManager { static std::string const CurrentModuleObject("ZoneHVAC:AirDistributionUnit"); // Object type for getting and error messages // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int AirDistUnitNum; - int AirDistCompUnitNum; - int NumAlphas; - int NumNums; - int IOStat; bool ErrorsFound(false); // If errors detected in input - bool IsNotOK; // Flag to verify name Array1D_string AlphArray(5); Array1D NumArray(2); Array1D_string cAlphaFields(5); // Alpha field names Array1D_string cNumericFields(2); // Numeric field names Array1D_bool lAlphaBlanks(5); // Logical array, alpha field input BLANK = .TRUE. Array1D_bool lNumericBlanks(2); // Logical array, numeric field input BLANK = .TRUE. - bool DualDuctRecircIsUsed; // local temporary for deciding if recirc side used by dual duct terminal int NumAirDistUnits = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject); state.dataDefineEquipment->AirDistUnit.allocate(NumAirDistUnits); if (NumAirDistUnits > 0) { + int NumAlphas; + int NumNums; + int IOStat; + bool IsNotOK; // Flag to verify name - for (AirDistUnitNum = 1; AirDistUnitNum <= NumAirDistUnits; ++AirDistUnitNum) { + for (int AirDistUnitNum = 1; AirDistUnitNum <= NumAirDistUnits; ++AirDistUnitNum) { auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(AirDistUnitNum); state.dataInputProcessing->inputProcessor->getObjectItem(state, CurrentModuleObject, @@ -267,7 +264,7 @@ namespace ZoneAirLoopEquipmentManager { ObjectIsParent); airDistUnit.InletNodeNum = 0; airDistUnit.NumComponents = 1; - AirDistCompUnitNum = 1; + int AirDistCompUnitNum = 1; // Load the air Distribution Unit Equip and Name airDistUnit.EquipType(AirDistCompUnitNum) = AlphArray(3); airDistUnit.EquipName(AirDistCompUnitNum) = AlphArray(4); @@ -387,6 +384,7 @@ namespace ZoneAirLoopEquipmentManager { airDistUnit.EquipName(AirDistCompUnitNum), "UNDEFINED", AlphArray(2)); + bool DualDuctRecircIsUsed; // local temporary for deciding if recirc side used by dual duct terminal GetDualDuctOutdoorAirRecircUse( state, airDistUnit.EquipType(AirDistCompUnitNum), airDistUnit.EquipName(AirDistCompUnitNum), DualDuctRecircIsUsed); if (DualDuctRecircIsUsed) { @@ -409,7 +407,7 @@ namespace ZoneAirLoopEquipmentManager { } } // End of Air Dist Do Loop - for (AirDistUnitNum = 1; AirDistUnitNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++AirDistUnitNum) { + for (int AirDistUnitNum = 1; AirDistUnitNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++AirDistUnitNum) { auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(AirDistUnitNum); SetupOutputVariable(state, "Zone Air Terminal Sensible Heating Energy", @@ -557,8 +555,6 @@ namespace ZoneAirLoopEquipmentManager { bool ProvideSysOutput; int AirDistCompNum; - int InNodeNum; // air distribution unit inlet node - int OutNodeNum; // air distribution unit outlet node int AirLoopNum(0); // index of air loop Real64 MassFlowRateMaxAvail; // max avail mass flow rate excluding leaks [kg/s] Real64 MassFlowRateMinAvail; // min avail mass flow rate excluding leaks [kg/s] @@ -574,8 +570,8 @@ namespace ZoneAirLoopEquipmentManager { NonAirSysOutput = 0.0; auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(AirDistUnitNum); - InNodeNum = airDistUnit.InletNodeNum; - OutNodeNum = airDistUnit.OutletNodeNum; + int InNodeNum = airDistUnit.InletNodeNum; + int OutNodeNum = airDistUnit.OutletNodeNum; MassFlowRateMaxAvail = 0.0; MassFlowRateMinAvail = 0.0; // check for no plenum diff --git a/src/EnergyPlus/ZoneContaminantPredictorCorrector.cc b/src/EnergyPlus/ZoneContaminantPredictorCorrector.cc index 32863ffb574..ad19296411e 100644 --- a/src/EnergyPlus/ZoneContaminantPredictorCorrector.cc +++ b/src/EnergyPlus/ZoneContaminantPredictorCorrector.cc @@ -1504,7 +1504,6 @@ void InitZoneContSetPoints(EnergyPlusData &state) Real64 Pi; // Pressue at zone i Real64 Pj; // Pressue at zone j Real64 Sch; // Schedule value - bool ErrorsFound(false); if (state.dataContaminantBalance->Contaminant.CO2Simulation) { state.dataContaminantBalance->OutdoorCO2 = @@ -1707,6 +1706,7 @@ void InitZoneContSetPoints(EnergyPlusData &state) } if (allocated(state.dataZoneEquip->ZoneEquipConfig) && state.dataZoneContaminantPredictorCorrector->MyConfigOneTimeFlag) { + bool ErrorsFound = false; for (int ContZoneNum = 1; ContZoneNum <= (int)state.dataContaminantBalance->ContaminantControlledZone.size(); ++ContZoneNum) { int ZoneNum = state.dataContaminantBalance->ContaminantControlledZone(ContZoneNum).ActualZoneNum; for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumInletNodes; ++zoneInNode) { @@ -1817,13 +1817,13 @@ void InitZoneContSetPoints(EnergyPlusData &state) // From decay model for (auto &con : state.dataContaminantBalance->ZoneContamGenericDecay) { - int Sch = ScheduleManager::GetCurrentScheduleValue(state, con.GCEmiRateSchedPtr); - if (Sch == 0.0 || state.dataGlobal->BeginEnvrnFlag || state.dataGlobal->WarmupFlag) { + int intSch = ScheduleManager::GetCurrentScheduleValue(state, con.GCEmiRateSchedPtr); + if (intSch == 0.0 || state.dataGlobal->BeginEnvrnFlag || state.dataGlobal->WarmupFlag) { con.GCTime = 0.0; } else { con.GCTime += state.dataGlobal->TimeStepZoneSec; } - GCGain = con.GCInitEmiRate * Sch * std::exp(-con.GCTime / con.GCDelayTime); + GCGain = con.GCInitEmiRate * intSch * std::exp(-con.GCTime / con.GCDelayTime); con.GCGenRate = GCGain; } @@ -2051,7 +2051,6 @@ void PredictZoneContaminants(EnergyPlusData &state, // Calculate the coefficients for the 3rd Order derivative for final // zone CO2. The A, B, C coefficients are analogous to the CO2 balance. // Assume that the system will have flow - auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (state.afn->multizone_always_simulated || (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation && state.afn->AirflowNetworkFanActivated)) { @@ -2165,7 +2164,6 @@ void PredictZoneContaminants(EnergyPlusData &state, // Calculate the coefficients for the 3rd Order derivative for final // zone GC. The A, B, C coefficients are analogous to the GC balance. // Assume that the system will have flow - auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (state.afn->multizone_always_simulated || (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation && state.afn->AirflowNetworkFanActivated)) { @@ -2334,12 +2332,12 @@ void RevertZoneTimestepHistories(EnergyPlusData &state) } void InverseModelCO2(EnergyPlusData &state, - int const ZoneNum, // Zone number - Real64 &CO2Gain, // Zone total CO2 gain - Real64 &CO2GainExceptPeople, // ZOne total CO2 gain from sources except for people - Real64 &ZoneMassFlowRate, // Zone air mass flow rate - Real64 &CO2MassFlowRate, // Zone air CO2 mass flow rate - Real64 &RhoAir // Air density + int const ZoneNum, // Zone number + Real64 const CO2Gain, // Zone total CO2 gain + Real64 const CO2GainExceptPeople, // ZOne total CO2 gain from sources except for people + Real64 const ZoneMassFlowRate, // Zone air mass flow rate + Real64 const CO2MassFlowRate, // Zone air CO2 mass flow rate + Real64 const RhoAir // Air density ) { // SUBROUTINE INFORMATION: @@ -2363,7 +2361,7 @@ void InverseModelCO2(EnergyPlusData &state, state.dataEnvrn->DayOfYear <= state.dataHybridModel->HybridModelZone(ZoneNum).HybridEndDayOfYear) { state.dataContaminantBalance->ZoneAirCO2(ZoneNum) = state.dataHeatBal->Zone(ZoneNum).ZoneMeasuredCO2Concentration; - auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); + auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (state.dataHybridModel->HybridModelZone(ZoneNum).InfiltrationCalc_C && state.dataHVACGlobal->UseZoneTimeStepHistory) { static constexpr std::string_view RoutineNameInfiltration("CalcAirFlowSimple:Infiltration"); // Conditionally calculate the CO2-dependent and CO2-independent terms. @@ -2575,7 +2573,7 @@ void CorrectZoneContaminants(EnergyPlusData &state, // Calculate moisture flow rate into each zone for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumInletNodes; ++NodeNum) { - auto &node = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).InletNode(NodeNum)); + auto const &node = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).InletNode(NodeNum)); if (state.dataContaminantBalance->Contaminant.CO2Simulation) { CO2MassFlowRate += (node.MassFlowRate * node.CO2) / ZoneMult; } @@ -2588,7 +2586,7 @@ void CorrectZoneContaminants(EnergyPlusData &state, // Do the calculations for the plenum zone } else if (ZoneRetPlenumAirFlag) { for (int NodeNum = 1; NodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZoneRetPlenumNum).NumInletNodes; ++NodeNum) { - auto &node = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneRetPlenCond(ZoneRetPlenumNum).InletNode(NodeNum)); + auto const &node = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneRetPlenCond(ZoneRetPlenumNum).InletNode(NodeNum)); if (state.dataContaminantBalance->Contaminant.CO2Simulation) { CO2MassFlowRate += (node.MassFlowRate * node.CO2) / ZoneMult; } @@ -2602,7 +2600,7 @@ void CorrectZoneContaminants(EnergyPlusData &state, int ADUNum = state.dataZonePlenum->ZoneRetPlenCond(ZoneRetPlenumNum).ADUIndex(ADUListIndex); if (state.dataDefineEquipment->AirDistUnit(ADUNum).UpStreamLeak) { auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(ADUNum); - auto &node = state.dataLoopNodes->Node(airDistUnit.InletNodeNum); + auto const &node = state.dataLoopNodes->Node(airDistUnit.InletNodeNum); if (state.dataContaminantBalance->Contaminant.CO2Simulation) { CO2MassFlowRate += (airDistUnit.MassFlowRateUpStrLk * node.CO2) / ZoneMult; } @@ -2613,7 +2611,7 @@ void CorrectZoneContaminants(EnergyPlusData &state, } if (state.dataDefineEquipment->AirDistUnit(ADUNum).DownStreamLeak) { auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(ADUNum); - auto &node = state.dataLoopNodes->Node(airDistUnit.OutletNodeNum); + auto const &node = state.dataLoopNodes->Node(airDistUnit.OutletNodeNum); if (state.dataContaminantBalance->Contaminant.CO2Simulation) { CO2MassFlowRate += (airDistUnit.MassFlowRateDnStrLk * node.CO2) / ZoneMult; } @@ -2625,7 +2623,7 @@ void CorrectZoneContaminants(EnergyPlusData &state, } } else if (ZoneSupPlenumAirFlag) { - auto &node = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneSupPlenCond(ZoneSupPlenumNum).InletNode); + auto const &node = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneSupPlenCond(ZoneSupPlenumNum).InletNode); if (state.dataContaminantBalance->Contaminant.CO2Simulation) { CO2MassFlowRate += (node.MassFlowRate * node.CO2) / ZoneMult; } diff --git a/src/EnergyPlus/ZoneContaminantPredictorCorrector.hh b/src/EnergyPlus/ZoneContaminantPredictorCorrector.hh index 0201ede7c4d..230fd43e58f 100644 --- a/src/EnergyPlus/ZoneContaminantPredictorCorrector.hh +++ b/src/EnergyPlus/ZoneContaminantPredictorCorrector.hh @@ -87,12 +87,12 @@ namespace ZoneContaminantPredictorCorrector { void RevertZoneTimestepHistories(EnergyPlusData &state); void InverseModelCO2(EnergyPlusData &state, - int ZoneNum, // Zone number - Real64 &CO2Gain, // Zone total CO2 gain - Real64 &CO2GainExceptPeople, // ZOne total CO2 gain from sources except for people - Real64 &ZoneMassFlowRate, // Zone air mass flow rate - Real64 &CO2MassFlowRate, // Zone air CO2 mass flow rate - Real64 &RhoAir // Air density + int ZoneNum, // Zone number + Real64 CO2Gain, // Zone total CO2 gain + Real64 CO2GainExceptPeople, // ZOne total CO2 gain from sources except for people + Real64 ZoneMassFlowRate, // Zone air mass flow rate + Real64 CO2MassFlowRate, // Zone air CO2 mass flow rate + Real64 RhoAir // Air density ); void CorrectZoneContaminants(EnergyPlusData &state, diff --git a/src/EnergyPlus/ZoneDehumidifier.cc b/src/EnergyPlus/ZoneDehumidifier.cc index 95ec5aa25d2..7328ea976e2 100644 --- a/src/EnergyPlus/ZoneDehumidifier.cc +++ b/src/EnergyPlus/ZoneDehumidifier.cc @@ -749,7 +749,6 @@ namespace ZoneDehumidifier { Real64 AirMassFlowRate; // Air mass flow rate through this dehumidifier (kg/s) Real64 Cp; // Heat capacity of inlet air (J/kg-C) int AirInletNodeNum(0); // Node number for the inlet air to the dehumidifier - int AirOutletNodeNum(0); // Node number for the outlet air from the dehumidifier SensibleOutput = 0.0; LatentOutput = 0.0; @@ -763,7 +762,6 @@ namespace ZoneDehumidifier { ElectricPowerOnCycle = 0.0; AirInletNodeNum = state.dataZoneDehumidifier->ZoneDehumid(ZoneDehumNum).AirInletNodeNum; - AirOutletNodeNum = state.dataZoneDehumidifier->ZoneDehumid(ZoneDehumNum).AirOutletNodeNum; InletAirTemp = state.dataLoopNodes->Node(AirInletNodeNum).Temp; InletAirHumRat = state.dataLoopNodes->Node(AirInletNodeNum).HumRat; @@ -1105,7 +1103,6 @@ namespace ZoneDehumidifier { Real64 RhoWater; // Density of condensate (water) being removed (kg/m3) Real64 InletAirTemp; // Dry-bulb temperature of air entering the dehumidifier (C) Real64 OutletAirTemp; // Dry-bulb temperature of air leaving the dehumidifier (C) - int AirInletNodeNum; // Node number corresponding to the air entering dehumidifier state.dataZoneDehumidifier->ZoneDehumid(DehumidNum).SensHeatingEnergy = state.dataZoneDehumidifier->ZoneDehumid(DehumidNum).SensHeatingRate * TimeStepSysSec; @@ -1121,7 +1118,7 @@ namespace ZoneDehumidifier { // Calculate and report condensation rate (how much water extracted from the air stream) // Volumetric flow of water in m3/s for water system interactions - AirInletNodeNum = state.dataZoneDehumidifier->ZoneDehumid(DehumidNum).AirInletNodeNum; + int AirInletNodeNum = state.dataZoneDehumidifier->ZoneDehumid(DehumidNum).AirInletNodeNum; InletAirTemp = state.dataLoopNodes->Node(AirInletNodeNum).Temp; OutletAirTemp = max((InletAirTemp - 11.0), 1.0); // Assume coil outlet air is 11C (20F) lower than inlet air temp RhoWater = RhoH2O(OutletAirTemp); // Density of water, minimum temp = 1.0 C diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index d10a2e33572..c886910a15c 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -305,7 +305,7 @@ void sizeZoneSpaceEquipmentPart1(EnergyPlusData &state, DataSizing::ZoneSizingData &zsCalcSizing, DataZoneEnergyDemands::ZoneSystemSensibleDemand &zsEnergyDemand, DataZoneEnergyDemands::ZoneSystemMoistureDemand &zsMoistureDemand, - DataHeatBalance::ZoneData &zoneOrSpace, + DataHeatBalance::ZoneData const &zoneOrSpace, int zoneNum, int spaceNum) { @@ -315,8 +315,6 @@ void sizeZoneSpaceEquipmentPart1(EnergyPlusData &state, : state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).NonAirSystemResponse; auto &sysDepZoneLoads = (spaceNum > 0) ? state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).SysDepZoneLoads : state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).SysDepZoneLoads; - auto &zoneLatentGain = (spaceNum > 0) ? state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).latentGain - : state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).latentGain; auto &zoneNodeNum = (spaceNum > 0) ? state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber : state.dataHeatBal->Zone(zoneNum).SystemZoneNodeNumber; nonAirSystemResponse = 0.0; @@ -559,6 +557,8 @@ void sizeZoneSpaceEquipmentPart1(EnergyPlusData &state, nonAirSystemResponse = SysOutputProvided; if (zsCalcSizing.zoneLatentSizing) { int zoneMult = zoneOrSpace.Multiplier * zoneOrSpace.ListMultiplier; + auto &zoneLatentGain = (spaceNum > 0) ? state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).latentGain + : state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).latentGain; zoneLatentGain += (LatOutputProvided * HgAir) / zoneMult; } if (state.dataHeatBal->doSpaceHeatBalance && spaceNum == 0) { @@ -588,7 +588,7 @@ void sizeZoneSpaceEquipmentPart2(EnergyPlusData &state, int zoneNodeNum = (spaceNum > 0) ? state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber : state.dataHeatBal->Zone(zoneNum).SystemZoneNodeNumber; Real64 RetTemp = (returnNodeNum > 0) ? state.dataLoopNodes->Node(returnNodeNum).Temp : state.dataLoopNodes->Node(zoneNodeNum).Temp; - auto &zoneTstatSP = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(zoneNum); + auto const &zoneTstatSP = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(zoneNum); if (zsCalcSizing.HeatLoad > 0.0) { zsCalcSizing.HeatZoneRetTemp = RetTemp; zsCalcSizing.HeatTstatTemp = (zoneTstatSP > 0.0) ? zoneTstatSP : state.dataHeatBalFanSys->ZoneThermostatSetPointLo(zoneNum); @@ -996,7 +996,7 @@ void SetUpZoneSizingArrays(EnergyPlusData &state) // from the specified OA method for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) { if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue; - auto &thisZone = state.dataHeatBal->Zone(CtrlZoneNum); + auto const &thisZone = state.dataHeatBal->Zone(CtrlZoneNum); auto &finalZoneSizing = state.dataSize->FinalZoneSizing(CtrlZoneNum); auto &calcFinalZoneSizing = state.dataSize->CalcFinalZoneSizing(CtrlZoneNum); // Use the max occupancy PEOPLE structure to calculate design min OA for each zone from the outside air flow per person input @@ -1008,7 +1008,6 @@ void SetUpZoneSizingArrays(EnergyPlusData &state) // If this is a DesignSpecification:OutdoorAir:SpaceList check to make sure spaces are valid and belong to this zone if (thisOAReq.numDSOA > 0) { for (int spaceCounter = 1; spaceCounter <= thisOAReq.numDSOA; ++spaceCounter) { - std::string thisSpaceName = thisOAReq.dsoaSpaceNames(spaceCounter); int thisSpaceNum = thisOAReq.dsoaSpaceIndexes(spaceCounter); if (thisSpaceNum > 0) { if (state.dataHeatBal->space(thisSpaceNum).zoneNum != CtrlZoneNum) { @@ -1054,13 +1053,13 @@ void SetUpZoneSizingArrays(EnergyPlusData &state) // Calculate the design min OA flow rate for this zone // flag to use occupancy schedule when calculating OA - bool UseOccSchFlag = false; // flag to use min OA schedule when calculating OA - bool UseMinOASchFlag = false; state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ZoneDesignSpecOAIndex = DSOAPtr; // store for later use state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ZoneAirDistributionIndex = finalZoneSizing.ZoneAirDistributionIndex; // store for later use Real64 OAVolumeFlowRate = 0.0; if (!dsoaError) { + bool UseOccSchFlag = false; + bool UseMinOASchFlag = false; OAVolumeFlowRate = DataSizing::calcDesignSpecificationOutdoorAir(state, DSOAPtr, CtrlZoneNum, UseOccSchFlag, UseMinOASchFlag); } @@ -1352,7 +1351,7 @@ void RezeroZoneSizingArrays(EnergyPlusData &state) } } } -void updateZoneSizingBeginDay(EnergyPlusData &state, DataSizing::ZoneSizingData &zsCalcSizing) +void updateZoneSizingBeginDay(EnergyPlusData const &state, DataSizing::ZoneSizingData &zsCalcSizing) { zsCalcSizing.CoolDesDay = state.dataEnvrn->EnvironmentName; zsCalcSizing.HeatDesDay = state.dataEnvrn->EnvironmentName; @@ -1762,7 +1761,7 @@ void updateZoneSizingEndDay(DataSizing::ZoneSizingData &zsCalcSizing, // save heat peak conditions when there is no design heating load or design heating volume flow rate, i.e., when // zone temperature is always greater than the zone heating thermostat temperature if (zsCalcFinalSizing.DesHeatLoad == 0) { - bool FirstIteration = true; + bool FirstIteration = true; // declare as static to save for next iteration? but needs to be space/zone specific? for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepInDay; ++TimeStepIndex) { if ((zsCalcSizing.HeatZoneTempSeq(TimeStepIndex) < zsCalcSizing.ZoneTempAtHeatPeak) || FirstIteration) { zsCalcSizing.ZoneTempAtHeatPeak = zsCalcSizing.HeatZoneTempSeq(TimeStepIndex); @@ -1957,7 +1956,7 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum // Other - Initialize to first space values (clear later if not all the same) int firstSpace = state.dataHeatBal->Zone(zoneNum).spaceIndexes[0]; - auto &firstSpaceCFS = state.dataSize->CalcFinalSpaceSizing(firstSpace); + auto const &firstSpaceCFS = state.dataSize->CalcFinalSpaceSizing(firstSpace); zoneCFS.HeatDesDay = firstSpaceCFS.HeatDesDay; zoneCFS.HeatDDNum = firstSpaceCFS.HeatDDNum; zoneCFS.cHeatDDDate = firstSpaceCFS.cHeatDDDate; @@ -1990,10 +1989,6 @@ void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum } int numSpaces = 0; // Track this for averages later - bool heatDDNumAllSame = true; - bool coolDDNumAllSame = true; - int priorHeatDDNum = 0; - int priorCoolDDNum = 0; for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { auto &spaceCFS = state.dataSize->CalcFinalSpaceSizing(spaceNum); ++numSpaces; @@ -2309,7 +2304,7 @@ void updateZoneSizingEndZoneSizingCalc2(EnergyPlusData &state, DataSizing::ZoneS zsCalcSizing.LatCoolPeakDateHrMin = zsCalcSizing.cLatentCoolDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtLatentCoolMax); } -std::string sizingPeakTimeStamp(EnergyPlusData &state, int timeStepIndex) +std::string sizingPeakTimeStamp(EnergyPlusData const &state, int timeStepIndex) { int constexpr minToSec = 60; int hour = 0; @@ -2324,7 +2319,7 @@ std::string sizingPeakTimeStamp(EnergyPlusData &state, int timeStepIndex) void writeZszSpsz(EnergyPlusData &state, EnergyPlus::InputOutputFile &outputFile, int const numSpacesOrZones, - Array1D const zsEquipConfig, + Array1D const &zsEquipConfig, EPVector const &zsCalcFinalSizing, Array2D const &zsCalcSizing) { @@ -3317,8 +3312,8 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI for (std::size_t i = 0; i < state.dataSize->ZoneSizing.size(); ++i) { updateZoneSizingEndZoneSizingCalc4(state.dataSize->ZoneSizing[i], state.dataSize->CalcZoneSizing[i]); if (state.dataHeatBal->doSpaceHeatBalanceSizing) { - for (std::size_t i = 0; i < state.dataSize->SpaceSizing.size(); ++i) { - updateZoneSizingEndZoneSizingCalc4(state.dataSize->SpaceSizing[i], state.dataSize->CalcSpaceSizing[i]); + for (std::size_t j = 0; j < state.dataSize->SpaceSizing.size(); ++j) { + updateZoneSizingEndZoneSizingCalc4(state.dataSize->SpaceSizing[j], state.dataSize->CalcSpaceSizing[j]); } } } @@ -3326,8 +3321,8 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI for (std::size_t i = 0; i < state.dataSize->FinalZoneSizing.size(); ++i) { updateZoneSizingEndZoneSizingCalc5(state.dataSize->FinalZoneSizing[i], state.dataSize->CalcFinalZoneSizing[i]); if (state.dataHeatBal->doSpaceHeatBalanceSizing) { - for (std::size_t i = 0; i < state.dataSize->FinalSpaceSizing.size(); ++i) { - updateZoneSizingEndZoneSizingCalc5(state.dataSize->FinalSpaceSizing[i], state.dataSize->CalcFinalSpaceSizing[i]); + for (std::size_t j = 0; j < state.dataSize->FinalSpaceSizing.size(); ++j) { + updateZoneSizingEndZoneSizingCalc5(state.dataSize->FinalSpaceSizing[j], state.dataSize->CalcFinalSpaceSizing[j]); } } } @@ -4042,9 +4037,6 @@ void SetZoneEquipSimOrder(EnergyPlusData &state, int const ControlledZoneNum) // required conditions (heating or cooling). // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int CurEqHeatingPriority; // Used to make sure "optimization features" on compilers don't defeat purpose of this routine - int CurEqCoolingPriority; // Used to make sure "optimization features" on compilers don't defeat purpose of this routine - auto &zeq(state.dataZoneEquip->ZoneEquipList(ControlledZoneNum)); int const NumOfEquipTypes(zeq.NumOfEquipTypes); for (int EquipTypeNum = 1; EquipTypeNum <= NumOfEquipTypes; ++EquipTypeNum) { @@ -4069,8 +4061,8 @@ void SetZoneEquipSimOrder(EnergyPlusData &state, int const ControlledZoneNum) for (int EquipTypeNum = 1; EquipTypeNum <= NumOfEquipTypes; ++EquipTypeNum) { auto &pso(state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum)); - CurEqHeatingPriority = pso.HeatingPriority; - CurEqCoolingPriority = pso.CoolingPriority; + int CurEqHeatingPriority = pso.HeatingPriority; + int CurEqCoolingPriority = pso.CoolingPriority; for (int ComparedEquipTypeNum = EquipTypeNum; ComparedEquipTypeNum <= NumOfEquipTypes; ++ComparedEquipTypeNum) { auto &psc(state.dataZoneEquipmentManager->PrioritySimOrder(ComparedEquipTypeNum)); @@ -4266,8 +4258,8 @@ void distributeOutputRequired(EnergyPlusData &state, const int &equipNum = state.dataZoneEquipmentManager->PrioritySimOrder(priorityNum).EquipPtr; // Determine whether we're heating or cooling and choose the appropriate fraction - const Real64 heatLoadRatio = thisZEqList.SequentialHeatingFraction(state, equipNum); - const Real64 coolLoadRatio = thisZEqList.SequentialCoolingFraction(state, equipNum); + heatLoadRatio = thisZEqList.SequentialHeatingFraction(state, equipNum); + coolLoadRatio = thisZEqList.SequentialCoolingFraction(state, equipNum); const Real64 loadRatio = (energy.TotalOutputRequired >= 0.0) ? heatLoadRatio : coolLoadRatio; // Energy loads @@ -5004,7 +4996,7 @@ void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration) for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { auto &thisZoneEquip(state.dataZoneEquip->ZoneEquipConfig(zoneNum)); - auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum); + auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum); if (!thisZoneEquip.IsControlled) continue; int numRetNodes = thisZoneEquip.NumReturnNodes; Real64 totalZoneReturnMassFlow = 0.0; @@ -5092,8 +5084,8 @@ void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration) } void CalcZoneInfiltrationFlows(EnergyPlusData &state, - int const ZoneNum, // current zone index - Real64 &ZoneReturnAirMassFlowRate // zone total zone return air mass flow rate + int const ZoneNum, // current zone index + Real64 const &ZoneReturnAirMassFlowRate // zone total zone return air mass flow rate ) { Real64 constexpr ConvergenceTolerance(0.000010); @@ -5230,7 +5222,7 @@ void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIterat if (state.dataHeatBal->Zone(ZoneNum).HasAirFlowWindowReturn) { for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { - auto &thisSpace = state.dataHeatBal->space(spaceNum); + auto const &thisSpace = state.dataHeatBal->space(spaceNum); for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0 && state.dataSurface->SurfWinAirflowDestination(SurfNum) == DataSurfaces::WindowAirFlowDestination::Return) { @@ -5811,20 +5803,20 @@ void CalcAirFlowSimple(EnergyPlusData &state, Real64 HumRatZN = 0.0; // HumRat of this Zone/Space Real64 HumRatZM = 0.0; // HumRat of From Zone/Space if (state.dataHeatBal->doSpaceHeatBalance) { - auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisMixing.spaceIndex); + auto const &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisMixing.spaceIndex); TZN = thisSpaceHB.MixingMAT; // Temperature of this Space HumRatZN = thisSpaceHB.MixingHumRat; // HumRat of this Space if (thisMixing.fromSpaceIndex == 0) { - auto &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(fromZoneNum); + auto const &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(fromZoneNum); TZM = fromZoneHB.MixingMAT; // Temperature of From Zone HumRatZM = fromZoneHB.MixingHumRat; // HumRat of From Zone } else { - auto &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisMixing.fromSpaceIndex); + auto const &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisMixing.fromSpaceIndex); TZM = fromSpaceHB.MixingMAT; // Temperature of From Space HumRatZM = fromSpaceHB.MixingHumRat; // HumRat of From Space } } else { - auto &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(fromZoneNum); + auto const &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(fromZoneNum); TZN = thisZoneHB.MixingMAT; // Temperature of this zone TZM = fromZoneHB.MixingMAT; // Temperature of From Zone HumRatZN = thisZoneHB.MixingHumRat; // HumRat of this zone @@ -5841,9 +5833,8 @@ void CalcAirFlowSimple(EnergyPlusData &state, bool MixingLimitFlag = false; // Hybrid ventilation global control - int I = 0; if (thisMixing.HybridControlType == DataHeatBalance::HybridCtrlType::Global && thisMixing.HybridControlMasterNum > 0) { - I = thisMixing.HybridControlMasterNum; + int I = thisMixing.HybridControlMasterNum; if (!state.dataHeatBal->Ventilation(I).HybridControlMasterStatus) continue; } else { // Ensure the minimum indoor temperature <= the maximum indoor temperature @@ -6070,14 +6061,14 @@ void CalcAirFlowSimple(EnergyPlusData &state, Real64 HumRatZN = 0.0; // HumRat of this Zone/Space Real64 HumRatZM = 0.0; // HumRat of From Zone/Space if (state.dataHeatBal->doSpaceHeatBalance) { - auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.spaceIndex); + auto const &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.spaceIndex); TZN = thisSpaceHB.MixingMAT; // Temperature of this Space HumRatZN = thisSpaceHB.MixingHumRat; // HumRat of this Space if (thisCrossMixing.fromSpaceIndex == 0) { TZM = fromZoneHB.MixingMAT; // Temperature of From Zone HumRatZM = fromZoneHB.MixingHumRat; // HumRat of From Zone } else { - auto &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.fromSpaceIndex); + auto const &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.fromSpaceIndex); TZM = fromSpaceHB.MixingMAT; // Temperature of From Space HumRatZM = fromSpaceHB.MixingHumRat; // HumRat of From Space } @@ -6191,7 +6182,7 @@ void CalcAirFlowSimple(EnergyPlusData &state, thisCrossMixing.ReportFlag = true; } - if ((TD <= 0.0) || ((TD > 0.0) && (TZM - TZN >= TD))) { + if ((TD <= 0.0) || (TZM - TZN >= TD)) { // SET COEFFICIENTS . Real64 Tavg = (TZN + TZM) / 2.0; Real64 Wavg = (HumRatZN + HumRatZM) / 2.0; @@ -6268,7 +6259,7 @@ void CalcAirFlowSimple(EnergyPlusData &state, Real64 TZoneA = zoneAHB.MixingMAT; Real64 HumRatZoneA = zoneAHB.MixingHumRat; if ((state.dataHeatBal->doSpaceHeatBalance) && (thisRefDoorMixing.spaceIndex > 0)) { - auto &spaceAHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.spaceIndex); + auto const &spaceAHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.spaceIndex); TZoneA = spaceAHB.MixingMAT; HumRatZoneA = spaceAHB.MixingHumRat; } @@ -6281,7 +6272,7 @@ void CalcAirFlowSimple(EnergyPlusData &state, Real64 HumRatZoneB = zoneBHB.MixingHumRat; Real64 CpAirZoneB = PsyCpAirFnW(HumRatZoneB); if ((state.dataHeatBal->doSpaceHeatBalance) && (thisRefDoorMixing.fromSpaceIndex > 0)) { - auto &spaceBHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.fromSpaceIndex); + auto const &spaceBHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.fromSpaceIndex); TZoneB = spaceBHB.MixingMAT; HumRatZoneB = spaceBHB.MixingHumRat; } diff --git a/src/EnergyPlus/ZoneEquipmentManager.hh b/src/EnergyPlus/ZoneEquipmentManager.hh index b1114a23688..85ef5c9400b 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.hh +++ b/src/EnergyPlus/ZoneEquipmentManager.hh @@ -94,7 +94,7 @@ namespace ZoneEquipmentManager { DataSizing::ZoneSizingData &zsCalcSizing, DataZoneEnergyDemands::ZoneSystemSensibleDemand &zsEnergyDemand, DataZoneEnergyDemands::ZoneSystemMoistureDemand &zsMoistureDemand, - DataHeatBalance::ZoneData &zoneOrSpace, + DataHeatBalance::ZoneData const &zoneOrSpace, int zoneNum, int spaceNum = 0); @@ -121,7 +121,7 @@ namespace ZoneEquipmentManager { void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator CallIndicator); - void updateZoneSizingBeginDay(EnergyPlusData &state, DataSizing::ZoneSizingData &zsCalcSizing); + void updateZoneSizingBeginDay(EnergyPlusData const &state, DataSizing::ZoneSizingData &zsCalcSizing); void updateZoneSizingDuringDay(DataSizing::ZoneSizingData &zsSizing, DataSizing::ZoneSizingData &zsCalcSizing, @@ -147,11 +147,11 @@ namespace ZoneEquipmentManager { void writeZszSpsz(EnergyPlusData &state, EnergyPlus::InputOutputFile &outputFile, int const numSpacesOrZones, - Array1D const zsEquipConfig, + Array1D const &zsEquipConfig, EPVector const &zsCalcFinalSizing, Array2D const &zsCalcSizing); - std::string sizingPeakTimeStamp(EnergyPlusData &state, int timeStepIndex); + std::string sizingPeakTimeStamp(EnergyPlusData const &state, int timeStepIndex); void updateZoneSizingEndZoneSizingCalc3(DataSizing::ZoneSizingData &zsCalcFinalSizing, Array2D &zsCalcSizing, @@ -213,8 +213,8 @@ namespace ZoneEquipmentManager { void CalcZoneMassBalance(EnergyPlusData &state, bool FirstHVACIteration); void CalcZoneInfiltrationFlows(EnergyPlusData &state, - int ZoneNum, // current zone index - Real64 &ZoneReturnAirMassFlowRate // zone total zone return air mass flow rate + int const ZoneNum, // current zone index + Real64 const &ZoneReturnAirMassFlowRate // zone total zone return air mass flow rate ); void CalcAirFlowSimple(EnergyPlusData &state, diff --git a/src/EnergyPlus/ZoneTempPredictorCorrector.cc b/src/EnergyPlus/ZoneTempPredictorCorrector.cc index d5eb9574cfb..bfd6a4138c3 100644 --- a/src/EnergyPlus/ZoneTempPredictorCorrector.cc +++ b/src/EnergyPlus/ZoneTempPredictorCorrector.cc @@ -282,8 +282,6 @@ void GetZoneAirSetPoints(EnergyPlusData &state) int CTIndex; int HumidControlledZoneNum; // The Humidity Controller that information is being loaded into bool ValidScheduleControlType; - bool ValidRadFractSched; // check for if radiative fraction schedule has valid numbers - bool ValidZoneOvercoolRangeSched; // check for if Zone Overcool range schedule has valid numbers int SchedMin; int SchedMax; int ActualZoneNum; @@ -291,10 +289,8 @@ void GetZoneAirSetPoints(EnergyPlusData &state) int ComfortControlledZoneNum; // The Splitter that you are currently loading input into int i; - int IZoneCount; int found; int NumStageControlledZones; // Number of staged controlled objects - int StageControlledZoneNum; // Index for staged controlled zones Array1D_int CTSchedMapToControlledZone; Array1D_int CCmSchedMapToControlledZone; @@ -327,17 +323,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) static constexpr std::string_view Format_701("Zone Volume Capacitance Multiplier,{:8.3F} ,{:8.3F},{:8.3F},{:8.3F}\n"); auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject; - auto &TStatObjects = state.dataZoneCtrls->TStatObjects; - auto &Zone = state.dataHeatBal->Zone; - auto &ZoneList = state.dataHeatBal->ZoneList; - auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone; - auto &HumidityControlZone = state.dataZoneCtrls->HumidityControlZone; - auto &ComfortTStatObjects = state.dataZoneCtrls->ComfortTStatObjects; - auto &ComfortControlledZone = state.dataZoneCtrls->ComfortControlledZone; int NumOfZones = state.dataGlobal->NumOfZones; - auto &StageControlledZone = state.dataZoneCtrls->StageControlledZone; - auto &SetPointSingleHeating = state.dataZoneTempPredictorCorrector->SetPointSingleHeating; - auto &SetPointSingleCooling = state.dataZoneTempPredictorCorrector->SetPointSingleCooling; auto &cAlphaArgs = state.dataIPShortCut->cAlphaArgs; auto &rNumericArgs = state.dataIPShortCut->rNumericArgs; auto &lNumericFieldBlanks = state.dataIPShortCut->lNumericFieldBlanks; @@ -345,16 +331,16 @@ void GetZoneAirSetPoints(EnergyPlusData &state) auto &cAlphaFieldNames = state.dataIPShortCut->cAlphaFieldNames; auto &cNumericFieldNames = state.dataIPShortCut->cNumericFieldNames; auto &inputProcessor = state.dataInputProcessing->inputProcessor; - auto &SetPointDualHeatCool = state.dataZoneTempPredictorCorrector->SetPointDualHeatCool; cCurrentModuleObject = cZControlTypes(static_cast(ZoneControlTypes::TStat)); // Update Num in state and make local convenience copy int NumTStatStatements = state.dataZoneCtrls->NumTStatStatements = inputProcessor->getNumObjectsFound(state, cCurrentModuleObject); - TStatObjects.allocate(NumTStatStatements); + state.dataZoneCtrls->TStatObjects.allocate(NumTStatStatements); // Pre-scan for use of Zone lists in TStat statements (i.e. Global application of TStat) state.dataZoneCtrls->NumTempControlledZones = 0; for (Item = 1; Item <= NumTStatStatements; ++Item) { + auto &TStatObjects = state.dataZoneCtrls->TStatObjects(Item); inputProcessor->getObjectItem(state, cCurrentModuleObject, Item, @@ -369,22 +355,23 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cNumericFieldNames); Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound); - TStatObjects(Item).Name = cAlphaArgs(1); - Item1 = Util::FindItemInList(cAlphaArgs(2), Zone); + TStatObjects.Name = cAlphaArgs(1); + Item1 = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->Zone); ZLItem = 0; - if (Item1 == 0 && state.dataHeatBal->NumOfZoneLists > 0) ZLItem = Util::FindItemInList(cAlphaArgs(2), ZoneList); + if (Item1 == 0 && state.dataHeatBal->NumOfZoneLists > 0) ZLItem = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->ZoneList); if (Item1 > 0) { - TStatObjects(Item).TempControlledZoneStartPtr = state.dataZoneCtrls->NumTempControlledZones + 1; + TStatObjects.TempControlledZoneStartPtr = state.dataZoneCtrls->NumTempControlledZones + 1; ++state.dataZoneCtrls->NumTempControlledZones; - TStatObjects(Item).NumOfZones = 1; - TStatObjects(Item).ZoneListActive = false; - TStatObjects(Item).ZoneOrZoneListPtr = Item1; + TStatObjects.NumOfZones = 1; + TStatObjects.ZoneListActive = false; + TStatObjects.ZoneOrZoneListPtr = Item1; } else if (ZLItem > 0) { - TStatObjects(Item).TempControlledZoneStartPtr = state.dataZoneCtrls->NumTempControlledZones + 1; - state.dataZoneCtrls->NumTempControlledZones += ZoneList(ZLItem).NumOfZones; - TStatObjects(Item).NumOfZones = ZoneList(ZLItem).NumOfZones; - TStatObjects(Item).ZoneListActive = true; - TStatObjects(Item).ZoneOrZoneListPtr = ZLItem; + auto const &ZoneList = state.dataHeatBal->ZoneList(ZLItem); + TStatObjects.TempControlledZoneStartPtr = state.dataZoneCtrls->NumTempControlledZones + 1; + state.dataZoneCtrls->NumTempControlledZones += ZoneList.NumOfZones; + TStatObjects.NumOfZones = ZoneList.NumOfZones; + TStatObjects.ZoneListActive = true; + TStatObjects.ZoneOrZoneListPtr = ZLItem; } else { ShowSevereError( state, format("{}=\"{}\" invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2))); @@ -399,13 +386,14 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } if (state.dataZoneCtrls->NumTempControlledZones > 0) { - TempControlledZone.allocate(state.dataZoneCtrls->NumTempControlledZones); + state.dataZoneCtrls->TempControlledZone.allocate(state.dataZoneCtrls->NumTempControlledZones); TStatControlTypes.allocate(state.dataZoneCtrls->NumTempControlledZones); // Number of set point types CTSchedMapToControlledZone.dimension(state.dataZoneCtrls->NumTempControlledZones, 0); TempControlledZoneNum = 0; state.dataZoneTempPredictorCorrector->NumOnOffCtrZone = 0; for (Item = 1; Item <= NumTStatStatements; ++Item) { + auto &TStatObjects = state.dataZoneCtrls->TStatObjects(Item); inputProcessor->getObjectItem(state, cCurrentModuleObject, Item, @@ -418,58 +406,63 @@ void GetZoneAirSetPoints(EnergyPlusData &state) lAlphaFieldBlanks, cAlphaFieldNames, cNumericFieldNames); - for (Item1 = 1; Item1 <= TStatObjects(Item).NumOfZones; ++Item1) { + for (Item1 = 1; Item1 <= TStatObjects.NumOfZones; ++Item1) { ++TempControlledZoneNum; - if (TStatObjects(Item).ZoneListActive) { - cAlphaArgs(2) = Zone(ZoneList(TStatObjects(Item).ZoneOrZoneListPtr).Zone(Item1)).Name; + auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone(TempControlledZoneNum); + if (TStatObjects.ZoneListActive) { + auto &ZoneList = state.dataHeatBal->ZoneList(TStatObjects.ZoneOrZoneListPtr); + cAlphaArgs(2) = state.dataHeatBal->Zone(ZoneList.Zone(Item1)).Name; } - int ZoneAssigned = - Util::FindItemInList(cAlphaArgs(2), TempControlledZone, &DataZoneControls::ZoneTempControls::ZoneName, TempControlledZoneNum - 1); + int ZoneAssigned = Util::FindItemInList( + cAlphaArgs(2), state.dataZoneCtrls->TempControlledZone, &DataZoneControls::ZoneTempControls::ZoneName, TempControlledZoneNum - 1); if (ZoneAssigned == 0) { - TempControlledZone(TempControlledZoneNum).ZoneName = cAlphaArgs(2); - TempControlledZone(TempControlledZoneNum).ActualZoneNum = Util::FindItemInList(cAlphaArgs(2), Zone); - if (TempControlledZone(TempControlledZoneNum).ActualZoneNum == 0) { + TempControlledZone.ZoneName = cAlphaArgs(2); + TempControlledZone.ActualZoneNum = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->Zone); + if (TempControlledZone.ActualZoneNum == 0) { ShowSevereError( state, format( "{}=\"{}\" invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2))); ErrorsFound = true; } else { - Zone(TempControlledZone(TempControlledZoneNum).ActualZoneNum).TempControlledZoneIndex = TempControlledZoneNum; + state.dataHeatBal->Zone(TempControlledZone.ActualZoneNum).TempControlledZoneIndex = TempControlledZoneNum; } } else { - TempControlledZone(TempControlledZoneNum).ZoneName = cAlphaArgs(2); // for continuity + TempControlledZone.ZoneName = cAlphaArgs(2); // for continuity ShowSevereError(state, format("{}=\"{}\" invalid {}=\"{}\" zone previously assigned.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2))); - ShowContinueError(state, format("...Zone was previously assigned to Thermostat=\"{}\".", TempControlledZone(ZoneAssigned).Name)); + ShowContinueError( + state, + format("...Zone was previously assigned to Thermostat=\"{}\".", state.dataZoneCtrls->TempControlledZone(ZoneAssigned).Name)); ErrorsFound = true; continue; } - if (!TStatObjects(Item).ZoneListActive) { - TempControlledZone(TempControlledZoneNum).Name = cAlphaArgs(1); + if (!TStatObjects.ZoneListActive) { + TempControlledZone.Name = cAlphaArgs(1); } else { + auto &ZoneList = state.dataHeatBal->ZoneList(TStatObjects.ZoneOrZoneListPtr); CheckCreatedZoneItemName(state, RoutineName, cCurrentModuleObject, - Zone(ZoneList(TStatObjects(Item).ZoneOrZoneListPtr).Zone(Item1)).Name, - ZoneList(TStatObjects(Item).ZoneOrZoneListPtr).MaxZoneNameLength, - TStatObjects(Item).Name, - TempControlledZone, + state.dataHeatBal->Zone(ZoneList.Zone(Item1)).Name, + ZoneList.MaxZoneNameLength, + TStatObjects.Name, + state.dataZoneCtrls->TempControlledZone, TempControlledZoneNum - 1, - TempControlledZone(TempControlledZoneNum).Name, + TempControlledZone.Name, errFlag); if (errFlag) ErrorsFound = true; } - TempControlledZone(TempControlledZoneNum).ControlTypeSchedName = cAlphaArgs(3); - TempControlledZone(TempControlledZoneNum).CTSchedIndex = GetScheduleIndex(state, cAlphaArgs(3)); + TempControlledZone.ControlTypeSchedName = cAlphaArgs(3); + TempControlledZone.CTSchedIndex = GetScheduleIndex(state, cAlphaArgs(3)); if (Item1 == 1) { // only show error on first of several if zone list - if (TempControlledZone(TempControlledZoneNum).CTSchedIndex == 0) { + if (TempControlledZone.CTSchedIndex == 0) { ShowSevereError( state, format( @@ -477,8 +470,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } else { // Check validity of control types. - ValidScheduleControlType = - CheckScheduleValueMinMax(state, TempControlledZone(TempControlledZoneNum).CTSchedIndex, ">=", 0.0, "<=", 4.0); + ValidScheduleControlType = CheckScheduleValueMinMax(state, TempControlledZone.CTSchedIndex, ">=", 0.0, "<=", 4.0); if (!ValidScheduleControlType) { ShowSevereError( state, @@ -497,20 +489,20 @@ void GetZoneAirSetPoints(EnergyPlusData &state) NumAlphas = 9; } - TempControlledZone(TempControlledZoneNum).NumControlTypes = nint((NumAlphas - 3.0) / 2.0); - TempControlledZone(TempControlledZoneNum).ControlType.allocate(TempControlledZone(TempControlledZoneNum).NumControlTypes); - TempControlledZone(TempControlledZoneNum).ControlTypeName.allocate(TempControlledZone(TempControlledZoneNum).NumControlTypes); - TempControlledZone(TempControlledZoneNum).ControlTypeEnum.allocate(TempControlledZone(TempControlledZoneNum).NumControlTypes); + TempControlledZone.NumControlTypes = nint((NumAlphas - 3.0) / 2.0); + TempControlledZone.ControlType.allocate(TempControlledZone.NumControlTypes); + TempControlledZone.ControlTypeName.allocate(TempControlledZone.NumControlTypes); + TempControlledZone.ControlTypeEnum.allocate(TempControlledZone.NumControlTypes); - for (ControlTypeNum = 1; ControlTypeNum <= TempControlledZone(TempControlledZoneNum).NumControlTypes; ++ControlTypeNum) { + for (ControlTypeNum = 1; ControlTypeNum <= TempControlledZone.NumControlTypes; ++ControlTypeNum) { - TempControlledZone(TempControlledZoneNum).ControlType(ControlTypeNum) = cAlphaArgs(nint(2.0 * ControlTypeNum - 1 + 3)); - TempControlledZone(TempControlledZoneNum).ControlTypeName(ControlTypeNum) = cAlphaArgs(nint(2.0 * ControlTypeNum + 3)); + TempControlledZone.ControlType(ControlTypeNum) = cAlphaArgs(nint(2.0 * ControlTypeNum - 1 + 3)); + TempControlledZone.ControlTypeName(ControlTypeNum) = cAlphaArgs(nint(2.0 * ControlTypeNum + 3)); - if (!TempControlledZone(TempControlledZoneNum).ControlType(ControlTypeNum).empty()) { - HVAC::ThermostatType ctrlType = static_cast( - getEnumValue(ValidControlTypesUC, TempControlledZone(TempControlledZoneNum).ControlType(ControlTypeNum))); - TempControlledZone(TempControlledZoneNum).ControlTypeEnum(ControlTypeNum) = ctrlType; + if (!TempControlledZone.ControlType(ControlTypeNum).empty()) { + HVAC::ThermostatType ctrlType = + static_cast(getEnumValue(ValidControlTypesUC, TempControlledZone.ControlType(ControlTypeNum))); + TempControlledZone.ControlTypeEnum(ControlTypeNum) = ctrlType; if (ctrlType == HVAC::ThermostatType::Invalid) { ShowSevereError(state, format("{}=\"{}\" invalid {}=\"{}\"", @@ -531,7 +523,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } if (NumNums > 0) { if (rNumericArgs(1) >= 0.0) { - TempControlledZone(TempControlledZoneNum).DeltaTCutSet = rNumericArgs(1); + TempControlledZone.DeltaTCutSet = rNumericArgs(1); if (rNumericArgs(1) > 0.0) state.dataZoneTempPredictorCorrector->NumOnOffCtrZone++; } else { ShowSevereError( @@ -541,10 +533,9 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } } - if (TempControlledZone(TempControlledZoneNum).DeltaTCutSet > 0.0) { - for (ControlTypeNum = 1; ControlTypeNum <= TempControlledZone(TempControlledZoneNum).NumControlTypes; ++ControlTypeNum) { - if (Util::SameString(TempControlledZone(TempControlledZoneNum).ControlType(ControlTypeNum), - "ThermostatSetpoint:SingleHeatingOrCooling")) { + if (TempControlledZone.DeltaTCutSet > 0.0) { + for (ControlTypeNum = 1; ControlTypeNum <= TempControlledZone.NumControlTypes; ++ControlTypeNum) { + if (Util::SameString(TempControlledZone.ControlType(ControlTypeNum), "ThermostatSetpoint:SingleHeatingOrCooling")) { ShowWarningError(state, format("{}=\"{}: The choice of Temperature Difference Between Cutout And Setpoint will not be applied " "to ThermostatSetpoint:SingleHeatingOrCooling.", @@ -561,7 +552,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) state.dataZoneTempPredictorCorrector->NumSingleTempHeatingControls = inputProcessor->getNumObjectsFound(state, cCurrentModuleObject); if (state.dataZoneTempPredictorCorrector->NumSingleTempHeatingControls > 0) - SetPointSingleHeating.allocate(state.dataZoneTempPredictorCorrector->NumSingleTempHeatingControls); + state.dataZoneTempPredictorCorrector->SetPointSingleHeating.allocate(state.dataZoneTempPredictorCorrector->NumSingleTempHeatingControls); for (int idx = 1; idx <= state.dataZoneTempPredictorCorrector->NumSingleTempHeatingControls; ++idx) { inputProcessor->getObjectItem(state, @@ -577,7 +568,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaFieldNames, cNumericFieldNames); Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound); - auto &singleHtgSetpoint = SetPointSingleHeating(idx); + auto &singleHtgSetpoint = state.dataZoneTempPredictorCorrector->SetPointSingleHeating(idx); singleHtgSetpoint.Name = cAlphaArgs(1); singleHtgSetpoint.TempSchedName = cAlphaArgs(2); singleHtgSetpoint.TempSchedIndex = GetScheduleIndex(state, cAlphaArgs(2)); @@ -593,7 +584,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) state.dataZoneTempPredictorCorrector->NumSingleTempCoolingControls = inputProcessor->getNumObjectsFound(state, cCurrentModuleObject); if (state.dataZoneTempPredictorCorrector->NumSingleTempCoolingControls > 0) - SetPointSingleCooling.allocate(state.dataZoneTempPredictorCorrector->NumSingleTempCoolingControls); + state.dataZoneTempPredictorCorrector->SetPointSingleCooling.allocate(state.dataZoneTempPredictorCorrector->NumSingleTempCoolingControls); for (int idx = 1; idx <= state.dataZoneTempPredictorCorrector->NumSingleTempCoolingControls; ++idx) { inputProcessor->getObjectItem(state, @@ -609,7 +600,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaFieldNames, cNumericFieldNames); Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound); - auto &singleClgSetpoint = SetPointSingleCooling(idx); + auto &singleClgSetpoint = state.dataZoneTempPredictorCorrector->SetPointSingleCooling(idx); singleClgSetpoint.Name = cAlphaArgs(1); singleClgSetpoint.TempSchedName = cAlphaArgs(2); singleClgSetpoint.TempSchedIndex = GetScheduleIndex(state, cAlphaArgs(2)); @@ -656,7 +647,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) state.dataZoneTempPredictorCorrector->NumDualTempHeatCoolControls = inputProcessor->getNumObjectsFound(state, cCurrentModuleObject); if (state.dataZoneTempPredictorCorrector->NumDualTempHeatCoolControls > 0) - SetPointDualHeatCool.allocate(state.dataZoneTempPredictorCorrector->NumDualTempHeatCoolControls); + state.dataZoneTempPredictorCorrector->SetPointDualHeatCool.allocate(state.dataZoneTempPredictorCorrector->NumDualTempHeatCoolControls); for (int idx = 1; idx <= state.dataZoneTempPredictorCorrector->NumDualTempHeatCoolControls; ++idx) { inputProcessor->getObjectItem(state, @@ -672,7 +663,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaFieldNames, cNumericFieldNames); Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound); - auto &dualHeatCoolSetpoint = SetPointDualHeatCool(idx); + auto &dualHeatCoolSetpoint = state.dataZoneTempPredictorCorrector->SetPointDualHeatCool(idx); dualHeatCoolSetpoint.Name = cAlphaArgs(1); dualHeatCoolSetpoint.HeatTempSetptSchedName = cAlphaArgs(2); dualHeatCoolSetpoint.HeatTempSchedIndex = GetScheduleIndex(state, cAlphaArgs(2)); @@ -695,29 +686,32 @@ void GetZoneAirSetPoints(EnergyPlusData &state) int setPointObjectArrayIndex; for (TempControlledZoneNum = 1; TempControlledZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TempControlledZoneNum) { for (int ct = 1; ct <= state.dataZoneCtrls->TempControlledZone(TempControlledZoneNum).NumControlTypes; ct++) { + auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone(TempControlledZoneNum); switch (state.dataZoneCtrls->TempControlledZone(TempControlledZoneNum).ControlTypeEnum(ct)) { case HVAC::ThermostatType::SingleHeating: - setPointObjectArrayIndex = Util::FindItem(TempControlledZone(TempControlledZoneNum).ControlTypeName(ct), SetPointSingleHeating); - TempControlledZone(TempControlledZoneNum).SchIndx_SingleHeatSetPoint = + setPointObjectArrayIndex = + Util::FindItem(TempControlledZone.ControlTypeName(ct), state.dataZoneTempPredictorCorrector->SetPointSingleHeating); + TempControlledZone.SchIndx_SingleHeatSetPoint = state.dataZoneTempPredictorCorrector->SetPointSingleHeating(setPointObjectArrayIndex).TempSchedIndex; break; case HVAC::ThermostatType::SingleCooling: - setPointObjectArrayIndex = Util::FindItem(TempControlledZone(TempControlledZoneNum).ControlTypeName(ct), SetPointSingleCooling); - TempControlledZone(TempControlledZoneNum).SchIndx_SingleCoolSetPoint = + setPointObjectArrayIndex = + Util::FindItem(TempControlledZone.ControlTypeName(ct), state.dataZoneTempPredictorCorrector->SetPointSingleCooling); + TempControlledZone.SchIndx_SingleCoolSetPoint = state.dataZoneTempPredictorCorrector->SetPointSingleCooling(setPointObjectArrayIndex).TempSchedIndex; break; case HVAC::ThermostatType::SingleHeatCool: - setPointObjectArrayIndex = Util::FindItem(TempControlledZone(TempControlledZoneNum).ControlTypeName(ct), - state.dataZoneTempPredictorCorrector->SetPointSingleHeatCool); - TempControlledZone(TempControlledZoneNum).SchIndx_SingleHeatCoolSetPoint = + setPointObjectArrayIndex = + Util::FindItem(TempControlledZone.ControlTypeName(ct), state.dataZoneTempPredictorCorrector->SetPointSingleHeatCool); + TempControlledZone.SchIndx_SingleHeatCoolSetPoint = state.dataZoneTempPredictorCorrector->SetPointSingleHeatCool(setPointObjectArrayIndex).TempSchedIndex; break; case HVAC::ThermostatType::DualSetPointWithDeadBand: - setPointObjectArrayIndex = Util::FindItem(TempControlledZone(TempControlledZoneNum).ControlTypeName(ct), - state.dataZoneTempPredictorCorrector->SetPointDualHeatCool); - TempControlledZone(TempControlledZoneNum).SchIndx_DualSetPointWDeadBandHeat = + setPointObjectArrayIndex = + Util::FindItem(TempControlledZone.ControlTypeName(ct), state.dataZoneTempPredictorCorrector->SetPointDualHeatCool); + TempControlledZone.SchIndx_DualSetPointWDeadBandHeat = state.dataZoneTempPredictorCorrector->SetPointDualHeatCool(setPointObjectArrayIndex).HeatTempSchedIndex; - TempControlledZone(TempControlledZoneNum).SchIndx_DualSetPointWDeadBandCool = + TempControlledZone.SchIndx_DualSetPointWDeadBandCool = state.dataZoneTempPredictorCorrector->SetPointDualHeatCool(setPointObjectArrayIndex).CoolTempSchedIndex; break; default: @@ -730,15 +724,16 @@ void GetZoneAirSetPoints(EnergyPlusData &state) for (TempControlledZoneNum = 1; TempControlledZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TempControlledZoneNum) { - ActualZoneNum = TempControlledZone(TempControlledZoneNum).ActualZoneNum; - CTIndex = TempControlledZone(TempControlledZoneNum).CTSchedIndex; + auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone(TempControlledZoneNum); + ActualZoneNum = TempControlledZone.ActualZoneNum; + CTIndex = TempControlledZone.CTSchedIndex; if (CTIndex == 0) continue; // error will be caught elsewhere SchedMin = GetScheduleMinValue(state, CTIndex); SchedMax = GetScheduleMaxValue(state, CTIndex); if (SchedMin == 0 && SchedMax == 0) { if (FindNumberInList(CTIndex, CTSchedMapToControlledZone, state.dataZoneCtrls->NumTempControlledZones) == 0) { - ShowSevereError(state, format("Control Type Schedule={}", TempControlledZone(TempControlledZoneNum).ControlTypeSchedName)); + ShowSevereError(state, format("Control Type Schedule={}", TempControlledZone.ControlTypeSchedName)); ShowContinueError(state, "..specifies control type 0 for all entries."); ShowContinueError(state, "All zones using this Control Type Schedule have no heating or cooling available."); } @@ -752,70 +747,62 @@ void GetZoneAirSetPoints(EnergyPlusData &state) case HVAC::ThermostatType::Uncontrolled: break; case HVAC::ThermostatType::SingleHeating: - TempIndex = TempControlledZone(TempControlledZoneNum).SchIndx_SingleHeatSetPoint; + TempIndex = TempControlledZone.SchIndx_SingleHeatSetPoint; if (TempIndex == 0) { if (CheckScheduleValue(state, CTIndex, static_cast(HVAC::ThermostatType::SingleHeating))) { - ShowSevereError(state, format("Control Type Schedule={}", TempControlledZone(TempControlledZoneNum).ControlTypeSchedName)); + ShowSevereError(state, format("Control Type Schedule={}", TempControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("..specifies control type 1 ({}) as the control type. Not valid for this zone.", ValidControlTypes[static_cast(HVAC::ThermostatType::SingleHeating)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TStat)), - TempControlledZone(TempControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", TempControlledZone(TempControlledZoneNum).ZoneName)); + ShowContinueError( + state, format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TStat)), TempControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", TempControlledZone.ZoneName)); ErrorsFound = true; } } break; case HVAC::ThermostatType::SingleCooling: - TempIndex = TempControlledZone(TempControlledZoneNum).SchIndx_SingleCoolSetPoint; + TempIndex = TempControlledZone.SchIndx_SingleCoolSetPoint; if (TempIndex == 0) { if (CheckScheduleValue(state, CTIndex, static_cast(HVAC::ThermostatType::SingleCooling))) { - ShowSevereError(state, format("Control Type Schedule={}", TempControlledZone(TempControlledZoneNum).ControlTypeSchedName)); + ShowSevereError(state, format("Control Type Schedule={}", TempControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("..specifies control type 2 ({}) as the control type. Not valid for this zone.", ValidControlTypes[static_cast(HVAC::ThermostatType::SingleCooling)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TStat)), - TempControlledZone(TempControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", TempControlledZone(TempControlledZoneNum).ZoneName)); + ShowContinueError( + state, format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TStat)), TempControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", TempControlledZone.ZoneName)); ErrorsFound = true; } } break; case HVAC::ThermostatType::SingleHeatCool: - TempIndex = TempControlledZone(TempControlledZoneNum).SchIndx_SingleHeatCoolSetPoint; + TempIndex = TempControlledZone.SchIndx_SingleHeatCoolSetPoint; if (TempIndex == 0) { if (CheckScheduleValue(state, CTIndex, static_cast(HVAC::ThermostatType::SingleHeatCool))) { - ShowSevereError(state, format("Schedule={}", TempControlledZone(TempControlledZoneNum).ControlTypeSchedName)); + ShowSevereError(state, format("Schedule={}", TempControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("..specifies control type 3 ({}) as the control type. Not valid for this zone.", ValidControlTypes[static_cast(HVAC::ThermostatType::SingleHeatCool)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TStat)), - TempControlledZone(TempControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", TempControlledZone(TempControlledZoneNum).ZoneName)); + ShowContinueError( + state, format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TStat)), TempControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", TempControlledZone.ZoneName)); ErrorsFound = true; } } break; case HVAC::ThermostatType::DualSetPointWithDeadBand: - TempIndex = TempControlledZone(TempControlledZoneNum) + TempIndex = TempControlledZone .SchIndx_DualSetPointWDeadBandHeat; // using "Heat" as a sentinel that dualsetpoint is on this zone control object if (TempIndex == 0) { if (CheckScheduleValue(state, CTIndex, static_cast(HVAC::ThermostatType::DualSetPointWithDeadBand))) { - ShowSevereError(state, format("Schedule={}", TempControlledZone(TempControlledZoneNum).ControlTypeSchedName)); + ShowSevereError(state, format("Schedule={}", TempControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("..specifies control type 4 ({}) as the control type. Not valid for this zone.", ValidControlTypes[static_cast(HVAC::ThermostatType::DualSetPointWithDeadBand)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TStat)), - TempControlledZone(TempControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", TempControlledZone(TempControlledZoneNum).ZoneName)); + ShowContinueError( + state, format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TStat)), TempControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", TempControlledZone.ZoneName)); ErrorsFound = true; } } @@ -823,9 +810,9 @@ void GetZoneAirSetPoints(EnergyPlusData &state) default: ShowSevereError(state, format("GetZoneAirSetpoints: Illegal control type for Zone={}, Found value={}, in Schedule={}", - Zone(ActualZoneNum).Name, + state.dataHeatBal->Zone(ActualZoneNum).Name, ControlTypeNum, - TempControlledZone(TempControlledZoneNum).ControlTypeSchedName)); + TempControlledZone.ControlTypeSchedName)); ShowContinueError(state, "..valid range values are [0,4]."); ErrorsFound = true; } @@ -834,8 +821,9 @@ void GetZoneAirSetPoints(EnergyPlusData &state) for (TempControlledZoneNum = 1; TempControlledZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TempControlledZoneNum) { - ActualZoneNum = TempControlledZone(TempControlledZoneNum).ActualZoneNum; - CTIndex = TempControlledZone(TempControlledZoneNum).CTSchedIndex; + auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone(TempControlledZoneNum); + ActualZoneNum = TempControlledZone.ActualZoneNum; + CTIndex = TempControlledZone.CTSchedIndex; if (CTIndex == 0) continue; // error caught elsewhere -- would just be confusing here for (ControlTypeNum = 1; ControlTypeNum <= 4; ++ControlTypeNum) { @@ -845,51 +833,43 @@ void GetZoneAirSetPoints(EnergyPlusData &state) switch (static_cast(ControlTypeNum)) { case HVAC::ThermostatType::SingleHeating: if (!TStatControlTypes(TempControlledZoneNum).MustHave[ControlTypeNum]) continue; - ShowWarningError(state, format("Schedule={}", TempControlledZone(TempControlledZoneNum).ControlTypeSchedName)); + ShowWarningError(state, format("Schedule={}", TempControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("...should include control type 1 ({}) but does not.", ValidControlTypes[static_cast(HVAC::ThermostatType::SingleHeating)])); ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TStat)), - TempControlledZone(TempControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", TempControlledZone(TempControlledZoneNum).ZoneName)); + format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TStat)), TempControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", TempControlledZone.ZoneName)); break; case HVAC::ThermostatType::SingleCooling: if (!TStatControlTypes(TempControlledZoneNum).MustHave[ControlTypeNum]) continue; - ShowWarningError(state, format("Schedule={}", TempControlledZone(TempControlledZoneNum).ControlTypeSchedName)); + ShowWarningError(state, format("Schedule={}", TempControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("...should include control type 2 ({}) but does not.", ValidControlTypes[static_cast(HVAC::ThermostatType::SingleCooling)])); ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TStat)), - TempControlledZone(TempControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", TempControlledZone(TempControlledZoneNum).ZoneName)); + format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TStat)), TempControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", TempControlledZone.ZoneName)); break; case HVAC::ThermostatType::SingleHeatCool: if (!TStatControlTypes(TempControlledZoneNum).MustHave[ControlTypeNum]) continue; - ShowWarningError(state, format("Schedule={}", TempControlledZone(TempControlledZoneNum).ControlTypeSchedName)); + ShowWarningError(state, format("Schedule={}", TempControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("...should include control type 3 ({}) but does not.", ValidControlTypes[static_cast(HVAC::ThermostatType::SingleHeating)])); ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TStat)), - TempControlledZone(TempControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", TempControlledZone(TempControlledZoneNum).ZoneName)); + format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TStat)), TempControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", TempControlledZone.ZoneName)); break; case HVAC::ThermostatType::DualSetPointWithDeadBand: if (!TStatControlTypes(TempControlledZoneNum).MustHave[ControlTypeNum]) continue; - ShowWarningError(state, format("Schedule={}", TempControlledZone(TempControlledZoneNum).ControlTypeSchedName)); + ShowWarningError(state, format("Schedule={}", TempControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("...should include control type 4 ({}) but does not.", ValidControlTypes[static_cast(HVAC::ThermostatType::DualSetPointWithDeadBand)])); ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TStat)), - TempControlledZone(TempControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", TempControlledZone(TempControlledZoneNum).ZoneName)); + format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TStat)), TempControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", TempControlledZone.ZoneName)); break; default: break; @@ -903,12 +883,13 @@ void GetZoneAirSetPoints(EnergyPlusData &state) state.dataZoneCtrls->NumHumidityControlZones = inputProcessor->getNumObjectsFound(state, cCurrentModuleObject); if (state.dataZoneCtrls->NumHumidityControlZones > 0) { - HumidityControlZone.allocate(state.dataZoneCtrls->NumHumidityControlZones); + state.dataZoneCtrls->HumidityControlZone.allocate(state.dataZoneCtrls->NumHumidityControlZones); state.dataZoneTempPredictorCorrector->HumidityControlZoneUniqueNames.reserve( static_cast(state.dataZoneCtrls->NumHumidityControlZones)); } for (HumidControlledZoneNum = 1; HumidControlledZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HumidControlledZoneNum) { + auto &HumidityControlZone = state.dataZoneCtrls->HumidityControlZone(HumidControlledZoneNum); inputProcessor->getObjectItem(state, cCurrentModuleObject, HumidControlledZoneNum, @@ -923,7 +904,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cNumericFieldNames); Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound); - HumidityControlZone(HumidControlledZoneNum).ControlName = cAlphaArgs(1); + HumidityControlZone.ControlName = cAlphaArgs(1); GlobalNames::IntraObjUniquenessCheck(state, cAlphaArgs(2), cCurrentModuleObject, @@ -931,33 +912,33 @@ void GetZoneAirSetPoints(EnergyPlusData &state) state.dataZoneTempPredictorCorrector->HumidityControlZoneUniqueNames, ErrorsFound); - HumidityControlZone(HumidControlledZoneNum).ZoneName = cAlphaArgs(2); - HumidityControlZone(HumidControlledZoneNum).ActualZoneNum = Util::FindItem(cAlphaArgs(2), Zone); - if (HumidityControlZone(HumidControlledZoneNum).ActualZoneNum == 0) { + HumidityControlZone.ZoneName = cAlphaArgs(2); + HumidityControlZone.ActualZoneNum = Util::FindItem(cAlphaArgs(2), state.dataHeatBal->Zone); + if (HumidityControlZone.ActualZoneNum == 0) { ShowSevereError(state, format("{}=\"{} invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2))); ErrorsFound = true; } else { - state.dataHeatBal->Zone(HumidityControlZone(HumidControlledZoneNum).ActualZoneNum).humidityControlZoneIndex = HumidControlledZoneNum; + state.dataHeatBal->Zone(HumidityControlZone.ActualZoneNum).humidityControlZoneIndex = HumidControlledZoneNum; } - HumidityControlZone(HumidControlledZoneNum).HumidifyingSched = cAlphaArgs(3); - HumidityControlZone(HumidControlledZoneNum).HumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(3)); - if (HumidityControlZone(HumidControlledZoneNum).HumidifyingSchedIndex == 0) { + HumidityControlZone.HumidifyingSched = cAlphaArgs(3); + HumidityControlZone.HumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(3)); + if (HumidityControlZone.HumidifyingSchedIndex == 0) { ShowSevereError(state, format("{}=\"{} invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(3), cAlphaArgs(3))); ErrorsFound = true; } if (NumAlphas == 4) { - HumidityControlZone(HumidControlledZoneNum).DehumidifyingSched = cAlphaArgs(4); - HumidityControlZone(HumidControlledZoneNum).DehumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(4)); - if (HumidityControlZone(HumidControlledZoneNum).DehumidifyingSchedIndex == 0) { + HumidityControlZone.DehumidifyingSched = cAlphaArgs(4); + HumidityControlZone.DehumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(4)); + if (HumidityControlZone.DehumidifyingSchedIndex == 0) { ShowSevereError( state, format("{}=\"{} invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(4), cAlphaArgs(4))); ErrorsFound = true; } } else { - HumidityControlZone(HumidControlledZoneNum).DehumidifyingSched = cAlphaArgs(3); - HumidityControlZone(HumidControlledZoneNum).DehumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(3)); + HumidityControlZone.DehumidifyingSched = cAlphaArgs(3); + HumidityControlZone.DehumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(3)); } } // HumidControlledZoneNum @@ -965,7 +946,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) // Start to read Thermal comfort control objects cCurrentModuleObject = cZControlTypes(static_cast(ZoneControlTypes::TCTStat)); state.dataZoneCtrls->NumComfortTStatStatements = inputProcessor->getNumObjectsFound(state, cCurrentModuleObject); - ComfortTStatObjects.allocate(state.dataZoneCtrls->NumComfortTStatStatements); + state.dataZoneCtrls->ComfortTStatObjects.allocate(state.dataZoneCtrls->NumComfortTStatStatements); // Pre-scan for use of Zone lists in TStat statements (i.e. Global application of TStat) state.dataZoneCtrls->NumComfortControlledZones = 0; @@ -985,22 +966,24 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cNumericFieldNames); Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound); - Item1 = Util::FindItemInList(cAlphaArgs(2), Zone); + Item1 = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->Zone); ZLItem = 0; - if (Item1 == 0 && state.dataHeatBal->NumOfZoneLists > 0) ZLItem = Util::FindItemInList(cAlphaArgs(2), ZoneList); - ComfortTStatObjects(Item).Name = cAlphaArgs(1); + if (Item1 == 0 && state.dataHeatBal->NumOfZoneLists > 0) ZLItem = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->ZoneList); + auto &ComfortTStatObjects = state.dataZoneCtrls->ComfortTStatObjects(Item); + ComfortTStatObjects.Name = cAlphaArgs(1); if (Item1 > 0) { - ComfortTStatObjects(Item).ComfortControlledZoneStartPtr = state.dataZoneCtrls->NumComfortControlledZones + 1; + ComfortTStatObjects.ComfortControlledZoneStartPtr = state.dataZoneCtrls->NumComfortControlledZones + 1; ++state.dataZoneCtrls->NumComfortControlledZones; - ComfortTStatObjects(Item).NumOfZones = 1; - ComfortTStatObjects(Item).ZoneListActive = false; - ComfortTStatObjects(Item).ZoneOrZoneListPtr = Item1; + ComfortTStatObjects.NumOfZones = 1; + ComfortTStatObjects.ZoneListActive = false; + ComfortTStatObjects.ZoneOrZoneListPtr = Item1; } else if (ZLItem > 0) { - ComfortTStatObjects(Item).ComfortControlledZoneStartPtr = state.dataZoneCtrls->NumComfortControlledZones + 1; - state.dataZoneCtrls->NumComfortControlledZones += ZoneList(ZLItem).NumOfZones; - ComfortTStatObjects(Item).NumOfZones = ZoneList(ZLItem).NumOfZones; - ComfortTStatObjects(Item).ZoneListActive = true; - ComfortTStatObjects(Item).ZoneOrZoneListPtr = ZLItem; + auto const &ZoneList = state.dataHeatBal->ZoneList(ZLItem); + ComfortTStatObjects.ComfortControlledZoneStartPtr = state.dataZoneCtrls->NumComfortControlledZones + 1; + state.dataZoneCtrls->NumComfortControlledZones += ZoneList.NumOfZones; + ComfortTStatObjects.NumOfZones = ZoneList.NumOfZones; + ComfortTStatObjects.ZoneListActive = true; + ComfortTStatObjects.ZoneOrZoneListPtr = ZLItem; } else { ShowSevereError( state, format("{}=\"{}\" invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2))); @@ -1016,12 +999,13 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } if (state.dataZoneCtrls->NumComfortControlledZones > 0) { - ComfortControlledZone.allocate(state.dataZoneCtrls->NumComfortControlledZones); + state.dataZoneCtrls->ComfortControlledZone.allocate(state.dataZoneCtrls->NumComfortControlledZones); TComfortControlTypes.allocate(state.dataZoneCtrls->NumComfortControlledZones); // Number of set point types CCmSchedMapToControlledZone.dimension(state.dataZoneCtrls->NumComfortControlledZones, 0); ComfortControlledZoneNum = 0; for (Item = 1; Item <= state.dataZoneCtrls->NumComfortTStatStatements; ++Item) { + auto &ComfortTStatObjects = state.dataZoneCtrls->ComfortTStatObjects(Item); inputProcessor->getObjectItem(state, cCurrentModuleObject, Item, @@ -1034,17 +1018,21 @@ void GetZoneAirSetPoints(EnergyPlusData &state) lAlphaFieldBlanks, cAlphaFieldNames, cNumericFieldNames); - for (Item1 = 1; Item1 <= ComfortTStatObjects(Item).NumOfZones; ++Item1) { + for (Item1 = 1; Item1 <= ComfortTStatObjects.NumOfZones; ++Item1) { ++ComfortControlledZoneNum; - if (ComfortTStatObjects(Item).ZoneListActive) { - cAlphaArgs(2) = state.dataHeatBal->Zone(ZoneList(ComfortTStatObjects(Item).ZoneOrZoneListPtr).Zone(Item1)).Name; - } - int ZoneAssigned = Util::FindItemInList( - cAlphaArgs(2), ComfortControlledZone, &DataZoneControls::ZoneComfortControls::ZoneName, ComfortControlledZoneNum - 1); + auto &ComfortControlledZone = state.dataZoneCtrls->ComfortControlledZone(ComfortControlledZoneNum); + if (ComfortTStatObjects.ZoneListActive) { + auto &ZoneList = state.dataHeatBal->ZoneList(ComfortTStatObjects.ZoneOrZoneListPtr); + cAlphaArgs(2) = state.dataHeatBal->Zone(ZoneList.Zone(Item1)).Name; + } + int ZoneAssigned = Util::FindItemInList(cAlphaArgs(2), + state.dataZoneCtrls->ComfortControlledZone, + &DataZoneControls::ZoneComfortControls::ZoneName, + ComfortControlledZoneNum - 1); if (ZoneAssigned == 0) { - ComfortControlledZone(ComfortControlledZoneNum).ZoneName = cAlphaArgs(2); - ComfortControlledZone(ComfortControlledZoneNum).ActualZoneNum = Util::FindItemInList(cAlphaArgs(2), Zone); - if (ComfortControlledZone(ComfortControlledZoneNum).ActualZoneNum == 0) { + ComfortControlledZone.ZoneName = cAlphaArgs(2); + ComfortControlledZone.ActualZoneNum = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->Zone); + if (ComfortControlledZone.ActualZoneNum == 0) { ShowSevereError( state, format( @@ -1052,7 +1040,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } } else { - ComfortControlledZone(ComfortControlledZoneNum).ZoneName = cAlphaArgs(2); // for continuity + ComfortControlledZone.ZoneName = cAlphaArgs(2); // for continuity ShowSevereError(state, format("{}=\"{}\" invalid {}=\"{}\" zone previously assigned.", cCurrentModuleObject, @@ -1060,28 +1048,28 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaFieldNames(2), cAlphaArgs(2))); ShowContinueError(state, - format("...Zone was previously assigned to Thermostat=\"{}\".", ComfortControlledZone(ZoneAssigned).Name)); + format("...Zone was previously assigned to Thermostat=\"{}\".", + state.dataZoneCtrls->ComfortControlledZone(ZoneAssigned).Name)); ErrorsFound = true; continue; } - if (!ComfortTStatObjects(Item).ZoneListActive) { - ComfortControlledZone(ComfortControlledZoneNum).Name = cAlphaArgs(1); + if (!ComfortTStatObjects.ZoneListActive) { + ComfortControlledZone.Name = cAlphaArgs(1); } else { - ComfortControlledZone(ComfortControlledZoneNum).Name = - state.dataHeatBal->Zone(ZoneList(ComfortTStatObjects(Item).ZoneOrZoneListPtr).Zone(Item1)).Name + ' ' + - ComfortTStatObjects(Item).Name; + auto &ZoneList = state.dataHeatBal->ZoneList(ComfortTStatObjects.ZoneOrZoneListPtr); + ComfortControlledZone.Name = state.dataHeatBal->Zone(ZoneList.Zone(Item1)).Name + ' ' + ComfortTStatObjects.Name; } // Read Fields A3 and A4 for averaging method - IZoneCount = 0; + int IZoneCount = 0; for (i = 1; i <= state.dataHeatBal->TotPeople; ++i) { - if (ComfortControlledZone(ComfortControlledZoneNum).ActualZoneNum == state.dataHeatBal->People(i).ZonePtr) { + if (ComfortControlledZone.ActualZoneNum == state.dataHeatBal->People(i).ZonePtr) { ++IZoneCount; } } // Could not find a people object for this particular zone - if (IZoneCount == 0 && ComfortControlledZone(ComfortControlledZoneNum).ActualZoneNum > 0) { + if (IZoneCount == 0 && ComfortControlledZone.ActualZoneNum > 0) { ShowSevereError(state, format("{}=\"{} no PEOPLE in {}=\"{}\" - cannot use Comfort Control.", cCurrentModuleObject, @@ -1090,44 +1078,43 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaArgs(2))); ErrorsFound = true; } - ComfortControlledZone(ComfortControlledZoneNum).AverageMethod = DataZoneControls::AverageMethod::NO; + ComfortControlledZone.AverageMethod = DataZoneControls::AverageMethod::NO; if (IZoneCount > 1) { - ComfortControlledZone(ComfortControlledZoneNum).AverageMethodName = cAlphaArgs(3); + ComfortControlledZone.AverageMethodName = cAlphaArgs(3); if (Util::SameString(cAlphaArgs(3), "SpecificObject")) { - ComfortControlledZone(ComfortControlledZoneNum).AverageMethod = DataZoneControls::AverageMethod::SPE; + ComfortControlledZone.AverageMethod = DataZoneControls::AverageMethod::SPE; } if (Util::SameString(cAlphaArgs(3), "ObjectAverage")) { - ComfortControlledZone(ComfortControlledZoneNum).AverageMethod = DataZoneControls::AverageMethod::OBJ; + ComfortControlledZone.AverageMethod = DataZoneControls::AverageMethod::OBJ; } if (Util::SameString(cAlphaArgs(3), "PeopleAverage")) { - ComfortControlledZone(ComfortControlledZoneNum).AverageMethod = DataZoneControls::AverageMethod::PEO; + ComfortControlledZone.AverageMethod = DataZoneControls::AverageMethod::PEO; } - if (ComfortControlledZone(ComfortControlledZoneNum).AverageMethod == DataZoneControls::AverageMethod::NO) { + if (ComfortControlledZone.AverageMethod == DataZoneControls::AverageMethod::NO) { ShowSevereError( state, format("{}=\"{} invalid {}=\"{}\".", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(3), cAlphaArgs(3))); ShowContinueError(state, "Allowed keys are SpecificObject, ObjectAverage, or PeopleAverage"); ErrorsFound = true; } - if (ComfortControlledZone(ComfortControlledZoneNum).AverageMethod == DataZoneControls::AverageMethod::SPE) { - ComfortControlledZone(ComfortControlledZoneNum).AverageObjectName = cAlphaArgs(4); + if (ComfortControlledZone.AverageMethod == DataZoneControls::AverageMethod::SPE) { + ComfortControlledZone.AverageObjectName = cAlphaArgs(4); if (Util::FindItem(cAlphaArgs(4), state.dataHeatBal->People) == 0) { ShowSevereError( state, format("{}=\"{} invalid {}=\"{}\".", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(4), cAlphaArgs(4))); ErrorsFound = true; } else { - ComfortControlledZone(ComfortControlledZoneNum).SpecificObjectNum = - Util::FindItem(cAlphaArgs(4), state.dataHeatBal->People); + ComfortControlledZone.SpecificObjectNum = Util::FindItem(cAlphaArgs(4), state.dataHeatBal->People); } } } else { for (i = 1; i <= state.dataHeatBal->TotPeople; ++i) { - if (ComfortControlledZone(ComfortControlledZoneNum).ActualZoneNum == state.dataHeatBal->People(i).ZonePtr) break; + if (ComfortControlledZone.ActualZoneNum == state.dataHeatBal->People(i).ZonePtr) break; } - ComfortControlledZone(ComfortControlledZoneNum).SpecificObjectNum = i; + ComfortControlledZone.SpecificObjectNum = i; } // Check values used for thermal comfort calculation for (i = 1; i <= state.dataHeatBal->TotPeople; ++i) { - if (ComfortControlledZone(ComfortControlledZoneNum).ActualZoneNum == state.dataHeatBal->People(i).ZonePtr) { + if (ComfortControlledZone.ActualZoneNum == state.dataHeatBal->People(i).ZonePtr) { // Check activity level if (state.dataHeatBal->People(i).ActivityLevelPtr > 0) { ValidScheduleControlType = @@ -1193,7 +1180,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) // Read Max and Min temperature setpoint if (NumNums > 0) { - ComfortControlledZone(ComfortControlledZoneNum).TdbMinSetPoint = rNumericArgs(1); + ComfortControlledZone.TdbMinSetPoint = rNumericArgs(1); if (rNumericArgs(1) > 50 || rNumericArgs(1) < 0) { ShowSevereError( state, @@ -1203,7 +1190,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } } if (NumNums > 1) { - ComfortControlledZone(ComfortControlledZoneNum).TdbMaxSetPoint = rNumericArgs(2); + ComfortControlledZone.TdbMaxSetPoint = rNumericArgs(2); if (rNumericArgs(2) > 50 || rNumericArgs(2) < 0) { ShowSevereError( state, @@ -1213,31 +1200,29 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } } // Ensure MaxTemp >= MinTemp - if (ComfortControlledZone(ComfortControlledZoneNum).TdbMinSetPoint > ComfortControlledZone(ComfortControlledZoneNum).TdbMaxSetPoint) { + if (ComfortControlledZone.TdbMinSetPoint > ComfortControlledZone.TdbMaxSetPoint) { ShowSevereError(state, format("{}=\"{}", cCurrentModuleObject, cAlphaArgs(1))); ShowContinueError(state, format("..{} > {}", cNumericFieldNames(1), cNumericFieldNames(2))); ShowContinueError(state, format("..[{:.0T}] > [{:.0T}].", rNumericArgs(1), rNumericArgs(2))); ErrorsFound = true; } // If MaxTemp = MinTemp, no thermal comfort control - if (ComfortControlledZone(ComfortControlledZoneNum).TdbMinSetPoint == - ComfortControlledZone(ComfortControlledZoneNum).TdbMaxSetPoint) { + if (ComfortControlledZone.TdbMinSetPoint == ComfortControlledZone.TdbMaxSetPoint) { ShowSevereError(state, format("{}=\"{}", cCurrentModuleObject, cAlphaArgs(1))); ShowContinueError(state, format("..{} = {}", cNumericFieldNames(1), cNumericFieldNames(2))); ShowContinueError(state, "The zone will be controlled using this dry-bulb temperature setpoint."); } // read Thermal comfort type schedule name - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName = cAlphaArgs(5); - ComfortControlledZone(ComfortControlledZoneNum).ComfortSchedIndex = GetScheduleIndex(state, cAlphaArgs(5)); - if (ComfortControlledZone(ComfortControlledZoneNum).ComfortSchedIndex == 0) { + ComfortControlledZone.ControlTypeSchedName = cAlphaArgs(5); + ComfortControlledZone.ComfortSchedIndex = GetScheduleIndex(state, cAlphaArgs(5)); + if (ComfortControlledZone.ComfortSchedIndex == 0) { ShowSevereError( state, format("{}=\"{} invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(5), cAlphaArgs(5))); ErrorsFound = true; } else { // Check validity of control types. - ValidScheduleControlType = - CheckScheduleValueMinMax(state, ComfortControlledZone(ComfortControlledZoneNum).ComfortSchedIndex, ">=", 0.0, "<=", 4.0); + ValidScheduleControlType = CheckScheduleValueMinMax(state, ComfortControlledZone.ComfortSchedIndex, ">=", 0.0, "<=", 4.0); if (!ValidScheduleControlType) { ShowSevereError( state, @@ -1246,19 +1231,16 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } } - ComfortControlledZone(ComfortControlledZoneNum).NumControlTypes = nint((NumAlphas - 5.0) / 2.0); - ComfortControlledZone(ComfortControlledZoneNum).ControlType.allocate(ComfortControlledZone(ComfortControlledZoneNum).NumControlTypes); - ComfortControlledZone(ComfortControlledZoneNum) - .ControlTypeName.allocate(ComfortControlledZone(ComfortControlledZoneNum).NumControlTypes); - ComfortControlledZone(ComfortControlledZoneNum) - .ControlTypeSchIndx.allocate(ComfortControlledZone(ComfortControlledZoneNum).NumControlTypes); - - for (ControlTypeNum = 1; ControlTypeNum <= ComfortControlledZone(ComfortControlledZoneNum).NumControlTypes; ++ControlTypeNum) { - ComfortControlledZone(ComfortControlledZoneNum).ControlType(ControlTypeNum) = cAlphaArgs(nint(2.0 * ControlTypeNum - 1 + 5)); - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeName(ControlTypeNum) = cAlphaArgs(nint(2.0 * ControlTypeNum + 5)); - if (ComfortControlledZone(ComfortControlledZoneNum).ControlType(ControlTypeNum) != "") { - CTIndex = getEnumValue(ValidComfortControlTypesUC, - Util::makeUPPER(ComfortControlledZone(ComfortControlledZoneNum).ControlType(ControlTypeNum))); + ComfortControlledZone.NumControlTypes = nint((NumAlphas - 5.0) / 2.0); + ComfortControlledZone.ControlType.allocate(ComfortControlledZone.NumControlTypes); + ComfortControlledZone.ControlTypeName.allocate(ComfortControlledZone.NumControlTypes); + ComfortControlledZone.ControlTypeSchIndx.allocate(ComfortControlledZone.NumControlTypes); + + for (ControlTypeNum = 1; ControlTypeNum <= ComfortControlledZone.NumControlTypes; ++ControlTypeNum) { + ComfortControlledZone.ControlType(ControlTypeNum) = cAlphaArgs(nint(2.0 * ControlTypeNum - 1 + 5)); + ComfortControlledZone.ControlTypeName(ControlTypeNum) = cAlphaArgs(nint(2.0 * ControlTypeNum + 5)); + if (ComfortControlledZone.ControlType(ControlTypeNum) != "") { + CTIndex = getEnumValue(ValidComfortControlTypesUC, Util::makeUPPER(ComfortControlledZone.ControlType(ControlTypeNum))); if (CTIndex == 0) { ShowSevereError(state, format("{}=\"{}\" invalid {}=\"{}\"", @@ -1286,7 +1268,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaFieldNames(nint(2.0 * ControlTypeNum - 1 + 5)))); ErrorsFound = true; } - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchIndx(ControlTypeNum) = 0; + ComfortControlledZone.ControlTypeSchIndx(ControlTypeNum) = 0; } } } // NumComfortTStatStatements @@ -1483,48 +1465,45 @@ void GetZoneAirSetPoints(EnergyPlusData &state) // Finish filling in Schedule pointing indexes for Thermal Comfort Control for (ComfortControlledZoneNum = 1; ComfortControlledZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++ComfortControlledZoneNum) { + auto &ComfortControlledZone = state.dataZoneCtrls->ComfortControlledZone(ComfortControlledZoneNum); int ComfortIndex = Util::FindItem(ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleHeating)], - ComfortControlledZone(ComfortControlledZoneNum).ControlType, - ComfortControlledZone(ComfortControlledZoneNum).NumControlTypes); - ComfortControlledZone(ComfortControlledZoneNum).SchIndx_SingleHeating = ComfortIndex; + ComfortControlledZone.ControlType, + ComfortControlledZone.NumControlTypes); + ComfortControlledZone.SchIndx_SingleHeating = ComfortIndex; if (ComfortIndex > 0) { - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchIndx(ComfortIndex) = - Util::FindItem(ComfortControlledZone(ComfortControlledZoneNum).ControlTypeName(ComfortIndex), - state.dataZoneTempPredictorCorrector->SetPointSingleHeatingFanger); + ComfortControlledZone.ControlTypeSchIndx(ComfortIndex) = Util::FindItem( + ComfortControlledZone.ControlTypeName(ComfortIndex), state.dataZoneTempPredictorCorrector->SetPointSingleHeatingFanger); TComfortControlTypes(ComfortControlledZoneNum).MustHave[static_cast(HVAC::ThermostatType::SingleHeating)] = true; } ComfortIndex = Util::FindItem(ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleCooling)], - ComfortControlledZone(ComfortControlledZoneNum).ControlType, - ComfortControlledZone(ComfortControlledZoneNum).NumControlTypes); - ComfortControlledZone(ComfortControlledZoneNum).SchIndx_SingleCooling = ComfortIndex; + ComfortControlledZone.ControlType, + ComfortControlledZone.NumControlTypes); + ComfortControlledZone.SchIndx_SingleCooling = ComfortIndex; if (ComfortIndex > 0) { - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchIndx(ComfortIndex) = - Util::FindItem(ComfortControlledZone(ComfortControlledZoneNum).ControlTypeName(ComfortIndex), - state.dataZoneTempPredictorCorrector->SetPointSingleCoolingFanger); + ComfortControlledZone.ControlTypeSchIndx(ComfortIndex) = Util::FindItem( + ComfortControlledZone.ControlTypeName(ComfortIndex), state.dataZoneTempPredictorCorrector->SetPointSingleCoolingFanger); TComfortControlTypes(ComfortControlledZoneNum).MustHave[static_cast(HVAC::ThermostatType::SingleCooling)] = true; } ComfortIndex = Util::FindItem(ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleHeatCool)], - ComfortControlledZone(ComfortControlledZoneNum).ControlType, - ComfortControlledZone(ComfortControlledZoneNum).NumControlTypes); - ComfortControlledZone(ComfortControlledZoneNum).SchIndx_SingleHeatCool = ComfortIndex; + ComfortControlledZone.ControlType, + ComfortControlledZone.NumControlTypes); + ComfortControlledZone.SchIndx_SingleHeatCool = ComfortIndex; if (ComfortIndex > 0) { - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchIndx(ComfortIndex) = - Util::FindItem(ComfortControlledZone(ComfortControlledZoneNum).ControlTypeName(ComfortIndex), - state.dataZoneTempPredictorCorrector->SetPointSingleHeatCoolFanger); + ComfortControlledZone.ControlTypeSchIndx(ComfortIndex) = Util::FindItem( + ComfortControlledZone.ControlTypeName(ComfortIndex), state.dataZoneTempPredictorCorrector->SetPointSingleHeatCoolFanger); TComfortControlTypes(ComfortControlledZoneNum).MustHave[static_cast(HVAC::ThermostatType::SingleHeatCool)] = true; } ComfortIndex = Util::FindItem(ValidComfortControlTypes[static_cast(HVAC::ThermostatType::DualSetPointWithDeadBand)], - ComfortControlledZone(ComfortControlledZoneNum).ControlType, - ComfortControlledZone(ComfortControlledZoneNum).NumControlTypes); - ComfortControlledZone(ComfortControlledZoneNum).SchIndx_DualSetPointWithDeadBand = ComfortIndex; + ComfortControlledZone.ControlType, + ComfortControlledZone.NumControlTypes); + ComfortControlledZone.SchIndx_DualSetPointWithDeadBand = ComfortIndex; if (ComfortIndex > 0) { - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchIndx(ComfortIndex) = - Util::FindItem(ComfortControlledZone(ComfortControlledZoneNum).ControlTypeName(ComfortIndex), - state.dataZoneTempPredictorCorrector->SetPointDualHeatCoolFanger); + ComfortControlledZone.ControlTypeSchIndx(ComfortIndex) = + Util::FindItem(ComfortControlledZone.ControlTypeName(ComfortIndex), state.dataZoneTempPredictorCorrector->SetPointDualHeatCoolFanger); TComfortControlTypes(ComfortControlledZoneNum).MustHave[static_cast(HVAC::ThermostatType::DualSetPointWithDeadBand)] = true; } } @@ -1532,16 +1511,17 @@ void GetZoneAirSetPoints(EnergyPlusData &state) // Now, Check the schedule values/indices for validity for Thermal Comfort Control for (ComfortControlledZoneNum = 1; ComfortControlledZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++ComfortControlledZoneNum) { + auto &ComfortControlledZone = state.dataZoneCtrls->ComfortControlledZone(ComfortControlledZoneNum); - ActualZoneNum = ComfortControlledZone(ComfortControlledZoneNum).ActualZoneNum; - CTIndex = ComfortControlledZone(ComfortControlledZoneNum).ComfortSchedIndex; + ActualZoneNum = ComfortControlledZone.ActualZoneNum; + CTIndex = ComfortControlledZone.ComfortSchedIndex; if (CTIndex == 0) continue; // error will be caught elsewhere SchedMin = GetScheduleMinValue(state, CTIndex); SchedMax = GetScheduleMaxValue(state, CTIndex); if (SchedMin == 0 && SchedMax == 0) { if (FindNumberInList(CTIndex, CCmSchedMapToControlledZone, state.dataZoneCtrls->NumComfortControlledZones) == 0) { - ShowWarningError(state, format("Control Type Schedule={}", ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName)); + ShowWarningError(state, format("Control Type Schedule={}", ComfortControlledZone.ControlTypeSchedName)); ShowContinueError(state, "..specifies control type 0 for all entries."); ShowContinueError(state, "All zones using this Control Type Schedule have no thermal comfort control."); } @@ -1555,111 +1535,105 @@ void GetZoneAirSetPoints(EnergyPlusData &state) case HVAC::ThermostatType::Uncontrolled: break; case HVAC::ThermostatType::SingleHeating: - ComfortIndex = ComfortControlledZone(ComfortControlledZoneNum).SchIndx_SingleHeating; + ComfortIndex = ComfortControlledZone.SchIndx_SingleHeating; TComfortControlTypes(ComfortControlledZoneNum).DidHave[static_cast(HVAC::ThermostatType::SingleHeating)] = true; if (ComfortIndex != 0) { - SchedTypeIndex = ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchIndx(ComfortIndex); + SchedTypeIndex = ComfortControlledZone.ControlTypeSchIndx(ComfortIndex); if (SchedTypeIndex == 0) { ShowSevereError(state, format("GetZoneAirSetpoints: Could not find {} Schedule={}", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleHeating)], - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeName(ComfortIndex))); + ComfortControlledZone.ControlTypeName(ComfortIndex))); ErrorsFound = true; } } else { // ComfortIndex = 0 if (CheckScheduleValue(state, CTIndex, static_cast(HVAC::ThermostatType::SingleHeating))) { - ShowSevereError(state, - format("Control Type Schedule={}", ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName)); + ShowSevereError(state, format("Control Type Schedule={}", ComfortControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("..specifies thermal control type 1 ({}) as the control type. Not valid for this zone.", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleHeating)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), - ComfortControlledZone(ComfortControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone(ComfortControlledZoneNum).ZoneName)); + ShowContinueError( + state, + format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), ComfortControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone.ZoneName)); ErrorsFound = true; } } break; case HVAC::ThermostatType::SingleCooling: - ComfortIndex = ComfortControlledZone(ComfortControlledZoneNum).SchIndx_SingleCooling; + ComfortIndex = ComfortControlledZone.SchIndx_SingleCooling; TComfortControlTypes(ComfortControlledZoneNum).DidHave[static_cast(HVAC::ThermostatType::SingleCooling)] = true; if (ComfortIndex != 0) { - SchedTypeIndex = ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchIndx(ComfortIndex); + SchedTypeIndex = ComfortControlledZone.ControlTypeSchIndx(ComfortIndex); if (SchedTypeIndex == 0) { ShowSevereError(state, format("GetZoneAirSetpoints: Could not find {} Schedule={}", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleCooling)], - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeName(ComfortIndex))); + ComfortControlledZone.ControlTypeName(ComfortIndex))); ErrorsFound = true; } } else { // ComfortIndex = 0 if (CheckScheduleValue(state, CTIndex, static_cast(HVAC::ThermostatType::SingleCooling))) { - ShowSevereError(state, - format("Control Type Schedule={}", ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName)); + ShowSevereError(state, format("Control Type Schedule={}", ComfortControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("..specifies thermal control type 2 ({}) as the control type. Not valid for this zone.", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleCooling)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), - ComfortControlledZone(ComfortControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone(ComfortControlledZoneNum).ZoneName)); + ShowContinueError( + state, + format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), ComfortControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone.ZoneName)); ErrorsFound = true; } } break; case HVAC::ThermostatType::SingleHeatCool: - ComfortIndex = ComfortControlledZone(ComfortControlledZoneNum).SchIndx_SingleHeatCool; + ComfortIndex = ComfortControlledZone.SchIndx_SingleHeatCool; TComfortControlTypes(ComfortControlledZoneNum).DidHave[static_cast(HVAC::ThermostatType::SingleHeatCool)] = true; if (ComfortIndex != 0) { - SchedTypeIndex = ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchIndx(ComfortIndex); + SchedTypeIndex = ComfortControlledZone.ControlTypeSchIndx(ComfortIndex); if (SchedTypeIndex == 0) { ShowSevereError(state, format("GetZoneAirSetpoints: Could not find {} Schedule={}", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleHeatCool)], - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeName(ComfortIndex))); + ComfortControlledZone.ControlTypeName(ComfortIndex))); ErrorsFound = true; } } else { // ComfortIndex = 0 if (CheckScheduleValue(state, CTIndex, static_cast(HVAC::ThermostatType::SingleHeatCool))) { - ShowSevereError(state, format("Schedule={}", ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName)); + ShowSevereError(state, format("Schedule={}", ComfortControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("..specifies thermal control type 3 ({}) as the control type. Not valid for this zone.", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleHeatCool)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), - ComfortControlledZone(ComfortControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone(ComfortControlledZoneNum).ZoneName)); + ShowContinueError( + state, + format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), ComfortControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone.ZoneName)); ErrorsFound = true; } } break; case HVAC::ThermostatType::DualSetPointWithDeadBand: - ComfortIndex = ComfortControlledZone(ComfortControlledZoneNum).SchIndx_DualSetPointWithDeadBand; + ComfortIndex = ComfortControlledZone.SchIndx_DualSetPointWithDeadBand; TComfortControlTypes(ComfortControlledZoneNum).DidHave[static_cast(HVAC::ThermostatType::DualSetPointWithDeadBand)] = true; if (ComfortIndex != 0) { - SchedTypeIndex = ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchIndx(ComfortIndex); + SchedTypeIndex = ComfortControlledZone.ControlTypeSchIndx(ComfortIndex); if (SchedTypeIndex == 0) { ShowSevereError(state, format("GetZoneAirSetpoints: Could not find {} Schedule={}", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::DualSetPointWithDeadBand)], - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeName(ComfortIndex))); + ComfortControlledZone.ControlTypeName(ComfortIndex))); ErrorsFound = true; } } else { // ComfortIndex = 0 if (CheckScheduleValue(state, CTIndex, static_cast(HVAC::ThermostatType::DualSetPointWithDeadBand))) { - ShowSevereError(state, format("Schedule={}", ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName)); + ShowSevereError(state, format("Schedule={}", ComfortControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("..specifies thermal control type 4 ({}) as the control type. Not valid for this zone.", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::DualSetPointWithDeadBand)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), - ComfortControlledZone(ComfortControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone(ComfortControlledZoneNum).ZoneName)); + ShowContinueError( + state, + format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), ComfortControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone.ZoneName)); ErrorsFound = true; } } @@ -1667,9 +1641,9 @@ void GetZoneAirSetPoints(EnergyPlusData &state) default: ShowSevereError(state, format("GetZoneAirSetpoints: Illegal control type for Zone={}, Found value={}, in Schedule={}", - Zone(ActualZoneNum).Name, + state.dataHeatBal->Zone(ActualZoneNum).Name, ControlTypeNum, - ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName)); + ComfortControlledZone.ControlTypeSchedName)); ShowContinueError(state, "..valid range values are [0,4]."); ErrorsFound = true; break; @@ -1678,9 +1652,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } for (ComfortControlledZoneNum = 1; ComfortControlledZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++ComfortControlledZoneNum) { + auto &ComfortControlledZone = state.dataZoneCtrls->ComfortControlledZone(ComfortControlledZoneNum); - ActualZoneNum = ComfortControlledZone(ComfortControlledZoneNum).ActualZoneNum; - CTIndex = ComfortControlledZone(ComfortControlledZoneNum).ComfortSchedIndex; + ActualZoneNum = ComfortControlledZone.ActualZoneNum; + CTIndex = ComfortControlledZone.ComfortSchedIndex; if (CTIndex == 0) continue; // error caught elsewhere -- would just be confusing here for (ControlTypeNum = 1; ControlTypeNum <= 4; ++ControlTypeNum) { @@ -1691,51 +1666,43 @@ void GetZoneAirSetPoints(EnergyPlusData &state) switch (static_cast(ControlTypeNum)) { case HVAC::ThermostatType::SingleHeating: if (!TComfortControlTypes(ComfortControlledZoneNum).MustHave[ControlTypeNum]) continue; - ShowWarningError(state, format("Schedule={}", ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName)); + ShowWarningError(state, format("Schedule={}", ComfortControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("...should include control type 1 ({}) but does not.", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleHeating)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), - ComfortControlledZone(ComfortControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone(ComfortControlledZoneNum).ZoneName)); + ShowContinueError( + state, format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), ComfortControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone.ZoneName)); break; case HVAC::ThermostatType::SingleCooling: if (!TComfortControlTypes(ComfortControlledZoneNum).MustHave[ControlTypeNum]) continue; - ShowWarningError(state, format("Schedule={}", ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName)); + ShowWarningError(state, format("Schedule={}", ComfortControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("...should include control type 2 ({}) but does not.", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleCooling)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), - ComfortControlledZone(ComfortControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone(ComfortControlledZoneNum).ZoneName)); + ShowContinueError( + state, format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), ComfortControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone.ZoneName)); break; case HVAC::ThermostatType::SingleHeatCool: if (!TComfortControlTypes(ComfortControlledZoneNum).MustHave[ControlTypeNum]) continue; - ShowWarningError(state, format("Schedule={}", ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName)); + ShowWarningError(state, format("Schedule={}", ComfortControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("...should include control type 3 ({}) but does not.", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::SingleHeatCool)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), - ComfortControlledZone(ComfortControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone(ComfortControlledZoneNum).ZoneName)); + ShowContinueError( + state, format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), ComfortControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone.ZoneName)); break; case HVAC::ThermostatType::DualSetPointWithDeadBand: if (!TComfortControlTypes(ComfortControlledZoneNum).MustHave[ControlTypeNum]) continue; - ShowWarningError(state, format("Schedule={}", ComfortControlledZone(ComfortControlledZoneNum).ControlTypeSchedName)); + ShowWarningError(state, format("Schedule={}", ComfortControlledZone.ControlTypeSchedName)); ShowContinueError(state, format("...should include control type 4 ({}) but does not.", ValidComfortControlTypes[static_cast(HVAC::ThermostatType::DualSetPointWithDeadBand)])); - ShowContinueError(state, - format("..reference {}={}", - cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), - ComfortControlledZone(ComfortControlledZoneNum).Name)); - ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone(ComfortControlledZoneNum).ZoneName)); + ShowContinueError( + state, format("..reference {}={}", cZControlTypes(static_cast(ZoneControlTypes::TCTStat)), ComfortControlledZone.Name)); + ShowContinueError(state, format("..reference ZONE={}", ComfortControlledZone.ZoneName)); break; default: break; @@ -1760,10 +1727,11 @@ void GetZoneAirSetPoints(EnergyPlusData &state) if (NumZoneCapaMultiplier == 0) { // Assign default multiplier values to all zones for (int ZoneNum = 1; ZoneNum <= NumOfZones; ZoneNum++) { - Zone(ZoneNum).ZoneVolCapMultpSens = ZoneVolCapMultpSens; - Zone(ZoneNum).ZoneVolCapMultpMoist = ZoneVolCapMultpMoist; - Zone(ZoneNum).ZoneVolCapMultpCO2 = ZoneVolCapMultpCO2; - Zone(ZoneNum).ZoneVolCapMultpGenContam = ZoneVolCapMultpGenContam; + auto &Zone = state.dataHeatBal->Zone(ZoneNum); + Zone.ZoneVolCapMultpSens = ZoneVolCapMultpSens; + Zone.ZoneVolCapMultpMoist = ZoneVolCapMultpMoist; + Zone.ZoneVolCapMultpCO2 = ZoneVolCapMultpCO2; + Zone.ZoneVolCapMultpGenContam = ZoneVolCapMultpGenContam; } } else { @@ -1793,25 +1761,25 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ZoneVolCapMultpGenContam = rNumericArgs(4); } else { // multiplier values for the specified zone(s) - int ZoneNum = 0; ZLItem = 0; - Item1 = Util::FindItemInList(cAlphaArgs(2), Zone); - if (Item1 == 0 && state.dataHeatBal->NumOfZoneLists > 0) ZLItem = Util::FindItemInList(cAlphaArgs(2), ZoneList); + Item1 = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->Zone); + if (Item1 == 0 && state.dataHeatBal->NumOfZoneLists > 0) ZLItem = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->ZoneList); if (Item1 > 0) { - ZoneNum = Item1; - Zone(ZoneNum).FlagCustomizedZoneCap = true; - Zone(ZoneNum).ZoneVolCapMultpSens = rNumericArgs(1); - Zone(ZoneNum).ZoneVolCapMultpMoist = rNumericArgs(2); - Zone(ZoneNum).ZoneVolCapMultpCO2 = rNumericArgs(3); - Zone(ZoneNum).ZoneVolCapMultpGenContam = rNumericArgs(4); + auto &Zone = state.dataHeatBal->Zone(Item1); + Zone.FlagCustomizedZoneCap = true; + Zone.ZoneVolCapMultpSens = rNumericArgs(1); + Zone.ZoneVolCapMultpMoist = rNumericArgs(2); + Zone.ZoneVolCapMultpCO2 = rNumericArgs(3); + Zone.ZoneVolCapMultpGenContam = rNumericArgs(4); } else if (ZLItem > 0) { - for (int ZonePtrNum = 1; ZonePtrNum < ZoneList(ZLItem).NumOfZones; ZonePtrNum++) { - ZoneNum = ZoneList(ZLItem).Zone(ZonePtrNum); - Zone(ZoneNum).FlagCustomizedZoneCap = true; - Zone(ZoneNum).ZoneVolCapMultpSens = rNumericArgs(1); - Zone(ZoneNum).ZoneVolCapMultpMoist = rNumericArgs(2); - Zone(ZoneNum).ZoneVolCapMultpCO2 = rNumericArgs(3); - Zone(ZoneNum).ZoneVolCapMultpGenContam = rNumericArgs(4); + auto &ZoneList = state.dataHeatBal->ZoneList(ZLItem); + for (int ZonePtrNum = 1; ZonePtrNum < ZoneList.NumOfZones; ZonePtrNum++) { + auto &Zone = state.dataHeatBal->Zone(ZoneList.Zone(ZonePtrNum)); + Zone.FlagCustomizedZoneCap = true; + Zone.ZoneVolCapMultpSens = rNumericArgs(1); + Zone.ZoneVolCapMultpMoist = rNumericArgs(2); + Zone.ZoneVolCapMultpCO2 = rNumericArgs(3); + Zone.ZoneVolCapMultpGenContam = rNumericArgs(4); } } else { @@ -1825,11 +1793,12 @@ void GetZoneAirSetPoints(EnergyPlusData &state) // Assign default multiplier values to all the other zones for (int ZoneNum = 1; ZoneNum <= NumOfZones; ZoneNum++) { - if (!Zone(ZoneNum).FlagCustomizedZoneCap) { - Zone(ZoneNum).ZoneVolCapMultpSens = ZoneVolCapMultpSens; - Zone(ZoneNum).ZoneVolCapMultpMoist = ZoneVolCapMultpMoist; - Zone(ZoneNum).ZoneVolCapMultpCO2 = ZoneVolCapMultpCO2; - Zone(ZoneNum).ZoneVolCapMultpGenContam = ZoneVolCapMultpGenContam; + auto &Zone = state.dataHeatBal->Zone(ZoneNum); + if (!Zone.FlagCustomizedZoneCap) { + Zone.ZoneVolCapMultpSens = ZoneVolCapMultpSens; + Zone.ZoneVolCapMultpMoist = ZoneVolCapMultpMoist; + Zone.ZoneVolCapMultpCO2 = ZoneVolCapMultpCO2; + Zone.ZoneVolCapMultpGenContam = ZoneVolCapMultpGenContam; } } @@ -1841,10 +1810,11 @@ void GetZoneAirSetPoints(EnergyPlusData &state) Real64 ZoneVolCapMultpGenContam_temp = 0.0; for (int ZoneNum = 1; ZoneNum <= NumOfZones; ZoneNum++) { - ZoneVolCapMultpSens_temp += Zone(ZoneNum).ZoneVolCapMultpSens; - ZoneVolCapMultpMoist_temp += Zone(ZoneNum).ZoneVolCapMultpMoist; - ZoneVolCapMultpCO2_temp += Zone(ZoneNum).ZoneVolCapMultpCO2; - ZoneVolCapMultpGenContam_temp += Zone(ZoneNum).ZoneVolCapMultpGenContam; + auto const &Zone = state.dataHeatBal->Zone(ZoneNum); + ZoneVolCapMultpSens_temp += Zone.ZoneVolCapMultpSens; + ZoneVolCapMultpMoist_temp += Zone.ZoneVolCapMultpMoist; + ZoneVolCapMultpCO2_temp += Zone.ZoneVolCapMultpCO2; + ZoneVolCapMultpGenContam_temp += Zone.ZoneVolCapMultpGenContam; } if (NumOfZones > 0) { @@ -1879,10 +1849,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaFieldNames, cNumericFieldNames); // find matching name of ZONECONTROL:THERMOSTAT object - found = Util::FindItem(cAlphaArgs(1), TStatObjects); + found = Util::FindItem(cAlphaArgs(1), state.dataZoneCtrls->TStatObjects); if (found == 0) { // It might be in the TempControlledZones - found = Util::FindItem(cAlphaArgs(1), TempControlledZone); + found = Util::FindItem(cAlphaArgs(1), state.dataZoneCtrls->TempControlledZone); if (found == 0) { // throw error ShowSevereError(state, format("{}={} invalid {} reference not found.", @@ -1891,10 +1861,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cZControlTypes(static_cast(ZoneControlTypes::TStat)))); ErrorsFound = true; } else { - TempControlledZoneNum = found; - TempControlledZone(TempControlledZoneNum).OperativeTempControl = true; + auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone(found); + TempControlledZone.OperativeTempControl = true; if (Util::SameString(cAlphaArgs(2), "Scheduled")) { - TempControlledZone(TempControlledZoneNum).OpTempCntrlModeScheduled = true; + TempControlledZone.OpTempCntrlModeScheduled = true; } if ((!(Util::SameString(cAlphaArgs(2), "Scheduled"))) && (!(Util::SameString(cAlphaArgs(2), "Constant")))) { ShowSevereError(state, @@ -1902,10 +1872,9 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } - TempControlledZone(TempControlledZoneNum).FixedRadiativeFraction = rNumericArgs(1); - TempControlledZone(TempControlledZoneNum).OpTempRadiativeFractionSched = GetScheduleIndex(state, cAlphaArgs(3)); - if ((TempControlledZone(TempControlledZoneNum).OpTempRadiativeFractionSched == 0) && - (TempControlledZone(TempControlledZoneNum).OpTempCntrlModeScheduled)) { // throw error + TempControlledZone.FixedRadiativeFraction = rNumericArgs(1); + TempControlledZone.OpTempRadiativeFractionSched = GetScheduleIndex(state, cAlphaArgs(3)); + if ((TempControlledZone.OpTempRadiativeFractionSched == 0) && (TempControlledZone.OpTempCntrlModeScheduled)) { // throw error ShowSevereError( state, format("{}={} invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(3), cAlphaArgs(3))); @@ -1913,8 +1882,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } // check validity of fixed radiative fraction - if ((TempControlledZone(TempControlledZoneNum).FixedRadiativeFraction < 0.0) && - (!(TempControlledZone(TempControlledZoneNum).OpTempCntrlModeScheduled))) { + if ((TempControlledZone.FixedRadiativeFraction < 0.0) && (!(TempControlledZone.OpTempCntrlModeScheduled))) { ShowSevereError(state, format("{}={} invalid {}=[{:.2T}\" cannot be negative.", cCurrentModuleObject, @@ -1923,8 +1891,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) rNumericArgs(1))); ErrorsFound = true; } - if ((TempControlledZone(TempControlledZoneNum).FixedRadiativeFraction >= 0.9) && - (!(TempControlledZone(TempControlledZoneNum).OpTempCntrlModeScheduled))) { + if ((TempControlledZone.FixedRadiativeFraction >= 0.9) && (!(TempControlledZone.OpTempCntrlModeScheduled))) { ShowSevereError(state, format("{}={} invalid {}=[{:.2T}\" cannot >= .9.", cCurrentModuleObject, @@ -1935,9 +1902,9 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } // check schedule min max. - if (TempControlledZone(TempControlledZoneNum).OpTempCntrlModeScheduled) { - ValidRadFractSched = CheckScheduleValueMinMax( - state, TempControlledZone(TempControlledZoneNum).OpTempRadiativeFractionSched, ">=", 0.0, "<", 0.9); + if (TempControlledZone.OpTempCntrlModeScheduled) { + bool ValidRadFractSched = + CheckScheduleValueMinMax(state, TempControlledZone.OpTempRadiativeFractionSched, ">=", 0.0, "<", 0.9); if (!ValidRadFractSched) { ShowSevereError( state, @@ -1949,7 +1916,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) // added Jan, 2017 - Xuan Luo // read adaptive comfort model and calculate adaptive thermal comfort setpoint - if (TempControlledZone(TempControlledZoneNum).OperativeTempControl) { + if (TempControlledZone.OperativeTempControl) { if (NumAlphas >= 4 && !lAlphaFieldBlanks(4)) { int adaptiveComfortModelTypeIndex = Util::FindItem(cAlphaArgs(4), AdaptiveComfortModelTypes, AdaptiveComfortModelTypes.isize()); @@ -1962,8 +1929,8 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaArgs(4))); ErrorsFound = true; } else if (adaptiveComfortModelTypeIndex != static_cast(AdaptiveComfortModel::ADAP_NONE)) { - TempControlledZone(TempControlledZoneNum).AdaptiveComfortTempControl = true; - TempControlledZone(TempControlledZoneNum).AdaptiveComfortModelTypeIndex = + TempControlledZone.AdaptiveComfortTempControl = true; + TempControlledZone.AdaptiveComfortModelTypeIndex = Util::FindItem(cAlphaArgs(4), AdaptiveComfortModelTypes, AdaptiveComfortModelTypes.isize()); if (!state.dataZoneTempPredictorCorrector->AdapComfortDailySetPointSchedule.initialized) { Array1D runningAverageASH(state.dataWeather->NumDaysInYear, 0.0); @@ -1979,18 +1946,20 @@ void GetZoneAirSetPoints(EnergyPlusData &state) SetupOutputVariable(state, "Zone Thermostat Operative Temperature", Constant::Units::C, - state.dataHeatBal->ZnAirRpt(TempControlledZone(TempControlledZoneNum).ActualZoneNum).ThermOperativeTemp, + state.dataHeatBal->ZnAirRpt(TempControlledZone.ActualZoneNum).ThermOperativeTemp, OutputProcessor::TimeStepType::Zone, OutputProcessor::StoreType::Average, - Zone(TempControlledZone(TempControlledZoneNum).ActualZoneNum).Name); + state.dataHeatBal->Zone(TempControlledZone.ActualZoneNum).Name); } } else { - for (Item = 1; Item <= TStatObjects(found).NumOfZones; ++Item) { - TempControlledZoneNum = TStatObjects(found).TempControlledZoneStartPtr + Item - 1; + auto const &TStatObjects = state.dataZoneCtrls->TStatObjects(found); + for (Item = 1; Item <= TStatObjects.NumOfZones; ++Item) { + TempControlledZoneNum = TStatObjects.TempControlledZoneStartPtr + Item - 1; + auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone(TempControlledZoneNum); if (state.dataZoneCtrls->NumTempControlledZones == 0) continue; - TempControlledZone(TempControlledZoneNum).OperativeTempControl = true; + TempControlledZone.OperativeTempControl = true; if (Util::SameString(cAlphaArgs(2), "Scheduled")) { - TempControlledZone(TempControlledZoneNum).OpTempCntrlModeScheduled = true; + TempControlledZone.OpTempCntrlModeScheduled = true; } if (Item == 1) { if ((!(Util::SameString(cAlphaArgs(2), "Scheduled"))) && (!(Util::SameString(cAlphaArgs(2), "Constant")))) { @@ -2000,23 +1969,18 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } } - TempControlledZone(TempControlledZoneNum).FixedRadiativeFraction = rNumericArgs(1); - TempControlledZone(TempControlledZoneNum).OpTempRadiativeFractionSched = GetScheduleIndex(state, cAlphaArgs(3)); + TempControlledZone.FixedRadiativeFraction = rNumericArgs(1); + TempControlledZone.OpTempRadiativeFractionSched = GetScheduleIndex(state, cAlphaArgs(3)); if (Item == 1) { - if ((TempControlledZone(TempControlledZoneNum).OpTempRadiativeFractionSched == 0) && - (TempControlledZone(TempControlledZoneNum).OpTempCntrlModeScheduled)) { // throw error + if ((TempControlledZone.OpTempRadiativeFractionSched == 0) && (TempControlledZone.OpTempCntrlModeScheduled)) { // throw error ShowSevereError( state, format( "{}={} invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(3), cAlphaArgs(3))); ErrorsFound = true; } - } - - // check validity of fixed radiative fraction - if (Item == 1) { - if ((TempControlledZone(TempControlledZoneNum).FixedRadiativeFraction < 0.0) && - (!(TempControlledZone(TempControlledZoneNum).OpTempCntrlModeScheduled))) { + // check validity of fixed radiative fraction + if ((TempControlledZone.FixedRadiativeFraction < 0.0) && (!(TempControlledZone.OpTempCntrlModeScheduled))) { ShowSevereError(state, format("{}={} invalid {}=[{:.2T}\" cannot be negative.", cCurrentModuleObject, @@ -2025,10 +1989,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) rNumericArgs(1))); ErrorsFound = true; } - } - if (Item == 1) { - if ((TempControlledZone(TempControlledZoneNum).FixedRadiativeFraction >= 0.9) && - (!(TempControlledZone(TempControlledZoneNum).OpTempCntrlModeScheduled))) { + if ((TempControlledZone.FixedRadiativeFraction >= 0.9) && (!(TempControlledZone.OpTempCntrlModeScheduled))) { ShowSevereError(state, format("{}={} invalid {}=[{:.2T}\" cannot >= .9.", cCurrentModuleObject, @@ -2037,13 +1998,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) rNumericArgs(1))); ErrorsFound = true; } - } - - // check schedule min max. - if (Item == 1) { - if (TempControlledZone(TempControlledZoneNum).OpTempCntrlModeScheduled) { - ValidRadFractSched = CheckScheduleValueMinMax( - state, TempControlledZone(TempControlledZoneNum).OpTempRadiativeFractionSched, ">=", 0.0, "<", 0.9); + // check schedule min max. + if (TempControlledZone.OpTempCntrlModeScheduled) { + bool ValidRadFractSched = + CheckScheduleValueMinMax(state, TempControlledZone.OpTempRadiativeFractionSched, ">=", 0.0, "<", 0.9); if (!ValidRadFractSched) { ShowSevereError( state, @@ -2057,7 +2015,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) // added Jan, 2017 - Xuan Luo // read adaptive comfort model and calculate adaptive thermal comfort setpoint - if (TempControlledZone(TempControlledZoneNum).OperativeTempControl) { + if (TempControlledZone.OperativeTempControl) { if (NumAlphas >= 4 && !lAlphaFieldBlanks(4)) { int adaptiveComfortModelTypeIndex = Util::FindItem(cAlphaArgs(4), AdaptiveComfortModelTypes, AdaptiveComfortModelTypes.isize()); @@ -2070,8 +2028,8 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaArgs(4))); ErrorsFound = true; } else if (adaptiveComfortModelTypeIndex != static_cast(AdaptiveComfortModel::ADAP_NONE)) { - TempControlledZone(TempControlledZoneNum).AdaptiveComfortTempControl = true; - TempControlledZone(TempControlledZoneNum).AdaptiveComfortModelTypeIndex = + TempControlledZone.AdaptiveComfortTempControl = true; + TempControlledZone.AdaptiveComfortModelTypeIndex = Util::FindItem(cAlphaArgs(4), AdaptiveComfortModelTypes, AdaptiveComfortModelTypes.isize()); if (!state.dataZoneTempPredictorCorrector->AdapComfortDailySetPointSchedule.initialized) { Array1D runningAverageASH(state.dataWeather->NumDaysInYear, 0.0); @@ -2087,10 +2045,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) SetupOutputVariable(state, "Zone Thermostat Operative Temperature", Constant::Units::C, - state.dataHeatBal->ZnAirRpt(TempControlledZone(TempControlledZoneNum).ActualZoneNum).ThermOperativeTemp, + state.dataHeatBal->ZnAirRpt(TempControlledZone.ActualZoneNum).ThermOperativeTemp, OutputProcessor::TimeStepType::Zone, OutputProcessor::StoreType::Average, - Zone(TempControlledZone(TempControlledZoneNum).ActualZoneNum).Name); + state.dataHeatBal->Zone(TempControlledZone.ActualZoneNum).Name); } // TStat Objects Loop } // found thermostat referene } // loop over NumOpTempControlledZones @@ -2117,10 +2075,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaFieldNames, cNumericFieldNames); // find matching name of ZONECONTROL:THERMOSTAT object - found = Util::FindItem(cAlphaArgs(1), TStatObjects); + found = Util::FindItem(cAlphaArgs(1), state.dataZoneCtrls->TStatObjects); if (found == 0) { // It might be in the TempControlledZones - found = Util::FindItem(cAlphaArgs(1), TempControlledZone); + found = Util::FindItem(cAlphaArgs(1), state.dataZoneCtrls->TempControlledZone); if (found == 0) { // throw error ShowSevereError(state, format("{}={} invalid {} reference not found.", @@ -2130,20 +2088,21 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } else { TempControlledZoneNum = found; - TempControlledZone(TempControlledZoneNum).DehumidifyingSched = cAlphaArgs(2); - TempControlledZone(TempControlledZoneNum).DehumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(2)); - if (TempControlledZone(TempControlledZoneNum).DehumidifyingSchedIndex == 0) { + auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone(TempControlledZoneNum); + TempControlledZone.DehumidifyingSched = cAlphaArgs(2); + TempControlledZone.DehumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(2)); + if (TempControlledZone.DehumidifyingSchedIndex == 0) { ShowSevereError( state, format("{}=\"{} invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2))); ErrorsFound = true; } - TempControlledZone(TempControlledZoneNum).ZoneOvercoolControl = true; + TempControlledZone.ZoneOvercoolControl = true; if ((Util::SameString(cAlphaArgs(3), "None"))) { - TempControlledZone(TempControlledZoneNum).ZoneOvercoolControl = false; + TempControlledZone.ZoneOvercoolControl = false; } if (Util::SameString(cAlphaArgs(4), "Scheduled")) { - TempControlledZone(TempControlledZoneNum).OvercoolCntrlModeScheduled = true; + TempControlledZone.OvercoolCntrlModeScheduled = true; } if ((!(Util::SameString(cAlphaArgs(4), "Scheduled"))) && (!(Util::SameString(cAlphaArgs(4), "Constant")))) { ShowSevereError(state, @@ -2151,10 +2110,9 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } - TempControlledZone(TempControlledZoneNum).ZoneOvercoolConstRange = rNumericArgs(1); - TempControlledZone(TempControlledZoneNum).ZoneOvercoolRangeSchedIndex = GetScheduleIndex(state, cAlphaArgs(4)); - if ((TempControlledZone(TempControlledZoneNum).ZoneOvercoolRangeSchedIndex == 0) && - (TempControlledZone(TempControlledZoneNum).OvercoolCntrlModeScheduled)) { // throw error + TempControlledZone.ZoneOvercoolConstRange = rNumericArgs(1); + TempControlledZone.ZoneOvercoolRangeSchedIndex = GetScheduleIndex(state, cAlphaArgs(4)); + if ((TempControlledZone.ZoneOvercoolRangeSchedIndex == 0) && (TempControlledZone.OvercoolCntrlModeScheduled)) { // throw error ShowSevereError( state, format("{}={} invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(5), cAlphaArgs(5))); @@ -2162,8 +2120,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } // check validity of zone Overcool constant range - if ((TempControlledZone(TempControlledZoneNum).ZoneOvercoolConstRange < 0.0) && - (!(TempControlledZone(TempControlledZoneNum).OvercoolCntrlModeScheduled))) { + if ((TempControlledZone.ZoneOvercoolConstRange < 0.0) && (!(TempControlledZone.OvercoolCntrlModeScheduled))) { ShowSevereError(state, format("{}={} invalid {}=[{:.2T}\" cannot be negative.", cCurrentModuleObject, @@ -2172,8 +2129,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) rNumericArgs(1))); ErrorsFound = true; } - if ((TempControlledZone(TempControlledZoneNum).ZoneOvercoolConstRange > 3.0) && - (!(TempControlledZone(TempControlledZoneNum).OvercoolCntrlModeScheduled))) { + if ((TempControlledZone.ZoneOvercoolConstRange > 3.0) && (!(TempControlledZone.OvercoolCntrlModeScheduled))) { ShowSevereError(state, format("{}={} invalid {}=[{:.2T}\" cannot be > 3.0", cCurrentModuleObject, @@ -2184,9 +2140,9 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } // check zone Overcool range schedule min/max values. - if (TempControlledZone(TempControlledZoneNum).OvercoolCntrlModeScheduled) { - ValidZoneOvercoolRangeSched = CheckScheduleValueMinMax( - state, TempControlledZone(TempControlledZoneNum).ZoneOvercoolRangeSchedIndex, ">=", 0.0, "<=", 3.0); + if (TempControlledZone.OvercoolCntrlModeScheduled) { + bool ValidZoneOvercoolRangeSched = + CheckScheduleValueMinMax(state, TempControlledZone.ZoneOvercoolRangeSchedIndex, ">=", 0.0, "<=", 3.0); if (!ValidZoneOvercoolRangeSched) { ShowSevereError( state, @@ -2196,8 +2152,8 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } } // check Overcool Control Ratio limits - TempControlledZone(TempControlledZoneNum).ZoneOvercoolControlRatio = rNumericArgs(2); - if (TempControlledZone(TempControlledZoneNum).ZoneOvercoolControlRatio < 0.0) { + TempControlledZone.ZoneOvercoolControlRatio = rNumericArgs(2); + if (TempControlledZone.ZoneOvercoolControlRatio < 0.0) { ShowSevereError(state, format("{}={} invalid {}=[{:.2T}\" cannot be negative.", cCurrentModuleObject, @@ -2208,22 +2164,24 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } } } else { - for (Item = 1; Item <= TStatObjects(found).NumOfZones; ++Item) { - TempControlledZoneNum = TStatObjects(found).TempControlledZoneStartPtr + Item - 1; - TempControlledZone(TempControlledZoneNum).DehumidifyingSched = cAlphaArgs(2); - TempControlledZone(TempControlledZoneNum).DehumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(2)); - if (TempControlledZone(TempControlledZoneNum).DehumidifyingSchedIndex == 0) { + auto const &TStatObjects = state.dataZoneCtrls->TStatObjects(found); + for (Item = 1; Item <= TStatObjects.NumOfZones; ++Item) { + TempControlledZoneNum = TStatObjects.TempControlledZoneStartPtr + Item - 1; + auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone(TempControlledZoneNum); + TempControlledZone.DehumidifyingSched = cAlphaArgs(2); + TempControlledZone.DehumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(2)); + if (TempControlledZone.DehumidifyingSchedIndex == 0) { ShowSevereError( state, format("{}=\"{} invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2))); ErrorsFound = true; } - TempControlledZone(TempControlledZoneNum).ZoneOvercoolControl = true; + TempControlledZone.ZoneOvercoolControl = true; if ((Util::SameString(cAlphaArgs(3), "None"))) { - TempControlledZone(TempControlledZoneNum).ZoneOvercoolControl = false; + TempControlledZone.ZoneOvercoolControl = false; } if (Util::SameString(cAlphaArgs(4), "Scheduled")) { - TempControlledZone(TempControlledZoneNum).OvercoolCntrlModeScheduled = false; + TempControlledZone.OvercoolCntrlModeScheduled = false; } if (Item == 1) { if ((!(Util::SameString(cAlphaArgs(4), "Scheduled"))) && (!(Util::SameString(cAlphaArgs(4), "Constant")))) { @@ -2232,22 +2190,18 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } } - TempControlledZone(TempControlledZoneNum).ZoneOvercoolConstRange = rNumericArgs(1); - TempControlledZone(TempControlledZoneNum).ZoneOvercoolRangeSchedIndex = GetScheduleIndex(state, cAlphaArgs(6)); + TempControlledZone.ZoneOvercoolConstRange = rNumericArgs(1); + TempControlledZone.ZoneOvercoolRangeSchedIndex = GetScheduleIndex(state, cAlphaArgs(6)); if (Item == 1) { - if ((TempControlledZone(TempControlledZoneNum).ZoneOvercoolRangeSchedIndex == 0) && - (TempControlledZone(TempControlledZoneNum).OvercoolCntrlModeScheduled)) { // throw error + if ((TempControlledZone.ZoneOvercoolRangeSchedIndex == 0) && (TempControlledZone.OvercoolCntrlModeScheduled)) { // throw error ShowSevereError( state, format( "{}={} invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(5), cAlphaArgs(5))); ErrorsFound = true; } - } - // check validity of zone Overcool constant range - if (Item == 1) { - if ((TempControlledZone(TempControlledZoneNum).ZoneOvercoolConstRange < 0.0) && - (!(TempControlledZone(TempControlledZoneNum).OvercoolCntrlModeScheduled))) { + // check validity of zone Overcool constant range + if ((TempControlledZone.ZoneOvercoolConstRange < 0.0) && (!(TempControlledZone.OvercoolCntrlModeScheduled))) { ShowSevereError(state, format("{}={} invalid {}=[{:.2T}\" cannot be negative.", cCurrentModuleObject, @@ -2256,10 +2210,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) rNumericArgs(1))); ErrorsFound = true; } - } - if (Item == 1) { - if ((TempControlledZone(TempControlledZoneNum).ZoneOvercoolConstRange > 3.0) && - (!(TempControlledZone(TempControlledZoneNum).OvercoolCntrlModeScheduled))) { + if ((TempControlledZone.ZoneOvercoolConstRange > 3.0) && (!(TempControlledZone.OvercoolCntrlModeScheduled))) { ShowSevereError(state, format("{}={} invalid {}=[{:.2T}\" cannot > 3.0", cCurrentModuleObject, @@ -2268,12 +2219,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) rNumericArgs(1))); ErrorsFound = true; } - } - // check zone Overcool range schedule min/max values. - if (Item == 1) { - if (TempControlledZone(TempControlledZoneNum).OvercoolCntrlModeScheduled) { - ValidZoneOvercoolRangeSched = CheckScheduleValueMinMax( - state, TempControlledZone(TempControlledZoneNum).ZoneOvercoolRangeSchedIndex, ">=", 0.0, "<=", 3.0); + // check zone Overcool range schedule min/max values. + if (TempControlledZone.OvercoolCntrlModeScheduled) { + bool ValidZoneOvercoolRangeSched = + CheckScheduleValueMinMax(state, TempControlledZone.ZoneOvercoolRangeSchedIndex, ">=", 0.0, "<=", 3.0); if (!ValidZoneOvercoolRangeSched) { ShowSevereError( state, @@ -2284,10 +2233,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } } } - TempControlledZone(TempControlledZoneNum).ZoneOvercoolControlRatio = rNumericArgs(2); + TempControlledZone.ZoneOvercoolControlRatio = rNumericArgs(2); // check Overcool Control Ratio limits if (Item == 1) { - if (TempControlledZone(TempControlledZoneNum).ZoneOvercoolControlRatio < 0.0) { + if (TempControlledZone.ZoneOvercoolControlRatio < 0.0) { ShowSevereError(state, format("{}={} invalid {}=[{:.2T}\" cannot be negative.", cCurrentModuleObject, @@ -2326,9 +2275,9 @@ void GetZoneAirSetPoints(EnergyPlusData &state) Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound); state.dataZoneCtrls->StagedTStatObjects(Item).Name = cAlphaArgs(1); - Item1 = Util::FindItemInList(cAlphaArgs(2), Zone); + Item1 = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->Zone); ZLItem = 0; - if (Item1 == 0 && state.dataHeatBal->NumOfZoneLists > 0) ZLItem = Util::FindItemInList(cAlphaArgs(2), ZoneList); + if (Item1 == 0 && state.dataHeatBal->NumOfZoneLists > 0) ZLItem = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->ZoneList); if (Item1 > 0) { state.dataZoneCtrls->StagedTStatObjects(Item).StageControlledZoneStartPtr = state.dataZoneTempPredictorCorrector->NumStageCtrZone + 1; ++state.dataZoneTempPredictorCorrector->NumStageCtrZone; @@ -2336,9 +2285,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) state.dataZoneCtrls->StagedTStatObjects(Item).ZoneListActive = false; state.dataZoneCtrls->StagedTStatObjects(Item).ZoneOrZoneListPtr = Item1; } else if (ZLItem > 0) { + auto const &ZoneList = state.dataHeatBal->ZoneList(ZLItem); state.dataZoneCtrls->StagedTStatObjects(Item).TempControlledZoneStartPtr = state.dataZoneTempPredictorCorrector->NumStageCtrZone + 1; - state.dataZoneTempPredictorCorrector->NumStageCtrZone += ZoneList(ZLItem).NumOfZones; - state.dataZoneCtrls->StagedTStatObjects(Item).NumOfZones = ZoneList(ZLItem).NumOfZones; + state.dataZoneTempPredictorCorrector->NumStageCtrZone += ZoneList.NumOfZones; + state.dataZoneCtrls->StagedTStatObjects(Item).NumOfZones = ZoneList.NumOfZones; state.dataZoneCtrls->StagedTStatObjects(Item).ZoneListActive = true; state.dataZoneCtrls->StagedTStatObjects(Item).ZoneOrZoneListPtr = ZLItem; } else { @@ -2355,10 +2305,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } if (state.dataZoneTempPredictorCorrector->NumStageCtrZone > 0) { - StageControlledZone.allocate(state.dataZoneTempPredictorCorrector->NumStageCtrZone); + state.dataZoneCtrls->StageControlledZone.allocate(state.dataZoneTempPredictorCorrector->NumStageCtrZone); state.dataZoneCtrls->StageZoneLogic.dimension(NumOfZones, false); - StageControlledZoneNum = 0; + int StageControlledZoneNum = 0; for (Item = 1; Item <= NumStageControlledZones; ++Item) { inputProcessor->getObjectItem(state, cCurrentModuleObject, @@ -2375,56 +2325,61 @@ void GetZoneAirSetPoints(EnergyPlusData &state) for (Item1 = 1; Item1 <= state.dataZoneCtrls->StagedTStatObjects(Item).NumOfZones; ++Item1) { ++StageControlledZoneNum; if (state.dataZoneCtrls->StagedTStatObjects(Item).ZoneListActive) { - cAlphaArgs(2) = - state.dataHeatBal->Zone(ZoneList(state.dataZoneCtrls->StagedTStatObjects(Item).ZoneOrZoneListPtr).Zone(Item1)).Name; - } - int ZoneAssigned = Util::FindItemInList( - cAlphaArgs(2), StageControlledZone, &DataZoneControls::ZoneStagedControls::ZoneName, StageControlledZoneNum - 1); + auto &ZoneList = state.dataHeatBal->ZoneList(state.dataZoneCtrls->StagedTStatObjects(Item).ZoneOrZoneListPtr); + cAlphaArgs(2) = state.dataHeatBal->Zone(ZoneList.Zone(Item1)).Name; + } + int ZoneAssigned = Util::FindItemInList(cAlphaArgs(2), + state.dataZoneCtrls->StageControlledZone, + &DataZoneControls::ZoneStagedControls::ZoneName, + StageControlledZoneNum - 1); + auto &stageControlledZone = state.dataZoneCtrls->StageControlledZone(StageControlledZoneNum); if (ZoneAssigned == 0) { - StageControlledZone(StageControlledZoneNum).ZoneName = cAlphaArgs(2); - StageControlledZone(StageControlledZoneNum).ActualZoneNum = Util::FindItemInList(cAlphaArgs(2), Zone); - if (StageControlledZone(StageControlledZoneNum).ActualZoneNum == 0) { + stageControlledZone.ZoneName = cAlphaArgs(2); + stageControlledZone.ActualZoneNum = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->Zone); + if (stageControlledZone.ActualZoneNum == 0) { ShowSevereError( state, format( "{}=\"{}\" invalid {}=\"{}\" not found.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2))); ErrorsFound = true; } else { - // Zone(StageControlledZone(StageControlledZoneNum)%ActualZoneNum)%StageControlledZoneIndex = + // Zone(stageControlledZone%ActualZoneNum)%StageControlledZoneIndex = // StageControlledZoneNum } - state.dataZoneCtrls->StageZoneLogic(StageControlledZone(StageControlledZoneNum).ActualZoneNum) = true; + state.dataZoneCtrls->StageZoneLogic(stageControlledZone.ActualZoneNum) = true; } else { - StageControlledZone(StageControlledZoneNum).ZoneName = cAlphaArgs(2); // for continuity + stageControlledZone.ZoneName = cAlphaArgs(2); // for continuity ShowSevereError(state, format("{}=\"{}\" invalid {}=\"{}\" zone previously assigned.", cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2))); - ShowContinueError(state, format("...Zone was previously assigned to Thermostat=\"{}\".", StageControlledZone(ZoneAssigned).Name)); + ShowContinueError( + state, + format("...Zone was previously assigned to Thermostat=\"{}\".", state.dataZoneCtrls->StageControlledZone(ZoneAssigned).Name)); ErrorsFound = true; continue; } if (!state.dataZoneCtrls->StagedTStatObjects(Item).ZoneListActive) { - StageControlledZone(StageControlledZoneNum).Name = cAlphaArgs(1); + stageControlledZone.Name = cAlphaArgs(1); } else { - CheckCreatedZoneItemName( - state, - RoutineName, - cCurrentModuleObject, - state.dataHeatBal->Zone(ZoneList(state.dataZoneCtrls->StagedTStatObjects(Item).ZoneOrZoneListPtr).Zone(Item1)).Name, - ZoneList(state.dataZoneCtrls->StagedTStatObjects(Item).ZoneOrZoneListPtr).MaxZoneNameLength, - state.dataZoneCtrls->StagedTStatObjects(Item).Name, - StageControlledZone, - StageControlledZoneNum - 1, - StageControlledZone(StageControlledZoneNum).Name, - errFlag); + auto &ZoneList = state.dataHeatBal->ZoneList(state.dataZoneCtrls->StagedTStatObjects(Item).ZoneOrZoneListPtr); + CheckCreatedZoneItemName(state, + RoutineName, + cCurrentModuleObject, + state.dataHeatBal->Zone(ZoneList.Zone(Item1)).Name, + ZoneList.MaxZoneNameLength, + state.dataZoneCtrls->StagedTStatObjects(Item).Name, + state.dataZoneCtrls->StageControlledZone, + StageControlledZoneNum - 1, + stageControlledZone.Name, + errFlag); if (errFlag) ErrorsFound = true; } - StageControlledZone(StageControlledZoneNum).NumOfHeatStages = rNumericArgs(1); + stageControlledZone.NumOfHeatStages = rNumericArgs(1); if (rNumericArgs(1) < 1 || rNumericArgs(1) > 4) { ShowSevereError( state, @@ -2433,10 +2388,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } - StageControlledZone(StageControlledZoneNum).HeatSetBaseSchedName = cAlphaArgs(3); - StageControlledZone(StageControlledZoneNum).HSBchedIndex = GetScheduleIndex(state, cAlphaArgs(3)); + stageControlledZone.HeatSetBaseSchedName = cAlphaArgs(3); + stageControlledZone.HSBchedIndex = GetScheduleIndex(state, cAlphaArgs(3)); if (Item1 == 1) { // only show error on first of several if zone list - if (StageControlledZone(StageControlledZoneNum).HSBchedIndex == 0) { + if (stageControlledZone.HSBchedIndex == 0) { ShowSevereError( state, format( @@ -2445,7 +2400,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } } - StageControlledZone(StageControlledZoneNum).HeatThroRange = rNumericArgs(2); + stageControlledZone.HeatThroRange = rNumericArgs(2); if (rNumericArgs(1) < 0.0) { ShowSevereError(state, format("{}=\"{}\" negative value is found at {}=\"{:.1R}\"", @@ -2457,10 +2412,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } - if (StageControlledZone(StageControlledZoneNum).NumOfHeatStages > 0) { - StageControlledZone(StageControlledZoneNum).HeatTOffset.allocate(StageControlledZone(StageControlledZoneNum).NumOfHeatStages); - for (i = 1; i <= StageControlledZone(StageControlledZoneNum).NumOfHeatStages; ++i) { - StageControlledZone(StageControlledZoneNum).HeatTOffset(i) = rNumericArgs(2 + i); + if (stageControlledZone.NumOfHeatStages > 0) { + stageControlledZone.HeatTOffset.allocate(stageControlledZone.NumOfHeatStages); + for (i = 1; i <= stageControlledZone.NumOfHeatStages; ++i) { + stageControlledZone.HeatTOffset(i) = rNumericArgs(2 + i); if (rNumericArgs(2 + i) > 0.0) { ShowSevereError(state, format("{}=\"{}\" positive value is found at {}", @@ -2493,7 +2448,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } } - StageControlledZone(StageControlledZoneNum).NumOfCoolStages = rNumericArgs(7); + stageControlledZone.NumOfCoolStages = rNumericArgs(7); if (rNumericArgs(7) < 1 || rNumericArgs(7) > 4) { ShowSevereError( state, @@ -2502,10 +2457,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } - StageControlledZone(StageControlledZoneNum).CoolSetBaseSchedName = cAlphaArgs(4); - StageControlledZone(StageControlledZoneNum).CSBchedIndex = GetScheduleIndex(state, cAlphaArgs(4)); + stageControlledZone.CoolSetBaseSchedName = cAlphaArgs(4); + stageControlledZone.CSBchedIndex = GetScheduleIndex(state, cAlphaArgs(4)); if (Item1 == 1) { // only show error on first of several if zone list - if (StageControlledZone(StageControlledZoneNum).CSBchedIndex == 0) { + if (stageControlledZone.CSBchedIndex == 0) { ShowSevereError( state, format( @@ -2514,7 +2469,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) } } - StageControlledZone(StageControlledZoneNum).CoolThroRange = rNumericArgs(8); + stageControlledZone.CoolThroRange = rNumericArgs(8); if (rNumericArgs(8) < 0.0) { ShowSevereError(state, format("{}=\"{}\" negative value is found at {}=\"{:.1R}\"", @@ -2526,10 +2481,10 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ErrorsFound = true; } - if (StageControlledZone(StageControlledZoneNum).NumOfCoolStages > 0) { - StageControlledZone(StageControlledZoneNum).CoolTOffset.allocate(StageControlledZone(StageControlledZoneNum).NumOfCoolStages); - for (i = 1; i <= StageControlledZone(StageControlledZoneNum).NumOfCoolStages; ++i) { - StageControlledZone(StageControlledZoneNum).CoolTOffset(i) = rNumericArgs(8 + i); + if (stageControlledZone.NumOfCoolStages > 0) { + stageControlledZone.CoolTOffset.allocate(stageControlledZone.NumOfCoolStages); + for (i = 1; i <= stageControlledZone.NumOfCoolStages; ++i) { + stageControlledZone.CoolTOffset(i) = rNumericArgs(8 + i); if (rNumericArgs(8 + i) < 0.0) { ShowSevereError(state, format("{}=\"{}\" negative value is found at {}=\"{:.1R}\"", @@ -2599,37 +2554,25 @@ void CalculateMonthlyRunningAverageDryBulb(EnergyPlusData &state, Array1D adaptiveTemp(state.dataWeather->NumDaysInYear, 0.0); Array1D dailyDryTemp(state.dataWeather->NumDaysInYear, 0.0); - readStat = 0; if (FileSystem::fileExists(state.files.inputWeatherFilePath.filePath)) { // Read hourly dry bulb temperature first auto epwFile = state.files.inputWeatherFilePath.open(state, "CalcThermalComfortAdaptive"); - for (i = 1; i <= 9; ++i) { // Headers + for (int i = 1; i <= 9; ++i) { // Headers epwFile.readLine(); } - for (i = 1; i <= state.dataWeather->NumDaysInYear; ++i) { + for (int i = 1; i <= state.dataWeather->NumDaysInYear; ++i) { avgDryBulb = 0.0; - for (j = 1; j <= 24; ++j) { - epwLine = epwFile.readLine().data; - for (ind = 1; ind <= 6; ++ind) { + for (int j = 1; j <= 24; ++j) { + std::string epwLine = epwFile.readLine().data; + for (int ind = 1; ind <= 6; ++ind) { pos = index(epwLine, ','); epwLine.erase(0, pos + 1); } @@ -2645,23 +2588,23 @@ void CalculateMonthlyRunningAverageDryBulb(EnergyPlusData &state, Array1DNumDaysInYear) { dayOfYear++; - calcEndDay = dayOfYear - 1; - calcStartDayASH = calcEndDay - 30; - calcStartDayCEN = calcEndDay - 7; + int calcEndDay = dayOfYear - 1; + int calcStartDayASH = calcEndDay - 30; + int calcStartDayCEN = calcEndDay - 7; if (calcStartDayASH > 0) { - for (i = calcStartDayASH; i <= calcStartDayASH + 30; i++) { + for (int i = calcStartDayASH; i <= calcStartDayASH + 30; i++) { avgDryBulb = dailyDryTemp(i); runningAverageASH(dayOfYear) = runningAverageASH(dayOfYear) + avgDryBulb; } runningAverageASH(dayOfYear) /= 30; } else { // Do special things for wrapping the epw calcStartDayASH += state.dataWeather->NumDaysInYear; - for (i = 1; i <= calcEndDay; i++) { + for (int i = 1; i <= calcEndDay; i++) { avgDryBulb = dailyDryTemp(i); runningAverageASH(dayOfYear) = runningAverageASH(dayOfYear) + avgDryBulb; } - for (i = calcStartDayASH; i < state.dataWeather->NumDaysInYear; i++) { + for (int i = calcStartDayASH; i < state.dataWeather->NumDaysInYear; i++) { avgDryBulb = dailyDryTemp(i); runningAverageASH(dayOfYear) = runningAverageASH(dayOfYear) + avgDryBulb; } @@ -2669,18 +2612,18 @@ void CalculateMonthlyRunningAverageDryBulb(EnergyPlusData &state, Array1D 0) { - for (i = calcStartDayCEN; i <= calcStartDayCEN + 7; i++) { + for (int i = calcStartDayCEN; i <= calcStartDayCEN + 7; i++) { avgDryBulb = dailyDryTemp(i); runningAverageCEN(dayOfYear) = runningAverageCEN(dayOfYear) + avgDryBulb; } runningAverageCEN(dayOfYear) /= 7; } else { // Do special things for wrapping the epw calcStartDayCEN += state.dataWeather->NumDaysInYear; - for (i = 1; i <= calcEndDay; i++) { + for (int i = 1; i <= calcEndDay; i++) { avgDryBulb = dailyDryTemp(i); runningAverageCEN(dayOfYear) = runningAverageCEN(dayOfYear) + avgDryBulb; } - for (i = calcStartDayCEN; i < state.dataWeather->NumDaysInYear; i++) { + for (int i = calcStartDayCEN; i < state.dataWeather->NumDaysInYear; i++) { avgDryBulb = dailyDryTemp(i); runningAverageCEN(dayOfYear) = runningAverageCEN(dayOfYear) + avgDryBulb; } @@ -2788,30 +2731,20 @@ void InitZoneAirSetPoints(EnergyPlusData &state) static constexpr std::string_view RoutineName("InitZoneAirSetpoints: "); // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - bool FirstSurfFlag; - int TRefFlag; // Flag for Reference Temperature process in Zones - - auto &ZoneList = state.dataHeatBal->ZoneList; - auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone; - auto &TempZoneThermostatSetPoint = state.dataHeatBalFanSys->TempZoneThermostatSetPoint; - auto &TempControlType = state.dataHeatBalFanSys->TempControlType; - auto &TempControlTypeRpt = state.dataHeatBalFanSys->TempControlTypeRpt; - auto &ComfortControlledZone = state.dataZoneCtrls->ComfortControlledZone; - auto &ZoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo; - auto &ZoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi; int NumOfZones = state.dataGlobal->NumOfZones; if (state.dataZoneTempPredictorCorrector->InitZoneAirSetPointsOneTimeFlag) { - TempZoneThermostatSetPoint.dimension(NumOfZones, 0.0); + int TRefFlag; // Flag for Reference Temperature process in Zones + state.dataHeatBalFanSys->TempZoneThermostatSetPoint.dimension(NumOfZones, 0.0); state.dataHeatBalFanSys->AdapComfortCoolingSetPoint.dimension(NumOfZones, 0.0); - ZoneThermostatSetPointHi.dimension(NumOfZones, 0.0); - ZoneThermostatSetPointLo.dimension(NumOfZones, 0.0); + state.dataHeatBalFanSys->ZoneThermostatSetPointHi.dimension(NumOfZones, 0.0); + state.dataHeatBalFanSys->ZoneThermostatSetPointLo.dimension(NumOfZones, 0.0); state.dataHeatBalFanSys->ZoneThermostatSetPointHiAver.dimension(NumOfZones, 0.0); state.dataHeatBalFanSys->ZoneThermostatSetPointLoAver.dimension(NumOfZones, 0.0); state.dataHeatBalFanSys->LoadCorrectionFactor.dimension(NumOfZones, 0.0); - TempControlType.dimension(NumOfZones, HVAC::ThermostatType::Uncontrolled); - TempControlTypeRpt.dimension(NumOfZones, 0); + state.dataHeatBalFanSys->TempControlType.dimension(NumOfZones, HVAC::ThermostatType::Uncontrolled); + state.dataHeatBalFanSys->TempControlTypeRpt.dimension(NumOfZones, 0); if (state.dataZoneCtrls->NumComfortControlledZones > 0) { state.dataHeatBalFanSys->ComfortControlType.dimension(NumOfZones, HVAC::ThermostatType::Uncontrolled); state.dataHeatBalFanSys->ComfortControlTypeRpt.dimension(NumOfZones, 0); @@ -2848,9 +2781,9 @@ void InitZoneAirSetPoints(EnergyPlusData &state) } for (int zoneNum = 1; zoneNum <= NumOfZones; ++zoneNum) { - FirstSurfFlag = true; + bool FirstSurfFlag = true; for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { - auto &thisSpace = state.dataHeatBal->space(spaceNum); + auto const &thisSpace = state.dataHeatBal->space(spaceNum); for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { if (FirstSurfFlag) { TRefFlag = state.dataSurface->SurfTAirRef(SurfNum); @@ -2915,21 +2848,21 @@ void InitZoneAirSetPoints(EnergyPlusData &state) SetupOutputVariable(state, "Zone Thermostat Control Type", Constant::Units::None, - TempControlTypeRpt(zoneNum), + state.dataHeatBalFanSys->TempControlTypeRpt(zoneNum), OutputProcessor::TimeStepType::Zone, OutputProcessor::StoreType::Average, thisZone.Name); SetupOutputVariable(state, "Zone Thermostat Heating Setpoint Temperature", Constant::Units::C, - ZoneThermostatSetPointLo(zoneNum), + state.dataHeatBalFanSys->ZoneThermostatSetPointLo(zoneNum), OutputProcessor::TimeStepType::System, OutputProcessor::StoreType::Average, thisZone.Name); SetupOutputVariable(state, "Zone Thermostat Cooling Setpoint Temperature", Constant::Units::C, - ZoneThermostatSetPointHi(zoneNum), + state.dataHeatBalFanSys->ZoneThermostatSetPointHi(zoneNum), OutputProcessor::TimeStepType::System, OutputProcessor::StoreType::Average, thisZone.Name); @@ -2953,7 +2886,7 @@ void InitZoneAirSetPoints(EnergyPlusData &state) if (state.dataZoneCtrls->NumComfortControlledZones > 0) { // CurrentModuleObject='ZoneControl:Thermostat:ThermalComfort' for (int Loop = 1; Loop <= state.dataZoneCtrls->NumComfortControlledZones; ++Loop) { - int zoneNum = ComfortControlledZone(Loop).ActualZoneNum; + int zoneNum = state.dataZoneCtrls->ComfortControlledZone(Loop).ActualZoneNum; auto &thisZone = state.dataHeatBal->Zone(zoneNum); SetupOutputVariable(state, "Zone Thermal Comfort Control Type", @@ -2981,66 +2914,68 @@ void InitZoneAirSetPoints(EnergyPlusData &state) // CurrentModuleObject='ZoneList' for (int Loop = 1; Loop <= state.dataHeatBal->NumOfZoneLists; ++Loop) { + auto &zoneList = state.dataHeatBal->ZoneList(Loop); SetupOutputVariable(state, "Zone List Sensible Heating Energy", Constant::Units::J, state.dataHeatBal->ZoneListSNLoadHeatEnergy(Loop), OutputProcessor::TimeStepType::System, OutputProcessor::StoreType::Sum, - ZoneList(Loop).Name); + zoneList.Name); SetupOutputVariable(state, "Zone List Sensible Cooling Energy", Constant::Units::J, state.dataHeatBal->ZoneListSNLoadCoolEnergy(Loop), OutputProcessor::TimeStepType::System, OutputProcessor::StoreType::Sum, - ZoneList(Loop).Name); + zoneList.Name); SetupOutputVariable(state, "Zone List Sensible Heating Rate", Constant::Units::W, state.dataHeatBal->ZoneListSNLoadHeatRate(Loop), OutputProcessor::TimeStepType::System, OutputProcessor::StoreType::Average, - ZoneList(Loop).Name); + zoneList.Name); SetupOutputVariable(state, "Zone List Sensible Cooling Rate", Constant::Units::W, state.dataHeatBal->ZoneListSNLoadCoolRate(Loop), OutputProcessor::TimeStepType::System, OutputProcessor::StoreType::Average, - ZoneList(Loop).Name); + zoneList.Name); } // Loop // CurrentModuleObject='ZoneGroup' for (int Loop = 1; Loop <= state.dataHeatBal->NumOfZoneGroups; ++Loop) { + auto &zoneGroup = state.dataHeatBal->ZoneGroup(Loop); SetupOutputVariable(state, "Zone Group Sensible Heating Energy", Constant::Units::J, state.dataHeatBal->ZoneGroupSNLoadHeatEnergy(Loop), OutputProcessor::TimeStepType::System, OutputProcessor::StoreType::Sum, - state.dataHeatBal->ZoneGroup(Loop).Name); + zoneGroup.Name); SetupOutputVariable(state, "Zone Group Sensible Cooling Energy", Constant::Units::J, state.dataHeatBal->ZoneGroupSNLoadCoolEnergy(Loop), OutputProcessor::TimeStepType::System, OutputProcessor::StoreType::Sum, - state.dataHeatBal->ZoneGroup(Loop).Name); + zoneGroup.Name); SetupOutputVariable(state, "Zone Group Sensible Heating Rate", Constant::Units::W, state.dataHeatBal->ZoneGroupSNLoadHeatRate(Loop), OutputProcessor::TimeStepType::System, OutputProcessor::StoreType::Average, - state.dataHeatBal->ZoneGroup(Loop).Name); + zoneGroup.Name); SetupOutputVariable(state, "Zone Group Sensible Cooling Rate", Constant::Units::W, state.dataHeatBal->ZoneGroupSNLoadCoolRate(Loop), OutputProcessor::TimeStepType::System, OutputProcessor::StoreType::Average, - state.dataHeatBal->ZoneGroup(Loop).Name); + zoneGroup.Name); } // Loop state.dataZoneTempPredictorCorrector->InitZoneAirSetPointsOneTimeFlag = false; @@ -3056,13 +2991,13 @@ void InitZoneAirSetPoints(EnergyPlusData &state) thisSpaceHB.beginEnvironmentInit(state); } } - TempZoneThermostatSetPoint = 0.0; + state.dataHeatBalFanSys->TempZoneThermostatSetPoint = 0.0; state.dataHeatBalFanSys->AdapComfortCoolingSetPoint = 0.0; - ZoneThermostatSetPointHi = 0.0; - ZoneThermostatSetPointLo = 0.0; + state.dataHeatBalFanSys->ZoneThermostatSetPointHi = 0.0; + state.dataHeatBalFanSys->ZoneThermostatSetPointLo = 0.0; state.dataHeatBalFanSys->LoadCorrectionFactor = 1.0; - TempControlType = HVAC::ThermostatType::Uncontrolled; + state.dataHeatBalFanSys->TempControlType = HVAC::ThermostatType::Uncontrolled; for (auto &e : state.dataZoneEnergyDemand->ZoneSysEnergyDemand) { e.beginEnvironmentInit(); } @@ -3106,53 +3041,56 @@ void InitZoneAirSetPoints(EnergyPlusData &state) } for (int Loop = 1; Loop <= state.dataZoneCtrls->NumTempControlledZones; ++Loop) { + auto &tempControlledZone = state.dataZoneCtrls->TempControlledZone(Loop); if (state.dataZoneEquip->ZoneEquipInputsFilled && !state.dataZoneTempPredictorCorrector->ControlledZonesChecked) { - if (!VerifyControlledZoneForThermostat(state, TempControlledZone(Loop).ZoneName)) { + if (!VerifyControlledZoneForThermostat(state, tempControlledZone.ZoneName)) { ShowSevereError(state, format("{}Zone=\"{}\" has specified a Thermostatic control but is not a controlled zone.", RoutineName, - TempControlledZone(Loop).ZoneName)); + tempControlledZone.ZoneName)); ShowContinueError(state, "...must have a ZoneHVAC:EquipmentConnections specification for this zone."); state.dataZoneTempPredictorCorrector->ErrorsFound = true; } } - if (TempControlledZone(Loop).ManageDemand) { - int ZoneNum = TempControlledZone(Loop).ActualZoneNum; + if (tempControlledZone.ManageDemand) { + int ZoneNum = tempControlledZone.ActualZoneNum; + auto &zoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum); + auto &zoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum); + auto &tempZoneThermostatSetPoint = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum); + auto &tempControlType = state.dataHeatBalFanSys->TempControlType(ZoneNum); - switch (TempControlType(ZoneNum)) { + switch (tempControlType) { case HVAC::ThermostatType::SingleHeating: - if (TempZoneThermostatSetPoint(ZoneNum) > TempControlledZone(Loop).HeatingResetLimit) { - TempZoneThermostatSetPoint(ZoneNum) = TempControlledZone(Loop).HeatingResetLimit; - ZoneThermostatSetPointLo(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); + if (tempZoneThermostatSetPoint > tempControlledZone.HeatingResetLimit) { + tempZoneThermostatSetPoint = tempControlledZone.HeatingResetLimit; + zoneThermostatSetPointLo = tempZoneThermostatSetPoint; } break; case HVAC::ThermostatType::SingleCooling: - if (TempZoneThermostatSetPoint(ZoneNum) < TempControlledZone(Loop).CoolingResetLimit) { - TempZoneThermostatSetPoint(ZoneNum) = TempControlledZone(Loop).CoolingResetLimit; - ZoneThermostatSetPointHi(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); + if (tempZoneThermostatSetPoint < tempControlledZone.CoolingResetLimit) { + tempZoneThermostatSetPoint = tempControlledZone.CoolingResetLimit; + zoneThermostatSetPointHi = tempZoneThermostatSetPoint; } break; case HVAC::ThermostatType::SingleHeatCool: - if ((TempZoneThermostatSetPoint(ZoneNum) > TempControlledZone(Loop).HeatingResetLimit) || - (TempZoneThermostatSetPoint(ZoneNum) < TempControlledZone(Loop).CoolingResetLimit)) { + if ((tempZoneThermostatSetPoint > tempControlledZone.HeatingResetLimit) || + (tempZoneThermostatSetPoint < tempControlledZone.CoolingResetLimit)) { - TempControlType(ZoneNum) = HVAC::ThermostatType::DualSetPointWithDeadBand; - TempControlTypeRpt(ZoneNum) = static_cast(TempControlType(ZoneNum)); - ZoneThermostatSetPointLo(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); - ZoneThermostatSetPointHi(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); + tempControlType = HVAC::ThermostatType::DualSetPointWithDeadBand; + state.dataHeatBalFanSys->TempControlTypeRpt(ZoneNum) = static_cast(tempControlType); + zoneThermostatSetPointLo = tempZoneThermostatSetPoint; + zoneThermostatSetPointHi = tempZoneThermostatSetPoint; - if (ZoneThermostatSetPointLo(ZoneNum) > TempControlledZone(Loop).HeatingResetLimit) - ZoneThermostatSetPointLo(ZoneNum) = TempControlledZone(Loop).HeatingResetLimit; - if (ZoneThermostatSetPointHi(ZoneNum) < TempControlledZone(Loop).CoolingResetLimit) - ZoneThermostatSetPointHi(ZoneNum) = TempControlledZone(Loop).CoolingResetLimit; + if (zoneThermostatSetPointLo > tempControlledZone.HeatingResetLimit) + zoneThermostatSetPointLo = tempControlledZone.HeatingResetLimit; + if (zoneThermostatSetPointHi < tempControlledZone.CoolingResetLimit) + zoneThermostatSetPointHi = tempControlledZone.CoolingResetLimit; } break; case HVAC::ThermostatType::DualSetPointWithDeadBand: - if (ZoneThermostatSetPointLo(ZoneNum) > TempControlledZone(Loop).HeatingResetLimit) - ZoneThermostatSetPointLo(ZoneNum) = TempControlledZone(Loop).HeatingResetLimit; - if (ZoneThermostatSetPointHi(ZoneNum) < TempControlledZone(Loop).CoolingResetLimit) - ZoneThermostatSetPointHi(ZoneNum) = TempControlledZone(Loop).CoolingResetLimit; + if (zoneThermostatSetPointLo > tempControlledZone.HeatingResetLimit) zoneThermostatSetPointLo = tempControlledZone.HeatingResetLimit; + if (zoneThermostatSetPointHi < tempControlledZone.CoolingResetLimit) zoneThermostatSetPointHi = tempControlledZone.CoolingResetLimit; break; default: break; @@ -3161,58 +3099,64 @@ void InitZoneAirSetPoints(EnergyPlusData &state) } for (int Loop = 1; Loop <= state.dataZoneCtrls->NumComfortControlledZones; ++Loop) { + auto &comfortControlledZone = state.dataZoneCtrls->ComfortControlledZone(Loop); if (state.dataZoneEquip->ZoneEquipInputsFilled && !state.dataZoneTempPredictorCorrector->ControlledZonesChecked) { - if (!VerifyControlledZoneForThermostat(state, ComfortControlledZone(Loop).ZoneName)) { + if (!VerifyControlledZoneForThermostat(state, comfortControlledZone.ZoneName)) { ShowSevereError(state, format("{}Zone=\"{}\" has specified a Comfort control but is not a controlled zone.", RoutineName, - ComfortControlledZone(Loop).ZoneName)); + comfortControlledZone.ZoneName)); ShowContinueError(state, "...must have a ZoneHVAC:EquipmentConnections specification for this zone."); state.dataZoneTempPredictorCorrector->ErrorsFound = true; } } - if (ComfortControlledZone(Loop).ManageDemand) { - int ZoneNum = ComfortControlledZone(Loop).ActualZoneNum; + if (comfortControlledZone.ManageDemand) { + int ZoneNum = comfortControlledZone.ActualZoneNum; + auto &zoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum); + auto &zoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum); + auto &tempZoneThermostatSetPoint = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum); + auto &tempControlTypeRpt = state.dataHeatBalFanSys->TempControlTypeRpt(ZoneNum); + auto &tempControlType = state.dataHeatBalFanSys->TempControlType(ZoneNum); switch (state.dataHeatBalFanSys->ComfortControlType(ZoneNum)) { case HVAC::ThermostatType::SingleHeating: - if (TempZoneThermostatSetPoint(ZoneNum) >= ComfortControlledZone(Loop).HeatingResetLimit) { - TempZoneThermostatSetPoint(ZoneNum) = ComfortControlledZone(Loop).HeatingResetLimit; - ZoneThermostatSetPointLo(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); - TempControlType(ZoneNum) = HVAC::ThermostatType::SingleHeating; - TempControlTypeRpt(ZoneNum) = static_cast(TempControlType(ZoneNum)); + if (tempZoneThermostatSetPoint >= comfortControlledZone.HeatingResetLimit) { + tempZoneThermostatSetPoint = comfortControlledZone.HeatingResetLimit; + zoneThermostatSetPointLo = tempZoneThermostatSetPoint; + tempControlType = HVAC::ThermostatType::SingleHeating; + tempControlTypeRpt = static_cast(tempControlType); } break; case HVAC::ThermostatType::SingleCooling: - if (TempZoneThermostatSetPoint(ZoneNum) <= ComfortControlledZone(Loop).CoolingResetLimit) { - TempZoneThermostatSetPoint(ZoneNum) = ComfortControlledZone(Loop).CoolingResetLimit; - ZoneThermostatSetPointHi(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); - TempControlType(ZoneNum) = HVAC::ThermostatType::SingleCooling; - TempControlTypeRpt(ZoneNum) = static_cast(TempControlType(ZoneNum)); + if (tempZoneThermostatSetPoint <= comfortControlledZone.CoolingResetLimit) { + tempZoneThermostatSetPoint = comfortControlledZone.CoolingResetLimit; + zoneThermostatSetPointHi = tempZoneThermostatSetPoint; + tempControlType = HVAC::ThermostatType::SingleCooling; + tempControlTypeRpt = static_cast(tempControlType); } break; case HVAC::ThermostatType::SingleHeatCool: - if ((TempZoneThermostatSetPoint(ZoneNum) >= ComfortControlledZone(Loop).HeatingResetLimit) || - (TempZoneThermostatSetPoint(ZoneNum) <= ComfortControlledZone(Loop).CoolingResetLimit)) { + if ((tempZoneThermostatSetPoint >= comfortControlledZone.HeatingResetLimit) || + (tempZoneThermostatSetPoint <= comfortControlledZone.CoolingResetLimit)) { - TempControlType(ZoneNum) = HVAC::ThermostatType::DualSetPointWithDeadBand; - TempControlTypeRpt(ZoneNum) = static_cast(TempControlType(ZoneNum)); - ZoneThermostatSetPointLo(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); - ZoneThermostatSetPointHi(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); + tempControlType = HVAC::ThermostatType::DualSetPointWithDeadBand; + tempControlTypeRpt = static_cast(tempControlType); + zoneThermostatSetPointLo = tempZoneThermostatSetPoint; + zoneThermostatSetPointHi = tempZoneThermostatSetPoint; - if (ZoneThermostatSetPointLo(ZoneNum) >= ComfortControlledZone(Loop).HeatingResetLimit) - ZoneThermostatSetPointLo(ZoneNum) = ComfortControlledZone(Loop).HeatingResetLimit; - if (ZoneThermostatSetPointHi(ZoneNum) <= ComfortControlledZone(Loop).CoolingResetLimit) - ZoneThermostatSetPointHi(ZoneNum) = ComfortControlledZone(Loop).CoolingResetLimit; + if (zoneThermostatSetPointLo >= comfortControlledZone.HeatingResetLimit) + zoneThermostatSetPointLo = comfortControlledZone.HeatingResetLimit; + if (zoneThermostatSetPointHi <= comfortControlledZone.CoolingResetLimit) + zoneThermostatSetPointHi = comfortControlledZone.CoolingResetLimit; } break; case HVAC::ThermostatType::DualSetPointWithDeadBand: - TempControlType(ZoneNum) = HVAC::ThermostatType::DualSetPointWithDeadBand; - TempControlTypeRpt(ZoneNum) = static_cast(TempControlType(ZoneNum)); - if (ZoneThermostatSetPointLo(ZoneNum) >= ComfortControlledZone(Loop).HeatingResetLimit) - ZoneThermostatSetPointLo(ZoneNum) = ComfortControlledZone(Loop).HeatingResetLimit; - if (ZoneThermostatSetPointHi(ZoneNum) <= ComfortControlledZone(Loop).CoolingResetLimit) - ZoneThermostatSetPointHi(ZoneNum) = ComfortControlledZone(Loop).CoolingResetLimit; + tempControlType = HVAC::ThermostatType::DualSetPointWithDeadBand; + tempControlTypeRpt = static_cast(tempControlType); + if (zoneThermostatSetPointLo >= comfortControlledZone.HeatingResetLimit) + zoneThermostatSetPointLo = comfortControlledZone.HeatingResetLimit; + if (zoneThermostatSetPointHi <= comfortControlledZone.CoolingResetLimit) + zoneThermostatSetPointHi = comfortControlledZone.CoolingResetLimit; break; default: break; @@ -3326,7 +3270,7 @@ void PredictSystemLoads(EnergyPlusData &state, for (int RelativeZoneNum = 1; RelativeZoneNum <= state.dataZoneTempPredictorCorrector->NumStageCtrZone; ++RelativeZoneNum) { auto &thisStageControlZone = state.dataZoneCtrls->StageControlledZone(RelativeZoneNum); int ActualZoneNum = thisStageControlZone.ActualZoneNum; - auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ActualZoneNum); + auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ActualZoneNum); auto &thisZoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ActualZoneNum); auto &thisZoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ActualZoneNum); Real64 ZoneT = thisZoneHB.MAT; // Zone temperature at previous time step @@ -3412,7 +3356,7 @@ void PredictSystemLoads(EnergyPlusData &state, thisTempControlledZone.CoolModeLastSave = thisTempControlledZone.CoolModeLast; } auto &thisTempZoneThermostatSetPoint = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(thisTempControlledZone.ActualZoneNum); - auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisTempControlledZone.ActualZoneNum); + auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisTempControlledZone.ActualZoneNum); auto &thisZoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(thisTempControlledZone.ActualZoneNum); auto &thisZoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(thisTempControlledZone.ActualZoneNum); @@ -3670,8 +3614,6 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) // SUBROUTINE LOCAL VARIABLE DECLARATIONS: int RelativeZoneNum; - int ActualZoneNum; - int TempControlSchedIndex; int SetPointTempSchedIndexHot; int SetPointTempSchedIndexCold; int SchedNameIndex; @@ -3704,8 +3646,8 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) for (RelativeZoneNum = 1; RelativeZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++RelativeZoneNum) { // What if this zone not controlled??? - ActualZoneNum = TempControlledZone(RelativeZoneNum).ActualZoneNum; - TempControlSchedIndex = TempControlledZone(RelativeZoneNum).CTSchedIndex; + int ActualZoneNum = TempControlledZone(RelativeZoneNum).ActualZoneNum; + int TempControlSchedIndex = TempControlledZone(RelativeZoneNum).CTSchedIndex; TempControlType(ActualZoneNum) = static_cast(ScheduleManager::GetCurrentScheduleValue(state, TempControlSchedIndex)); TempControlTypeRpt(ActualZoneNum) = static_cast(TempControlType(ActualZoneNum)); // Error detection for these values is done in the Get routine @@ -3841,8 +3783,8 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) if (ScheduleManager::GetCurrentScheduleValue(state, state.dataFaultsMgr->FaultsThermostatOffset(iFault).availSchedNum) > 0.0) { // Check fault severity schedules to update the reference thermostat offset - double rSchVal = 1.0; - double offsetUpdated; + Real64 rSchVal = 1.0; + Real64 offsetUpdated; if (state.dataFaultsMgr->FaultsThermostatOffset(iFault).severitySchedNum >= 0) { rSchVal = ScheduleManager::GetCurrentScheduleValue(state, state.dataFaultsMgr->FaultsThermostatOffset(iFault).severitySchedNum); @@ -3922,11 +3864,7 @@ void ZoneSpaceHeatBalanceData::calcPredictedHumidityRatio(EnergyPlusData &state, // For Humidistat Offset Type I: ThermostatOffsetDependent bool IsThermostatFound = false; - double offsetThermostat = 0.0; - double offsetZoneRHHumidifyingSetPoint = 0.0; - double offsetZoneRHDehumidifyingSetPoint = 0.0; - double faultZoneWHumidifyingSetPoint; - double faultZoneWDehumidifyingSetPoint; + Real64 offsetThermostat = 0.0; // Get the offset value of the corresponding thermostat fault object if (state.dataFaultsMgr->NumFaultyThermostat > 0) { @@ -3943,7 +3881,7 @@ void ZoneSpaceHeatBalanceData::calcPredictedHumidityRatio(EnergyPlusData &state, state, state.dataFaultsMgr->FaultsThermostatOffset(iFaultThermo).availSchedNum) > 0.0) { // Check fault severity schedules to update the reference thermostat offset - double rSchVal = 1.0; + Real64 rSchVal = 1.0; if (state.dataFaultsMgr->FaultsThermostatOffset(iFaultThermo).severitySchedNum >= 0) { rSchVal = ScheduleManager::GetCurrentScheduleValue( state, state.dataFaultsMgr->FaultsThermostatOffset(iFaultThermo).severitySchedNum); @@ -3969,14 +3907,14 @@ void ZoneSpaceHeatBalanceData::calcPredictedHumidityRatio(EnergyPlusData &state, if (offsetThermostat != 0.0) { // Calculate the humidistat offset value from the thermostat offset value - faultZoneWHumidifyingSetPoint = Psychrometrics::PsyWFnTdbRhPb( + Real64 faultZoneWHumidifyingSetPoint = Psychrometrics::PsyWFnTdbRhPb( state, (this->MAT + offsetThermostat), (ZoneRHHumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress); - faultZoneWDehumidifyingSetPoint = Psychrometrics::PsyWFnTdbRhPb( + Real64 faultZoneWDehumidifyingSetPoint = Psychrometrics::PsyWFnTdbRhPb( state, (this->MAT + offsetThermostat), (ZoneRHDehumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress); - offsetZoneRHHumidifyingSetPoint = + Real64 offsetZoneRHHumidifyingSetPoint = ZoneRHHumidifyingSetPoint - Psychrometrics::PsyRhFnTdbWPb(state, this->MAT, faultZoneWHumidifyingSetPoint, state.dataEnvrn->OutBaroPress) * 100.0; - offsetZoneRHDehumidifyingSetPoint = + Real64 offsetZoneRHDehumidifyingSetPoint = ZoneRHDehumidifyingSetPoint - Psychrometrics::PsyRhFnTdbWPb(state, this->MAT, faultZoneWDehumidifyingSetPoint, state.dataEnvrn->OutBaroPress) * 100.0; @@ -3999,8 +3937,8 @@ void ZoneSpaceHeatBalanceData::calcPredictedHumidityRatio(EnergyPlusData &state, 0.0) { // Check fault severity schedules to update the reference humidistat offset - double rSchVal = 1.0; - double offsetUpdated; + Real64 rSchVal = 1.0; + Real64 offsetUpdated; if (state.dataFaultsMgr->FaultsHumidistatOffset(iFault).severitySchedNum >= 0) { rSchVal = ScheduleManager::GetCurrentScheduleValue( state, state.dataFaultsMgr->FaultsHumidistatOffset(iFault).severitySchedNum); @@ -4231,7 +4169,7 @@ Real64 correctZoneAirTemps(EnergyPlusData &state, } else { // If doing sizing and zone is controled, then set space node to match zone node if (state.dataHeatBal->doSpaceHeatBalanceSizing && thisZone.IsControlled) { - auto &thisZoneNode = state.dataLoopNodes->Node(thisZone.SystemZoneNodeNumber); + auto const &thisZoneNode = state.dataLoopNodes->Node(thisZone.SystemZoneNodeNumber); auto &thisSpaceNode = state.dataLoopNodes->Node(state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber); thisSpaceNode.Temp = thisZoneNode.Temp; thisSpaceNode.HumRat = thisZoneNode.HumRat; @@ -4374,7 +4312,7 @@ Real64 ZoneSpaceHeatBalanceData::correctAirTemp( } state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = 1.0; } else { - auto &thisAirModel = state.dataRoomAir->AirModel(zoneNum); + auto const &thisAirModel = state.dataRoomAir->AirModel(zoneNum); if ((thisAirModel.AirModel == RoomAir::RoomAirModel::Mixing) || (!thisAirModel.SimAirModel)) { // Fully mixed thisSystemNode.Temp = this->ZT; @@ -4848,7 +4786,7 @@ void ZoneSpaceHeatBalanceData::correctHumRat(EnergyPlusData &state, int const zo auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(zoneNum); // Calculate moisture flow rate into each zone for (int NodeNum = 1; NodeNum <= zoneEquipConfig.NumInletNodes; ++NodeNum) { - auto &inletNode = state.dataLoopNodes->Node(zoneEquipConfig.InletNode(NodeNum)); + auto const &inletNode = state.dataLoopNodes->Node(zoneEquipConfig.InletNode(NodeNum)); MoistureMassFlowRate += (inletNode.MassFlowRate * inletNode.HumRat) / ZoneMult; ZoneMassFlowRate += inletNode.MassFlowRate / ZoneMult; } @@ -4858,14 +4796,14 @@ void ZoneSpaceHeatBalanceData::correctHumRat(EnergyPlusData &state, int const zo int ZoneRetPlenumNum = zone.PlenumCondNum; auto &zoneRetPlenCond = state.dataZonePlenum->ZoneRetPlenCond(ZoneRetPlenumNum); for (int NodeNum = 1; NodeNum <= zoneRetPlenCond.NumInletNodes; ++NodeNum) { - auto &inletNode = state.dataLoopNodes->Node(zoneRetPlenCond.InletNode(NodeNum)); + auto const &inletNode = state.dataLoopNodes->Node(zoneRetPlenCond.InletNode(NodeNum)); MoistureMassFlowRate += (inletNode.MassFlowRate * inletNode.HumRat) / ZoneMult; ZoneMassFlowRate += inletNode.MassFlowRate / ZoneMult; } // add in the leak flow for (int ADUListIndex = 1; ADUListIndex <= zoneRetPlenCond.NumADUs; ++ADUListIndex) { int ADUNum = zoneRetPlenCond.ADUIndex(ADUListIndex); - auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(ADUNum); + auto const &airDistUnit = state.dataDefineEquipment->AirDistUnit(ADUNum); if (airDistUnit.UpStreamLeak) { int ADUInNode = airDistUnit.InletNodeNum; MoistureMassFlowRate += (airDistUnit.MassFlowRateUpStrLk * state.dataLoopNodes->Node(ADUInNode).HumRat) / ZoneMult; @@ -4880,7 +4818,7 @@ void ZoneSpaceHeatBalanceData::correctHumRat(EnergyPlusData &state, int const zo } else if (ZoneSupPlenumAirFlag) { int ZoneSupPlenumNum = zone.PlenumCondNum; - auto &inletNode = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneSupPlenCond(ZoneSupPlenumNum).InletNode); + auto const &inletNode = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneSupPlenCond(ZoneSupPlenumNum).InletNode); MoistureMassFlowRate += (inletNode.MassFlowRate * inletNode.HumRat) / ZoneMult; ZoneMassFlowRate += inletNode.MassFlowRate / ZoneMult; } @@ -4905,7 +4843,7 @@ void ZoneSpaceHeatBalanceData::correctHumRat(EnergyPlusData &state, int const zo if (state.afn->multizone_always_simulated || (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation && state.afn->AirflowNetworkFanActivated)) { - auto &exchangeData = state.afn->exchangeData(zoneNum); + auto const &exchangeData = state.afn->exchangeData(zoneNum); // Multizone airflow calculated in AirflowNetwork B = (LatentGain / H2OHtOfVap) + (exchangeData.SumMHrW + exchangeData.SumMMHrW) + (MoistureMassFlowRate) + this->SumHmARaW; A = ZoneMassFlowRate + exchangeData.SumMHr + exchangeData.SumMMHr + this->SumHmARa; @@ -5571,7 +5509,7 @@ void ZoneSpaceHeatBalanceData::calcZoneOrSpaceSums(EnergyPlusData &state, if (state.afn->multizone_always_simulated || (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation && state.afn->AirflowNetworkFanActivated)) { - auto &exchangeData = state.afn->exchangeData(zoneNum); + auto const &exchangeData = state.afn->exchangeData(zoneNum); this->SumMCp = exchangeData.SumMCp + exchangeData.SumMVCp + exchangeData.SumMMCp; this->SumMCpT = exchangeData.SumMCpT + exchangeData.SumMVCpT + exchangeData.SumMMCpT; } @@ -5907,7 +5845,7 @@ void CalcZoneComponentLoadSums(EnergyPlusData &state, // Sum all surface convection: SumHA, SumHATsurf, SumHATref (and additional contributions to SumIntGain) for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { - auto &thisSpace = state.dataHeatBal->space(spaceNum); + auto const &thisSpace = state.dataHeatBal->space(spaceNum); for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { Real64 Area = state.dataSurface->Surface(SurfNum).Area; // For windows, this is the glazing area @@ -6252,7 +6190,7 @@ void AdjustOperativeSetPointsforAdapComfort(EnergyPlusData &state, int const Tem // This routine adjust the operative setpoints for each controlled adaptive thermal comfort models. auto &tempControlledZone = state.dataZoneCtrls->TempControlledZone(TempControlledZoneID); - auto &AdapComfortDailySetPointSchedule = state.dataZoneTempPredictorCorrector->AdapComfortDailySetPointSchedule; + auto const &AdapComfortDailySetPointSchedule = state.dataZoneTempPredictorCorrector->AdapComfortDailySetPointSchedule; // SUBROUTINE LOCAL VARIABLE DECLARATIONS: int originZoneAirSetPoint = ZoneAirSetPoint; @@ -6320,11 +6258,11 @@ void CalcZoneAirComfortSetPoints(EnergyPlusData &state) Real64 SetPointLo = 0.0; Real64 SetPointHi = 0.0; Real64 Tset = 0.0; - int PeopleNum = 0; int ObjectCount = 0; Real64 PeopleCount = 0.0; int SetPointComfortSchedIndex = 0; int SchedTypeIndex = 0; + int PeopleNum; // Call thermal comfort module to read zone control comfort object if (state.dataZoneTempPredictorCorrector->CalcZoneAirComfortSetPointsFirstTimeFlag) { @@ -6440,13 +6378,13 @@ void CalcZoneAirComfortSetPoints(EnergyPlusData &state) case DataZoneControls::AverageMethod::OBJ: SetPointLo = 0.0; SetPointHi = 0.0; - for (int PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) { - if (ActualZoneNum == state.dataHeatBal->People(PeopleNum).ZonePtr) { + for (int peopleNum = 1; peopleNum <= state.dataHeatBal->TotPeople; ++peopleNum) { + if (ActualZoneNum == state.dataHeatBal->People(peopleNum).ZonePtr) { ++ObjectCount; - GetComfortSetPoints(state, PeopleNum, RelativeZoneNum, zoneComfortControlsFanger.LowPMV, Tset); + GetComfortSetPoints(state, peopleNum, RelativeZoneNum, zoneComfortControlsFanger.LowPMV, Tset); SetPointLo += Tset; if (comfortControlType == HVAC::ThermostatType::DualSetPointWithDeadBand) { - GetComfortSetPoints(state, PeopleNum, RelativeZoneNum, zoneComfortControlsFanger.HighPMV, Tset); + GetComfortSetPoints(state, peopleNum, RelativeZoneNum, zoneComfortControlsFanger.HighPMV, Tset); SetPointHi += Tset; } } @@ -6457,15 +6395,15 @@ void CalcZoneAirComfortSetPoints(EnergyPlusData &state) case DataZoneControls::AverageMethod::PEO: SetPointLo = 0.0; SetPointHi = 0.0; - for (int PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) { - if (ActualZoneNum == state.dataHeatBal->People(PeopleNum).ZonePtr) { - int NumberOccupants = state.dataHeatBal->People(PeopleNum).NumberOfPeople * - ScheduleManager::GetCurrentScheduleValue(state, state.dataHeatBal->People(PeopleNum).NumberOfPeoplePtr); + for (int peopleNum = 1; peopleNum <= state.dataHeatBal->TotPeople; ++peopleNum) { + if (ActualZoneNum == state.dataHeatBal->People(peopleNum).ZonePtr) { + int NumberOccupants = state.dataHeatBal->People(peopleNum).NumberOfPeople * + ScheduleManager::GetCurrentScheduleValue(state, state.dataHeatBal->People(peopleNum).NumberOfPeoplePtr); PeopleCount += NumberOccupants; - GetComfortSetPoints(state, PeopleNum, RelativeZoneNum, zoneComfortControlsFanger.LowPMV, Tset); + GetComfortSetPoints(state, peopleNum, RelativeZoneNum, zoneComfortControlsFanger.LowPMV, Tset); SetPointLo += Tset * NumberOccupants; if (comfortControlType == HVAC::ThermostatType::DualSetPointWithDeadBand) { - GetComfortSetPoints(state, PeopleNum, RelativeZoneNum, zoneComfortControlsFanger.HighPMV, Tset); + GetComfortSetPoints(state, peopleNum, RelativeZoneNum, zoneComfortControlsFanger.HighPMV, Tset); SetPointHi += Tset * NumberOccupants; } } @@ -6490,13 +6428,13 @@ void CalcZoneAirComfortSetPoints(EnergyPlusData &state) PeopleCount); SetPointLo = 0.0; SetPointHi = 0.0; - for (int PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) { - if (ActualZoneNum == state.dataHeatBal->People(PeopleNum).ZonePtr) { + for (int peopleNum = 1; peopleNum <= state.dataHeatBal->TotPeople; ++peopleNum) { + if (ActualZoneNum == state.dataHeatBal->People(peopleNum).ZonePtr) { ++ObjectCount; - GetComfortSetPoints(state, PeopleNum, RelativeZoneNum, zoneComfortControlsFanger.LowPMV, Tset); + GetComfortSetPoints(state, peopleNum, RelativeZoneNum, zoneComfortControlsFanger.LowPMV, Tset); SetPointLo += Tset; if (comfortControlType == HVAC::ThermostatType::DualSetPointWithDeadBand) { - GetComfortSetPoints(state, PeopleNum, RelativeZoneNum, zoneComfortControlsFanger.HighPMV, Tset); + GetComfortSetPoints(state, peopleNum, RelativeZoneNum, zoneComfortControlsFanger.HighPMV, Tset); SetPointHi += Tset; } } @@ -6675,7 +6613,6 @@ void GetComfortSetPoints(EnergyPlusData &state, // SUBROUTINE LOCAL VARIABLE DECLARATIONS: Real64 PMVResult = 0.0; // Calculated PMV value - int SolFla = 0; // feed back flag from SolveRoot auto &comfortControlledZone = state.dataZoneCtrls->ComfortControlledZone(ComfortControlNum); Real64 Tmin = comfortControlledZone.TdbMinSetPoint; @@ -6693,6 +6630,7 @@ void GetComfortSetPoints(EnergyPlusData &state, return (PMVSet - PMVresult); }; + int SolFla = 0; // feed back flag from SolveRoot General::SolveRoot(state, Acc, MaxIter, SolFla, Tset, f, Tmin, Tmax); if (SolFla == -1) { if (!state.dataGlobal->WarmupFlag) { @@ -6791,7 +6729,7 @@ void OverrideAirSetPointsforEMSCntrl(EnergyPlusData &state) auto &ZoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi; for (int Loop = 1; Loop <= state.dataZoneCtrls->NumTempControlledZones; ++Loop) { - auto &tempControlledZone = state.dataZoneCtrls->TempControlledZone(Loop); + auto const &tempControlledZone = state.dataZoneCtrls->TempControlledZone(Loop); if (tempControlledZone.EMSOverrideHeatingSetPointOn) { int ZoneNum = tempControlledZone.ActualZoneNum; @@ -7313,8 +7251,10 @@ void ZoneSpaceHeatBalanceData::calcPredictedSystemLoad(EnergyPlusData &state, Re } } ZoneSetPoint = thisTempZoneThermostatSetPoint; - if (RAFNFrac > 0.0) LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; - if (RAFNFrac > 0.0) LoadToCoolingSetPoint = LoadToCoolingSetPoint / RAFNFrac; + if (RAFNFrac > 0.0) { + LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; + LoadToCoolingSetPoint = LoadToCoolingSetPoint / RAFNFrac; + } if (thisZone.HasAdjustedReturnTempByITE && !(state.dataGlobal->BeginSimFlag)) { LoadToCoolingSetPoint = this->tempDepLoad * thisZone.AdjustedReturnTempByITE - this->tempIndLoad; @@ -7399,8 +7339,10 @@ void ZoneSpaceHeatBalanceData::calcPredictedSystemLoad(EnergyPlusData &state, Re assert(false); } } - if (RAFNFrac > 0.0) LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; - if (RAFNFrac > 0.0) LoadToCoolingSetPoint = LoadToCoolingSetPoint / RAFNFrac; + if (RAFNFrac > 0.0) { // several of these inside the switch/case ?? + LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; + LoadToCoolingSetPoint = LoadToCoolingSetPoint / RAFNFrac; + } if (thisZone.HasAdjustedReturnTempByITE && !(state.dataGlobal->BeginSimFlag)) { LoadToCoolingSetPoint = this->tempDepLoad * thisZone.AdjustedReturnTempByITE - this->tempIndLoad; diff --git a/tst/EnergyPlus/unit/AirflowNetworkHVAC.unit.cc b/tst/EnergyPlus/unit/AirflowNetworkHVAC.unit.cc index 00ecff66806..54e70f64c19 100644 --- a/tst/EnergyPlus/unit/AirflowNetworkHVAC.unit.cc +++ b/tst/EnergyPlus/unit/AirflowNetworkHVAC.unit.cc @@ -19669,7 +19669,8 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_ZoneOrderTest) " NodeList,", " Zone Inlet Nodes_unit1, !- Name", - " Zone Inlet Node_unit1; !- Node 1 Name", + " Dehumidifier Outlet Node,", + " Zone Inlet Node_unit1;", " ZoneHVAC:EquipmentList,", " ZoneEquipment_unit1, !- Name", @@ -19685,13 +19686,19 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_ZoneOrderTest) " 2, !- Zone Equipment 2 Cooling Sequence", " 2, !- Zone Equipment 2 Heating or No-Load Sequence", " , !- Zone Equipment 2 Sequential Cooling Fraction Schedule Name", - " ; !- Zone Equipment 2 Sequential Heating Fraction Schedule Name", + " , !- Zone Equipment 2 Sequential Heating Fraction Schedule Name", + " ZoneHVAC:Dehumidifier:DX, !- Zone Equipment 3 Object Type", + " North Zone Dehumidifier !- Zone Equipment 3 Name", + " 3, !- Zone Equipment 3 Cooling Sequence", + " 3, !- Zone Equipment 3 Heating or No-Load Sequence", + " , !- Zone Equipment 3 Sequential Cooling Fraction Schedule Name", + " ; !- Zone Equipment 3 Sequential Heating Fraction Schedule Name", " ZoneHVAC:EquipmentConnections,", " living_unit1, !- Zone Name", " ZoneEquipment_unit1, !- Zone Conditioning Equipment List Name", " zone inlet nodes_unit1, !- Zone Air Inlet Node or NodeList Name", - " Zone Exhaust Node_unit1, !- Zone Air Exhaust Node or NodeList Name", + " Zone Exhaust Node_unit1 Nodes, !- Zone Air Exhaust Node or NodeList Name", " Zone Node_unit1, !- Zone Air Node Name", " Zone Outlet Node_unit1; !- Zone Return Air Node or NodeList Name", @@ -19754,6 +19761,60 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_ZoneOrderTest) " CommaAndHTML, !- Column Separator", " InchPound; !- Unit Conversion", + " NodeList,", + " Zone Exhaust Node_unit1 Nodes,", + " Zone3DehumidifierInlet,", + " Zone Exhaust Node_unit1;", + + " ZoneHVAC:Dehumidifier:DX,", + " North Zone Dehumidifier, !- Name", + " always_avail, !- Availability Schedule Name", + " Zone3DehumidifierInlet, !- Air Inlet Node Name", + " Dehumidifier Outlet Node,!- Air Outlet Node Name", + " 50.16, !- Rated Water Removal {L/day}", + " 3.412, !- Rated Energy Factor {L/kWh}", + " 0.12036, !- Rated Air Flow Rate {m3/s}", + " ZoneDehumidWaterRemoval, !- Water Removal Curve Name", + " ZoneDehumidEnergyFactor, !- Energy Factor Curve Name", + " ZoneDehumidPLFFPLR, !- Part Load Fraction Correlation Curve Name", + " 10.0, !- Minimum Dry-Bulb Temperature for Dehumidifier Operation {C}", + " 32.0, !- Maximum Dry-Bulb Temperature for Dehumidifier Operation {C}", + " 0.0; !- Off-Cycle Parasitic Electric Load {W}", + + " Curve:Biquadratic,", + " ZoneDehumidWaterRemoval, !- Name", + " -2.724878664080, !- Coefficient1 Constant", + " 0.100711983591, !- Coefficient2 x", + " -0.000990538285, !- Coefficient3 x**2", + " 0.050053043874, !- Coefficient4 y", + " -0.000203629282, !- Coefficient5 y**2", + " -0.000341750531, !- Coefficient6 x*y", + " 21.0, !- Minimum Value of x", + " 32.22, !- Maximum Value of x", + " 40.0, !- Minimum Value of y", + " 80.0; !- Maximum Value of y", + + " Curve:Biquadratic,", + " ZoneDehumidEnergyFactor, !- Name", + " -2.388319068955, !- Coefficient1 Constant", + " 0.093047739452, !- Coefficient2 x", + " -0.001369700327, !- Coefficient3 x**2", + " 0.066533716758, !- Coefficient4 y", + " -0.000343198063, !- Coefficient5 y**2", + " -0.000562490295, !- Coefficient6 x*y", + " 21.0, !- Minimum Value of x", + " 32.22, !- Maximum Value of x", + " 40.0, !- Minimum Value of y", + " 80.0; !- Maximum Value of y", + + " Curve:Quadratic,", + " ZoneDehumidPLFFPLR, !- Name", + " 0.95, !- Coefficient1 Constant", + " 0.05, !- Coefficient2 x", + " 0.0, !- Coefficient3 x**2", + " 0.0, !- Minimum Value of x", + " 1.0; !- Maximum Value of x", + }); ASSERT_TRUE(process_idf(idf_objects)); @@ -19768,6 +19829,12 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_ZoneOrderTest) state->afn->AirflowNetworkNodeData(2).EPlusNodeNum = 4; // Attic_Unit1 state->afn->AirflowNetworkNodeData(3).EPlusNodeNum = 0; + + // Check that the validation fails if the AFN exhaust fan is not well setup + int exhaustFanInletNodeIndex = state->afn->MultizoneCompExhaustFanData(1).InletNode; + state->afn->MultizoneCompExhaustFanData(1).InletNode = 6; + state->afn->ValidateExhaustFanInputOneTimeFlag = true; + EXPECT_THROW(state->afn->validate_exhaust_fan_input(), std::runtime_error); } TEST_F(EnergyPlusFixture, AirflowNetwork_TestZoneEqpSupportZoneWindowAC) diff --git a/tst/EnergyPlus/unit/CMakeLists.txt b/tst/EnergyPlus/unit/CMakeLists.txt index 63eaff06bbc..3259c7e9983 100644 --- a/tst/EnergyPlus/unit/CMakeLists.txt +++ b/tst/EnergyPlus/unit/CMakeLists.txt @@ -110,6 +110,7 @@ set(test_src EvaporativeCoolers.unit.cc EvaporativeFluidCoolers.unit.cc ExhaustSystem.unit.cc + ExtendedHI.unit.cc ExteriorEnergyUse.unit.cc FanCoilUnits.unit.cc Fans.unit.cc diff --git a/tst/EnergyPlus/unit/ExtendedHI.unit.cc b/tst/EnergyPlus/unit/ExtendedHI.unit.cc new file mode 100644 index 00000000000..e2a00657cfa --- /dev/null +++ b/tst/EnergyPlus/unit/ExtendedHI.unit.cc @@ -0,0 +1,625 @@ +// EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois, +// The Regents of the University of California, through Lawrence Berkeley National Laboratory +// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge +// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other +// contributors. All rights reserved. +// +// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the +// U.S. Government consequently retains certain rights. As such, the U.S. Government has been +// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, +// worldwide license in the Software to reproduce, distribute copies to the public, prepare +// derivative works, and perform publicly and display publicly, and to permit others to do so. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// (1) Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, +// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific prior +// written permission. +// +// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form +// without changes from the version obtained under this License, or (ii) Licensee makes a +// reference solely to the software portion of its product, Licensee must refer to the +// software as "EnergyPlus version X" software, where "X" is the version number Licensee +// obtained under this License and may not use a different name for the software. Except as +// specifically required in this Section (4), Licensee shall not use in a company name, a +// product name, in advertising, publicity, or other promotional activities any name, trade +// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly +// similar designation, without the U.S. Department of Energy's prior written consent. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// Google Test Headers +#include + +#include +#include +#include +#include + +// EnergyPlus Headers +#include "Fixtures/EnergyPlusFixture.hh" +#include +#include +#include + +using namespace EnergyPlus; +using namespace ExtendedHI; + +TEST_F(EnergyPlusFixture, extendedHI_pvstar) +{ + Real64 tol = 1e-8; + std::vector T_values = {200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370}; + std::vector result = {0.16315953, + 0.70457376, + 2.66392126, + 8.97272134, + 27.31539419, + 76.07472151, + 195.83100376, + 470.03352248, + 991.92542226, + 1920.68015554, + 3538.94082369, + 6235.88791594, + 10554.04916628, + 17222.31477378, + 27187.71571487, + 41643.76611223, + 62053.26405691, + 90163.72448627}; + + for (size_t i = 0; i < T_values.size(); ++i) { + EXPECT_NEAR(ExtendedHI::pvstar(T_values[i]), result[i], tol); + } +} + +TEST_F(EnergyPlusFixture, extendedHI_Le) +{ + Real64 tol = 1e-2; + std::vector T_values = {200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370}; + std::vector result = {2663805.16, + 2641405.16, + 2619005.16, + 2596605.16, + 2574205.16, + 2551805.16, + 2529405.16, + 2507005.16, + 2484605.16, + 2462205.16, + 2439805.16, + 2417405.16, + 2395005.16, + 2372605.16, + 2350205.16, + 2327805.16, + 2305405.16, + 2283005.16}; + for (size_t i = 0; i < T_values.size(); ++i) { + EXPECT_NEAR(ExtendedHI::Le(T_values[i]), result[i], tol); + } +} + +TEST_F(EnergyPlusFixture, extendedHI_Qv) +{ + Real64 tol = 1e-8; + std::vector T_values = {200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370}; + std::vector P_values = {1, 10, 100, 1000, 10000}; + std::vector> result = {{49.94618971, 49.91176799, 49.56755081, 46.12537897, 11.70366056}, + {47.35664275, 47.32222103, 46.97800385, 43.53583201, 9.1141136}, + {44.76709579, 44.73267407, 44.38845689, 40.94628505, 6.52456664}, + {42.17754883, 42.14312711, 41.79890993, 38.35673809, 3.93501968}, + {39.58800187, 39.55358015, 39.20936297, 35.76719113, 1.34547272}, + {36.99845491, 36.96403319, 36.61981601, 33.17764417, -1.24407424}, + {34.40890795, 34.37448623, 34.03026905, 30.58809721, -3.8336212}, + {31.81936099, 31.78493927, 31.44072209, 27.99855025, -6.42316816}, + {29.22981403, 29.19539231, 28.85117513, 25.40900329, -9.01271512}, + {26.64026707, 26.60584535, 26.26162817, 22.81945633, -11.60226208}, + {24.05072011, 24.01629839, 23.67208121, 20.22990937, -14.19180904}, + {21.46117315, 21.42675143, 21.08253425, 17.64036241, -16.781356}, + {18.87162619, 18.83720447, 18.49298729, 15.05081545, -19.37090296}, + {16.28207923, 16.24765751, 15.90344033, 12.46126849, -21.96044992}, + {13.69253227, 13.65811055, 13.31389337, 9.87172153, -24.54999688}, + {11.10298531, 11.06856359, 10.72434641, 7.28217457, -27.13954384}, + {8.51343835, 8.47901663, 8.13479945, 4.69262761, -29.7290908}, + {5.92389139, 5.88946967, 5.54525249, 2.10308065, -32.31863776}}; + for (size_t i = 0; i < T_values.size(); ++i) { + for (size_t j = 0; j < P_values.size(); ++j) { + EXPECT_NEAR(ExtendedHI::Qv(T_values[i], P_values[j]), result[i][j], tol); + } + } +} + +TEST_F(EnergyPlusFixture, extendedHI_Zs) +{ + Real64 tol = 1e-8; + std::vector Rs_values = {0.0387, 0.5, 1, 1.2}; + std::vector result = {52.1, 18750000.0, 600000000.0, 1492991999.9999998}; + for (size_t i = 0; i < Rs_values.size(); ++i) { + EXPECT_NEAR(ExtendedHI::Zs(Rs_values[i]), result[i], tol); + } +} + +TEST_F(EnergyPlusFixture, extendedHI_Ra) +{ + Real64 tol = 1e-8; + std::vector Ts_values = {240, 260, 280, 300, 320, 340, 360}; + std::vector Ta_values = {240, 260, 280, 300, 320, 340, 360}; + std::vector> result = {{0.05003743, 0.04919687, 0.04829495, 0.04733483, 0.04632048, 0.04525658, 0.04414843}, + {0.04919687, 0.04834035, 0.0474255, 0.04645568, 0.045435, 0.0443682, 0.04326057}, + {0.04829495, 0.0474255, 0.04650092, 0.04552473, 0.04450111, 0.04343485, 0.04233118}, + {0.04733483, 0.04645568, 0.04552473, 0.0445456, 0.04352252, 0.04246025, 0.04136396}, + {0.04632048, 0.045435, 0.04450111, 0.04352252, 0.04250345, 0.0414486, 0.04036303}, + {0.04525658, 0.0443682, 0.04343485, 0.04246025, 0.0414486, 0.04040451, 0.03933288}, + {0.04414843, 0.04326057, 0.04233118, 0.04136396, 0.04036303, 0.03933288, 0.03827822}}; + for (size_t i = 0; i < Ts_values.size(); ++i) { + for (size_t j = 0; j < Ta_values.size(); ++j) { + EXPECT_NEAR(ExtendedHI::Ra(Ts_values[i], Ta_values[j]), result[i][j], tol); + } + } +} + +TEST_F(EnergyPlusFixture, extendedHI_Ra_bar) +{ + Real64 tol = 1e-8; + std::vector Tf_values = {240, 260, 280, 300, 320, 340, 360}; + std::vector Ta_values = {240, 260, 280, 300, 320, 340, 360}; + std::vector> result = {{0.07141547, 0.06983279, 0.06815365, 0.0663875, 0.06454507, 0.06263806, 0.06067882}, + {0.06983279, 0.06823771, 0.06655337, 0.06478927, 0.06295607, 0.06106521, 0.05912865}, + {0.06815365, 0.06655337, 0.06487109, 0.06311629, 0.06129941, 0.05943158, 0.0575243}, + {0.0663875, 0.06478927, 0.06311629, 0.06137788, 0.05958421, 0.05774599, 0.05587418}, + {0.06454507, 0.06295607, 0.06129941, 0.05958421, 0.05782026, 0.05601779, 0.05418719}, + {0.06263806, 0.06106521, 0.05943158, 0.05774599, 0.05601779, 0.05425668, 0.05247244}, + {0.06067882, 0.05912865, 0.0575243, 0.05587418, 0.05418719, 0.05247244, 0.0507391}}; + + for (size_t i = 0; i < Tf_values.size(); ++i) { + for (size_t j = 0; j < Ta_values.size(); ++j) { + EXPECT_NEAR(ExtendedHI::Ra_bar(Tf_values[i], Ta_values[j]), result[i][j], tol); + } + } +} + +TEST_F(EnergyPlusFixture, extendedHI_Ra_un) +{ + Real64 tol = 1e-8; + std::vector Tf_values = {240, 260, 280, 300, 320, 340, 360}; + std::vector Ta_values = {240, 260, 280, 300, 320, 340, 360}; + std::vector> result = {{0.06787493, 0.06642598, 0.06488609, 0.06326346, 0.06156753, 0.05980867, 0.05799795}, + {0.06642598, 0.06496324, 0.06341598, 0.0617925, 0.06010222, 0.05835534, 0.05656263}, + {0.06488609, 0.06341598, 0.06186786, 0.06025007, 0.0585719, 0.0568433, 0.05507465}, + {0.06326346, 0.0617925, 0.06025007, 0.05864444, 0.05698468, 0.05528041, 0.05354159}, + {0.06156753, 0.06010222, 0.0585719, 0.05698468, 0.05534934, 0.05367512, 0.0519715}, + {0.05980867, 0.05835534, 0.0568433, 0.05528041, 0.05367512, 0.05203623, 0.0503727}, + {0.05799795, 0.05656263, 0.05507465, 0.05354159, 0.0519715, 0.0503727, 0.0487536}}; + for (size_t i = 0; i < Tf_values.size(); ++i) { + for (size_t j = 0; j < Ta_values.size(); ++j) { + EXPECT_NEAR(ExtendedHI::Ra_un(Tf_values[i], Ta_values[j]), result[i][j], tol); + } + } +} + +TEST_F(EnergyPlusFixture, extendedHI_find_eqvar) +{ + Real64 tol = 1e-5; + std::vector Ta_values = {240, 260, 280, 300, 320, 340, 360}; + std::vector RH_values = {0, 0.2, 0.4, 0.6, 0.8, 1.0}; + std::vector> result_0 = {{static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf)}, + {static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf)}, + {static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf), + static_cast(EqvarName::Rf)}, + {static_cast(EqvarName::Rf), + static_cast(EqvarName::Rs), + static_cast(EqvarName::Rs), + static_cast(EqvarName::Rs), + static_cast(EqvarName::Rs), + static_cast(EqvarName::Rs)}, + {static_cast(EqvarName::Rs), + static_cast(EqvarName::Rs), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt)}, + {static_cast(EqvarName::Rs), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt)}, + {static_cast(EqvarName::Rs), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt), + static_cast(EqvarName::DTcdt)}}; + + std::vector> result_1 = {{33.04275, 32.69563, 32.35542, 32.02191, 31.69491, 31.37423}, + {1.56043, 1.54633, 1.53238, 1.51858, 1.50491, 1.49139}, + {0.44248, 0.42288, 0.40403, 0.38594, 0.36856, 0.35189}, + {0.01107, 0.03821, 0.03685, 0.03533, 0.03356, 0.0314}, + {0.02699, 0.02259, 0.00048, 0.00338, 0.00628, 0.00918}, + {0.02073, 0.00466, 0.01213, 0.0196, 0.02707, 0.03453}, + {0.00147, 0.01691, 0.03395, 0.051, 0.06804, 0.08509}}; + + for (size_t i = 0; i < Ta_values.size(); ++i) { + for (size_t j = 0; j < RH_values.size(); ++j) { + EXPECT_EQ(find_eqvar_name(*state, Ta_values[i], RH_values[j]), result_0[i][j]); + EXPECT_NEAR(find_eqvar_value(*state, Ta_values[i], RH_values[j]), result_1[i][j], tol); + } + } +} + +TEST_F(EnergyPlusFixture, extendedHI_find_T) +{ + Real64 tol = 1e-7; + state->dataRootFinder->HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverAlgorithm::Bisection; + std::vector Rf_values = {30, 32, 34, 36, 38}; + std::vector result_0_rf = {240.0675404, 239.9711237, 239.8858108, 239.8097882, 239.7416167}; + for (size_t i = 0; i < Rf_values.size(); ++i) { + EXPECT_NEAR(ExtendedHI::find_T(*state, static_cast(EnergyPlus::ExtendedHI::EqvarName::Rf), Rf_values[i]), result_0_rf[i], tol); + } + std::vector Rs_values = {0.01, 0.02, 0.03}; + std::vector result_0_rs = {337.8697, 329.7587, 307.4816}; + tol = 1e-4; + for (size_t i = 0; i < Rs_values.size(); ++i) { + EXPECT_NEAR(ExtendedHI::find_T(*state, static_cast(EnergyPlus::ExtendedHI::EqvarName::Rs), Rs_values[i]), result_0_rs[i], tol); + } + std::vector phi_values = {0.86, 0.88, 0.90, 0.92, 0.94, 0.96}; + std::vector result_0_phi = {228.6900, 215.9994, 199.0012, 175.1865, 139.7124, 82.0478}; + for (size_t i = 0; i < phi_values.size(); ++i) { + EXPECT_NEAR(ExtendedHI::find_T(*state, static_cast(EnergyPlus::ExtendedHI::EqvarName::Phi), phi_values[i]), result_0_phi[i], tol); + } + std::vector dTcdt_values = {0.01, 0.03, 0.05, 0.07, 0.09}; + std::vector result_0_dTcdt = {412.5272, 512.3596, 584.547, 641.1988, 688.0423}; + for (size_t i = 0; i < dTcdt_values.size(); ++i) { + EXPECT_NEAR(ExtendedHI::find_T(*state, static_cast(EnergyPlus::ExtendedHI::EqvarName::DTcdt), dTcdt_values[i]), result_0_dTcdt[i], tol); + } +} + +TEST_F(EnergyPlusFixture, extendedHI_heatindex) +{ + + state->dataRootFinder->HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverAlgorithm::Bisection; + std::vector> HI_values = {{199.9994, 199.9997, 200.0}, + {209.9976, 209.9988, 210.0}, + {219.9916, 219.9958, 220.0}, + {229.974, 229.987, 230.0}, + {239.9254, 239.9627, 240.0}, + {249.7677, 249.8837, 250.0}, + {259.3736, 259.6864, 260.0}, + {268.5454, 269.2746, 270.0}, + {277.2234, 278.6369, 280.0}, + {285.7511, 288.2814, 290.7861}, + {297.5738, 300.2923, 305.3947}, + {305.555, 318.6226, 359.9063}, + {313.0299, 359.0539, 407.5345}, + {320.5089, 398.576, 464.9949}, + {328.0358, 445.8599, 530.5525}, + {333.2806, 500.0422, 601.9518}, + {343.6313, 559.664, 677.2462}, + {354.1826, 623.196, 755.0833}}; + + std::vector T_values = {200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370}; + std::vector RH_values = {0, 0.5, 1}; + + Real64 tol = 1e-4; + + for (size_t i = 0; i < T_values.size(); ++i) { + for (size_t j = 0; j < RH_values.size(); ++j) { + Real64 HI = HI_values[i][j]; + EXPECT_NEAR(ExtendedHI::heatindex(*state, T_values[i], RH_values[j]), HI, tol); + } + } +} + +// helper: calculating HI the old way +Real64 calcHI(Real64 ZoneTF, Real64 ZoneRH) +{ + Real64 HI; + Real64 constexpr c1 = -42.379; + Real64 constexpr c2 = 2.04901523; + Real64 constexpr c3 = 10.14333127; + Real64 constexpr c4 = -.22475541; + Real64 constexpr c5 = -.00683783; + Real64 constexpr c6 = -.05481717; + Real64 constexpr c7 = .00122874; + Real64 constexpr c8 = .00085282; + Real64 constexpr c9 = -.00000199; + if (ZoneTF < 80) { + HI = 0.5 * (ZoneTF + 61.0 + (ZoneTF - 68.0) * 1.2 + (ZoneRH * 0.094)); + } else { + HI = c1 + c2 * ZoneTF + c3 * ZoneRH + c4 * ZoneTF * ZoneRH + c5 * ZoneTF * ZoneTF + c6 * ZoneRH * ZoneRH + c7 * ZoneTF * ZoneTF * ZoneRH + + c8 * ZoneTF * ZoneRH * ZoneRH + c9 * ZoneTF * ZoneTF * ZoneRH * ZoneRH; + if (ZoneRH < 13 && ZoneTF < 112) { + HI -= (13 - ZoneRH) / 4 * std::sqrt((17 - abs(ZoneTF - 95)) / 17); + } else if (ZoneRH > 85 && ZoneTF < 87) { + HI += (ZoneRH - 85) / 10 * (87 - ZoneTF) / 5; + } + } + HI = (HI - 32.0) * (5.0 / 9.0); + return HI; +} + +constexpr Real64 Fahrenheit2Celsius(Real64 F) +{ + return (F - 32.0) * 5.0 / 9.0; +} + +// compare different the old and new HI method +TEST_F(EnergyPlusFixture, extendedHI_heatindex_compare) +{ + // uncomment the following to write out outputs comparing the old HI and the extended HI + // for (int T = 80; T < 112; T += 2) { + // for (int RH_percent = 40; RH_percent < 105; RH_percent += 5) { + // fmt::print("{},{},{},{}\n", T, Fahrenheit2Celsius(T) + 273.15, RH_percent, calcHI(T * 1.0, RH_percent) + 273.15); + // } + // } + // + // fmt::print("--------------------------extended HI------------------------------\n"); + // + // for (int T = 80; T < 112; T += 2) { + // for (int RH_percent = 40; RH_percent < 105; RH_percent += 5) { + // fmt::print("{},{},{},{}\n", + // T, + // Fahrenheit2Celsius(T) + 273.15, + // RH_percent, + // ExtendedHI::heatindex(*state, Fahrenheit2Celsius(T) + 273.15, RH_percent / 100.0, false)); + // } + // } + + std::vector> HI_values = {{299.50263955106493, + 299.776740099187, + 300.0697403535014, + 300.3840374486754, + 300.7224627089454, + 301.0883855406428, + 301.48585129820276, + 301.91976206202526, + 302.39612058678176, + 302.9223619942786, + 303.50781721121166, + 304.164366737823, + 304.90738965163473}, + {300.7371586287627, + 301.08082855993416, + 301.45165138470475, + 301.85347046062816, + 302.29090810229536, + 302.7695771184517, + 303.2963640097296, + 303.8798186200438, + 304.5306942932075, + 305.2627171872882, + 306.0937017010292, + 307.0472131000133, + 308.15511379914824}, + {302.02736771141645, + 302.4561810697196, + 302.92349559196737, + 303.4353941195877, + 303.9993409969611, + 304.62460199545603, + 305.322829571669, + 306.10889266303275, + 307.00207884714473, + 308.027883155155, + 309.2207373859128, + 313.0628398671979, + 321.5848247316899}, + {303.3841495186789, + 303.9170689758612, + 304.50409744807985, + 305.1547874516109, + 305.88112467259634, + 306.69836198852863, + 307.62622559734154, + 308.69069155014586, + 309.9266883142991, + 311.38231908960734, + 318.54246110946406, + 328.0043066147482, + 333.3393972698832}, + {304.8199354641838, + 305.48032203514595, + 306.21634121227544, + 307.0429394330131, + 307.97934497182723, + 309.05072723689955, + 310.29069143289234, + 311.7451353772776, + 313.95530016103294, + 323.83440227771644, + 332.4701096833451, + 334.90678639907856, + 337.31894975469913}, + {306.3492841011612, + 307.16624582593795, + 308.0886627669679, + 309.13992447021883, + 310.35097800020594, + 311.7636495939223, + 313.43586634553503, + 317.6494802389061, + 328.3628307696199, + 333.74059265770484, + 336.3222867687, + 338.8761290133698, + 341.4020377426641}, + {307.98957814869937, + 308.99980285495985, + 310.15708861581516, + 311.49815879471134, + 313.0731694836868, + 314.95241500844713, + 320.7787010347238, + 331.8317274673609, + 334.83416476810817, + 337.5699159357464, + 340.2740648871986, + 342.94652084296104, + 345.6054543473874}, + {309.7619108116487, + 311.0122043680167, + 312.46811247605365, + 314.187658362207, + 316.2529625179013, + 323.0801825976232, + 332.79726637585554, + 335.7326857879525, + 338.63242015999276, + 341.4963439834537, + 344.32435625989456, + 347.16610411327565, + 349.9882094984059}, + {311.6922567837173, + 313.2431093422929, + 315.0828601612011, + 317.30399334745016, + 324.3992667720886, + 333.3013983833371, + 336.4164381631417, + 339.4910959439585, + 342.5252268166514, + 345.53482289920794, + 348.55059671303025, + 351.53749776567565, + 354.49586372385966}, + {313.81305196962785, + 315.74373047973495, + 318.0832217884017, + 324.6363173221471, + 333.556578377611, + 336.86389599752147, + 340.12557708716486, + 343.3414515358163, + 346.5464459863142, + 349.74051965837134, + 352.90212786378106, + 356.0316775160027, + 359.1295787363197}, + {316.1653665843187, + 318.58128181367647, + 323.6855917231878, + 333.5378166526789, + 337.0514521509176, + 340.51358119759243, + 343.9240011043148, + 347.3324049610528, + 350.715991469624, + 354.063080122869, + 357.3741601619986, + 360.6497245162609, + 363.89026874647243}, + {318.80192411888856, + 321.8453275115462, + 333.2175307610305, + 336.9530971109634, + 340.63061076856684, + 344.2498254548991, + 347.8701384467422, + 351.4554844770464, + 354.99980266642524, + 358.5036799122463, + 361.96770739537897, + 365.39247917797184, + 368.7785908780643}, + {321.79129250056576, + 332.5651462195674, + 336.5400431206217, + 340.4496004333487, + 344.2935131903505, + 348.13508995372104, + 351.9356167348451, + 355.6900213044719, + 359.3990061376826, + 363.0632788382354, + 366.6835501792957, + 370.2605324515025, + 373.7949378686608}, + {329.9497329717269, + 335.7802855706541, + 339.9405041738646, + 344.0269053383963, + 348.1004405542626, + 352.130907458195, + 356.1095161383855, + 360.03710570017574, + 363.9145213572192, + 367.74261204962386, + 371.5222280813032, + 375.2542191799148, + 378.9394325375906}, + {334.63809705979656, + 339.06981446722057, + 343.41864144138526, + 347.7367934017093, + 352.013488568773, + 356.2318584616878, + 360.3929031532607, + 364.49763041891856, + 368.54705243284116, + 372.5421826945967, + 376.48403349361615, + 380.3736132776248, + 384.2119247702067}, + {337.80000485421624, + 342.43363185960334, + 347.0118012771127, + 351.55276412755484, + 356.0280998123926, + 360.438997685269, + 364.78665706905304, + 369.07228278025286, + 373.2970810952247, + 377.4622562734294, + 381.56900731119094, + 385.6185252717114, + 389.61199074954493}}; + + std::vector T_values; + for (int i = 0; i < 16; ++i) { + T_values.push_back(80 + 2 * i); + } + std::vector RH_values; + for (int i = 0; i < 13; ++i) { + RH_values.push_back(40 + 5 * i); + } + + Real64 extended; + for (size_t i = 0; i < T_values.size(); ++i) { + for (size_t j = 0; j < RH_values.size(); ++j) { + extended = ExtendedHI::heatindex(*state, Fahrenheit2Celsius(T_values[i]) + 273.15, RH_values[j] / 100.0); + EXPECT_NEAR(HI_values[i][j], extended, 1e-4); + } + } +} diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index c7f26710338..135170a65fd 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -2593,6 +2593,52 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Compressor) EXPECT_NEAR(2080, Ncomp, 1); EXPECT_EQ(state->dataLoopNodes->Node(state->dataHVACVarRefFlow->VRFTU(1).VRFTUInletNodeNum).MassFlowRate, 0.0); } + +{ + // Test the method VRFOU_CalcCompC at low load condition with cycling + + // Inputs_condition + Real64 TU_load = 6006; // Indoor unit cooling load [W] + Real64 T_suction = 8.86; // Compressor suction temperature Te' [C] + Real64 T_discharge = 40.26; // Compressor discharge temperature Tc' [C] + Real64 Psuction = 1.2e6; // Compressor suction pressure Pe' [Pa] + Real64 T_comp_in = 25.0; // Refrigerant temperature at compressor inlet (after piping loss) [C] + Real64 h_comp_in = 4.3e5; // Enthalpy after piping loss (compressor inlet) [kJ/kg] + Real64 h_IU_evap_in = 2.5e5; // Enthalpy of IU at inlet [kJ/kg] + Real64 Pipe_Q_c = 5.0; // Piping Loss Algorithm Parameter: Heat loss [W] + Real64 CapMaxTc = 50.0; // The maximum temperature that Tc can be at heating mode [C] + Real64 OUEvapHeatExtract = 900.0; // Evaporator heat extract [W] + Real64 Ncomp = 1058; // Compressor power [W] + Real64 CompSpdActual; // Actual compressor running speed [rps] + + // Run + Real64 CyclingRatio = 1.0; + state->dataHVACVarRefFlow->VRF(VRFCond).VRFOU_CalcCompC(*state, + TU_load, + T_suction, + T_discharge, + Psuction, + T_comp_in, + h_comp_in, + h_IU_evap_in, + Pipe_Q_c, + CapMaxTc, + OUEvapHeatExtract, + CompSpdActual, + Ncomp, + CyclingRatio); + + // Test + auto const &thisVRF = state->dataHVACVarRefFlow->VRF(VRFCond); + Real64 CompEvaporatingCAPSpdMin = + thisVRF.RatedEvapCapacity * CurveValue(*state, thisVRF.OUCoolingCAPFT(1), thisVRF.CondensingTemp, thisVRF.EvaporatingTemp); + Real64 CompEvaporatingPWRSpdMin = + thisVRF.RatedCompPower * CurveValue(*state, thisVRF.OUCoolingPWRFT(1), thisVRF.CondensingTemp, thisVRF.EvaporatingTemp); + EXPECT_NEAR(0.34, CyclingRatio, 0.01); + EXPECT_NEAR(OUEvapHeatExtract, CompEvaporatingCAPSpdMin + Ncomp, 1e-4); + EXPECT_NEAR(1500, CompSpdActual, 1); + EXPECT_NEAR(Ncomp, CompEvaporatingPWRSpdMin, 1e-4); +} } TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_VRFOU_Coil) @@ -13275,9 +13321,9 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_ReportOutputVerificationTest) EXPECT_EQ(0.0, thisVRFTU.NoCoolHeatOutAirMassFlow); EXPECT_NEAR(5125.0840, thisDXCoolingCoil.TotalCoolingEnergyRate, 0.0001); EXPECT_NEAR(4999.8265, thisVRFTU.TotalCoolingRate, 0.0001); - EXPECT_NEAR(125.2573 * thisDXCoolingCoil.CoolingCoilRuntimeFraction, thisFan->totalPower, 0.0001); + EXPECT_NEAR(125.2573, thisFan->totalPower, 0.0001); EXPECT_NEAR(thisDXCoolingCoil.TotalCoolingEnergyRate, (thisVRFTU.TotalCoolingRate + thisFan->totalPower), 0.0001); - EXPECT_NEAR(0.8930, state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio, 0.0001); + EXPECT_NEAR(0.3682, state->dataHVACVarRefFlow->VRF(1).VRFCondCyclingRatio, 0.0001); EXPECT_NEAR(state->dataHVACVarRefFlow->VRF(1).OUFanPower, state->dataHVACVarRefFlow->VRF(1).RatedOUFanPower, 0.0001); } diff --git a/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc b/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc index dbb84bbd90a..9601e745d0b 100644 --- a/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc +++ b/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc @@ -3258,7 +3258,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).airHumRatAvg = 0.0022; // RH = 10% CalcThermalResilience(*state); ReportThermalResilience(*state); - EXPECT_NEAR(26, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); + EXPECT_NEAR(25, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); EXPECT_NEAR(23, state->dataHeatBal->Resilience(1).ZoneHumidex, 1); // Heat Index Case 4: Rothfusz regression, other than the above conditions; @@ -3833,7 +3833,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).airHumRatAvg = 0.0022; // RH = 10% CalcThermalResilience(*state); ReportThermalResilience(*state); - EXPECT_NEAR(26, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); + EXPECT_NEAR(25, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); EXPECT_NEAR(23, state->dataHeatBal->Resilience(1).ZoneHumidex, 1); // Heat Index Case 4: Rothfusz regression, other than the above conditions; diff --git a/tst/EnergyPlus/unit/PlantCentralGSHP.unit.cc b/tst/EnergyPlus/unit/PlantCentralGSHP.unit.cc index 4cdfdf1dea1..b121de3d3a3 100644 --- a/tst/EnergyPlus/unit/PlantCentralGSHP.unit.cc +++ b/tst/EnergyPlus/unit/PlantCentralGSHP.unit.cc @@ -363,3 +363,410 @@ TEST_F(EnergyPlusFixture, Test_CentralHeatPumpSystem_Control_Schedule_fix) // verify that under this scenario of not finding a schedule match, ScheduleAlwaysOn is the treated default EXPECT_EQ(state->dataPlantCentralGSHP->Wrapper(1).WrapperComp(1).CHSchedPtr, ScheduleManager::ScheduleAlwaysOn); } + +TEST_F(EnergyPlusFixture, Test_CentralHeatPumpSystem_adjustChillerHeaterCondFlowTemp) +{ + state->dataPlantCentralGSHP->Wrapper.allocate(1); + state->dataPlantCentralGSHP->Wrapper(1).WrapperComp.allocate(1); + state->dataPlantCentralGSHP->Wrapper(1).ChillerHeater.allocate(1); + auto &thisWrap = state->dataPlantCentralGSHP->Wrapper(1); + auto &thisCH = thisWrap.ChillerHeater(1); + state->dataPlnt->PlantLoop.allocate(1); + state->dataPlnt->PlantLoop(1).FluidName = "WATER"; + state->dataPlnt->PlantLoop(1).FluidIndex = FluidProperties::GetGlycolNum(*state, state->dataPlnt->PlantLoop(1).FluidName); + thisWrap.HWPlantLoc.loopNum = 1; + FluidProperties::GetFluidPropertiesData(*state); + + Real64 qCondenser; + Real64 condMassFlowRate; + Real64 condOutletTemp; + Real64 condInletTemp; + Real64 condDeltaTemp; + Real64 expCondenser; + Real64 expMassFlowRate; + Real64 expOutletTemp; + Real64 constexpr allowedTolerance = 0.0001; + + // Test 1: Variable Flow--qCondenser is less than what the conditions say (mass flow reduced, nothing else changes) + qCondenser = 1000.0; + condMassFlowRate = 1.0; + condOutletTemp = 60.0; + condInletTemp = 59.0; + condDeltaTemp = 1.0; + thisWrap.VariableFlowCH = true; + expCondenser = 1000.0; + expMassFlowRate = 0.23897; + expOutletTemp = 60.0; + thisWrap.adjustChillerHeaterCondFlowTemp(*state, qCondenser, condMassFlowRate, condOutletTemp, condInletTemp, condDeltaTemp); + EXPECT_NEAR(qCondenser, expCondenser, allowedTolerance); + EXPECT_NEAR(condMassFlowRate, expMassFlowRate, allowedTolerance); + EXPECT_NEAR(condOutletTemp, expOutletTemp, allowedTolerance); + + // Test 2: Variable Flow--qCondenser is greater than what conditions say (load reduced, nothing else changes) + qCondenser = 5000.0; + condMassFlowRate = 1.0; + condOutletTemp = 60.0; + condInletTemp = 59.0; + condDeltaTemp = 1.0; + thisWrap.VariableFlowCH = true; + expCondenser = 4184.6; + expMassFlowRate = 1.0; + expOutletTemp = 60.0; + thisWrap.adjustChillerHeaterCondFlowTemp(*state, qCondenser, condMassFlowRate, condOutletTemp, condInletTemp, condDeltaTemp); + EXPECT_NEAR(qCondenser, expCondenser, allowedTolerance); + EXPECT_NEAR(condMassFlowRate, expMassFlowRate, allowedTolerance); + EXPECT_NEAR(condOutletTemp, expOutletTemp, allowedTolerance); + + // Test 3: Constant Flow--Outlet Temp greater than calculated outlet temp (outlet temp changes, nothing else changes) + qCondenser = 1000.0; + condMassFlowRate = 1.0; + condOutletTemp = 60.0; + condInletTemp = 59.0; + condDeltaTemp = 1.0; + thisWrap.VariableFlowCH = false; + expCondenser = 1000.0; + expMassFlowRate = 1.0; + expOutletTemp = 59.23897; + thisWrap.adjustChillerHeaterCondFlowTemp(*state, qCondenser, condMassFlowRate, condOutletTemp, condInletTemp, condDeltaTemp); + EXPECT_NEAR(qCondenser, expCondenser, allowedTolerance); + EXPECT_NEAR(condMassFlowRate, expMassFlowRate, allowedTolerance); + EXPECT_NEAR(condOutletTemp, expOutletTemp, allowedTolerance); + + // Test 4: Constant Flow--Outlet Temp less than calculated outlet temp (load changes, nothing else changes) + qCondenser = 8369.2; + condMassFlowRate = 1.0; + condOutletTemp = 60.0; + condInletTemp = 59.0; + condDeltaTemp = 1.0; + thisWrap.VariableFlowCH = false; + expCondenser = 4184.6; + expMassFlowRate = 1.0; + expOutletTemp = 60.0; + thisWrap.adjustChillerHeaterCondFlowTemp(*state, qCondenser, condMassFlowRate, condOutletTemp, condInletTemp, condDeltaTemp); + EXPECT_NEAR(qCondenser, expCondenser, allowedTolerance); + EXPECT_NEAR(condMassFlowRate, expMassFlowRate, allowedTolerance); + EXPECT_NEAR(condOutletTemp, expOutletTemp, allowedTolerance); +} + +TEST_F(EnergyPlusFixture, Test_CentralHeatPumpSystem_adjustChillerHeaterEvapFlowTemp) +{ + state->dataPlantCentralGSHP->Wrapper.allocate(1); + state->dataPlantCentralGSHP->Wrapper(1).WrapperComp.allocate(1); + state->dataPlantCentralGSHP->Wrapper(1).ChillerHeater.allocate(1); + auto &thisWrap = state->dataPlantCentralGSHP->Wrapper(1); + auto &thisCH = thisWrap.ChillerHeater(1); + state->dataPlnt->PlantLoop.allocate(1); + state->dataPlnt->PlantLoop(1).FluidName = "WATER"; + state->dataPlnt->PlantLoop(1).FluidIndex = FluidProperties::GetGlycolNum(*state, state->dataPlnt->PlantLoop(1).FluidName); + thisWrap.HWPlantLoc.loopNum = 1; + FluidProperties::GetFluidPropertiesData(*state); + + Real64 qEvaporator; + Real64 evapMassFlowRate; + Real64 evapOutletTemp; + Real64 evapInletTemp; + Real64 expMassFlowRate; + Real64 expOutletTemp; + Real64 constexpr allowedTolerance = 0.0001; + + // Test 1a: qEvaporator is too low, flow rate set to zero and outlet temp set to inlet temp + qEvaporator = 0.00001; + evapMassFlowRate = 1.0; + evapOutletTemp = 34.0; + evapInletTemp = 35.0; + thisWrap.VariableFlowCH = false; + expMassFlowRate = 0.0; + expOutletTemp = 35.0; + thisWrap.adjustChillerHeaterEvapFlowTemp(*state, qEvaporator, evapMassFlowRate, evapOutletTemp, evapInletTemp); + EXPECT_NEAR(evapMassFlowRate, expMassFlowRate, allowedTolerance); + EXPECT_NEAR(evapOutletTemp, expOutletTemp, allowedTolerance); + + // Test 1b: delta T is zero, load and flow rate set to zero and outlet temp set to inlet temp + qEvaporator = 1000.0; + evapMassFlowRate = 1.0; + evapOutletTemp = 35.0; + evapInletTemp = 35.0; + thisWrap.VariableFlowCH = false; + expMassFlowRate = 0.0; + expOutletTemp = 35.0; + thisWrap.adjustChillerHeaterEvapFlowTemp(*state, qEvaporator, evapMassFlowRate, evapOutletTemp, evapInletTemp); + EXPECT_NEAR(evapMassFlowRate, expMassFlowRate, allowedTolerance); + EXPECT_NEAR(evapOutletTemp, expOutletTemp, allowedTolerance); + + // Test 2a: Variable Flow, Load higher than max flow rate passed in, keep flow rate and adjust outlet temp + qEvaporator = 5000.0; + evapMassFlowRate = 1.0; + evapOutletTemp = 34.0; + evapInletTemp = 35.0; + thisWrap.VariableFlowCH = true; + expMassFlowRate = 1.0; + expOutletTemp = 33.80383; + thisWrap.adjustChillerHeaterEvapFlowTemp(*state, qEvaporator, evapMassFlowRate, evapOutletTemp, evapInletTemp); + EXPECT_NEAR(evapMassFlowRate, expMassFlowRate, allowedTolerance); + EXPECT_NEAR(evapOutletTemp, expOutletTemp, allowedTolerance); + + // Test 2b: Variable Flow, Load lower than max flow rate passed in, adjust flow rate and keep outlet temp + qEvaporator = 1045.0; + evapMassFlowRate = 1.0; + evapOutletTemp = 34.0; + evapInletTemp = 35.0; + thisWrap.VariableFlowCH = true; + expMassFlowRate = 0.25; + expOutletTemp = 34.0; + thisWrap.adjustChillerHeaterEvapFlowTemp(*state, qEvaporator, evapMassFlowRate, evapOutletTemp, evapInletTemp); + EXPECT_NEAR(evapMassFlowRate, expMassFlowRate, allowedTolerance); + EXPECT_NEAR(evapOutletTemp, expOutletTemp, allowedTolerance); + + // Test 3: Constant Flow--adjust outlet temperature + qEvaporator = 2090.0; + evapMassFlowRate = 1.0; + evapOutletTemp = 34.0; + evapInletTemp = 35.0; + thisWrap.VariableFlowCH = false; + expMassFlowRate = 1.0; + expOutletTemp = 34.5; + thisWrap.adjustChillerHeaterEvapFlowTemp(*state, qEvaporator, evapMassFlowRate, evapOutletTemp, evapInletTemp); + EXPECT_NEAR(evapMassFlowRate, expMassFlowRate, allowedTolerance); + EXPECT_NEAR(evapOutletTemp, expOutletTemp, allowedTolerance); +} + +TEST_F(EnergyPlusFixture, Test_CentralHeatPumpSystem_setChillerHeaterCondTemp) +{ + state->dataPlantCentralGSHP->Wrapper.allocate(1); + state->dataPlantCentralGSHP->Wrapper(1).WrapperComp.allocate(1); + state->dataPlantCentralGSHP->Wrapper(1).ChillerHeater.allocate(1); + auto &thisWrap = state->dataPlantCentralGSHP->Wrapper(1); + auto &thisCH = thisWrap.ChillerHeater(1); + + Real64 functionAnswer; + Real64 expectedAnswer; + Real64 constexpr allowedTolerance = 0.001; + Real64 condEnterTemp; + Real64 condLeaveTemp; + int chillNum = 1; + + // Test 1: get the condenser entering temperature + functionAnswer = 0.0; + thisCH.CondMode = EnergyPlus::PlantCentralGSHP::CondenserModeTemperature::EnteringCondenser; + condEnterTemp = 55.5; + condLeaveTemp = 44.4; + expectedAnswer = 55.5; + functionAnswer = thisWrap.setChillerHeaterCondTemp(*state, chillNum, condEnterTemp, condLeaveTemp); + EXPECT_NEAR(functionAnswer, expectedAnswer, allowedTolerance); + + // Test 2: get the condenser leaving temperature + functionAnswer = 0.0; + thisCH.CondMode = EnergyPlus::PlantCentralGSHP::CondenserModeTemperature::LeavingCondenser; + condEnterTemp = 55.5; + condLeaveTemp = 44.4; + expectedAnswer = 44.4; + functionAnswer = thisWrap.setChillerHeaterCondTemp(*state, chillNum, condEnterTemp, condLeaveTemp); + EXPECT_NEAR(functionAnswer, expectedAnswer, allowedTolerance); +} + +TEST_F(EnergyPlusFixture, Test_CentralHeatPumpSystem_checkEvapOutletTemp) +{ + state->dataPlantCentralGSHP->Wrapper.allocate(1); + state->dataPlantCentralGSHP->Wrapper(1).WrapperComp.allocate(1); + state->dataPlantCentralGSHP->Wrapper(1).ChillerHeater.allocate(1); + auto &thisWrap = state->dataPlantCentralGSHP->Wrapper(1); + auto &thisCH = thisWrap.ChillerHeater(1); + + int chNum = 1; + Real64 evapOutletTemp; + Real64 lowTempLimitEout; + Real64 evapInletTemp; + Real64 qEvaporator; + Real64 evapMassFlowRate; + Real64 Cp = 4000.0; + Real64 expQEvap; + Real64 expTout; + Real64 constexpr allowedTolerance = 0.0001; + + // Test 1a: Evaporator outlet temperature lower the evaporator outlet low temperature limit, adjust outlet and load + thisCH.EvapOutletNode.TempMin = 5.0; + evapInletTemp = 10.0; + evapOutletTemp = 8.0; + lowTempLimitEout = 9.0; + qEvaporator = 4000.0; + evapMassFlowRate = 0.5; + expQEvap = 2000.0; + expTout = 9.0; + thisWrap.checkEvapOutletTemp(*state, chNum, evapOutletTemp, lowTempLimitEout, evapInletTemp, qEvaporator, evapMassFlowRate, Cp); + EXPECT_NEAR(qEvaporator, expQEvap, allowedTolerance); + EXPECT_NEAR(evapOutletTemp, expTout, allowedTolerance); + + // Test 1b: Evaporator outlet temperature lower the evaporator outlet low temperature limit and inlet temp at or below lowTempLimitEout, + // zero flow and set outlet temperature to inlet temperature + thisCH.EvapOutletNode.TempMin = 5.0; + evapInletTemp = 8.0; + evapOutletTemp = 7.0; + lowTempLimitEout = 9.0; + qEvaporator = 2000.0; + evapMassFlowRate = 0.5; + expQEvap = 0.0; + expTout = 8.0; + thisWrap.checkEvapOutletTemp(*state, chNum, evapOutletTemp, lowTempLimitEout, evapInletTemp, qEvaporator, evapMassFlowRate, Cp); + EXPECT_NEAR(qEvaporator, expQEvap, allowedTolerance); + EXPECT_NEAR(evapOutletTemp, expTout, allowedTolerance); + + // Test 2a: Evaporator outlet temperature lower the node minimum temperature limit, adjust outlet and load + thisCH.EvapOutletNode.TempMin = 9.0; + evapInletTemp = 10.0; + evapOutletTemp = 8.0; + lowTempLimitEout = 5.0; + qEvaporator = 4000.0; + evapMassFlowRate = 0.5; + expQEvap = 2000.0; + expTout = 9.0; + thisWrap.checkEvapOutletTemp(*state, chNum, evapOutletTemp, lowTempLimitEout, evapInletTemp, qEvaporator, evapMassFlowRate, Cp); + EXPECT_NEAR(qEvaporator, expQEvap, allowedTolerance); + EXPECT_NEAR(evapOutletTemp, expTout, allowedTolerance); + + // Test 2b: Evaporator outlet temperature lower the node minimum temperature limit and inlet temp at or below node temperature limt, + // zero flow and set outlet temperature to inlet temperature + thisCH.EvapOutletNode.TempMin = 9.0; + evapInletTemp = 8.0; + evapOutletTemp = 7.0; + lowTempLimitEout = 5.0; + qEvaporator = 2000.0; + evapMassFlowRate = 0.5; + expQEvap = 0.0; + expTout = 8.0; + thisWrap.checkEvapOutletTemp(*state, chNum, evapOutletTemp, lowTempLimitEout, evapInletTemp, qEvaporator, evapMassFlowRate, Cp); + EXPECT_NEAR(qEvaporator, expQEvap, allowedTolerance); + EXPECT_NEAR(evapOutletTemp, expTout, allowedTolerance); + + // Test 3: Everything is fine, no changes to anything + thisCH.EvapOutletNode.TempMin = 5.0; + evapInletTemp = 8.0; + evapOutletTemp = 6.0; + lowTempLimitEout = 5.0; + qEvaporator = 4000.0; + evapMassFlowRate = 0.5; + expQEvap = 4000.0; + expTout = 6.0; + thisWrap.checkEvapOutletTemp(*state, chNum, evapOutletTemp, lowTempLimitEout, evapInletTemp, qEvaporator, evapMassFlowRate, Cp); + EXPECT_NEAR(qEvaporator, expQEvap, allowedTolerance); + EXPECT_NEAR(evapOutletTemp, expTout, allowedTolerance); +} + +TEST_F(EnergyPlusFixture, Test_CentralHeatPumpSystem_calcPLRAndCyclingRatio) +{ + state->dataPlantCentralGSHP->Wrapper.allocate(1); + state->dataPlantCentralGSHP->Wrapper(1).WrapperComp.allocate(1); + state->dataPlantCentralGSHP->Wrapper(1).ChillerHeater.allocate(1); + auto &thisWrap = state->dataPlantCentralGSHP->Wrapper(1); + auto &thisCH = thisWrap.ChillerHeater(1); + + Real64 availChillerCap; + Real64 actualPartLoadRatio; + Real64 minPartLoadRatio; + Real64 maxPartLoadRatio; + Real64 qEvaporator; + Real64 frac; + Real64 expPLR; + Real64 expFrac; + Real64 expFalseLoad; + Real64 constexpr allowedTolerance = 0.0001; + + // Test 1: available chiller capacity less than zero (PLR should be zero, frac should be 1.0) + availChillerCap = -10000.0; + actualPartLoadRatio = -1.0; + minPartLoadRatio = 0.1; + maxPartLoadRatio = 1.0; + qEvaporator = 50000.0; + frac = -1.0; + expPLR = 0.0; + expFrac = 1.0; + expFalseLoad = 0.0; + state->dataPlantCentralGSHP->ChillerCyclingRatio = -1.0; + state->dataPlantCentralGSHP->ChillerPartLoadRatio = -1.0; + state->dataPlantCentralGSHP->ChillerFalseLoadRate = -1.0; + thisWrap.calcPLRAndCyclingRatio(*state, availChillerCap, actualPartLoadRatio, minPartLoadRatio, maxPartLoadRatio, qEvaporator, frac); + EXPECT_NEAR(frac, expFrac, allowedTolerance); + EXPECT_NEAR(actualPartLoadRatio, expPLR, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerCyclingRatio, expFrac, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerPartLoadRatio, expPLR, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerFalseLoadRate, expFalseLoad, allowedTolerance); + + // Test 2a: valid chiller capacity and evaporator load, negative minPLR + availChillerCap = 50000.0; + actualPartLoadRatio = -1.0; + minPartLoadRatio = -0.1; + maxPartLoadRatio = 1.0; + qEvaporator = 10000.0; + frac = -1.0; + expPLR = 0.2; + expFrac = 1.0; + expFalseLoad = 0.0; + state->dataPlantCentralGSHP->ChillerCyclingRatio = -1.0; + state->dataPlantCentralGSHP->ChillerPartLoadRatio = -1.0; + state->dataPlantCentralGSHP->ChillerFalseLoadRate = -1.0; + thisWrap.calcPLRAndCyclingRatio(*state, availChillerCap, actualPartLoadRatio, minPartLoadRatio, maxPartLoadRatio, qEvaporator, frac); + EXPECT_NEAR(frac, expFrac, allowedTolerance); + EXPECT_NEAR(actualPartLoadRatio, expPLR, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerCyclingRatio, expFrac, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerPartLoadRatio, expPLR, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerFalseLoadRate, expFalseLoad, allowedTolerance); + + // Test 2b: valid chiller capacity and evaporator load, actualPLR lower then minPLR + availChillerCap = 50000.0; + actualPartLoadRatio = -1.0; + minPartLoadRatio = 0.4; + maxPartLoadRatio = 1.0; + qEvaporator = 10000.0; + frac = -1.0; + expPLR = 0.4; + expFrac = 0.5; + expFalseLoad = 0.0; + state->dataPlantCentralGSHP->ChillerCyclingRatio = -1.0; + state->dataPlantCentralGSHP->ChillerPartLoadRatio = -1.0; + state->dataPlantCentralGSHP->ChillerFalseLoadRate = -1.0; + thisWrap.calcPLRAndCyclingRatio(*state, availChillerCap, actualPartLoadRatio, minPartLoadRatio, maxPartLoadRatio, qEvaporator, frac); + EXPECT_NEAR(frac, expFrac, allowedTolerance); + EXPECT_NEAR(actualPartLoadRatio, expPLR, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerCyclingRatio, expFrac, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerPartLoadRatio, expPLR, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerFalseLoadRate, expFalseLoad, allowedTolerance); + + // Test 2c: valid chiller capacity and evaporator load, actualPLR higher then minPLR + availChillerCap = 50000.0; + actualPartLoadRatio = -1.0; + minPartLoadRatio = 0.4; + maxPartLoadRatio = 1.0; + qEvaporator = 30000.0; + frac = -1.0; + expPLR = 0.6; + expFrac = 1.0; + expFalseLoad = 0.0; + state->dataPlantCentralGSHP->ChillerCyclingRatio = -1.0; + state->dataPlantCentralGSHP->ChillerPartLoadRatio = -1.0; + state->dataPlantCentralGSHP->ChillerFalseLoadRate = -1.0; + thisWrap.calcPLRAndCyclingRatio(*state, availChillerCap, actualPartLoadRatio, minPartLoadRatio, maxPartLoadRatio, qEvaporator, frac); + EXPECT_NEAR(frac, expFrac, allowedTolerance); + EXPECT_NEAR(actualPartLoadRatio, expPLR, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerCyclingRatio, expFrac, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerPartLoadRatio, expPLR, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerFalseLoadRate, expFalseLoad, allowedTolerance); + + // Test 2d: valid chiller capacity and evaporator load, actualPLR higher then maxPLR + availChillerCap = 50000.0; + actualPartLoadRatio = -1.0; + minPartLoadRatio = 0.4; + maxPartLoadRatio = 1.0; + qEvaporator = 60000.0; + frac = -1.0; + expPLR = 1.0; + expFrac = 1.0; + expFalseLoad = 0.0; + state->dataPlantCentralGSHP->ChillerCyclingRatio = -1.0; + state->dataPlantCentralGSHP->ChillerPartLoadRatio = -1.0; + state->dataPlantCentralGSHP->ChillerFalseLoadRate = -1.0; + thisWrap.calcPLRAndCyclingRatio(*state, availChillerCap, actualPartLoadRatio, minPartLoadRatio, maxPartLoadRatio, qEvaporator, frac); + EXPECT_NEAR(frac, expFrac, allowedTolerance); + EXPECT_NEAR(actualPartLoadRatio, expPLR, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerCyclingRatio, expFrac, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerPartLoadRatio, expPLR, allowedTolerance); + EXPECT_NEAR(state->dataPlantCentralGSHP->ChillerFalseLoadRate, expFalseLoad, allowedTolerance); +} diff --git a/tst/EnergyPlus/unit/UnitarySystem.unit.cc b/tst/EnergyPlus/unit/UnitarySystem.unit.cc index a1cc7eebea8..dd552559557 100644 --- a/tst/EnergyPlus/unit/UnitarySystem.unit.cc +++ b/tst/EnergyPlus/unit/UnitarySystem.unit.cc @@ -23957,3 +23957,261 @@ TEST_F(EnergyPlusFixture, UnitarySystemModel_MultiSpeedFanWSHP_Test) EXPECT_EQ(thisSys1.m_SpeedNum, 2); EXPECT_NEAR(sensOut, 500.0, 2); } + +TEST_F(ZoneUnitarySysTest, ZeroCoolingSpeedTest) +{ + std::string_view constexpr idf_objects = R"IDF( + + AirLoopHVAC:UnitarySystem, + Sys 1 Furnace DX Cool Unitary System, !- Name + Load, !- Control Type + SPACE1-1, !- Controlling Zone or Thermostat Location + None, !- Dehumidification Control Type + , !- Availability Schedule Name + Sys 1 Furnace DX Cool Mixed Air Outlet, !- Air Inlet Node Name + Sys 1 Furnace DX Cool Heating Coil Outlet, !- Air Outlet Node Name + , !- Supply Fan Object Type + , !- Supply Fan Name + , !- Fan Placement + , !- Supply Air Fan Operating Mode Schedule Name + , !- Heating Coil Object Type + , !- Heating Coil Name + , !- DX Heating Coil Sizing Ratio + Coil:Cooling:DX, !- Cooling Coil Object Type + Sys 1 Furnace DX Cool Cooling Coil, !- Cooling Coil Name + , !- Use DOAS DX Cooling Coil + , !- Minimum Supply Air Temperature {C} + , !- Latent Load Control + , !- Supplemental Heating Coil Object Type + , !- Supplemental Heating Coil Name + SupplyAirFlowRate, !- Cooling Supply Air Flow Rate Method + autosize, !- Cooling Supply Air Flow Rate {m3/s} + , !- Cooling Supply Air Flow Rate Per Floor Area {m3/s-m2} + , !- Cooling Fraction of Autosized Cooling Supply Air Flow Rate + , !- Cooling Supply Air Flow Rate Per Unit of Capacity {m3/s-W} + SupplyAirFlowRate, !- Heating Supply Air Flow Rate Method + autosize, !- Heating Supply Air Flow Rate {m3/s} + , !- Heating Supply Air Flow Rate Per Floor Area {m3/s-m2} + , !- Heating Fraction of Autosized Heating Supply Air Flow Rate + , !- Heating Supply Air Flow Rate Per Unit of Capacity {m3/s-W} + SupplyAirFlowRate, !- No Load Supply Air Flow Rate Method + autosize, !- No Load Supply Air Flow Rate {m3/s} + , !- No Load Supply Air Flow Rate Per Floor Area {m3/s-m2} + , !- No Load Fraction of Autosized Cooling Supply Air Flow Rate + , !- No Load Fraction of Autosized Heating Supply Air Flow Rate + , !- No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation {m3/s-W} + , !- No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation {m3/s-W} + , !- No Load Supply Air Flow Rate Control Set To Low Speed + Autosize, !- Maximum Supply Air Temperature {C} + 21, !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C} + , !- Outdoor Dry-Bulb Temperature Sensor Node Name + , !- Ancillary On-Cycle Electric Power {W} + , !- Ancillary Off-Cycle Electric Power {W} + , !- Design Heat Recovery Water Flow Rate {m3/s} + , !- Maximum Temperature for Heat Recovery {C} + , !- Heat Recovery Water Inlet Node Name + , !- Heat Recovery Water Outlet Node Name + UnitarySystemPerformance:Multispeed, !- Design Specification Multispeed Object Type + Sys 1 Furnace DX Cool Unitary System MultiSpeed Performance; !- Design Specification Multispeed Object Name + Coil:Cooling:DX, + Sys 1 Furnace DX Cool Cooling Coil, !- Name + Sys 1 Furnace DX Cool Supply Fan Outlet, !- Evaporator Inlet Node Name + Sys 1 Furnace DX Cool Cooling Coil Outlet, !- Evaporator Outlet Node Name + , !- Availability Schedule Name + , !- Condenser Zone Name + Sys 1 Furnace DX Cool Cooling Coil Condenser Inlet, !- Condenser Inlet Node Name + Sys 1 Furnace DX Cool Cooling Coil Condenser Outlet Node, !- Condenser Outlet Node Name + Sys 1 Furnace DX Cool Cooling Coil Performance; !- Performance Object Name + + Coil:Cooling:DX:CurveFit:Performance, + Sys 1 Furnace DX Cool Cooling Coil Performance, !- Name + 0.0, !- Crankcase Heater Capacity {W} + , !- Crankcase Heater Capacity Function of Temperature Curve Name + , !- Minimum Outdoor Dry-Bulb Temperature for Compressor Operation {C} + 10.0, !- Maximum Outdoor Dry-Bulb Temperature for Crankcase Heater Operation {C} + , !- Unit Internal Static Air Pressure {Pa} + Discrete, !- Capacity Control Method + , !- Evaporative Condenser Basin Heater Capacity {W/K} + , !- Evaporative Condenser Basin Heater Setpoint Temperature {C} + , !- Evaporative Condenser Basin Heater Operating Schedule Name + Electricity, !- Compressor Fuel Type + Sys 1 Furnace DX Cool Cooling Coil Operating Mode; !- Base Operating Mode + + Coil:Cooling:DX:CurveFit:OperatingMode, + Sys 1 Furnace DX Cool Cooling Coil Operating Mode, !- Name + autosize, !- Rated Gross Total Cooling Capacity {W} + autosize, !- Rated Evaporator Air Flow Rate {m3/s} + , !- Rated Condenser Air Flow Rate {m3/s} + 0, !- Maximum Cycling Rate {cycles/hr} + 0, !- Ratio of Initial Moisture Evaporation Rate and Steady State Latent Capacity {dimensionless} + 0, !- Latent Capacity Time Constant {s} + 0, !- Nominal Time for Condensate Removal to Begin {s} + No, !- Apply Latent Degradation to Speeds Greater than 1 + AirCooled, !- Condenser Type + , !- Nominal Evaporative Condenser Pump Power {W} + 2, !- Nominal Speed Number + Sys 1 Furnace DX Cool Cooling Coil Speed 1 Performance, !- Speed 1 Name + Sys 1 Furnace DX Cool Cooling Coil Speed 2 Performance; !- Speed 2 Name + + Coil:Cooling:DX:CurveFit:Speed, + Sys 1 Furnace DX Cool Cooling Coil Speed 1 Performance, !- Name + 0.5000, !- Gross Total Cooling Capacity Fraction + 0.5000, !- Evaporator Air Flow Rate Fraction + , !- Condenser Air Flow Rate Fraction + autosize, !- Gross Sensible Heat Ratio + 3, !- Gross Cooling COP {W/W} + 1.0, !- Active Fraction of Coil Face Area + , !- 2017 Rated Evaporator Fan Power Per Volume Flow Rate {W/(m3/s)} + 934.4, !- 2023 Rated Evaporator Fan Power Per Volume Flow Rate {W/(m3/s)} + , !- Evaporative Condenser Pump Power Fraction + , !- Evaporative Condenser Effectiveness {dimensionless} + Sys 1 Furnace DX Cool Cool Coil Cap-FT, !- Total Cooling Capacity Modifier Function of Temperature Curve Name + Sys 1 Furnace DX Cool Cool Coil Cap-FF, !- Total Cooling Capacity Modifier Function of Air Flow Fraction Curve Name + Sys 1 Furnace DX Cool Cool Coil EIR-FT, !- Energy Input Ratio Modifier Function of Temperature Curve Name + Sys 1 Furnace DX Cool Cool Coil EIR-FF, !- Energy Input Ratio Modifier Function of Air Flow Fraction Curve Name + Sys 1 Furnace DX Cool Cool Coil PLF, !- Part Load Fraction Correlation Curve Name + 0.2, !- Rated Waste Heat Fraction of Power Input {dimensionless} + Sys 1 Furnace DX Cool Cool Coil WH-FT; !- Waste Heat Modifier Function of Temperature Curve Name + + Coil:Cooling:DX:CurveFit:Speed, + Sys 1 Furnace DX Cool Cooling Coil Speed 2 Performance, !- Name + 1.0000, !- Gross Total Cooling Capacity Fraction + 1.0000, !- Evaporator Air Flow Rate Fraction + , !- Condenser Air Flow Rate Fraction + autosize, !- Gross Sensible Heat Ratio + 3, !- Gross Cooling COP {W/W} + 1.0, !- Active Fraction of Coil Face Area + , !- 2017 Rated Evaporator Fan Power Per Volume Flow Rate {W/(m3/s)} + 934.4, !- 2023 Rated Evaporator Fan Power Per Volume Flow Rate {W/(m3/s)} + , !- Evaporative Condenser Pump Power Fraction + , !- Evaporative Condenser Effectiveness {dimensionless} + Sys 1 Furnace DX Cool Cool Coil Cap-FT, !- Total Cooling Capacity Modifier Function of Temperature Curve Name + Sys 1 Furnace DX Cool Cool Coil Cap-FF, !- Total Cooling Capacity Modifier Function of Air Flow Fraction Curve Name + Sys 1 Furnace DX Cool Cool Coil EIR-FT, !- Energy Input Ratio Modifier Function of Temperature Curve Name + Sys 1 Furnace DX Cool Cool Coil EIR-FF, !- Energy Input Ratio Modifier Function of Air Flow Fraction Curve Name + Sys 1 Furnace DX Cool Cool Coil PLF, !- Part Load Fraction Correlation Curve Name + 0.2, !- Rated Waste Heat Fraction of Power Input {dimensionless} + Sys 1 Furnace DX Cool Cool Coil WH-FT; !- Waste Heat Modifier Function of Temperature Curve Name + +! Curves from example file MultiSpeedHeatPump.idf, Sep 2013, same curves for all speeds. + + Curve:Biquadratic, + Sys 1 Furnace DX Cool Cool Coil Cap-FT, !- Name + 0.476428E+00, !- Coefficient1 Constant + 0.401147E-01, !- Coefficient2 x + 0.226411E-03, !- Coefficient3 x**2 + -0.827136E-03, !- Coefficient4 y + -0.732240E-05, !- Coefficient5 y**2 + -0.446278E-03, !- Coefficient6 x*y + 0.0, !- Minimum Value of x + 50.0, !- Maximum Value of x + 0.0, !- Minimum Value of y + 50.0, !- Maximum Value of y + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Temperature, !- Input Unit Type for X + Temperature, !- Input Unit Type for Y + Dimensionless; !- Output Unit Type + + Curve:Cubic, + Sys 1 Furnace DX Cool Cool Coil Cap-FF, !- Name + 0.47278589, !- Coefficient1 Constant + 1.2433415, !- Coefficient2 x + -1.0387055, !- Coefficient3 x**2 + 0.32257813, !- Coefficient4 x**3 + 0.5, !- Minimum Value of x + 1.5; !- Maximum Value of x + + Curve:Biquadratic, + Sys 1 Furnace DX Cool Cool Coil EIR-FT, !- Name + 0.632475E+00, !- Coefficient1 Constant + -0.121321E-01, !- Coefficient2 x + 0.507773E-03, !- Coefficient3 x**2 + 0.155377E-01, !- Coefficient4 y + 0.272840E-03, !- Coefficient5 y**2 + -0.679201E-03, !- Coefficient6 x*y + 0.0, !- Minimum Value of x + 50.0, !- Maximum Value of x + 0.0, !- Minimum Value of y + 50.0, !- Maximum Value of y + 0.0, !- Minimum Curve Output + 5.0, !- Maximum Curve Output + Temperature, !- Input Unit Type for X + Temperature, !- Input Unit Type for Y + Dimensionless; !- Output Unit Type + + Curve:Cubic, + Sys 1 Furnace DX Cool Cool Coil EIR-FF, !- Name + 0.47278589, !- Coefficient1 Constant + 1.2433415, !- Coefficient2 x + -1.0387055, !- Coefficient3 x**2 + 0.32257813, !- Coefficient4 x**3 + 0.5, !- Minimum Value of x + 1.5; !- Maximum Value of x + +! PLF = l.- Cd(1.-PLR) where Cd = 0.15 + + Curve:Quadratic, + Sys 1 Furnace DX Cool Cool Coil PLF, !- Name + 0.85, !- Coefficient1 Constant + 0.15, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0, !- Minimum Value of x + 1; !- Maximum Value of x + + Curve:Biquadratic, + Sys 1 Furnace DX Cool Cool Coil WH-FT, !- Name + 1.0, !- Coefficient1 Constant + 0.0, !- Coefficient2 x + 0.0, !- Coefficient3 x**2 + 0.0, !- Coefficient4 y + 0.0, !- Coefficient5 y**2 + 0.0, !- Coefficient6 x*y + 0, !- Minimum Value of x + 50, !- Maximum Value of x + 0, !- Minimum Value of y + 50, !- Maximum Value of y + , !- Minimum Curve Output + , !- Maximum Curve Output + Temperature, !- Input Unit Type for X + Temperature, !- Input Unit Type for Y + Dimensionless; !- Output Unit Type + +)IDF"; + + EXPECT_TRUE(process_idf(idf_objects, false)); + + bool zoneEquipment = true; + state->dataZoneEquip->ZoneEquipInputsFilled = true; + bool ErrorsFound(false); + std::string compName = "SYS 1 FURNACE DX COOL UNITARY SYSTEM"; + UnitarySystems::UnitarySys::factory(*state, HVAC::UnitarySysType::Unitary_AnyCoilType, compName, zoneEquipment, 0); + auto thisSys = &state->dataUnitarySystems->unitarySys[0]; + thisSys->getUnitarySystemInputData(*state, compName, zoneEquipment, 0, ErrorsFound); + + OutputReportPredefined::SetPredefinedTables(*state); + + state->dataGlobal->BeginEnvrnFlag = false; + state->dataLoopNodes->Node(thisSys->CoolCoilInletNodeNum).MassFlowRate = 0.05; + state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(1); + state->dataZoneEnergyDemand->ZoneSysMoistureDemand.allocate(1); + state->dataUnitarySystems->CoolingLoad = true; + state->dataHVACGlobal->MSHPMassFlowRateLow = 0.15; + + int AirLoopNum(0); + bool FirstHVACIteration = false; + thisSys->sizeSystem(*state, FirstHVACIteration, AirLoopNum); + + Real64 OnOffAirFlowRatio(1.0); + Real64 CoilCoolHeatRat(1.0); + HVAC::CompressorOp CompressorOn(HVAC::CompressorOp::On); + thisSys->m_CoolingSpeedNum = 0; + thisSys->m_SingleMode = 0; + thisSys->m_CoolingPartLoadFrac = 0.5; + thisSys->calcUnitaryCoolingSystem( + *state, AirLoopNum, FirstHVACIteration, thisSys->m_CoolingPartLoadFrac, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, false); + EXPECT_EQ(state->dataLoopNodes->Node(thisSys->CoolCoilInletNodeNum).Temp, state->dataLoopNodes->Node(thisSys->CoolCoilOutletNodeNum).Temp); + EXPECT_EQ(state->dataLoopNodes->Node(thisSys->CoolCoilInletNodeNum).HumRat, state->dataLoopNodes->Node(thisSys->CoolCoilOutletNodeNum).HumRat); + EXPECT_EQ(state->dataLoopNodes->Node(thisSys->CoolCoilInletNodeNum).Enthalpy, + state->dataLoopNodes->Node(thisSys->CoolCoilOutletNodeNum).Enthalpy); +}